summaryrefslogtreecommitdiffstats
path: root/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'main.cc')
-rw-r--r--main.cc87
1 files changed, 43 insertions, 44 deletions
diff --git a/main.cc b/main.cc
index 023729c..8004bd8 100644
--- a/main.cc
+++ b/main.cc
@@ -36,6 +36,7 @@
#include <string>
#include <vector>
#include <fcntl.h>
+#include <pthread.h> // pthread_t
#include <stdint.h> // SIZE_MAX
#include <unistd.h>
#include <utime.h>
@@ -104,8 +105,8 @@ enum Mode { m_none, m_alone_to_lz, m_byte_repair, m_check, m_debug_byte_repair,
m_nrep_stats, m_range_dec, m_remove, m_reproduce, m_show_packets,
m_split, m_strip, m_test, m_unzcrash_bit, m_unzcrash_block };
-/* Variable used in signal handler context.
- It is not declared volatile because the handler never returns. */
+/* Variables used in signal handler context.
+ They are not declared volatile because the handler never returns. */
bool delete_output_on_interrupt = false;
@@ -156,8 +157,6 @@ void show_help( const long num_online )
" --dump=<list>:d:e:t dump members, damaged/empty, tdata to stdout\n"
" --remove=<list>:d:e:t remove members, tdata from files in place\n"
" --strip=<list>:d:e:t copy files to stdout stripping members given\n"
- " --ignore-empty ignore empty members in multimember files\n"
- " --ignore-nonzero ignore a nonzero first LZMA byte\n"
" --loose-trailing allow trailing data seeming corrupt header\n"
" --nonzero-repair repair in place a nonzero first LZMA byte\n",
num_online );
@@ -228,7 +227,7 @@ const char * format_ds( const unsigned dictionary_size )
const char * p = "";
const char * np = " ";
unsigned num = dictionary_size;
- bool exact = ( num % factor == 0 );
+ bool exact = num % factor == 0;
for( int i = 0; i < n && ( num > 9999 || ( exact && num >= factor ) ); ++i )
{ num /= factor; if( num % factor != 0 ) exact = false;
@@ -263,12 +262,12 @@ void Member_list::parse_ml( const char * const arg,
if( len <= 7 && std::strncmp( "damaged", p, len ) == 0 )
{ damaged = true; cl_opts.ignore_errors = true; goto next; }
if( len <= 5 && std::strncmp( "empty", p, len ) == 0 )
- { empty = true; cl_opts.ignore_empty = true; goto next; }
+ { empty = true; goto next; }
if( len <= 5 && std::strncmp( "tdata", p, len ) == 0 )
{ tdata = true; cl_opts.ignore_trailing = true; goto next; }
}
{
- const bool reverse = ( *p == 'r' );
+ const bool reverse = *p == 'r';
if( reverse ) ++p;
if( *p == '^' ) { ++p; if( reverse ) rin = false; else in = false; }
std::vector< Block > * rvp = reverse ? &rrange_vector : &range_vector;
@@ -322,7 +321,7 @@ const char * parse_range( const char * const arg, const char * const pn,
range.pos( value );
if( tail[0] == 0 || tail[0] == ':' )
{ range.size( INT64_MAX - value ); return tail; }
- const bool is_size = ( tail[0] == ',' );
+ const bool is_size = tail[0] == ',';
if( sector_sizep && tail[1] == ',' ) { value = INT64_MAX - value; ++tail; }
else value = getnum( tail + 1, pn, 0, 1, INT64_MAX, &tail ); // size
if( !is_size && value <= range.pos() )
@@ -390,6 +389,12 @@ void parse_range_vector( const char * const arg, const char * const pn,
}
+void no_to_stdout( const bool to_stdout )
+ {
+ if( to_stdout )
+ { show_error( "'--stdout' not allowed." ); std::exit( 1 ); }
+ }
+
void one_file( const int files )
{
if( files != 1 )
@@ -562,9 +567,9 @@ int open_instream( const char * const name, struct stat * const in_statsp,
{
const int i = fstat( infd, in_statsp );
const mode_t mode = in_statsp->st_mode;
- const bool can_read = ( i == 0 && !reg_only &&
- ( S_ISBLK( mode ) || S_ISCHR( mode ) ||
- S_ISFIFO( mode ) || S_ISSOCK( mode ) ) );
+ const bool can_read = i == 0 && !reg_only &&
+ ( S_ISBLK( mode ) || S_ISCHR( mode ) ||
+ S_ISFIFO( mode ) || S_ISSOCK( mode ) );
if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) )
{
if( verbosity >= 0 )
@@ -677,8 +682,8 @@ void set_signals( void (*action)(int) )
void cleanup_and_fail( const int retval )
{
- cleanup_mutex_lock(); // only one thread can delete and exit
set_signals( SIG_IGN ); // ignore signals
+ cleanup_mutex_lock(); // only one thread can delete and exit
if( delete_output_on_interrupt )
{
delete_output_on_interrupt = false;
@@ -795,12 +800,12 @@ bool show_trailing_data( const uint8_t * const data, const int size,
int decompress( const unsigned long long cfile_size, const int infd,
const Cl_options & cl_opts, const Pretty_print & pp,
- const bool testing )
+ const bool from_stdin, const bool testing )
{
unsigned long long partial_file_pos = 0;
Range_decoder rdec( infd );
int retval = 0;
- bool empty = false, nonempty = false;
+ bool empty = false, multi = false;
for( bool first_member = true; ; first_member = false )
{
@@ -843,11 +848,10 @@ int decompress( const unsigned long long cfile_size, const int infd,
LZ_decoder decoder( rdec, dictionary_size, outfd );
show_dprogress( cfile_size, partial_file_pos, &rdec, &pp ); // init
- const int result = decoder.decode_member( pp, cl_opts.ignore_nonzero );
+ const int result = decoder.decode_member( pp, cl_opts.ignore_errors );
partial_file_pos += rdec.member_position();
if( result != 0 )
{
- retval = 2;
if( verbosity >= 0 && result <= 2 )
{
pp();
@@ -855,19 +859,20 @@ int decompress( const unsigned long long cfile_size, const int infd,
"File ends unexpectedly" : "Decoder error",
partial_file_pos );
}
- else if( result == 5 ) { pp( nonzero_msg ); break; }
+ else if( result == 5 ) pp( nonzero_msg );
+ retval = 2;
if( cl_opts.ignore_errors ) { pp.reset(); continue; } else break;
}
- if( !cl_opts.ignore_empty )
- { if( decoder.data_position() == 0 ) empty = true; else nonempty = true; }
+ if( !from_stdin && !cl_opts.ignore_errors ) { multi = !first_member;
+ if( decoder.data_position() == 0 ) empty = true; }
if( verbosity >= 2 )
{ std::fputs( testing ? "ok\n" : "done\n", stderr ); pp.reset(); }
}
if( verbosity == 1 && retval == 0 )
std::fputs( testing ? "ok\n" : "done\n", stderr );
- if( retval == 2 && cl_opts.ignore_errors ) retval = 0;
- if( empty && nonempty && retval == 0 )
+ if( empty && multi && retval == 0 )
{ show_file_error( pp.name(), empty_msg ); retval = 2; }
+ if( retval == 2 && cl_opts.ignore_errors ) retval = 0;
return retval;
}
@@ -972,8 +977,8 @@ int main( const int argc, const char * const argv[] )
bool to_stdout = false;
if( argc > 0 ) invocation_name = argv[0];
- enum { opt_chk = 256, opt_dbg, opt_du, opt_ff, opt_g16, opt_ie, opt_inz,
- opt_lt, opt_lzl, opt_lzn, opt_nzr, opt_ref, opt_rem, opt_rnd, opt_st };
+ enum { opt_chk = 256, opt_dbg, opt_du, opt_ff, opt_g16, opt_lt,
+ opt_lzl, opt_lzn, opt_nzr, opt_ref, opt_rem, opt_rnd, opt_st };
const Arg_parser::Option options[] =
{
{ '0', 0, Arg_parser::no },
@@ -1024,8 +1029,6 @@ int main( const int argc, const char * const argv[] )
{ opt_du, "dump", Arg_parser::yes },
{ opt_ff, "fec-file", Arg_parser::yes },
{ opt_g16, "gf16", Arg_parser::no },
- { opt_ie, "ignore-empty", Arg_parser::no },
- { opt_inz, "ignore-nonzero", Arg_parser::no },
{ opt_lt, "loose-trailing", Arg_parser::no },
{ opt_lzl, "lzip-level", Arg_parser::yes },
{ opt_lzn, "lzip-name", Arg_parser::yes },
@@ -1106,8 +1109,6 @@ int main( const int argc, const char * const argv[] )
member_list.parse_ml( arg, pn, cl_opts ); break;
case opt_ff: cl_fec_filename = sarg; break;
case opt_g16: cl_gf16 = true; break;
- case opt_ie: cl_opts.ignore_empty = true; break;
- case opt_inz: cl_opts.ignore_nonzero = true; break;
case opt_lt: cl_opts.loose_trailing = true; break;
case opt_lzl: lzip_level = parse_lzip_level( arg, pn ); break;
case opt_lzn: lzip_name = arg; break;
@@ -1132,9 +1133,6 @@ int main( const int argc, const char * const argv[] )
show_error( "You must specify the operation to be performed.", 0, true );
return 1;
}
- if( program_mode != m_decompress && program_mode != m_list &&
- program_mode != m_test && program_mode != m_range_dec )
- cl_opts.ignore_empty = true;
std::vector< std::string > filenames;
bool filenames_given = false;
@@ -1151,20 +1149,19 @@ int main( const int argc, const char * const argv[] )
case m_none: internal_error( "invalid operation." ); break;
case m_alone_to_lz: break;
case m_byte_repair:
- one_file( filenames.size() );
+ one_file( filenames.size() ); no_to_stdout( to_stdout );
return byte_repair( filenames[0], default_output_filename, cl_opts,
terminator, force );
case m_check: return gf_check( cblocks, cl_gf16, fec_random );
case m_debug_byte_repair:
one_file( filenames.size() );
- return debug_byte_repair( filenames[0].c_str(), cl_opts, bad_byte,
- terminator );
+ return debug_byte_repair( filenames[0], cl_opts, bad_byte, terminator );
case m_debug_decompress:
one_file( filenames.size() );
- return debug_decompress( filenames[0].c_str(), cl_opts, bad_byte, false );
+ return debug_decompress( filenames[0], cl_opts, bad_byte, false );
case m_debug_delay:
one_file( filenames.size() );
- return debug_delay( filenames[0].c_str(), cl_opts, range, terminator );
+ return debug_delay( filenames[0], cl_opts, range, terminator );
case m_decompress: break;
case m_dump:
case m_strip:
@@ -1197,7 +1194,7 @@ int main( const int argc, const char * const argv[] )
return fec_dZ( filenames[0], cl_fec_filename, delta, sector_size );
case m_list: break;
case m_md5sum: break;
- case m_merge:
+ case m_merge: no_to_stdout( to_stdout );
if( filenames.size() < 2 )
{ show_error( "You must specify at least 2 files.", 0, true ); return 1; }
return merge_files( filenames, default_output_filename, cl_opts,
@@ -1215,28 +1212,28 @@ int main( const int argc, const char * const argv[] )
at_least_one_file( filenames.size() );
return remove_members( filenames, cl_opts, member_list );
case m_reproduce:
- one_file( filenames.size() );
+ one_file( filenames.size() ); no_to_stdout( to_stdout );
if( !reference_filename || !reference_filename[0] )
{ show_error( "You must specify a reference file.", 0, true ); return 1; }
if( range.size() > 0 )
- return debug_reproduce_file( filenames[0].c_str(), lzip_name,
+ return debug_reproduce_file( filenames[0], lzip_name,
reference_filename, cl_opts, range, sector_size, lzip_level );
else
return reproduce_file( filenames[0], default_output_filename, lzip_name,
reference_filename, cl_opts, lzip_level, terminator, force );
case m_show_packets:
one_file( filenames.size() );
- return debug_decompress( filenames[0].c_str(), cl_opts, bad_byte, true );
+ return debug_decompress( filenames[0], cl_opts, bad_byte, true );
case m_split:
- one_file( filenames.size() );
+ one_file( filenames.size() ); no_to_stdout( to_stdout );
return split_file( filenames[0], default_output_filename, cl_opts, force );
case m_test: break;
case m_unzcrash_bit:
one_file( filenames.size() );
- return lunzcrash_bit( filenames[0].c_str(), cl_opts );
+ return lunzcrash_bit( filenames[0], cl_opts );
case m_unzcrash_block:
one_file( filenames.size() );
- return lunzcrash_block( filenames[0].c_str(), cl_opts, sector_size );
+ return lunzcrash_block( filenames[0], cl_opts, sector_size );
}
}
catch( std::bad_alloc & ) { show_error( mem_msg ); cleanup_and_fail( 1 ); }
@@ -1274,9 +1271,10 @@ int main( const int argc, const char * const argv[] )
{
std::string input_filename;
int infd;
+ const bool from_stdin = filenames[i] == "-";
pp.set_name( filenames[i] );
- if( filenames[i] == "-" )
+ if( from_stdin )
{
if( stdin_used ) continue; else stdin_used = true;
infd = STDIN_FILENO;
@@ -1318,7 +1316,8 @@ int main( const int argc, const char * const argv[] )
if( program_mode == m_alone_to_lz )
tmp = alone_to_lz( infd, pp );
else
- tmp = decompress( cfile_size, infd, cl_opts, pp, program_mode == m_test );
+ tmp = decompress( cfile_size, infd, cl_opts, pp, from_stdin,
+ program_mode == m_test );
}
catch( std::bad_alloc & ) { pp( mem_msg ); tmp = 1; }
catch( Error & e ) { pp(); show_error( e.msg, errno ); tmp = 1; }