diff options
Diffstat (limited to 'extract.cc')
-rw-r--r-- | extract.cc | 72 |
1 files changed, 20 insertions, 52 deletions
@@ -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 ) |