diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | INSTALL | 12 | ||||
-rw-r--r-- | README | 29 | ||||
-rw-r--r-- | carg_parser.c | 7 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | decoder.c | 16 | ||||
-rw-r--r-- | decoder.h | 5 | ||||
-rw-r--r-- | doc/lunzip.1 | 20 | ||||
-rw-r--r-- | lzip.h | 2 | ||||
-rw-r--r-- | main.c | 40 | ||||
-rwxr-xr-x | testsuite/check.sh | 40 |
11 files changed, 91 insertions, 91 deletions
@@ -1,11 +1,6 @@ -2014-01-21 Antonio Diaz Diaz <antonio@gnu.org> +2014-04-11 Antonio Diaz Diaz <antonio@gnu.org> - * Version 1.5-rc2 released. - * Minor optimizations. - -2013-10-30 Antonio Diaz Diaz <antonio@gnu.org> - - * Version 1.5-rc1 released. + * Version 1.5 released. * main.c: Added new option '-u, --buffer-size' (low memory mode). * main.c (close_and_set_permissions): Behave like 'cp -p'. @@ -43,12 +43,12 @@ the main archive. Another way ----------- -You can also compile lunzip into a separate directory. To do this, you -must use a version of 'make' that supports the 'VPATH' variable, such -as GNU 'make'. 'cd' to the directory where you want the object files -and executables to go and run the 'configure' script. 'configure' -automatically checks for the source code in '.', in '..' and in the -directory that 'configure' is in. +You can also compile lunzip into a separate directory. +To do this, you must use a version of 'make' that supports the 'VPATH' +variable, such as GNU 'make'. 'cd' to the directory where you want the +object files and executables to go and run the 'configure' script. +'configure' automatically checks for the source code in '.', in '..' and +in the directory that 'configure' is in. 'configure' recognizes the option '--srcdir=DIR' to control where to look for the sources. Usually 'configure' can determine that directory @@ -5,20 +5,6 @@ small size makes it well suited for embedded devices or software installers that need to decompress files but do not need compression capabilities. Lunzip is fully compatible with lzip-1.4 or newer. -If the size of the output buffer is specified with the "--buffer-size" -option, lunzip uses the decompressed file as dictionary for distances -beyond the buffer size and is able to decompress any file using as -little memory as 50 kB, irrespective of the dictionary size used to -compress the file. Of course, the smaller the output buffer size used in -relation to the dictionary size, the more accesses to disk are needed -and the slower the decompression is. This "low memory" mode only works -when decompressing to a regular file and is intended for systems without -enough memory (RAM + swap) to keep the whole dictionary at once. - -The amount of memory required by lunzip to decompress a file is about -46 kB larger than the dictionary size used to compress that file, unless -the "--buffer-size" option is specified. - The lzip file format is designed for long-term data archiving. It is clean, provides very safe 4 factor integrity checking, and is backed by the recovery capabilities of lziprecover. @@ -28,6 +14,21 @@ bzip2, which makes it safer than decompressors returning ambiguous warning values (like gunzip) when it is used as a back end for tar or zutils. +Lunzip provides a "low memory" mode able to decompress any file using as +little memory as 50 kB, irrespective of the dictionary size used to +compress the file. To activate it, specify the size of the output buffer +with the "--buffer-size" option and lunzip will use the decompressed +file as dictionary for distances beyond the buffer size. Of course, the +smaller the output buffer size used in relation to the dictionary size, +the more accesses to disk are needed and the slower the decompression +is. This "low memory" mode only works when decompressing to a regular +file and is intended for systems without enough memory (RAM + swap) to +keep the whole dictionary at once. + +The amount of memory required by lunzip to decompress a file is about +46 kB larger than the dictionary size used to compress that file, unless +the "--buffer-size" option is specified. + Lunzip attempts to guess the name for the decompressed file from that of the compressed file as follows: diff --git a/carg_parser.c b/carg_parser.c index 1dfcb2b..80e60c1 100644 --- a/carg_parser.c +++ b/carg_parser.c @@ -176,7 +176,8 @@ static char parse_short_option( struct Arg_parser * const ap, if( index < 0 ) { - add_error( ap, "invalid option -- " ); add_error( ap, code_str ); + add_error( ap, "invalid option -- '" ); add_error( ap, code_str ); + add_error( ap, "'" ); return 1; } @@ -191,8 +192,8 @@ static char parse_short_option( struct Arg_parser * const ap, { if( !arg || !arg[0] ) { - add_error( ap, "option requires an argument -- " ); - add_error( ap, code_str ); + add_error( ap, "option requires an argument -- '" ); + add_error( ap, code_str ); add_error( ap, "'" ); return 1; } ++*argindp; cind = 0; @@ -6,7 +6,7 @@ # to copy, distribute and modify it. pkgname=lunzip -pkgversion=1.5-rc2 +pkgversion=1.5 progname=lunzip srctrigger=doc/${progname}.1 @@ -45,7 +45,7 @@ void Pp_show_msg( struct Pretty_print * const pp, const char * const msg ) for( i = 0; i < len; ++i ) fprintf( stderr, " " ); if( !msg ) fflush( stderr ); } - if( msg ) fprintf( stderr, "%s.\n", msg ); + if( msg ) fprintf( stderr, "%s\n", msg ); } } @@ -127,8 +127,8 @@ void LZd_flush_data( struct LZ_decoder * const d ) } -bool LZd_verify_trailer( struct LZ_decoder * const d, - struct Pretty_print * const pp ) +static bool LZd_verify_trailer( struct LZ_decoder * const d, + struct Pretty_print * const pp ) { File_trailer trailer; const unsigned long long member_size = Rd_member_position( d->rdec ) + Ft_size; @@ -153,7 +153,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const d, if( d->rdec->code != 0 ) { error = true; - Pp_show_msg( pp, "Range decoder final code is not zero" ); + Pp_show_msg( pp, "Range decoder final code is not zero." ); } trailer_crc = Ft_get_data_crc( trailer ); if( trailer_crc != LZd_crc( d ) ) @@ -208,7 +208,7 @@ int LZd_decode_member( struct LZ_decoder * const d, struct Range_decoder * const rdec = d->rdec; void (* const copy_block) ( struct LZ_decoder * const d, const int distance, int len ) = - ( d->buffer_size >= (int)d->dictionary_size ) ? + ( (unsigned)d->buffer_size >= d->dictionary_size ) ? &LZd_copy_block : &LZd_copy_block2; unsigned rep0 = 0; /* rep[0-3] latest four distances */ unsigned rep1 = 0; /* used for efficient coding of */ @@ -227,14 +227,14 @@ int LZd_decode_member( struct LZ_decoder * const d, { state -= ( state < 4 ) ? state : 3; LZd_put_byte( d, Rd_decode_tree( rdec, - d->bm_literal[get_lit_state(prev_byte)], 8 ) ); + d->bm_literal[get_lit_state(prev_byte)], 8 ) ); } else { state -= ( state < 10 ) ? 3 : 6; LZd_put_byte( d, Rd_decode_matched( rdec, - d->bm_literal[get_lit_state(prev_byte)], - LZd_get_byte( d, rep0 ) ) ); + d->bm_literal[get_lit_state(prev_byte)], + LZd_get_byte( d, rep0 ) ) ); } } else @@ -158,7 +158,7 @@ static inline int Rd_decode_tree6( struct Range_decoder * const rdec, symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); - return symbol - (1 << 6); + return symbol & 0x3F; } static inline int Rd_decode_tree_reversed( struct Range_decoder * const rdec, @@ -256,9 +256,6 @@ struct LZ_decoder void LZd_flush_data( struct LZ_decoder * const d ); -bool LZd_verify_trailer( struct LZ_decoder * const d, - struct Pretty_print * const pp ); - int seek_read( const int fd, uint8_t * const buf, const int size, const int offset ); diff --git a/doc/lunzip.1 b/doc/lunzip.1 index 4557839..15b2683 100644 --- a/doc/lunzip.1 +++ b/doc/lunzip.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH LUNZIP "1" "January 2014" "Lunzip 1.5-rc2" "User Commands" +.TH LUNZIP "1" "April 2014" "lunzip 1.5" "User Commands" .SH NAME -Lunzip \- decompressor for lzip files +lunzip \- decompressor for lzip files .SH SYNOPSIS .B lunzip [\fIoptions\fR] [\fIfiles\fR] @@ -11,14 +11,14 @@ small size makes it well suited for embedded devices or software installers that need to decompress files but do not need compression capabilities. Lunzip is fully compatible with lzip\-1.4 or newer. .PP -If the size of the output buffer is specified with the '\-\-buffer\-size' -option, lunzip uses the decompressed file as dictionary for distances -beyond the buffer size and is able to decompress any file using as +Lunzip provides a 'low memory' mode able to decompress any file using as little memory as 50 kB, irrespective of the dictionary size used to -compress the file. Of course, the smaller the output buffer size used in -relation to the dictionary size, the more accesses to disk are needed -and the slower the decompression is. This 'low memory' mode only works -when decompressing to a regular file. +compress the file. To activate it, specify the size of the output buffer +with the '\-\-buffer\-size' option and lunzip will use the decompressed +file as dictionary for distances beyond the buffer size. Of course, the +smaller the output buffer size used in relation to the dictionary size, +the more accesses to disk are needed and the slower the decompression is. +This 'low memory' mode only works when decompressing to a regular file. .SH OPTIONS .TP \fB\-h\fR, \fB\-\-help\fR @@ -56,6 +56,8 @@ be verbose (a 2nd \fB\-v\fR gives more) .PP If no file names are given, lunzip decompresses from standard input to standard output. +Numbers may be followed by a multiplier: k = kB = 10^3 = 1000, +Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc... .PP Exit status: 0 for a normal exit, 1 for environmental problems (file not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or @@ -46,7 +46,7 @@ static inline State St_set_short_rep( const State st ) enum { min_dictionary_bits = 12, - min_dictionary_size = 1 << min_dictionary_bits, + min_dictionary_size = 1 << min_dictionary_bits, /* >= modeled_distances */ max_dictionary_bits = 29, max_dictionary_size = 1 << max_dictionary_bits, literal_context_bits = 3, @@ -88,14 +88,14 @@ static void show_help( void ) "small size makes it well suited for embedded devices or software\n" "installers that need to decompress files but do not need compression\n" "capabilities. Lunzip is fully compatible with lzip-1.4 or newer.\n" - "\nIf the size of the output buffer is specified with the '--buffer-size'\n" - "option, lunzip uses the decompressed file as dictionary for distances\n" - "beyond the buffer size and is able to decompress any file using as\n" + "\nLunzip provides a 'low memory' mode able to decompress any file using as\n" "little memory as 50 kB, irrespective of the dictionary size used to\n" - "compress the file. Of course, the smaller the output buffer size used in\n" - "relation to the dictionary size, the more accesses to disk are needed\n" - "and the slower the decompression is. This 'low memory' mode only works\n" - "when decompressing to a regular file.\n" ); + "compress the file. To activate it, specify the size of the output buffer\n" + "with the '--buffer-size' option and lunzip will use the decompressed\n" + "file as dictionary for distances beyond the buffer size. Of course, the\n" + "smaller the output buffer size used in relation to the dictionary size,\n" + "the more accesses to disk are needed and the slower the decompression is.\n" + "This 'low memory' mode only works when decompressing to a regular file.\n" ); printf( "\nUsage: %s [options] [files]\n", invocation_name ); printf( "\nOptions:\n" " -h, --help display this help and exit\n" @@ -111,6 +111,8 @@ static void show_help( void ) " -v, --verbose be verbose (a 2nd -v gives more)\n" "If no file names are given, lunzip decompresses from standard input to\n" "standard output.\n" + "Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n" + "Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n" "\nExit status: 0 for a normal exit, 1 for environmental problems (file\n" "not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or\n" "invalid input file, 3 for an internal consistency error (eg, bug) which\n" @@ -122,7 +124,7 @@ static void show_help( void ) static void show_version( void ) { - printf( "%s %s\n", Program_name, PROGVERSION ); + printf( "%s %s\n", program_name, PROGVERSION ); printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year ); 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" @@ -232,8 +234,7 @@ static int open_instream( const char * const name, struct stat * const in_statsp const bool no_ofile ) { int infd; - do infd = open( name, O_RDONLY | O_BINARY ); - while( infd < 0 && errno == EINTR ); + infd = open( name, O_RDONLY | O_BINARY ); if( infd < 0 ) { if( verbosity >= 0 ) @@ -305,8 +306,7 @@ static bool open_outstream( const bool force ) int flags = O_APPEND | O_CREAT | O_RDWR | O_BINARY; if( force ) flags |= O_TRUNC; else flags |= O_EXCL; - do outfd = open( output_filename, flags, outfd_mode ); - while( outfd < 0 && errno == EINTR ); + outfd = open( output_filename, flags, outfd_mode ); if( outfd < 0 && verbosity >= 0 ) { if( errno == EEXIST ) @@ -390,14 +390,14 @@ static int decompress( const int buffer_size, const int infd, if( Rd_finished( &rdec ) ) /* End Of File */ { if( first_member ) - { Pp_show_msg( pp, "File ends unexpectedly at member header" ); + { Pp_show_msg( pp, "File ends unexpectedly at member header." ); retval = 2; } break; } if( !Fh_verify_magic( header ) ) { if( !first_member ) break; /* trailing garbage */ - Pp_show_msg( pp, "Bad magic number (file not in lzip format)" ); + Pp_show_msg( pp, "Bad magic number (file not in lzip format)." ); retval = 2; break; } if( !Fh_verify_version( header ) ) @@ -411,7 +411,7 @@ static int decompress( const int buffer_size, const int infd, 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" ); + { Pp_show_msg( pp, "Invalid dictionary size in member header." ); retval = 2; break; } if( verbosity >= 2 || ( verbosity == 1 && first_member ) ) @@ -432,10 +432,10 @@ static int decompress( const int buffer_size, const int infd, { Pp_show_msg( pp, 0 ); if( result == 2 ) - fprintf( stderr, "File ends unexpectedly at pos %llu\n", + fprintf( stderr, "File ends unexpectedly at pos %llu.\n", partial_file_pos ); else - fprintf( stderr, "Decoder error at pos %llu\n", partial_file_pos ); + fprintf( stderr, "Decoder error at pos %llu.\n", partial_file_pos ); } retval = 2; break; } @@ -472,7 +472,7 @@ void show_error( const char * const msg, const int errcode, const bool help ) if( msg && msg[0] ) { fprintf( stderr, "%s: %s", program_name, msg ); - if( errcode > 0 ) fprintf( stderr, ": %s", strerror( errcode ) ); + if( errcode > 0 ) fprintf( stderr, ": %s.", strerror( errcode ) ); fprintf( stderr, "\n" ); } if( help ) @@ -485,7 +485,7 @@ void show_error( const char * const msg, const int errcode, const bool help ) void internal_error( const char * const msg ) { if( verbosity >= 0 ) - fprintf( stderr, "%s: internal error: %s.\n", program_name, msg ); + fprintf( stderr, "%s: internal error: %s\n", program_name, msg ); exit( 3 ); } @@ -553,7 +553,7 @@ int main( const int argc, const char * const argv[] ) case 'u': buffer_size = get_dict_size( arg ); 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 */ diff --git a/testsuite/check.sh b/testsuite/check.sh index 21199b7..76ab094 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -12,7 +12,7 @@ testdir=`cd "$1" ; pwd` LZIP="${objdir}"/lunzip framework_failure() { echo "failure in testing framework" ; exit 1 ; } -if [ ! -x "${LZIP}" ] ; then +if [ ! -f "${LZIP}" ] || [ ! -x "${LZIP}" ] ; then echo "${LZIP}: cannot execute" exit 1 fi @@ -28,21 +28,24 @@ fail=0 printf "testing lunzip-%s..." "$2" "${LZIP}" -cqu-1 "${in_lz}" > /dev/null -if [ $? = 1 ] ; then printf . ; else fail=1 ; printf - ; fi +if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi "${LZIP}" -cqu0 "${in_lz}" > /dev/null -if [ $? = 1 ] ; then printf . ; else fail=1 ; printf - ; fi +if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi "${LZIP}" -cqu4095 "${in_lz}" > /dev/null -if [ $? = 1 ] ; then printf . ; else fail=1 ; printf - ; fi +if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi "${LZIP}" -cqu513MiB "${in_lz}" > /dev/null -if [ $? = 1 ] ; then printf . ; else fail=1 ; printf - ; fi -"${LZIP}" -tq in -if [ $? = 2 ] ; then printf . ; else fail=1 ; printf - ; fi -"${LZIP}" -tq < in -if [ $? = 2 ] ; then printf . ; else fail=1 ; printf - ; fi +if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi +printf " in: Bad magic number (file not in lzip format).\n" > msg +"${LZIP}" -t in 2> out +if [ $? = 2 ] && cmp out msg ; then printf . ; else printf - ; fail=1 ; fi +printf " (stdin): Bad magic number (file not in lzip format).\n" > msg +"${LZIP}" -t < in 2> out +if [ $? = 2 ] && cmp out msg ; then printf . ; else printf - ; fail=1 ; fi +rm -f out msg "${LZIP}" -cdq in -if [ $? = 2 ] ; then printf . ; else fail=1 ; printf - ; fi +if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi "${LZIP}" -cdq < in -if [ $? = 2 ] ; then printf . ; else fail=1 ; printf - ; fi +if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi dd if="${in_lz}" bs=1 count=6 2> /dev/null | "${LZIP}" -tq if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi dd if="${in_lz}" bs=1 count=20 2> /dev/null | "${LZIP}" -tq @@ -54,6 +57,7 @@ cmp in copy || fail=1 printf . cat "${in_lz}" > copy.lz || framework_failure +printf "to be overwritten" > copy || framework_failure "${LZIP}" -df copy.lz || fail=1 cmp in copy || fail=1 printf . @@ -63,13 +67,6 @@ printf "to be overwritten" > copy || framework_failure cmp in copy || fail=1 printf . -for i in 12 4096 4Ki 29 512KiB ; do - printf "to be overwritten" > copy || framework_failure - "${LZIP}" -df -u$i -o copy < "${in_lz}" || fail=1 - cmp in copy || fail=1 - printf . -done - cat "${in_lz}" > anyothername || framework_failure "${LZIP}" -d anyothername || fail=1 cmp in anyothername.out || fail=1 @@ -89,6 +86,13 @@ printf "to be overwritten" > copy2 || framework_failure cmp in2 copy2 || fail=1 printf . +for i in 12 4096 4Ki 29 512KiB ; do + printf "to be overwritten" > copy || framework_failure + "${LZIP}" -df -u$i -o copy < "${in_lz}" || fail=1 + cmp in copy || fail=1 + printf . +done + echo if [ ${fail} = 0 ] ; then echo "tests completed successfully." |