Merging upstream version 1.6~pre1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
a9ce1f9ead
commit
d98841c4ec
18 changed files with 848 additions and 856 deletions
97
main.c
97
main.c
|
@ -1,5 +1,5 @@
|
|||
/* Clzip - LZMA lossless data compressor
|
||||
Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
Copyright (C) 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 "decoder.h"
|
||||
#include "encoder.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#if CHAR_BIT != 8
|
||||
#error "Environments where CHAR_BIT != 8 are not supported."
|
||||
#endif
|
||||
|
@ -63,15 +67,9 @@
|
|||
|
||||
const char * const Program_name = "Clzip";
|
||||
const char * const program_name = "clzip";
|
||||
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" },
|
||||
|
@ -145,14 +143,14 @@ static void show_version( void )
|
|||
}
|
||||
|
||||
|
||||
static void show_header( const File_header header )
|
||||
static void show_header( const unsigned dictionary_size )
|
||||
{
|
||||
const char * const prefix[8] =
|
||||
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
|
||||
enum { factor = 1024 };
|
||||
const char * p = "";
|
||||
const char * np = " ";
|
||||
unsigned num = Fh_get_dictionary_size( header ), i;
|
||||
unsigned num = dictionary_size, i;
|
||||
bool exact = ( num % factor == 0 );
|
||||
|
||||
for( i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i )
|
||||
|
@ -256,7 +254,8 @@ static int open_instream( const char * const name, struct stat * const in_statsp
|
|||
}
|
||||
else
|
||||
{
|
||||
infd = open( name, O_RDONLY | o_binary );
|
||||
do infd = open( name, O_RDONLY | O_BINARY );
|
||||
while( infd < 0 && errno == EINTR );
|
||||
if( infd < 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
|
@ -337,10 +336,11 @@ static void set_d_outname( const char * const name, const int i )
|
|||
|
||||
static 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, flags, outfd_mode );
|
||||
do outfd = open( output_filename, flags, outfd_mode );
|
||||
while( outfd < 0 && errno == EINTR );
|
||||
if( outfd < 0 && verbosity >= 0 )
|
||||
{
|
||||
if( errno == EEXIST )
|
||||
|
@ -393,10 +393,14 @@ static 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;
|
||||
|
@ -434,6 +438,8 @@ static int compress( const unsigned long long member_size,
|
|||
const int infd, struct Pretty_print * const pp,
|
||||
const struct stat * const in_statsp )
|
||||
{
|
||||
const unsigned long long cfile_size =
|
||||
(in_statsp && S_ISREG( in_statsp->st_mode )) ? in_statsp->st_size / 100 : 0;
|
||||
unsigned long long in_size = 0, out_size = 0, partial_volume_size = 0;
|
||||
int retval = 0;
|
||||
struct Matchfinder matchfinder;
|
||||
|
@ -464,7 +470,8 @@ static int compress( const unsigned long long member_size,
|
|||
show_error( "Not enough memory. Try a smaller dictionary size.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
show_progress( in_size, &matchfinder, pp, in_statsp ); /* init */
|
||||
if( verbosity >= 2 )
|
||||
show_progress( in_size, &matchfinder, pp, cfile_size ); /* init */
|
||||
if( !LZe_encode_member( &encoder, size ) )
|
||||
{ Pp_show_msg( pp, "Encoder error" ); retval = 1; break; }
|
||||
in_size += Mf_data_position( &matchfinder );
|
||||
|
@ -516,13 +523,14 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
bool first_member;
|
||||
if( !Rd_init( &rdec, infd ) )
|
||||
{
|
||||
show_error( "Not enough memory. Find a machine with more memory.", 0, false );
|
||||
show_error( "Not enough memory.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
|
||||
for( first_member = true; ; first_member = false )
|
||||
{
|
||||
int result;
|
||||
unsigned dictionary_size;
|
||||
File_header header;
|
||||
struct LZ_decoder decoder;
|
||||
Rd_reset_member_position( &rdec );
|
||||
|
@ -548,17 +556,19 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
Fh_version( header ) ); }
|
||||
retval = 2; break;
|
||||
}
|
||||
if( Fh_get_dictionary_size( header ) < min_dictionary_size ||
|
||||
Fh_get_dictionary_size( header ) > max_dictionary_size )
|
||||
dictionary_size = Fh_get_dictionary_size( header );
|
||||
if( dictionary_size < min_dictionary_size ||
|
||||
dictionary_size > max_dictionary_size )
|
||||
{ Pp_show_msg( pp, "Invalid dictionary size in member header" );
|
||||
retval = 2; break; }
|
||||
|
||||
if( verbosity >= 2 || ( verbosity == 1 && first_member ) )
|
||||
{ Pp_show_msg( pp, 0 ); if( verbosity >= 3 ) show_header( header ); }
|
||||
{ Pp_show_msg( pp, 0 );
|
||||
if( verbosity >= 3 ) show_header( dictionary_size ); }
|
||||
|
||||
if( !LZd_init( &decoder, header, &rdec, outfd ) )
|
||||
if( !LZd_init( &decoder, &rdec, dictionary_size, outfd ) )
|
||||
{
|
||||
show_error( "Not enough memory. Find a machine with more memory.", 0, false );
|
||||
show_error( "Not enough memory.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
result = LZd_decode_member( &decoder, pp );
|
||||
|
@ -603,27 +613,6 @@ static void set_signals( void )
|
|||
}
|
||||
|
||||
|
||||
void Pp_init( struct Pretty_print * const pp, const char * const filenames[],
|
||||
const int num_filenames )
|
||||
{
|
||||
unsigned stdin_name_len;
|
||||
int i;
|
||||
pp->name = 0;
|
||||
pp->stdin_name = "(stdin)";
|
||||
pp->longest_name = 0;
|
||||
pp->first_post = false;
|
||||
stdin_name_len = strlen( pp->stdin_name );
|
||||
|
||||
for( i = 0; i < num_filenames; ++i )
|
||||
{
|
||||
const char * const s = filenames[i];
|
||||
const int len = ( (strcmp( s, "-" ) == 0) ? stdin_name_len : strlen( s ) );
|
||||
if( len > pp->longest_name ) pp->longest_name = len;
|
||||
}
|
||||
if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len;
|
||||
}
|
||||
|
||||
|
||||
void show_error( const char * const msg, const int errcode, const bool help )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
|
@ -652,25 +641,20 @@ void internal_error( const char * const msg )
|
|||
void show_progress( const unsigned long long partial_size,
|
||||
const struct Matchfinder * const m,
|
||||
struct Pretty_print * const p,
|
||||
const struct stat * const in_statsp )
|
||||
const unsigned long long cfile_size )
|
||||
{
|
||||
static unsigned long long cfile_size = 0; /* file_size / 100 */
|
||||
static unsigned long long csize = 0; /* file_size / 100 */
|
||||
static unsigned long long psize = 0;
|
||||
static const struct Matchfinder * mf = 0;
|
||||
static struct Pretty_print * pp = 0;
|
||||
|
||||
if( m ) /* initialize static vars */
|
||||
{
|
||||
psize = partial_size; mf = m; pp = p;
|
||||
cfile_size = ( in_statsp && S_ISREG( in_statsp->st_mode ) ) ?
|
||||
in_statsp->st_size / 100 : 0;
|
||||
return;
|
||||
}
|
||||
{ csize = cfile_size; psize = partial_size; mf = m; pp = p; }
|
||||
if( mf && pp )
|
||||
{
|
||||
const unsigned long long pos = psize + Mf_data_position( mf );
|
||||
if( cfile_size > 0 )
|
||||
fprintf( stderr, "%4llu%%", pos / cfile_size );
|
||||
if( csize > 0 )
|
||||
fprintf( stderr, "%4llu%%", pos / csize );
|
||||
fprintf( stderr, " %.1f MB\r", pos / 1000000.0 );
|
||||
Pp_reset( pp ); Pp_show_msg( pp, 0 ); /* restore cursor position */
|
||||
}
|
||||
|
@ -750,7 +734,7 @@ int main( const int argc, const char * const argv[] )
|
|||
CRC32_init();
|
||||
|
||||
if( !ap_init( &parser, argc, argv, options, 0 ) )
|
||||
{ show_error( "Memory exhausted.", 0, false ); return 1; }
|
||||
{ show_error( "Not enough memory.", 0, false ); return 1; }
|
||||
if( ap_error( &parser ) ) /* bad option */
|
||||
{ show_error( ap_error( &parser ), 0, true ); return 1; }
|
||||
|
||||
|
@ -761,8 +745,7 @@ int main( const int argc, const char * const argv[] )
|
|||
if( !code ) break; /* no more options */
|
||||
switch( code )
|
||||
{
|
||||
case '0':
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
encoder_options = option_mapping[code-'0']; break;
|
||||
case 'b': member_size = getnum( arg, 100000, max_member_size ); break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue