Merging upstream version 1.16~pre1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
c9bda4fdd7
commit
6a54533419
23 changed files with 520 additions and 446 deletions
94
main.cc
94
main.cc
|
@ -1,5 +1,5 @@
|
|||
/* Lziprecover - Data recovery tool for lzip files
|
||||
Copyright (C) 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 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
|
||||
|
@ -56,6 +56,10 @@
|
|||
#include "lzip.h"
|
||||
#include "decoder.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#if CHAR_BIT != 8
|
||||
#error "Environments where CHAR_BIT != 8 are not supported."
|
||||
#endif
|
||||
|
@ -65,22 +69,16 @@ namespace {
|
|||
|
||||
const char * const Program_name = "Lziprecover";
|
||||
const char * const program_name = "lziprecover";
|
||||
const char * const program_year = "2013";
|
||||
const char * const program_year = "2014";
|
||||
const char * invocation_name = 0;
|
||||
|
||||
#ifdef O_BINARY
|
||||
const int o_binary = O_BINARY;
|
||||
#else
|
||||
const int o_binary = 0;
|
||||
#endif
|
||||
|
||||
struct { const char * from; const char * to; } const known_extensions[] = {
|
||||
{ ".lz", "" },
|
||||
{ ".tlz", ".tar" },
|
||||
{ 0, 0 } };
|
||||
|
||||
enum Mode { m_none, m_decompress, m_generate, m_list, m_merge, m_range,
|
||||
m_recover, m_repair, m_split, m_test };
|
||||
enum Mode { m_none, m_decompress, m_list, m_merge, m_range, m_repair,
|
||||
m_split, m_test };
|
||||
|
||||
std::string output_filename;
|
||||
int outfd = -1;
|
||||
|
@ -102,14 +100,12 @@ void show_help()
|
|||
" -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"
|
||||
" -i, --ignore-errors make '--range-decompress' ignore data errors\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 multi-member file in single-member files\n"
|
||||
" -t, --test test compressed file integrity\n"
|
||||
|
@ -127,7 +123,7 @@ void show_help()
|
|||
|
||||
void show_version()
|
||||
{
|
||||
std::printf( "%s %s\n", Program_name, PROGVERSION );
|
||||
std::printf( "%s %s\n", program_name, PROGVERSION );
|
||||
std::printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
|
||||
std::printf( "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n"
|
||||
"This is free software: you are free to change and redistribute it.\n"
|
||||
|
@ -189,15 +185,15 @@ int extension_index( const std::string & name )
|
|||
|
||||
} // end namespace
|
||||
|
||||
int open_instream( const std::string & name, struct stat * const in_statsp,
|
||||
int open_instream( const char * const name, struct stat * const in_statsp,
|
||||
const bool no_ofile, const bool reg_only )
|
||||
{
|
||||
int infd = open( name.c_str(), O_RDONLY | o_binary );
|
||||
int infd = open( name, O_RDONLY | O_BINARY );
|
||||
if( infd < 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Can't open input file '%s': %s.\n",
|
||||
program_name, name.c_str(), std::strerror( errno ) );
|
||||
program_name, name, std::strerror( errno ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -210,7 +206,7 @@ int open_instream( const std::string & name, struct stat * const in_statsp,
|
|||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n",
|
||||
program_name, name.c_str(),
|
||||
program_name, name,
|
||||
( can_read && !no_ofile ) ?
|
||||
" and '--stdout' was not specified" : "" );
|
||||
close( infd );
|
||||
|
@ -243,7 +239,7 @@ void set_d_outname( const std::string & name, const int i )
|
|||
|
||||
bool open_outstream( const bool force )
|
||||
{
|
||||
int flags = O_CREAT | O_WRONLY | o_binary;
|
||||
int flags = O_CREAT | O_WRONLY | O_BINARY;
|
||||
if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
|
||||
|
||||
outfd = open( output_filename.c_str(), flags, outfd_mode );
|
||||
|
@ -293,10 +289,14 @@ void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
bool warning = false;
|
||||
if( in_statsp )
|
||||
{
|
||||
const mode_t mode = in_statsp->st_mode;
|
||||
// fchown will in many cases return with EPERM, which can be safely ignored.
|
||||
if( ( fchown( outfd, in_statsp->st_uid, in_statsp->st_gid ) != 0 &&
|
||||
errno != EPERM ) ||
|
||||
fchmod( outfd, in_statsp->st_mode ) != 0 ) warning = true;
|
||||
if( fchown( outfd, in_statsp->st_uid, in_statsp->st_gid ) == 0 )
|
||||
{ if( fchmod( outfd, mode ) != 0 ) warning = true; }
|
||||
else
|
||||
if( errno != EPERM ||
|
||||
fchmod( outfd, mode & ~( S_ISUID | S_ISGID | S_ISVTX ) ) != 0 )
|
||||
warning = true;
|
||||
}
|
||||
if( close( outfd ) != 0 ) cleanup_and_fail( 1 );
|
||||
outfd = -1;
|
||||
|
@ -356,6 +356,7 @@ void show_trailing_garbage( const uint8_t * const data, const int size,
|
|||
garbage_msg += xdigit( data[i] & 0x0F );
|
||||
}
|
||||
}
|
||||
garbage_msg += '.';
|
||||
pp( garbage_msg.c_str() );
|
||||
}
|
||||
|
||||
|
@ -375,7 +376,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
|
|||
if( rdec.finished() ) // End Of File
|
||||
{
|
||||
if( first_member )
|
||||
{ pp( "File ends unexpectedly at member header" ); retval = 2; }
|
||||
{ pp( "File ends unexpectedly at member header." ); retval = 2; }
|
||||
else if( verbosity >= 4 && size > 0 )
|
||||
show_trailing_garbage( header.data, size, pp, true );
|
||||
break;
|
||||
|
@ -383,7 +384,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
|
|||
if( !header.verify_magic() )
|
||||
{
|
||||
if( first_member )
|
||||
{ pp( "Bad magic number (file not in lzip format)" ); retval = 2; }
|
||||
{ pp( "Bad magic number (file not in lzip format)." ); retval = 2; }
|
||||
else if( verbosity >= 4 )
|
||||
show_trailing_garbage( header.data, size, pp, false );
|
||||
break;
|
||||
|
@ -398,7 +399,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
|
|||
}
|
||||
if( header.dictionary_size() < min_dictionary_size ||
|
||||
header.dictionary_size() > max_dictionary_size )
|
||||
{ pp( "Invalid dictionary size in member header" ); retval = 2; break; }
|
||||
{ pp( "Invalid dictionary size in member header." ); retval = 2; break; }
|
||||
|
||||
if( verbosity >= 2 || ( verbosity == 1 && first_member ) )
|
||||
{ pp(); if( verbosity >= 3 ) show_header( header ); }
|
||||
|
@ -412,10 +413,10 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
|
|||
{
|
||||
pp();
|
||||
if( result == 2 )
|
||||
std::fprintf( stderr, "File ends unexpectedly at pos %llu\n",
|
||||
std::fprintf( stderr, "File ends unexpectedly at pos %llu.\n",
|
||||
partial_file_pos );
|
||||
else
|
||||
std::fprintf( stderr, "Decoder error at pos %llu\n",
|
||||
std::fprintf( stderr, "Decoder error at pos %llu.\n",
|
||||
partial_file_pos );
|
||||
}
|
||||
retval = 2; break;
|
||||
|
@ -424,11 +425,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
|
|||
{ std::fprintf( stderr, testing ? "ok\n" : "done\n" ); pp.reset(); }
|
||||
}
|
||||
}
|
||||
catch( std::bad_alloc )
|
||||
{
|
||||
pp( "Not enough memory. Find a machine with more memory" );
|
||||
retval = 1;
|
||||
}
|
||||
catch( std::bad_alloc ) { pp( "Not enough memory." ); retval = 1; }
|
||||
catch( Error e ) { pp(); show_error( e.msg, errno ); retval = 1; }
|
||||
if( verbosity == 1 && retval == 0 )
|
||||
std::fprintf( stderr, testing ? "ok\n" : "done\n" );
|
||||
|
@ -455,7 +452,7 @@ void set_signals()
|
|||
|
||||
int open_outstream_rw( const std::string & output_filename, const bool force )
|
||||
{
|
||||
int flags = O_CREAT | O_RDWR | o_binary;
|
||||
int flags = O_CREAT | O_RDWR | O_BINARY;
|
||||
if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
|
||||
|
||||
int outfd = open( output_filename.c_str(), flags, all_rw );
|
||||
|
@ -481,7 +478,7 @@ void show_error( const char * const msg, const int errcode, const bool help )
|
|||
{
|
||||
std::fprintf( stderr, "%s: %s", program_name, msg );
|
||||
if( errcode > 0 )
|
||||
std::fprintf( stderr, ": %s", std::strerror( errcode ) );
|
||||
std::fprintf( stderr, ": %s.", std::strerror( errcode ) );
|
||||
std::fprintf( stderr, "\n" );
|
||||
}
|
||||
if( help )
|
||||
|
@ -491,10 +488,18 @@ void show_error( const char * const msg, const int errcode, const bool help )
|
|||
}
|
||||
|
||||
|
||||
void show_error2( const char * const msg1, const char * const name,
|
||||
const char * const msg2 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: %s '%s' %s\n", program_name, msg1, name, msg2 );
|
||||
}
|
||||
|
||||
|
||||
void internal_error( const char * const msg )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: internal error: %s.\n", program_name, msg );
|
||||
std::fprintf( stderr, "%s: internal error: %s\n", program_name, msg );
|
||||
std::exit( 3 );
|
||||
}
|
||||
|
||||
|
@ -564,7 +569,7 @@ int main( const int argc, const char * const argv[] )
|
|||
case 't': set_mode( program_mode, m_test ); break;
|
||||
case 'v': if( verbosity < 4 ) ++verbosity; break;
|
||||
case 'V': show_version(); return 0;
|
||||
default : internal_error( "uncaught option" );
|
||||
default : internal_error( "uncaught option." );
|
||||
}
|
||||
} // end process options
|
||||
|
||||
|
@ -588,9 +593,7 @@ int main( const int argc, const char * const argv[] )
|
|||
|
||||
switch( program_mode )
|
||||
{
|
||||
case m_generate:
|
||||
case m_recover:
|
||||
case m_none: internal_error( "invalid operation" ); break;
|
||||
case m_none: internal_error( "invalid operation." ); break;
|
||||
case m_decompress: break;
|
||||
case m_list:
|
||||
if( filenames.size() < 1 )
|
||||
|
@ -599,7 +602,7 @@ int main( const int argc, const char * const argv[] )
|
|||
case m_merge:
|
||||
if( filenames.size() < 2 )
|
||||
{ show_error( "You must specify at least 2 files.", 0, true ); return 1; }
|
||||
if( !default_output_filename.size() )
|
||||
if( default_output_filename.empty() )
|
||||
default_output_filename = insert_fixed( filenames[0] );
|
||||
return merge_files( filenames, default_output_filename, verbosity, force );
|
||||
case m_range:
|
||||
|
@ -608,9 +611,10 @@ int main( const int argc, const char * const argv[] )
|
|||
range_string, verbosity, force, ignore, to_stdout );
|
||||
case m_repair:
|
||||
one_file( filenames.size() );
|
||||
if( !default_output_filename.size() )
|
||||
if( default_output_filename.empty() )
|
||||
default_output_filename = insert_fixed( filenames[0] );
|
||||
return repair_file( filenames[0], default_output_filename, verbosity, force );
|
||||
return repair_file( filenames[0], default_output_filename,
|
||||
verbosity, force );
|
||||
case m_split:
|
||||
one_file( filenames.size() );
|
||||
return split_file( filenames[0], default_output_filename, verbosity, force );
|
||||
|
@ -620,7 +624,7 @@ int main( const int argc, const char * const argv[] )
|
|||
if( program_mode == m_test )
|
||||
outfd = -1;
|
||||
else if( program_mode != m_decompress )
|
||||
internal_error( "invalid decompressor operation" );
|
||||
internal_error( "invalid decompressor operation." );
|
||||
|
||||
if( filenames.empty() ) filenames.push_back("-");
|
||||
if( !to_stdout && program_mode != m_test &&
|
||||
|
@ -635,13 +639,13 @@ int main( const int argc, const char * const argv[] )
|
|||
struct stat in_stats;
|
||||
output_filename.clear();
|
||||
|
||||
if( !filenames[i].size() || filenames[i] == "-" )
|
||||
if( filenames[i].empty() || filenames[i] == "-" )
|
||||
{
|
||||
input_filename.clear();
|
||||
infd = STDIN_FILENO;
|
||||
if( program_mode != m_test )
|
||||
{
|
||||
if( to_stdout || !default_output_filename.size() )
|
||||
if( to_stdout || default_output_filename.empty() )
|
||||
outfd = STDOUT_FILENO;
|
||||
else
|
||||
{
|
||||
|
@ -659,7 +663,7 @@ int main( const int argc, const char * const argv[] )
|
|||
else
|
||||
{
|
||||
input_filename = filenames[i];
|
||||
infd = open_instream( input_filename, &in_stats,
|
||||
infd = open_instream( input_filename.c_str(), &in_stats,
|
||||
to_stdout || program_mode == m_test );
|
||||
if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; }
|
||||
if( program_mode != m_test )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue