Merging upstream version 1.11.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
2b58741015
commit
648618884e
21 changed files with 727 additions and 631 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,9 +1,18 @@
|
|||
2024-01-21 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.11 released.
|
||||
* main.cc: Reformat file diagnostics as 'PROGRAM: FILE: MESSAGE'.
|
||||
(show_option_error): New function showing argument and option name.
|
||||
(main): Make -o preserve date/mode/owner if 1 input file.
|
||||
(open_outstream): Create missing intermediate directories.
|
||||
* configure, Makefile.in: New variable 'MAKEINFO'.
|
||||
|
||||
2022-01-24 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.10 released.
|
||||
* main.cc (getnum): Show option name and valid range if error.
|
||||
(check_lib): Check that LZ_API_VERSION and LZ_version_string match.
|
||||
* Set variable LIBS from configure.
|
||||
* configure: Set variable LIBS.
|
||||
* Improve several descriptions in manual, '--help', and man page.
|
||||
* plzip.texi: Change GNU Texinfo category to 'Compression'.
|
||||
(Reported by Alfred M. Szmidt).
|
||||
|
@ -220,8 +229,7 @@
|
|||
until something better appears on the net.
|
||||
|
||||
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
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
|
||||
modify it.
|
||||
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 modify it.
|
||||
|
|
24
INSTALL
24
INSTALL
|
@ -1,17 +1,16 @@
|
|||
Requirements
|
||||
------------
|
||||
You will need a C++98 compiler with suport for 'long long', and the
|
||||
You will need a C++98 compiler with support for 'long long', and the
|
||||
compression library lzlib installed. (gcc 3.3.6 or newer is recommended).
|
||||
I use gcc 6.1.0 and 3.3.6, but the code should compile with any standards
|
||||
compliant compiler.
|
||||
Gcc is available at http://gcc.gnu.org.
|
||||
Lzlib is available at http://www.nongnu.org/lzip/lzlib.html.
|
||||
|
||||
Lzlib must be version 1.0 or newer, but the fast encoder requires lzlib 1.7
|
||||
or newer, the Hamming distance (HD) = 3 detection of corrupt headers in
|
||||
non-seekable multimember files requires lzlib 1.10 or newer, and the 'no
|
||||
copy' optimization for testing requires lzlib 1.12 or newer.
|
||||
|
||||
Gcc is available at http://gcc.gnu.org.
|
||||
Lzlib is available at http://www.nongnu.org/lzip/lzlib.html.
|
||||
non-seekable multimember files requires lzlib 1.10 or newer, and the
|
||||
'no copy' optimization for testing requires lzlib 1.12 or newer.
|
||||
|
||||
The operating system must allow signal handlers read access to objects with
|
||||
static storage duration so that the cleanup handler for Control-C can delete
|
||||
|
@ -26,8 +25,8 @@ Procedure
|
|||
or
|
||||
lzip -cd plzip[version].tar.lz | tar -xf -
|
||||
|
||||
This creates the directory ./plzip[version] containing the source from
|
||||
the main archive.
|
||||
This creates the directory ./plzip[version] containing the source code
|
||||
extracted from the archive.
|
||||
|
||||
2. Change to plzip directory and run configure.
|
||||
(Try 'configure --help' for usage instructions).
|
||||
|
@ -54,7 +53,8 @@ the main archive.
|
|||
4. Optionally, type 'make check' to run the tests that come with plzip.
|
||||
|
||||
5. Type 'make install' to install the program and any data files and
|
||||
documentation.
|
||||
documentation. You need root privileges to install into a prefix owned
|
||||
by root.
|
||||
|
||||
Or type 'make install-compress', which additionally compresses the
|
||||
info manual and the man page after installation.
|
||||
|
@ -78,15 +78,15 @@ object files and executables to go and run the 'configure' script.
|
|||
'configure' automatically checks for the source code in '.', in '..', and
|
||||
in the directory that 'configure' is in.
|
||||
|
||||
'configure' recognizes the option '--srcdir=DIR' to control where to
|
||||
look for the sources. Usually 'configure' can determine that directory
|
||||
'configure' recognizes the option '--srcdir=DIR' to control where to look
|
||||
for the source code. Usually 'configure' can determine that directory
|
||||
automatically.
|
||||
|
||||
After running 'configure', you can run 'make' and 'make install' as
|
||||
explained above.
|
||||
|
||||
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
|
|
@ -32,6 +32,10 @@ main.o : main.cc
|
|||
%.o : %.cc
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
# prevent 'make' from trying to remake source files
|
||||
$(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ;
|
||||
%.h %.cc : ;
|
||||
|
||||
$(objs) : Makefile
|
||||
arg_parser.o : arg_parser.h
|
||||
compress.o : lzip.h
|
||||
|
@ -42,13 +46,12 @@ list.o : lzip.h lzip_index.h
|
|||
lzip_index.o : lzip.h lzip_index.h
|
||||
main.o : arg_parser.h lzip.h
|
||||
|
||||
|
||||
doc : info man
|
||||
|
||||
info : $(VPATH)/doc/$(pkgname).info
|
||||
|
||||
$(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texi
|
||||
cd $(VPATH)/doc && makeinfo $(pkgname).texi
|
||||
cd $(VPATH)/doc && $(MAKEINFO) $(pkgname).texi
|
||||
|
||||
man : $(VPATH)/doc/$(progname).1
|
||||
|
||||
|
|
17
NEWS
17
NEWS
|
@ -1,13 +1,14 @@
|
|||
Changes in version 1.10:
|
||||
Changes in version 1.11:
|
||||
|
||||
In case of error in a numerical argument to a command line option, plzip
|
||||
now shows the name of the option and the range of valid values.
|
||||
File diagnostics have been reformatted as 'PROGRAM: FILE: MESSAGE'.
|
||||
|
||||
'--check-lib' now checks that LZ_API_VERSION and LZ_version_string match.
|
||||
Diagnostics caused by invalid arguments to command-line options now show the
|
||||
argument and the name of the option.
|
||||
|
||||
The variable LIBS can now be set from configure.
|
||||
The option '-o, --output' now preserves dates, permissions, and ownership of
|
||||
the file when (de)compressing exactly one file.
|
||||
|
||||
Several descriptions have been improved in manual, '--help', and man page.
|
||||
The option '-o, --output' now creates missing intermediate directories when
|
||||
writing to a file.
|
||||
|
||||
The texinfo category of the manual has been changed from 'Data Compression'
|
||||
to 'Compression' to match that of gzip. (Reported by Alfred M. Szmidt).
|
||||
The variable MAKEINFO has been added to configure and Makefile.in.
|
||||
|
|
51
README
51
README
|
@ -1,18 +1,19 @@
|
|||
Description
|
||||
|
||||
Plzip is a massively parallel (multi-threaded) implementation of lzip, fully
|
||||
Plzip is a massively parallel (multi-threaded) implementation of lzip,
|
||||
compatible with lzip 1.4 or newer. Plzip uses the compression library lzlib.
|
||||
|
||||
Lzip is a lossless data compressor with a user interface similar to the one
|
||||
of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov
|
||||
chain-Algorithm' (LZMA) stream format and provides a 3 factor integrity
|
||||
checking to maximize interoperability and optimize safety. Lzip can compress
|
||||
about as fast as gzip (lzip -0) or compress most files more than bzip2
|
||||
(lzip -9). Decompression speed is intermediate between gzip and bzip2.
|
||||
Lzip is better than gzip and bzip2 from 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.
|
||||
chain-Algorithm' (LZMA) stream format to maximize interoperability. The
|
||||
maximum dictionary size is 512 MiB so that any lzip file can be decompressed
|
||||
on 32-bit machines. Lzip provides accurate and robust 3-factor integrity
|
||||
checking. Lzip can compress about as fast as gzip (lzip -0) or compress most
|
||||
files more than bzip2 (lzip -9). Decompression speed is intermediate between
|
||||
gzip and bzip2. Lzip is better than gzip and bzip2 from 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.
|
||||
|
||||
Plzip can compress/decompress large files on multiprocessor machines much
|
||||
faster than lzip, at the cost of a slightly reduced compression ratio (0.4
|
||||
|
@ -27,11 +28,12 @@ alignment between tar members and lzip members.
|
|||
|
||||
When compressing, plzip divides the input file into chunks and compresses as
|
||||
many chunks simultaneously as worker threads are chosen, creating a
|
||||
multimember compressed file.
|
||||
multimember compressed file. Each chunk is compressed in-place (using the
|
||||
same buffer for input and output), reducing the amount of RAM required.
|
||||
|
||||
When decompressing, plzip decompresses as many members simultaneously as
|
||||
worker threads are chosen. Files that were compressed with lzip will not
|
||||
be decompressed faster than using lzip (unless the option '-b' was used)
|
||||
worker threads are chosen. Files that were compressed with lzip are not
|
||||
decompressed faster than using lzip (unless the option '-b' was used)
|
||||
because lzip usually produces single-member files, which can't be
|
||||
decompressed in parallel.
|
||||
|
||||
|
@ -63,9 +65,9 @@ Plzip uses the same well-defined exit status values used by lzip, which
|
|||
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.
|
||||
|
||||
Plzip will automatically use for each file the largest dictionary size that
|
||||
does not exceed neither the file size nor the limit given. Keep in mind that
|
||||
the decompression memory requirement is affected at compression time by the
|
||||
Plzip automatically uses for each file the largest dictionary size that does
|
||||
not exceed neither the file size nor the limit given. Keep in mind that the
|
||||
decompression memory requirement is affected at compression time by the
|
||||
choice of dictionary size limit.
|
||||
|
||||
When compressing, plzip replaces every file given in the command line
|
||||
|
@ -78,20 +80,20 @@ filename.tlz becomes filename.tar
|
|||
anyothername becomes anyothername.out
|
||||
|
||||
(De)compressing a file is much like copying or moving it. Therefore plzip
|
||||
preserves the access and modification dates, permissions, and, when
|
||||
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
|
||||
S_ISGID are cleared).
|
||||
preserves the access and modification dates, permissions, and, if you have
|
||||
appropriate privileges, 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 S_ISGID are cleared).
|
||||
|
||||
Plzip is able to read from some types of non-regular files if either the
|
||||
option '-c' or the option '-o' is specified.
|
||||
|
||||
If no file names are specified, plzip compresses (or decompresses) from
|
||||
standard input to standard output. Plzip will refuse to read compressed data
|
||||
standard input to standard output. Plzip refuses to read compressed data
|
||||
from a terminal or write compressed data to a terminal, as this would be
|
||||
entirely incomprehensible and might leave the terminal in an abnormal state.
|
||||
|
||||
Plzip will correctly decompress a file which is the concatenation of two or
|
||||
Plzip correctly decompresses a file which is the concatenation of two or
|
||||
more compressed files. The result is the concatenation of the corresponding
|
||||
decompressed files. Integrity testing of concatenated compressed files is
|
||||
also supported.
|
||||
|
@ -101,11 +103,10 @@ been compressed. Decompressed is used to refer to data which have undergone
|
|||
the process of decompression.
|
||||
|
||||
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
||||
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
|
||||
itself.
|
||||
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 itself.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
/* Arg_parser - POSIX/GNU command-line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2024 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
/* Arg_parser - POSIX/GNU command-line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2024 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009 Laszlo Ersek.
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include "lzip.h"
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
|
||||
#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
|
||||
#endif
|
||||
|
||||
|
||||
|
|
31
configure
vendored
31
configure
vendored
|
@ -1,12 +1,12 @@
|
|||
#! /bin/sh
|
||||
# configure script for Plzip - Massively parallel implementation of lzip
|
||||
# Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
#
|
||||
# This configure script is free software: you have unlimited permission
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
pkgname=plzip
|
||||
pkgversion=1.10
|
||||
pkgversion=1.11
|
||||
progname=plzip
|
||||
with_mingw=
|
||||
srctrigger=doc/${pkgname}.texi
|
||||
|
@ -26,6 +26,7 @@ CPPFLAGS=
|
|||
CXXFLAGS='-Wall -W -O2'
|
||||
LDFLAGS=
|
||||
LIBS='-llz -lpthread'
|
||||
MAKEINFO=makeinfo
|
||||
|
||||
# checking whether we are using GNU C++.
|
||||
/bin/sh -c "${CXX} --version" > /dev/null 2>&1 || { CXX=c++ ; CXXFLAGS=-O2 ; }
|
||||
|
@ -59,7 +60,7 @@ while [ $# != 0 ] ; do
|
|||
echo "Options and variables: [defaults in brackets]"
|
||||
echo " -h, --help display this help and exit"
|
||||
echo " -V, --version output version information and exit"
|
||||
echo " --srcdir=DIR find the sources in DIR [. or ..]"
|
||||
echo " --srcdir=DIR find the source code in DIR [. or ..]"
|
||||
echo " --prefix=DIR install into DIR [${prefix}]"
|
||||
echo " --exec-prefix=DIR base directory for arch-dependent files [${exec_prefix}]"
|
||||
echo " --bindir=DIR user executables directory [${bindir}]"
|
||||
|
@ -68,11 +69,12 @@ while [ $# != 0 ] ; do
|
|||
echo " --mandir=DIR man pages directory [${mandir}]"
|
||||
echo " --with-mingw use included pread/pwrite functions missing in MinGW"
|
||||
echo " CXX=COMPILER C++ compiler to use [${CXX}]"
|
||||
echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]"
|
||||
echo " CXXFLAGS=OPTIONS command line options for the C++ compiler [${CXXFLAGS}]"
|
||||
echo " CPPFLAGS=OPTIONS command-line options for the preprocessor [${CPPFLAGS}]"
|
||||
echo " CXXFLAGS=OPTIONS command-line options for the C++ compiler [${CXXFLAGS}]"
|
||||
echo " CXXFLAGS+=OPTIONS append options to the current value of CXXFLAGS"
|
||||
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
|
||||
echo " LDFLAGS=OPTIONS command-line options for the linker [${LDFLAGS}]"
|
||||
echo " LIBS=OPTIONS libraries to pass to the linker [${LIBS}]"
|
||||
echo " MAKEINFO=NAME makeinfo program to use [${MAKEINFO}]"
|
||||
echo
|
||||
exit 0 ;;
|
||||
--version | -V)
|
||||
|
@ -94,7 +96,7 @@ while [ $# != 0 ] ; do
|
|||
--infodir=*) infodir=${optarg} ;;
|
||||
--mandir=*) mandir=${optarg} ;;
|
||||
--no-create) no_create=yes ;;
|
||||
--with-mingw) with_mingw="-DWITH_MINGW" ;;
|
||||
--with-mingw) with_mingw=-DWITH_MINGW ;;
|
||||
|
||||
CXX=*) CXX=${optarg} ;;
|
||||
CPPFLAGS=*) CPPFLAGS=${optarg} ;;
|
||||
|
@ -102,6 +104,7 @@ while [ $# != 0 ] ; do
|
|||
CXXFLAGS+=*) CXXFLAGS="${CXXFLAGS} ${optarg}" ;;
|
||||
LDFLAGS=*) LDFLAGS=${optarg} ;;
|
||||
LIBS=*) LIBS="${optarg} ${LIBS}" ;;
|
||||
MAKEINFO=*) MAKEINFO=${optarg} ;;
|
||||
|
||||
--*)
|
||||
echo "configure: WARNING: unrecognized option: '${option}'" 1>&2 ;;
|
||||
|
@ -121,7 +124,7 @@ while [ $# != 0 ] ; do
|
|||
fi
|
||||
done
|
||||
|
||||
# Find the source files, if location was not specified.
|
||||
# Find the source code, if location was not specified.
|
||||
srcdirtext=
|
||||
if [ -z "${srcdir}" ] ; then
|
||||
srcdirtext="or . or .." ; srcdir=.
|
||||
|
@ -133,7 +136,7 @@ if [ -z "${srcdir}" ] ; then
|
|||
fi
|
||||
|
||||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
|
||||
echo "configure: Can't find sources in ${srcdir} ${srcdirtext}" 1>&2
|
||||
echo "configure: Can't find source code in ${srcdir} ${srcdirtext}" 1>&2
|
||||
echo "configure: (At least ${srctrigger} is missing)." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
@ -153,7 +156,7 @@ if [ -z "${no_create}" ] ; then
|
|||
# This script is free software: you have unlimited permission
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
exec /bin/sh $0 ${args} --no-create
|
||||
exec /bin/sh "$0" ${args} --no-create
|
||||
EOF
|
||||
chmod +x config.status
|
||||
fi
|
||||
|
@ -172,10 +175,11 @@ echo "CPPFLAGS = ${CPPFLAGS}"
|
|||
echo "CXXFLAGS = ${CXXFLAGS}"
|
||||
echo "LDFLAGS = ${LDFLAGS}"
|
||||
echo "LIBS = ${LIBS}"
|
||||
echo "MAKEINFO = ${MAKEINFO}"
|
||||
rm -f Makefile
|
||||
cat > Makefile << EOF
|
||||
# Makefile for Plzip - Massively parallel implementation of lzip
|
||||
# Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
# This file was generated automatically by configure. Don't edit.
|
||||
#
|
||||
# This Makefile is free software: you have unlimited permission
|
||||
|
@ -197,9 +201,10 @@ CPPFLAGS = ${CPPFLAGS}
|
|||
CXXFLAGS = ${CXXFLAGS}
|
||||
LDFLAGS = ${LDFLAGS}
|
||||
LIBS = ${LIBS}
|
||||
MAKEINFO = ${MAKEINFO}
|
||||
EOF
|
||||
cat "${srcdir}/Makefile.in" >> Makefile
|
||||
|
||||
echo "OK. Now you can run make."
|
||||
echo "If make fails, verify that the compression library lzlib is correctly"
|
||||
echo "installed (see INSTALL)."
|
||||
echo "If make fails, check that the compression library lzlib is correctly installed"
|
||||
echo "(see INSTALL)."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009 Laszlo Ersek.
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009 Laszlo Ersek.
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -443,10 +443,10 @@ fail:
|
|||
( size <= 0 ) ? "File ends unexpectedly at member header." :
|
||||
"Input file is too short." ); goto fail; }
|
||||
const Lzip_header & header = *(const Lzip_header *)buffer;
|
||||
if( !header.verify_magic() )
|
||||
if( !header.check_magic() )
|
||||
{ if( shared_retval.set_value( 2 ) )
|
||||
{ show_file_error( pp.name(), bad_magic_msg ); } goto fail; }
|
||||
if( !header.verify_version() )
|
||||
if( !header.check_version() )
|
||||
{ if( shared_retval.set_value( 2 ) )
|
||||
{ pp( bad_version( header.version() ) ); } goto fail; }
|
||||
tmp.dictionary_size = header.dictionary_size();
|
||||
|
@ -474,10 +474,10 @@ fail:
|
|||
*(const Lzip_trailer *)(buffer + newpos - tsize);
|
||||
const unsigned long long member_size = trailer.member_size();
|
||||
if( partial_member_size + newpos - pos == member_size &&
|
||||
trailer.verify_consistency() )
|
||||
trailer.check_consistency() )
|
||||
{ // header found
|
||||
const Lzip_header & header = *(const Lzip_header *)(buffer + newpos);
|
||||
if( !header.verify_version() )
|
||||
if( !header.check_version() )
|
||||
{ if( shared_retval.set_value( 2 ) )
|
||||
{ pp( bad_version( header.version() ) ); } goto fail; }
|
||||
const unsigned dictionary_size = header.dictionary_size();
|
||||
|
@ -565,11 +565,10 @@ void muxer( Packet_courier & courier, const Pretty_print & pp,
|
|||
/* Init the courier, then start the splitter and the workers and, if not
|
||||
testing, call the muxer.
|
||||
*/
|
||||
int dec_stream( const unsigned long long cfile_size,
|
||||
const int num_workers, const int infd, const int outfd,
|
||||
int dec_stream( const unsigned long long cfile_size, const int num_workers,
|
||||
const int infd, const int outfd, const Cl_options & cl_opts,
|
||||
const Pretty_print & pp, const int debug_level,
|
||||
const int in_slots, const int out_slots,
|
||||
const bool ignore_trailing, const bool loose_trailing )
|
||||
const int in_slots, const int out_slots )
|
||||
{
|
||||
const int total_in_slots = ( INT_MAX / num_workers >= in_slots ) ?
|
||||
num_workers * in_slots : INT_MAX;
|
||||
|
@ -596,8 +595,8 @@ int dec_stream( const unsigned long long cfile_size,
|
|||
splitter_arg.worker_arg.pp = &pp;
|
||||
splitter_arg.worker_arg.shared_retval = &shared_retval;
|
||||
splitter_arg.worker_arg.worker_id = 0;
|
||||
splitter_arg.worker_arg.ignore_trailing = ignore_trailing;
|
||||
splitter_arg.worker_arg.loose_trailing = loose_trailing;
|
||||
splitter_arg.worker_arg.ignore_trailing = cl_opts.ignore_trailing;
|
||||
splitter_arg.worker_arg.loose_trailing = cl_opts.loose_trailing;
|
||||
splitter_arg.worker_arg.testing = ( outfd < 0 );
|
||||
splitter_arg.worker_arg.nocopy = nocopy;
|
||||
splitter_arg.worker_args = worker_args;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009 Laszlo Ersek.
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -266,22 +266,21 @@ done:
|
|||
|
||||
// start the workers and wait for them to finish.
|
||||
int decompress( const unsigned long long cfile_size, int num_workers,
|
||||
const int infd, const int outfd, const Pretty_print & pp,
|
||||
const int debug_level, const int in_slots,
|
||||
const int out_slots, const bool ignore_trailing,
|
||||
const bool loose_trailing, const bool infd_isreg,
|
||||
const bool one_to_one )
|
||||
const int infd, const int outfd, const Cl_options & cl_opts,
|
||||
const Pretty_print & pp, const int debug_level,
|
||||
const int in_slots, const int out_slots,
|
||||
const bool infd_isreg, const bool one_to_one )
|
||||
{
|
||||
if( !infd_isreg )
|
||||
return dec_stream( cfile_size, num_workers, infd, outfd, pp, debug_level,
|
||||
in_slots, out_slots, ignore_trailing, loose_trailing );
|
||||
return dec_stream( cfile_size, num_workers, infd, outfd, cl_opts, pp,
|
||||
debug_level, in_slots, out_slots );
|
||||
|
||||
const Lzip_index lzip_index( infd, ignore_trailing, loose_trailing );
|
||||
const Lzip_index lzip_index( infd, cl_opts );
|
||||
if( lzip_index.retval() == 1 ) // decompress as stream if seek fails
|
||||
{
|
||||
lseek( infd, 0, SEEK_SET );
|
||||
return dec_stream( cfile_size, num_workers, infd, outfd, pp, debug_level,
|
||||
in_slots, out_slots, ignore_trailing, loose_trailing );
|
||||
return dec_stream( cfile_size, num_workers, infd, outfd, cl_opts, pp,
|
||||
debug_level, in_slots, out_slots );
|
||||
}
|
||||
if( lzip_index.retval() != 0 ) // corrupt or invalid input file
|
||||
{
|
||||
|
|
50
doc/plzip.1
50
doc/plzip.1
|
@ -1,24 +1,25 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||
.TH PLZIP "1" "January 2022" "plzip 1.10" "User Commands"
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
|
||||
.TH PLZIP "1" "January 2024" "plzip 1.11" "User Commands"
|
||||
.SH NAME
|
||||
plzip \- reduces the size of files
|
||||
.SH SYNOPSIS
|
||||
.B plzip
|
||||
[\fI\,options\/\fR] [\fI\,files\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Plzip is a massively parallel (multi\-threaded) implementation of lzip, fully
|
||||
Plzip is a massively parallel (multi\-threaded) implementation of lzip,
|
||||
compatible with lzip 1.4 or newer. Plzip uses the compression library lzlib.
|
||||
.PP
|
||||
Lzip is a lossless data compressor with a user interface similar to the one
|
||||
of gzip or bzip2. Lzip uses a simplified form of the 'Lempel\-Ziv\-Markov
|
||||
chain\-Algorithm' (LZMA) stream format and provides a 3 factor integrity
|
||||
checking to maximize interoperability and optimize safety. Lzip can compress
|
||||
about as fast as gzip (lzip \fB\-0\fR) or compress most files more than bzip2
|
||||
(lzip \fB\-9\fR). Decompression speed is intermediate between gzip and bzip2.
|
||||
Lzip is better than gzip and bzip2 from 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.
|
||||
chain\-Algorithm' (LZMA) stream format to maximize interoperability. The
|
||||
maximum dictionary size is 512 MiB so that any lzip file can be decompressed
|
||||
on 32\-bit machines. Lzip provides accurate and robust 3\-factor integrity
|
||||
checking. Lzip can compress about as fast as gzip (lzip \fB\-0\fR) or compress most
|
||||
files more than bzip2 (lzip \fB\-9\fR). Decompression speed is intermediate between
|
||||
gzip and bzip2. Lzip is better than gzip and bzip2 from 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.
|
||||
.PP
|
||||
Plzip can compress/decompress large files on multiprocessor machines much
|
||||
faster than lzip, at the cost of a slightly reduced compression ratio (0.4
|
||||
|
@ -44,7 +45,7 @@ set size of input data blocks [2x8=16 MiB]
|
|||
write to standard output, keep input files
|
||||
.TP
|
||||
\fB\-d\fR, \fB\-\-decompress\fR
|
||||
decompress
|
||||
decompress, test compressed file integrity
|
||||
.TP
|
||||
\fB\-f\fR, \fB\-\-force\fR
|
||||
overwrite existing output files
|
||||
|
@ -104,21 +105,21 @@ If no file names are given, or if a file is '\-', plzip compresses or
|
|||
decompresses from standard input to standard output.
|
||||
Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,
|
||||
Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...
|
||||
Dictionary sizes 12 to 29 are interpreted as powers of two, meaning 2^12
|
||||
to 2^29 bytes.
|
||||
Dictionary sizes 12 to 29 are interpreted as powers of two, meaning 2^12 to
|
||||
2^29 bytes.
|
||||
.PP
|
||||
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,
|
||||
etc, you may need to use the options \fB\-\-dictionary\-size\fR and \fB\-\-match\-length\fR
|
||||
directly to achieve optimal performance.
|
||||
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, etc, you
|
||||
may need to use the options \fB\-\-dictionary\-size\fR and \fB\-\-match\-length\fR 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 'plzip \fB\-cd\fR foo.tar.lz | tar \fB\-xf\fR \-'.
|
||||
.PP
|
||||
Exit status: 0 for a normal exit, 1 for environmental problems (file
|
||||
not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or
|
||||
invalid input file, 3 for an internal consistency error (e.g., bug) which
|
||||
caused plzip to panic.
|
||||
Exit status: 0 for a normal exit, 1 for environmental problems
|
||||
(file not found, invalid command\-line options, I/O errors, etc), 2 to
|
||||
indicate a corrupt or invalid input file, 3 for an internal consistency
|
||||
error (e.g., bug) which caused plzip to panic.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to lzip\-bug@nongnu.org
|
||||
.br
|
||||
|
@ -126,12 +127,13 @@ Plzip home page: http://www.nongnu.org/lzip/plzip.html
|
|||
.SH COPYRIGHT
|
||||
Copyright \(co 2009 Laszlo Ersek.
|
||||
.br
|
||||
Copyright \(co 2022 Antonio Diaz Diaz.
|
||||
Using lzlib 1.13
|
||||
Copyright \(co 2024 Antonio Diaz Diaz.
|
||||
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
|
||||
.br
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
Using lzlib 1.14
|
||||
Using LZ_API_VERSION = 1014
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B plzip
|
||||
|
|
234
doc/plzip.info
234
doc/plzip.info
|
@ -11,13 +11,13 @@ File: plzip.info, Node: Top, Next: Introduction, Up: (dir)
|
|||
Plzip Manual
|
||||
************
|
||||
|
||||
This manual is for Plzip (version 1.10, 24 January 2022).
|
||||
This manual is for Plzip (version 1.11, 21 January 2024).
|
||||
|
||||
* Menu:
|
||||
|
||||
* Introduction:: Purpose and features of plzip
|
||||
* Output:: Meaning of plzip's output
|
||||
* Invoking plzip:: Command line interface
|
||||
* Invoking plzip:: Command-line interface
|
||||
* Program design:: Internal structure of plzip
|
||||
* Memory requirements:: Memory required to compress and decompress
|
||||
* Minimum file sizes:: Minimum file sizes required for full speed
|
||||
|
@ -28,7 +28,7 @@ This manual is for Plzip (version 1.10, 24 January 2022).
|
|||
* Concept index:: Index of concepts
|
||||
|
||||
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This manual is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
@ -39,19 +39,20 @@ File: plzip.info, Node: Introduction, Next: Output, Prev: Top, Up: Top
|
|||
1 Introduction
|
||||
**************
|
||||
|
||||
Plzip is a massively parallel (multi-threaded) implementation of lzip, fully
|
||||
Plzip is a massively parallel (multi-threaded) implementation of lzip,
|
||||
compatible with lzip 1.4 or newer. Plzip uses the compression library lzlib.
|
||||
|
||||
Lzip is a lossless data compressor with a user interface similar to the
|
||||
one of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov
|
||||
chain-Algorithm' (LZMA) stream format and provides a 3 factor integrity
|
||||
checking to maximize interoperability and optimize safety. Lzip can compress
|
||||
about as fast as gzip (lzip -0) or compress most files more than bzip2
|
||||
(lzip -9). Decompression speed is intermediate between gzip and bzip2. Lzip
|
||||
is better than gzip and bzip2 from 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.
|
||||
chain-Algorithm' (LZMA) stream format to maximize interoperability. The
|
||||
maximum dictionary size is 512 MiB so that any lzip file can be decompressed
|
||||
on 32-bit machines. Lzip provides accurate and robust 3-factor integrity
|
||||
checking. Lzip can compress about as fast as gzip (lzip -0) or compress most
|
||||
files more than bzip2 (lzip -9). Decompression speed is intermediate between
|
||||
gzip and bzip2. Lzip is better than gzip and bzip2 from 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.
|
||||
|
||||
Plzip can compress/decompress large files on multiprocessor machines much
|
||||
faster than lzip, at the cost of a slightly reduced compression ratio (0.4
|
||||
|
@ -94,10 +95,10 @@ byte near the beginning is a thing of the past.
|
|||
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.
|
||||
|
||||
Plzip will automatically use for each file the largest dictionary size
|
||||
that does not exceed neither the file size nor the limit given. Keep in
|
||||
mind that the decompression memory requirement is affected at compression
|
||||
time by the choice of dictionary size limit. *Note Memory requirements::.
|
||||
Plzip automatically uses for each file the largest dictionary size that
|
||||
does not exceed neither the file size nor the limit given. Keep in mind
|
||||
that the decompression memory requirement is affected at compression time
|
||||
by the choice of dictionary size limit. *Note Memory requirements::.
|
||||
|
||||
When compressing, plzip replaces every file given in the command line
|
||||
with a compressed version of itself, with the name "original_name.lz". When
|
||||
|
@ -109,22 +110,22 @@ filename.tlz becomes filename.tar
|
|||
anyothername becomes anyothername.out
|
||||
|
||||
(De)compressing a file is much like copying or moving it. Therefore plzip
|
||||
preserves the access and modification dates, permissions, and, when
|
||||
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
|
||||
S_ISGID are cleared).
|
||||
preserves the access and modification dates, permissions, and, if you have
|
||||
appropriate privileges, 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 S_ISGID are cleared).
|
||||
|
||||
Plzip is able to read from some types of non-regular files if either the
|
||||
option '-c' or the option '-o' is specified.
|
||||
|
||||
Plzip will refuse to read compressed data from a terminal or write
|
||||
compressed data to a terminal, as this would be entirely incomprehensible
|
||||
and might leave the terminal in an abnormal state.
|
||||
Plzip refuses to read compressed data from a terminal or write compressed
|
||||
data to a terminal, as this would be entirely incomprehensible and might
|
||||
leave the terminal in an abnormal state.
|
||||
|
||||
Plzip will correctly decompress a file which is the concatenation of two
|
||||
or more compressed files. The result is the concatenation of the
|
||||
corresponding decompressed files. Integrity testing of concatenated
|
||||
compressed files is also supported.
|
||||
Plzip correctly decompresses a file which is the concatenation of two or
|
||||
more compressed files. The result is the concatenation of the corresponding
|
||||
decompressed files. Integrity testing of concatenated compressed files is
|
||||
also supported.
|
||||
|
||||
|
||||
File: plzip.info, Node: Output, Next: Invoking plzip, Prev: Introduction, Up: Top
|
||||
|
@ -185,7 +186,8 @@ The format for running plzip is:
|
|||
If no file names are specified, plzip compresses (or decompresses) from
|
||||
standard input to standard output. A hyphen '-' used as a FILE argument
|
||||
means standard input. It can be mixed with other FILES and is read just
|
||||
once, the first time it appears in the command line.
|
||||
once, the first time it appears in the command line. Remember to prepend
|
||||
'./' to any file name beginning with a hyphen, or use '--'.
|
||||
|
||||
plzip supports the following options: *Note Argument syntax:
|
||||
(arg_parser)Argument syntax.
|
||||
|
@ -208,30 +210,32 @@ once, the first time it appears in the command line.
|
|||
'-B BYTES'
|
||||
'--data-size=BYTES'
|
||||
When compressing, set the size in bytes of the input data blocks. The
|
||||
input file will be divided in chunks of this size before compression is
|
||||
input file is divided in chunks of this size before compression is
|
||||
performed. Valid values range from 8 KiB to 1 GiB. Default value is
|
||||
two times the dictionary size, except for option '-0' where it
|
||||
defaults to 1 MiB. Plzip will reduce the dictionary size if it is
|
||||
larger than the data size specified. *Note Minimum file sizes::.
|
||||
defaults to 1 MiB. Plzip reduces the dictionary size if it is larger
|
||||
than the data size specified. *Note Minimum file sizes::.
|
||||
|
||||
'-c'
|
||||
'--stdout'
|
||||
Compress or decompress to standard output; keep input files unchanged.
|
||||
If compressing several files, each file is compressed independently.
|
||||
This option (or '-o') is needed when reading from a named pipe (fifo)
|
||||
or from a device. Use 'lziprecover -cd -i' to recover as much of the
|
||||
decompressed data as possible when decompressing a corrupt file. '-c'
|
||||
overrides '-o'. '-c' has no effect when testing or listing.
|
||||
(The output consists of a sequence of independently compressed
|
||||
members). This option (or '-o') is needed when reading from a named
|
||||
pipe (fifo) or from a device. Use 'lziprecover -cd -i' to recover as
|
||||
much of the decompressed data as possible when decompressing a corrupt
|
||||
file. '-c' overrides '-o'. '-c' has no effect when testing or listing.
|
||||
|
||||
'-d'
|
||||
'--decompress'
|
||||
Decompress the files specified. If a file does not exist, can't be
|
||||
opened, or the destination file already exists and '--force' has not
|
||||
been specified, plzip continues decompressing the rest of the files
|
||||
and exits with error status 1. If a file fails to decompress, or is a
|
||||
terminal, plzip exits immediately with error status 2 without
|
||||
decompressing the rest of the files. A terminal is considered an
|
||||
uncompressed file, and therefore invalid.
|
||||
Decompress the files specified. The integrity of the files specified is
|
||||
checked. If a file does not exist, can't be opened, or the destination
|
||||
file already exists and '--force' has not been specified, plzip
|
||||
continues decompressing the rest of the files and exits with error
|
||||
status 1. If a file fails to decompress, or is a terminal, plzip exits
|
||||
immediately with error status 2 without decompressing the rest of the
|
||||
files. A terminal is considered an uncompressed file, and therefore
|
||||
invalid.
|
||||
|
||||
'-f'
|
||||
'--force'
|
||||
|
@ -258,18 +262,18 @@ once, the first time it appears in the command line.
|
|||
printed.
|
||||
|
||||
If any file is damaged, does not exist, can't be opened, or is not
|
||||
regular, the final exit status will be > 0. '-lq' can be used to verify
|
||||
regular, the final exit status is > 0. '-lq' can be used to check
|
||||
quickly (without decompressing) the structural integrity of the files
|
||||
specified. (Use '--test' to verify the data integrity). '-alq'
|
||||
additionally verifies that none of the files specified contain
|
||||
trailing data.
|
||||
specified. (Use '--test' to check the data integrity). '-alq'
|
||||
additionally checks that none of the files specified contain trailing
|
||||
data.
|
||||
|
||||
'-m BYTES'
|
||||
'--match-length=BYTES'
|
||||
When compressing, set the match length limit in bytes. After a match
|
||||
this long is found, the search is finished. Valid values range from 5
|
||||
to 273. Larger values usually give better compression ratios but longer
|
||||
compression times.
|
||||
to 273. Larger values usually give better compression ratios but
|
||||
longer compression times.
|
||||
|
||||
'-n N'
|
||||
'--threads=N'
|
||||
|
@ -291,10 +295,12 @@ once, the first time it appears in the command line.
|
|||
|
||||
'-o FILE'
|
||||
'--output=FILE'
|
||||
If '-c' has not been also specified, write the (de)compressed output to
|
||||
FILE; keep input files unchanged. If compressing several files, each
|
||||
file is compressed independently. This option (or '-c') is needed when
|
||||
reading from a named pipe (fifo) or from a device. '-o -' is
|
||||
If '-c' has not been also specified, write the (de)compressed output
|
||||
to FILE, automatically creating any missing parent directories; keep
|
||||
input files unchanged. If compressing several files, each file is
|
||||
compressed independently. (The output consists of a sequence of
|
||||
independently compressed members). This option (or '-c') is needed
|
||||
when reading from a named pipe (fifo) or from a device. '-o -' is
|
||||
equivalent to '-c'. '-o' has no effect when testing or listing.
|
||||
|
||||
In order to keep backward compatibility with plzip versions prior to
|
||||
|
@ -311,14 +317,14 @@ once, the first time it appears in the command line.
|
|||
|
||||
'-s BYTES'
|
||||
'--dictionary-size=BYTES'
|
||||
When compressing, set the dictionary size limit in bytes. Plzip will
|
||||
use for each file the largest dictionary size that does not exceed
|
||||
neither the file size nor this limit. Valid values range from 4 KiB to
|
||||
512 MiB. Values 12 to 29 are interpreted as powers of two, meaning
|
||||
2^12 to 2^29 bytes. Dictionary sizes are quantized so that they can be
|
||||
coded in just one byte (*note coded-dict-size::). If the size specified
|
||||
does not match one of the valid sizes, it will be rounded upwards by
|
||||
adding up to (BYTES / 8) to it.
|
||||
When compressing, set the dictionary size limit in bytes. Plzip uses
|
||||
for each file the largest dictionary size that does not exceed neither
|
||||
the file size nor this limit. Valid values range from 4 KiB to 512 MiB.
|
||||
Values 12 to 29 are interpreted as powers of two, meaning 2^12 to 2^29
|
||||
bytes. Dictionary sizes are quantized so that they can be coded in
|
||||
just one byte (*note coded-dict-size::). If the size specified does
|
||||
not match one of the valid sizes, it is rounded upwards by adding up
|
||||
to (BYTES / 8) to it.
|
||||
|
||||
For maximum compression you should use a dictionary size limit as large
|
||||
as possible, but keep in mind that the decompression memory requirement
|
||||
|
@ -330,7 +336,7 @@ once, the first time it appears in the command line.
|
|||
really performs a trial decompression and throws away the result. Use
|
||||
it together with '-v' to see information about the files. If a file
|
||||
fails the test, does not exist, can't be opened, or is a terminal,
|
||||
plzip continues checking the rest of the files. A final diagnostic is
|
||||
plzip continues testing the rest of the files. A final diagnostic is
|
||||
shown at verbosity level 1 or higher if any file fails the test when
|
||||
testing multiple files.
|
||||
|
||||
|
@ -408,26 +414,29 @@ once, the first time it appears in the command line.
|
|||
(lzlib)Library version.
|
||||
|
||||
|
||||
Numbers given as arguments to options may be followed by a multiplier
|
||||
and an optional 'B' for "byte".
|
||||
Numbers given as arguments to options may be expressed in decimal,
|
||||
hexadecimal, or octal (using the same syntax as integer constants in C++),
|
||||
and may be followed by a multiplier and an optional 'B' for "byte".
|
||||
|
||||
Table of SI and binary prefixes (unit multipliers):
|
||||
|
||||
Prefix Value | Prefix Value
|
||||
k kilobyte (10^3 = 1000) | Ki kibibyte (2^10 = 1024)
|
||||
M megabyte (10^6) | Mi mebibyte (2^20)
|
||||
G gigabyte (10^9) | Gi gibibyte (2^30)
|
||||
T terabyte (10^12) | Ti tebibyte (2^40)
|
||||
P petabyte (10^15) | Pi pebibyte (2^50)
|
||||
E exabyte (10^18) | Ei exbibyte (2^60)
|
||||
Z zettabyte (10^21) | Zi zebibyte (2^70)
|
||||
Y yottabyte (10^24) | Yi yobibyte (2^80)
|
||||
Prefix Value | Prefix Value
|
||||
k kilobyte (10^3 = 1000) | Ki kibibyte (2^10 = 1024)
|
||||
M megabyte (10^6) | Mi mebibyte (2^20)
|
||||
G gigabyte (10^9) | Gi gibibyte (2^30)
|
||||
T terabyte (10^12) | Ti tebibyte (2^40)
|
||||
P petabyte (10^15) | Pi pebibyte (2^50)
|
||||
E exabyte (10^18) | Ei exbibyte (2^60)
|
||||
Z zettabyte (10^21) | Zi zebibyte (2^70)
|
||||
Y yottabyte (10^24) | Yi yobibyte (2^80)
|
||||
R ronnabyte (10^27) | Ri robibyte (2^90)
|
||||
Q quettabyte (10^30) | Qi quebibyte (2^100)
|
||||
|
||||
|
||||
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 invalid
|
||||
input file, 3 for an internal consistency error (e.g., bug) which caused
|
||||
plzip to panic.
|
||||
found, invalid command-line options, I/O errors, etc), 2 to indicate a
|
||||
corrupt or invalid input file, 3 for an internal consistency error (e.g.,
|
||||
bug) which caused plzip to panic.
|
||||
|
||||
|
||||
File: plzip.info, Node: Program design, Next: Memory requirements, Prev: Invoking plzip, Up: Top
|
||||
|
@ -441,7 +450,7 @@ multimember compressed file. Each chunk is compressed in-place (using the
|
|||
same buffer for input and output), reducing the amount of RAM required.
|
||||
|
||||
When decompressing, plzip decompresses as many members simultaneously as
|
||||
worker threads are chosen. Files that were compressed with lzip will not be
|
||||
worker threads are chosen. Files that were compressed with lzip are not
|
||||
decompressed faster than using lzip (unless the option '-b' was used)
|
||||
because lzip usually produces single-member files, which can't be
|
||||
decompressed in parallel.
|
||||
|
@ -535,10 +544,10 @@ multimember compressed file.
|
|||
For this to work as expected (and roughly multiply the compression speed
|
||||
by the number of available processors), the uncompressed file must be at
|
||||
least as large as the number of worker threads times the chunk size (*note
|
||||
--data-size::). Else some processors will not get any data to compress, and
|
||||
compression will be proportionally slower. The maximum speed increase
|
||||
achievable on a given file is limited by the ratio (file_size / data_size).
|
||||
For example, a tarball the size of gcc or linux will scale up to 10 or 14
|
||||
--data-size::). Else some processors do not get any data to compress, and
|
||||
compression is proportionally slower. The maximum speed increase achievable
|
||||
on a given file is limited by the ratio (file_size / data_size). For
|
||||
example, a tarball the size of gcc or linux scales up to 10 or 14
|
||||
processors at level -9.
|
||||
|
||||
The following table shows the minimum uncompressed file size needed for
|
||||
|
@ -585,7 +594,7 @@ when there is no longer anything to take away.
|
|||
represents a variable number of bytes.
|
||||
|
||||
|
||||
A lzip file consists of a series of independent "members" (compressed
|
||||
A lzip file consists of one or more independent "members" (compressed
|
||||
data sets). The members simply appear one after another in the file, with no
|
||||
additional information before, between, or after them. Each member can
|
||||
encode in compressed form up to 16 EiB - 1 byte of uncompressed data. The
|
||||
|
@ -629,10 +638,10 @@ size of a multimember file is unlimited.
|
|||
|
||||
'Member size (8 bytes)'
|
||||
Total size of the member, including header and trailer. This field acts
|
||||
as a distributed index, allows the verification of stream integrity,
|
||||
and facilitates the safe recovery of undamaged members from
|
||||
multimember files. Member size should be limited to 2 PiB to prevent
|
||||
the data size field from overflowing.
|
||||
as a distributed index, improves the checking of stream integrity, and
|
||||
facilitates the safe recovery of undamaged members from multimember
|
||||
files. Lzip limits the member size to 2 PiB to prevent the data size
|
||||
field from overflowing.
|
||||
|
||||
|
||||
|
||||
|
@ -648,12 +657,13 @@ member. Such trailing data may be:
|
|||
example when writing to a tape. It is safe to append any amount of
|
||||
padding zero bytes to a lzip file.
|
||||
|
||||
* Useful data added by the user; a cryptographically secure hash, a
|
||||
* Useful data added by the user; an "End Of File" string (to check that
|
||||
the file has not been truncated), a cryptographically secure hash, a
|
||||
description of file contents, etc. It is safe to append any amount of
|
||||
text to a lzip file as long as none of the first four bytes of the text
|
||||
match the corresponding byte in the string "LZIP", and the text does
|
||||
not contain any zero bytes (null characters). Nonzero bytes and zero
|
||||
bytes can't be safely mixed in trailing data.
|
||||
text to a lzip file as long as none of the first four bytes of the
|
||||
text matches the corresponding byte in the string "LZIP", and the text
|
||||
does not contain any zero bytes (null characters). Nonzero bytes and
|
||||
zero bytes can't be safely mixed in trailing data.
|
||||
|
||||
* Garbage added by some not totally successful copy operation.
|
||||
|
||||
|
@ -669,7 +679,7 @@ member. Such trailing data may be:
|
|||
discriminate trailing data from a corrupt header has a Hamming
|
||||
distance (HD) of 3, and the 3 bit flips must happen in different magic
|
||||
bytes for the test to fail. In any case, the option '--trailing-error'
|
||||
guarantees that any corrupt header will be detected.
|
||||
guarantees that any corrupt header is detected.
|
||||
|
||||
Trailing data are in no way part of the lzip file format, but tools
|
||||
reading lzip files are expected to behave as correctly and usefully as
|
||||
|
@ -689,12 +699,12 @@ File: plzip.info, Node: Examples, Next: Problems, Prev: Trailing data, Up: T
|
|||
WARNING! Even if plzip is bug-free, other causes may result in a corrupt
|
||||
compressed file (bugs in the system libraries, memory errors, etc).
|
||||
Therefore, if the data you are going to compress are important, give the
|
||||
option '--keep' to plzip and don't remove the original file until you
|
||||
verify the compressed file with a command like
|
||||
'plzip -cd file.lz | cmp file -'. Most RAM errors happening during
|
||||
compression can only be detected by comparing the compressed file with the
|
||||
original because the corruption happens before plzip compresses the RAM
|
||||
contents, resulting in a valid compressed file containing wrong data.
|
||||
option '--keep' to plzip and don't remove the original file until you check
|
||||
the compressed file with a command like 'plzip -cd file.lz | cmp file -'.
|
||||
Most RAM errors happening during compression can only be detected by
|
||||
comparing the compressed file with the original because the corruption
|
||||
happens before plzip compresses the RAM contents, resulting in a valid
|
||||
compressed file containing wrong data.
|
||||
|
||||
|
||||
Example 1: Extract all the files from archive 'foo.tar.lz'.
|
||||
|
@ -722,7 +732,7 @@ the operation is successful, 'file.lz' is removed.
|
|||
plzip -d file.lz
|
||||
|
||||
|
||||
Example 5: Verify the integrity of the compressed file 'file.lz' and show
|
||||
Example 5: Check the integrity of the compressed file 'file.lz' and show
|
||||
status.
|
||||
|
||||
plzip -tv file.lz
|
||||
|
@ -800,20 +810,20 @@ Concept index
|
|||
Tag Table:
|
||||
Node: Top217
|
||||
Node: Introduction1156
|
||||
Node: Output5829
|
||||
Node: Invoking plzip7392
|
||||
Ref: --trailing-error8187
|
||||
Ref: --data-size8425
|
||||
Node: Program design18819
|
||||
Node: Memory requirements21122
|
||||
Node: Minimum file sizes22807
|
||||
Node: File format24821
|
||||
Ref: coded-dict-size26260
|
||||
Node: Trailing data27514
|
||||
Node: Examples29775
|
||||
Ref: concat-example31210
|
||||
Node: Problems31967
|
||||
Node: Concept index32522
|
||||
Node: Output5934
|
||||
Node: Invoking plzip7497
|
||||
Ref: --trailing-error8372
|
||||
Ref: --data-size8610
|
||||
Node: Program design19519
|
||||
Node: Memory requirements21818
|
||||
Node: Minimum file sizes23503
|
||||
Node: File format25506
|
||||
Ref: coded-dict-size26945
|
||||
Node: Trailing data28195
|
||||
Node: Examples30531
|
||||
Ref: concat-example31964
|
||||
Node: Problems32721
|
||||
Node: Concept index33276
|
||||
|
||||
End Tag Table
|
||||
|
||||
|
|
248
doc/plzip.texi
248
doc/plzip.texi
|
@ -6,8 +6,8 @@
|
|||
@finalout
|
||||
@c %**end of header
|
||||
|
||||
@set UPDATED 24 January 2022
|
||||
@set VERSION 1.10
|
||||
@set UPDATED 21 January 2024
|
||||
@set VERSION 1.11
|
||||
|
||||
@dircategory Compression
|
||||
@direntry
|
||||
|
@ -38,7 +38,7 @@ This manual is for Plzip (version @value{VERSION}, @value{UPDATED}).
|
|||
@menu
|
||||
* Introduction:: Purpose and features of plzip
|
||||
* Output:: Meaning of plzip's output
|
||||
* Invoking plzip:: Command line interface
|
||||
* Invoking plzip:: Command-line interface
|
||||
* Program design:: Internal structure of plzip
|
||||
* Memory requirements:: Memory required to compress and decompress
|
||||
* Minimum file sizes:: Minimum file sizes required for full speed
|
||||
|
@ -50,7 +50,7 @@ This manual is for Plzip (version @value{VERSION}, @value{UPDATED}).
|
|||
@end menu
|
||||
|
||||
@sp 1
|
||||
Copyright @copyright{} 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright @copyright{} 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This manual is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
@ -62,21 +62,22 @@ distribute, and modify it.
|
|||
@cindex introduction
|
||||
|
||||
@uref{http://www.nongnu.org/lzip/plzip.html,,Plzip}
|
||||
is a massively parallel (multi-threaded) implementation of lzip, fully
|
||||
is a massively parallel (multi-threaded) implementation of lzip,
|
||||
compatible with lzip 1.4 or newer. Plzip uses the compression library
|
||||
@uref{http://www.nongnu.org/lzip/lzlib.html,,lzlib}.
|
||||
|
||||
@uref{http://www.nongnu.org/lzip/lzip.html,,Lzip}
|
||||
is a lossless data compressor with a user interface similar to the one
|
||||
of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov
|
||||
chain-Algorithm' (LZMA) stream format and provides a 3 factor integrity
|
||||
checking to maximize interoperability and optimize safety. Lzip can compress
|
||||
about as fast as gzip @w{(lzip -0)} or compress most files more than bzip2
|
||||
@w{(lzip -9)}. Decompression speed is intermediate between gzip and bzip2.
|
||||
Lzip is better than gzip and bzip2 from 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.
|
||||
chain-Algorithm' (LZMA) stream format to maximize interoperability. The
|
||||
maximum dictionary size is 512 MiB so that any lzip file can be decompressed
|
||||
on 32-bit machines. Lzip provides accurate and robust 3-factor integrity
|
||||
checking. Lzip can compress about as fast as gzip @w{(lzip -0)} or compress most
|
||||
files more than bzip2 @w{(lzip -9)}. Decompression speed is intermediate between
|
||||
gzip and bzip2. Lzip is better than gzip and bzip2 from 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.
|
||||
|
||||
Plzip can compress/decompress large files on multiprocessor machines much
|
||||
faster than lzip, at the cost of a slightly reduced compression ratio (0.4
|
||||
|
@ -130,9 +131,9 @@ Plzip uses the same well-defined exit status values used by lzip, which
|
|||
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.
|
||||
|
||||
Plzip will automatically use for each file the largest dictionary size that
|
||||
does not exceed neither the file size nor the limit given. Keep in mind that
|
||||
the decompression memory requirement is affected at compression time by the
|
||||
Plzip automatically uses for each file the largest dictionary size that does
|
||||
not exceed neither the file size nor the limit given. Keep in mind that the
|
||||
decompression memory requirement is affected at compression time by the
|
||||
choice of dictionary size limit. @xref{Memory requirements}.
|
||||
|
||||
When compressing, plzip replaces every file given in the command line
|
||||
|
@ -147,19 +148,19 @@ file from that of the compressed file as follows:
|
|||
@end multitable
|
||||
|
||||
(De)compressing a file is much like copying or moving it. Therefore plzip
|
||||
preserves the access and modification dates, permissions, and, when
|
||||
possible, ownership of the file just as @w{@samp{cp -p}} does. (If the user ID or
|
||||
the group ID can't be duplicated, the file permission bits S_ISUID and
|
||||
S_ISGID are cleared).
|
||||
preserves the access and modification dates, permissions, and, if you have
|
||||
appropriate privileges, ownership of the file just as @w{@samp{cp -p}} does.
|
||||
(If the user ID or the group ID can't be duplicated, the file permission
|
||||
bits S_ISUID and S_ISGID are cleared).
|
||||
|
||||
Plzip is able to read from some types of non-regular files if either the
|
||||
option @samp{-c} or the option @samp{-o} is specified.
|
||||
option @option{-c} or the option @option{-o} is specified.
|
||||
|
||||
Plzip will refuse to read compressed data from a terminal or write compressed
|
||||
Plzip refuses to read compressed data from a terminal or write compressed
|
||||
data to a terminal, as this would be entirely incomprehensible and might
|
||||
leave the terminal in an abnormal state.
|
||||
|
||||
Plzip will correctly decompress a file which is the concatenation of two or
|
||||
Plzip correctly decompresses a file which is the concatenation of two or
|
||||
more compressed files. The result is the concatenation of the corresponding
|
||||
decompressed files. Integrity testing of concatenated compressed files is
|
||||
also supported.
|
||||
|
@ -231,7 +232,8 @@ plzip [@var{options}] [@var{files}]
|
|||
If no file names are specified, plzip compresses (or decompresses) from
|
||||
standard input to standard output. A hyphen @samp{-} used as a @var{file}
|
||||
argument means standard input. It can be mixed with other @var{files} and is
|
||||
read just once, the first time it appears in the command line.
|
||||
read just once, the first time it appears in the command line. Remember to
|
||||
prepend @file{./} to any file name beginning with a hyphen, or use @samp{--}.
|
||||
|
||||
plzip supports the following
|
||||
@uref{http://www.nongnu.org/arg-parser/manual/arg_parser_manual.html#Argument-syntax,,options}:
|
||||
|
@ -259,30 +261,32 @@ garbage that can be safely ignored. @xref{concat-example}.
|
|||
@anchor{--data-size}
|
||||
@item -B @var{bytes}
|
||||
@itemx --data-size=@var{bytes}
|
||||
When compressing, set the size in bytes of the input data blocks. The
|
||||
input file will be divided in chunks of this size before compression is
|
||||
performed. Valid values range from @w{8 KiB} to @w{1 GiB}. Default value
|
||||
is two times the dictionary size, except for option @samp{-0} where it
|
||||
defaults to @w{1 MiB}. Plzip will reduce the dictionary size if it is
|
||||
larger than the data size specified. @xref{Minimum file sizes}.
|
||||
When compressing, set the size in bytes of the input data blocks. The input
|
||||
file is divided in chunks of this size before compression is performed.
|
||||
Valid values range from @w{8 KiB} to @w{1 GiB}. Default value is two times
|
||||
the dictionary size, except for option @option{-0} where it defaults to
|
||||
@w{1 MiB}. Plzip reduces the dictionary size if it is larger than the data
|
||||
size specified. @xref{Minimum file sizes}.
|
||||
|
||||
@item -c
|
||||
@itemx --stdout
|
||||
Compress or decompress to standard output; keep input files unchanged. If
|
||||
compressing several files, each file is compressed independently. This
|
||||
option (or @samp{-o}) is needed when reading from a named pipe (fifo) or
|
||||
compressing several files, each file is compressed independently. (The
|
||||
output consists of a sequence of independently compressed members). This
|
||||
option (or @option{-o}) is needed when reading from a named pipe (fifo) or
|
||||
from a device. Use @w{@samp{lziprecover -cd -i}} to recover as much of the
|
||||
decompressed data as possible when decompressing a corrupt file. @samp{-c}
|
||||
overrides @samp{-o}. @samp{-c} has no effect when testing or listing.
|
||||
decompressed data as possible when decompressing a corrupt file. @option{-c}
|
||||
overrides @option{-o}. @option{-c} has no effect when testing or listing.
|
||||
|
||||
@item -d
|
||||
@itemx --decompress
|
||||
Decompress the files specified. If a file does not exist, can't be opened,
|
||||
or the destination file already exists and @samp{--force} has not been
|
||||
specified, plzip continues decompressing the rest of the files and exits with
|
||||
error status 1. If a file fails to decompress, or is a terminal, plzip exits
|
||||
immediately with error status 2 without decompressing the rest of the files.
|
||||
A terminal is considered an uncompressed file, and therefore invalid.
|
||||
Decompress the files specified. The integrity of the files specified is
|
||||
checked. If a file does not exist, can't be opened, or the destination file
|
||||
already exists and @option{--force} has not been specified, plzip continues
|
||||
decompressing the rest of the files and exits with error status 1. If a file
|
||||
fails to decompress, or is a terminal, plzip exits immediately with error
|
||||
status 2 without decompressing the rest of the files. A terminal is
|
||||
considered an uncompressed file, and therefore invalid.
|
||||
|
||||
@item -f
|
||||
@itemx --force
|
||||
|
@ -302,23 +306,23 @@ Keep (don't delete) input files during compression or decompression.
|
|||
Print the uncompressed size, compressed size, and percentage saved of the
|
||||
files specified. Trailing data are ignored. The values produced are correct
|
||||
even for multimember files. If more than one file is given, a final line
|
||||
containing the cumulative sizes is printed. With @samp{-v}, the dictionary
|
||||
containing the cumulative sizes is printed. With @option{-v}, the dictionary
|
||||
size, the number of members in the file, and the amount of trailing data (if
|
||||
any) are also printed. With @samp{-vv}, the positions and sizes of each
|
||||
any) are also printed. With @option{-vv}, the positions and sizes of each
|
||||
member in multimember files are also printed.
|
||||
|
||||
If any file is damaged, does not exist, can't be opened, or is not regular,
|
||||
the final exit status will be @w{> 0}. @samp{-lq} can be used to verify
|
||||
quickly (without decompressing) the structural integrity of the files
|
||||
specified. (Use @samp{--test} to verify the data integrity). @samp{-alq}
|
||||
additionally verifies that none of the files specified contain trailing data.
|
||||
the final exit status is @w{> 0}. @option{-lq} can be used to check quickly
|
||||
(without decompressing) the structural integrity of the files specified.
|
||||
(Use @option{--test} to check the data integrity). @option{-alq}
|
||||
additionally checks that none of the files specified contain trailing data.
|
||||
|
||||
@item -m @var{bytes}
|
||||
@itemx --match-length=@var{bytes}
|
||||
When compressing, set the match length limit in bytes. After a match
|
||||
this long is found, the search is finished. Valid values range from 5 to
|
||||
273. Larger values usually give better compression ratios but longer
|
||||
compression times.
|
||||
When compressing, set the match length limit in bytes. After a match this
|
||||
long is found, the search is finished. Valid values range from 5 to 273.
|
||||
Larger values usually give better compression ratios but longer compression
|
||||
times.
|
||||
|
||||
@item -n @var{n}
|
||||
@itemx --threads=@var{n}
|
||||
|
@ -339,17 +343,19 @@ can find the number of members in a lzip file by running
|
|||
|
||||
@item -o @var{file}
|
||||
@itemx --output=@var{file}
|
||||
If @samp{-c} has not been also specified, write the (de)compressed output to
|
||||
@var{file}; keep input files unchanged. If compressing several files, each
|
||||
file is compressed independently. This option (or @samp{-c}) is needed when
|
||||
reading from a named pipe (fifo) or from a device. @w{@samp{-o -}} is
|
||||
equivalent to @samp{-c}. @samp{-o} has no effect when testing or listing.
|
||||
If @option{-c} has not been also specified, write the (de)compressed output
|
||||
to @var{file}, automatically creating any missing parent directories; keep
|
||||
input files unchanged. If compressing several files, each file is compressed
|
||||
independently. (The output consists of a sequence of independently
|
||||
compressed members). This option (or @option{-c}) is needed when reading
|
||||
from a named pipe (fifo) or from a device. @w{@option{-o -}} is equivalent
|
||||
to @option{-c}. @option{-o} has no effect when testing or listing.
|
||||
|
||||
In order to keep backward compatibility with plzip versions prior to 1.9,
|
||||
when compressing from standard input and no other file names are given, the
|
||||
extension @samp{.lz} is appended to @var{file} unless it already ends in
|
||||
@samp{.lz} or @samp{.tlz}. This feature will be removed in a future version
|
||||
of plzip. Meanwhile, redirection may be used instead of @samp{-o} to write
|
||||
of plzip. Meanwhile, redirection may be used instead of @option{-o} to write
|
||||
the compressed output to a file without the extension @samp{.lz} in its
|
||||
name: @w{@samp{plzip < file > foo}}.
|
||||
|
||||
|
@ -359,14 +365,14 @@ Quiet operation. Suppress all messages.
|
|||
|
||||
@item -s @var{bytes}
|
||||
@itemx --dictionary-size=@var{bytes}
|
||||
When compressing, set the dictionary size limit in bytes. Plzip will use
|
||||
for each file the largest dictionary size that does not exceed neither
|
||||
the file size nor this limit. Valid values range from @w{4 KiB} to
|
||||
@w{512 MiB}. Values 12 to 29 are interpreted as powers of two, meaning
|
||||
2^12 to 2^29 bytes. Dictionary sizes are quantized so that they can be
|
||||
coded in just one byte (@pxref{coded-dict-size}). If the size specified
|
||||
does not match one of the valid sizes, it will be rounded upwards by
|
||||
adding up to @w{(@var{bytes} / 8)} to it.
|
||||
When compressing, set the dictionary size limit in bytes. Plzip uses for
|
||||
each file the largest dictionary size that does not exceed neither the file
|
||||
size nor this limit. Valid values range from @w{4 KiB} to @w{512 MiB}.
|
||||
Values 12 to 29 are interpreted as powers of two, meaning 2^12 to 2^29
|
||||
bytes. Dictionary sizes are quantized so that they can be coded in just one
|
||||
byte (@pxref{coded-dict-size}). If the size specified does not match one of
|
||||
the valid sizes, it is rounded upwards by adding up to @w{(@var{bytes} / 8)}
|
||||
to it.
|
||||
|
||||
For maximum compression you should use a dictionary size limit as large
|
||||
as possible, but keep in mind that the decompression memory requirement
|
||||
|
@ -376,11 +382,11 @@ is affected at compression time by the choice of dictionary size limit.
|
|||
@itemx --test
|
||||
Check integrity of the files specified, but don't decompress them. This
|
||||
really performs a trial decompression and throws away the result. Use it
|
||||
together with @samp{-v} to see information about the files. If a file
|
||||
together with @option{-v} to see information about the files. If a file
|
||||
fails the test, does not exist, can't be opened, or is a terminal, plzip
|
||||
continues checking the rest of the files. A final diagnostic is shown at
|
||||
verbosity level 1 or higher if any file fails the test when testing
|
||||
multiple files.
|
||||
continues testing the rest of the files. A final diagnostic is shown at
|
||||
verbosity level 1 or higher if any file fails the test when testing multiple
|
||||
files.
|
||||
|
||||
@item -v
|
||||
@itemx --verbose
|
||||
|
@ -390,24 +396,24 @@ processed.@*
|
|||
When decompressing or testing, further -v's (up to 4) increase the
|
||||
verbosity level, showing status, compression ratio, dictionary size,
|
||||
decompressed size, and compressed size.@*
|
||||
Two or more @samp{-v} options show the progress of (de)compression,
|
||||
Two or more @option{-v} options show the progress of (de)compression,
|
||||
except for single-member files.
|
||||
|
||||
@item -0 .. -9
|
||||
Compression level. Set the compression parameters (dictionary size and
|
||||
match length limit) as shown in the table below. The default compression
|
||||
level is @samp{-6}, equivalent to @w{@samp{-s8MiB -m36}}. Note that
|
||||
@samp{-9} can be much slower than @samp{-0}. These options have no
|
||||
level is @option{-6}, equivalent to @w{@option{-s8MiB -m36}}. Note that
|
||||
@option{-9} can be much slower than @option{-0}. These options have no
|
||||
effect when decompressing, testing, or listing.
|
||||
|
||||
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,
|
||||
etc, you may need to use the options @samp{--dictionary-size} and
|
||||
@samp{--match-length} directly to achieve optimal performance.
|
||||
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, etc, you
|
||||
may need to use the options @option{--dictionary-size} and
|
||||
@option{--match-length} directly to achieve optimal performance.
|
||||
|
||||
If several compression levels or @samp{-s} or @samp{-m} options are
|
||||
given, the last setting is used. For example @w{@samp{-9 -s64MiB}} is
|
||||
equivalent to @w{@samp{-s64MiB -m273}}
|
||||
If several compression levels or @option{-s} or @option{-m} options are
|
||||
given, the last setting is used. For example @w{@option{-9 -s64MiB}} is
|
||||
equivalent to @w{@option{-s64MiB -m273}}
|
||||
|
||||
@multitable {Level} {Dictionary size (-s)} {Match length limit (-m)}
|
||||
@item Level @tab Dictionary size (-s) @tab Match length limit (-m)
|
||||
|
@ -461,28 +467,31 @@ and the value of LZ_API_VERSION (if defined).
|
|||
|
||||
@end table
|
||||
|
||||
Numbers given as arguments to options may be followed by a multiplier
|
||||
and an optional @samp{B} for "byte".
|
||||
Numbers given as arguments to options may be expressed in decimal,
|
||||
hexadecimal, or octal (using the same syntax as integer constants in C++),
|
||||
and may be followed by a multiplier and an optional @samp{B} for "byte".
|
||||
|
||||
Table of SI and binary prefixes (unit multipliers):
|
||||
|
||||
@multitable {Prefix} {kilobyte (10^3 = 1000)} {|} {Prefix} {kibibyte (2^10 = 1024)}
|
||||
@multitable {Prefix} {kilobyte (10^3 = 1000)} {|} {Prefix} {kibibyte (2^10 = 1024)}
|
||||
@item Prefix @tab Value @tab | @tab Prefix @tab Value
|
||||
@item k @tab kilobyte (10^3 = 1000) @tab | @tab Ki @tab kibibyte (2^10 = 1024)
|
||||
@item M @tab megabyte (10^6) @tab | @tab Mi @tab mebibyte (2^20)
|
||||
@item G @tab gigabyte (10^9) @tab | @tab Gi @tab gibibyte (2^30)
|
||||
@item T @tab terabyte (10^12) @tab | @tab Ti @tab tebibyte (2^40)
|
||||
@item P @tab petabyte (10^15) @tab | @tab Pi @tab pebibyte (2^50)
|
||||
@item E @tab exabyte (10^18) @tab | @tab Ei @tab exbibyte (2^60)
|
||||
@item Z @tab zettabyte (10^21) @tab | @tab Zi @tab zebibyte (2^70)
|
||||
@item Y @tab yottabyte (10^24) @tab | @tab Yi @tab yobibyte (2^80)
|
||||
@item k @tab kilobyte (10^3 = 1000) @tab | @tab Ki @tab kibibyte (2^10 = 1024)
|
||||
@item M @tab megabyte (10^6) @tab | @tab Mi @tab mebibyte (2^20)
|
||||
@item G @tab gigabyte (10^9) @tab | @tab Gi @tab gibibyte (2^30)
|
||||
@item T @tab terabyte (10^12) @tab | @tab Ti @tab tebibyte (2^40)
|
||||
@item P @tab petabyte (10^15) @tab | @tab Pi @tab pebibyte (2^50)
|
||||
@item E @tab exabyte (10^18) @tab | @tab Ei @tab exbibyte (2^60)
|
||||
@item Z @tab zettabyte (10^21) @tab | @tab Zi @tab zebibyte (2^70)
|
||||
@item Y @tab yottabyte (10^24) @tab | @tab Yi @tab yobibyte (2^80)
|
||||
@item R @tab ronnabyte (10^27) @tab | @tab Ri @tab robibyte (2^90)
|
||||
@item Q @tab quettabyte (10^30) @tab | @tab Qi @tab quebibyte (2^100)
|
||||
@end multitable
|
||||
|
||||
@sp 1
|
||||
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 invalid
|
||||
input file, 3 for an internal consistency error (e.g., bug) which caused
|
||||
plzip to panic.
|
||||
Exit status: 0 for a normal exit, 1 for environmental problems
|
||||
(file not found, invalid command-line options, I/O errors, etc), 2 to
|
||||
indicate a corrupt or invalid input file, 3 for an internal consistency
|
||||
error (e.g., bug) which caused plzip to panic.
|
||||
|
||||
|
||||
@node Program design
|
||||
|
@ -495,8 +504,8 @@ multimember compressed file. Each chunk is compressed in-place (using the
|
|||
same buffer for input and output), reducing the amount of RAM required.
|
||||
|
||||
When decompressing, plzip decompresses as many members simultaneously as
|
||||
worker threads are chosen. Files that were compressed with lzip will not
|
||||
be decompressed faster than using lzip (unless the option @samp{-b} was used)
|
||||
worker threads are chosen. Files that were compressed with lzip are not
|
||||
decompressed faster than using lzip (unless the option @option{-b} was used)
|
||||
because lzip usually produces single-member files, which can't be
|
||||
decompressed in parallel.
|
||||
|
||||
|
@ -600,14 +609,14 @@ When compressing, plzip divides the input file into chunks and
|
|||
compresses as many chunks simultaneously as worker threads are chosen,
|
||||
creating a multimember compressed file.
|
||||
|
||||
For this to work as expected (and roughly multiply the compression speed
|
||||
by the number of available processors), the uncompressed file must be at
|
||||
least as large as the number of worker threads times the chunk size
|
||||
(@pxref{--data-size}). Else some processors will not get any data to
|
||||
compress, and compression will be proportionally slower. The maximum
|
||||
speed increase achievable on a given file is limited by the ratio
|
||||
@w{(file_size / data_size)}. For example, a tarball the size of gcc or
|
||||
linux will scale up to 10 or 14 processors at level -9.
|
||||
For this to work as expected (and roughly multiply the compression speed by
|
||||
the number of available processors), the uncompressed file must be at least
|
||||
as large as the number of worker threads times the chunk size
|
||||
(@pxref{--data-size}). Else some processors do not get any data to compress,
|
||||
and compression is proportionally slower. The maximum speed increase
|
||||
achievable on a given file is limited by the ratio
|
||||
@w{(file_size / data_size)}. For example, a tarball the size of gcc or linux
|
||||
scales up to 10 or 14 processors at level -9.
|
||||
|
||||
The following table shows the minimum uncompressed file size needed for
|
||||
full use of N processors at a given compression level, using the default
|
||||
|
@ -657,7 +666,7 @@ represents one byte; a box like this:
|
|||
represents a variable number of bytes.
|
||||
|
||||
@sp 1
|
||||
A lzip file consists of a series of independent "members" (compressed data
|
||||
A lzip file consists of one or more independent "members" (compressed data
|
||||
sets). The members simply appear one after another in the file, with no
|
||||
additional information before, between, or after them. Each member can
|
||||
encode in compressed form up to @w{16 EiB - 1 byte} of uncompressed data.
|
||||
|
@ -711,10 +720,10 @@ Size of the original uncompressed data.
|
|||
|
||||
@item Member size (8 bytes)
|
||||
Total size of the member, including header and trailer. This field acts
|
||||
as a distributed index, allows the verification of stream integrity, and
|
||||
as a distributed index, improves the checking of stream integrity, and
|
||||
facilitates the safe recovery of undamaged members from multimember files.
|
||||
Member size should be limited to @w{2 PiB} to prevent the data size field
|
||||
from overflowing.
|
||||
Lzip limits the member size to @w{2 PiB} to prevent the data size field from
|
||||
overflowing.
|
||||
|
||||
@end table
|
||||
|
||||
|
@ -733,12 +742,13 @@ example when writing to a tape. It is safe to append any amount of
|
|||
padding zero bytes to a lzip file.
|
||||
|
||||
@item
|
||||
Useful data added by the user; a cryptographically secure hash, a
|
||||
description of file contents, etc. It is safe to append any amount of
|
||||
text to a lzip file as long as none of the first four bytes of the text
|
||||
match the corresponding byte in the string "LZIP", and the text does not
|
||||
contain any zero bytes (null characters). Nonzero bytes and zero bytes
|
||||
can't be safely mixed in trailing data.
|
||||
Useful data added by the user; an "End Of File" string (to check that the
|
||||
file has not been truncated), a cryptographically secure hash, a description
|
||||
of file contents, etc. It is safe to append any amount of text to a lzip
|
||||
file as long as none of the first four bytes of the text matches the
|
||||
corresponding byte in the string "LZIP", and the text does not contain any
|
||||
zero bytes (null characters). Nonzero bytes and zero bytes can't be safely
|
||||
mixed in trailing data.
|
||||
|
||||
@item
|
||||
Garbage added by some not totally successful copy operation.
|
||||
|
@ -756,8 +766,8 @@ integrity information itself. Therefore it can be considered to be below
|
|||
the noise level. Additionally, the test used by plzip to discriminate
|
||||
trailing data from a corrupt header has a Hamming distance (HD) of 3,
|
||||
and the 3 bit flips must happen in different magic bytes for the test to
|
||||
fail. In any case, the option @samp{--trailing-error} guarantees that
|
||||
any corrupt header will be detected.
|
||||
fail. In any case, the option @option{--trailing-error} guarantees that
|
||||
any corrupt header is detected.
|
||||
@end itemize
|
||||
|
||||
Trailing data are in no way part of the lzip file format, but tools
|
||||
|
@ -767,7 +777,7 @@ possible in the presence of trailing data.
|
|||
Trailing data can be safely ignored in most cases. In some cases, like
|
||||
that of user-added data, they are expected to be ignored. In those cases
|
||||
where a file containing trailing data must be rejected, the option
|
||||
@samp{--trailing-error} can be used. @xref{--trailing-error}.
|
||||
@option{--trailing-error} can be used. @xref{--trailing-error}.
|
||||
|
||||
|
||||
@node Examples
|
||||
|
@ -777,8 +787,8 @@ where a file containing trailing data must be rejected, the option
|
|||
WARNING! Even if plzip is bug-free, other causes may result in a corrupt
|
||||
compressed file (bugs in the system libraries, memory errors, etc).
|
||||
Therefore, if the data you are going to compress are important, give the
|
||||
option @samp{--keep} to plzip and don't remove the original file until you
|
||||
verify the compressed file with a command like
|
||||
option @option{--keep} to plzip and don't remove the original file until you
|
||||
check the compressed file with a command like
|
||||
@w{@samp{plzip -cd file.lz | cmp file -}}. Most RAM errors happening during
|
||||
compression can only be detected by comparing the compressed file with the
|
||||
original because the corruption happens before plzip compresses the RAM
|
||||
|
@ -823,7 +833,7 @@ plzip -d file.lz
|
|||
|
||||
@sp 1
|
||||
@noindent
|
||||
Example 5: Verify the integrity of the compressed file @samp{file.lz} and
|
||||
Example 5: Check the integrity of the compressed file @samp{file.lz} and
|
||||
show status.
|
||||
|
||||
@example
|
||||
|
|
7
list.cc
7
list.cc
|
@ -1,5 +1,5 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -48,12 +48,13 @@ void list_line( const unsigned long long uncomp_size,
|
|||
|
||||
|
||||
int list_files( const std::vector< std::string > & filenames,
|
||||
const bool ignore_trailing, const bool loose_trailing )
|
||||
const Cl_options & cl_opts )
|
||||
{
|
||||
unsigned long long total_comp = 0, total_uncomp = 0;
|
||||
int files = 0, retval = 0;
|
||||
bool first_post = true;
|
||||
bool stdin_used = false;
|
||||
|
||||
for( unsigned i = 0; i < filenames.size(); ++i )
|
||||
{
|
||||
const bool from_stdin = ( filenames[i] == "-" );
|
||||
|
@ -65,7 +66,7 @@ int list_files( const std::vector< std::string > & filenames,
|
|||
open_instream( input_filename, &in_stats, false, true );
|
||||
if( infd < 0 ) { set_retval( retval, 1 ); continue; }
|
||||
|
||||
const Lzip_index lzip_index( infd, ignore_trailing, loose_trailing );
|
||||
const Lzip_index lzip_index( infd, cl_opts );
|
||||
close( infd );
|
||||
if( lzip_index.retval() != 0 )
|
||||
{
|
||||
|
|
69
lzip.h
69
lzip.h
|
@ -1,5 +1,5 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -68,8 +68,8 @@ public:
|
|||
|
||||
|
||||
inline bool isvalid_ds( const unsigned dictionary_size )
|
||||
{ return ( dictionary_size >= min_dictionary_size &&
|
||||
dictionary_size <= max_dictionary_size ); }
|
||||
{ return dictionary_size >= min_dictionary_size &&
|
||||
dictionary_size <= max_dictionary_size; }
|
||||
|
||||
|
||||
inline int real_bits( unsigned value )
|
||||
|
@ -84,35 +84,35 @@ const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; // "LZIP"
|
|||
|
||||
struct Lzip_header
|
||||
{
|
||||
uint8_t data[6]; // 0-3 magic bytes
|
||||
enum { size = 6 };
|
||||
uint8_t data[size]; // 0-3 magic bytes
|
||||
// 4 version
|
||||
// 5 coded dictionary size
|
||||
enum { size = 6 };
|
||||
|
||||
void set_magic() { std::memcpy( data, lzip_magic, 4 ); data[4] = 1; }
|
||||
bool verify_magic() const
|
||||
{ return ( std::memcmp( data, lzip_magic, 4 ) == 0 ); }
|
||||
bool check_magic() const { return std::memcmp( data, lzip_magic, 4 ) == 0; }
|
||||
|
||||
bool verify_prefix( const int sz ) const // detect (truncated) header
|
||||
bool check_prefix( const int sz ) const // detect (truncated) header
|
||||
{
|
||||
for( int i = 0; i < sz && i < 4; ++i )
|
||||
if( data[i] != lzip_magic[i] ) return false;
|
||||
return ( sz > 0 );
|
||||
return sz > 0;
|
||||
}
|
||||
bool verify_corrupt() const // detect corrupt header
|
||||
|
||||
bool check_corrupt() const // detect corrupt header
|
||||
{
|
||||
int matches = 0;
|
||||
for( int i = 0; i < 4; ++i )
|
||||
if( data[i] == lzip_magic[i] ) ++matches;
|
||||
return ( matches > 1 && matches < 4 );
|
||||
return matches > 1 && matches < 4;
|
||||
}
|
||||
|
||||
uint8_t version() const { return data[4]; }
|
||||
bool verify_version() const { return ( data[4] == 1 ); }
|
||||
bool check_version() const { return data[4] == 1; }
|
||||
|
||||
unsigned dictionary_size() const
|
||||
{
|
||||
unsigned sz = ( 1 << ( data[5] & 0x1F ) );
|
||||
unsigned sz = 1 << ( data[5] & 0x1F );
|
||||
if( sz > min_dictionary_size )
|
||||
sz -= ( sz / 16 ) * ( ( data[5] >> 5 ) & 7 );
|
||||
return sz;
|
||||
|
@ -128,23 +128,23 @@ struct Lzip_header
|
|||
const unsigned fraction = base_size / 16;
|
||||
for( unsigned i = 7; i >= 1; --i )
|
||||
if( base_size - ( i * fraction ) >= sz )
|
||||
{ data[5] |= ( i << 5 ); break; }
|
||||
{ data[5] |= i << 5; break; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool verify() const
|
||||
{ return verify_magic() && verify_version() &&
|
||||
bool check() const
|
||||
{ return check_magic() && check_version() &&
|
||||
isvalid_ds( dictionary_size() ); }
|
||||
};
|
||||
|
||||
|
||||
struct Lzip_trailer
|
||||
{
|
||||
uint8_t data[20]; // 0-3 CRC32 of the uncompressed data
|
||||
enum { size = 20 };
|
||||
uint8_t data[size]; // 0-3 CRC32 of the uncompressed data
|
||||
// 4-11 size of the uncompressed data
|
||||
// 12-19 member size including header and trailer
|
||||
enum { size = 20 };
|
||||
|
||||
unsigned data_crc() const
|
||||
{
|
||||
|
@ -176,7 +176,7 @@ struct Lzip_trailer
|
|||
void member_size( unsigned long long sz )
|
||||
{ for( int i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } }
|
||||
|
||||
bool verify_consistency() const // check internal consistency
|
||||
bool check_consistency() const // check internal consistency
|
||||
{
|
||||
const unsigned crc = data_crc();
|
||||
const unsigned long long dsize = data_size();
|
||||
|
@ -192,6 +192,15 @@ struct Lzip_trailer
|
|||
};
|
||||
|
||||
|
||||
struct Cl_options // command-line options
|
||||
{
|
||||
bool ignore_trailing;
|
||||
bool loose_trailing;
|
||||
|
||||
Cl_options() : ignore_trailing( true ), loose_trailing( false ) {}
|
||||
};
|
||||
|
||||
|
||||
inline void set_retval( int & retval, const int new_val )
|
||||
{ if( retval < new_val ) retval = new_val; }
|
||||
|
||||
|
@ -220,7 +229,7 @@ int compress( const unsigned long long cfile_size,
|
|||
const Pretty_print & pp, const int debug_level );
|
||||
|
||||
// defined in lzip_index.cc
|
||||
class Lzip_index;
|
||||
class Lzip_index; // forward declaration
|
||||
|
||||
// defined in dec_stdout.cc
|
||||
int dec_stdout( const int num_workers, const int infd, const int outfd,
|
||||
|
@ -228,11 +237,10 @@ int dec_stdout( const int num_workers, const int infd, const int outfd,
|
|||
const int out_slots, const Lzip_index & lzip_index );
|
||||
|
||||
// defined in dec_stream.cc
|
||||
int dec_stream( const unsigned long long cfile_size,
|
||||
const int num_workers, const int infd, const int outfd,
|
||||
int dec_stream( const unsigned long long cfile_size, const int num_workers,
|
||||
const int infd, const int outfd, const Cl_options & cl_opts,
|
||||
const Pretty_print & pp, const int debug_level,
|
||||
const int in_slots, const int out_slots,
|
||||
const bool ignore_trailing, const bool loose_trailing );
|
||||
const int in_slots, const int out_slots );
|
||||
|
||||
// defined in decompress.cc
|
||||
int preadblock( const int fd, uint8_t * const buf, const int size,
|
||||
|
@ -245,15 +253,14 @@ void show_results( const unsigned long long in_size,
|
|||
const unsigned long long out_size,
|
||||
const unsigned dictionary_size, const bool testing );
|
||||
int decompress( const unsigned long long cfile_size, int num_workers,
|
||||
const int infd, const int outfd, const Pretty_print & pp,
|
||||
const int debug_level, const int in_slots,
|
||||
const int out_slots, const bool ignore_trailing,
|
||||
const bool loose_trailing, const bool infd_isreg,
|
||||
const bool one_to_one );
|
||||
const int infd, const int outfd, const Cl_options & cl_opts,
|
||||
const Pretty_print & pp, const int debug_level,
|
||||
const int in_slots, const int out_slots,
|
||||
const bool infd_isreg, const bool one_to_one );
|
||||
|
||||
// defined in list.cc
|
||||
int list_files( const std::vector< std::string > & filenames,
|
||||
const bool ignore_trailing, const bool loose_trailing );
|
||||
const Cl_options & cl_opts );
|
||||
|
||||
// defined in main.cc
|
||||
struct stat;
|
||||
|
@ -290,7 +297,7 @@ public:
|
|||
|
||||
~Slot_tally() { xdestroy_cond( &slot_av ); xdestroy_mutex( &mutex ); }
|
||||
|
||||
bool all_free() { return ( num_free == num_slots ); }
|
||||
bool all_free() { return num_free == num_slots; }
|
||||
|
||||
void get_slot() // wait for a free slot
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -43,17 +43,16 @@ int seek_read( const int fd, uint8_t * const buf, const int size,
|
|||
} // end namespace
|
||||
|
||||
|
||||
bool Lzip_index::check_header_error( const Lzip_header & header,
|
||||
const bool first )
|
||||
bool Lzip_index::check_header( const Lzip_header & header, const bool first )
|
||||
{
|
||||
if( !header.verify_magic() )
|
||||
if( !header.check_magic() )
|
||||
{ error_ = bad_magic_msg; retval_ = 2; if( first ) bad_magic_ = true;
|
||||
return true; }
|
||||
if( !header.verify_version() )
|
||||
{ error_ = bad_version( header.version() ); retval_ = 2; return true; }
|
||||
return false; }
|
||||
if( !header.check_version() )
|
||||
{ error_ = bad_version( header.version() ); retval_ = 2; return false; }
|
||||
if( !isvalid_ds( header.dictionary_size() ) )
|
||||
{ error_ = bad_dict_msg; retval_ = 2; return true; }
|
||||
return false;
|
||||
{ error_ = bad_dict_msg; retval_ = 2; return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
void Lzip_index::set_errno_error( const char * const msg )
|
||||
|
@ -74,7 +73,7 @@ void Lzip_index::set_num_error( const char * const msg, unsigned long long num )
|
|||
bool Lzip_index::read_header( const int fd, Lzip_header & header,
|
||||
const long long pos )
|
||||
{
|
||||
if( seek_read( fd, header.data, Lzip_header::size, pos ) != Lzip_header::size )
|
||||
if( seek_read( fd, header.data, header.size, pos ) != header.size )
|
||||
{ set_errno_error( "Error reading member header: " ); return false; }
|
||||
return true;
|
||||
}
|
||||
|
@ -82,8 +81,7 @@ bool Lzip_index::read_header( const int fd, Lzip_header & header,
|
|||
|
||||
// If successful, push last member and set pos to member header.
|
||||
bool Lzip_index::skip_trailing_data( const int fd, unsigned long long & pos,
|
||||
const bool ignore_trailing,
|
||||
const bool loose_trailing )
|
||||
const Cl_options & cl_opts )
|
||||
{
|
||||
if( pos < min_member_size ) return false;
|
||||
enum { block_size = 16384,
|
||||
|
@ -104,34 +102,33 @@ bool Lzip_index::skip_trailing_data( const int fd, unsigned long long & pos,
|
|||
if( buffer[i-1] <= max_msb ) // most significant byte of member_size
|
||||
{
|
||||
const Lzip_trailer & trailer =
|
||||
*(const Lzip_trailer *)( buffer + i - Lzip_trailer::size );
|
||||
*(const Lzip_trailer *)( buffer + i - trailer.size );
|
||||
const unsigned long long member_size = trailer.member_size();
|
||||
if( member_size == 0 ) // skip trailing zeros
|
||||
{ while( i > Lzip_trailer::size && buffer[i-9] == 0 ) --i; continue; }
|
||||
if( member_size > ipos + i || !trailer.verify_consistency() )
|
||||
continue;
|
||||
{ while( i > trailer.size && buffer[i-9] == 0 ) --i; continue; }
|
||||
if( member_size > ipos + i || !trailer.check_consistency() ) continue;
|
||||
Lzip_header header;
|
||||
if( !read_header( fd, header, ipos + i - member_size ) ) return false;
|
||||
if( !header.verify() ) continue;
|
||||
if( !header.check() ) continue;
|
||||
const Lzip_header & header2 = *(const Lzip_header *)( buffer + i );
|
||||
const bool full_h2 = bsize - i >= Lzip_header::size;
|
||||
if( header2.verify_prefix( bsize - i ) ) // last member
|
||||
const bool full_h2 = bsize - i >= header.size;
|
||||
if( header2.check_prefix( bsize - i ) ) // last member
|
||||
{
|
||||
if( !full_h2 ) error_ = "Last member in input file is truncated.";
|
||||
else if( !check_header_error( header2, false ) )
|
||||
else if( check_header( header2, false ) )
|
||||
error_ = "Last member in input file is truncated or corrupt.";
|
||||
retval_ = 2; return false;
|
||||
}
|
||||
if( !loose_trailing && full_h2 && header2.verify_corrupt() )
|
||||
if( !cl_opts.loose_trailing && full_h2 && header2.check_corrupt() )
|
||||
{ error_ = corrupt_mm_msg; retval_ = 2; return false; }
|
||||
if( !ignore_trailing )
|
||||
if( !cl_opts.ignore_trailing )
|
||||
{ error_ = trailing_msg; retval_ = 2; return false; }
|
||||
pos = ipos + i - member_size;
|
||||
pos = ipos + i - member_size; // good member
|
||||
const unsigned dictionary_size = header.dictionary_size();
|
||||
member_vector.push_back( Member( 0, trailer.data_size(), pos,
|
||||
member_size, dictionary_size ) );
|
||||
if( dictionary_size_ < dictionary_size )
|
||||
dictionary_size_ = dictionary_size;
|
||||
member_vector.push_back( Member( 0, trailer.data_size(), pos,
|
||||
member_size, dictionary_size ) );
|
||||
return true;
|
||||
}
|
||||
if( ipos == 0 )
|
||||
|
@ -146,8 +143,7 @@ bool Lzip_index::skip_trailing_data( const int fd, unsigned long long & pos,
|
|||
}
|
||||
|
||||
|
||||
Lzip_index::Lzip_index( const int infd, const bool ignore_trailing,
|
||||
const bool loose_trailing )
|
||||
Lzip_index::Lzip_index( const int infd, const Cl_options & cl_opts )
|
||||
: insize( lseek( infd, 0, SEEK_END ) ), retval_( 0 ), dictionary_size_( 0 ),
|
||||
bad_magic_( false )
|
||||
{
|
||||
|
@ -160,42 +156,38 @@ Lzip_index::Lzip_index( const int infd, const bool ignore_trailing,
|
|||
retval_ = 2; return; }
|
||||
|
||||
Lzip_header header;
|
||||
if( !read_header( infd, header, 0 ) ) return;
|
||||
if( check_header_error( header, true ) ) return;
|
||||
if( !read_header( infd, header, 0 ) ||
|
||||
!check_header( header, true ) ) return;
|
||||
|
||||
unsigned long long pos = insize; // always points to a header or to EOF
|
||||
while( pos >= min_member_size )
|
||||
{
|
||||
Lzip_trailer trailer;
|
||||
if( seek_read( infd, trailer.data, Lzip_trailer::size,
|
||||
pos - Lzip_trailer::size ) != Lzip_trailer::size )
|
||||
if( seek_read( infd, trailer.data, trailer.size, pos - trailer.size ) !=
|
||||
trailer.size )
|
||||
{ set_errno_error( "Error reading member trailer: " ); break; }
|
||||
const unsigned long long member_size = trailer.member_size();
|
||||
if( member_size > pos || !trailer.verify_consistency() ) // bad trailer
|
||||
if( member_size > pos || !trailer.check_consistency() ) // bad trailer
|
||||
{
|
||||
if( member_vector.empty() )
|
||||
{ if( skip_trailing_data( infd, pos, ignore_trailing, loose_trailing ) )
|
||||
continue; else return; }
|
||||
set_num_error( "Bad trailer at pos ", pos - Lzip_trailer::size );
|
||||
break;
|
||||
{ if( skip_trailing_data( infd, pos, cl_opts ) ) continue; return; }
|
||||
set_num_error( "Bad trailer at pos ", pos - trailer.size ); break;
|
||||
}
|
||||
if( !read_header( infd, header, pos - member_size ) ) break;
|
||||
if( !header.verify() ) // bad header
|
||||
if( !header.check() ) // bad header
|
||||
{
|
||||
if( member_vector.empty() )
|
||||
{ if( skip_trailing_data( infd, pos, ignore_trailing, loose_trailing ) )
|
||||
continue; else return; }
|
||||
set_num_error( "Bad header at pos ", pos - member_size );
|
||||
break;
|
||||
{ if( skip_trailing_data( infd, pos, cl_opts ) ) continue; return; }
|
||||
set_num_error( "Bad header at pos ", pos - member_size ); break;
|
||||
}
|
||||
pos -= member_size;
|
||||
pos -= member_size; // good member
|
||||
const unsigned dictionary_size = header.dictionary_size();
|
||||
member_vector.push_back( Member( 0, trailer.data_size(), pos,
|
||||
member_size, dictionary_size ) );
|
||||
if( dictionary_size_ < dictionary_size )
|
||||
dictionary_size_ = dictionary_size;
|
||||
member_vector.push_back( Member( 0, trailer.data_size(), pos,
|
||||
member_size, dictionary_size ) );
|
||||
}
|
||||
if( pos != 0 || member_vector.empty() )
|
||||
if( pos != 0 || member_vector.empty() || retval_ != 0 )
|
||||
{
|
||||
member_vector.clear();
|
||||
if( retval_ == 0 ) { error_ = "Can't create file index."; retval_ = 2; }
|
||||
|
|
21
lzip_index.h
21
lzip_index.h
|
@ -1,5 +1,5 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,13 +16,13 @@
|
|||
*/
|
||||
|
||||
#ifndef INT64_MAX
|
||||
#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
|
||||
#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
|
||||
#endif
|
||||
|
||||
|
||||
class Block
|
||||
{
|
||||
long long pos_, size_; // pos + size <= INT64_MAX
|
||||
long long pos_, size_; // pos >= 0, size >= 0, pos + size <= INT64_MAX
|
||||
|
||||
public:
|
||||
Block( const long long p, const long long s ) : pos_( p ), size_( s ) {}
|
||||
|
@ -43,9 +43,11 @@ class Lzip_index
|
|||
Block dblock, mblock; // data block, member block
|
||||
unsigned dictionary_size;
|
||||
|
||||
Member( const long long dp, const long long ds,
|
||||
const long long mp, const long long ms, const unsigned dict_size )
|
||||
: dblock( dp, ds ), mblock( mp, ms ), dictionary_size( dict_size ) {}
|
||||
Member( const long long dpos, const long long dsize,
|
||||
const long long mpos, const long long msize,
|
||||
const unsigned dict_size )
|
||||
: dblock( dpos, dsize ), mblock( mpos, msize ),
|
||||
dictionary_size( dict_size ) {}
|
||||
};
|
||||
|
||||
std::vector< Member > member_vector;
|
||||
|
@ -55,16 +57,15 @@ class Lzip_index
|
|||
unsigned dictionary_size_; // largest dictionary size in the file
|
||||
bool bad_magic_; // bad magic in first header
|
||||
|
||||
bool check_header_error( const Lzip_header & header, const bool first );
|
||||
bool check_header( const Lzip_header & header, const bool first );
|
||||
void set_errno_error( const char * const msg );
|
||||
void set_num_error( const char * const msg, unsigned long long num );
|
||||
bool read_header( const int fd, Lzip_header & header, const long long pos );
|
||||
bool skip_trailing_data( const int fd, unsigned long long & pos,
|
||||
const bool ignore_trailing, const bool loose_trailing );
|
||||
const Cl_options & cl_opts );
|
||||
|
||||
public:
|
||||
Lzip_index( const int infd, const bool ignore_trailing,
|
||||
const bool loose_trailing );
|
||||
Lzip_index( const int infd, const Cl_options & cl_opts );
|
||||
|
||||
long members() const { return member_vector.size(); }
|
||||
const std::string & error() const { return error_; }
|
||||
|
|
244
main.cc
244
main.cc
|
@ -1,6 +1,6 @@
|
|||
/* Plzip - Massively parallel implementation of lzip
|
||||
Copyright (C) 2009 Laszlo Ersek.
|
||||
Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,16 +17,16 @@
|
|||
*/
|
||||
/*
|
||||
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 invalid input file, 3 for an internal consistency error
|
||||
(e.g., bug) which caused plzip to panic.
|
||||
(file not found, invalid command-line options, I/O errors, etc), 2 to
|
||||
indicate a corrupt or invalid input file, 3 for an internal consistency
|
||||
error (e.g., bug) which caused plzip to panic.
|
||||
*/
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
#include <climits> // SSIZE_MAX
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdint.h> // SIZE_MAX
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -77,7 +77,7 @@ int verbosity = 0;
|
|||
namespace {
|
||||
|
||||
const char * const program_name = "plzip";
|
||||
const char * const program_year = "2022";
|
||||
const char * const program_year = "2024";
|
||||
const char * invocation_name = program_name; // default value
|
||||
|
||||
const struct { const char * from; const char * to; } known_extensions[] = {
|
||||
|
@ -102,18 +102,19 @@ bool delete_output_on_interrupt = false;
|
|||
|
||||
void show_help( const long num_online )
|
||||
{
|
||||
std::printf( "Plzip is a massively parallel (multi-threaded) implementation of lzip, fully\n"
|
||||
std::printf( "Plzip is a massively parallel (multi-threaded) implementation of lzip,\n"
|
||||
"compatible with lzip 1.4 or newer. Plzip uses the compression library lzlib.\n"
|
||||
"\nLzip is a lossless data compressor with a user interface similar to the one\n"
|
||||
"of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov\n"
|
||||
"chain-Algorithm' (LZMA) stream format and provides a 3 factor integrity\n"
|
||||
"checking to maximize interoperability and optimize safety. Lzip can compress\n"
|
||||
"about as fast as gzip (lzip -0) or compress most files more than bzip2\n"
|
||||
"(lzip -9). Decompression speed is intermediate between gzip and bzip2.\n"
|
||||
"Lzip is better than gzip and bzip2 from a data recovery perspective. Lzip\n"
|
||||
"has been designed, written, and tested with great care to replace gzip and\n"
|
||||
"bzip2 as the standard general-purpose compressed format for unix-like\n"
|
||||
"systems.\n"
|
||||
"chain-Algorithm' (LZMA) stream format to maximize interoperability. The\n"
|
||||
"maximum dictionary size is 512 MiB so that any lzip file can be decompressed\n"
|
||||
"on 32-bit machines. Lzip provides accurate and robust 3-factor integrity\n"
|
||||
"checking. Lzip can compress about as fast as gzip (lzip -0) or compress most\n"
|
||||
"files more than bzip2 (lzip -9). Decompression speed is intermediate between\n"
|
||||
"gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery\n"
|
||||
"perspective. Lzip has been designed, written, and tested with great care to\n"
|
||||
"replace gzip and bzip2 as the standard general-purpose compressed format for\n"
|
||||
"Unix-like systems.\n"
|
||||
"\nPlzip can compress/decompress large files on multiprocessor machines much\n"
|
||||
"faster than lzip, at the cost of a slightly reduced compression ratio (0.4\n"
|
||||
"to 2 percent larger compressed files). Note that the number of usable\n"
|
||||
|
@ -127,7 +128,7 @@ void show_help( const long num_online )
|
|||
" -a, --trailing-error exit with error status if trailing data\n"
|
||||
" -B, --data-size=<bytes> set size of input data blocks [2x8=16 MiB]\n"
|
||||
" -c, --stdout write to standard output, keep input files\n"
|
||||
" -d, --decompress decompress\n"
|
||||
" -d, --decompress decompress, test compressed file integrity\n"
|
||||
" -f, --force overwrite existing output files\n"
|
||||
" -F, --recompress force re-compression of compressed files\n"
|
||||
" -k, --keep keep (don't delete) input files\n"
|
||||
|
@ -155,32 +156,46 @@ void show_help( const long num_online )
|
|||
"decompresses from standard input to standard output.\n"
|
||||
"Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n"
|
||||
"Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n"
|
||||
"Dictionary sizes 12 to 29 are interpreted as powers of two, meaning 2^12\n"
|
||||
"to 2^29 bytes.\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"
|
||||
"etc, you may need to use the options --dictionary-size and --match-length\n"
|
||||
"directly to achieve optimal performance.\n"
|
||||
"Dictionary sizes 12 to 29 are interpreted as powers of two, meaning 2^12 to\n"
|
||||
"2^29 bytes.\n"
|
||||
"\nThe bidimensional parameter space of LZMA can't be mapped to a linear scale\n"
|
||||
"optimal for all files. If your files are large, very repetitive, etc, you\n"
|
||||
"may need to use the options --dictionary-size and --match-length directly\n"
|
||||
"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 'plzip -cd foo.tar.lz | tar -xf -'.\n"
|
||||
"\nExit status: 0 for a normal exit, 1 for environmental problems (file\n"
|
||||
"not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or\n"
|
||||
"invalid input file, 3 for an internal consistency error (e.g., bug) which\n"
|
||||
"caused plzip to panic.\n"
|
||||
"\nExit status: 0 for a normal exit, 1 for environmental problems\n"
|
||||
"(file not found, invalid command-line options, I/O errors, etc), 2 to\n"
|
||||
"indicate a corrupt or invalid input file, 3 for an internal consistency\n"
|
||||
"error (e.g., bug) which caused plzip to panic.\n"
|
||||
"\nReport bugs to lzip-bug@nongnu.org\n"
|
||||
"Plzip home page: http://www.nongnu.org/lzip/plzip.html\n" );
|
||||
}
|
||||
|
||||
|
||||
void show_lzlib_version()
|
||||
{
|
||||
std::printf( "Using lzlib %s\n", LZ_version() );
|
||||
#if !defined LZ_API_VERSION
|
||||
std::fputs( "LZ_API_VERSION is not defined.\n", stdout );
|
||||
#elif LZ_API_VERSION >= 1012
|
||||
std::printf( "Using LZ_API_VERSION = %u\n", LZ_api_version() );
|
||||
#else
|
||||
std::printf( "Compiled with LZ_API_VERSION = %u. "
|
||||
"Using an unknown LZ_API_VERSION\n", LZ_API_VERSION );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void show_version()
|
||||
{
|
||||
std::printf( "%s %s\n", program_name, PROGVERSION );
|
||||
std::printf( "Copyright (C) 2009 Laszlo Ersek.\n" );
|
||||
std::printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
|
||||
std::printf( "Using lzlib %s\n", LZ_version() );
|
||||
std::printf( "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>\n"
|
||||
"This is free software: you are free to change and redistribute it.\n"
|
||||
"There is NO WARRANTY, to the extent permitted by law.\n" );
|
||||
show_lzlib_version();
|
||||
}
|
||||
|
||||
|
||||
|
@ -226,18 +241,7 @@ int check_lib()
|
|||
std::printf( "warning: LZ_API_VERSION != LZ_api_version() (%u vs %u)\n",
|
||||
LZ_API_VERSION, LZ_api_version() ); }
|
||||
#endif
|
||||
if( verbosity >= 1 )
|
||||
{
|
||||
std::printf( "Using lzlib %s\n", LZ_version() );
|
||||
#if !defined LZ_API_VERSION
|
||||
std::fputs( "LZ_API_VERSION is not defined.\n", stdout );
|
||||
#elif LZ_API_VERSION >= 1012
|
||||
std::printf( "Using LZ_API_VERSION = %u\n", LZ_api_version() );
|
||||
#else
|
||||
std::printf( "Compiled with LZ_API_VERSION = %u. "
|
||||
"Using an unknown LZ_API_VERSION\n", LZ_API_VERSION );
|
||||
#endif
|
||||
}
|
||||
if( verbosity >= 1 ) show_lzlib_version();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -267,16 +271,15 @@ const char * bad_version( const unsigned version )
|
|||
|
||||
const char * format_ds( const unsigned dictionary_size )
|
||||
{
|
||||
enum { bufsize = 16, factor = 1024 };
|
||||
enum { bufsize = 16, factor = 1024, n = 3 };
|
||||
static char buf[bufsize];
|
||||
const char * const prefix[8] =
|
||||
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
|
||||
const char * const prefix[n] = { "Ki", "Mi", "Gi" };
|
||||
const char * p = "";
|
||||
const char * np = " ";
|
||||
unsigned num = dictionary_size;
|
||||
bool exact = ( num % factor == 0 );
|
||||
|
||||
for( int i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i )
|
||||
for( int i = 0; i < n && ( num > 9999 || ( exact && num >= factor ) ); ++i )
|
||||
{ num /= factor; if( num % factor != 0 ) exact = false;
|
||||
p = prefix[i]; np = ""; }
|
||||
snprintf( buf, bufsize, "%s%4u %sB", np, num, p );
|
||||
|
@ -291,12 +294,12 @@ void show_header( const unsigned dictionary_size )
|
|||
|
||||
namespace {
|
||||
|
||||
// separate large numbers >= 100_000 in groups of 3 digits using '_'
|
||||
// separate numbers of 5 or more digits in groups of 3 digits using '_'
|
||||
const char * format_num3( unsigned long long num )
|
||||
{
|
||||
const char * const si_prefix = "kMGTPEZY";
|
||||
const char * const binary_prefix = "KMGTPEZY";
|
||||
enum { buffers = 8, bufsize = 4 * sizeof (long long) };
|
||||
enum { buffers = 8, bufsize = 4 * sizeof num, n = 10 };
|
||||
const char * const si_prefix = "kMGTPEZYRQ";
|
||||
const char * const binary_prefix = "KMGTPEZYRQ";
|
||||
static char buffer[buffers][bufsize]; // circle of static buffers for printf
|
||||
static int current = 0;
|
||||
|
||||
|
@ -306,15 +309,15 @@ const char * format_num3( unsigned long long num )
|
|||
if( num > 1024 )
|
||||
{
|
||||
char prefix = 0; // try binary first, then si
|
||||
for( int i = 0; i < 8 && num >= 1024 && num % 1024 == 0; ++i )
|
||||
for( int i = 0; i < n && num != 0 && num % 1024 == 0; ++i )
|
||||
{ num /= 1024; prefix = binary_prefix[i]; }
|
||||
if( prefix ) *(--p) = 'i';
|
||||
else
|
||||
for( int i = 0; i < 8 && num >= 1000 && num % 1000 == 0; ++i )
|
||||
for( int i = 0; i < n && num != 0 && num % 1000 == 0; ++i )
|
||||
{ num /= 1000; prefix = si_prefix[i]; }
|
||||
if( prefix ) *(--p) = prefix;
|
||||
}
|
||||
const bool split = num >= 100000;
|
||||
const bool split = num >= 10000;
|
||||
|
||||
for( int i = 0; ; )
|
||||
{
|
||||
|
@ -325,6 +328,16 @@ const char * format_num3( unsigned long long num )
|
|||
}
|
||||
|
||||
|
||||
void show_option_error( const char * const arg, const char * const msg,
|
||||
const char * const option_name )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: '%s': %s option '%s'.\n",
|
||||
program_name, arg, msg, option_name );
|
||||
}
|
||||
|
||||
|
||||
// Recognized formats: <num>k, <num>Ki, <num>[MGTPEZYRQ][i]
|
||||
unsigned long long getnum( const char * const arg,
|
||||
const char * const option_name,
|
||||
const unsigned long long llimit,
|
||||
|
@ -334,12 +347,8 @@ unsigned long long getnum( const char * const arg,
|
|||
errno = 0;
|
||||
unsigned long long result = strtoull( arg, &tail, 0 );
|
||||
if( tail == arg )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Bad or missing numerical argument in "
|
||||
"option '%s'.\n", program_name, option_name );
|
||||
std::exit( 1 );
|
||||
}
|
||||
{ show_option_error( arg, "Bad or missing numerical argument in",
|
||||
option_name ); std::exit( 1 ); }
|
||||
|
||||
if( !errno && tail[0] )
|
||||
{
|
||||
|
@ -347,6 +356,8 @@ unsigned long long getnum( const char * const arg,
|
|||
int exponent = 0; // 0 = bad multiplier
|
||||
switch( tail[0] )
|
||||
{
|
||||
case 'Q': exponent = 10; break;
|
||||
case 'R': exponent = 9; break;
|
||||
case 'Y': exponent = 8; break;
|
||||
case 'Z': exponent = 7; break;
|
||||
case 'E': exponent = 6; break;
|
||||
|
@ -358,12 +369,8 @@ unsigned long long getnum( const char * const arg,
|
|||
case 'k': if( factor == 1000 ) exponent = 1; break;
|
||||
}
|
||||
if( exponent <= 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Bad multiplier in numerical argument of "
|
||||
"option '%s'.\n", program_name, option_name );
|
||||
std::exit( 1 );
|
||||
}
|
||||
{ show_option_error( arg, "Bad multiplier in numerical argument of",
|
||||
option_name ); std::exit( 1 ); }
|
||||
for( int i = 0; i < exponent; ++i )
|
||||
{
|
||||
if( ulimit / factor >= result ) result *= factor;
|
||||
|
@ -374,8 +381,8 @@ unsigned long long getnum( const char * const arg,
|
|||
if( errno )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Numerical argument out of limits [%s,%s] "
|
||||
"in option '%s'.\n", program_name, format_num3( llimit ),
|
||||
std::fprintf( stderr, "%s: '%s': Value out of limits [%s,%s] in "
|
||||
"option '%s'.\n", program_name, arg, format_num3( llimit ),
|
||||
format_num3( ulimit ), option_name );
|
||||
std::exit( 1 );
|
||||
}
|
||||
|
@ -447,7 +454,7 @@ void set_d_outname( const std::string & name, const int eindex )
|
|||
}
|
||||
output_filename = name; output_filename += ".out";
|
||||
if( verbosity >= 1 )
|
||||
std::fprintf( stderr, "%s: Can't guess original name for '%s' -- using '%s'\n",
|
||||
std::fprintf( stderr, "%s: %s: Can't guess original name -- using '%s'\n",
|
||||
program_name, name.c_str(), output_filename.c_str() );
|
||||
}
|
||||
|
||||
|
@ -469,9 +476,9 @@ int open_instream( const char * const name, struct stat * const in_statsp,
|
|||
if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n",
|
||||
std::fprintf( stderr, "%s: %s: Input file is not a regular file%s.\n",
|
||||
program_name, name, ( can_read && one_to_one ) ?
|
||||
",\n and neither '-c' nor '-o' were specified" : "" );
|
||||
",\n and neither '-c' nor '-o' were specified" : "" );
|
||||
close( infd );
|
||||
infd = -1;
|
||||
}
|
||||
|
@ -488,7 +495,7 @@ int open_instream2( const char * const name, struct stat * const in_statsp,
|
|||
if( program_mode == m_compress && !recompress && eindex >= 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Input file '%s' already has '%s' suffix.\n",
|
||||
std::fprintf( stderr, "%s: %s: Input file already has '%s' suffix.\n",
|
||||
program_name, name, known_extensions[eindex].from );
|
||||
return -1;
|
||||
}
|
||||
|
@ -496,6 +503,33 @@ int open_instream2( const char * const name, struct stat * const in_statsp,
|
|||
}
|
||||
|
||||
|
||||
bool make_dirs( const std::string & name )
|
||||
{
|
||||
int i = name.size();
|
||||
while( i > 0 && name[i-1] != '/' ) --i; // remove last component
|
||||
while( i > 0 && name[i-1] == '/' ) --i; // remove slash(es)
|
||||
const int dirsize = i; // size of dirname without trailing slash(es)
|
||||
|
||||
for( i = 0; i < dirsize; ) // if dirsize == 0, dirname is '/' or empty
|
||||
{
|
||||
while( i < dirsize && name[i] == '/' ) ++i;
|
||||
const int first = i;
|
||||
while( i < dirsize && name[i] != '/' ) ++i;
|
||||
if( first < i )
|
||||
{
|
||||
const std::string partial( name, 0, i );
|
||||
const mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
struct stat st;
|
||||
if( stat( partial.c_str(), &st ) == 0 )
|
||||
{ if( !S_ISDIR( st.st_mode ) ) { errno = ENOTDIR; return false; } }
|
||||
else if( mkdir( partial.c_str(), mode ) != 0 && errno != EEXIST )
|
||||
return false; // if EEXIST, another process created the dir
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool open_outstream( const bool force, const bool protect )
|
||||
{
|
||||
const mode_t usr_rw = S_IRUSR | S_IWUSR;
|
||||
|
@ -504,18 +538,21 @@ bool open_outstream( const bool force, const bool protect )
|
|||
int flags = O_CREAT | O_WRONLY | O_BINARY;
|
||||
if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
|
||||
|
||||
outfd = open( output_filename.c_str(), flags, outfd_mode );
|
||||
if( outfd >= 0 ) delete_output_on_interrupt = true;
|
||||
else if( verbosity >= 0 )
|
||||
{
|
||||
outfd = -1;
|
||||
if( output_filename.size() &&
|
||||
output_filename[output_filename.size()-1] == '/' ) errno = EISDIR;
|
||||
else {
|
||||
if( !protect && !make_dirs( output_filename ) )
|
||||
{ show_file_error( output_filename.c_str(),
|
||||
"Error creating intermediate directory", errno ); return false; }
|
||||
outfd = open( output_filename.c_str(), flags, outfd_mode );
|
||||
if( outfd >= 0 ) { delete_output_on_interrupt = true; return true; }
|
||||
if( errno == EEXIST )
|
||||
std::fprintf( stderr, "%s: Output file '%s' already exists, skipping.\n",
|
||||
program_name, output_filename.c_str() );
|
||||
else
|
||||
std::fprintf( stderr, "%s: Can't create output file '%s': %s\n",
|
||||
program_name, output_filename.c_str(), std::strerror( errno ) );
|
||||
{ show_file_error( output_filename.c_str(),
|
||||
"Output file already exists, skipping." ); return false; }
|
||||
}
|
||||
return ( outfd >= 0 );
|
||||
show_file_error( output_filename.c_str(), "Can't create output file", errno );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -545,13 +582,13 @@ void cleanup_and_fail( const int retval )
|
|||
{
|
||||
delete_output_on_interrupt = false;
|
||||
if( saved_verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Deleting output file '%s', if it exists.\n",
|
||||
std::fprintf( stderr, "%s: %s: Deleting output file, if it exists.\n",
|
||||
program_name, output_filename.c_str() );
|
||||
if( outfd >= 0 ) { close( outfd ); outfd = -1; }
|
||||
if( std::remove( output_filename.c_str() ) != 0 && errno != ENOENT &&
|
||||
saved_verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: WARNING: deletion of output file "
|
||||
"(apparently) failed.\n", program_name );
|
||||
std::fprintf( stderr, "%s: warning: deletion of output file failed: %s\n",
|
||||
program_name, std::strerror( errno ) );
|
||||
}
|
||||
std::exit( retval );
|
||||
}
|
||||
|
@ -596,7 +633,7 @@ void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
if( in_statsp )
|
||||
{
|
||||
const mode_t mode = in_statsp->st_mode;
|
||||
// fchown will in many cases return with EPERM, which can be safely ignored.
|
||||
// fchown in many cases returns with EPERM, which can be safely ignored.
|
||||
if( fchown( outfd, in_statsp->st_uid, in_statsp->st_gid ) == 0 )
|
||||
{ if( fchmod( outfd, mode ) != 0 ) warning = true; }
|
||||
else
|
||||
|
@ -605,10 +642,8 @@ void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
warning = true;
|
||||
}
|
||||
if( close( outfd ) != 0 )
|
||||
{
|
||||
show_error( "Error closing output file", errno );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
{ show_file_error( output_filename.c_str(), "Error closing output file",
|
||||
errno ); cleanup_and_fail( 1 ); }
|
||||
outfd = -1;
|
||||
delete_output_on_interrupt = false;
|
||||
if( in_statsp )
|
||||
|
@ -619,7 +654,8 @@ void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
if( utime( output_filename.c_str(), &t ) != 0 ) warning = true;
|
||||
}
|
||||
if( warning && verbosity >= 1 )
|
||||
show_error( "Can't change output file attributes." );
|
||||
show_file_error( output_filename.c_str(),
|
||||
"warning: can't change output file attributes", errno );
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
@ -708,8 +744,8 @@ long sysconf( int flag )
|
|||
|
||||
int main( const int argc, const char * const argv[] )
|
||||
{
|
||||
/* Mapping from gzip/bzip2 style 1..9 compression modes
|
||||
to the corresponding LZMA compression modes. */
|
||||
/* Mapping from gzip/bzip2 style 0..9 compression levels to the
|
||||
corresponding LZMA compression parameters. */
|
||||
const Lzma_options option_mapping[] =
|
||||
{
|
||||
{ 65535, 16 }, // -0 (65535,16 chooses fast encoder)
|
||||
|
@ -730,10 +766,9 @@ int main( const int argc, const char * const argv[] )
|
|||
int in_slots = 4;
|
||||
int out_slots = 64;
|
||||
Mode program_mode = m_compress;
|
||||
Cl_options cl_opts; // command-line options
|
||||
bool force = false;
|
||||
bool ignore_trailing = true;
|
||||
bool keep_input_files = false;
|
||||
bool loose_trailing = false;
|
||||
bool recompress = false;
|
||||
bool to_stdout = false;
|
||||
if( argc > 0 ) invocation_name = argv[0];
|
||||
|
@ -799,7 +834,7 @@ int main( const int argc, const char * const argv[] )
|
|||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
encoder_options = option_mapping[code-'0']; break;
|
||||
case 'a': ignore_trailing = false; break;
|
||||
case 'a': cl_opts.ignore_trailing = false; break;
|
||||
case 'b': break;
|
||||
case 'B': data_size = getnum( arg, pn, 2 * LZ_min_dictionary_size(),
|
||||
2 * LZ_max_dictionary_size() ); break;
|
||||
|
@ -826,9 +861,9 @@ int main( const int argc, const char * const argv[] )
|
|||
case opt_chk: return check_lib();
|
||||
case opt_dbg: debug_level = getnum( arg, pn, 0, 3 ); break;
|
||||
case opt_in: in_slots = getnum( arg, pn, 1, 64 ); break;
|
||||
case opt_lt: loose_trailing = true; break;
|
||||
case opt_lt: cl_opts.loose_trailing = true; break;
|
||||
case opt_out: out_slots = getnum( arg, pn, 1, 1024 ); break;
|
||||
default : internal_error( "uncaught option." );
|
||||
default: internal_error( "uncaught option." );
|
||||
}
|
||||
} // end process options
|
||||
|
||||
|
@ -850,8 +885,7 @@ int main( const int argc, const char * const argv[] )
|
|||
}
|
||||
if( filenames.empty() ) filenames.push_back("-");
|
||||
|
||||
if( program_mode == m_list )
|
||||
return list_files( filenames, ignore_trailing, loose_trailing );
|
||||
if( program_mode == m_list ) return list_files( filenames, cl_opts );
|
||||
|
||||
const bool fast = encoder_options.dictionary_size == 65535 &&
|
||||
encoder_options.match_len_limit == 16;
|
||||
|
@ -896,11 +930,11 @@ int main( const int argc, const char * const argv[] )
|
|||
int retval = 0;
|
||||
const bool one_to_one = !to_stdout && program_mode != m_test && !to_file;
|
||||
bool stdin_used = false;
|
||||
struct stat in_stats;
|
||||
for( unsigned i = 0; i < filenames.size(); ++i )
|
||||
{
|
||||
std::string input_filename;
|
||||
int infd;
|
||||
struct stat in_stats;
|
||||
|
||||
pp.set_name( filenames[i] );
|
||||
if( filenames[i] == "-" )
|
||||
|
@ -917,7 +951,7 @@ int main( const int argc, const char * const argv[] )
|
|||
eindex, one_to_one, recompress );
|
||||
if( infd < 0 ) { set_retval( retval, 1 ); continue; }
|
||||
if( !check_tty_in( pp.name(), infd, program_mode, retval ) ) continue;
|
||||
if( one_to_one ) // open outfd after verifying infd
|
||||
if( one_to_one ) // open outfd after checking infd
|
||||
{
|
||||
if( program_mode == m_compress )
|
||||
set_c_outname( input_filename, true, true );
|
||||
|
@ -930,7 +964,7 @@ int main( const int argc, const char * const argv[] )
|
|||
if( one_to_one && !check_tty_out( program_mode ) )
|
||||
{ set_retval( retval, 1 ); return retval; } // don't delete a tty
|
||||
|
||||
if( to_file && outfd < 0 ) // open outfd after verifying infd
|
||||
if( to_file && outfd < 0 ) // open outfd after checking infd
|
||||
{
|
||||
if( program_mode == m_compress ) set_c_outname( default_output_filename,
|
||||
filenames_given, false );
|
||||
|
@ -950,9 +984,9 @@ int main( const int argc, const char * const argv[] )
|
|||
encoder_options.match_len_limit, num_workers,
|
||||
infd, outfd, pp, debug_level );
|
||||
else
|
||||
tmp = decompress( cfile_size, num_workers, infd, outfd, pp,
|
||||
debug_level, in_slots, out_slots, ignore_trailing,
|
||||
loose_trailing, infd_isreg, one_to_one );
|
||||
tmp = decompress( cfile_size, num_workers, infd, outfd, cl_opts, pp,
|
||||
debug_level, in_slots, out_slots, infd_isreg,
|
||||
one_to_one );
|
||||
if( close( infd ) != 0 )
|
||||
{ show_file_error( pp.name(), "Error closing input file", errno );
|
||||
set_retval( tmp, 1 ); }
|
||||
|
@ -966,7 +1000,9 @@ int main( const int argc, const char * const argv[] )
|
|||
if( input_filename.size() && !keep_input_files && one_to_one )
|
||||
std::remove( input_filename.c_str() );
|
||||
}
|
||||
if( delete_output_on_interrupt ) close_and_set_permissions( 0 ); // -o
|
||||
if( delete_output_on_interrupt ) // -o
|
||||
close_and_set_permissions( ( retval == 0 && !stdin_used &&
|
||||
filenames_given && filenames.size() == 1 ) ? &in_stats : 0 );
|
||||
else if( outfd >= 0 && close( outfd ) != 0 ) // -c
|
||||
{
|
||||
show_error( "Error closing stdout", errno );
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# check script for Plzip - Massively parallel implementation of lzip
|
||||
# Copyright (C) 2009-2022 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2024 Antonio Diaz Diaz.
|
||||
#
|
||||
# This script is free software: you have unlimited permission
|
||||
# to copy, distribute, and modify it.
|
||||
|
@ -45,6 +45,7 @@ lzlib_1_10() { [ ${lwarn10} = 0 ] &&
|
|||
|
||||
"${LZIP}" --check-lib # just print warning
|
||||
[ $? != 2 ] || test_failed $LINENO # unless bad lzlib.h
|
||||
|
||||
printf "testing plzip-%s..." "$2"
|
||||
|
||||
"${LZIP}" -fkqm4 in
|
||||
|
@ -81,9 +82,9 @@ done
|
|||
# these are for code coverage
|
||||
"${LZIP}" -lt "${in_lz}" 2> /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -cdl "${in_lz}" > out 2> /dev/null
|
||||
"${LZIP}" -cdl "${in_lz}" 2> /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -cdt "${in_lz}" > out 2> /dev/null
|
||||
"${LZIP}" -cdt "${in_lz}" 2> /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -t -- nx_file.lz 2> /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
|
@ -108,50 +109,50 @@ done
|
|||
printf "LZIP\001-.............................." | "${LZIP}" -t 2> /dev/null
|
||||
printf "LZIP\002-.............................." | "${LZIP}" -t 2> /dev/null
|
||||
printf "LZIP\001+.............................." | "${LZIP}" -t 2> /dev/null
|
||||
rm -f out || framework_failure
|
||||
|
||||
printf "\ntesting decompression..."
|
||||
|
||||
for i in "${in_lz}" "${in_em}" ; do
|
||||
"${LZIP}" -lq "$i" || test_failed $LINENO "$i"
|
||||
"${LZIP}" -t "$i" || test_failed $LINENO "$i"
|
||||
"${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
|
||||
"${LZIP}" -d "$i" -o out || test_failed $LINENO "$i"
|
||||
cmp in out || test_failed $LINENO "$i"
|
||||
"${LZIP}" -cd "$i" > out || test_failed $LINENO "$i"
|
||||
cmp in out || test_failed $LINENO "$i"
|
||||
"${LZIP}" -d "$i" -o - > out || test_failed $LINENO "$i"
|
||||
cmp in out || test_failed $LINENO "$i"
|
||||
"${LZIP}" -d < "$i" > out || test_failed $LINENO "$i"
|
||||
cmp in out || test_failed $LINENO "$i"
|
||||
rm -f out || framework_failure
|
||||
done
|
||||
|
||||
lines=$("${LZIP}" -tvv "${in_em}" 2>&1 | wc -l) || test_failed $LINENO
|
||||
lines=`"${LZIP}" -tvv "${in_em}" 2>&1 | wc -l` || test_failed $LINENO
|
||||
[ "${lines}" -eq 1 ] || test_failed $LINENO "${lines}"
|
||||
|
||||
lines=$("${LZIP}" -lvv "${in_em}" | wc -l) || test_failed $LINENO
|
||||
lines=`"${LZIP}" -lvv "${in_em}" | wc -l` || test_failed $LINENO
|
||||
[ "${lines}" -eq 11 ] || test_failed $LINENO "${lines}"
|
||||
|
||||
"${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO
|
||||
cat "${in_lz}" > copy.lz || framework_failure
|
||||
"${LZIP}" -dk copy.lz || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
cat fox > copy || framework_failure
|
||||
cat "${in_lz}" > out.lz || framework_failure
|
||||
"${LZIP}" -dk out.lz || test_failed $LINENO
|
||||
cmp in out || test_failed $LINENO
|
||||
rm -f out || framework_failure
|
||||
"${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO
|
||||
cat fox > copy || framework_failure
|
||||
cat "${in_lz}" > copy.lz || framework_failure
|
||||
"${LZIP}" -d copy.lz out.lz 2> /dev/null # skip copy, decompress out
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
[ ! -e out.lz ] || test_failed $LINENO
|
||||
cmp fox copy || test_failed $LINENO
|
||||
cmp in out || test_failed $LINENO
|
||||
"${LZIP}" -df copy.lz || test_failed $LINENO
|
||||
[ ! -e copy.lz ] || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
rm -f fox out || framework_failure
|
||||
rm -f copy out || framework_failure
|
||||
|
||||
printf "to be overwritten" > copy || framework_failure
|
||||
"${LZIP}" -df -o copy < "${in_lz}" || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
rm -f out copy || framework_failure
|
||||
printf "to be overwritten" > out || framework_failure
|
||||
"${LZIP}" -df -o out < "${in_lz}" || test_failed $LINENO
|
||||
cmp in out || test_failed $LINENO
|
||||
rm -f out || framework_failure
|
||||
"${LZIP}" -d -o ./- "${in_lz}" || test_failed $LINENO
|
||||
cmp in ./- || test_failed $LINENO
|
||||
rm -f ./- || framework_failure
|
||||
|
@ -160,11 +161,11 @@ cmp in ./- || test_failed $LINENO
|
|||
rm -f ./- || framework_failure
|
||||
|
||||
cat "${in_lz}" > anyothername || framework_failure
|
||||
"${LZIP}" -dv - anyothername - < "${in_lz}" > copy 2> /dev/null ||
|
||||
"${LZIP}" -dv - anyothername - < "${in_lz}" > out 2> /dev/null ||
|
||||
test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
cmp in out || test_failed $LINENO
|
||||
cmp in anyothername.out || test_failed $LINENO
|
||||
rm -f copy anyothername.out || framework_failure
|
||||
rm -f out anyothername.out || framework_failure
|
||||
|
||||
"${LZIP}" -lq in "${in_lz}"
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
|
@ -174,62 +175,73 @@ rm -f copy anyothername.out || framework_failure
|
|||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -tq nx_file.lz "${in_lz}"
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -cdq in "${in_lz}" > copy
|
||||
"${LZIP}" -cdq in "${in_lz}" > out
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
cat copy in | cmp in - || test_failed $LINENO # copy must be empty
|
||||
"${LZIP}" -cdq nx_file.lz "${in_lz}" > copy
|
||||
cat out in | cmp in - || test_failed $LINENO # out must be empty
|
||||
"${LZIP}" -cdq nx_file.lz "${in_lz}" > out # skip nx_file, decompress in
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
rm -f copy || framework_failure
|
||||
cat "${in_lz}" > copy.lz || framework_failure
|
||||
cmp in out || test_failed $LINENO
|
||||
rm -f out || framework_failure
|
||||
cat "${in_lz}" > out.lz || framework_failure
|
||||
for i in 1 2 3 4 5 6 7 ; do
|
||||
printf "g" >> copy.lz || framework_failure
|
||||
"${LZIP}" -alvv copy.lz "${in_lz}" > /dev/null 2>&1
|
||||
printf "g" >> out.lz || framework_failure
|
||||
"${LZIP}" -alvv out.lz "${in_lz}" > /dev/null 2>&1
|
||||
[ $? = 2 ] || test_failed $LINENO $i
|
||||
"${LZIP}" -atvvvv copy.lz "${in_lz}" 2> /dev/null
|
||||
"${LZIP}" -atvvvv out.lz "${in_lz}" 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO $i
|
||||
done
|
||||
"${LZIP}" -dq in copy.lz
|
||||
"${LZIP}" -dq in out.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
[ -e copy.lz ] || test_failed $LINENO
|
||||
[ ! -e copy ] || test_failed $LINENO
|
||||
[ -e out.lz ] || test_failed $LINENO
|
||||
[ ! -e out ] || test_failed $LINENO
|
||||
[ ! -e in.out ] || test_failed $LINENO
|
||||
"${LZIP}" -dq nx_file.lz copy.lz
|
||||
"${LZIP}" -dq nx_file.lz out.lz
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
[ ! -e copy.lz ] || test_failed $LINENO
|
||||
[ ! -e out.lz ] || test_failed $LINENO
|
||||
[ ! -e nx_file ] || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
cmp in out || test_failed $LINENO
|
||||
rm -f out || framework_failure
|
||||
|
||||
cat in in > in2 || framework_failure
|
||||
"${LZIP}" -lq "${in_lz}" "${in_lz}" || test_failed $LINENO
|
||||
"${LZIP}" -t "${in_lz}" "${in_lz}" || test_failed $LINENO
|
||||
"${LZIP}" -cd "${in_lz}" "${in_lz}" -o out > copy2 || test_failed $LINENO
|
||||
"${LZIP}" -cd "${in_lz}" "${in_lz}" -o out > out2 || test_failed $LINENO
|
||||
[ ! -e out ] || test_failed $LINENO # override -o
|
||||
cmp in2 copy2 || test_failed $LINENO
|
||||
rm -f copy2 || framework_failure
|
||||
"${LZIP}" -d "${in_lz}" "${in_lz}" -o copy2 || test_failed $LINENO
|
||||
cmp in2 copy2 || test_failed $LINENO
|
||||
rm -f copy2 || framework_failure
|
||||
cmp in2 out2 || test_failed $LINENO
|
||||
rm -f out2 || framework_failure
|
||||
"${LZIP}" -d "${in_lz}" "${in_lz}" -o out2 || test_failed $LINENO
|
||||
cmp in2 out2 || test_failed $LINENO
|
||||
rm -f out2 || framework_failure
|
||||
|
||||
cat "${in_lz}" "${in_lz}" > copy2.lz || framework_failure
|
||||
printf "\ngarbage" >> copy2.lz || framework_failure
|
||||
"${LZIP}" -tvvvv copy2.lz 2> /dev/null || test_failed $LINENO
|
||||
"${LZIP}" -alq copy2.lz
|
||||
cat "${in_lz}" "${in_lz}" > out2.lz || framework_failure
|
||||
printf "\ngarbage" >> out2.lz || framework_failure
|
||||
"${LZIP}" -tvvvv out2.lz 2> /dev/null || test_failed $LINENO
|
||||
"${LZIP}" -alq out2.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -atq copy2.lz
|
||||
"${LZIP}" -atq out2.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -atq < copy2.lz
|
||||
"${LZIP}" -atq < out2.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -adkq copy2.lz
|
||||
"${LZIP}" -adkq out2.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
[ ! -e copy2 ] || test_failed $LINENO
|
||||
"${LZIP}" -adkq -o copy2 < copy2.lz
|
||||
[ ! -e out2 ] || test_failed $LINENO
|
||||
"${LZIP}" -adkq -o out2 < out2.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
[ ! -e copy2 ] || test_failed $LINENO
|
||||
printf "to be overwritten" > copy2 || framework_failure
|
||||
"${LZIP}" -df copy2.lz || test_failed $LINENO
|
||||
cmp in2 copy2 || test_failed $LINENO
|
||||
rm -f copy2 || framework_failure
|
||||
[ ! -e out2 ] || test_failed $LINENO
|
||||
printf "to be overwritten" > out2 || framework_failure
|
||||
"${LZIP}" -df out2.lz || test_failed $LINENO
|
||||
cmp in2 out2 || test_failed $LINENO
|
||||
rm -f out2 || framework_failure
|
||||
|
||||
"${LZIP}" -d "${fox_lz}" -o a/b/c/fox || test_failed $LINENO
|
||||
cmp fox a/b/c/fox || test_failed $LINENO
|
||||
rm -rf a || framework_failure
|
||||
"${LZIP}" -d -o a/b/c/fox < "${fox_lz}" || test_failed $LINENO
|
||||
cmp fox a/b/c/fox || test_failed $LINENO
|
||||
rm -rf a || framework_failure
|
||||
"${LZIP}" -dq "${fox_lz}" -o a/b/c/
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
[ ! -e a ] || test_failed $LINENO
|
||||
|
||||
printf "\ntesting compression..."
|
||||
|
||||
|
@ -237,14 +249,16 @@ printf "\ntesting compression..."
|
|||
[ ! -e out3.lz ] || test_failed $LINENO # override -o
|
||||
"${LZIP}" -0f in in --output=copy2.lz || test_failed $LINENO
|
||||
"${LZIP}" -d copy2.lz -o out2 || test_failed $LINENO
|
||||
[ -e copy2.lz ] || 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}" > lzlz 2> /dev/null # /dev/null is a tty on OS/2
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -Fvvm36 -o - "${in_lz}" > out 2> /dev/null || test_failed $LINENO
|
||||
"${LZIP}" -cd out | "${LZIP}" -d > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
"${LZIP}" -Fvvm36 -o - "${in_lz}" > lzlz 2> /dev/null || test_failed $LINENO
|
||||
"${LZIP}" -cd lzlz | "${LZIP}" -d > out || test_failed $LINENO
|
||||
cmp in out || test_failed $LINENO
|
||||
rm -f lzlz out || framework_failure
|
||||
|
||||
"${LZIP}" -0 -o ./- in || test_failed $LINENO
|
||||
"${LZIP}" -cd ./- | cmp in - || test_failed $LINENO
|
||||
|
@ -256,10 +270,10 @@ rm -f ./-.lz || framework_failure
|
|||
|
||||
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
||||
"${LZIP}" -k -$i in || test_failed $LINENO $i
|
||||
mv -f in.lz copy.lz || test_failed $LINENO $i
|
||||
printf "garbage" >> copy.lz || framework_failure
|
||||
"${LZIP}" -df copy.lz || test_failed $LINENO $i
|
||||
cmp in copy || test_failed $LINENO $i
|
||||
mv in.lz out.lz || test_failed $LINENO $i
|
||||
printf "garbage" >> out.lz || framework_failure
|
||||
"${LZIP}" -df out.lz || test_failed $LINENO $i
|
||||
cmp in out || test_failed $LINENO $i
|
||||
|
||||
"${LZIP}" -$i in -c > out || test_failed $LINENO $i
|
||||
"${LZIP}" -$i in -o o_out || test_failed $LINENO $i # don't add .lz
|
||||
|
@ -281,7 +295,7 @@ for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
|||
"${LZIP}" -df -o copy < out.lz || test_failed $LINENO $i
|
||||
cmp in copy || test_failed $LINENO $i
|
||||
done
|
||||
rm -f out out.lz || framework_failure
|
||||
rm -f copy out.lz || framework_failure
|
||||
|
||||
cat in in in in > in4 || framework_failure
|
||||
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
|
||||
|
@ -304,21 +318,28 @@ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
|
|||
"${LZIP}" -d -n$i out4.lz || test_failed $LINENO $i
|
||||
cmp in4 out4 || test_failed $LINENO $i
|
||||
done
|
||||
rm -f out4 || framework_failure
|
||||
rm -f in4 out4 || framework_failure
|
||||
|
||||
cat in in in in in in in in | "${LZIP}" -1s4Ki | "${LZIP}" -t ||
|
||||
test_failed $LINENO
|
||||
|
||||
"${LZIP}" fox -o a/b/c/fox.lz || test_failed $LINENO
|
||||
cmp "${fox_lz}" a/b/c/fox.lz || test_failed $LINENO
|
||||
rm -rf a || framework_failure
|
||||
"${LZIP}" -o a/b/c/fox.lz < fox || test_failed $LINENO
|
||||
cmp "${fox_lz}" a/b/c/fox.lz || test_failed $LINENO
|
||||
rm -rf a fox || framework_failure
|
||||
|
||||
printf "\ntesting bad input..."
|
||||
|
||||
headers='LZIp LZiP LZip LzIP LzIp LziP lZIP lZIp lZiP lzIP'
|
||||
body='\001\014\000\203\377\373\377\377\300\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000\000\000\000\000'
|
||||
cat "${in_lz}" > int.lz
|
||||
printf "LZIP${body}" >> int.lz
|
||||
cat "${in_lz}" > int.lz || framework_failure
|
||||
printf "LZIP${body}" >> int.lz || framework_failure
|
||||
if "${LZIP}" -tq int.lz ; then
|
||||
for header in ${headers} ; do
|
||||
printf "${header}${body}" > int.lz # first member
|
||||
"${LZIP}" -lq int.lz
|
||||
printf "${header}${body}" > int.lz || framework_failure
|
||||
"${LZIP}" -lq int.lz # first member
|
||||
[ $? = 2 ] || test_failed $LINENO ${header}
|
||||
"${LZIP}" -tq int.lz
|
||||
[ $? = 2 ] || test_failed $LINENO ${header}
|
||||
|
@ -334,9 +355,9 @@ if "${LZIP}" -tq int.lz ; then
|
|||
[ $? = 2 ] || test_failed $LINENO ${header}
|
||||
"${LZIP}" -cdq --loose-trailing int.lz > /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO ${header}
|
||||
cat "${in_lz}" > int.lz
|
||||
printf "${header}${body}" >> int.lz # trailing data
|
||||
"${LZIP}" -lq int.lz
|
||||
cat "${in_lz}" > int.lz || framework_failure
|
||||
printf "${header}${body}" >> int.lz || framework_failure
|
||||
"${LZIP}" -lq int.lz # trailing data
|
||||
[ $? = 2 ] || test_failed $LINENO ${header}
|
||||
"${LZIP}" -tq int.lz
|
||||
[ $? = 2 ] || test_failed $LINENO ${header}
|
||||
|
@ -384,15 +405,15 @@ if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null &&
|
|||
[ $? = 2 ] || test_failed $LINENO $i
|
||||
"${LZIP}" -tq < trunc.lz
|
||||
[ $? = 2 ] || lzlib_1_8 # requires lzlib 1.8
|
||||
"${LZIP}" -cdq trunc.lz > out
|
||||
"${LZIP}" -cdq trunc.lz > /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO $i
|
||||
"${LZIP}" -dq < trunc.lz > out
|
||||
"${LZIP}" -dq < trunc.lz > /dev/null
|
||||
[ $? = 2 ] || lzlib_1_8 # requires lzlib 1.8
|
||||
done
|
||||
else
|
||||
printf "\nwarning: skipping truncation test: 'dd' does not work on your system."
|
||||
fi
|
||||
rm -f in2.lz in3.lz trunc.lz out || framework_failure
|
||||
rm -f in2.lz in3.lz trunc.lz || framework_failure
|
||||
|
||||
cat "${in_lz}" > ingin.lz || framework_failure
|
||||
printf "g" >> ingin.lz || framework_failure
|
||||
|
@ -403,18 +424,18 @@ cat "${in_lz}" >> ingin.lz || framework_failure
|
|||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -atq < ingin.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -acdq ingin.lz > out
|
||||
"${LZIP}" -acdq ingin.lz > /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -adq < ingin.lz > out
|
||||
"${LZIP}" -adq < ingin.lz > /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -tq ingin.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -t < ingin.lz || test_failed $LINENO
|
||||
"${LZIP}" -cdq ingin.lz > copy
|
||||
"${LZIP}" -cdq ingin.lz > out
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -d < ingin.lz > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
rm -f copy ingin.lz out || framework_failure
|
||||
"${LZIP}" -d < ingin.lz > out || test_failed $LINENO
|
||||
cmp in out || test_failed $LINENO
|
||||
rm -f out ingin.lz || framework_failure
|
||||
|
||||
echo
|
||||
if [ ${fail} = 0 ] ; then
|
||||
|
|
Loading…
Add table
Reference in a new issue