1
0
Fork 0

Adding upstream version 0.23.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-17 21:17:35 +01:00
parent 22f7f3575c
commit 9a8733dd3b
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
39 changed files with 2213 additions and 1444 deletions

View file

@ -68,7 +68,8 @@ void format_mode_string( const Tar_header header, char buf[mode_string_size] )
}
int format_user_group_string( const Tar_header header,
int format_user_group_string( const Extended & extended,
const Tar_header header,
char buf[group_string_size] )
{
int len;
@ -76,11 +77,8 @@ int format_user_group_string( const Tar_header header,
len = snprintf( buf, group_string_size,
" %.32s/%.32s", header + uname_o, header + gname_o );
else
{
const unsigned uid = parse_octal( header + uid_o, uid_l );
const unsigned gid = parse_octal( header + gid_o, gid_l );
len = snprintf( buf, group_string_size, " %u/%u", uid, gid );
}
len = snprintf( buf, group_string_size, " %llu/%llu",
extended.get_uid(), extended.get_gid() );
return len;
}
@ -122,32 +120,41 @@ bool format_member_name( const Extended & extended, const Tar_header header,
{
format_mode_string( header, rbuf() );
const int group_string_len =
format_user_group_string( header, rbuf() + mode_string_size );
format_user_group_string( extended, header, rbuf() + mode_string_size );
int offset = mode_string_size + group_string_len;
const time_t mtime = parse_octal( header + mtime_o, mtime_l ); // 33 bits
struct tm tms;
const struct tm * tm = localtime_r( &mtime, &tms );
if( !tm )
{ time_t z = 0; tm = localtime_r( &z, &tms ); if( !tm ) tm = &tms; }
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
{ 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 );
const char * const link_string = !islink ? "" :
( ( typeflag == tf_link ) ? " link to " : " -> " );
// print "user/group size" in a field of width 19 with 8 or more for size
if( typeflag == tf_chardev || typeflag == tf_blockdev )
offset += snprintf( rbuf() + offset, rbuf.size() - offset, " %5u,%u",
(unsigned)parse_octal( header + devmajor_o, devmajor_l ),
(unsigned)parse_octal( header + devminor_o, devminor_l ) );
{
const unsigned devmajor = parse_octal( header + devmajor_o, devmajor_l );
const unsigned devminor = parse_octal( header + devminor_o, devminor_l );
const int width = std::max( 1,
std::max( 8, 19 - group_string_len ) - 1 - decimal_digits( devminor ) );
offset += snprintf( rbuf() + offset, rbuf.size() - offset, " %*u,%u",
width, devmajor, devminor );
}
else
offset += snprintf( rbuf() + offset, rbuf.size() - offset, " %9llu",
extended.file_size() );
{
const int width = std::max( 8, 19 - group_string_len );
offset += snprintf( rbuf() + offset, rbuf.size() - offset, " %*llu",
width, extended.file_size() );
}
for( int i = 0; i < 2; ++i ) // resize rbuf if not large enough
{
const int len = snprintf( rbuf() + offset, rbuf.size() - offset,
" %4d-%02u-%02u %02u:%02u %s%s%s\n",
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, extended.path().c_str(),
link_string, islink ? extended.linkpath().c_str() : "" );
if( (int)rbuf.size() > len + offset ) break;
1900 + t.tm_year, 1 + t.tm_mon, t.tm_mday, t.tm_hour,
t.tm_min, extended.path().c_str(), link_string,
islink ? extended.linkpath().c_str() : "" );
if( len + offset < (int)rbuf.size() ) break;
if( !rbuf.resize( len + offset + 1 ) ) return false;
}
}
@ -180,16 +187,18 @@ bool check_skip_filename( const Cl_options & cl_opts,
const char * const filename )
{
if( Exclude::excluded( filename ) ) return true; // skip excluded files
bool skip = cl_opts.num_files > 0;
if( skip )
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 ) )
{
const char * const name =
remove_leading_dotslash( cl_opts.parser.argument( i ).c_str() );
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 ) )
{ skip = false; name_pending[i] = false; break; }
{ print_removed_prefix( removed_prefix );
skip = false; name_pending[i] = false; break; }
}
return skip;
}
@ -224,10 +233,10 @@ bool make_path( const std::string & name )
{
const std::string partial( name, 0, index );
struct stat st;
if( stat( partial.c_str(), &st ) == 0 )
{ if( !S_ISDIR( st.st_mode ) ) return false; }
if( lstat( partial.c_str(), &st ) == 0 )
{ if( !S_ISDIR( st.st_mode ) ) { errno = ENOTDIR; return false; } }
else if( mkdir( partial.c_str(), mode ) != 0 && errno != EEXIST )
return false;
return false; // if EEXIST, another thread or process created the dir
}
}
return true;