diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 90 |
1 files changed, 44 insertions, 46 deletions
@@ -1,4 +1,4 @@ -/* Pdlzip - Data compressor based on the LZMA algorithm +/* Pdlzip - LZMA lossless data compressor 2009-08-14 : Igor Pavlov : Public domain Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. @@ -154,7 +154,7 @@ static const char * format_num( unsigned num ) } -void show_header( const File_header header ) +static void show_header( const File_header header ) { const char * const prefix[8] = { "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" }; @@ -167,8 +167,6 @@ void show_header( const File_header header ) for( i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i ) { num /= factor; if( num % factor != 0 ) exact = false; p = prefix[i]; np = ""; } - if( verbosity >= 4 ) - fprintf( stderr, "version %d, ", Fh_version( header ) ); fprintf( stderr, "dictionary size %s%4u %sB. ", np, num, p ); } @@ -281,12 +279,13 @@ static int open_instream( const char * const name, struct stat * const in_statsp 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 ) ) ) + const bool no_ofile = to_stdout || program_mode == m_test; + if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || !no_ofile ) ) ) { if( verbosity >= 0 ) fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n", program_name, name, - ( can_read && !to_stdout ) ? + ( can_read && !no_ofile ) ? " and '--stdout' was not specified" : "" ); close( infd ); infd = -1; @@ -297,22 +296,6 @@ static int open_instream( const char * const name, struct stat * const in_statsp } -void cleanup_and_fail( const int retval ) - { - if( delete_output_on_interrupt ) - { - delete_output_on_interrupt = false; - if( verbosity >= 0 ) - fprintf( stderr, "%s: Deleting output file '%s', if it exists.\n", - program_name, output_filename ); - if( outfd >= 0 ) { close( outfd ); outfd = -1; } - if( remove( output_filename ) != 0 && errno != ENOENT ) - show_error( "WARNING: deletion of output file (apparently) failed.", 0, false ); - } - exit( retval ); - } - - /* assure at least a minimum size for buffer 'buf' */ static void * resize_buffer( void * buf, const int min_size ) { @@ -396,6 +379,22 @@ static bool check_tty( const int infd, const enum Mode program_mode ) } +void cleanup_and_fail( const int retval ) + { + if( delete_output_on_interrupt ) + { + delete_output_on_interrupt = false; + if( verbosity >= 0 ) + fprintf( stderr, "%s: Deleting output file '%s', if it exists.\n", + program_name, output_filename ); + if( outfd >= 0 ) { close( outfd ); outfd = -1; } + if( remove( output_filename ) != 0 && errno != ENOENT ) + show_error( "WARNING: deletion of output file (apparently) failed.", 0, false ); + } + exit( retval ); + } + + /* Set permissions, owner and times. */ static void close_and_set_permissions( const struct stat * const in_statsp ) { @@ -426,11 +425,11 @@ static int compress( const struct Lzma_options * const encoder_options, const int infd, struct Pretty_print * const pp ) { int retval = 0; - File_header header; CLzmaEncHandle encoder; + File_header header; + Fh_set_magic( header ); if( verbosity >= 1 ) Pp_show_msg( pp, 0 ); - Fh_set_magic( header ); if( !Fh_set_dictionary_size( header, encoder_options->dictionary_size ) || encoder_options->match_len_limit < min_match_len_limit || encoder_options->match_len_limit > max_match_len ) @@ -480,11 +479,14 @@ static bool read_inbuf( const int infd, uint8_t inBuf[], } +/* 5 bytes of LZMA properties and 8 bytes of uncompressed size */ +enum { lzma_header_size = LZMA_PROPS_SIZE + 8 }; + static int lzma_decode( uint64_t unpackSize, CLzmaDec *decoder, const int infd, uint8_t inBuf[], int * const inPos, int * const inSize, const bool testing ) { - unsigned long long total_in = 13, total_out = 0; + unsigned long long total_in = lzma_header_size, total_out = 0; uint8_t outBuf[OUT_BUF_SIZE]; int outPos = 0; const bool thereIsSize = (unpackSize != (uint64_t)-1); @@ -540,8 +542,7 @@ static int lzma_decode( uint64_t unpackSize, CLzmaDec *decoder, const int infd, static int lzip_decode( CLzmaDec *decoder, const int infd, uint8_t inBuf[], - int * const inPos, int * const inSize, - const int member_version ) + int * const inPos, int * const inSize ) { unsigned long long total_in = Fh_size, total_out = 0; uint8_t outBuf[OUT_BUF_SIZE]; @@ -579,27 +580,25 @@ static int lzip_decode( CLzmaDec *decoder, const int infd, uint8_t inBuf[], { File_trailer trailer; int i; - const int trailer_size = Ft_versioned_size( member_version ); bool error = false; if( status != LZMA_STATUS_FINISHED_WITH_MARK ) { show_error( "Data error.", 0, false ); return 2; } - if( *inSize - *inPos < trailer_size && + if( *inSize - *inPos < Ft_size && !read_inbuf( infd, inBuf, inPos, inSize ) ) return 1; - if( *inSize - *inPos < trailer_size ) + if( *inSize - *inPos < Ft_size ) { error = true; if( verbosity >= 0 ) fprintf( stderr, "Trailer truncated at trailer position %u;" " some checks may fail.\n", (unsigned)(*inSize - *inPos) ); - for( i = *inSize - *inPos; i < trailer_size; ++i ) + for( i = *inSize - *inPos; i < Ft_size; ++i ) inBuf[*inPos+i] = 0; } - for( i = 0; i < trailer_size; ++i ) + for( i = 0; i < Ft_size; ++i ) trailer[i] = inBuf[(*inPos)++]; - total_in += trailer_size; - if( member_version == 0 ) Ft_set_member_size( trailer, total_in ); + total_in += Ft_size; if( Ft_get_data_crc( trailer ) != ( crc ^ 0xFFFFFFFFU ) ) { error = true; @@ -647,28 +646,29 @@ static int decompress( const int infd, struct Pretty_print * const pp, int retval = 0; bool lzip_mode = true; bool first_member; - /* 5 bytes of LZMA properties and 8 bytes of uncompressed size */ - uint8_t raw_props[LZMA_PROPS_SIZE+8]; + uint8_t raw_props[lzma_header_size]; for( first_member = true; ; first_member = false ) { int i; File_header header; - if( inSize - inPos < Fh_size && + if( inSize - inPos < lzma_header_size && !read_inbuf( infd, inBuf, &inPos, &inSize ) ) return 1; - if( inSize - inPos < Fh_size ) /* End Of File */ + if( inSize - inPos <= Fh_size ) /* End Of File */ { if( first_member ) - { Pp_show_msg( pp, "Error reading member header" ); retval = 1; } + { Pp_show_msg( pp, "File ends unexpectedly at member header" ); + retval = 2; } break; } for( i = 0; i < Fh_size; ++i ) raw_props[i] = header[i] = inBuf[inPos++]; if( !Fh_verify_magic( header ) ) { if( !first_member ) break; /* trailing garbage */ - if( inSize - inPos >= 13 - Fh_size ) /* try lzma-alone */ + if( inSize - inPos >= lzma_header_size - Fh_size ) /* try lzma-alone */ { - for( i = Fh_size; i < 13; ++i ) raw_props[i] = inBuf[inPos++]; + for( i = Fh_size; i < lzma_header_size; ++i ) + raw_props[i] = inBuf[inPos++]; for( i = 0; i < 8; ++i ) unpackSize += (uint64_t)raw_props[LZMA_PROPS_SIZE+i] << (i * 8); if( ( raw_props[12] == 0 || raw_props[12] == 0xFF ) && @@ -714,8 +714,7 @@ static int decompress( const int infd, struct Pretty_print * const pp, cleanup_and_fail( 1 ); } if( lzip_mode ) - retval = lzip_decode( &decoder, infd, inBuf, &inPos, &inSize, - Fh_version( header ) ); + retval = lzip_decode( &decoder, infd, inBuf, &inPos, &inSize ); else retval = lzma_decode( unpackSize, &decoder, infd, inBuf, &inPos, &inSize, testing ); @@ -747,14 +746,13 @@ static void set_signals( void ) void Pp_init( struct Pretty_print * const pp, const char * const filenames[], - const int num_filenames, const int v ) + const int num_filenames ) { unsigned stdin_name_len; int i; pp->name = 0; pp->stdin_name = "(stdin)"; pp->longest_name = 0; - pp->verbosity = v; pp->first_post = false; stdin_name_len = strlen( pp->stdin_name ); @@ -939,7 +937,7 @@ int main( const int argc, const char * const argv[] ) ( filenames_given || default_output_filename[0] ) ) set_signals(); - Pp_init( &pp, filenames, num_filenames, verbosity ); + Pp_init( &pp, filenames, num_filenames ); output_filename = resize_buffer( output_filename, 1 ); for( i = 0; i < num_filenames; ++i ) |