diff options
Diffstat (limited to 'main.cc')
-rw-r--r-- | main.cc | 87 |
1 files changed, 43 insertions, 44 deletions
@@ -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; } |