summaryrefslogtreecommitdiffstats
path: root/tarlz.h
diff options
context:
space:
mode:
Diffstat (limited to 'tarlz.h')
-rw-r--r--tarlz.h231
1 files changed, 123 insertions, 108 deletions
diff --git a/tarlz.h b/tarlz.h
index 8b0a0ad..e9371ec 100644
--- a/tarlz.h
+++ b/tarlz.h
@@ -1,18 +1,18 @@
-/* Tarlz - Archiver with multimember lzip compression
- Copyright (C) 2013-2019 Antonio Diaz Diaz.
+/* Tarlz - Archiver with multimember lzip compression
+ Copyright (C) 2013-2020 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
- the Free Software Foundation, either version 2 of the License, or
- (at your option) any later version.
+ 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
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define max_file_size ( LLONG_MAX - header_size )
@@ -157,6 +157,50 @@ public:
};
+class CRC32
+ {
+ uint32_t data[256]; // Table of CRCs of all 8-bit messages.
+
+public:
+ CRC32( const bool castagnoli = false )
+ {
+ const unsigned cpol = 0x82F63B78U; // CRC32-C Castagnoli polynomial.
+ const unsigned ipol = 0xEDB88320U; // IEEE 802.3 Ethernet polynomial.
+ const unsigned poly = castagnoli ? cpol : ipol;
+
+ for( unsigned n = 0; n < 256; ++n )
+ {
+ unsigned c = n;
+ for( int k = 0; k < 8; ++k )
+ { if( c & 1 ) c = poly ^ ( c >> 1 ); else c >>= 1; }
+ data[n] = c;
+ }
+ }
+
+ void update_byte( uint32_t & crc, const uint8_t byte ) const
+ { crc = data[(crc^byte)&0xFF] ^ ( crc >> 8 ); }
+
+ void update_buf( uint32_t & crc, const uint8_t * const buffer,
+ const int size ) const
+ {
+ uint32_t c = crc;
+ for( int i = 0; i < size; ++i )
+ c = data[(c^buffer[i])&0xFF] ^ ( c >> 8 );
+ crc = c;
+ }
+
+ // Calculates the crc of size bytes except a window of 8 bytes at pos
+ uint32_t windowed_crc( const uint8_t * const buffer, const int pos,
+ const int size ) const
+ {
+ uint32_t crc = 0xFFFFFFFFU;
+ update_buf( crc, buffer, pos );
+ update_buf( crc, buffer + pos + 8, size - pos - 8 );
+ return crc ^ 0xFFFFFFFFU;
+ }
+ };
+
+
enum {
min_dictionary_bits = 12,
min_dictionary_size = 1 << min_dictionary_bits,
@@ -178,7 +222,7 @@ struct Lzip_header
{
uint8_t data[6]; // 0-3 magic bytes
// 4 version
- // 5 coded_dict_size
+ // 5 coded dictionary size
enum { size = 6 };
bool verify_magic() const
@@ -208,6 +252,10 @@ struct Lzip_header
sz -= ( sz / 16 ) * ( ( data[5] >> 5 ) & 7 );
return sz;
}
+
+ bool verify() const
+ { return verify_magic() && verify_version() &&
+ isvalid_ds( dictionary_size() ); }
};
@@ -255,50 +303,41 @@ struct Lzip_trailer
};
-class CRC32
+enum Program_mode { m_none, m_append, 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
{
- uint32_t data[256]; // Table of CRCs of all 8-bit messages.
-
-public:
- CRC32( const bool castagnoli = false )
- {
- const unsigned cpol = 0x82F63B78U; // CRC32-C Castagnoli polynomial.
- const unsigned ipol = 0xEDB88320U; // IEEE 802.3 Ethernet polynomial.
- const unsigned poly = castagnoli ? cpol : ipol;
-
- for( unsigned n = 0; n < 256; ++n )
- {
- unsigned c = n;
- for( int k = 0; k < 8; ++k )
- { if( c & 1 ) c = poly ^ ( c >> 1 ); else c >>= 1; }
- data[n] = c;
- }
- }
-
- void update_byte( uint32_t & crc, const uint8_t byte ) const
- { crc = data[(crc^byte)&0xFF] ^ ( crc >> 8 ); }
-
- void update_buf( uint32_t & crc, const uint8_t * const buffer,
- const int size ) const
- {
- uint32_t c = crc;
- for( int i = 0; i < size; ++i )
- c = data[(c^buffer[i])&0xFF] ^ ( c >> 8 );
- crc = c;
- }
-
- // Calculates the crc of size bytes except a window of 8 bytes at pos
- uint32_t windowed_crc( const uint8_t * const buffer, const int pos,
- const int size ) const
- {
- uint32_t crc = 0xFFFFFFFFU;
- update_buf( crc, buffer, pos );
- update_buf( crc, buffer + pos + 8, size - pos - 8 );
- return crc ^ 0xFFFFFFFFU;
- }
+ const Arg_parser & parser;
+ std::string archive_name;
+ long long mtime;
+ Program_mode program_mode;
+ Solidity solidity;
+ int data_size;
+ int debug_level;
+ int filenames;
+ int level; // compression level, < 0 means uncompressed
+ int num_workers; // start this many worker threads
+ int out_slots;
+ int owner;
+ int group;
+ bool dereference;
+ bool ignore_ids;
+ bool keep_damaged;
+ bool missing_crc;
+ bool permissive;
+ bool preserve_permissions;
+
+ Cl_options( const Arg_parser & ap )
+ : parser( ap ), mtime( -1 ), program_mode( m_none ), solidity( bsolid ),
+ data_size( 0 ), debug_level( 0 ), filenames( 0 ), level( 6 ),
+ num_workers( -1 ), out_slots( 64 ), owner( -1 ), group( -1 ),
+ dereference( false ), ignore_ids( false ), keep_damaged( false ),
+ missing_crc( false ), permissive( false ), preserve_permissions( false )
+ {}
};
-extern const CRC32 crc32c;
const char * const bad_magic_msg = "Bad magic number (file not in lzip format).";
const char * const bad_dict_msg = "Invalid dictionary size in member header.";
@@ -330,24 +369,19 @@ 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
-class Arg_parser;
bool block_is_zero( const uint8_t * const buf, const int size );
bool format_member_name( const Extended & extended, const Tar_header header,
Resizable_buffer & rbuf, const bool long_format );
bool show_member_name( const Extended & extended, const Tar_header header,
const int vlevel, Resizable_buffer & rbuf );
-bool check_skip_filename( const Arg_parser & parser,
+bool check_skip_filename( const Cl_options & cl_opts,
std::vector< char > & name_pending,
- const char * const filename, const int filenames );
+ const char * const filename );
// defined in create.cc
-enum Solidity { no_solid, bsolid, dsolid, asolid, solid };
-extern int cl_owner;
-extern int cl_group;
-extern int cl_data_size;
-extern Solidity solidity;
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 );
@@ -364,18 +398,13 @@ int final_exit_status( int retval, const bool show_msg = true );
unsigned ustar_chksum( const uint8_t * const header );
bool verify_ustar_chksum( const uint8_t * const header );
bool has_lz_ext( const std::string & name );
-int concatenate( const std::string & archive_name, const Arg_parser & parser,
- const int filenames );
-int encode( const std::string & archive_name, const Arg_parser & parser,
- const int filenames, const int level, const int num_workers,
- const int out_slots, const int debug_level, const bool append,
- const bool dereference );
+int concatenate( const Cl_options & cl_opts );
+int encode( Cl_options & cl_opts );
// defined in create_lz.cc
-int encode_lz( const char * const archive_namep, const Arg_parser & parser,
+int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
const int dictionary_size, const int match_len_limit,
- const int num_workers, const int outfd, const int out_slots,
- const int debug_level, const bool dereference );
+ const int outfd );
// defined in delete.cc
class Lzip_index;
@@ -384,17 +413,14 @@ int tail_copy( const char * const archive_namep, const Arg_parser & parser,
std::vector< char > & name_pending,
const Lzip_index & lzip_index, const long long istream_pos,
const int infd, const int outfd, int retval );
-int delete_members( const std::string & archive_name, const Arg_parser & parser,
- const int filenames, const bool missing_crc,
- const bool permissive );
+int delete_members( const Cl_options & cl_opts );
// defined in delete_lz.cc
-int delete_members_lz( const char * const archive_namep,
- const Arg_parser & parser,
+int delete_members_lz( const Cl_options & cl_opts,
+ const char * const archive_namep,
std::vector< char > & name_pending,
const Lzip_index & lzip_index,
- const int filenames, const int infd, const int outfd,
- const bool missing_crc, const bool permissive );
+ const int infd, const int outfd );
// defined in exclude.cc
namespace Exclude {
@@ -403,35 +429,21 @@ bool excluded( const char * const filename );
} // end namespace Exclude
// defined in extract.cc
-enum Program_mode { m_none, m_append, m_concatenate, m_create, m_delete,
- m_diff, m_extract, m_list };
-int decode( const std::string & archive_name, const Arg_parser & parser,
- const int filenames, const int num_workers, const int debug_level,
- const Program_mode program_mode, const bool ignore_ids,
- const bool keep_damaged, const bool missing_crc,
- const bool permissive );
-
-// defined in list_lz.cc
-struct LZ_Decoder;
-int archive_read_lz( LZ_Decoder * const decoder, const int infd,
- long long & file_pos, const long long member_end,
- const long long cdata_size, uint8_t * const buf,
- const int size, const char ** msg );
-int parse_records_lz( LZ_Decoder * const decoder, const int infd,
- long long & file_pos, const long long member_end,
- const long long cdata_size, long long & data_pos,
- Extended & extended, const Tar_header header,
- Resizable_buffer & rbuf, const char ** msg,
- const bool permissive );
-int skip_member_lz( LZ_Decoder * const decoder, const int infd,
- long long & file_pos, const long long member_end,
- const long long cdata_size, long long & data_pos,
- long long rest, const char ** msg );
-int list_lz( const char * const archive_namep, const Arg_parser & parser,
- std::vector< char > & name_pending, const Lzip_index & lzip_index,
- const int filenames, const int debug_level, const int infd,
- const int num_workers, const bool missing_crc,
- const bool permissive );
+bool compare_file_type( std::string & estr, std::string & ostr,
+ const Cl_options & cl_opts,
+ const Extended & extended, const Tar_header header );
+class Archive_reader_base;
+bool compare_file_contents( std::string & estr, std::string & ostr,
+ Archive_reader_base & ar, const long long file_size,
+ const char * const filename, const int infd2 );
+int decode( const Cl_options & cl_opts );
+
+// defined in decode_lz.cc
+int preadblock( const int fd, uint8_t * const buf, const int size,
+ const long long pos );
+struct Archive_descriptor;
+int decode_lz( const Cl_options & cl_opts, const Archive_descriptor & ad,
+ std::vector< char > & name_pending );
// defined in lzip_index.cc
int seek_read( const int fd, uint8_t * const buf, const int size,
@@ -440,12 +452,15 @@ int seek_read( const int fd, uint8_t * const buf, const int size,
// defined in main.cc
extern int verbosity;
struct stat;
-int hstat( const char * const filename, struct stat * const st );
+int hstat( const char * const filename, struct stat * const st,
+ const bool dereference );
int open_instream( const std::string & name );
int open_outstream( const std::string & name, const bool create = true );
void cleanup_and_fail( const int retval = 1 ); // terminate the program
void show_error( const char * const msg, const int errcode = 0,
const bool help = false );
+void format_file_error( std::string & estr, 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 );