Adding upstream version 0.23.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
22f7f3575c
commit
9a8733dd3b
39 changed files with 2213 additions and 1444 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue