Adding upstream version 0.24.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
9a8733dd3b
commit
4f5d0de2b2
33 changed files with 905 additions and 882 deletions
|
@ -1,5 +1,5 @@
|
|||
/* Tarlz - Archiver with multimember lzip compression
|
||||
Copyright (C) 2013-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2013-2023 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,12 +19,13 @@
|
|||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "tarlz.h"
|
||||
#include "arg_parser.h"
|
||||
#include "decode.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
@ -125,7 +126,7 @@ bool format_member_name( const Extended & extended, const Tar_header header,
|
|||
const time_t mtime = extended.mtime().sec();
|
||||
struct tm t;
|
||||
if( !localtime_r( &mtime, &t ) ) // if local time fails
|
||||
{ time_t z = 0; if( !gmtime_r( &z, &t ) ) // use the UTC epoch
|
||||
{ time_t z = 0; if( !gmtime_r( &z, &t ) ) // use UTC, the epoch
|
||||
{ t.tm_year = 70; t.tm_mon = t.tm_hour = t.tm_min = 0; t.tm_mday = 1; } }
|
||||
const Typeflag typeflag = (Typeflag)header[typeflag_o];
|
||||
const bool islink = ( typeflag == tf_link || typeflag == tf_symlink );
|
||||
|
@ -184,36 +185,48 @@ bool show_member_name( const Extended & extended, const Tar_header header,
|
|||
|
||||
bool check_skip_filename( const Cl_options & cl_opts,
|
||||
std::vector< char > & name_pending,
|
||||
const char * const filename )
|
||||
const char * const filename, const int chdir_fd )
|
||||
{
|
||||
static int c_idx = -1; // parser index of last -C executed
|
||||
if( Exclude::excluded( filename ) ) return true; // skip excluded files
|
||||
bool skip = cl_opts.num_files > 0; // if no files specified, skip nothing
|
||||
if( skip ) // else skip all but the files (or trees) specified
|
||||
for( int i = 0; i < cl_opts.parser.arguments(); ++i )
|
||||
if( nonempty_arg( cl_opts.parser, i ) )
|
||||
if( cl_opts.num_files <= 0 ) return false; // no files specified, no skip
|
||||
bool skip = true; // else skip all but the files (or trees) specified
|
||||
bool chdir_pending = false;
|
||||
|
||||
for( int i = 0; i < cl_opts.parser.arguments(); ++i )
|
||||
{
|
||||
if( cl_opts.parser.code( i ) == 'C' ) { chdir_pending = true; continue; }
|
||||
if( !nonempty_arg( cl_opts.parser, i ) ) continue; // skip opts, empty names
|
||||
std::string removed_prefix;
|
||||
const char * const name = remove_leading_dotslash(
|
||||
cl_opts.parser.argument( i ).c_str(), &removed_prefix );
|
||||
if( compare_prefix_dir( name, filename ) ||
|
||||
compare_tslash( name, filename ) )
|
||||
{
|
||||
print_removed_prefix( removed_prefix );
|
||||
skip = false; name_pending[i] = false;
|
||||
if( chdir_pending && chdir_fd >= 0 )
|
||||
{
|
||||
std::string removed_prefix;
|
||||
const char * const name = remove_leading_dotslash(
|
||||
cl_opts.parser.argument( i ).c_str(), &removed_prefix );
|
||||
if( compare_prefix_dir( name, filename ) ||
|
||||
compare_tslash( name, filename ) )
|
||||
{ print_removed_prefix( removed_prefix );
|
||||
skip = false; name_pending[i] = false; break; }
|
||||
if( c_idx > i )
|
||||
{ if( fchdir( chdir_fd ) != 0 )
|
||||
{ show_error( "Error changing to initial working directory", errno );
|
||||
throw Chdir_error(); } c_idx = -1; }
|
||||
for( int j = c_idx + 1; j < i; ++j )
|
||||
{
|
||||
if( cl_opts.parser.code( j ) != 'C' ) continue;
|
||||
const char * const dir = cl_opts.parser.argument( j ).c_str();
|
||||
if( chdir( dir ) != 0 )
|
||||
{ show_file_error( dir, chdir_msg, errno ); throw Chdir_error(); }
|
||||
c_idx = j;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return skip;
|
||||
}
|
||||
|
||||
|
||||
mode_t get_umask()
|
||||
{
|
||||
static mode_t mask = 0; // read once, cache the result
|
||||
static bool first_call = true;
|
||||
if( first_call ) { first_call = false; mask = umask( 0 ); umask( mask );
|
||||
mask &= S_IRWXU | S_IRWXG | S_IRWXO; }
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
bool make_path( const std::string & name )
|
||||
{
|
||||
const mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue