summaryrefslogtreecommitdiffstats
path: root/tarlz.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-01-23 05:08:19 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-01-23 05:08:19 +0000
commitcb1387c92038634c063ee06a24e249b87525f519 (patch)
treeaeebf76566be407c42678fff1c2482ee9dc8fe17 /tarlz.h
parentReleasing debian version 0.23-3. (diff)
downloadtarlz-cb1387c92038634c063ee06a24e249b87525f519.tar.xz
tarlz-cb1387c92038634c063ee06a24e249b87525f519.zip
Merging upstream version 0.25.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tarlz.h')
-rw-r--r--tarlz.h121
1 files changed, 60 insertions, 61 deletions
diff --git a/tarlz.h b/tarlz.h
index 2da81dd..16ae6e0 100644
--- a/tarlz.h
+++ b/tarlz.h
@@ -1,5 +1,5 @@
/* Tarlz - Archiver with multimember lzip compression
- Copyright (C) 2013-2022 Antonio Diaz Diaz.
+ Copyright (C) 2013-2024 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();
@@ -421,7 +419,7 @@ enum Program_mode { m_none, m_append, m_compress, m_concatenate, m_create,
enum Solidity { no_solid, bsolid, dsolid, asolid, solid };
class Arg_parser;
-struct Cl_options // command line options
+struct Cl_options // command-line options
{
const Arg_parser & parser;
std::string archive_name;
@@ -440,8 +438,10 @@ struct Cl_options // command line options
bool dereference;
bool filenames_given;
bool ignore_ids;
+ bool ignore_metadata;
bool ignore_overflow;
bool keep_damaged;
+ bool level_set; // compression level set in command line
bool missing_crc;
bool mtime_set;
bool permissive;
@@ -452,10 +452,15 @@ struct Cl_options // command line options
: 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 ) {}
+ filenames_given( false ), ignore_ids( false ), ignore_metadata( false ),
+ ignore_overflow( 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 == "-"; }
};
@@ -465,7 +470,6 @@ inline void set_retval( int & retval, const int new_val )
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.";
const char * const corrupt_mm_msg = "Corrupt header in multimember file.";
-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.";
@@ -486,21 +490,12 @@ 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";
+const char * const intdir_msg = "Failed to create intermediate 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 +505,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();
-bool make_path( const std::string & name );
+ const char * const filename, const int chdir_fd = -1 );
+bool make_dirs( 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 +527,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 +590,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,