diff options
Diffstat (limited to '')
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | NEWS | 11 | ||||
-rw-r--r-- | README | 20 | ||||
-rwxr-xr-x | configure | 4 | ||||
-rw-r--r-- | decoder.c | 30 | ||||
-rw-r--r-- | decoder.h | 2 | ||||
-rw-r--r-- | doc/lunzip.1 | 4 | ||||
-rw-r--r-- | lzip.h | 15 | ||||
-rw-r--r-- | main.c | 23 | ||||
-rwxr-xr-x | testsuite/check.sh | 50 |
12 files changed, 81 insertions, 90 deletions
@@ -1,3 +1,9 @@ +2013-06-27 Antonio Diaz Diaz <antonio@gnu.org> + + * Version 1.4-rc1 released. + * main.c (show_header): Do not show header version. + * Minor fixes. + 2013-06-18 Antonio Diaz Diaz <antonio@gnu.org> * Version 1.3 released. @@ -10,9 +10,9 @@ Procedure --------- 1. Unpack the archive if you have not done so already: - lzip -cd lunzip[version].tar.lz | tar -xf - + tar -xf lunzip[version].tar.lz or - gzip -cd lunzip[version].tar.gz | tar -xf - + lzip -cd lunzip[version].tar.lz | tar -xf - This creates the directory ./lunzip[version] containing the source from the main archive. diff --git a/Makefile.in b/Makefile.in index 7fc59ac..0e9b9ae 100644 --- a/Makefile.in +++ b/Makefile.in @@ -43,7 +43,7 @@ $(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texinfo man : $(VPATH)/doc/$(progname).1 $(VPATH)/doc/$(progname).1 : $(progname) - help2man -n 'small decompressor for lzip files' \ + help2man -n 'decompressor for lzip files' \ -o $@ --no-info ./$(progname) Makefile : $(VPATH)/configure $(VPATH)/Makefile.in @@ -1,10 +1,5 @@ -Changes in version 1.3: +Changes in version 1.4: -Decompression time has been reduced by 1%. +File version is no more shown in status messages. -File version is now shown only if verbosity >= 4. - -Option "-n, --threads" is now accepted and ignored for compatibility -with plzip. - -"configure" now accepts options with a separate argument. +Minor fixes. @@ -3,26 +3,16 @@ Description Lunzip is a decompressor for lzip files. It is written in C and its small size makes it well suited for embedded devices or software installers that need to decompress files but do not need compression -capabilities. +capabilities. Lunzip is fully compatible with lzip-1.4 or newer. + +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. Lunzip uses the same well-defined exit status values used by lzip and bzip2, which makes it safer when used in pipes or scripts than decompressors returning ambiguous warning values, like gunzip. -The 4 factor integrity checking of the lzip format guarantees that the -decompressed version of the data is identical to the original. This -guards against corruption of the compressed data, and against undetected -bugs in lunzip (hopefully very unlikely). The chances of data corruption -going undetected are microscopic. Be aware, though, that the check -occurs upon decompression, so it can only tell you that something is -wrong. It can't help you recover the original uncompressed data. - -If you ever need to recover data from a damaged lzip file, try the -lziprecover program. Lziprecover makes lzip files resistant to bit-flip, -one of the most common forms of data corruption, and its recovery -capabilities contribute to make of the lzip format one of the best -options for long-term data archiving. - Lunzip replaces every file given in the command line with a decompressed version of itself. Each decompressed file has the same modification date, permissions, and, when possible, ownership as the corresponding @@ -6,9 +6,9 @@ # to copy, distribute and modify it. pkgname=lunzip -pkgversion=1.3 +pkgversion=1.4-rc1 progname=lunzip -srctrigger=doc/lunzip.1 +srctrigger=doc/${progname}.1 # clear some things potentially inherited from environment. LC_ALL=C @@ -34,7 +34,7 @@ CRC32 crc32; void Pp_show_msg( struct Pretty_print * const pp, const char * const msg ) { - if( pp->verbosity >= 0 ) + if( verbosity >= 0 ) { if( pp->first_post ) { @@ -122,26 +122,23 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, struct Pretty_print * const pp ) { File_trailer trailer; - const int trailer_size = Ft_versioned_size( decoder->member_version ); const unsigned long long member_size = - Rd_member_position( decoder->rdec ) + trailer_size; + Rd_member_position( decoder->rdec ) + Ft_size; bool error = false; - int size = Rd_read_data( decoder->rdec, trailer, trailer_size ); - if( size < trailer_size ) + int size = Rd_read_data( decoder->rdec, trailer, Ft_size ); + if( size < Ft_size ) { error = true; - if( pp->verbosity >= 0 ) + if( verbosity >= 0 ) { Pp_show_msg( pp, 0 ); fprintf( stderr, "Trailer truncated at trailer position %d;" " some checks may fail.\n", size ); } - while( size < trailer_size ) trailer[size++] = 0; + while( size < Ft_size ) trailer[size++] = 0; } - if( decoder->member_version == 0 ) Ft_set_member_size( trailer, member_size ); - if( decoder->rdec->code != 0 ) { error = true; @@ -150,7 +147,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, if( Ft_get_data_crc( trailer ) != LZd_crc( decoder ) ) { error = true; - if( pp->verbosity >= 0 ) + if( verbosity >= 0 ) { Pp_show_msg( pp, 0 ); fprintf( stderr, "CRC mismatch; trailer says %08X, data CRC is %08X.\n", @@ -160,7 +157,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, if( Ft_get_data_size( trailer ) != LZd_data_position( decoder ) ) { error = true; - if( pp->verbosity >= 0 ) + if( verbosity >= 0 ) { Pp_show_msg( pp, 0 ); fprintf( stderr, "Data size mismatch; trailer says %llu, data size is %llu (0x%llX).\n", @@ -170,19 +167,19 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, if( Ft_get_member_size( trailer ) != member_size ) { error = true; - if( pp->verbosity >= 0 ) + if( verbosity >= 0 ) { Pp_show_msg( pp, 0 ); fprintf( stderr, "Member size mismatch; trailer says %llu, member size is %llu (0x%llX).\n", Ft_get_member_size( trailer ), member_size, member_size ); } } - if( !error && pp->verbosity >= 2 && LZd_data_position( decoder ) > 0 && member_size > 0 ) + if( !error && verbosity >= 2 && LZd_data_position( decoder ) > 0 && member_size > 0 ) fprintf( stderr, "%6.3f:1, %6.3f bits/byte, %5.2f%% saved. ", (double)LZd_data_position( decoder ) / member_size, ( 8.0 * member_size ) / LZd_data_position( decoder ), 100.0 * ( 1.0 - ( (double)member_size / LZd_data_position( decoder ) ) ) ); - if( !error && pp->verbosity >= 4 ) + if( !error && verbosity >= 4 ) fprintf( stderr, "data CRC %08X, data size %9llu, member size %8llu. ", Ft_get_data_crc( trailer ), Ft_get_data_size( trailer ), Ft_get_member_size( trailer ) ); @@ -266,8 +263,7 @@ int LZd_decode_member( struct LZ_decoder * const decoder, rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits; if( dis_slot < end_dis_model ) rep0 += Rd_decode_tree_reversed( rdec, - decoder->bm_dis + rep0 - dis_slot - 1, - direct_bits ); + decoder->bm_dis + rep0 - dis_slot - 1, direct_bits ); else { rep0 += Rd_decode( rdec, direct_bits - dis_align_bits ) << dis_align_bits; @@ -285,7 +281,7 @@ int LZd_decode_member( struct LZ_decoder * const decoder, { Rd_load( rdec ); continue; } - if( pp->verbosity >= 0 ) + if( verbosity >= 0 ) { Pp_show_msg( pp, 0 ); fprintf( stderr, "Unsupported marker code '%d'.\n", len ); @@ -237,7 +237,6 @@ struct LZ_decoder int stream_pos; /* first byte not yet written to file */ uint32_t crc; int outfd; /* output file descriptor */ - int member_version; Bit_model bm_literal[1<<literal_context_bits][0x300]; Bit_model bm_match[states][pos_states]; @@ -314,7 +313,6 @@ static inline bool LZd_init( struct LZ_decoder * const decoder, decoder->stream_pos = 0; decoder->crc = 0xFFFFFFFFU; decoder->outfd = ofd; - decoder->member_version = Fh_version( header ); Bm_array_init( decoder->bm_literal[0], (1 << literal_context_bits) * 0x300 ); Bm_array_init( decoder->bm_match[0], states * pos_states ); diff --git a/doc/lunzip.1 b/doc/lunzip.1 index e04ac0e..ab4c9e0 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" "June 2013" "Lunzip 1.3" "User Commands" +.TH LUNZIP "1" "July 2013" "Lunzip 1.4-rc1" "User Commands" .SH NAME -Lunzip \- small decompressor for lzip files +Lunzip \- decompressor for lzip files .SH SYNOPSIS .B lunzip [\fIoptions\fR] [\fIfiles\fR] @@ -118,12 +118,11 @@ struct Pretty_print const char * name; const char * stdin_name; int longest_name; - int verbosity; bool first_post; }; void Pp_init( struct Pretty_print * const pp, const char * const filenames[], - const int num_filenames, const int v ); + const int num_filenames ); static inline void Pp_set_name( struct Pretty_print * const pp, const char * const filename ) @@ -193,7 +192,7 @@ static inline uint8_t Fh_version( const File_header data ) { return data[4]; } static inline bool Fh_verify_version( const File_header data ) - { return ( data[4] <= 1 ); } + { return ( data[4] == 1 ); } static inline unsigned Fh_get_dictionary_size( const File_header data ) { @@ -203,15 +202,15 @@ static inline unsigned Fh_get_dictionary_size( const File_header data ) return sz; } -static inline bool Fh_set_dictionary_size( File_header data, const int sz ) +static inline bool Fh_set_dictionary_size( File_header data, const unsigned sz ) { if( sz >= min_dictionary_size && sz <= max_dictionary_size ) { data[5] = real_bits( sz - 1 ); if( sz > min_dictionary_size ) { - const int base_size = 1 << data[5]; - const int wedge = base_size / 16; + const unsigned base_size = 1 << data[5]; + const unsigned wedge = base_size / 16; int i; for( i = 7; i >= 1; --i ) if( base_size - ( i * wedge ) >= sz ) @@ -230,9 +229,6 @@ typedef uint8_t File_trailer[20]; enum { Ft_size = 20 }; -static inline int Ft_versioned_size( const int version ) - { return ( ( version >= 1 ) ? 20 : 12 ); } - static inline unsigned Ft_get_data_crc( const File_trailer data ) { unsigned tmp = 0; @@ -277,5 +273,6 @@ static inline void Ft_set_member_size( File_trailer data, unsigned long long sz /* defined in main.c */ +extern int verbosity; void cleanup_and_fail( const int retval ); void show_error( const char * const msg, const int errcode, const bool help ); @@ -120,7 +120,7 @@ static void show_version( void ) } -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" }; @@ -133,8 +133,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 ); } @@ -153,8 +151,8 @@ static int extension_index( const char * const name ) } -static int open_instream( const char * const name, - struct stat * const in_statsp, const bool to_stdout ) +static int open_instream( const char * const name, struct stat * const in_statsp, + const bool testing, const bool to_stdout ) { int infd = -1; infd = open( name, O_RDONLY | o_binary ); @@ -171,12 +169,13 @@ static int open_instream( const char * const name, 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 || testing; + 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; @@ -308,7 +307,8 @@ static int decompress( const int infd, struct Pretty_print * const pp, if( Rd_finished( &rdec ) ) /* 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; } if( !Fh_verify_magic( header ) ) @@ -381,14 +381,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 ); @@ -513,7 +512,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 ) @@ -549,7 +548,7 @@ int main( const int argc, const char * const argv[] ) else { input_filename = filenames[i]; - infd = open_instream( input_filename, &in_stats, to_stdout ); + infd = open_instream( input_filename, &in_stats, testing, to_stdout ); if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; } if( !testing ) { diff --git a/testsuite/check.sh b/testsuite/check.sh index 8408109..c4f612e 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -22,41 +22,51 @@ mkdir tmp cd "${objdir}"/tmp cat "${testdir}"/test.txt > in || framework_failure -cat in in > in2 || framework_failure -cat "${testdir}"/test.txt.lz > in.lz || framework_failure -cat in.lz in.lz > in2.lz || framework_failure +in_lz="${testdir}"/test.txt.lz fail=0 printf "testing lunzip-%s..." "$2" -"${LZIP}" -t "${testdir}"/test.txt.lz || fail=1 -"${LZIP}" -cd "${testdir}"/test.txt.lz > copy || fail=1 +"${LZIP}" -tq in +if [ $? = 2 ] ; then printf . ; else fail=1 ; printf - ; fi +"${LZIP}" -tq < in +if [ $? = 2 ] ; then printf . ; else fail=1 ; printf - ; fi +"${LZIP}" -cdq in +if [ $? = 2 ] ; then printf . ; else fail=1 ; printf - ; fi +"${LZIP}" -cdq < in +if [ $? = 2 ] ; then printf . ; else fail=1 ; printf - ; 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 +if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi + +"${LZIP}" -t "${in_lz}" || fail=1 +"${LZIP}" -cd "${in_lz}" > copy || fail=1 cmp in copy || fail=1 printf . -"${LZIP}" -t in2.lz || fail=1 +printf "to be overwritten" > copy || framework_failure +"${LZIP}" -df -o copy < "${in_lz}" || fail=1 +cmp in copy || fail=1 printf . -"${LZIP}" -cd in2.lz > copy2 || fail=1 -cmp in2 copy2 || fail=1 + +cat "${in_lz}" > anyothername || framework_failure +"${LZIP}" -d anyothername || fail=1 +cmp in anyothername.out || fail=1 printf . -cat in2.lz > copy2.lz || framework_failure -printf "garbage" >> copy2.lz || framework_failure -printf "to be overwritten" > copy2 || framework_failure +cat in in > in2 || framework_failure +cat "${in_lz}" "${in_lz}" > copy2.lz || framework_failure "${LZIP}" -t copy2.lz || fail=1 printf . -"${LZIP}" -dfk copy2.lz || fail=1 +"${LZIP}" -cd copy2.lz > copy2 || fail=1 cmp in2 copy2 || fail=1 printf . -printf "to be overwritten" > copy || framework_failure -"${LZIP}" -df -o copy < in.lz || fail=1 -cmp in copy || fail=1 -printf . - -cat in.lz > anyothername || framework_failure -"${LZIP}" -d anyothername || fail=1 -cmp in anyothername.out || fail=1 +printf "garbage" >> copy2.lz || framework_failure +printf "to be overwritten" > copy2 || framework_failure +"${LZIP}" -dfk copy2.lz || fail=1 +cmp in2 copy2 || fail=1 printf . echo |