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
136
tarlz.h
136
tarlz.h
|
@ -57,7 +57,7 @@ inline void init_tar_header( Tar_header header ) // set magic and version
|
|||
}
|
||||
|
||||
inline void print_octal( uint8_t * const buf, int size, unsigned long long num )
|
||||
{ while( --size >= 0 ) { buf[size] = '0' + ( num % 8 ); num /= 8; } }
|
||||
{ while( --size >= 0 ) { buf[size] = num % 8 + '0'; num /= 8; } }
|
||||
|
||||
|
||||
// Round "size" to the next multiple of header size (512).
|
||||
|
@ -70,6 +70,14 @@ inline unsigned long long round_up( const unsigned long long size )
|
|||
}
|
||||
|
||||
|
||||
inline int decimal_digits( unsigned long long value )
|
||||
{
|
||||
int digits = 1;
|
||||
while( value >= 10 ) { value /= 10; ++digits; }
|
||||
return digits;
|
||||
}
|
||||
|
||||
|
||||
inline bool dotdot_at_i( const char * const filename, const int i )
|
||||
{
|
||||
return ( filename[i] == '.' && filename[i+1] == '.' &&
|
||||
|
@ -119,12 +127,45 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class Extended // stores metadata from/for extended records
|
||||
inline bool uid_in_ustar_range( const long long uid ) // also for gid
|
||||
{ return uid >= 0 && uid < 1 << 21; }
|
||||
|
||||
inline bool time_in_ustar_range( const long long seconds )
|
||||
{ return seconds >= 0 && seconds < 1LL << 33; }
|
||||
|
||||
|
||||
/* The sign of the seconds field applies to the whole time value.
|
||||
A nanoseconds value out of range means an invalid time. */
|
||||
class Etime // time since (or before) the epoch
|
||||
{
|
||||
long long sec_;
|
||||
int nsec_; // range [0, 999_999_999]
|
||||
|
||||
public:
|
||||
Etime() : sec_( 0 ), nsec_( -1 ) {}
|
||||
void reset() { sec_ = 0; nsec_ = -1; }
|
||||
void set( const long long s ) { sec_ = s; nsec_ = 0; }
|
||||
long long sec() const { return sec_; }
|
||||
int nsec() const { return nsec_; }
|
||||
bool isvalid() const { return nsec_ >= 0 && nsec_ <= 999999999; }
|
||||
bool out_of_ustar_range() const
|
||||
{ return isvalid() && !time_in_ustar_range( sec_ ); }
|
||||
|
||||
unsigned decimal_size() const;
|
||||
unsigned print( char * const buf ) const;
|
||||
bool parse( const char * const ptr, const char ** const tailp,
|
||||
const long long size );
|
||||
};
|
||||
|
||||
|
||||
class Extended // stores metadata from/for extended records
|
||||
{
|
||||
static std::vector< std::string > unknown_keywords; // already diagnosed
|
||||
std::string linkpath_; // these are the real metadata
|
||||
std::string path_;
|
||||
long long file_size_; // >= 0 && <= max_file_size
|
||||
long long uid_, gid_; // may not fit in unsigned int
|
||||
Etime atime_, mtime_;
|
||||
|
||||
// cached sizes; if full_size_ < 0 they must be recalculated
|
||||
mutable long long edsize_; // extended data size
|
||||
|
@ -133,6 +174,10 @@ class Extended // stores metadata from/for extended records
|
|||
mutable long long linkpath_recsize_;
|
||||
mutable long long path_recsize_;
|
||||
mutable int file_size_recsize_;
|
||||
mutable int uid_recsize_;
|
||||
mutable int gid_recsize_;
|
||||
mutable int atime_recsize_;
|
||||
mutable int mtime_recsize_;
|
||||
|
||||
// true if CRC present in parsed or formatted records
|
||||
mutable bool crc_present_;
|
||||
|
@ -143,29 +188,47 @@ class Extended // stores metadata from/for extended records
|
|||
|
||||
public:
|
||||
static const std::string crc_record;
|
||||
std::string removed_prefix;
|
||||
|
||||
Extended()
|
||||
: file_size_( 0 ), edsize_( 0 ), padded_edsize_( 0 ), full_size_( 0 ),
|
||||
linkpath_recsize_( 0 ), path_recsize_( 0 ), file_size_recsize_( 0 ),
|
||||
: file_size_( 0 ), uid_( -1 ), gid_( -1 ), edsize_( 0 ),
|
||||
padded_edsize_( 0 ), full_size_( 0 ), linkpath_recsize_( 0 ),
|
||||
path_recsize_( 0 ), file_size_recsize_( 0 ), uid_recsize_( 0 ),
|
||||
gid_recsize_( 0 ), atime_recsize_( 0 ), mtime_recsize_( 0 ),
|
||||
crc_present_( false ) {}
|
||||
|
||||
void reset()
|
||||
{ linkpath_.clear(); path_.clear(); file_size_ = 0; edsize_ = 0;
|
||||
padded_edsize_ = 0; full_size_ = 0; linkpath_recsize_ = 0;
|
||||
path_recsize_ = 0; file_size_recsize_ = 0; crc_present_ = false; }
|
||||
{ linkpath_.clear(); path_.clear(); file_size_ = 0; uid_ = -1; gid_ = -1;
|
||||
atime_.reset(); mtime_.reset(); edsize_ = 0; padded_edsize_ = 0;
|
||||
full_size_ = 0; linkpath_recsize_ = 0; path_recsize_ = 0;
|
||||
file_size_recsize_ = 0; uid_recsize_ = 0; gid_recsize_ = 0;
|
||||
atime_recsize_ = 0; mtime_recsize_ = 0; crc_present_ = false;
|
||||
removed_prefix.clear(); }
|
||||
|
||||
bool empty() const
|
||||
{ return linkpath_.empty() && path_.empty() && file_size_ == 0; }
|
||||
{ return linkpath_.empty() && path_.empty() && file_size_ == 0 &&
|
||||
uid_ < 0 && gid_ < 0 &&
|
||||
!atime_.out_of_ustar_range() && !mtime_.out_of_ustar_range(); }
|
||||
|
||||
const std::string & linkpath() const { return linkpath_; }
|
||||
const std::string & path() const { return path_; }
|
||||
long long file_size() const { return file_size_; }
|
||||
long long get_file_size_and_reset( const Tar_header header );
|
||||
long long get_uid() const { return uid_; }
|
||||
long long get_gid() const { return gid_; }
|
||||
const Etime & atime() const { return atime_; }
|
||||
const Etime & mtime() const { return mtime_; }
|
||||
|
||||
void linkpath( const char * const lp ) { linkpath_ = lp; full_size_ = -1; }
|
||||
void path( const char * const p ) { path_ = p; full_size_ = -1; }
|
||||
void file_size( const long long fs ) { full_size_ = -1;
|
||||
file_size_ = ( fs >= 0 && fs <= max_file_size ) ? fs : 0; }
|
||||
bool set_uid( const long long id )
|
||||
{ if( id >= 0 ) { uid_ = id; full_size_ = -1; } return id >= 0; }
|
||||
bool set_gid( const long long id )
|
||||
{ if( id >= 0 ) { gid_ = id; full_size_ = -1; } return id >= 0; }
|
||||
void set_atime( const long long s ) { atime_.set( s ); full_size_ = -1; }
|
||||
void set_mtime( const long long s ) { mtime_.set( s ); full_size_ = -1; }
|
||||
|
||||
long long full_size() const
|
||||
{ if( full_size_ < 0 ) calculate_sizes(); return full_size_; }
|
||||
|
@ -269,10 +332,10 @@ const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; // "LZIP"
|
|||
|
||||
struct Lzip_header
|
||||
{
|
||||
uint8_t data[6]; // 0-3 magic bytes
|
||||
enum { size = 6 };
|
||||
uint8_t data[size]; // 0-3 magic bytes
|
||||
// 4 version
|
||||
// 5 coded dictionary size
|
||||
enum { size = 6 };
|
||||
|
||||
bool verify_magic() const
|
||||
{ return ( std::memcmp( data, lzip_magic, 4 ) == 0 ); }
|
||||
|
@ -283,6 +346,7 @@ struct Lzip_header
|
|||
if( data[i] != lzip_magic[i] ) return false;
|
||||
return ( sz > 0 );
|
||||
}
|
||||
|
||||
bool verify_corrupt() const // detect corrupt header
|
||||
{
|
||||
int matches = 0;
|
||||
|
@ -310,10 +374,10 @@ struct Lzip_header
|
|||
|
||||
struct Lzip_trailer
|
||||
{
|
||||
uint8_t data[20]; // 0-3 CRC32 of the uncompressed data
|
||||
enum { size = 20 };
|
||||
uint8_t data[size]; // 0-3 CRC32 of the uncompressed data
|
||||
// 4-11 size of the uncompressed data
|
||||
// 12-19 member size including header and trailer
|
||||
enum { size = 20 };
|
||||
|
||||
unsigned data_crc() const
|
||||
{
|
||||
|
@ -356,12 +420,15 @@ enum Program_mode { m_none, m_append, m_compress, m_concatenate, m_create,
|
|||
m_delete, m_diff, m_extract, m_list };
|
||||
enum Solidity { no_solid, bsolid, dsolid, asolid, solid };
|
||||
class Arg_parser;
|
||||
|
||||
struct Cl_options // command line options
|
||||
{
|
||||
const Arg_parser & parser;
|
||||
std::string archive_name;
|
||||
std::string output_filename;
|
||||
long long mtime;
|
||||
long long uid;
|
||||
long long gid;
|
||||
Program_mode program_mode;
|
||||
Solidity solidity;
|
||||
int data_size;
|
||||
|
@ -370,29 +437,28 @@ struct Cl_options // command line options
|
|||
int num_files;
|
||||
int num_workers; // start this many worker threads
|
||||
int out_slots;
|
||||
int owner;
|
||||
int group;
|
||||
bool dereference;
|
||||
bool filenames_given;
|
||||
bool ignore_ids;
|
||||
bool ignore_overflow;
|
||||
bool keep_damaged;
|
||||
bool missing_crc;
|
||||
bool mtime_set;
|
||||
bool permissive;
|
||||
bool preserve_permissions;
|
||||
bool warn_newer;
|
||||
|
||||
Cl_options( const Arg_parser & ap )
|
||||
: parser( ap ), mtime( -1 ), program_mode( m_none ), solidity( bsolid ),
|
||||
data_size( 0 ), debug_level( 0 ), level( 6 ), num_files( 0 ),
|
||||
num_workers( -1 ), out_slots( 64 ), owner( -1 ), group( -1 ),
|
||||
dereference( false ), filenames_given( false ), ignore_ids( false ),
|
||||
keep_damaged( false ), missing_crc( false ), permissive( false ),
|
||||
preserve_permissions( false ), warn_newer( false ) {}
|
||||
: parser( ap ), mtime( 0 ), uid( -1 ), gid( -1 ), program_mode( m_none ),
|
||||
solidity( bsolid ), data_size( 0 ), debug_level( 0 ), level( 6 ),
|
||||
num_files( 0 ), num_workers( -1 ), out_slots( 64 ), dereference( false ),
|
||||
filenames_given( false ), ignore_ids( false ), ignore_overflow( false ),
|
||||
keep_damaged( false ), missing_crc( false ), mtime_set( false ),
|
||||
permissive( false ), preserve_permissions( false ), warn_newer( false ) {}
|
||||
|
||||
bool to_stdout() const { return output_filename == "-"; }
|
||||
};
|
||||
|
||||
|
||||
inline void set_retval( int & retval, const int new_val )
|
||||
{ if( retval < new_val ) retval = new_val; }
|
||||
|
||||
|
@ -403,15 +469,23 @@ const char * const trailing_msg = "Trailing data not allowed.";
|
|||
const char * const bad_hdr_msg = "Corrupt or invalid tar header.";
|
||||
const char * const gblrec_msg = "Error in global extended records.";
|
||||
const char * const extrec_msg = "Error in extended records.";
|
||||
const char * const mcrc_msg = "Missing CRC in extended records.";
|
||||
const char * const miscrc_msg = "Missing CRC in extended records.";
|
||||
const char * const misrec_msg = "Missing extended records.";
|
||||
const char * const longrec_msg = "Extended records are too long.";
|
||||
const char * const end_msg = "Archive ends unexpectedly.";
|
||||
const char * const mem_msg = "Not enough memory.";
|
||||
const char * const mem_msg2 = "Not enough memory. Try a lower compression level.";
|
||||
const char * const fv_msg1 = "Format violation: extended header followed by EOF blocks.";
|
||||
const char * const fv_msg1 = "Format violation: extended header followed by EOA blocks.";
|
||||
const char * const fv_msg2 = "Format violation: extended header followed by global header.";
|
||||
const char * const fv_msg3 = "Format violation: consecutive extended headers found.";
|
||||
const char * const posix_msg = "This does not look like a POSIX tar archive.";
|
||||
const char * const posix_lz_msg = "This does not look like a POSIX tar.lz archive.";
|
||||
const char * const eclosa_msg = "Error closing archive";
|
||||
const char * const eclosf_msg = "Error closing file";
|
||||
const char * const nfound_msg = "Not found in archive.";
|
||||
const char * const seek_msg = "Seek error";
|
||||
const char * const werr_msg = "Write error";
|
||||
const char * const chdir_msg = "Error changing working directory";
|
||||
|
||||
// defined in common.cc
|
||||
void xinit_mutex( pthread_mutex_t * const mutex );
|
||||
|
@ -441,15 +515,17 @@ mode_t get_umask();
|
|||
bool make_path( const std::string & name );
|
||||
|
||||
// defined in compress.cc
|
||||
int compress( Cl_options & cl_opts );
|
||||
int compress( const Cl_options & cl_opts );
|
||||
|
||||
// defined in create.cc
|
||||
bool copy_file( const int infd, const int outfd, const long long max_size = -1 );
|
||||
bool writeblock_wrapper( const int outfd, const uint8_t * const buffer,
|
||||
const int size );
|
||||
bool write_eof_records( const int outfd, const bool compressed );
|
||||
bool write_eoa_records( const int outfd, const bool compressed );
|
||||
const char * remove_leading_dotslash( const char * const filename,
|
||||
const bool dotdot = false );
|
||||
std::string * const removed_prefixp, const bool dotdot = false );
|
||||
bool print_removed_prefix( const std::string & prefix,
|
||||
std::string * const msgp = 0 );
|
||||
bool fill_headers( const char * const filename, Extended & extended,
|
||||
Tar_header header, long long & file_size, const int flag );
|
||||
bool block_is_full( const long long extended_size,
|
||||
|
@ -462,11 +538,10 @@ unsigned ustar_chksum( const Tar_header header );
|
|||
bool verify_ustar_chksum( const Tar_header header );
|
||||
bool has_lz_ext( const std::string & name );
|
||||
int concatenate( const Cl_options & cl_opts );
|
||||
int encode( Cl_options & cl_opts );
|
||||
int encode( const Cl_options & cl_opts );
|
||||
|
||||
// defined in create_lz.cc
|
||||
int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
|
||||
const int dictionary_size, const int match_len_limit,
|
||||
const int outfd );
|
||||
|
||||
// defined in decode.cc
|
||||
|
@ -522,8 +597,13 @@ int open_outstream( const std::string & name, const bool create = true,
|
|||
void exit_fail_mt( const int retval = 1 ); // terminate the program
|
||||
void show_error( const char * const msg, const int errcode = 0,
|
||||
const bool help = false );
|
||||
bool format_error( Resizable_buffer & rbuf, const int errcode,
|
||||
const char * const format, ... );
|
||||
void print_error( const int errcode, const char * const format, ... );
|
||||
void format_file_error( std::string & estr, const char * const filename,
|
||||
const char * const msg, const int errcode = 0 );
|
||||
bool format_file_error( Resizable_buffer & rbuf, const char * const filename,
|
||||
const char * const msg, const int errcode = 0 );
|
||||
void show_file_error( const char * const filename, const char * const msg,
|
||||
const int errcode = 0 );
|
||||
void internal_error( const char * const msg );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue