diff options
Diffstat (limited to 'tarlz.h')
-rw-r--r-- | tarlz.h | 112 |
1 files changed, 55 insertions, 57 deletions
@@ -1,5 +1,5 @@ /* Tarlz - Archiver with multimember lzip compression - Copyright (C) 2013-2022 Antonio Diaz Diaz. + Copyright (C) 2013-2023 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,14 +16,15 @@ */ #include <climits> +#include <cstdlib> #include <cstring> #include <string> #include <vector> #include <stdint.h> -#include <sys/types.h> #define max_file_size ( LLONG_MAX - header_size ) -enum { header_size = 512 }; +enum { header_size = 512, + max_edata_size = ( INT_MAX / header_size - 2 ) * header_size }; typedef uint8_t Tar_header[header_size]; enum Offsets { @@ -46,7 +47,7 @@ enum Typeflag { const uint8_t ustar_magic[magic_l] = { 0x75, 0x73, 0x74, 0x61, 0x72, 0 }; // "ustar\0" -inline bool verify_ustar_magic( const Tar_header header ) +inline bool check_ustar_magic( const Tar_header header ) { return std::memcmp( header + magic_o, ustar_magic, magic_l ) == 0; } inline void init_tar_header( Tar_header header ) // set magic and version @@ -154,7 +155,7 @@ public: unsigned decimal_size() const; unsigned print( char * const buf ) const; bool parse( const char * const ptr, const char ** const tailp, - const long long size ); + const int size ); }; @@ -167,12 +168,12 @@ class Extended // stores metadata from/for extended records 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 - mutable long long padded_edsize_; // edsize rounded up - mutable long long full_size_; // header + padded edsize - mutable long long linkpath_recsize_; - mutable long long path_recsize_; + // cached sizes; if full_size_ <= -4 they must be recalculated + mutable int edsize_; // extended data size + mutable int padded_edsize_; // edsize rounded up + mutable int full_size_; // header + padded edsize + mutable int linkpath_recsize_; + mutable int path_recsize_; mutable int file_size_recsize_; mutable int uid_recsize_; mutable int gid_recsize_; @@ -183,8 +184,7 @@ class Extended // stores metadata from/for extended records mutable bool crc_present_; void calculate_sizes() const; - void unknown_keyword( const char * const buf, - const unsigned long long size ) const; + void unknown_keyword( const char * const buf, const int size ) const; public: static const std::string crc_record; @@ -205,11 +205,6 @@ public: atime_recsize_ = 0; mtime_recsize_ = 0; crc_present_ = false; removed_prefix.clear(); } - bool empty() const - { 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_; } @@ -219,23 +214,26 @@ public: 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; + void linkpath( const char * const lp ) { linkpath_ = lp; full_size_ = -4; } + void path( const char * const p ) { path_ = p; full_size_ = -4; } + void file_size( const long long fs ) { full_size_ = -4; 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; } + { if( id >= 0 ) { uid_ = id; full_size_ = -4; } 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; } + { if( id >= 0 ) { gid_ = id; full_size_ = -4; } return id >= 0; } + void set_atime( const long long s ) { atime_.set( s ); full_size_ = -4; } + void set_mtime( const long long s ) { mtime_.set( s ); full_size_ = -4; } - long long full_size() const - { if( full_size_ < 0 ) calculate_sizes(); return full_size_; } + /* Return the size of the extended block, or 0 if empty. + Return -1 if error, -2 if out of memory, -3 if block too long. */ + int full_size() const + { if( full_size_ <= -4 ) calculate_sizes(); return full_size_; } + int format_block( Resizable_buffer & rbuf ) const; + const char * full_size_error() const; bool crc_present() const { return crc_present_; } - long long format_block( Resizable_buffer & rbuf ) const; - bool parse( const char * const buf, const unsigned long long edsize, + bool parse( const char * const buf, const int edsize, const bool permissive ); void fill_from_ustar( const Tar_header header ); }; @@ -337,17 +335,17 @@ struct Lzip_header // 4 version // 5 coded dictionary size - bool verify_magic() const + bool check_magic() const { return ( std::memcmp( data, lzip_magic, 4 ) == 0 ); } - bool verify_prefix( const int sz ) const // detect (truncated) header + bool check_prefix( const int sz ) const // detect (truncated) header { for( int i = 0; i < sz && i < 4; ++i ) if( data[i] != lzip_magic[i] ) return false; return ( sz > 0 ); } - bool verify_corrupt() const // detect corrupt header + bool check_corrupt() const // detect corrupt header { int matches = 0; for( int i = 0; i < 4; ++i ) @@ -356,7 +354,7 @@ struct Lzip_header } uint8_t version() const { return data[4]; } - bool verify_version() const { return ( data[4] == 1 ); } + bool check_version() const { return ( data[4] == 1 ); } unsigned dictionary_size() const { @@ -366,8 +364,8 @@ struct Lzip_header return sz; } - bool verify() const - { return verify_magic() && verify_version() && + bool check() const + { return check_magic() && check_version() && isvalid_ds( dictionary_size() ); } }; @@ -400,7 +398,7 @@ struct Lzip_trailer return tmp; } - bool verify_consistency() const // check internal consistency + bool check_consistency() const // check internal consistency { const unsigned crc = data_crc(); const unsigned long long dsize = data_size(); @@ -442,6 +440,7 @@ struct Cl_options // command line options bool ignore_ids; bool ignore_overflow; bool keep_damaged; + bool level_set; // compression level set in command line bool missing_crc; bool mtime_set; bool permissive; @@ -453,9 +452,14 @@ struct Cl_options // command line options 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 ) {} + keep_damaged( false ), level_set( false ), missing_crc( false ), + mtime_set( false ), permissive( false ), preserve_permissions( false ), + warn_newer( false ) {} + + void set_level( const int l ) { level = l; level_set = true; } + int compressed() const; // tri-state bool with error (-2) + bool uncompressed() const { return level < 0 || level > 9; } bool to_stdout() const { return output_filename == "-"; } }; @@ -488,19 +492,9 @@ 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 ); -void xinit_cond( pthread_cond_t * const cond ); -void xdestroy_mutex( pthread_mutex_t * const mutex ); -void xdestroy_cond( pthread_cond_t * const cond ); -void xlock( pthread_mutex_t * const mutex ); -void xunlock( pthread_mutex_t * const mutex ); -void xwait( pthread_cond_t * const cond, pthread_mutex_t * const mutex ); -void xsignal( pthread_cond_t * const cond ); -void xbroadcast( pthread_cond_t * const cond ); unsigned long long parse_octal( const uint8_t * const ptr, const int size ); int readblock( const int fd, uint8_t * const buf, const int size ); int writeblock( const int fd, const uint8_t * const buf, const int size ); -bool nonempty_arg( const Arg_parser & parser, const int i ); // defined in common_decode.cc bool block_is_zero( const uint8_t * const buf, const int size ); @@ -510,11 +504,19 @@ bool show_member_name( const Extended & extended, const Tar_header header, const int vlevel, Resizable_buffer & rbuf ); bool check_skip_filename( const Cl_options & cl_opts, std::vector< char > & name_pending, - const char * const filename ); -mode_t get_umask(); + const char * const filename, const int chdir_fd = -1 ); bool make_path( const std::string & name ); +// defined in common_mutex.cc +void exit_fail_mt( const int retval = 1 ); // terminate the program +bool print_removed_prefix( const std::string & prefix, + std::string * const msgp = 0 ); +void set_error_status( const int retval ); +int final_exit_status( int retval, const bool show_msg = true ); + // defined in compress.cc +void show_atpos_error( const char * const filename, const long long pos, + const bool isarchive ); int compress( const Cl_options & cl_opts ); // defined in create.cc @@ -524,18 +526,14 @@ bool writeblock_wrapper( const int outfd, const uint8_t * const buffer, bool write_eoa_records( const int outfd, const bool compressed ); const char * remove_leading_dotslash( const char * const filename, 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, +bool block_is_full( const int extended_size, const unsigned long long file_size, const unsigned long long target_size, unsigned long long & partial_data_size ); -void set_error_status( const int retval ); -int final_exit_status( int retval, const bool show_msg = true ); unsigned ustar_chksum( const Tar_header header ); -bool verify_ustar_chksum( const Tar_header header ); +bool check_ustar_chksum( const Tar_header header ); bool has_lz_ext( const std::string & name ); int concatenate( const Cl_options & cl_opts ); int encode( const Cl_options & cl_opts ); @@ -591,10 +589,10 @@ extern const char * const program_name; struct stat; int hstat( const char * const filename, struct stat * const st, const bool dereference ); +bool nonempty_arg( const Arg_parser & parser, const int i ); int open_instream( const std::string & name ); int open_outstream( const std::string & name, const bool create = true, Resizable_buffer * const rbufp = 0, const bool force = 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, |