Merging upstream version 0.7.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
fe9dba7d15
commit
238d2661e5
18 changed files with 317 additions and 287 deletions
149
main.cc
149
main.cc
|
@ -61,10 +61,10 @@
|
|||
|
||||
namespace {
|
||||
|
||||
const char * const Program_name = "Plzip";
|
||||
const char * const program_name = "plzip";
|
||||
const char * const program_year = "2010";
|
||||
const char * invocation_name = 0;
|
||||
const char * const Program_name = "Plzip";
|
||||
const char * const program_name = "plzip";
|
||||
const char * const program_year = "2010";
|
||||
|
||||
#ifdef O_BINARY
|
||||
const int o_binary = O_BINARY;
|
||||
|
@ -83,7 +83,7 @@ struct Lzma_options
|
|||
int match_len_limit; // 5..273
|
||||
};
|
||||
|
||||
enum Mode { m_compress = 0, m_decompress, m_test };
|
||||
enum Mode { m_compress, m_decompress, m_test };
|
||||
|
||||
std::string output_filename;
|
||||
int outfd = -1;
|
||||
|
@ -105,7 +105,7 @@ void show_help() throw()
|
|||
std::printf( " -d, --decompress decompress\n" );
|
||||
std::printf( " -f, --force overwrite existing output files\n" );
|
||||
std::printf( " -k, --keep keep (don't delete) input files\n" );
|
||||
std::printf( " -m, --match-length=<n> set match length limit in bytes [80]\n" );
|
||||
std::printf( " -m, --match-length=<n> set match length limit in bytes [36]\n" );
|
||||
std::printf( " -n, --threads=<n> set the number of (de)compression threads\n" );
|
||||
std::printf( " -o, --output=<file> if reading stdin, place the output into <file>\n" );
|
||||
std::printf( " -q, --quiet suppress all messages\n" );
|
||||
|
@ -140,30 +140,6 @@ void show_version() throw()
|
|||
}
|
||||
|
||||
|
||||
const char * format_num( long long num, long long limit = 9999,
|
||||
const int set_prefix = 0 ) 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 = false;
|
||||
static char buf[16];
|
||||
|
||||
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 = "";
|
||||
limit = std::max( 999LL, std::min( 999999LL, limit ) );
|
||||
|
||||
for( int i = 0; i < 8 && ( llabs( num ) > limit ||
|
||||
( llabs( num ) >= factor && num % factor == 0 ) ); ++i )
|
||||
{ num /= factor; p = prefix[i]; }
|
||||
snprintf( buf, sizeof buf, "%lld %s", num, p );
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
long long getnum( const char * const ptr, const int bs = 0,
|
||||
const long long llimit = LLONG_MIN + 1,
|
||||
const long long ulimit = LLONG_MAX ) throw()
|
||||
|
@ -173,7 +149,7 @@ long long getnum( const char * const ptr, const int bs = 0,
|
|||
long long result = strtoll( ptr, &tail, 0 );
|
||||
if( tail == ptr )
|
||||
{
|
||||
show_error( "bad or missing numerical argument", 0, true );
|
||||
show_error( "Bad or missing numerical argument.", 0, true );
|
||||
std::exit( 1 );
|
||||
}
|
||||
|
||||
|
@ -203,7 +179,7 @@ long long getnum( const char * const ptr, const int bs = 0,
|
|||
}
|
||||
if( bad_multiplier )
|
||||
{
|
||||
show_error( "bad multiplier in numerical argument", 0, true );
|
||||
show_error( "Bad multiplier in numerical argument.", 0, true );
|
||||
std::exit( 1 );
|
||||
}
|
||||
for( int i = 0; i < exponent; ++i )
|
||||
|
@ -215,7 +191,7 @@ long long getnum( const char * const ptr, const int bs = 0,
|
|||
if( !errno && ( result < llimit || result > ulimit ) ) errno = ERANGE;
|
||||
if( errno )
|
||||
{
|
||||
show_error( "numerical argument out of limits" );
|
||||
show_error( "Numerical argument out of limits." );
|
||||
std::exit( 1 );
|
||||
}
|
||||
return result;
|
||||
|
@ -254,7 +230,7 @@ int open_instream( const std::string & name, struct stat * const in_statsp,
|
|||
if( program_mode == m_compress && !force && eindex >= 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: input file `%s' already has `%s' suffix.\n",
|
||||
std::fprintf( stderr, "%s: Input file `%s' already has `%s' suffix.\n",
|
||||
program_name, name.c_str(),
|
||||
known_extensions[eindex].from );
|
||||
}
|
||||
|
@ -271,14 +247,16 @@ int open_instream( const std::string & name, struct stat * const in_statsp,
|
|||
{
|
||||
const int i = fstat( infd, in_statsp );
|
||||
const mode_t & mode = in_statsp->st_mode;
|
||||
if( i < 0 || !( S_ISREG( mode ) || ( to_stdout &&
|
||||
( S_ISFIFO( mode ) || S_ISSOCK( mode ) ||
|
||||
S_ISBLK( mode ) || S_ISCHR( mode ) ) ) ) )
|
||||
const bool can_read = ( i == 0 &&
|
||||
( S_ISBLK( mode ) || S_ISCHR( mode ) ||
|
||||
S_ISFIFO( mode ) || S_ISSOCK( mode ) ) );
|
||||
if( i != 0 || ( !S_ISREG( mode ) && ( !to_stdout || !can_read ) ) )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: input file `%s' is not a regular file%s.\n",
|
||||
std::fprintf( stderr, "%s: Input file `%s' is not a regular file%s.\n",
|
||||
program_name, name.c_str(),
|
||||
to_stdout ? "" : " and `--stdout' was not specified" );
|
||||
( can_read && !to_stdout ) ?
|
||||
" and `--stdout' was not specified" : "" );
|
||||
close( infd );
|
||||
infd = -1;
|
||||
}
|
||||
|
@ -309,7 +287,7 @@ void set_d_outname( const std::string & name, const int i ) throw()
|
|||
}
|
||||
output_filename = name; output_filename += ".out";
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: can't guess original name for `%s' -- using `%s'.\n",
|
||||
std::fprintf( stderr, "%s: Can't guess original name for `%s' -- using `%s'.\n",
|
||||
program_name, name.c_str(), output_filename.c_str() );
|
||||
}
|
||||
|
||||
|
@ -320,18 +298,14 @@ bool open_outstream( const bool force ) throw()
|
|||
if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
|
||||
|
||||
outfd = open( output_filename.c_str(), flags, outfd_mode );
|
||||
if( outfd < 0 )
|
||||
if( outfd < 0 && verbosity >= 0 )
|
||||
{
|
||||
if( errno == EEXIST ) outfd = -2; else outfd = -1;
|
||||
if( verbosity >= 0 )
|
||||
{
|
||||
if( outfd == -2 )
|
||||
std::fprintf( stderr, "%s: Output file %s already exists, skipping.\n",
|
||||
program_name, output_filename.c_str() );
|
||||
else
|
||||
std::fprintf( stderr, "%s: Can't create output file `%s': %s.\n",
|
||||
program_name, output_filename.c_str(), std::strerror( errno ) );
|
||||
}
|
||||
if( errno == EEXIST )
|
||||
std::fprintf( stderr, "%s: Output file `%s' already exists, skipping.\n",
|
||||
program_name, output_filename.c_str() );
|
||||
else
|
||||
std::fprintf( stderr, "%s: Can't create output file `%s': %s.\n",
|
||||
program_name, output_filename.c_str(), std::strerror( errno ) );
|
||||
}
|
||||
return ( outfd >= 0 );
|
||||
}
|
||||
|
@ -339,7 +313,7 @@ bool open_outstream( const bool force ) throw()
|
|||
|
||||
bool check_tty( const int infd, const Mode program_mode ) throw()
|
||||
{
|
||||
if( program_mode == m_compress && isatty( outfd ) )
|
||||
if( program_mode == m_compress && outfd >= 0 && isatty( outfd ) )
|
||||
{
|
||||
show_error( "I won't write compressed data to a terminal.", 0, true );
|
||||
return false;
|
||||
|
@ -376,8 +350,9 @@ void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
bool error = false;
|
||||
if( in_statsp )
|
||||
{
|
||||
if( fchmod( outfd, in_statsp->st_mode ) != 0 ) error = true;
|
||||
else (void)fchown( outfd, in_statsp->st_uid, in_statsp->st_gid );
|
||||
if( fchmod( outfd, in_statsp->st_mode ) != 0 ||
|
||||
( fchown( outfd, in_statsp->st_uid, in_statsp->st_gid ) != 0 &&
|
||||
errno != EPERM ) ) error = true;
|
||||
// fchown will in many cases return with EPERM, which can be safely ignored.
|
||||
}
|
||||
if( close( outfd ) == 0 ) outfd = -1;
|
||||
|
@ -393,7 +368,7 @@ void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
}
|
||||
if( error )
|
||||
{
|
||||
show_error( "I can't change output file attributes." );
|
||||
show_error( "Can't change output file attributes." );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
}
|
||||
|
@ -409,15 +384,11 @@ extern "C" void signal_handler( int sig ) throw()
|
|||
}
|
||||
|
||||
|
||||
void set_signals( const bool to_file ) throw()
|
||||
void set_signals() throw()
|
||||
{
|
||||
if( to_file )
|
||||
{
|
||||
std::signal( SIGHUP, signal_handler );
|
||||
std::signal( SIGINT, signal_handler );
|
||||
std::signal( SIGTERM, signal_handler );
|
||||
}
|
||||
std::signal( SIGUSR1, signal_handler );
|
||||
std::signal( SIGHUP, signal_handler );
|
||||
std::signal( SIGINT, signal_handler );
|
||||
std::signal( SIGTERM, signal_handler );
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
@ -453,22 +424,24 @@ void show_error( const char * const msg, const int errcode, const bool help ) th
|
|||
{
|
||||
if( verbosity >= 0 )
|
||||
{
|
||||
if( msg && msg[0] != 0 )
|
||||
if( msg && msg[0] )
|
||||
{
|
||||
std::fprintf( stderr, "%s: %s", program_name, msg );
|
||||
if( errcode > 0 ) std::fprintf( stderr, ": %s", std::strerror( errcode ) );
|
||||
if( errcode > 0 )
|
||||
std::fprintf( stderr, ": %s", std::strerror( errcode ) );
|
||||
std::fprintf( stderr, "\n" );
|
||||
}
|
||||
if( help && invocation_name && invocation_name[0] != 0 )
|
||||
std::fprintf( stderr, "Try `%s --help' for more information.\n", invocation_name );
|
||||
if( help && invocation_name && invocation_name[0] )
|
||||
std::fprintf( stderr, "Try `%s --help' for more information.\n",
|
||||
invocation_name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void internal_error( const char * const msg )
|
||||
{
|
||||
std::string s( "internal error: " ); s += msg;
|
||||
show_error( s.c_str() );
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: internal error: %s.\n", program_name, msg );
|
||||
std::exit( 3 );
|
||||
}
|
||||
|
||||
|
@ -516,21 +489,21 @@ int main( const int argc, const char * const argv[] )
|
|||
// to the corresponding LZMA compression modes.
|
||||
const Lzma_options option_mapping[] =
|
||||
{
|
||||
{ 1 << 16, 5 }, // -0
|
||||
{ 1 << 20, 10 }, // -1
|
||||
{ 3 << 19, 12 }, // -2
|
||||
{ 1 << 21, 17 }, // -3
|
||||
{ 3 << 20, 26 }, // -4
|
||||
{ 1 << 22, 44 }, // -5
|
||||
{ 1 << 23, 80 }, // -6
|
||||
{ 1 << 24, 108 }, // -7
|
||||
{ 3 << 23, 163 }, // -8
|
||||
{ 1 << 20, 5 }, // -0
|
||||
{ 1 << 20, 5 }, // -1
|
||||
{ 3 << 19, 6 }, // -2
|
||||
{ 1 << 21, 8 }, // -3
|
||||
{ 3 << 20, 12 }, // -4
|
||||
{ 1 << 22, 20 }, // -5
|
||||
{ 1 << 23, 36 }, // -6
|
||||
{ 1 << 24, 68 }, // -7
|
||||
{ 3 << 23, 132 }, // -8
|
||||
{ 1 << 25, 273 } }; // -9
|
||||
Lzma_options encoder_options = option_mapping[6]; // default = "-6"
|
||||
int data_size = 0;
|
||||
int debug_level = 0;
|
||||
int infd = -1;
|
||||
int num_workers = 0; // Start this many worker threads
|
||||
int num_workers = 0; // start this many worker threads
|
||||
Mode program_mode = m_compress;
|
||||
bool force = false;
|
||||
bool keep_input_files = false;
|
||||
|
@ -554,8 +527,8 @@ int main( const int argc, const char * const argv[] )
|
|||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
{ '0', 0, Arg_parser::no },
|
||||
{ '1', "fast", Arg_parser::no },
|
||||
{ '0', "fast", Arg_parser::no },
|
||||
{ '1', 0, Arg_parser::no },
|
||||
{ '2', 0, Arg_parser::no },
|
||||
{ '3', 0, Arg_parser::no },
|
||||
{ '4', 0, Arg_parser::no },
|
||||
|
@ -584,7 +557,7 @@ int main( const int argc, const char * const argv[] )
|
|||
{ 'V', "version", Arg_parser::no },
|
||||
{ 0 , 0, Arg_parser::no } };
|
||||
|
||||
Arg_parser parser( argc, argv, options );
|
||||
const Arg_parser parser( argc, argv, options );
|
||||
if( parser.error().size() ) // bad option
|
||||
{ show_error( parser.error().c_str(), 0, true ); return 1; }
|
||||
|
||||
|
@ -605,7 +578,7 @@ int main( const int argc, const char * const argv[] )
|
|||
case 'c': to_stdout = true; break;
|
||||
case 'd': program_mode = m_decompress; break;
|
||||
case 'D': debug_level = getnum( arg, 0, 0, 3 ); break;
|
||||
case 'e': break;
|
||||
case 'e': break; // ignored by now
|
||||
case 'f': force = true; break;
|
||||
case 'h': show_help(); return 0;
|
||||
case 'k': keep_input_files = true; break;
|
||||
|
@ -623,7 +596,7 @@ int main( const int argc, const char * const argv[] )
|
|||
case 'V': show_version(); return 0;
|
||||
default : internal_error( "uncaught option" );
|
||||
}
|
||||
}
|
||||
} // end process options
|
||||
|
||||
if( data_size <= 0 )
|
||||
data_size = 2 * std::max( 65536, encoder_options.dictionary_size );
|
||||
|
@ -646,8 +619,10 @@ int main( const int argc, const char * const argv[] )
|
|||
}
|
||||
|
||||
if( filenames.empty() ) filenames.push_back("-");
|
||||
set_signals( !to_stdout && program_mode != m_test &&
|
||||
( filenames_given || default_output_filename.size() ) );
|
||||
if( !to_stdout && program_mode != m_test &&
|
||||
( filenames_given || default_output_filename.size() ) )
|
||||
set_signals();
|
||||
std::signal( SIGUSR1, signal_handler );
|
||||
|
||||
Pretty_print pp( filenames );
|
||||
if( program_mode == m_test )
|
||||
|
@ -737,9 +712,7 @@ int main( const int argc, const char * const argv[] )
|
|||
}
|
||||
if( outfd >= 0 && close( outfd ) != 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Can't close stdout: %s.\n",
|
||||
program_name, std::strerror( errno ) );
|
||||
show_error( "Can't close stdout", errno );
|
||||
if( retval < 1 ) retval = 1;
|
||||
}
|
||||
return retval;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue