1
0
Fork 0

Merging upstream version 1.12.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-17 20:49:14 +01:00
parent 819b7ffe8f
commit 93292ac251
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
35 changed files with 1973 additions and 1678 deletions

View file

@ -1,7 +1,7 @@
Clzip was written by Antonio Diaz Diaz. Clzip was written by Antonio Diaz Diaz.
The ideas embodied in clzip are due to (at least) the following people: The ideas embodied in clzip are due to (at least) the following people:
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the
the definition of Markov chains), G.N.N. Martin (for the definition of definition of Markov chains), G.N.N. Martin (for the definition of range
range encoding), Igor Pavlov (for putting all the above together in encoding), Igor Pavlov (for putting all the above together in LZMA), and
LZMA), and Julian Seward (for bzip2's CLI). Julian Seward (for bzip2's CLI).

View file

@ -1,31 +1,46 @@
2021-01-04 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.12 released.
* main.c (main): Report an error if a file name is empty.
Make '-o' behave like '-c', but writing to file instead of stdout.
Make '-c' and '-o' check whether the output is a terminal only once.
Do not open output if input is a terminal.
* Replace 'decompressed', 'compressed' with 'out', 'in' in output.
* lzip_index.c: Improve messages for corruption in last header.
* main.c: Set a valid invocation_name even if argc == 0.
* Document extraction from tar.lz in manual, '--help', and man page.
* clzip.texi (Introduction): Mention plzip and tarlz as alternatives.
* clzip.texi: Several fixes and improvements.
* testsuite: Add 9 new test files.
2019-01-03 Antonio Diaz Diaz <antonio@gnu.org> 2019-01-03 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.11 released. * Version 1.11 released.
* File_* renamed to Lzip_*. * Rename File_* to Lzip_*.
* lzip.h (Lzip_trailer): New function 'Lt_verify_consistency'. * lzip.h (Lzip_trailer): New function 'Lt_verify_consistency'.
* lzip_index.c: Detect some kinds of corrupt trailers. * lzip_index.c: Detect some kinds of corrupt trailers.
* main.c (main): Check return value of close( infd ). * main.c (main): Check return value of close( infd ).
* main.c: Compile on DOS with DJGPP. * main.c: Compile on DOS with DJGPP.
* clzip.texi: Improved descriptions of '-0..-9', '-m' and '-s'. * clzip.texi: Improve descriptions of '-0..-9', '-m', and '-s'.
* configure: Accept appending to CFLAGS, 'CFLAGS+=OPTIONS'. * configure: Accept appending to CFLAGS, 'CFLAGS+=OPTIONS'.
* INSTALL: Document use of CFLAGS+='-D __USE_MINGW_ANSI_STDIO'. * INSTALL: Document use of CFLAGS+='-D __USE_MINGW_ANSI_STDIO'.
2018-02-06 Antonio Diaz Diaz <antonio@gnu.org> 2018-02-06 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.10 released. * Version 1.10 released.
* Added new option '--loose-trailing'. * New option '--loose-trailing'.
* Improved corrupt header detection to HD=3. * Improve corrupt header detection to HD=3.
* main.c: Show corrupt or truncated header in multimember file. * main.c: Show corrupt or truncated header in multimember file.
* main.c (main): Option '-S, --volume-size' now keeps input files. * main.c (main): Option '-S, --volume-size' now keeps input files.
* encoder_base.*: Adjust dictionary size for each member. * encoder_base.*: Adjust dictionary size for each member.
* Replaced 'bits/byte' with inverse compression ratio in output. * Replace 'bits/byte' with inverse compression ratio in output.
* Show progress of decompression at verbosity level 2 (-vv). * Show progress of decompression at verbosity level 2 (-vv).
* Show progress of (de)compression only if stderr is a terminal. * Show progress of (de)compression only if stderr is a terminal.
* main.c: Show final diagnostic when testing multiple files. * main.c: Show final diagnostic when testing multiple files.
* main.c: Do not add a second .lz extension to the arg of -o. * main.c: Do not add a second .lz extension to the arg of -o.
* decoder.c (LZd_verify_trailer): Show stored sizes also in hex. * decoder.c (LZd_verify_trailer): Show stored sizes also in hex.
Show dictionary size at verbosity level 4 (-vvvv). Show dictionary size at verbosity level 4 (-vvvv).
* lzip.texi: Added chapter 'Output'. * clzip.texi: New chapter 'Meaning of clzip's output'.
2017-04-13 Antonio Diaz Diaz <antonio@gnu.org> 2017-04-13 Antonio Diaz Diaz <antonio@gnu.org>
@ -38,19 +53,19 @@
* main.c: Continue testing if any input file is a terminal. * main.c: Continue testing if any input file is a terminal.
* main.c: Show trailing data in both hexadecimal and ASCII. * main.c: Show trailing data in both hexadecimal and ASCII.
* lzip_index.c: Improve detection of bad dict and trailing data. * lzip_index.c: Improve detection of bad dict and trailing data.
* lzip.h: Unified messages for bad magic, trailing data, etc. * lzip.h: Unify messages for bad magic, trailing data, etc.
* clzip.texi: Added missing chapters from lzip.texi. * clzip.texi: Add missing chapters from lzip.texi.
2016-05-13 Antonio Diaz Diaz <antonio@gnu.org> 2016-05-13 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.8 released. * Version 1.8 released.
* Added new option '-a, --trailing-error'. * New option '-a, --trailing-error'.
* main.c (decompress): Print up to 6 bytes of trailing data * main.c (decompress): Print up to 6 bytes of trailing data
when '-vvvv' is specified. when '-vvvv' is specified.
* decoder.c (LZd_verify_trailer): Removed test of final code. * decoder.c (LZd_verify_trailer): Remove test of final code.
* main.c (main): Delete '--output' file if infd is a terminal. * main.c (main): Delete '--output' file if infd is a terminal.
* main.c (main): Don't use stdin more than once. * main.c (main): Don't use stdin more than once.
* clzip.texi: Added chapter 'Trailing data'. * clzip.texi: New chapter 'Trailing data'.
* configure: Avoid warning on some shells when testing for gcc. * configure: Avoid warning on some shells when testing for gcc.
* Makefile.in: Detect the existence of install-info. * Makefile.in: Detect the existence of install-info.
* check.sh: A POSIX shell is required to run the tests. * check.sh: A POSIX shell is required to run the tests.
@ -59,16 +74,16 @@
2015-07-07 Antonio Diaz Diaz <antonio@gnu.org> 2015-07-07 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.7 released. * Version 1.7 released.
* Ported fast encoder and option '-0' from lzip. * Port fast encoder and option '-0' from lzip.
* Makefile.in: Added new targets 'install*-compress'. * Makefile.in: New targets 'install*-compress'.
2014-08-28 Antonio Diaz Diaz <antonio@gnu.org> 2014-08-28 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.6 released. * Version 1.6 released.
* Compression ratio of option '-9' has been slightly increased. * Compression ratio of option '-9' has been slightly increased.
* main.c (close_and_set_permissions): Behave like 'cp -p'. * main.c (close_and_set_permissions): Behave like 'cp -p'.
* clzip.texinfo: Renamed to clzip.texi. * clzip.texinfo: Rename to clzip.texi.
* License changed to GPL version 2 or later. * Change license to GPL version 2 or later.
2013-09-17 Antonio Diaz Diaz <antonio@gnu.org> 2013-09-17 Antonio Diaz Diaz <antonio@gnu.org>
@ -85,8 +100,7 @@
* Compression ratio has been slightly increased. * Compression ratio has been slightly increased.
* Compression time has been reduced by 10%. * Compression time has been reduced by 10%.
* Decompression time has been reduced by 8%. * Decompression time has been reduced by 8%.
* Makefile.in: Added new target 'install-as-lzip'. * Makefile.in: New targets 'install-as-lzip' and 'install-bin'.
* Makefile.in: Added new target 'install-bin'.
* main.c: Use 'setmode' instead of '_setmode' on Windows and OS/2. * main.c: Use 'setmode' instead of '_setmode' on Windows and OS/2.
* main.c: Define 'strtoull' to 'strtoul' on Windows. * main.c: Define 'strtoull' to 'strtoul' on Windows.
@ -98,33 +112,33 @@
* encoder.c (Mf_init): Return false if out of memory instead of * encoder.c (Mf_init): Return false if out of memory instead of
calling cleanup_and_fail. calling cleanup_and_fail.
* Small change in '--help' output and man page. * Small change in '--help' output and man page.
* Changed quote characters in messages as advised by GNU Standards. * Change quote characters in messages as advised by GNU Standards.
* configure: 'datadir' renamed to 'datarootdir'. * configure: Rename 'datadir' to 'datarootdir'.
2011-05-18 Antonio Diaz Diaz <ant_diaz@teleline.es> 2011-05-18 Antonio Diaz Diaz <ant_diaz@teleline.es>
* Version 1.2 released. * Version 1.2 released.
* Added new option '-F, --recompress'. * New option '-F, --recompress'.
* main.c (decompress): Print only one status line for each * main.c (decompress): Print only one status line for each
multimember file when only one '-v' is specified. multimember file when only one '-v' is specified.
* encoder.h (Lee_update_prices): Update high length symbol prices * encoder.h (Lee_update_prices): Update high length symbol prices
independently of the value of 'pos_state'. This gives better independently of the value of 'pos_state'. This gives better
compression for large values of '--match-length' without being compression for large values of '--match-length' without being
slower. slower.
* encoder.h encoder.c: Optimize pair price calculations. This * encoder.h, encoder.c: Optimize pair price calculations, reducing
reduces compression time for large values of '--match-length' compression time for large values of '--match-length' by up to 6%.
by up to 6%.
2011-01-11 Antonio Diaz Diaz <ant_diaz@teleline.es> 2011-01-11 Antonio Diaz Diaz <ant_diaz@teleline.es>
* Version 1.1 released. * Version 1.1 released.
* Code has been converted to 'C89 + long long' from C99. * Code has been converted to 'C89 + long long' from C99.
* main.c: Fixed warning about fchown return value being ignored. * main.c: Fix warning about fchown return value being ignored.
* decoder.c: '-tvvvv' now shows compression ratio. * decoder.c: '-tvvvv' now shows compression ratio.
* main.c: Match length limit set by options -1 to -8 has been * main.c: Match length limit set by options -1 to -8 has been
reduced to extend range of use towards gzip. Lower numbers now reduced to extend range of use towards gzip. Lower numbers now
compress less but faster. (-1 now takes 43% less time for only compress less but faster. (-1 now takes 43% less time for only 20%
20% larger compressed size). larger compressed size).
Exit with status 1 if any output file exists and is skipped.
* Compression ratio of option '-9' has been slightly increased. * Compression ratio of option '-9' has been slightly increased.
* main.c (open_instream): Don't show the message * main.c (open_instream): Don't show the message
" and '--stdout' was not specified" for directories, etc. " and '--stdout' was not specified" for directories, etc.
@ -137,8 +151,8 @@
* Translated to C from the C++ source of lzip 1.10. * Translated to C from the C++ source of lzip 1.10.
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This file is a collection of facts, and thus it is not copyrightable, This file is a collection of facts, and thus it is not copyrightable,
but just in case, you have unlimited permission to copy, distribute and but just in case, you have unlimited permission to copy, distribute, and
modify it. modify it.

22
INSTALL
View file

@ -1,7 +1,7 @@
Requirements Requirements
------------ ------------
You will need a C compiler. You will need a C99 compiler. (gcc 3.3.6 or newer is recommended).
I use gcc 5.3.0 and 4.1.2, but the code should compile with any standards I use gcc 6.1.0 and 4.1.2, but the code should compile with any standards
compliant compiler. compliant compiler.
Gcc is available at http://gcc.gnu.org. Gcc is available at http://gcc.gnu.org.
@ -41,11 +41,11 @@ the main archive.
documentation. documentation.
Or type 'make install-compress', which additionally compresses the Or type 'make install-compress', which additionally compresses the
info manual and the man page after installation. (Installing info manual and the man page after installation.
compressed docs may become the default in the future). (Installing compressed docs may become the default in the future).
You can install only the program, the info manual or the man page by You can install only the program, the info manual, or the man page by
typing 'make install-bin', 'make install-info' or 'make install-man' typing 'make install-bin', 'make install-info', or 'make install-man'
respectively. respectively.
Instead of 'make install', you can type 'make install-as-lzip' to Instead of 'make install', you can type 'make install-as-lzip' to
@ -56,10 +56,10 @@ the main archive.
Another way Another way
----------- -----------
You can also compile clzip into a separate directory. You can also compile clzip into a separate directory.
To do this, you must use a version of 'make' that supports the 'VPATH' To do this, you must use a version of 'make' that supports the variable
variable, such as GNU 'make'. 'cd' to the directory where you want the 'VPATH', such as GNU 'make'. 'cd' to the directory where you want the
object files and executables to go and run the 'configure' script. object files and executables to go and run the 'configure' script.
'configure' automatically checks for the source code in '.', in '..' and 'configure' automatically checks for the source code in '.', in '..', and
in the directory that 'configure' is in. in the directory that 'configure' is in.
'configure' recognizes the option '--srcdir=DIR' to control where to 'configure' recognizes the option '--srcdir=DIR' to control where to
@ -70,7 +70,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above. explained above.
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy, This file is free documentation: you have unlimited permission to copy,
distribute and modify it. distribute, and modify it.

View file

@ -75,7 +75,7 @@ install-info :
-rm -f "$(DESTDIR)$(infodir)/$(pkgname).info"* -rm -f "$(DESTDIR)$(infodir)/$(pkgname).info"*
$(INSTALL_DATA) $(VPATH)/doc/$(pkgname).info "$(DESTDIR)$(infodir)/$(pkgname).info" $(INSTALL_DATA) $(VPATH)/doc/$(pkgname).info "$(DESTDIR)$(infodir)/$(pkgname).info"
-if $(CAN_RUN_INSTALLINFO) ; then \ -if $(CAN_RUN_INSTALLINFO) ; then \
install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$(pkgname).info" ; \ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$(pkgname).info" ; \
fi fi
install-info-compress : install-info install-info-compress : install-info
@ -100,7 +100,7 @@ uninstall-bin :
uninstall-info : uninstall-info :
-if $(CAN_RUN_INSTALLINFO) ; then \ -if $(CAN_RUN_INSTALLINFO) ; then \
install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$(pkgname).info" ; \ install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$(pkgname).info" ; \
fi fi
-rm -f "$(DESTDIR)$(infodir)/$(pkgname).info"* -rm -f "$(DESTDIR)$(infodir)/$(pkgname).info"*
@ -125,7 +125,10 @@ dist : doc
$(DISTNAME)/*.c \ $(DISTNAME)/*.c \
$(DISTNAME)/testsuite/check.sh \ $(DISTNAME)/testsuite/check.sh \
$(DISTNAME)/testsuite/test.txt \ $(DISTNAME)/testsuite/test.txt \
$(DISTNAME)/testsuite/test.txt.lz $(DISTNAME)/testsuite/fox.lz \
$(DISTNAME)/testsuite/fox_*.lz \
$(DISTNAME)/testsuite/test.txt.lz \
$(DISTNAME)/testsuite/test_em.txt.lz
rm -f $(DISTNAME) rm -f $(DISTNAME)
lzip -v -9 $(DISTNAME).tar lzip -v -9 $(DISTNAME).tar

41
NEWS
View file

@ -1,17 +1,36 @@
Changes in version 1.11: Changes in version 1.12:
Detection of forbidden combinations of characters in trailing data has been Clzip now reports an error if a file name is empty (clzip -t "").
improved.
Errors are now also checked when closing the input file. Option '-o, --output' now behaves like '-c, --stdout', but sending the
output unconditionally to a file instead of to standard output. See the new
description of '-o' in the manual. This change is backwards compatible only
when (de)compressing from standard input alone. Therefore commands like:
clzip -o foo.lz - bar < foo
must now be split into:
clzip -o foo.lz - < foo
clzip bar
or rewritten as:
clzip - bar < foo > foo.lz
Clzip now compiles on DOS with DJGPP. (Patch from Robert Riebisch). When using '-c' or '-o', clzip now checks whether the output is a terminal
only once.
The descriptions of '-0..-9', '-m' and '-s' in the manual have been Clzip now does not even open the output file if the input file is a terminal.
improved.
The configure script now accepts appending options to CFLAGS using the The words 'decompressed' and 'compressed' have been replaced with the
syntax 'CFLAGS+=OPTIONS'. shorter 'out' and 'in' in the verbose output when decompressing or testing.
It has been documented in INSTALL the use of Option '--list' now reports corruption or truncation of the last header in a
CFLAGS+='-D __USE_MINGW_ANSI_STDIO' when compiling on MinGW. multimenber file specifically instead of showing the generic message "Last
member in input file is truncated or corrupt."
The commands needed to extract files from a tar.lz archive have been
documented in the manual, in the output of '--help', and in the man page.
Plzip and tarlz are mentioned in the manual as alternatives for
multiprocessors.
Several fixes and improvements have been made to the manual.
9 new test files have been added to the testsuite.

127
README
View file

@ -2,56 +2,66 @@ Description
Clzip is a C language version of lzip, fully compatible with lzip 1.4 or Clzip is a C language version of lzip, fully compatible with lzip 1.4 or
newer. As clzip is written in C, it may be easier to integrate in newer. As clzip is written in C, it may be easier to integrate in
applications like package managers, embedded devices, or systems lacking applications like package managers, embedded devices, or systems lacking a
a C++ compiler. C++ compiler.
Lzip is a lossless data compressor with a user interface similar to the Lzip is a lossless data compressor with a user interface similar to the one
one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0) of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov
or compress most files more than bzip2 (lzip -9). Decompression speed is chain-Algorithm' (LZMA) stream format, chosen to maximize safety and
intermediate between gzip and bzip2. Lzip is better than gzip and bzip2 interoperability. Lzip can compress about as fast as gzip (lzip -0) or
from a data recovery perspective. Lzip has been designed, written and compress most files more than bzip2 (lzip -9). Decompression speed is
tested with great care to replace gzip and bzip2 as the standard intermediate between gzip and bzip2. Lzip is better than gzip and bzip2 from
general-purpose compressed format for unix-like systems. a data recovery perspective. Lzip has been designed, written, and tested
with great care to replace gzip and bzip2 as the standard general-purpose
compressed format for unix-like systems.
For compressing/decompressing large files on multiprocessor machines plzip
can be much faster than lzip at the cost of a slightly reduced compression
ratio.
For creation and manipulation of compressed tar archives tarlz can be more
efficient than using tar and plzip because tarlz is able to keep the
alignment between tar members and lzip members.
The lzip file format is designed for data sharing and long-term archiving, The lzip file format is designed for data sharing and long-term archiving,
taking into account both data integrity and decoder availability: taking into account both data integrity and decoder availability:
* The lzip format provides very safe integrity checking and some data * The lzip format provides very safe integrity checking and some data
recovery means. The lziprecover program can repair bit flip errors recovery means. The program lziprecover can repair bit flip errors
(one of the most common forms of data corruption) in lzip files, (one of the most common forms of data corruption) in lzip files, and
and provides data recovery capabilities, including error-checked provides data recovery capabilities, including error-checked merging
merging of damaged copies of a file. of damaged copies of a file.
* The lzip format is as simple as possible (but not simpler). The * The lzip format is as simple as possible (but not simpler). The lzip
lzip manual provides the source code of a simple decompressor manual provides the source code of a simple decompressor along with a
along with a detailed explanation of how it works, so that with detailed explanation of how it works, so that with the only help of the
the only help of the lzip manual it would be possible for a lzip manual it would be possible for a digital archaeologist to extract
digital archaeologist to extract the data from a lzip file long the data from a lzip file long after quantum computers eventually
after quantum computers eventually render LZMA obsolete. render LZMA obsolete.
* Additionally the lzip reference implementation is copylefted, which * Additionally the lzip reference implementation is copylefted, which
guarantees that it will remain free forever. guarantees that it will remain free forever.
A nice feature of the lzip format is that a corrupt byte is easier to A nice feature of the lzip format is that a corrupt byte is easier to repair
repair the nearer it is from the beginning of the file. Therefore, with the nearer it is from the beginning of the file. Therefore, with the help of
the help of lziprecover, losing an entire archive just because of a lziprecover, losing an entire archive just because of a corrupt byte near
corrupt byte near the beginning is a thing of the past. the beginning is a thing of the past.
Clzip uses the same well-defined exit status values used by lzip, which Clzip uses the same well-defined exit status values used by bzip2, which
makes it safer than compressors returning ambiguous warning values (like makes it safer than compressors returning ambiguous warning values (like
gzip) when it is used as a back end for other programs like tar or zutils. gzip) when it is used as a back end for other programs like tar or zutils.
Clzip will automatically use for each file the largest dictionary size Clzip will automatically use for each file the largest dictionary size that
that does not exceed neither the file size nor the limit given. Keep in does not exceed neither the file size nor the limit given. Keep in mind that
mind that the decompression memory requirement is affected at the decompression memory requirement is affected at compression time by the
compression time by the choice of dictionary size limit. choice of dictionary size limit.
The amount of memory required for compression is about 1 or 2 times the The amount of memory required for compression is about 1 or 2 times the
dictionary size limit (1 if input file size is less than dictionary size dictionary size limit (1 if input file size is less than dictionary size
limit, else 2) plus 9 times the dictionary size really used. The option limit, else 2) plus 9 times the dictionary size really used. The option '-0'
'-0' is special and only requires about 1.5 MiB at most. The amount of is special and only requires about 1.5 MiB at most. The amount of memory
memory required for decompression is about 46 kB larger than the required for decompression is about 46 kB larger than the dictionary size
dictionary size really used. really used.
When compressing, clzip replaces every file given in the command line When compressing, clzip replaces every file given in the command line
with a compressed version of itself, with the name "original_name.lz". with a compressed version of itself, with the name "original_name.lz".
@ -68,37 +78,36 @@ possible, ownership of the file just as 'cp -p' does. (If the user ID or
the group ID can't be duplicated, the file permission bits S_ISUID and the group ID can't be duplicated, the file permission bits S_ISUID and
S_ISGID are cleared). S_ISGID are cleared).
Clzip is able to read from some types of non regular files if the Clzip is able to read from some types of non-regular files if either the
'--stdout' option is specified. option '-c' or the option '-o' is specified.
If no file names are specified, clzip compresses (or decompresses) from If no file names are specified, clzip compresses (or decompresses) from
standard input to standard output. In this case, clzip will decline to standard input to standard output. Clzip will refuse to read compressed data
write compressed output to a terminal, as this would be entirely from a terminal or write compressed data to a terminal, as this would be
incomprehensible and therefore pointless. entirely incomprehensible and might leave the terminal in an abnormal state.
Clzip will correctly decompress a file which is the concatenation of two or Clzip will correctly decompress a file which is the concatenation of two or
more compressed files. The result is the concatenation of the corresponding more compressed files. The result is the concatenation of the corresponding
decompressed files. Integrity testing of concatenated compressed files is decompressed files. Integrity testing of concatenated compressed files is
also supported. also supported.
Clzip can produce multimember files, and lziprecover can safely recover Clzip can produce multimember files, and lziprecover can safely recover the
the undamaged members in case of file damage. Clzip can also split the undamaged members in case of file damage. Clzip can also split the compressed
compressed output in volumes of a given size, even when reading from output in volumes of a given size, even when reading from standard input.
standard input. This allows the direct creation of multivolume This allows the direct creation of multivolume compressed tar archives.
compressed tar archives.
Clzip is able to compress and decompress streams of unlimited size by Clzip is able to compress and decompress streams of unlimited size by
automatically creating multimember output. The members so created are automatically creating multimember output. The members so created are large,
large, about 2 PiB each. about 2 PiB each.
In spite of its name (Lempel-Ziv-Markov chain-Algorithm), LZMA is not a In spite of its name (Lempel-Ziv-Markov chain-Algorithm), LZMA is not a
concrete algorithm; it is more like "any algorithm using the LZMA coding concrete algorithm; it is more like "any algorithm using the LZMA coding
scheme". For example, the option '-0' of lzip uses the scheme in almost scheme". For example, the option '-0' of lzip uses the scheme in almost the
the simplest way possible; issuing the longest match it can find, or a simplest way possible; issuing the longest match it can find, or a literal
literal byte if it can't find a match. Inversely, a much more elaborated byte if it can't find a match. Inversely, a much more elaborated way of
way of finding coding sequences of minimum size than the one currently finding coding sequences of minimum size than the one currently used by lzip
used by lzip could be developed, and the resulting sequence could also could be developed, and the resulting sequence could also be coded using the
be coded using the LZMA coding scheme. LZMA coding scheme.
Clzip currently implements two variants of the LZMA algorithm; fast Clzip currently implements two variants of the LZMA algorithm; fast
(used by option '-0') and normal (used by all other compression levels). (used by option '-0') and normal (used by all other compression levels).
@ -110,20 +119,20 @@ similar order-0 entropy coder as its last stage) with segregation of
contexts according to what the bits are used for. contexts according to what the bits are used for.
The ideas embodied in clzip are due to (at least) the following people: The ideas embodied in clzip are due to (at least) the following people:
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the
the definition of Markov chains), G.N.N. Martin (for the definition of definition of Markov chains), G.N.N. Martin (for the definition of range
range encoding), Igor Pavlov (for putting all the above together in encoding), Igor Pavlov (for putting all the above together in LZMA), and
LZMA), and Julian Seward (for bzip2's CLI). Julian Seward (for bzip2's CLI).
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never have
have been compressed. Decompressed is used to refer to data which have been compressed. Decompressed is used to refer to data which have undergone
undergone the process of decompression. the process of decompression.
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy, This file is free documentation: you have unlimited permission to copy,
distribute and modify it. distribute, and modify it.
The file Makefile.in is a data file used by configure to produce the The file Makefile.in is a data file used by configure to produce the
Makefile. It has the same copyright owner and permissions that configure Makefile. It has the same copyright owner and permissions that configure

View file

@ -1,20 +1,20 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C version) /* Arg_parser - POSIX/GNU command line argument parser. (C version)
Copyright (C) 2006-2019 Antonio Diaz Diaz. Copyright (C) 2006-2021 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and This library is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided binary forms, with or without modification, are permitted provided
that the following conditions are met: that the following conditions are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/ */
#include <stdlib.h> #include <stdlib.h>

View file

@ -1,44 +1,44 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C version) /* Arg_parser - POSIX/GNU command line argument parser. (C version)
Copyright (C) 2006-2019 Antonio Diaz Diaz. Copyright (C) 2006-2021 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and This library is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided binary forms, with or without modification, are permitted provided
that the following conditions are met: that the following conditions are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/ */
/* Arg_parser reads the arguments in 'argv' and creates a number of /* Arg_parser reads the arguments in 'argv' and creates a number of
option codes, option arguments and non-option arguments. option codes, option arguments, and non-option arguments.
In case of error, 'ap_error' returns a non-null pointer to an error In case of error, 'ap_error' returns a non-null pointer to an error
message. message.
'options' is an array of 'struct ap_Option' terminated by an element 'options' is an array of 'struct ap_Option' terminated by an element
containing a code which is zero. A null name means a short-only containing a code which is zero. A null name means a short-only
option. A code value outside the unsigned char range means a option. A code value outside the unsigned char range means a
long-only option. long-only option.
Arg_parser normally makes it appear as if all the option arguments Arg_parser normally makes it appear as if all the option arguments
were specified before all the non-option arguments for the purposes were specified before all the non-option arguments for the purposes
of parsing, even if the user of your program intermixed option and of parsing, even if the user of your program intermixed option and
non-option arguments. If you want the arguments in the exact order non-option arguments. If you want the arguments in the exact order
the user typed them, call 'ap_init' with 'in_order' = true. the user typed them, call 'ap_init' with 'in_order' = true.
The argument '--' terminates all options; any following arguments are The argument '--' terminates all options; any following arguments are
treated as non-option arguments, even if they begin with a hyphen. treated as non-option arguments, even if they begin with a hyphen.
The syntax for optional option arguments is '-<short_option><argument>' The syntax for optional option arguments is '-<short_option><argument>'
(without whitespace), or '--<long_option>=<argument>'. (without whitespace), or '--<long_option>=<argument>'.
*/ */
#ifdef __cplusplus #ifdef __cplusplus
@ -79,11 +79,11 @@ void ap_free( struct Arg_parser * const ap );
const char * ap_error( const struct Arg_parser * const ap ); const char * ap_error( const struct Arg_parser * const ap );
/* The number of arguments parsed (may be different from argc) */ /* The number of arguments parsed. May be different from argc. */
int ap_arguments( const struct Arg_parser * const ap ); int ap_arguments( const struct Arg_parser * const ap );
/* If ap_code( i ) is 0, ap_argument( i ) is a non-option. /* If ap_code( i ) is 0, ap_argument( i ) is a non-option.
Else ap_argument( i ) is the option's argument (or empty). */ Else ap_argument( i ) is the option's argument (or empty). */
int ap_code( const struct Arg_parser * const ap, const int i ); int ap_code( const struct Arg_parser * const ap, const int i );
const char * ap_argument( const struct Arg_parser * const ap, const int i ); const char * ap_argument( const struct Arg_parser * const ap, const int i );

25
configure vendored
View file

@ -1,12 +1,12 @@
#! /bin/sh #! /bin/sh
# configure script for Clzip - LZMA lossless data compressor # configure script for Clzip - LZMA lossless data compressor
# Copyright (C) 2010-2019 Antonio Diaz Diaz. # Copyright (C) 2010-2021 Antonio Diaz Diaz.
# #
# This configure script is free software: you have unlimited permission # This configure script is free software: you have unlimited permission
# to copy, distribute and modify it. # to copy, distribute, and modify it.
pkgname=clzip pkgname=clzip
pkgversion=1.11 pkgversion=1.12
progname=clzip progname=clzip
srctrigger=doc/${pkgname}.texi srctrigger=doc/${pkgname}.texi
@ -26,11 +26,7 @@ CFLAGS='-Wall -W -O2'
LDFLAGS= LDFLAGS=
# checking whether we are using GNU C. # checking whether we are using GNU C.
/bin/sh -c "${CC} --version" > /dev/null 2>&1 || /bin/sh -c "${CC} --version" > /dev/null 2>&1 || { CC=cc ; CFLAGS=-O2 ; }
{
CC=cc
CFLAGS=-O2
}
# Loop over all args # Loop over all args
args= args=
@ -42,11 +38,12 @@ while [ $# != 0 ] ; do
shift shift
# Add the argument quoted to args # Add the argument quoted to args
args="${args} \"${option}\"" if [ -z "${args}" ] ; then args="\"${option}\""
else args="${args} \"${option}\"" ; fi
# Split out the argument for options that take them # Split out the argument for options that take them
case ${option} in case ${option} in
*=*) optarg=`echo ${option} | sed -e 's,^[^=]*=,,;s,/$,,'` ;; *=*) optarg=`echo "${option}" | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
esac esac
# Process the options # Process the options
@ -125,7 +122,7 @@ if [ -z "${srcdir}" ] ; then
if [ ! -r "${srcdir}/${srctrigger}" ] ; then srcdir=.. ; fi if [ ! -r "${srcdir}/${srctrigger}" ] ; then srcdir=.. ; fi
if [ ! -r "${srcdir}/${srctrigger}" ] ; then if [ ! -r "${srcdir}/${srctrigger}" ] ; then
## the sed command below emulates the dirname command ## the sed command below emulates the dirname command
srcdir=`echo $0 | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` srcdir=`echo "$0" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
fi fi
fi fi
@ -148,7 +145,7 @@ if [ -z "${no_create}" ] ; then
# Run this file to recreate the current configuration. # Run this file to recreate the current configuration.
# #
# This script is free software: you have unlimited permission # This script is free software: you have unlimited permission
# to copy, distribute and modify it. # to copy, distribute, and modify it.
exec /bin/sh $0 ${args} --no-create exec /bin/sh $0 ${args} --no-create
EOF EOF
@ -170,11 +167,11 @@ echo "LDFLAGS = ${LDFLAGS}"
rm -f Makefile rm -f Makefile
cat > Makefile << EOF cat > Makefile << EOF
# Makefile for Clzip - LZMA lossless data compressor # Makefile for Clzip - LZMA lossless data compressor
# Copyright (C) 2010-2019 Antonio Diaz Diaz. # Copyright (C) 2010-2021 Antonio Diaz Diaz.
# This file was generated automatically by configure. Don't edit. # This file was generated automatically by configure. Don't edit.
# #
# This Makefile is free software: you have unlimited permission # This Makefile is free software: you have unlimited permission
# to copy, distribute and modify it. # to copy, distribute, and modify it.
pkgname = ${pkgname} pkgname = ${pkgname}
pkgversion = ${pkgversion} pkgversion = ${pkgversion}

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
@ -159,16 +159,15 @@ static bool LZd_verify_trailer( struct LZ_decoder * const d,
{ {
if( verbosity >= 4 ) show_header( d->dictionary_size ); if( verbosity >= 4 ) show_header( d->dictionary_size );
if( data_size == 0 || member_size == 0 ) if( data_size == 0 || member_size == 0 )
fputs( "no data compressed. ", stderr ); fputs( "no data compressed. ", stderr );
else else
fprintf( stderr, "%6.3f:1, %5.2f%% ratio, %5.2f%% saved. ", fprintf( stderr, "%6.3f:1, %5.2f%% ratio, %5.2f%% saved. ",
(double)data_size / member_size, (double)data_size / member_size,
( 100.0 * member_size ) / data_size, ( 100.0 * member_size ) / data_size,
100.0 - ( ( 100.0 * member_size ) / data_size ) ); 100.0 - ( ( 100.0 * member_size ) / data_size ) );
if( verbosity >= 4 ) fprintf( stderr, "CRC %08X, ", td_crc ); if( verbosity >= 4 ) fprintf( stderr, "CRC %08X, ", td_crc );
if( verbosity >= 3 ) if( verbosity >= 3 )
fprintf( stderr, "decompressed %9llu, compressed %8llu. ", fprintf( stderr, "%9llu out, %8llu in. ", data_size, member_size );
data_size, member_size );
} }
return true; return true;
} }

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
enum { rd_buffer_size = 16384 }; enum { rd_buffer_size = 16384 };
@ -107,7 +107,7 @@ static inline unsigned Rd_decode( struct Range_decoder * const rdec,
/* symbol <<= 1; */ /* symbol <<= 1; */
/* if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */ /* if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */
bit = ( rdec->code >= rdec->range ); bit = ( rdec->code >= rdec->range );
symbol = ( symbol << 1 ) + bit; symbol <<= 1; symbol += bit;
rdec->code -= rdec->range & ( 0U - bit ); rdec->code -= rdec->range & ( 0U - bit );
} }
return symbol; return symbol;
@ -137,8 +137,7 @@ static inline unsigned Rd_decode_bit( struct Range_decoder * const rdec,
static inline unsigned Rd_decode_tree3( struct Range_decoder * const rdec, static inline unsigned Rd_decode_tree3( struct Range_decoder * const rdec,
Bit_model bm[] ) Bit_model bm[] )
{ {
unsigned symbol = 1; unsigned symbol = 2 | Rd_decode_bit( rdec, &bm[1] );
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] );
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
return symbol & 7; return symbol & 7;
@ -147,8 +146,7 @@ static inline unsigned Rd_decode_tree3( struct Range_decoder * const rdec,
static inline unsigned Rd_decode_tree6( struct Range_decoder * const rdec, static inline unsigned Rd_decode_tree6( struct Range_decoder * const rdec,
Bit_model bm[] ) Bit_model bm[] )
{ {
unsigned symbol = 1; unsigned symbol = 2 | Rd_decode_bit( rdec, &bm[1] );
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] );
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] ); symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
@ -177,7 +175,7 @@ Rd_decode_tree_reversed( struct Range_decoder * const rdec,
for( i = 0; i < num_bits; ++i ) for( i = 0; i < num_bits; ++i )
{ {
const unsigned bit = Rd_decode_bit( rdec, &bm[model] ); const unsigned bit = Rd_decode_bit( rdec, &bm[model] );
model = ( model << 1 ) + bit; model <<= 1; model += bit;
symbol |= ( bit << i ); symbol |= ( bit << i );
} }
return symbol; return symbol;
@ -187,12 +185,9 @@ static inline unsigned
Rd_decode_tree_reversed4( struct Range_decoder * const rdec, Bit_model bm[] ) Rd_decode_tree_reversed4( struct Range_decoder * const rdec, Bit_model bm[] )
{ {
unsigned symbol = Rd_decode_bit( rdec, &bm[1] ); unsigned symbol = Rd_decode_bit( rdec, &bm[1] );
unsigned model = 2 + symbol; symbol += Rd_decode_bit( rdec, &bm[2+symbol] ) << 1;
unsigned bit = Rd_decode_bit( rdec, &bm[model] ); symbol += Rd_decode_bit( rdec, &bm[4+symbol] ) << 2;
model = ( model << 1 ) + bit; symbol |= ( bit << 1 ); symbol += Rd_decode_bit( rdec, &bm[8+symbol] ) << 3;
bit = Rd_decode_bit( rdec, &bm[model] );
model = ( model << 1 ) + bit; symbol |= ( bit << 2 );
symbol |= ( Rd_decode_bit( rdec, &bm[model] ) << 3 );
return symbol; return symbol;
} }
@ -205,7 +200,7 @@ static inline unsigned Rd_decode_matched( struct Range_decoder * const rdec,
{ {
const unsigned match_bit = ( match_byte <<= 1 ) & mask; const unsigned match_bit = ( match_byte <<= 1 ) & mask;
const unsigned bit = Rd_decode_bit( rdec, &bm[symbol+match_bit+mask] ); const unsigned bit = Rd_decode_bit( rdec, &bm[symbol+match_bit+mask] );
symbol = ( symbol << 1 ) + bit; symbol <<= 1; symbol += bit;
if( symbol > 0xFF ) return symbol & 0xFF; if( symbol > 0xFF ) return symbol & 0xFF;
mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */ mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */
} }

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
.TH CLZIP "1" "January 2019" "clzip 1.11" "User Commands" .TH CLZIP "1" "January 2021" "clzip 1.12" "User Commands"
.SH NAME .SH NAME
clzip \- reduces the size of files clzip \- reduces the size of files
.SH SYNOPSIS .SH SYNOPSIS
@ -8,16 +8,18 @@ clzip \- reduces the size of files
.SH DESCRIPTION .SH DESCRIPTION
Clzip is a C language version of lzip, fully compatible with lzip 1.4 or Clzip is a C language version of lzip, fully compatible with lzip 1.4 or
newer. As clzip is written in C, it may be easier to integrate in newer. As clzip is written in C, it may be easier to integrate in
applications like package managers, embedded devices, or systems lacking applications like package managers, embedded devices, or systems lacking a
a C++ compiler. C++ compiler.
.PP .PP
Lzip is a lossless data compressor with a user interface similar to the Lzip is a lossless data compressor with a user interface similar to the one
one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip \fB\-0\fR) of gzip or bzip2. Lzip uses a simplified form of the 'Lempel\-Ziv\-Markov
or compress most files more than bzip2 (lzip \fB\-9\fR). Decompression speed is chain\-Algorithm' (LZMA) stream format, chosen to maximize safety and
intermediate between gzip and bzip2. Lzip is better than gzip and bzip2 interoperability. Lzip can compress about as fast as gzip (lzip \fB\-0\fR) or
from a data recovery perspective. Lzip has been designed, written and compress most files more than bzip2 (lzip \fB\-9\fR). Decompression speed is
tested with great care to replace gzip and bzip2 as the standard intermediate between gzip and bzip2. Lzip is better than gzip and bzip2 from
general\-purpose compressed format for unix\-like systems. a data recovery perspective. Lzip has been designed, written, and tested
with great care to replace gzip and bzip2 as the standard general\-purpose
compressed format for unix\-like systems.
.SH OPTIONS .SH OPTIONS
.TP .TP
\fB\-h\fR, \fB\-\-help\fR \fB\-h\fR, \fB\-\-help\fR
@ -54,7 +56,7 @@ print (un)compressed file sizes
set match length limit in bytes [36] set match length limit in bytes [36]
.TP .TP
\fB\-o\fR, \fB\-\-output=\fR<file> \fB\-o\fR, \fB\-\-output=\fR<file>
if reading standard input, write to <file> write to <file>, keep input files
.TP .TP
\fB\-q\fR, \fB\-\-quiet\fR \fB\-q\fR, \fB\-\-quiet\fR
suppress all messages suppress all messages
@ -92,19 +94,28 @@ to 2^29 bytes.
.PP .PP
The bidimensional parameter space of LZMA can't be mapped to a linear The bidimensional parameter space of LZMA can't be mapped to a linear
scale optimal for all files. If your files are large, very repetitive, scale optimal for all files. If your files are large, very repetitive,
etc, you may need to use the \fB\-\-dictionary\-size\fR and \fB\-\-match\-length\fR etc, you may need to use the options \fB\-\-dictionary\-size\fR and \fB\-\-match\-length\fR
options directly to achieve optimal performance. directly to achieve optimal performance.
.PP
To extract all the files from archive 'foo.tar.lz', use the commands
\&'tar \fB\-xf\fR foo.tar.lz' or 'clzip \fB\-cd\fR foo.tar.lz | tar \fB\-xf\fR \-'.
.PP .PP
Exit status: 0 for a normal exit, 1 for environmental problems (file 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 not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or
invalid input file, 3 for an internal consistency error (eg, bug) which invalid input file, 3 for an internal consistency error (eg, bug) which
caused clzip to panic. caused clzip to panic.
.PP
The ideas embodied in clzip are due to (at least) the following people:
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the
definition of Markov chains), G.N.N. Martin (for the definition of range
encoding), Igor Pavlov (for putting all the above together in LZMA), and
Julian Seward (for bzip2's CLI).
.SH "REPORTING BUGS" .SH "REPORTING BUGS"
Report bugs to lzip\-bug@nongnu.org Report bugs to lzip\-bug@nongnu.org
.br .br
Clzip home page: http://www.nongnu.org/lzip/clzip.html Clzip home page: http://www.nongnu.org/lzip/clzip.html
.SH COPYRIGHT .SH COPYRIGHT
Copyright \(co 2019 Antonio Diaz Diaz. Copyright \(co 2021 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html> License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br .br
This is free software: you are free to change and redistribute it. This is free software: you are free to change and redistribute it.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
@ -37,7 +37,7 @@ int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs )
int32_t * ptr1 = ptr0 + 1; int32_t * ptr1 = ptr0 + 1;
int32_t * newptr; int32_t * newptr;
int len = 0, len0 = 0, len1 = 0; int len = 0, len0 = 0, len1 = 0;
int maxlen = 0; int maxlen = 3; /* only used if pairs != 0 */
int num_pairs = 0; int num_pairs = 0;
const int pos1 = e->eb.mb.pos + 1; const int pos1 = e->eb.mb.pos + 1;
const int min_pos = ( e->eb.mb.pos > e->eb.mb.dictionary_size ) ? const int min_pos = ( e->eb.mb.pos > e->eb.mb.dictionary_size ) ?
@ -62,8 +62,8 @@ int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs )
if( pairs ) if( pairs )
{ {
int np2 = e->eb.mb.prev_positions[key2]; const int np2 = e->eb.mb.prev_positions[key2];
int np3 = e->eb.mb.prev_positions[key3]; const int np3 = e->eb.mb.prev_positions[key3];
if( np2 > min_pos && e->eb.mb.buffer[np2-1] == data[0] ) if( np2 > min_pos && e->eb.mb.buffer[np2-1] == data[0] )
{ {
pairs[0].dis = e->eb.mb.pos - np2; pairs[0].dis = e->eb.mb.pos - np2;
@ -73,19 +73,17 @@ int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs )
if( np2 != np3 && np3 > min_pos && e->eb.mb.buffer[np3-1] == data[0] ) if( np2 != np3 && np3 > min_pos && e->eb.mb.buffer[np3-1] == data[0] )
{ {
maxlen = 3; maxlen = 3;
np2 = np3; pairs[num_pairs++].dis = e->eb.mb.pos - np3;
pairs[num_pairs].dis = e->eb.mb.pos - np2;
++num_pairs;
} }
if( num_pairs > 0 ) if( num_pairs > 0 )
{ {
const int delta = pos1 - np2; const int delta = pairs[num_pairs-1].dis + 1;
while( maxlen < len_limit && data[maxlen-delta] == data[maxlen] ) while( maxlen < len_limit && data[maxlen-delta] == data[maxlen] )
++maxlen; ++maxlen;
pairs[num_pairs-1].len = maxlen; pairs[num_pairs-1].len = maxlen;
if( maxlen < 3 ) maxlen = 3;
if( maxlen >= len_limit ) pairs = 0; /* done. now just skip */ if( maxlen >= len_limit ) pairs = 0; /* done. now just skip */
} }
if( maxlen < 3 ) maxlen = 3;
} }
e->eb.mb.prev_positions[key2] = pos1; e->eb.mb.prev_positions[key2] = pos1;

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
struct Len_prices struct Len_prices

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
@ -95,11 +95,10 @@ bool Mb_init( struct Matchfinder_base * const mb, const int before_size,
if( Mb_read_block( mb ) && !mb->at_stream_end && if( Mb_read_block( mb ) && !mb->at_stream_end &&
mb->buffer_size < buffer_size_limit ) mb->buffer_size < buffer_size_limit )
{ {
uint8_t * tmp; uint8_t * const tmp = (uint8_t *)realloc( mb->buffer, buffer_size_limit );
mb->buffer_size = buffer_size_limit;
tmp = (uint8_t *)realloc( mb->buffer, mb->buffer_size );
if( !tmp ) { free( mb->buffer ); return false; } if( !tmp ) { free( mb->buffer ); return false; }
mb->buffer = tmp; mb->buffer = tmp;
mb->buffer_size = buffer_size_limit;
Mb_read_block( mb ); Mb_read_block( mb );
} }
if( mb->at_stream_end && mb->stream_pos < dict_size ) if( mb->at_stream_end && mb->stream_pos < dict_size )
@ -167,7 +166,7 @@ void Re_flush_data( struct Range_encoder * const renc )
} }
/* End Of Stream mark => (dis == 0xFFFFFFFFU, len == min_match_len) */ /* End Of Stream marker => (dis == 0xFFFFFFFFU, len == min_match_len) */
void LZeb_full_flush( struct LZ_encoder_base * const eb, const State state ) void LZeb_full_flush( struct LZ_encoder_base * const eb, const State state )
{ {
int i; int i;

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
enum { price_shift_bits = 6, enum { price_shift_bits = 6,
@ -133,7 +133,7 @@ static inline int price_symbol_reversed( const Bit_model bm[], int symbol,
const bool bit = symbol & 1; const bool bit = symbol & 1;
symbol >>= 1; symbol >>= 1;
price += price_bit( bm[model], bit ); price += price_bit( bm[model], bit );
model = ( model << 1 ) | bit; model <<= 1; model |= bit;
} }
return price; return price;
} }
@ -333,28 +333,30 @@ static inline void Re_encode_bit( struct Range_encoder * const renc,
static inline void Re_encode_tree3( struct Range_encoder * const renc, static inline void Re_encode_tree3( struct Range_encoder * const renc,
Bit_model bm[], const int symbol ) Bit_model bm[], const int symbol )
{ {
int model = 1; int model;
bool bit = ( symbol >> 2 ) & 1; bool bit = ( symbol >> 2 ) & 1;
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; Re_encode_bit( renc, &bm[1], bit );
model = 2 | bit;
bit = ( symbol >> 1 ) & 1; bit = ( symbol >> 1 ) & 1;
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
Re_encode_bit( renc, &bm[model], symbol & 1 ); Re_encode_bit( renc, &bm[model], symbol & 1 );
} }
static inline void Re_encode_tree6( struct Range_encoder * const renc, static inline void Re_encode_tree6( struct Range_encoder * const renc,
Bit_model bm[], const unsigned symbol ) Bit_model bm[], const unsigned symbol )
{ {
int model = 1; int model;
bool bit = ( symbol >> 5 ) & 1; bool bit = ( symbol >> 5 ) & 1;
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; Re_encode_bit( renc, &bm[1], bit );
model = 2 | bit;
bit = ( symbol >> 4 ) & 1; bit = ( symbol >> 4 ) & 1;
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
bit = ( symbol >> 3 ) & 1; bit = ( symbol >> 3 ) & 1;
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
bit = ( symbol >> 2 ) & 1; bit = ( symbol >> 2 ) & 1;
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
bit = ( symbol >> 1 ) & 1; bit = ( symbol >> 1 ) & 1;
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
Re_encode_bit( renc, &bm[model], symbol & 1 ); Re_encode_bit( renc, &bm[model], symbol & 1 );
} }
@ -367,7 +369,7 @@ static inline void Re_encode_tree8( struct Range_encoder * const renc,
{ {
const bool bit = ( symbol >> i ) & 1; const bool bit = ( symbol >> i ) & 1;
Re_encode_bit( renc, &bm[model], bit ); Re_encode_bit( renc, &bm[model], bit );
model = ( model << 1 ) | bit; model <<= 1; model |= bit;
} }
} }
@ -381,7 +383,7 @@ static inline void Re_encode_tree_reversed( struct Range_encoder * const renc,
const bool bit = symbol & 1; const bool bit = symbol & 1;
symbol >>= 1; symbol >>= 1;
Re_encode_bit( renc, &bm[model], bit ); Re_encode_bit( renc, &bm[model], bit );
model = ( model << 1 ) | bit; model <<= 1; model |= bit;
} }
} }

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
struct FLZ_encoder struct FLZ_encoder

55
list.c
View file

@ -1,26 +1,26 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdint.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -33,11 +33,11 @@ static void list_line( const unsigned long long uncomp_size,
const char * const input_filename ) const char * const input_filename )
{ {
if( uncomp_size > 0 ) if( uncomp_size > 0 )
printf( "%15llu %15llu %6.2f%% %s\n", uncomp_size, comp_size, printf( "%14llu %14llu %6.2f%% %s\n", uncomp_size, comp_size,
100.0 - ( ( 100.0 * comp_size ) / uncomp_size ), 100.0 - ( ( 100.0 * comp_size ) / uncomp_size ),
input_filename ); input_filename );
else else
printf( "%15llu %15llu -INF%% %s\n", uncomp_size, comp_size, printf( "%14llu %14llu -INF%% %s\n", uncomp_size, comp_size,
input_filename ); input_filename );
} }
@ -60,15 +60,15 @@ int list_files( const char * const filenames[], const int num_filenames,
if( from_stdin ) { if( stdin_used ) continue; else stdin_used = true; } if( from_stdin ) { if( stdin_used ) continue; else stdin_used = true; }
input_filename = from_stdin ? "(stdin)" : filenames[i]; input_filename = from_stdin ? "(stdin)" : filenames[i];
infd = from_stdin ? STDIN_FILENO : infd = from_stdin ? STDIN_FILENO :
open_instream( input_filename, &in_stats, true, true ); open_instream( input_filename, &in_stats, false, true );
if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; } if( infd < 0 ) { set_retval( &retval, 1 ); continue; }
Li_init( &lzip_index, infd, ignore_trailing, loose_trailing ); Li_init( &lzip_index, infd, ignore_trailing, loose_trailing );
close( infd ); close( infd );
if( lzip_index.retval != 0 ) if( lzip_index.retval != 0 )
{ {
show_file_error( input_filename, lzip_index.error, 0 ); show_file_error( input_filename, lzip_index.error, 0 );
if( retval < lzip_index.retval ) retval = lzip_index.retval; set_retval( &retval, lzip_index.retval );
Li_free( &lzip_index ); continue; Li_free( &lzip_index ); continue;
} }
if( verbosity >= 0 ) if( verbosity >= 0 )
@ -80,31 +80,22 @@ int list_files( const char * const filenames[], const int num_filenames,
{ {
first_post = false; first_post = false;
if( verbosity >= 1 ) fputs( " dict memb trail ", stdout ); if( verbosity >= 1 ) fputs( " dict memb trail ", stdout );
fputs( " uncompressed compressed saved name\n", stdout ); fputs( " uncompressed compressed saved name\n", stdout );
} }
if( verbosity >= 1 ) if( verbosity >= 1 )
{ printf( "%s %5ld %6lld ", format_ds( lzip_index.dictionary_size ),
long long trailing_size; lzip_index.members, Li_file_size( &lzip_index ) - cdata_size );
unsigned dictionary_size = 0;
long i;
for( i = 0; i < lzip_index.members; ++i )
dictionary_size =
max( dictionary_size, Li_dictionary_size( &lzip_index, i ) );
trailing_size = Li_file_size( &lzip_index ) - cdata_size;
printf( "%s %5ld %6lld ", format_ds( dictionary_size ),
lzip_index.members, trailing_size );
}
list_line( udata_size, cdata_size, input_filename ); list_line( udata_size, cdata_size, input_filename );
if( verbosity >= 2 && lzip_index.members > 1 ) if( verbosity >= 2 && lzip_index.members > 1 )
{ {
long i; long i;
fputs( " member data_pos data_size member_pos member_size\n", stdout ); fputs( " member data_pos data_size member_pos member_size\n", stdout );
for( i = 0; i < lzip_index.members; ++i ) for( i = 0; i < lzip_index.members; ++i )
{ {
const struct Block * db = Li_dblock( &lzip_index, i ); const struct Block * db = Li_dblock( &lzip_index, i );
const struct Block * mb = Li_mblock( &lzip_index, i ); const struct Block * mb = Li_mblock( &lzip_index, i );
printf( "%5ld %15llu %15llu %15llu %15llu\n", printf( "%6ld %14llu %14llu %14llu %14llu\n",
i + 1, db->pos, db->size, mb->pos, mb->size ); i + 1, db->pos, db->size, mb->pos, mb->size );
} }
first_post = true; /* reprint heading after list of members */ first_post = true; /* reprint heading after list of members */

105
lzip.h
View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef max #ifndef max
@ -22,8 +22,6 @@
#define min(x,y) ((x) <= (y) ? (x) : (y)) #define min(x,y) ((x) <= (y) ? (x) : (y))
#endif #endif
void * resize_buffer( void * buf, const unsigned min_size );
typedef int State; typedef int State;
enum { states = 12 }; enum { states = 12 };
@ -84,7 +82,7 @@ static inline int get_len_state( const int len )
{ return min( len - min_match_len, len_states - 1 ); } { return min( len - min_match_len, len_states - 1 ); }
static inline int get_lit_state( const uint8_t prev_byte ) static inline int get_lit_state( const uint8_t prev_byte )
{ return ( prev_byte >> ( 8 - literal_context_bits ) ); } { return prev_byte >> ( 8 - literal_context_bits ); }
enum { bit_model_move_bits = 5, enum { bit_model_move_bits = 5,
@ -118,65 +116,6 @@ static inline void Lm_init( struct Len_model * const lm )
} }
/* defined in main.c */
extern int verbosity;
struct Pretty_print /* requires global var 'int verbosity' */
{
const char * name;
char * padded_name;
const char * stdin_name;
unsigned longest_name;
bool first_post;
};
static inline 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->padded_name = 0;
pp->stdin_name = "(stdin)";
pp->longest_name = 0;
pp->first_post = false;
if( verbosity <= 0 ) return;
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( pp->longest_name < len ) 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 )
{
unsigned name_len, padded_name_len, i = 0;
if( filename && filename[0] && strcmp( filename, "-" ) != 0 )
pp->name = filename;
else pp->name = pp->stdin_name;
name_len = strlen( pp->name );
padded_name_len = max( name_len, pp->longest_name ) + 4;
pp->padded_name = resize_buffer( pp->padded_name, padded_name_len + 1 );
while( i < 2 ) pp->padded_name[i++] = ' ';
while( i < name_len + 2 ) { pp->padded_name[i] = pp->name[i-2]; ++i; }
pp->padded_name[i++] = ':';
while( i < padded_name_len ) pp->padded_name[i++] = ' ';
pp->padded_name[i] = 0;
pp->first_post = true;
}
static inline void Pp_reset( struct Pretty_print * const pp )
{ if( pp->name && pp->name[0] ) pp->first_post = true; }
void Pp_show_msg( struct Pretty_print * const pp, const char * const msg );
typedef uint32_t CRC32[256]; /* Table of CRCs of all 8-bit messages. */ typedef uint32_t CRC32[256]; /* Table of CRCs of all 8-bit messages. */
extern CRC32 crc32; extern CRC32 crc32;
@ -226,7 +165,7 @@ static const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
typedef uint8_t Lzip_header[6]; /* 0-3 magic bytes */ typedef uint8_t Lzip_header[6]; /* 0-3 magic bytes */
/* 4 version */ /* 4 version */
/* 5 coded_dict_size */ /* 5 coded dictionary size */
enum { Lh_size = 6 }; enum { Lh_size = 6 };
static inline void Lh_set_magic( Lzip_header data ) static inline void Lh_set_magic( Lzip_header data )
@ -282,6 +221,12 @@ static inline bool Lh_set_dictionary_size( Lzip_header data, const unsigned sz )
return true; return true;
} }
static inline bool Lh_verify( const Lzip_header data )
{
return Lh_verify_magic( data ) && Lh_verify_version( data ) &&
isvalid_ds( Lh_get_dictionary_size( data ) );
}
typedef uint8_t Lzip_trailer[20]; typedef uint8_t Lzip_trailer[20];
/* 0-3 CRC32 of the uncompressed data */ /* 0-3 CRC32 of the uncompressed data */
@ -335,10 +280,14 @@ static inline bool Lt_verify_consistency( const Lzip_trailer data )
} }
static inline void set_retval( int * retval, const int new_val )
{ if( *retval < new_val ) *retval = new_val; }
static const char * const bad_magic_msg = "Bad magic number (file not in lzip format)."; static const char * const bad_magic_msg = "Bad magic number (file not in lzip format).";
static const char * const bad_dict_msg = "Invalid dictionary size in member header."; static const char * const bad_dict_msg = "Invalid dictionary size in member header.";
static const char * const corrupt_mm_msg = "Corrupt header in multimember file."; static const char * const corrupt_mm_msg = "Corrupt header in multimember file.";
static const char * const trailing_msg = "Trailing data not allowed."; static const char * const trailing_msg = "Trailing data not allowed.";
static const char * const mem_msg = "Not enough memory.";
/* defined in decoder.c */ /* defined in decoder.c */
int readblock( const int fd, uint8_t * const buf, const int size ); int readblock( const int fd, uint8_t * const buf, const int size );
@ -350,11 +299,15 @@ int list_files( const char * const filenames[], const int num_filenames,
/* defined in main.c */ /* defined in main.c */
struct stat; struct stat;
struct Pretty_print;
extern int verbosity;
void * resize_buffer( void * buf, const unsigned min_size );
void Pp_show_msg( struct Pretty_print * const pp, const char * const msg );
const char * bad_version( const unsigned version ); const char * bad_version( const unsigned version );
const char * format_ds( const unsigned dictionary_size ); const char * format_ds( const unsigned dictionary_size );
void show_header( const unsigned dictionary_size ); void show_header( const unsigned dictionary_size );
int open_instream( const char * const name, struct stat * const in_statsp, int open_instream( const char * const name, struct stat * const in_statsp,
const bool no_ofile, const bool reg_only ); const bool one_to_one, const bool reg_only );
void cleanup_and_fail( const int retval ); void cleanup_and_fail( const int retval );
void show_error( const char * const msg, const int errcode, const bool help ); void show_error( const char * const msg, const int errcode, const bool help );
void show_file_error( const char * const filename, const char * const msg, void show_file_error( const char * const filename, const char * const msg,

View file

@ -1,28 +1,28 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <errno.h> #include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include "lzip.h" #include "lzip.h"
@ -58,8 +58,7 @@ static bool push_back_member( struct Lzip_index * const li,
struct Member * p; struct Member * p;
void * tmp = resize_buffer( li->member_vector, void * tmp = resize_buffer( li->member_vector,
( li->members + 1 ) * sizeof li->member_vector[0] ); ( li->members + 1 ) * sizeof li->member_vector[0] );
if( !tmp ) if( !tmp ) { add_error( li, mem_msg ); li->retval = 1; return false; }
{ add_error( li, "Not enough memory." ); li->retval = 1; return false; }
li->member_vector = (struct Member *)tmp; li->member_vector = (struct Member *)tmp;
p = &(li->member_vector[li->members]); p = &(li->member_vector[li->members]);
init_member( p, dp, ds, mp, ms, dict_size ); init_member( p, dp, ds, mp, ms, dict_size );
@ -89,6 +88,19 @@ static void Li_reverse_member_vector( struct Lzip_index * const li )
} }
static bool Li_check_header_error( struct Lzip_index * const li,
const Lzip_header header )
{
if( !Lh_verify_magic( header ) )
{ add_error( li, bad_magic_msg ); li->retval = 2; return true; }
if( !Lh_verify_version( header ) )
{ add_error( li, bad_version( Lh_version( header ) ) ); li->retval = 2;
return true; }
if( !isvalid_ds( Lh_get_dictionary_size( header ) ) )
{ add_error( li, bad_dict_msg ); li->retval = 2; return true; }
return false;
}
static void Li_set_errno_error( struct Lzip_index * const li, static void Li_set_errno_error( struct Lzip_index * const li,
const char * const msg ) const char * const msg )
{ {
@ -106,9 +118,18 @@ static void Li_set_num_error( struct Lzip_index * const li,
} }
static bool Li_read_header( struct Lzip_index * const li, const int fd,
Lzip_header header, const long long pos )
{
if( seek_read( fd, header, Lh_size, pos ) != Lh_size )
{ Li_set_errno_error( li, "Error reading member header: " ); return false; }
return true;
}
/* If successful, push last member and set pos to member header. */ /* If successful, push last member and set pos to member header. */
static bool Li_skip_trailing_data( struct Lzip_index * const li, static bool Li_skip_trailing_data( struct Lzip_index * const li, const int fd,
const int fd, long long * const pos, unsigned long long * const pos,
const bool ignore_trailing, const bool ignore_trailing,
const bool loose_trailing ) const bool loose_trailing )
{ {
@ -135,36 +156,40 @@ static bool Li_skip_trailing_data( struct Lzip_index * const li,
if( buffer[i-1] <= max_msb ) /* most significant byte of member_size */ if( buffer[i-1] <= max_msb ) /* most significant byte of member_size */
{ {
Lzip_header header; Lzip_header header;
const Lzip_header * header2;
const Lzip_trailer * const trailer = const Lzip_trailer * const trailer =
(const Lzip_trailer *)( buffer + i - Lt_size ); (const Lzip_trailer *)( buffer + i - Lt_size );
const unsigned long long member_size = Lt_get_member_size( *trailer ); const unsigned long long member_size = Lt_get_member_size( *trailer );
unsigned dictionary_size; unsigned dictionary_size;
bool full_h2;
if( member_size == 0 ) /* skip trailing zeros */ if( member_size == 0 ) /* skip trailing zeros */
{ while( i > Lt_size && buffer[i-9] == 0 ) --i; continue; } { while( i > Lt_size && buffer[i-9] == 0 ) --i; continue; }
if( member_size > ipos + i || !Lt_verify_consistency( *trailer ) ) if( member_size > ipos + i || !Lt_verify_consistency( *trailer ) )
continue; continue;
if( seek_read( fd, header, Lh_size, if( !Li_read_header( li, fd, header, ipos + i - member_size ) )
ipos + i - member_size ) != Lh_size ) return false;
{ Li_set_errno_error( li, "Error reading member header: " ); if( !Lh_verify( header ) ) continue;
return false; } header2 = (const Lzip_header *)( buffer + i );
dictionary_size = Lh_get_dictionary_size( header ); full_h2 = bsize - i >= Lh_size;
if( !Lh_verify_magic( header ) || !Lh_verify_version( header ) || if( Lh_verify_prefix( *header2, bsize - i ) ) /* last member */
!isvalid_ds( dictionary_size ) ) continue;
if( Lh_verify_prefix( buffer + i, bsize - i ) )
{ {
add_error( li, "Last member in input file is truncated or corrupt." ); if( !full_h2 ) add_error( li, "Last member in input file is truncated." );
else if( !Li_check_header_error( li, *header2 ) )
add_error( li, "Last member in input file is truncated or corrupt." );
li->retval = 2; return false; li->retval = 2; return false;
} }
if( !loose_trailing && bsize - i >= Lh_size && if( !loose_trailing && full_h2 && Lh_verify_corrupt( *header2 ) )
Lh_verify_corrupt( buffer + i ) )
{ add_error( li, corrupt_mm_msg ); li->retval = 2; return false; } { add_error( li, corrupt_mm_msg ); li->retval = 2; return false; }
if( !ignore_trailing ) if( !ignore_trailing )
{ add_error( li, trailing_msg ); li->retval = 2; return false; } { add_error( li, trailing_msg ); li->retval = 2; return false; }
*pos = ipos + i - member_size; *pos = ipos + i - member_size;
dictionary_size = Lh_get_dictionary_size( header );
if( li->dictionary_size < dictionary_size )
li->dictionary_size = dictionary_size;
return push_back_member( li, 0, Lt_get_data_size( *trailer ), *pos, return push_back_member( li, 0, Lt_get_data_size( *trailer ), *pos,
member_size, dictionary_size ); member_size, dictionary_size );
} }
if( ipos <= 0 ) if( ipos == 0 )
{ Li_set_num_error( li, "Bad trailer at pos ", *pos - Lt_size ); { Li_set_num_error( li, "Bad trailer at pos ", *pos - Lt_size );
return false; } return false; }
bsize = buffer_size; bsize = buffer_size;
@ -180,7 +205,7 @@ bool Li_init( struct Lzip_index * const li, const int infd,
const bool ignore_trailing, const bool loose_trailing ) const bool ignore_trailing, const bool loose_trailing )
{ {
Lzip_header header; Lzip_header header;
long long pos; unsigned long long pos;
long i; long i;
li->member_vector = 0; li->member_vector = 0;
li->error = 0; li->error = 0;
@ -188,6 +213,7 @@ bool Li_init( struct Lzip_index * const li, const int infd,
li->members = 0; li->members = 0;
li->error_size = 0; li->error_size = 0;
li->retval = 0; li->retval = 0;
li->dictionary_size = 0;
if( li->insize < 0 ) if( li->insize < 0 )
{ Li_set_errno_error( li, "Input file is not seekable: " ); return false; } { Li_set_errno_error( li, "Input file is not seekable: " ); return false; }
if( li->insize < min_member_size ) if( li->insize < min_member_size )
@ -197,15 +223,8 @@ bool Li_init( struct Lzip_index * const li, const int infd,
{ add_error( li, "Input file is too long (2^63 bytes or more)." ); { add_error( li, "Input file is too long (2^63 bytes or more)." );
li->retval = 2; return false; } li->retval = 2; return false; }
if( seek_read( infd, header, Lh_size, 0 ) != Lh_size ) if( !Li_read_header( li, infd, header, 0 ) ) return false;
{ Li_set_errno_error( li, "Error reading member header: " ); return false; } if( Li_check_header_error( li, header ) ) return false;
if( !Lh_verify_magic( header ) )
{ add_error( li, bad_magic_msg ); li->retval = 2; return false; }
if( !Lh_verify_version( header ) )
{ add_error( li, bad_version( Lh_version( header ) ) ); li->retval = 2;
return false; }
if( !isvalid_ds( Lh_get_dictionary_size( header ) ) )
{ add_error( li, bad_dict_msg ); li->retval = 2; return false; }
pos = li->insize; /* always points to a header or to EOF */ pos = li->insize; /* always points to a header or to EOF */
while( pos >= min_member_size ) while( pos >= min_member_size )
@ -216,19 +235,16 @@ bool Li_init( struct Lzip_index * const li, const int infd,
if( seek_read( infd, trailer, Lt_size, pos - Lt_size ) != Lt_size ) if( seek_read( infd, trailer, Lt_size, pos - Lt_size ) != Lt_size )
{ Li_set_errno_error( li, "Error reading member trailer: " ); break; } { Li_set_errno_error( li, "Error reading member trailer: " ); break; }
member_size = Lt_get_member_size( trailer ); member_size = Lt_get_member_size( trailer );
if( member_size > (unsigned long long)pos || !Lt_verify_consistency( trailer ) ) if( member_size > pos || !Lt_verify_consistency( trailer ) )
{ { /* bad trailer */
if( li->members <= 0 ) if( li->members <= 0 )
{ if( Li_skip_trailing_data( li, infd, &pos, ignore_trailing, { if( Li_skip_trailing_data( li, infd, &pos, ignore_trailing,
loose_trailing ) ) continue; else return false; } loose_trailing ) ) continue; else return false; }
Li_set_num_error( li, "Bad trailer at pos ", pos - Lt_size ); Li_set_num_error( li, "Bad trailer at pos ", pos - Lt_size );
break; break;
} }
if( seek_read( infd, header, Lh_size, pos - member_size ) != Lh_size ) if( !Li_read_header( li, infd, header, pos - member_size ) ) break;
{ Li_set_errno_error( li, "Error reading member header: " ); break; } if( !Lh_verify( header ) ) /* bad header */
dictionary_size = Lh_get_dictionary_size( header );
if( !Lh_verify_magic( header ) || !Lh_verify_version( header ) ||
!isvalid_ds( dictionary_size ) )
{ {
if( li->members <= 0 ) if( li->members <= 0 )
{ if( Li_skip_trailing_data( li, infd, &pos, ignore_trailing, { if( Li_skip_trailing_data( li, infd, &pos, ignore_trailing,
@ -237,6 +253,9 @@ bool Li_init( struct Lzip_index * const li, const int infd,
break; break;
} }
pos -= member_size; pos -= member_size;
dictionary_size = Lh_get_dictionary_size( header );
if( li->dictionary_size < dictionary_size )
li->dictionary_size = dictionary_size;
if( !push_back_member( li, 0, Lt_get_data_size( trailer ), pos, if( !push_back_member( li, 0, Lt_get_data_size( trailer ), pos,
member_size, dictionary_size ) ) member_size, dictionary_size ) )
return false; return false;

View file

@ -1,18 +1,18 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INT64_MAX #ifndef INT64_MAX
@ -54,6 +54,7 @@ struct Lzip_index
long members; long members;
int error_size; int error_size;
int retval; int retval;
unsigned dictionary_size; /* largest dictionary size in the file */
}; };
bool Li_init( struct Lzip_index * const li, const int infd, bool Li_init( struct Lzip_index * const li, const int infd,

388
main.c
View file

@ -1,24 +1,24 @@
/* Clzip - LZMA lossless data compressor /* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2021 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* /*
Exit status: 0 for a normal exit, 1 for environmental problems Exit status: 0 for a normal exit, 1 for environmental problems
(file not found, invalid flags, I/O errors, etc), 2 to indicate a (file not found, invalid flags, I/O errors, etc), 2 to indicate a
corrupt or invalid input file, 3 for an internal consistency error corrupt or invalid input file, 3 for an internal consistency error
(eg, bug) which caused clzip to panic. (eg, bug) which caused clzip to panic.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
@ -74,11 +74,11 @@
int verbosity = 0; int verbosity = 0;
const char * const program_name = "clzip"; static const char * const program_name = "clzip";
const char * const program_year = "2019"; static const char * const program_year = "2021";
const char * invocation_name = 0; static const char * invocation_name = "clzip"; /* default value */
const struct { const char * from; const char * to; } known_extensions[] = { static const struct { const char * from; const char * to; } known_extensions[] = {
{ ".lz", "" }, { ".lz", "" },
{ ".tlz", ".tar" }, { ".tlz", ".tar" },
{ 0, 0 } }; { 0, 0 } };
@ -93,24 +93,26 @@ enum Mode { m_compress, m_decompress, m_list, m_test };
/* Variables used in signal handler context. /* Variables used in signal handler context.
They are not declared volatile because the handler never returns. */ They are not declared volatile because the handler never returns. */
char * output_filename = 0; static char * output_filename = 0;
int outfd = -1; static int outfd = -1;
bool delete_output_on_interrupt = false; static bool delete_output_on_interrupt = false;
static void show_help( void ) static void show_help( void )
{ {
printf( "Clzip is a C language version of lzip, fully compatible with lzip 1.4 or\n" printf( "Clzip is a C language version of lzip, fully compatible with lzip 1.4 or\n"
"newer. As clzip is written in C, it may be easier to integrate in\n" "newer. As clzip is written in C, it may be easier to integrate in\n"
"applications like package managers, embedded devices, or systems lacking\n" "applications like package managers, embedded devices, or systems lacking a\n"
"a C++ compiler.\n" "C++ compiler.\n"
"\nLzip is a lossless data compressor with a user interface similar to the\n" "\nLzip is a lossless data compressor with a user interface similar to the one\n"
"one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0)\n" "of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov\n"
"or compress most files more than bzip2 (lzip -9). Decompression speed is\n" "chain-Algorithm' (LZMA) stream format, chosen to maximize safety and\n"
"intermediate between gzip and bzip2. Lzip is better than gzip and bzip2\n" "interoperability. Lzip can compress about as fast as gzip (lzip -0) or\n"
"from a data recovery perspective. Lzip has been designed, written and\n" "compress most files more than bzip2 (lzip -9). Decompression speed is\n"
"tested with great care to replace gzip and bzip2 as the standard\n" "intermediate between gzip and bzip2. Lzip is better than gzip and bzip2 from\n"
"general-purpose compressed format for unix-like systems.\n" "a data recovery perspective. Lzip has been designed, written, and tested\n"
"with great care to replace gzip and bzip2 as the standard general-purpose\n"
"compressed format for unix-like systems.\n"
"\nUsage: %s [options] [files]\n", invocation_name ); "\nUsage: %s [options] [files]\n", invocation_name );
printf( "\nOptions:\n" printf( "\nOptions:\n"
" -h, --help display this help and exit\n" " -h, --help display this help and exit\n"
@ -124,7 +126,7 @@ static void show_help( void )
" -k, --keep keep (don't delete) input files\n" " -k, --keep keep (don't delete) input files\n"
" -l, --list print (un)compressed file sizes\n" " -l, --list print (un)compressed file sizes\n"
" -m, --match-length=<bytes> set match length limit in bytes [36]\n" " -m, --match-length=<bytes> set match length limit in bytes [36]\n"
" -o, --output=<file> if reading standard input, write to <file>\n" " -o, --output=<file> write to <file>, keep input files\n"
" -q, --quiet suppress all messages\n" " -q, --quiet suppress all messages\n"
" -s, --dictionary-size=<bytes> set dictionary size limit in bytes [8 MiB]\n" " -s, --dictionary-size=<bytes> set dictionary size limit in bytes [8 MiB]\n"
" -S, --volume-size=<bytes> set volume size limit in bytes\n" " -S, --volume-size=<bytes> set volume size limit in bytes\n"
@ -134,7 +136,7 @@ static void show_help( void )
" --fast alias for -0\n" " --fast alias for -0\n"
" --best alias for -9\n" " --best alias for -9\n"
" --loose-trailing allow trailing data seeming corrupt header\n" " --loose-trailing allow trailing data seeming corrupt header\n"
"If no file names are given, or if a file is '-', clzip compresses or\n" "\nIf no file names are given, or if a file is '-', clzip compresses or\n"
"decompresses from standard input to standard output.\n" "decompresses from standard input to standard output.\n"
"Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\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" "Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n"
@ -142,12 +144,19 @@ static void show_help( void )
"to 2^29 bytes.\n" "to 2^29 bytes.\n"
"\nThe bidimensional parameter space of LZMA can't be mapped to a linear\n" "\nThe bidimensional parameter space of LZMA can't be mapped to a linear\n"
"scale optimal for all files. If your files are large, very repetitive,\n" "scale optimal for all files. If your files are large, very repetitive,\n"
"etc, you may need to use the --dictionary-size and --match-length\n" "etc, you may need to use the options --dictionary-size and --match-length\n"
"options directly to achieve optimal performance.\n" "directly to achieve optimal performance.\n"
"\nTo extract all the files from archive 'foo.tar.lz', use the commands\n"
"'tar -xf foo.tar.lz' or 'clzip -cd foo.tar.lz | tar -xf -'.\n"
"\nExit status: 0 for a normal exit, 1 for environmental problems (file\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" "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" "invalid input file, 3 for an internal consistency error (eg, bug) which\n"
"caused clzip to panic.\n" "caused clzip to panic.\n"
"\nThe ideas embodied in clzip are due to (at least) the following people:\n"
"Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the\n"
"definition of Markov chains), G.N.N. Martin (for the definition of range\n"
"encoding), Igor Pavlov (for putting all the above together in LZMA), and\n"
"Julian Seward (for bzip2's CLI).\n"
"\nReport bugs to lzip-bug@nongnu.org\n" "\nReport bugs to lzip-bug@nongnu.org\n"
"Clzip home page: http://www.nongnu.org/lzip/clzip.html\n" ); "Clzip home page: http://www.nongnu.org/lzip/clzip.html\n" );
} }
@ -168,15 +177,64 @@ void * resize_buffer( void * buf, const unsigned min_size )
{ {
if( buf ) buf = realloc( buf, min_size ); if( buf ) buf = realloc( buf, min_size );
else buf = malloc( min_size ); else buf = malloc( min_size );
if( !buf ) if( !buf ) { show_error( mem_msg, 0, false ); cleanup_and_fail( 1 ); }
{
show_error( "Not enough memory.", 0, false );
cleanup_and_fail( 1 );
}
return buf; return buf;
} }
struct Pretty_print
{
const char * name;
char * padded_name;
const char * stdin_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->padded_name = 0;
pp->stdin_name = "(stdin)";
pp->longest_name = 0;
pp->first_post = false;
if( verbosity <= 0 ) return;
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( pp->longest_name < len ) pp->longest_name = len;
}
if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len;
}
static void Pp_set_name( struct Pretty_print * const pp,
const char * const filename )
{
unsigned name_len, padded_name_len, i = 0;
if( filename && filename[0] && strcmp( filename, "-" ) != 0 )
pp->name = filename;
else pp->name = pp->stdin_name;
name_len = strlen( pp->name );
padded_name_len = max( name_len, pp->longest_name ) + 4;
pp->padded_name = resize_buffer( pp->padded_name, padded_name_len + 1 );
while( i < 2 ) pp->padded_name[i++] = ' ';
while( i < name_len + 2 ) { pp->padded_name[i] = pp->name[i-2]; ++i; }
pp->padded_name[i++] = ':';
while( i < padded_name_len ) pp->padded_name[i++] = ' ';
pp->padded_name[i] = 0;
pp->first_post = true;
}
static void Pp_reset( struct Pretty_print * const pp )
{ if( pp->name && pp->name[0] ) pp->first_post = true; }
void Pp_show_msg( struct Pretty_print * const pp, const char * const msg ) void Pp_show_msg( struct Pretty_print * const pp, const char * const msg )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
@ -222,7 +280,7 @@ const char * format_ds( const unsigned dictionary_size )
void show_header( const unsigned dictionary_size ) void show_header( const unsigned dictionary_size )
{ {
fprintf( stderr, "dictionary %s, ", format_ds( dictionary_size ) ); fprintf( stderr, "dict %s, ", format_ds( dictionary_size ) );
} }
@ -289,7 +347,7 @@ static int get_dict_size( const char * const arg )
} }
void set_mode( enum Mode * const program_modep, const enum Mode new_mode ) static void set_mode( enum Mode * const program_modep, const enum Mode new_mode )
{ {
if( *program_modep != m_compress && *program_modep != new_mode ) if( *program_modep != m_compress && *program_modep != new_mode )
{ {
@ -316,14 +374,17 @@ static int extension_index( const char * const name )
} }
static void set_c_outname( const char * const name, const bool force_ext, static void set_c_outname( const char * const name, const bool filenames_given,
const bool multifile ) const bool force_ext, const bool multifile )
{ {
/* zupdate < 1.9 depends on lzip adding the extension '.lz' to name when
reading from standard input. */
output_filename = resize_buffer( output_filename, strlen( name ) + 5 + output_filename = resize_buffer( output_filename, strlen( name ) + 5 +
strlen( known_extensions[0].from ) + 1 ); strlen( known_extensions[0].from ) + 1 );
strcpy( output_filename, name ); strcpy( output_filename, name );
if( multifile ) strcat( output_filename, "00001" ); if( multifile ) strcat( output_filename, "00001" );
if( force_ext || multifile || extension_index( output_filename ) < 0 ) if( force_ext || multifile ||
( !filenames_given && extension_index( output_filename ) < 0 ) )
strcat( output_filename, known_extensions[0].from ); strcat( output_filename, known_extensions[0].from );
} }
@ -354,7 +415,7 @@ static void set_d_outname( const char * const name, const int eindex )
int open_instream( const char * const name, struct stat * const in_statsp, int open_instream( const char * const name, struct stat * const in_statsp,
const bool no_ofile, const bool reg_only ) const bool one_to_one, const bool reg_only )
{ {
int infd = open( name, O_RDONLY | O_BINARY ); int infd = open( name, O_RDONLY | O_BINARY );
if( infd < 0 ) if( infd < 0 )
@ -366,13 +427,12 @@ int open_instream( const char * const name, struct stat * const in_statsp,
const bool can_read = ( i == 0 && !reg_only && const bool can_read = ( i == 0 && !reg_only &&
( S_ISBLK( mode ) || S_ISCHR( mode ) || ( S_ISBLK( mode ) || S_ISCHR( mode ) ||
S_ISFIFO( mode ) || S_ISSOCK( mode ) ) ); S_ISFIFO( mode ) || S_ISSOCK( mode ) ) );
if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || !no_ofile ) ) ) if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n", fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n",
program_name, name, program_name, name, ( can_read && one_to_one ) ?
( can_read && !no_ofile ) ? ",\n and neither '-c' nor '-o' were specified" : "" );
",\n and '--stdout' was not specified" : "" );
close( infd ); close( infd );
infd = -1; infd = -1;
} }
@ -383,9 +443,8 @@ int open_instream( const char * const name, struct stat * const in_statsp,
static int open_instream2( const char * const name, struct stat * const in_statsp, static int open_instream2( const char * const name, struct stat * const in_statsp,
const enum Mode program_mode, const int eindex, const enum Mode program_mode, const int eindex,
const bool recompress, const bool to_stdout ) const bool one_to_one, const bool recompress )
{ {
const bool no_ofile = ( to_stdout || program_mode == m_test );
if( program_mode == m_compress && !recompress && eindex >= 0 ) if( program_mode == m_compress && !recompress && eindex >= 0 )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
@ -393,15 +452,15 @@ static int open_instream2( const char * const name, struct stat * const in_stats
program_name, name, known_extensions[eindex].from ); program_name, name, known_extensions[eindex].from );
return -1; return -1;
} }
return open_instream( name, in_statsp, no_ofile, false ); return open_instream( name, in_statsp, one_to_one, false );
} }
static bool open_outstream( const bool force, const bool from_stdin ) static bool open_outstream( const bool force, const bool protect )
{ {
const mode_t usr_rw = S_IRUSR | S_IWUSR; const mode_t usr_rw = S_IRUSR | S_IWUSR;
const mode_t all_rw = usr_rw | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; const mode_t all_rw = usr_rw | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
const mode_t outfd_mode = from_stdin ? all_rw : usr_rw; const mode_t outfd_mode = protect ? usr_rw : all_rw;
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; if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
@ -420,25 +479,6 @@ static bool open_outstream( const bool force, const bool from_stdin )
} }
static bool check_tty( const char * const input_filename, const int infd,
const enum Mode program_mode )
{
if( program_mode == m_compress && isatty( outfd ) )
{
show_error( "I won't write compressed data to a terminal.", 0, true );
return false;
}
if( ( program_mode == m_decompress || program_mode == m_test ) &&
isatty( infd ) )
{
show_file_error( input_filename,
"I won't read compressed data from a terminal.", 0 );
return false;
}
return true;
}
static void set_signals( void (*action)(int) ) static void set_signals( void (*action)(int) )
{ {
signal( SIGHUP, action ); signal( SIGHUP, action );
@ -464,7 +504,7 @@ void cleanup_and_fail( const int retval )
} }
void signal_handler( int sig ) static void signal_handler( int sig )
{ {
if( sig ) {} /* keep compiler happy */ if( sig ) {} /* keep compiler happy */
show_error( "Control-C or similar caught, quitting.", 0, false ); show_error( "Control-C or similar caught, quitting.", 0, false );
@ -472,7 +512,31 @@ void signal_handler( int sig )
} }
/* Set permissions, owner and times. */ static bool check_tty_in( const char * const input_filename, const int infd,
const enum Mode program_mode, int * const retval )
{
if( ( program_mode == m_decompress || program_mode == m_test ) &&
isatty( infd ) ) /* for example /dev/tty */
{ show_file_error( input_filename,
"I won't read compressed data from a terminal.", 0 );
close( infd ); set_retval( retval, 1 );
if( program_mode != m_test ) cleanup_and_fail( *retval );
return false; }
return true;
}
static bool check_tty_out( const enum Mode program_mode )
{
if( program_mode == m_compress && isatty( outfd ) )
{ show_file_error( output_filename[0] ?
output_filename : "(stdout)",
"I won't write compressed data to a terminal.", 0 );
return false; }
return true;
}
/* Set permissions, owner, and times. */
static void close_and_set_permissions( const struct stat * const in_statsp ) static void close_and_set_permissions( const struct stat * const in_statsp )
{ {
bool warning = false; bool warning = false;
@ -591,7 +655,7 @@ static int compress( const unsigned long long cfile_size,
close_and_set_permissions( in_statsp ); close_and_set_permissions( in_statsp );
if( !next_filename() ) if( !next_filename() )
{ Pp_show_msg( pp, "Too many volume files." ); retval = 1; break; } { Pp_show_msg( pp, "Too many volume files." ); retval = 1; break; }
if( !open_outstream( true, !in_statsp ) ) { retval = 1; break; } if( !open_outstream( true, in_statsp ) ) { retval = 1; break; }
} }
} }
} }
@ -661,10 +725,7 @@ static int decompress( const unsigned long long cfile_size, const int infd,
int retval = 0; int retval = 0;
bool first_member; bool first_member;
if( !Rd_init( &rdec, infd ) ) if( !Rd_init( &rdec, infd ) )
{ { show_error( mem_msg, 0, false ); cleanup_and_fail( 1 ); }
show_error( "Not enough memory.", 0, false );
cleanup_and_fail( 1 );
}
for( first_member = true; ; first_member = false ) for( first_member = true; ; first_member = false )
{ {
@ -711,7 +772,7 @@ static int decompress( const unsigned long long cfile_size, const int infd,
Pp_show_msg( pp, 0 ); Pp_show_msg( pp, 0 );
if( !LZd_init( &decoder, &rdec, dictionary_size, outfd ) ) if( !LZd_init( &decoder, &rdec, dictionary_size, outfd ) )
{ Pp_show_msg( pp, "Not enough memory." ); retval = 1; break; } { Pp_show_msg( pp, mem_msg ); retval = 1; break; }
show_dprogress( cfile_size, partial_file_pos, &rdec, pp ); /* init */ show_dprogress( cfile_size, partial_file_pos, &rdec, pp ); /* init */
result = LZd_decode_member( &decoder, pp ); result = LZd_decode_member( &decoder, pp );
partial_file_pos += Rd_member_position( &rdec ); partial_file_pos += Rd_member_position( &rdec );
@ -845,12 +906,14 @@ int main( const int argc, const char * const argv[] )
{ 3 << 23, 132 }, /* -8 */ { 3 << 23, 132 }, /* -8 */
{ 1 << 25, 273 } }; /* -9 */ { 1 << 25, 273 } }; /* -9 */
struct Lzma_options encoder_options = option_mapping[6]; /* default = "-6" */ struct Lzma_options encoder_options = option_mapping[6]; /* default = "-6" */
const unsigned long long max_member_size = 0x0008000000000000ULL; const unsigned long long max_member_size = 0x0008000000000000ULL; /* 2 PiB */
const unsigned long long max_volume_size = 0x4000000000000000ULL; const unsigned long long max_volume_size = 0x4000000000000000ULL; /* 4 EiB */
unsigned long long member_size = max_member_size; unsigned long long member_size = max_member_size;
unsigned long long volume_size = 0; unsigned long long volume_size = 0;
const char * default_output_filename = ""; const char * default_output_filename = "";
const char ** filenames = 0; static struct Arg_parser parser; /* static because valgrind complains */
static struct Pretty_print pp; /* and memory management in C sucks */
static const char ** filenames = 0;
int num_filenames = 0; int num_filenames = 0;
enum Mode program_mode = m_compress; enum Mode program_mode = m_compress;
int argind = 0; int argind = 0;
@ -866,20 +929,19 @@ int main( const int argc, const char * const argv[] )
bool stdin_used = false; bool stdin_used = false;
bool to_stdout = false; bool to_stdout = false;
bool zero = false; bool zero = false;
struct Pretty_print pp;
enum { opt_lt = 256 }; enum { opt_lt = 256 };
const struct ap_Option options[] = const struct ap_Option options[] =
{ {
{ '0', "fast", ap_no }, { '0', "fast", ap_no },
{ '1', 0, ap_no }, { '1', 0, ap_no },
{ '2', 0, ap_no }, { '2', 0, ap_no },
{ '3', 0, ap_no }, { '3', 0, ap_no },
{ '4', 0, ap_no }, { '4', 0, ap_no },
{ '5', 0, ap_no }, { '5', 0, ap_no },
{ '6', 0, ap_no }, { '6', 0, ap_no },
{ '7', 0, ap_no }, { '7', 0, ap_no },
{ '8', 0, ap_no }, { '8', 0, ap_no },
{ '9', "best", ap_no }, { '9', "best", ap_no },
{ 'a', "trailing-error", ap_no }, { 'a', "trailing-error", ap_no },
{ 'b', "member-size", ap_yes }, { 'b', "member-size", ap_yes },
@ -900,15 +962,13 @@ int main( const int argc, const char * const argv[] )
{ 'v', "verbose", ap_no }, { 'v', "verbose", ap_no },
{ 'V', "version", ap_no }, { 'V', "version", ap_no },
{ opt_lt, "loose-trailing", ap_no }, { opt_lt, "loose-trailing", ap_no },
{ 0 , 0, ap_no } }; { 0, 0, ap_no } };
struct Arg_parser parser; if( argc > 0 ) invocation_name = argv[0];
invocation_name = argv[0];
CRC32_init(); CRC32_init();
if( !ap_init( &parser, argc, argv, options, 0 ) ) if( !ap_init( &parser, argc, argv, options, 0 ) )
{ show_error( "Not enough memory.", 0, false ); return 1; } { show_error( mem_msg, 0, false ); return 1; }
if( ap_error( &parser ) ) /* bad option */ if( ap_error( &parser ) ) /* bad option */
{ show_error( ap_error( &parser ), 0, true ); return 1; } { show_error( ap_error( &parser ), 0, true ); return 1; }
@ -936,7 +996,8 @@ int main( const int argc, const char * const argv[] )
getnum( arg, min_match_len_limit, max_match_len ); getnum( arg, min_match_len_limit, max_match_len );
zero = false; break; zero = false; break;
case 'n': break; case 'n': break;
case 'o': default_output_filename = arg; break; case 'o': if( strcmp( arg, "-" ) == 0 ) to_stdout = true;
else { default_output_filename = arg; } break;
case 'q': verbosity = -1; break; case 'q': verbosity = -1; break;
case 's': encoder_options.dictionary_size = get_dict_size( arg ); case 's': encoder_options.dictionary_size = get_dict_size( arg );
zero = false; break; zero = false; break;
@ -967,21 +1028,33 @@ int main( const int argc, const char * const argv[] )
if( program_mode == m_list ) if( program_mode == m_list )
return list_files( filenames, num_filenames, ignore_trailing, loose_trailing ); return list_files( filenames, num_filenames, ignore_trailing, loose_trailing );
if( program_mode == m_test ) if( program_mode == m_compress )
outfd = -1;
else if( program_mode == m_compress )
{ {
if( volume_size > 0 && !to_stdout && default_output_filename[0] &&
num_filenames > 1 )
{ show_error( "Only can compress one file when using '-o' and '-S'.",
0, true ); return 1; }
Dis_slots_init(); Dis_slots_init();
Prob_prices_init(); Prob_prices_init();
} }
else volume_size = 0;
if( program_mode == m_test ) to_stdout = false; /* apply overrides */
if( program_mode == m_test || to_stdout ) default_output_filename = "";
if( !to_stdout && program_mode != m_test && output_filename = resize_buffer( output_filename, 1 );
( filenames_given || default_output_filename[0] ) ) output_filename[0] = 0;
if( to_stdout && program_mode != m_test ) /* check tty only once */
{ outfd = STDOUT_FILENO; if( !check_tty_out( program_mode ) ) return 1; }
else outfd = -1;
const bool to_file = !to_stdout && program_mode != m_test &&
default_output_filename[0];
if( !to_stdout && program_mode != m_test && ( filenames_given || to_file ) )
set_signals( signal_handler ); set_signals( signal_handler );
Pp_init( &pp, filenames, num_filenames ); Pp_init( &pp, filenames, num_filenames );
output_filename = resize_buffer( output_filename, 1 ); const bool one_to_one = !to_stdout && program_mode != m_test && !to_file;
for( i = 0; i < num_filenames; ++i ) for( i = 0; i < num_filenames; ++i )
{ {
unsigned long long cfile_size; unsigned long long cfile_size;
@ -990,70 +1063,50 @@ int main( const int argc, const char * const argv[] )
int tmp; int tmp;
struct stat in_stats; struct stat in_stats;
const struct stat * in_statsp; const struct stat * in_statsp;
output_filename[0] = 0;
if( !filenames[i][0] || strcmp( filenames[i], "-" ) == 0 ) Pp_set_name( &pp, filenames[i] );
if( strcmp( filenames[i], "-" ) == 0 )
{ {
if( stdin_used ) continue; else stdin_used = true; if( stdin_used ) continue; else stdin_used = true;
infd = STDIN_FILENO; infd = STDIN_FILENO;
if( program_mode != m_test ) if( !check_tty_in( pp.name, infd, program_mode, &retval ) ) continue;
{ if( one_to_one ) { outfd = STDOUT_FILENO; output_filename[0] = 0; }
if( to_stdout || !default_output_filename[0] )
outfd = STDOUT_FILENO;
else
{
if( program_mode == m_compress )
set_c_outname( default_output_filename, false, volume_size > 0 );
else
{
output_filename = resize_buffer( output_filename,
strlen( default_output_filename ) + 1 );
strcpy( output_filename, default_output_filename );
}
if( !open_outstream( force, true ) )
{
if( retval < 1 ) retval = 1;
close( infd );
continue;
}
}
}
} }
else else
{ {
const int eindex = extension_index( input_filename = filenames[i] ); const int eindex = extension_index( input_filename = filenames[i] );
infd = open_instream2( input_filename, &in_stats, program_mode, infd = open_instream2( input_filename, &in_stats, program_mode,
eindex, recompress, to_stdout ); eindex, one_to_one, recompress );
if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; } if( infd < 0 ) { set_retval( &retval, 1 ); continue; }
if( program_mode != m_test ) if( !check_tty_in( pp.name, infd, program_mode, &retval ) ) continue;
if( one_to_one ) /* open outfd after verifying infd */
{ {
if( to_stdout ) outfd = STDOUT_FILENO; if( program_mode == m_compress )
else set_c_outname( input_filename, true, true, volume_size > 0 );
{ else set_d_outname( input_filename, eindex );
if( program_mode == m_compress ) if( !open_outstream( force, true ) )
set_c_outname( input_filename, true, volume_size > 0 ); { close( infd ); set_retval( &retval, 1 ); continue; }
else set_d_outname( input_filename, eindex );
if( !open_outstream( force, false ) )
{
if( retval < 1 ) retval = 1;
close( infd );
continue;
}
}
} }
} }
Pp_set_name( &pp, input_filename ); if( one_to_one && !check_tty_out( program_mode ) )
if( !check_tty( pp.name, infd, program_mode ) ) { set_retval( &retval, 1 ); return retval; } /* don't delete a tty */
if( to_file && outfd < 0 ) /* open outfd after verifying infd */
{ {
if( retval < 1 ) retval = 1; if( program_mode == m_compress ) set_c_outname( default_output_filename,
if( program_mode == m_test ) { close( infd ); continue; } filenames_given, false, volume_size > 0 );
cleanup_and_fail( retval ); else
{ output_filename = resize_buffer( output_filename,
strlen( default_output_filename ) + 1 );
strcpy( output_filename, default_output_filename ); }
if( !open_outstream( force, false ) || !check_tty_out( program_mode ) )
return 1; /* check tty only once and don't try to delete a tty */
} }
in_statsp = input_filename[0] ? &in_stats : 0; in_statsp = ( input_filename[0] && one_to_one ) ? &in_stats : 0;
cfile_size = ( in_statsp && S_ISREG( in_statsp->st_mode ) ) ? cfile_size = ( input_filename[0] && S_ISREG( in_stats.st_mode ) ) ?
( in_statsp->st_size + 99 ) / 100 : 0; ( in_stats.st_size + 99 ) / 100 : 0;
if( program_mode == m_compress ) if( program_mode == m_compress )
tmp = compress( cfile_size, member_size, volume_size, infd, tmp = compress( cfile_size, member_size, volume_size, infd,
&encoder_options, &pp, in_statsp, zero ); &encoder_options, &pp, in_statsp, zero );
@ -1061,29 +1114,24 @@ int main( const int argc, const char * const argv[] )
tmp = decompress( cfile_size, infd, &pp, ignore_trailing, tmp = decompress( cfile_size, infd, &pp, ignore_trailing,
loose_trailing, program_mode == m_test ); loose_trailing, program_mode == m_test );
if( close( infd ) != 0 ) if( close( infd ) != 0 )
{ { show_file_error( pp.name, "Error closing input file", errno );
show_error( input_filename[0] ? "Error closing input file" : set_retval( &tmp, 1 ); }
"Error closing stdin", errno, false ); set_retval( &retval, tmp );
if( tmp < 1 ) tmp = 1;
}
if( tmp > retval ) retval = tmp;
if( tmp ) if( tmp )
{ if( program_mode != m_test ) cleanup_and_fail( retval ); { if( program_mode != m_test ) cleanup_and_fail( retval );
else ++failed_tests; } else ++failed_tests; }
if( delete_output_on_interrupt ) if( delete_output_on_interrupt && one_to_one )
close_and_set_permissions( in_statsp ); close_and_set_permissions( in_statsp );
if( input_filename[0] ) if( input_filename[0] && !keep_input_files && one_to_one &&
{ ( program_mode != m_compress || volume_size == 0 ) )
if( !keep_input_files && !to_stdout && program_mode != m_test && remove( input_filename );
( program_mode != m_compress || volume_size == 0 ) )
remove( input_filename );
}
} }
if( outfd >= 0 && close( outfd ) != 0 ) if( delete_output_on_interrupt ) close_and_set_permissions( 0 ); /* -o */
else if( outfd >= 0 && close( outfd ) != 0 ) /* -c */
{ {
show_error( "Error closing stdout", errno, false ); show_error( "Error closing stdout", errno, false );
if( retval < 1 ) retval = 1; set_retval( &retval, 1 );
} }
if( failed_tests > 0 && verbosity >= 1 && num_filenames > 1 ) if( failed_tests > 0 && verbosity >= 1 && num_filenames > 1 )
fprintf( stderr, "%s: warning: %d %s failed the test.\n", fprintf( stderr, "%s: warning: %d %s failed the test.\n",

View file

@ -1,9 +1,9 @@
#! /bin/sh #! /bin/sh
# check script for Clzip - LZMA lossless data compressor # check script for Clzip - LZMA lossless data compressor
# Copyright (C) 2010-2019 Antonio Diaz Diaz. # Copyright (C) 2010-2021 Antonio Diaz Diaz.
# #
# This script is free software: you have unlimited permission # This script is free software: you have unlimited permission
# to copy, distribute and modify it. # to copy, distribute, and modify it.
LC_ALL=C LC_ALL=C
export LC_ALL export LC_ALL
@ -30,6 +30,8 @@ cd "${objdir}"/tmp || framework_failure
cat "${testdir}"/test.txt > in || framework_failure cat "${testdir}"/test.txt > in || framework_failure
in_lz="${testdir}"/test.txt.lz in_lz="${testdir}"/test.txt.lz
in_em="${testdir}"/test_em.txt.lz
fox_lz="${testdir}"/fox.lz
fail=0 fail=0
test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; } test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; }
@ -58,6 +60,16 @@ done
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -dq -o in < "${in_lz}" "${LZIP}" -dq -o in < "${in_lz}"
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
"${LZIP}" -dq -o in "${in_lz}"
[ $? = 1 ] || test_failed $LINENO
"${LZIP}" -dq -o out nx_file.lz
[ $? = 1 ] || test_failed $LINENO
[ ! -e out ] || test_failed $LINENO
"${LZIP}" -q -o out.lz nx_file
[ $? = 1 ] || test_failed $LINENO
[ ! -e out.lz ] || test_failed $LINENO
"${LZIP}" -qf -S100k -o out in in
[ $? = 1 ] || test_failed $LINENO
# these are for code coverage # these are for code coverage
"${LZIP}" -lt "${in_lz}" 2> /dev/null "${LZIP}" -lt "${in_lz}" 2> /dev/null
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
@ -65,7 +77,9 @@ done
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
"${LZIP}" -cdt "${in_lz}" > out 2> /dev/null "${LZIP}" -cdt "${in_lz}" > out 2> /dev/null
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
"${LZIP}" -t -- nx_file 2> /dev/null "${LZIP}" -t -- nx_file.lz 2> /dev/null
[ $? = 1 ] || test_failed $LINENO
"${LZIP}" -t "" < /dev/null 2> /dev/null
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
"${LZIP}" --help > /dev/null || test_failed $LINENO "${LZIP}" --help > /dev/null || test_failed $LINENO
"${LZIP}" -n1 -V > /dev/null || test_failed $LINENO "${LZIP}" -n1 -V > /dev/null || test_failed $LINENO
@ -89,12 +103,26 @@ printf "LZIP\001+.............................." | "${LZIP}" -t 2> /dev/null
printf "\ntesting decompression..." printf "\ntesting decompression..."
"${LZIP}" -lq "${in_lz}" || test_failed $LINENO for i in "${in_lz}" "${in_em}" ; do
"${LZIP}" -t "${in_lz}" || test_failed $LINENO "${LZIP}" -lq "$i" || test_failed $LINENO "$i"
"${LZIP}" -cd "${in_lz}" > copy || test_failed $LINENO "${LZIP}" -t "$i" || test_failed $LINENO "$i"
cmp in copy || test_failed $LINENO "${LZIP}" -d "$i" -o copy || test_failed $LINENO "$i"
cmp in copy || test_failed $LINENO "$i"
"${LZIP}" -cd "$i" > copy || test_failed $LINENO "$i"
cmp in copy || test_failed $LINENO "$i"
"${LZIP}" -d "$i" -o - > copy || test_failed $LINENO "$i"
cmp in copy || test_failed $LINENO "$i"
"${LZIP}" -d < "$i" > copy || test_failed $LINENO "$i"
cmp in copy || test_failed $LINENO "$i"
rm -f copy || framework_failure
done
lines=$("${LZIP}" -tvv "${in_em}" 2>&1 | wc -l) || test_failed $LINENO
[ "${lines}" -eq 8 ] || test_failed $LINENO "${lines}"
lines=$("${LZIP}" -lvv "${in_em}" | wc -l) || test_failed $LINENO
[ "${lines}" -eq 11 ] || test_failed $LINENO "${lines}"
rm -f copy || framework_failure
cat "${in_lz}" > copy.lz || framework_failure cat "${in_lz}" > copy.lz || framework_failure
"${LZIP}" -dk copy.lz || test_failed $LINENO "${LZIP}" -dk copy.lz || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
@ -114,10 +142,16 @@ cmp in copy || test_failed $LINENO
printf "to be overwritten" > copy || framework_failure printf "to be overwritten" > copy || framework_failure
"${LZIP}" -df -o copy < "${in_lz}" || test_failed $LINENO "${LZIP}" -df -o copy < "${in_lz}" || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
rm -f out copy || framework_failure
"${LZIP}" -d -o ./- "${in_lz}" || test_failed $LINENO
cmp in ./- || test_failed $LINENO
rm -f ./- || framework_failure
"${LZIP}" -d -o ./- < "${in_lz}" || test_failed $LINENO
cmp in ./- || test_failed $LINENO
rm -f ./- || framework_failure
rm -f copy || framework_failure cat "${in_lz}" > anyothername || framework_failure
"${LZIP}" < in > anyothername || test_failed $LINENO "${LZIP}" -dv - anyothername - < "${in_lz}" > copy 2> /dev/null ||
"${LZIP}" -dv --output copy - anyothername - < "${in_lz}" 2> /dev/null ||
test_failed $LINENO test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
cmp in anyothername.out || test_failed $LINENO cmp in anyothername.out || test_failed $LINENO
@ -158,21 +192,19 @@ done
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
cat in in > in2 || framework_failure cat in in > in2 || framework_failure
cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure "${LZIP}" -lq "${in_lz}" "${in_lz}" || test_failed $LINENO
"${LZIP}" -lq in2.lz || test_failed $LINENO "${LZIP}" -t "${in_lz}" "${in_lz}" || test_failed $LINENO
"${LZIP}" -t in2.lz || test_failed $LINENO "${LZIP}" -cd "${in_lz}" "${in_lz}" -o out > copy2 || test_failed $LINENO
"${LZIP}" -cd in2.lz > copy2 || test_failed $LINENO [ ! -e out ] || test_failed $LINENO # override -o
cmp in2 copy2 || test_failed $LINENO cmp in2 copy2 || test_failed $LINENO
rm -f copy2 || framework_failure
"${LZIP}" --output=copy2.lz < in2 || test_failed $LINENO "${LZIP}" -d "${in_lz}" "${in_lz}" -o copy2 || test_failed $LINENO
"${LZIP}" -lq copy2.lz || test_failed $LINENO
"${LZIP}" -t copy2.lz || test_failed $LINENO
"${LZIP}" -cd copy2.lz > copy2 || test_failed $LINENO
cmp in2 copy2 || test_failed $LINENO cmp in2 copy2 || test_failed $LINENO
rm -f copy2 || framework_failure
cat "${in_lz}" "${in_lz}" > copy2.lz || framework_failure
printf "\ngarbage" >> copy2.lz || framework_failure printf "\ngarbage" >> copy2.lz || framework_failure
"${LZIP}" -tvvvv copy2.lz 2> /dev/null || test_failed $LINENO "${LZIP}" -tvvvv copy2.lz 2> /dev/null || test_failed $LINENO
rm -f copy2 || framework_failure
"${LZIP}" -alq copy2.lz "${LZIP}" -alq copy2.lz
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -atq copy2.lz "${LZIP}" -atq copy2.lz
@ -188,68 +220,92 @@ rm -f copy2 || framework_failure
printf "to be overwritten" > copy2 || framework_failure printf "to be overwritten" > copy2 || framework_failure
"${LZIP}" -df copy2.lz || test_failed $LINENO "${LZIP}" -df copy2.lz || test_failed $LINENO
cmp in2 copy2 || test_failed $LINENO cmp in2 copy2 || test_failed $LINENO
rm -f in2 copy2 || framework_failure rm -f copy2 || framework_failure
printf "\ntesting compression..." printf "\ntesting compression..."
"${LZIP}" -c -0 in in in -S100k -o out3.lz > copy2.lz || test_failed $LINENO
[ ! -e out3.lz ] || test_failed $LINENO # override -o and -S
"${LZIP}" -0f in in --output=copy2.lz || test_failed $LINENO
"${LZIP}" -d copy2.lz -o out2 || test_failed $LINENO
cmp in2 out2 || test_failed $LINENO
rm -f in2 out2 copy2.lz || framework_failure
"${LZIP}" -cf "${in_lz}" > out 2> /dev/null # /dev/null is a tty on OS/2 "${LZIP}" -cf "${in_lz}" > out 2> /dev/null # /dev/null is a tty on OS/2
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
"${LZIP}" -cFvvm36 "${in_lz}" > out 2> /dev/null || test_failed $LINENO "${LZIP}" -Fvvm36 -o - "${in_lz}" > out 2> /dev/null || test_failed $LINENO
"${LZIP}" -cd out | "${LZIP}" -d > copy || test_failed $LINENO "${LZIP}" -cd out | "${LZIP}" -d > copy || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
"${LZIP}" -0 -o ./- in || test_failed $LINENO
"${LZIP}" -cd ./- | cmp in - || test_failed $LINENO
rm -f ./- || framework_failure
"${LZIP}" -0 -o ./- < in || test_failed $LINENO # add .lz
[ ! -e ./- ] || test_failed $LINENO
"${LZIP}" -cd -- -.lz | cmp in - || test_failed $LINENO
rm -f ./-.lz || framework_failure
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
"${LZIP}" -k -$i in || test_failed $LINENO $i "${LZIP}" -k -$i in || test_failed $LINENO $i
mv -f in.lz copy.lz || test_failed $LINENO $i mv -f in.lz copy.lz || test_failed $LINENO $i
printf "garbage" >> copy.lz || framework_failure printf "garbage" >> copy.lz || framework_failure
"${LZIP}" -df copy.lz || test_failed $LINENO $i "${LZIP}" -df copy.lz || test_failed $LINENO $i
cmp in copy || test_failed $LINENO $i cmp in copy || test_failed $LINENO $i
done
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do "${LZIP}" -$i in -c > out || test_failed $LINENO $i
"${LZIP}" -c -$i in > out || test_failed $LINENO $i "${LZIP}" -$i in -o o_out || test_failed $LINENO $i # don't add .lz
[ ! -e o_out.lz ] || test_failed $LINENO
cmp out o_out || test_failed $LINENO $i
rm -f o_out || framework_failure
printf "g" >> out || framework_failure printf "g" >> out || framework_failure
"${LZIP}" -cd out > copy || test_failed $LINENO $i "${LZIP}" -cd out > copy || test_failed $LINENO $i
cmp in copy || test_failed $LINENO $i cmp in copy || test_failed $LINENO $i
done
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
"${LZIP}" -$i < in > out || test_failed $LINENO $i "${LZIP}" -$i < in > out || test_failed $LINENO $i
"${LZIP}" -d < out > copy || test_failed $LINENO $i "${LZIP}" -d < out > copy || test_failed $LINENO $i
cmp in copy || test_failed $LINENO $i cmp in copy || test_failed $LINENO $i
done
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do rm -f out || framework_failure
"${LZIP}" -f -$i -o out < in || test_failed $LINENO $i printf "to be overwritten" > out.lz || framework_failure
"${LZIP}" -f -$i -o out < in || test_failed $LINENO $i # add .lz
[ ! -e out ] || test_failed $LINENO
"${LZIP}" -df -o copy < out.lz || test_failed $LINENO $i "${LZIP}" -df -o copy < out.lz || test_failed $LINENO $i
cmp in copy || test_failed $LINENO $i cmp in copy || test_failed $LINENO $i
done done
rm -f out.lz || framework_failure rm -f out out.lz || framework_failure
cat in in in in in in in in > in8 || framework_failure cat in in in in in in in in > in8 || framework_failure
"${LZIP}" -1s12 -S100k in8 || test_failed $LINENO "${LZIP}" -1s12 -S100k in8 || test_failed $LINENO
"${LZIP}" -t in800001.lz in800002.lz || test_failed $LINENO "${LZIP}" -t in800001.lz in800002.lz || test_failed $LINENO
"${LZIP}" -cd in800001.lz in800002.lz | cmp in8 - || test_failed $LINENO "${LZIP}" -cd in800001.lz in800002.lz | cmp in8 - || test_failed $LINENO
[ ! -e in800003.lz ] || test_failed $LINENO
rm -f in800001.lz in800002.lz || framework_failure rm -f in800001.lz in800002.lz || framework_failure
"${LZIP}" -1s12 -S100k -o out.lz < in8 || test_failed $LINENO "${LZIP}" -1s12 -S100k -o out.lz in8 || test_failed $LINENO
# ignore -S
"${LZIP}" -d out.lz00001.lz out.lz00002.lz -S100k -o out || test_failed $LINENO
cmp in8 out || test_failed $LINENO
"${LZIP}" -t out.lz00001.lz out.lz00002.lz || test_failed $LINENO "${LZIP}" -t out.lz00001.lz out.lz00002.lz || test_failed $LINENO
"${LZIP}" -cd out.lz00001.lz out.lz00002.lz | cmp in8 - || test_failed $LINENO [ ! -e out.lz00003.lz ] || test_failed $LINENO
rm -f out.lz00001.lz out.lz00002.lz || framework_failure rm -f out out.lz00001.lz out.lz00002.lz || framework_failure
"${LZIP}" -1ks4Ki -b100000 in8 || test_failed $LINENO "${LZIP}" -1ks4Ki -b100000 in8 || test_failed $LINENO
"${LZIP}" -t in8.lz || test_failed $LINENO "${LZIP}" -t in8.lz || test_failed $LINENO
"${LZIP}" -cd in8.lz | cmp in8 - || test_failed $LINENO "${LZIP}" -cd in8.lz -o out | cmp in8 - || test_failed $LINENO # override -o
[ ! -e out ] || test_failed $LINENO
rm -f in8 || framework_failure rm -f in8 || framework_failure
"${LZIP}" -0 -S100k -o out < in8.lz || test_failed $LINENO "${LZIP}" -0 -S100k -o out < in8.lz || test_failed $LINENO
"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO "${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO
"${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO "${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO
[ ! -e out00003.lz ] || test_failed $LINENO
rm -f out00001.lz || framework_failure rm -f out00001.lz || framework_failure
"${LZIP}" -1 -S100k -o out < in8.lz || test_failed $LINENO "${LZIP}" -1 -S100k -o out < in8.lz || test_failed $LINENO
"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO "${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO
"${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO "${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO
[ ! -e out00003.lz ] || test_failed $LINENO
rm -f out00001.lz out00002.lz || framework_failure rm -f out00001.lz out00002.lz || framework_failure
"${LZIP}" -0 -F -S100k in8.lz || test_failed $LINENO "${LZIP}" -0 -F -S100k in8.lz || test_failed $LINENO
"${LZIP}" -t in8.lz00001.lz in8.lz00002.lz || test_failed $LINENO "${LZIP}" -t in8.lz00001.lz in8.lz00002.lz || test_failed $LINENO
"${LZIP}" -cd in8.lz00001.lz in8.lz00002.lz | cmp in8.lz - || test_failed $LINENO "${LZIP}" -cd in8.lz00001.lz in8.lz00002.lz | cmp in8.lz - || test_failed $LINENO
[ ! -e in8.lz00003.lz ] || test_failed $LINENO
rm -f in8.lz00001.lz in8.lz00002.lz || framework_failure rm -f in8.lz00001.lz in8.lz00002.lz || framework_failure
"${LZIP}" -0kF -b100k in8.lz || test_failed $LINENO "${LZIP}" -0kF -b100k in8.lz || test_failed $LINENO
"${LZIP}" -t in8.lz.lz || test_failed $LINENO "${LZIP}" -t in8.lz.lz || test_failed $LINENO
@ -313,6 +369,21 @@ else
fi fi
rm -f int.lz || framework_failure rm -f int.lz || framework_failure
for i in fox_v2.lz fox_s11.lz fox_de20.lz \
fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
"${LZIP}" -tq "${testdir}"/$i
[ $? = 2 ] || test_failed $LINENO $i
done
"${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO
for i in fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
"${LZIP}" -cdq "${testdir}"/$i > out
[ $? = 2 ] || test_failed $LINENO $i
cmp fox out || test_failed $LINENO $i
done
rm -f fox out || framework_failure
cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure
cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure
if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null && if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null &&
[ -e trunc.lz ] && cmp in2.lz trunc.lz > /dev/null 2>&1 ; then [ -e trunc.lz ] && cmp in2.lz trunc.lz > /dev/null 2>&1 ; then
@ -339,13 +410,21 @@ printf "g" >> ingin.lz || framework_failure
cat "${in_lz}" >> ingin.lz || framework_failure cat "${in_lz}" >> ingin.lz || framework_failure
"${LZIP}" -lq ingin.lz "${LZIP}" -lq ingin.lz
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -atq ingin.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -atq < ingin.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -acdq ingin.lz > out
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -adq < ingin.lz > out
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -t ingin.lz || test_failed $LINENO "${LZIP}" -t ingin.lz || test_failed $LINENO
"${LZIP}" -t < ingin.lz || test_failed $LINENO
"${LZIP}" -cd ingin.lz > copy || test_failed $LINENO "${LZIP}" -cd ingin.lz > copy || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
"${LZIP}" -t < ingin.lz || test_failed $LINENO
"${LZIP}" -d < ingin.lz > copy || test_failed $LINENO "${LZIP}" -d < ingin.lz > copy || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
rm -f copy ingin.lz || framework_failure rm -f copy ingin.lz out || framework_failure
echo echo
if [ ${fail} = 0 ] ; then if [ ${fail} = 0 ] ; then

BIN
testsuite/fox.lz Normal file

Binary file not shown.

BIN
testsuite/fox_bcrc.lz Normal file

Binary file not shown.

BIN
testsuite/fox_crc0.lz Normal file

Binary file not shown.

BIN
testsuite/fox_das46.lz Normal file

Binary file not shown.

BIN
testsuite/fox_de20.lz Normal file

Binary file not shown.

BIN
testsuite/fox_mes81.lz Normal file

Binary file not shown.

BIN
testsuite/fox_s11.lz Normal file

Binary file not shown.

BIN
testsuite/fox_v2.lz Normal file

Binary file not shown.

BIN
testsuite/test_em.txt.lz Normal file

Binary file not shown.