summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c91
1 files changed, 44 insertions, 47 deletions
diff --git a/main.c b/main.c
index 4435c01..ef12c33 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
/* Minilzip - Test program for the lzlib library
- 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
@@ -76,7 +76,7 @@ void internal_error( const char * const msg );
const char * const Program_name = "Minilzip";
const char * const program_name = "minilzip";
-const char * const program_year = "2013";
+const char * const program_year = "2014";
const char * invocation_name = 0;
struct { const char * from; const char * to; } const known_extensions[] = {
@@ -105,10 +105,30 @@ struct Pretty_print
{
const char * name;
const char * stdin_name;
- int longest_name;
+ unsigned longest_name;
bool first_post;
};
+static 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 unsigned 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;
+ }
+
static inline void Pp_set_name( struct Pretty_print * const pp,
const char * const filename )
{
@@ -118,11 +138,9 @@ static inline void Pp_set_name( struct Pretty_print * const pp,
pp->first_post = true;
}
-
static inline void Pp_reset( struct Pretty_print * const pp )
{ if( pp->name && pp->name[0] ) pp->first_post = true; }
-
static void Pp_show_msg( struct Pretty_print * const pp, const char * const msg )
{
if( verbosity >= 0 )
@@ -193,14 +211,14 @@ static void show_version( void )
}
-static void show_header( struct LZ_Decoder * const decoder )
+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 = LZ_decompress_dictionary_size( decoder ), i;
+ unsigned num = dictionary_size, i;
bool exact = ( num % factor == 0 );
for( i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i )
@@ -304,7 +322,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 )
@@ -388,7 +407,8 @@ static bool open_outstream( const bool force )
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 )
@@ -441,10 +461,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;
@@ -515,8 +539,8 @@ static bool next_filename( void )
static int do_compress( struct LZ_Encoder * const encoder,
const unsigned long long member_size,
- const unsigned long long volume_size, const int infd,
- struct Pretty_print * const pp,
+ const unsigned long long volume_size,
+ const int infd, struct Pretty_print * const pp,
const struct stat * const in_statsp )
{
unsigned long long partial_volume_size = 0;
@@ -688,7 +712,8 @@ int do_decompress( struct LZ_Decoder * const decoder, const int infd,
const unsigned long long data_position = LZ_decompress_data_position( decoder );
const unsigned long long member_size = LZ_decompress_member_position( decoder );
Pp_show_msg( pp, 0 );
- if( verbosity >= 3 ) show_header( decoder );
+ if( verbosity >= 3 )
+ show_header( LZ_decompress_dictionary_size( decoder ) );
if( verbosity >= 2 && data_position > 0 && member_size > 0 )
fprintf( stderr, "%6.3f:1, %6.3f bits/byte, %5.2f%% saved. ",
(double)data_position / member_size,
@@ -714,10 +739,7 @@ int do_decompress( struct LZ_Decoder * const decoder, const int infd,
return 2;
}
if( lz_errno == LZ_mem_error )
- {
- Pp_show_msg( pp, "Not enough memory. Find a machine with more memory" );
- return 1;
- }
+ { Pp_show_msg( pp, "Not enough memory" ); return 1; }
if( verbosity >= 0 )
{
Pp_show_msg( pp, 0 );
@@ -746,10 +768,7 @@ int decompress( const int infd, struct Pretty_print * const pp,
int retval;
if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok )
- {
- Pp_show_msg( pp, "Not enough memory. Find a machine with more memory" );
- retval = 1;
- }
+ { Pp_show_msg( pp, "Not enough memory" ); retval = 1; }
else retval = do_decompress( decoder, infd, pp, testing );
LZ_decompress_close( decoder );
@@ -773,27 +792,6 @@ static void set_signals( void )
}
-static 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 )
@@ -896,7 +894,7 @@ int main( const int argc, const char * const argv[] )
internal_error( "bad library version_string" );
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; }
@@ -907,8 +905,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;