diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-09-21 06:58:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-09-21 06:58:44 +0000 |
commit | dbbdc02b322480ee799107d2cfa317533008e6c8 (patch) | |
tree | a22c11b459ba27df42ea3427d8b48f7873110104 /main.cc | |
parent | Adding upstream version 0.23. (diff) | |
download | tarlz-dbbdc02b322480ee799107d2cfa317533008e6c8.tar.xz tarlz-dbbdc02b322480ee799107d2cfa317533008e6c8.zip |
Adding upstream version 0.24.upstream/0.24
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'main.cc')
-rw-r--r-- | main.cc | 58 |
1 files changed, 25 insertions, 33 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 @@ -27,10 +27,9 @@ #include <cerrno> #include <cstdarg> #include <cstdio> -#include <cstdlib> #include <ctime> #include <fcntl.h> -#include <pthread.h> +#include <pthread.h> // for pthread_t #include <stdint.h> // for lzlib.h #include <unistd.h> #include <sys/stat.h> @@ -57,7 +56,7 @@ const char * const program_name = "tarlz"; namespace { -const char * const program_year = "2022"; +const char * const program_year = "2023"; const char * invocation_name = program_name; // default value @@ -101,7 +100,7 @@ void show_help( const long num_online ) " -f, --file=<archive> use archive file <archive>\n" " -h, --dereference follow symlinks; archive the files they point to\n" " -n, --threads=<n> set number of (de)compression threads [%ld]\n" - " -o, --output=<file> compress to <file>\n" + " -o, --output=<file> compress to <file> ('-' for stdout)\n" " -p, --preserve-permissions don't subtract the umask on extraction\n" " -q, --quiet suppress all messages\n" " -v, --verbose verbosely list files processed\n" @@ -209,11 +208,11 @@ int check_lib() } -// separate numbers of 6 or more digits in groups of 3 digits using '_' +// separate numbers of 5 or more digits in groups of 3 digits using '_' const char * format_num3( long long num ) { - const char * const si_prefix = "kMGTPEZY"; - const char * const binary_prefix = "KMGTPEZY"; + const char * const si_prefix = "kMGTPEZYRQ"; + const char * const binary_prefix = "KMGTPEZYRQ"; enum { buffers = 8, bufsize = 4 * sizeof num }; static char buffer[buffers][bufsize]; // circle of static buffers for printf static int current = 0; @@ -230,12 +229,12 @@ const char * format_num3( long long num ) for( int i = 0; i < 8 && num != 0 && ( num / 1000 ) * 1000 == num; ++i ) { num /= 1000; prefix = si_prefix[i]; } if( prefix ) *(--p) = prefix; - const bool split = num >= 100000 || num <= -100000; + const bool split = num >= 10000 || num <= -10000; for( int i = 0; ; ) { - long long onum = num; num /= 10; - *(--p) = llabs( onum - 10 * num ) + '0'; if( num == 0 ) break; + const long long onum = num; num /= 10; + *(--p) = llabs( onum - ( 10 * num ) ) + '0'; if( num == 0 ) break; if( split && ++i >= 3 ) { i = 0; *(--p) = '_'; } } if( negative ) *(--p) = '-'; @@ -252,6 +251,8 @@ void show_option_error( const char * const arg, const char * const msg, } +// Recognized formats: <num>[QRYZEPTGM][i], <num>k, <num>Ki +// long long getnum( const char * const arg, const char * const option_name, const long long llimit = LLONG_MIN, const long long ulimit = LLONG_MAX ) @@ -269,6 +270,8 @@ long long getnum( const char * const arg, const char * const option_name, int exponent = 0; // 0 = bad multiplier switch( tail[0] ) { + case 'Q': exponent = 10; break; + case 'R': exponent = 9; break; case 'Y': exponent = 8; break; case 'Z': exponent = 7; break; case 'E': exponent = 6; break; @@ -327,7 +330,7 @@ void set_mode( Program_mode & program_mode, const Program_mode new_mode ) // parse time as 'long long' even if time_t is 32-bit long long parse_mtime( const char * arg, const char * const pn ) { - if( *arg == '@' ) return getnum( arg + 1, pn ); + if( *arg == '@' ) return getnum( arg + 1, pn ); // seconds since the epoch else if( *arg == '.' || *arg == '/' ) { struct stat st; @@ -389,6 +392,10 @@ int hstat( const char * const filename, struct stat * const st, { return dereference ? stat( filename, st ) : lstat( filename, st ); } +bool nonempty_arg( const Arg_parser & parser, const int i ) + { return ( parser.code( i ) == 0 && !parser.argument( i ).empty() ); } + + int open_instream( const std::string & name ) { const int infd = open( name.c_str(), O_RDONLY | O_BINARY ); @@ -422,20 +429,6 @@ int open_outstream( const std::string & name, const bool create, } -/* This can be called from any thread, main thread or sub-threads alike, - since they all call common helper functions that call exit_fail_mt() - in case of an error. -*/ -void exit_fail_mt( const int retval ) - { - // calling 'exit' more than once results in undefined behavior - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - - pthread_mutex_lock( &mutex ); // ignore errors to avoid loop - std::exit( retval ); - } - - void show_error( const char * const msg, const int errcode, const bool help ) { if( verbosity < 0 ) return; @@ -617,7 +610,7 @@ int main( const int argc, const char * const argv[] ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - cl_opts.level = code - '0'; break; + cl_opts.set_level( code - '0' ); break; case 'A': set_mode( cl_opts.program_mode, m_concatenate ); break; case 'B': cl_opts.data_size = getnum( arg, pn, min_data_size, max_data_size ); break; @@ -659,7 +652,7 @@ int main( const int argc, const char * const argv[] ) case opt_own: cl_opts.uid = parse_owner( arg, pn ); break; case opt_per: cl_opts.permissive = true; break; case opt_sol: cl_opts.solidity = solid; break; - case opt_un: cl_opts.level = -1; break; + case opt_un: cl_opts.set_level( -1 ); break; case opt_wn: cl_opts.warn_newer = true; break; default : internal_error( "uncaught option" ); } @@ -679,8 +672,7 @@ int main( const int argc, const char * const argv[] ) program_name, f_pn, z_pn ); return 1; } - if( cl_opts.program_mode == m_compress && - ( cl_opts.level < 0 || cl_opts.level > 9 ) ) + if( cl_opts.program_mode == m_compress && cl_opts.uncompressed() ) { if( verbosity >= 0 ) std::fprintf( stderr, "%s: Option '--uncompressed' can't be used with '%s'.\n", @@ -700,7 +692,7 @@ int main( const int argc, const char * const argv[] ) setmode( STDOUT_FILENO, O_BINARY ); #endif - if( cl_opts.data_size <= 0 && cl_opts.level >= 0 && cl_opts.level <= 9 ) + if( cl_opts.data_size <= 0 && !cl_opts.uncompressed() ) { if( cl_opts.level == 0 ) cl_opts.data_size = 1 << 20; else cl_opts.data_size = 2 * option_mapping[cl_opts.level].dictionary_size; @@ -715,9 +707,9 @@ int main( const int argc, const char * const argv[] ) case m_create: return encode( cl_opts ); case m_compress: return compress( cl_opts ); case m_concatenate: return concatenate( cl_opts ); - case m_delete: return delete_members( cl_opts ); + case m_delete: tzset(); return delete_members( cl_opts ); case m_diff: case m_extract: - case m_list: return decode( cl_opts ); + case m_list: tzset(); return decode( cl_opts ); } } |