Merging upstream version 0.13.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
dea1c6852b
commit
ab79495362
21 changed files with 280 additions and 225 deletions
72
extract.cc
72
extract.cc
|
@ -373,15 +373,20 @@ int compare_member( const int infd1, const Extended & extended,
|
|||
}
|
||||
if( typeflag != tf_symlink )
|
||||
{
|
||||
const time_t mtime = parse_octal( header + mtime_o, mtime_l ); // 33 bits
|
||||
if( mtime != st.st_mtime )
|
||||
{ show_file_diff( filename, "Mod time differs" ); diff = true; }
|
||||
if( typeflag != tf_directory )
|
||||
{
|
||||
const time_t mtime = parse_octal( header + mtime_o, mtime_l ); // 33 bits
|
||||
if( mtime != st.st_mtime )
|
||||
{ show_file_diff( filename, "Mod time differs" ); diff = true; }
|
||||
}
|
||||
if( ( typeflag == tf_regular || typeflag == tf_hiperf ) &&
|
||||
(off_t)rest != st.st_size ) // don't compare contents
|
||||
{ show_file_diff( filename, "Size differs" ); size_differs = true; }
|
||||
if( ( typeflag == tf_chardev || typeflag == tf_blockdev ) &&
|
||||
( parse_octal( header + devmajor_o, devmajor_l ) != major( st.st_rdev ) ||
|
||||
parse_octal( header + devminor_o, devminor_l ) != minor( st.st_rdev ) ) )
|
||||
( parse_octal( header + devmajor_o, devmajor_l ) !=
|
||||
(unsigned)major( st.st_rdev ) ||
|
||||
parse_octal( header + devminor_o, devminor_l ) !=
|
||||
(unsigned)minor( st.st_rdev ) ) )
|
||||
{ show_file_diff( filename, "Device number differs" ); diff = true; }
|
||||
}
|
||||
else
|
||||
|
@ -389,7 +394,12 @@ int compare_member( const int infd1, const Extended & extended,
|
|||
char * const buf = new char[st.st_size+1];
|
||||
long len = readlink( filename, buf, st.st_size );
|
||||
bool e = ( len != st.st_size );
|
||||
if( !e ) { buf[len] = 0; if( extended.linkpath() != buf ) e = true; }
|
||||
if( !e )
|
||||
{
|
||||
while( len > 1 && buf[len-1] == '/' ) --len; // trailing '/'
|
||||
buf[len] = 0;
|
||||
if( extended.linkpath() != buf ) e = true;
|
||||
}
|
||||
delete[] buf;
|
||||
if( e ) { show_file_diff( filename, "Symlink differs" ); diff = true; }
|
||||
}
|
||||
|
@ -451,9 +461,7 @@ int list_member( const int infd, const Extended & extended,
|
|||
bool contains_dotdot( const char * const filename )
|
||||
{
|
||||
for( int i = 0; filename[i]; ++i )
|
||||
if( filename[i] == '.' && filename[i+1] == '.' &&
|
||||
( i == 0 || filename[i-1] == '/' ) &&
|
||||
( filename[i+2] == 0 || filename[i+2] == '/' ) ) return true;
|
||||
if( dotdot_at_i( filename, i ) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -763,50 +771,10 @@ int decode( const std::string & archive_name, const Arg_parser & parser,
|
|||
}
|
||||
prev_extended = false;
|
||||
|
||||
if( extended.linkpath().empty() ) // copy linkpath from ustar header
|
||||
{
|
||||
int len = 0;
|
||||
while( len < linkname_l && header[linkname_o+len] ) ++len;
|
||||
while( len > 1 && header[linkname_o+len-1] == '/' ) --len; // trailing '/'
|
||||
if( len > 0 )
|
||||
{
|
||||
const uint8_t c = header[linkname_o+len]; header[linkname_o+len] = 0;
|
||||
extended.linkpath( (const char *)header + linkname_o );
|
||||
header[linkname_o+len] = c;
|
||||
}
|
||||
}
|
||||
|
||||
if( extended.path().empty() ) // copy path from ustar header
|
||||
{
|
||||
char stored_name[prefix_l+1+name_l+1];
|
||||
int len = 0;
|
||||
while( len < prefix_l && header[prefix_o+len] )
|
||||
{ stored_name[len] = header[prefix_o+len]; ++len; }
|
||||
if( len && header[name_o] ) stored_name[len++] = '/';
|
||||
for( int i = 0; i < name_l && header[name_o+i]; ++i )
|
||||
{ stored_name[len] = header[name_o+i]; ++len; }
|
||||
while( len > 0 && stored_name[len-1] == '/' ) --len; // trailing '/'
|
||||
stored_name[len] = 0;
|
||||
extended.path( remove_leading_dotslash( stored_name ) );
|
||||
}
|
||||
const char * const filename = extended.path().c_str();
|
||||
|
||||
bool skip = filenames > 0;
|
||||
if( skip )
|
||||
for( int i = 0; i < parser.arguments(); ++i )
|
||||
if( !parser.code( i ) && parser.argument( i ).size() )
|
||||
{
|
||||
const char * const name =
|
||||
remove_leading_dotslash( parser.argument( i ).c_str() );
|
||||
if( compare_prefix_dir( name, filename ) ||
|
||||
compare_tslash( name, filename ) )
|
||||
{ skip = false; name_pending[i] = false; break; }
|
||||
}
|
||||
|
||||
if( extended.file_size() == 0 &&
|
||||
( typeflag == tf_regular || typeflag == tf_hiperf ) )
|
||||
extended.file_size( parse_octal( header + size_o, size_l ) );
|
||||
extended.fill_from_ustar( header ); // copy metadata from header
|
||||
|
||||
const bool skip = check_skip_filename( parser, name_pending,
|
||||
extended.path().c_str(), filenames );
|
||||
if( skip )
|
||||
retval = skip_member( infd, extended );
|
||||
else if( program_mode == m_list )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue