Adding upstream version 1.13~rc2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
89ca1f7591
commit
7fe0f13dd3
17 changed files with 679 additions and 132 deletions
143
main.cc
143
main.cc
|
@ -71,8 +71,8 @@ struct { const char * from; const char * to; } const known_extensions[] = {
|
|||
{ ".tlz", ".tar" },
|
||||
{ 0, 0 } };
|
||||
|
||||
enum Mode { m_none, m_decompress, m_generate, m_merge, m_recover, m_repair,
|
||||
m_split, m_test, m_update };
|
||||
enum Mode { m_none, m_decompress, m_generate, m_list, m_merge, m_range,
|
||||
m_recover, m_repair, m_split, m_test, m_update };
|
||||
|
||||
std::string output_filename;
|
||||
int outfd = -1;
|
||||
|
@ -87,22 +87,26 @@ void show_help() throw()
|
|||
std::printf( "%s - Data recovery tool and decompressor for lzipped files.\n", Program_name );
|
||||
std::printf( "\nUsage: %s [options] [files]\n", invocation_name );
|
||||
std::printf( "\nOptions:\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n"
|
||||
" -c, --stdout send decompressed output to standard output\n"
|
||||
" -d, --decompress decompress\n"
|
||||
" -f, --force overwrite existing output files\n"
|
||||
// " -g, --generate-recover-file generate a recover file\n"
|
||||
" -k, --keep keep (don't delete) input files\n"
|
||||
" -m, --merge correct errors in file using several copies\n"
|
||||
" -o, --output=<file> place the output into <file>\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
// " -r, --recover correct errors in file using a recover file\n"
|
||||
" -R, --repair try to repair a small error in file\n"
|
||||
" -s, --split split a multimember file in single-member files\n"
|
||||
" -t, --test test compressed file integrity\n"
|
||||
// " -u, --update convert file from version 0 to version 1\n"
|
||||
" -v, --verbose be verbose (a 2nd -v gives more)\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n"
|
||||
" -c, --stdout send decompressed output to standard output\n"
|
||||
" -d, --decompress decompress\n"
|
||||
" -D, --range-decompress=<range> decompress only a range of bytes (N-M)\n"
|
||||
" -f, --force overwrite existing output files\n"
|
||||
// " -g, --generate-recover-file generate a recover file\n"
|
||||
" -k, --keep keep (don't delete) input files\n"
|
||||
" -l, --list print total file sizes and ratios\n"
|
||||
" -m, --merge correct errors in file using several copies\n"
|
||||
" -o, --output=<file> place the output into <file>\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
// " -r, --recover correct errors in file using a recover file\n"
|
||||
" -R, --repair try to repair a small error in file\n"
|
||||
" -s, --split split multimember file in single-member files\n"
|
||||
" -t, --test test compressed file integrity\n"
|
||||
// " -u, --update convert file from version 0 to version 1\n"
|
||||
" -v, --verbose be verbose (a 2nd -v gives more)\n"
|
||||
"Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n"
|
||||
"Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n"
|
||||
"\nReport bugs to lzip-bug@nongnu.org\n"
|
||||
"Lziprecover home page: http://www.nongnu.org/lzip/lziprecover.html\n" );
|
||||
}
|
||||
|
@ -118,20 +122,13 @@ void show_version() throw()
|
|||
}
|
||||
|
||||
|
||||
const char * format_num( long long num ) throw()
|
||||
void one_file( const int argind, const int arguments ) throw()
|
||||
{
|
||||
const char * const prefix[8] =
|
||||
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
|
||||
enum { buf_size = 16, factor = 1024 };
|
||||
static char buf[buf_size];
|
||||
const char *p = "";
|
||||
bool exact = ( num % factor == 0 );
|
||||
|
||||
for( int i = 0; i < 8 && ( llabs( num ) > 9999 ||
|
||||
( exact && llabs( num ) >= factor ) ); ++i )
|
||||
{ num /= factor; if( num % factor != 0 ) exact = false; p = prefix[i]; }
|
||||
snprintf( buf, buf_size, "%lld %s", num, p );
|
||||
return buf;
|
||||
if( argind + 1 != arguments )
|
||||
{
|
||||
show_error( "You must specify exactly 1 file.", 0, true );
|
||||
std::exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -345,7 +342,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
|
|||
if( verbosity >= 2 )
|
||||
std::fprintf( stderr, "version %d, dictionary size %7sB. ",
|
||||
header.version(),
|
||||
format_num( header.dictionary_size() ) );
|
||||
format_num( header.dictionary_size(), 9999, -1 ) );
|
||||
}
|
||||
LZ_decoder decoder( header, rdec, outfd );
|
||||
|
||||
|
@ -403,6 +400,30 @@ void set_signals() throw()
|
|||
int verbosity = 0;
|
||||
|
||||
|
||||
const char * format_num( long long num, long long limit,
|
||||
const int set_prefix ) throw()
|
||||
{
|
||||
const char * const si_prefix[8] =
|
||||
{ "k", "M", "G", "T", "P", "E", "Z", "Y" };
|
||||
const char * const binary_prefix[8] =
|
||||
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
|
||||
static bool si = true;
|
||||
static char buf[32];
|
||||
|
||||
if( set_prefix ) si = ( set_prefix > 0 );
|
||||
const int factor = ( si ? 1000 : 1024 );
|
||||
const char * const * prefix = ( si ? si_prefix : binary_prefix );
|
||||
const char * p = "";
|
||||
bool exact = ( num % factor == 0 );
|
||||
|
||||
for( int i = 0; i < 8 && ( llabs( num ) > limit ||
|
||||
( exact && llabs( num ) >= factor ) ); ++i )
|
||||
{ num /= factor; if( num % factor != 0 ) exact = false; p = prefix[i]; }
|
||||
snprintf( buf, sizeof buf, "%lld %s", num, p );
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int open_instream( const std::string & name, struct stat * const in_statsp,
|
||||
const bool to_stdout, const bool reg_only ) throw()
|
||||
{
|
||||
|
@ -491,25 +512,28 @@ int main( const int argc, const char * const argv[] )
|
|||
bool to_stdout = false;
|
||||
std::string input_filename;
|
||||
std::string default_output_filename;
|
||||
std::string range_string;
|
||||
std::vector< std::string > filenames;
|
||||
invocation_name = argv[0];
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
{ 'c', "stdout", Arg_parser::no },
|
||||
{ 'd', "decompress", Arg_parser::no },
|
||||
{ 'f', "force", Arg_parser::no },
|
||||
{ 'h', "help", Arg_parser::no },
|
||||
{ 'k', "keep", Arg_parser::no },
|
||||
{ 'm', "merge", Arg_parser::no },
|
||||
{ 'o', "output", Arg_parser::yes },
|
||||
{ 'q', "quiet", Arg_parser::no },
|
||||
{ 'R', "repair", Arg_parser::no },
|
||||
{ 's', "split", Arg_parser::no },
|
||||
{ 't', "test", Arg_parser::no },
|
||||
{ 'v', "verbose", Arg_parser::no },
|
||||
{ 'V', "version", Arg_parser::no },
|
||||
{ 0 , 0, Arg_parser::no } };
|
||||
{ 'c', "stdout", Arg_parser::no },
|
||||
{ 'd', "decompress", Arg_parser::no },
|
||||
{ 'D', "range-decompress", Arg_parser::yes },
|
||||
{ 'f', "force", Arg_parser::no },
|
||||
{ 'h', "help", Arg_parser::no },
|
||||
{ 'k', "keep", Arg_parser::no },
|
||||
{ 'l', "list", Arg_parser::no },
|
||||
{ 'm', "merge", Arg_parser::no },
|
||||
{ 'o', "output", Arg_parser::yes },
|
||||
{ 'q', "quiet", Arg_parser::no },
|
||||
{ 'R', "repair", Arg_parser::no },
|
||||
{ 's', "split", Arg_parser::no },
|
||||
{ 't', "test", Arg_parser::no },
|
||||
{ 'v', "verbose", Arg_parser::no },
|
||||
{ 'V', "version", Arg_parser::no },
|
||||
{ 0 , 0, Arg_parser::no } };
|
||||
|
||||
const Arg_parser parser( argc, argv, options );
|
||||
if( parser.error().size() ) // bad option
|
||||
|
@ -520,15 +544,19 @@ int main( const int argc, const char * const argv[] )
|
|||
{
|
||||
const int code = parser.code( argind );
|
||||
if( !code ) break; // no more options
|
||||
const std::string & arg = parser.argument( argind ).c_str();
|
||||
switch( code )
|
||||
{
|
||||
case 'c': to_stdout = true; break;
|
||||
case 'd': set_mode( program_mode, m_decompress ); break;
|
||||
case 'D': set_mode( program_mode, m_range );
|
||||
range_string = arg; break;
|
||||
case 'f': force = true; break;
|
||||
case 'h': show_help(); return 0;
|
||||
case 'k': keep_input_files = true; break;
|
||||
case 'l': set_mode( program_mode, m_list ); break;
|
||||
case 'm': set_mode( program_mode, m_merge ); break;
|
||||
case 'o': default_output_filename = parser.argument( argind ); break;
|
||||
case 'o': default_output_filename = arg; break;
|
||||
case 'q': verbosity = -1; break;
|
||||
case 'R': set_mode( program_mode, m_repair ); break;
|
||||
case 's': set_mode( program_mode, m_split ); break;
|
||||
|
@ -552,9 +580,10 @@ int main( const int argc, const char * const argv[] )
|
|||
case m_update:
|
||||
case m_none: internal_error( "invalid operation" ); break;
|
||||
case m_decompress: break;
|
||||
case m_list:
|
||||
one_file( argind, parser.arguments() );
|
||||
return list_file( parser.argument( argind ) );
|
||||
case m_merge:
|
||||
{
|
||||
std::vector< std::string > filenames;
|
||||
for( ; argind < parser.arguments(); ++argind )
|
||||
filenames.push_back( parser.argument( argind ) );
|
||||
if( filenames.size() < 2 )
|
||||
|
@ -562,21 +591,19 @@ int main( const int argc, const char * const argv[] )
|
|||
if( !default_output_filename.size() )
|
||||
default_output_filename = insert_fixed( filenames[0] );
|
||||
return merge_files( filenames, default_output_filename, force );
|
||||
} break;
|
||||
case m_range:
|
||||
one_file( argind, parser.arguments() );
|
||||
return range_decompress( parser.argument( argind ),
|
||||
default_output_filename, range_string,
|
||||
to_stdout, force );
|
||||
case m_repair:
|
||||
{
|
||||
if( argind + 1 != parser.arguments() )
|
||||
{ show_error( "You must specify exactly 1 file.", 0, true ); return 1; }
|
||||
one_file( argind, parser.arguments() );
|
||||
if( !default_output_filename.size() )
|
||||
default_output_filename = insert_fixed( parser.argument( argind ) );
|
||||
return repair_file( parser.argument( argind ), default_output_filename, force );
|
||||
} break;
|
||||
case m_split:
|
||||
{
|
||||
if( argind + 1 != parser.arguments() )
|
||||
{ show_error( "You must specify exactly 1 file.", 0, true ); return 1; }
|
||||
one_file( argind, parser.arguments() );
|
||||
return split_file( parser.argument( argind ), default_output_filename, force );
|
||||
} break;
|
||||
case m_test: break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue