Merging upstream version 1.9.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
3e7d50525b
commit
13941d3cbe
30 changed files with 1188 additions and 1060 deletions
107
ChangeLog
107
ChangeLog
|
@ -1,9 +1,25 @@
|
|||
2020-06-27 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.9 released.
|
||||
* zcmp.cc zdiff.cc: Read standard input only if requested.
|
||||
* zdiff.cc (main): Pass options '-W' and '-y' to diff.
|
||||
* zutils.cc (test_format): Detect bzip2 and lzip files better.
|
||||
* ztest.cc (main): Continue testing if any input file is a terminal.
|
||||
If verbosity >= 1, print number of files that failed the test.
|
||||
* zcat.cc zgrep.cc ztest.cc (main): Check return value of close( infd ).
|
||||
* zutils.cc (good_status): Ignore trailing data remaining in feeder.
|
||||
* zupdate.cc (zupdate_file): Support new and old lzip option '-o'.
|
||||
Keep combined extensions: tgz, tbz, tbz2, txz --> tlz.
|
||||
Quote file names in zcmp_command to allow file names with spaces.
|
||||
* *.cc (main): Set a valid invocation_name even if argc == 0.
|
||||
* zutils.texi: Improve descriptions of zcat, zcmp, and zdiff.
|
||||
|
||||
2019-01-01 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.8 released.
|
||||
* zcat.cc: Fixed a buffer overflow on outbuf when '-v' is used.
|
||||
* zcat.cc: Fix a buffer overflow on outbuf when '-v' is used.
|
||||
* zcat.cc (cat): A canary byte has been added to outbuf.
|
||||
* Added new option '-R, --dereference-recursive'.
|
||||
* New option '-R, --dereference-recursive'.
|
||||
* Option '-r, --recursive' now skips symlinks.
|
||||
* If no files and recursive, examine current working directory.
|
||||
* recursive.cc (test_full_name): Detect directory loops.
|
||||
|
@ -11,15 +27,15 @@
|
|||
* recursive.cc: Remove extra trailing slashes from directory args.
|
||||
* zcatgrep.cc (open_instream): Show correct errno.
|
||||
* zutils.cc (good_status): Wait for killed child.
|
||||
* Test and document continuation or exit of zcat, zgrep, ztest
|
||||
* Test and document continuation or exit of zcat, zgrep, ztest,
|
||||
and zupdate in case of error.
|
||||
* configure: Accept appending to CXXFLAGS, 'CXXFLAGS+=OPTIONS'.
|
||||
|
||||
2018-02-13 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.7 released.
|
||||
* zgrep.cc (main): Pass '--color' option to grep.
|
||||
* check.sh: Added new tests for zgrep.
|
||||
* zgrep.cc (main): Pass option '--color' to grep.
|
||||
* check.sh: Add new tests for zgrep.
|
||||
|
||||
2017-04-05 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
|
@ -41,124 +57,123 @@
|
|||
|
||||
* Version 1.4 released.
|
||||
* Option '--format' has been renamed to '-O, --force-format'.
|
||||
* Added new option '-M, --format=<list>' to all utilities.
|
||||
* Add new option '-M, --format=<list>' to all utilities.
|
||||
* zgrep.cc (main): Pass '-e' to grep if pattern begins with '-'.
|
||||
* Makefile.in: Added new targets 'install*-compress'.
|
||||
* Makefile.in: New targets 'install*-compress'.
|
||||
|
||||
2014-08-30 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.3 released.
|
||||
* check.sh: Fixed two values of expected exit status.
|
||||
* zutils.texi: Documented that '--format' does not verify format.
|
||||
* Added two missing #includes.
|
||||
* License changed to GPL version 2 or later.
|
||||
* check.sh: Fix two values of expected exit status.
|
||||
* zutils.texi: Document that '--format' does not verify format.
|
||||
* Add two missing #includes.
|
||||
* Change license to GPL version 2 or later.
|
||||
|
||||
2014-02-01 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.2 released.
|
||||
* Added new utility; zupdate.
|
||||
* Removed zutils executable. Utils are now independent executables.
|
||||
* zgrep.cc: Fixed the exit status returned on error.
|
||||
* zutils.texinfo: Renamed to zutils.texi.
|
||||
* New utility; zupdate.
|
||||
* Remove zutils executable. Utils are now independent executables.
|
||||
* zgrep.cc: Fix the exit status returned on error.
|
||||
* zutils.texinfo: Rename to zutils.texi.
|
||||
|
||||
2013-08-02 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.1 released.
|
||||
* Added options '--bz2', '--gz', '--lz' and '--xz' to all utilities.
|
||||
* Added runtime configuration file 'zutilsrc'.
|
||||
* Add options '--bz2', '--gz', '--lz', and '--xz' to all utilities.
|
||||
* Add runtime configuration file 'zutilsrc'.
|
||||
* New function 'good_status' checks exit status of all children.
|
||||
* Fixed all uses of decompressed/uncompressed in the documentation.
|
||||
* Fix all uses of decompressed/uncompressed in the documentation.
|
||||
|
||||
2013-05-31 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.0 released.
|
||||
* Added new option '--format' to all utilities.
|
||||
* Add new option '--format' to all utilities.
|
||||
* main.cc (main): Make 'grep_show_name' tri-state so that file
|
||||
name is no prefixed to output by default when searching one
|
||||
file and '--recursive' has not been selected.
|
||||
* Zgrep: Fixed output of option '-L' (it behaved like '-l').
|
||||
* zcmp.cc: Fixed deadlock when '-n' option is used.
|
||||
* zdiff.cc (set_data_feeder): Call compressor with option "-q"
|
||||
* Zgrep: Fix output of option '-L' (it behaved like '-l').
|
||||
* zcmp.cc: Fix deadlock when option '-n' is used.
|
||||
* zdiff.cc (set_data_feeder): Call compressor with option '-q'
|
||||
only if verbosity < 0.
|
||||
* zutils.cc (set_data_feeder): Likewise.
|
||||
* Changed quote characters in messages as advised by GNU Standards.
|
||||
* Change quote characters in messages as advised by GNU Standards.
|
||||
* configure: Options now accept a separate argument.
|
||||
* configure: 'datadir' renamed to 'datarootdir'.
|
||||
* Makefile.in: Added new target 'install-bin'.
|
||||
Rename 'datadir' to 'datarootdir'. Ignore environment variables.
|
||||
* Makefile.in: New target 'install-bin'.
|
||||
* Use 'setmode' instead of '_setmode' on Windows and OS/2.
|
||||
* zcat.cc (Line_number): Fixed a portability issue with Solaris 9.
|
||||
* zcat.cc (Line_number): Fix a portability issue with Solaris 9.
|
||||
* INSTALL: Document installing zutils along with GNU gzip.
|
||||
|
||||
2011-01-11 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.9 released.
|
||||
* configure: Added new options 'DIFF' and 'GREP'.
|
||||
* zcmp.cc: Fixed deadlock when files differ.
|
||||
* zgrep.cc: Fixed deadlock when binary file matches.
|
||||
* configure: New options 'DIFF' and 'GREP'.
|
||||
* zcmp.cc: Fix deadlock when files differ.
|
||||
* zgrep.cc: Fix deadlock when binary file matches.
|
||||
|
||||
2010-11-15 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.8 released.
|
||||
* main.cc: Added new options '--zcat', '--zgrep' and '--ztest'.
|
||||
* main.cc: New options '--zcat', '--zgrep', and '--ztest'.
|
||||
* zcat.cc: New file implementing zcat+cat functionality in C++.
|
||||
* zcmp.cc: New file implementing zcmp+cmp functionality in C++.
|
||||
* doc/zcmp.1: New file.
|
||||
* zcmp.in: Removed.
|
||||
* Remove files zcmp.in, zdiff.in.
|
||||
* zdiff.cc: New file implementing zdiff functionality in C++.
|
||||
* zdiff.in: Removed.
|
||||
* zgrep.cc: New file implementing zgrep functionality in C++.
|
||||
* All mentions to zegrep and zfgrep have been removed from the
|
||||
documentation because egrep and fgrep are deprecated.
|
||||
* ztest.cc: New file implementing ztest functionality in C++.
|
||||
* Makefile.in: Added quotes to directory names.
|
||||
* Makefile.in: Add quotes to directory names.
|
||||
* check.sh: Use 'test.txt' instead of 'COPYING' for testing.
|
||||
* Removed environment safeguards from configure as requested by
|
||||
* Remove environment safeguards from configure as requested by
|
||||
Richard Stallman. Now environment variables affect configure.
|
||||
|
||||
2009-10-21 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.7 released.
|
||||
* Added new utility; ztest.
|
||||
* zcat.in: Added new option '--recursive'.
|
||||
* New utility; ztest.
|
||||
* zcat.in: New option '-r, --recursive'.
|
||||
|
||||
2009-10-05 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.6 released.
|
||||
* zcat.in, zgrep.in: Removed again default compressor. Format of
|
||||
* zcat.in, zgrep.in: Remove again default compressor. Format of
|
||||
data read from stdin is now automatically detected.
|
||||
* Makefile.in: Added '--name' option to help2man invocation.
|
||||
* Makefile.in: Add option '--name' to help2man invocation.
|
||||
|
||||
2009-10-01 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.5 released.
|
||||
* zcat.in, zgrep.in: Read again data from stdin.
|
||||
* Added again default compressor for stdin only.
|
||||
* Add again default compressor for stdin only.
|
||||
|
||||
2009-09-17 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.4 released.
|
||||
* Added two new utilities; zegrep and zfgrep.
|
||||
* Added zutils executable which recognizes file formats.
|
||||
* Add two new utilities; zegrep and zfgrep.
|
||||
* Add zutils executable which recognizes file formats.
|
||||
|
||||
2009-08-28 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.3 released.
|
||||
* Removed default compressor.
|
||||
* Remove default compressor.
|
||||
* zcat.in, zgrep.in: Don't read data from stdin.
|
||||
* Updated home page and mailing list addresses.
|
||||
* Update home page and mailing list addresses.
|
||||
|
||||
2009-08-13 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.2 released.
|
||||
* Added support for xz.
|
||||
* Add support for xz.
|
||||
|
||||
2009-08-07 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.1 released.
|
||||
|
||||
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 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
|
||||
but just in case, you have unlimited permission to copy, distribute, and
|
||||
modify it.
|
||||
|
|
22
INSTALL
22
INSTALL
|
@ -1,7 +1,7 @@
|
|||
Requirements
|
||||
------------
|
||||
You will need a C++ compiler.
|
||||
I use gcc 5.3.0 and 4.1.2, but the code should compile with any standards
|
||||
You will need a C++11 compiler. (gcc 3.3.6 or newer is recommended).
|
||||
I use gcc 6.1.0 and 4.1.2, but the code should compile with any standards
|
||||
compliant compiler.
|
||||
Gcc is available at http://gcc.gnu.org.
|
||||
|
||||
|
@ -44,21 +44,21 @@ the main archive.
|
|||
documentation.
|
||||
|
||||
Or type 'make install-compress', which additionally compresses the
|
||||
info manual and the man pages after installation. (Installing
|
||||
compressed docs may become the default in the future).
|
||||
info manual and the man pages after installation.
|
||||
(Installing compressed docs may become the default in the future).
|
||||
|
||||
You can install only the programs, the info manual or the man pages by
|
||||
typing 'make install-bin', 'make install-info' or 'make install-man'
|
||||
You can install only the programs, the info manual, or the man pages by
|
||||
typing 'make install-bin', 'make install-info', or 'make install-man'
|
||||
respectively.
|
||||
|
||||
|
||||
Another way
|
||||
-----------
|
||||
You can also compile zutils into a separate directory.
|
||||
To do this, you must use a version of 'make' that supports the 'VPATH'
|
||||
variable, such as GNU 'make'. 'cd' to the directory where you want the
|
||||
To do this, you must use a version of 'make' that supports the variable
|
||||
'VPATH', such as GNU 'make'. 'cd' to the directory where you want the
|
||||
object files and executables to go and run the 'configure' script.
|
||||
'configure' automatically checks for the source code in '.', in '..' and
|
||||
'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
|
||||
|
@ -69,7 +69,7 @@ After running 'configure', you can run 'make' and 'make install' as
|
|||
explained above.
|
||||
|
||||
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute and modify it.
|
||||
distribute, and modify it.
|
||||
|
|
52
NEWS
52
NEWS
|
@ -1,38 +1,36 @@
|
|||
Changes in version 1.8:
|
||||
Changes in version 1.9:
|
||||
|
||||
A buffer overflow has been fixed in zcat which happened sometimes when
|
||||
the '-v, --show-nonprinting' option was used (or indirectly enabled).
|
||||
A canary byte has been added to the output buffer to prevent the buffer
|
||||
overflow from happening again.
|
||||
zcmp anf zdiff now meet the POSIX requirement for cmp and diff that the
|
||||
standard input shall be used only if the file1 or file2 operand refers to
|
||||
standard input.
|
||||
|
||||
The option '-R, --dereference-recursive', which recursively follows
|
||||
symbolic links, has been added to zcat, zgrep, ztest and zupdate.
|
||||
zdiff now passes the options '-W' and '-y' to diff. (But it only works if
|
||||
the diff program used supports them).
|
||||
|
||||
The option '-r, --recursive' now skips symlinks that are encountered
|
||||
recursively.
|
||||
Bzip2 and lzip files are now detected better.
|
||||
('echo LZIP | zcat' and 'echo BZh5 | zcat' no longer return an error).
|
||||
|
||||
If no files are given to zcat, zgrep, ztest and zupdate, a recursive
|
||||
search will now examine the current working directory.
|
||||
ztest now continues checking the rest of the files if any input file is a
|
||||
terminal.
|
||||
|
||||
Recursive directory loops are now detected.
|
||||
'ztest -v' now prints the number of files that failed the test (like lzip).
|
||||
|
||||
zcat and zgrep now ignore directories given in the command line if
|
||||
'--recursive' is not specified, instead of reporting an error.
|
||||
zcat, zgrep, and ztest now check for errors when closing the input file in
|
||||
addition to checking when closing the input from the decompressor.
|
||||
|
||||
Extra trailing slashes are now removed from directories given in the
|
||||
command line before recursing into them.
|
||||
Trailing data remaining in the data feeder to the decompressor are now
|
||||
correctly ignored.
|
||||
|
||||
zcat and zgrep now show the right error when they can't open an input
|
||||
file instead of showing "No such file or directory".
|
||||
zupdate has been modified to support the new behavior of lzip 1.22's option
|
||||
'-o' while retaining:
|
||||
perfect backwards compatibility with older versions of lzip down to 1.20,
|
||||
good backwards compatibility with older versions of lzip down to 1.11,
|
||||
acceptable backwards compatibility with older versions of lzip down to 1.4.
|
||||
|
||||
Killed decompressors are now waited for, preventing failure caused by
|
||||
too many open pipes.
|
||||
zupdate now keeps combined extensions: tgz, tbz, tbz2, txz --> tlz.
|
||||
This is useful when recompressing Slackware packages, for example.
|
||||
|
||||
Test and document that if a file fails to decompress, zcat, zgrep and
|
||||
ztest continue processing the rest of the files.
|
||||
zupdate now puts single quotes around file names when calling zcmp to allow
|
||||
file names with spaces. (But putting spaces in file names is a bad idea).
|
||||
|
||||
Test and document that if an error happens while recompressing a file,
|
||||
zupdate exits immediately without recompressing the rest of the files.
|
||||
|
||||
The configure script now accepts appending options to CXXFLAGS using the
|
||||
syntax 'CXXFLAGS+=OPTIONS'.
|
||||
The descriptions of zcat, zcmp, and zdiff have been improved.
|
||||
|
|
44
README
44
README
|
@ -1,46 +1,46 @@
|
|||
Description
|
||||
|
||||
Zutils is a collection of utilities able to process any combination of
|
||||
compressed and uncompressed files transparently. If any given file,
|
||||
including standard input, is compressed, its decompressed content is
|
||||
used. Compressed files are decompressed on the fly; no temporary files
|
||||
are created.
|
||||
compressed and uncompressed files transparently. If any file given,
|
||||
including standard input, is compressed, its decompressed content is used.
|
||||
Compressed files are decompressed on the fly; no temporary files are
|
||||
created.
|
||||
|
||||
These utilities are not wrapper scripts but safer and more efficient C++
|
||||
programs. In particular the '--recursive' option is very efficient in
|
||||
programs. In particular the option '--recursive' is very efficient in
|
||||
those utilities supporting it.
|
||||
|
||||
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest and zupdate.
|
||||
The formats supported are bzip2, gzip, lzip and xz.
|
||||
Zutils uses external compressors. The compressor to be used for each
|
||||
format is configurable at runtime.
|
||||
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest, and zupdate.
|
||||
The formats supported are bzip2, gzip, lzip, and xz.
|
||||
Zutils uses external compressors. The compressor to be used for each format
|
||||
is configurable at runtime.
|
||||
|
||||
zcat, zcmp, zdiff, and zgrep are improved replacements for the shell
|
||||
scripts provided by GNU gzip. ztest is unique to zutils. zupdate is
|
||||
similar to gzip's znew.
|
||||
zcat, zcmp, zdiff, and zgrep are improved replacements for the shell scripts
|
||||
provided by GNU gzip. ztest is unique to zutils. zupdate is similar to
|
||||
gzip's znew.
|
||||
|
||||
NOTE: Bzip2 and lzip provide well-defined values of exit status, which
|
||||
makes them safe to use with zutils. Gzip and xz may return ambiguous
|
||||
warning values, making them less reliable back ends for zutils.
|
||||
NOTE: Bzip2 and lzip provide well-defined values of exit status, which makes
|
||||
them safe to use with zutils. Gzip and xz may return ambiguous warning
|
||||
values, making them less reliable back ends for zutils.
|
||||
|
||||
FORMAT NOTE 1: The '--format' option allows the processing of a subset
|
||||
FORMAT NOTE 1: The option '--format' allows the processing of a subset
|
||||
of formats in recursive mode and when trying compressed file names:
|
||||
'zgrep foo -r --format=bz2,lz somedir somefile.tar'.
|
||||
|
||||
FORMAT NOTE 2: If the '--force-format' option is given, the files are
|
||||
FORMAT NOTE 2: If the option '--force-format' is given, the files are
|
||||
passed to the corresponding decompressor without verifying their format,
|
||||
allowing for example the processing of compress'd (.Z) files with gzip:
|
||||
'zcmp --force-format=gz file.Z file.lz'.
|
||||
|
||||
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never
|
||||
have been compressed. Decompressed is used to refer to data which have
|
||||
undergone the process of decompression.
|
||||
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never have
|
||||
been compressed. Decompressed is used to refer to data which have undergone
|
||||
the process of decompression.
|
||||
|
||||
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute and modify it.
|
||||
distribute, and modify it.
|
||||
|
||||
The file Makefile.in is a data file used by configure to produce the
|
||||
Makefile. It has the same copyright owner and permissions that configure
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2006-2020 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -167,7 +167,7 @@ Arg_parser::Arg_parser( const int argc, const char * const argv[],
|
|||
else non_options.push_back( argv[argind++] );
|
||||
}
|
||||
}
|
||||
if( error_.size() ) data.clear();
|
||||
if( !error_.empty() ) data.clear();
|
||||
else
|
||||
{
|
||||
for( unsigned i = 0; i < non_options.size(); ++i )
|
||||
|
@ -190,7 +190,7 @@ Arg_parser::Arg_parser( const char * const opt, const char * const arg,
|
|||
{ if( opt[2] ) parse_long_option( opt, arg, options, argind ); }
|
||||
else
|
||||
parse_short_option( opt, arg, options, argind );
|
||||
if( error_.size() ) data.clear();
|
||||
if( !error_.empty() ) data.clear();
|
||||
}
|
||||
else data.push_back( Record( opt ) );
|
||||
}
|
||||
|
|
19
arg_parser.h
19
arg_parser.h
|
@ -1,15 +1,15 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2006-2020 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
/* Arg_parser reads the arguments in 'argv' and creates a number of
|
||||
option codes, option arguments and non-option arguments.
|
||||
option codes, option arguments, and non-option arguments.
|
||||
|
||||
In case of error, 'error' returns a non-empty error message.
|
||||
|
||||
|
@ -61,6 +61,7 @@ private:
|
|||
explicit Record( const char * const arg ) : code( 0 ), argument( arg ) {}
|
||||
};
|
||||
|
||||
const std::string empty_arg;
|
||||
std::string error_;
|
||||
std::vector< Record > data;
|
||||
|
||||
|
@ -73,17 +74,17 @@ public:
|
|||
Arg_parser( const int argc, const char * const argv[],
|
||||
const Option options[], const bool in_order = false );
|
||||
|
||||
// Restricted constructor. Parses a single token and argument (if any)
|
||||
// Restricted constructor. Parses a single token and argument (if any).
|
||||
Arg_parser( const char * const opt, const char * const arg,
|
||||
const Option options[] );
|
||||
|
||||
const std::string & error() const { return error_; }
|
||||
|
||||
// The number of arguments parsed (may be different from argc)
|
||||
// The number of arguments parsed. May be different from argc.
|
||||
int arguments() const { return data.size(); }
|
||||
|
||||
// If code( i ) is 0, argument( i ) is a non-option.
|
||||
// Else argument( i ) is the option's argument (or empty).
|
||||
/* If code( i ) is 0, argument( i ) is a non-option.
|
||||
Else argument( i ) is the option's argument (or empty). */
|
||||
int code( const int i ) const
|
||||
{
|
||||
if( i >= 0 && i < arguments() ) return data[i].code;
|
||||
|
@ -93,6 +94,6 @@ public:
|
|||
const std::string & argument( const int i ) const
|
||||
{
|
||||
if( i >= 0 && i < arguments() ) return data[i].argument;
|
||||
else return error_;
|
||||
else return empty_arg;
|
||||
}
|
||||
};
|
||||
|
|
25
configure
vendored
25
configure
vendored
|
@ -1,12 +1,12 @@
|
|||
#! /bin/sh
|
||||
# configure script for Zutils - Utilities dealing with compressed files
|
||||
# Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2020 Antonio Diaz Diaz.
|
||||
#
|
||||
# This configure script is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
pkgname=zutils
|
||||
pkgversion=1.8
|
||||
pkgversion=1.9
|
||||
srctrigger=doc/${pkgname}.texi
|
||||
|
||||
# clear some things potentially inherited from environment.
|
||||
|
@ -28,11 +28,7 @@ DIFF=diff
|
|||
GREP=grep
|
||||
|
||||
# checking whether we are using GNU C++.
|
||||
/bin/sh -c "${CXX} --version" > /dev/null 2>&1 ||
|
||||
{
|
||||
CXX=c++
|
||||
CXXFLAGS=-O2
|
||||
}
|
||||
/bin/sh -c "${CXX} --version" > /dev/null 2>&1 || { CXX=c++ ; CXXFLAGS=-O2 ; }
|
||||
|
||||
# Loop over all args
|
||||
args=
|
||||
|
@ -44,11 +40,12 @@ while [ $# != 0 ] ; do
|
|||
shift
|
||||
|
||||
# Add the argument quoted to args
|
||||
args="${args} \"${option}\""
|
||||
if [ -z "${args}" ] ; then args="\"${option}\""
|
||||
else args="${args} \"${option}\"" ; fi
|
||||
|
||||
# Split out the argument for options that take them
|
||||
case ${option} in
|
||||
*=*) optarg=`echo ${option} | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
|
||||
*=*) optarg=`echo "${option}" | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
|
||||
esac
|
||||
|
||||
# Process the options
|
||||
|
@ -134,7 +131,7 @@ if [ -z "${srcdir}" ] ; then
|
|||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then srcdir=.. ; fi
|
||||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
|
||||
## the sed command below emulates the dirname command
|
||||
srcdir=`echo $0 | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
srcdir=`echo "$0" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -157,7 +154,7 @@ if [ -z "${no_create}" ] ; then
|
|||
# Run this file to recreate the current configuration.
|
||||
#
|
||||
# This script is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
exec /bin/sh $0 ${args} --no-create
|
||||
EOF
|
||||
|
@ -182,11 +179,11 @@ echo "GREP = ${GREP}"
|
|||
rm -f Makefile
|
||||
cat > Makefile << EOF
|
||||
# Makefile for Zutils - Utilities dealing with compressed files
|
||||
# Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2020 Antonio Diaz Diaz.
|
||||
# This file was generated automatically by configure. Don't edit.
|
||||
#
|
||||
# This Makefile is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
pkgname = ${pkgname}
|
||||
pkgversion = ${pkgversion}
|
||||
|
|
22
doc/zcat.1
22
doc/zcat.1
|
@ -1,27 +1,29 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
|
||||
.TH ZCAT "1" "January 2019" "zcat (zutils) 1.8" "User Commands"
|
||||
.TH ZCAT "1" "June 2020" "zcat (zutils) 1.9" "User Commands"
|
||||
.SH NAME
|
||||
zcat \- decompress and concatenate files to standard output
|
||||
.SH SYNOPSIS
|
||||
.B zcat
|
||||
[\fI\,options\/\fR] [\fI\,files\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Zcat copies each given file to standard output. If any given file is
|
||||
compressed, its decompressed content is used. If a given file does not
|
||||
exist, and its name does not end with one of the known extensions, zcat
|
||||
tries the compressed file names corresponding to the formats supported.
|
||||
zcat copies each file argument to standard output in sequence. If any
|
||||
file given is compressed, its decompressed content is copied. If a file
|
||||
given does not exist, and its name does not end with one of the known
|
||||
extensions, zcat tries the compressed file names corresponding to the
|
||||
formats supported. If a file fails to decompress, zcat continues copying the
|
||||
rest of the files.
|
||||
.PP
|
||||
If a file is specified as '\-', data are read from standard input,
|
||||
decompressed if needed, and sent to standard output. Data read from
|
||||
standard input must be of the same type; all uncompressed or all in the
|
||||
same compression format.
|
||||
same compressed format.
|
||||
.PP
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
.PP
|
||||
The formats supported are bzip2, gzip, lzip and xz.
|
||||
The formats supported are bzip2, gzip, lzip, and xz.
|
||||
.PP
|
||||
Exit status is 0 if no errors occurred, non\-zero otherwise.
|
||||
Exit status is 0 if no errors occurred, 1 otherwise.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
|
@ -52,7 +54,7 @@ number all output lines
|
|||
don't read runtime configuration file
|
||||
.TP
|
||||
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
||||
force given format (bz2, gz, lz, xz)
|
||||
force the format given (bz2, gz, lz, xz)
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR
|
||||
suppress all messages
|
||||
|
@ -94,7 +96,7 @@ Report bugs to zutils\-bug@nongnu.org
|
|||
.br
|
||||
Zutils home page: http://www.nongnu.org/zutils/zutils.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2019 Antonio Diaz Diaz.
|
||||
Copyright \(co 2020 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.
|
||||
|
|
28
doc/zcmp.1
28
doc/zcmp.1
|
@ -1,31 +1,29 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
|
||||
.TH ZCMP "1" "January 2019" "zcmp (zutils) 1.8" "User Commands"
|
||||
.TH ZCMP "1" "June 2020" "zcmp (zutils) 1.9" "User Commands"
|
||||
.SH NAME
|
||||
zcmp \- decompress and compare two files byte by byte
|
||||
.SH SYNOPSIS
|
||||
.B zcmp
|
||||
[\fI\,options\/\fR] \fI\,file1 \/\fR[\fI\,file2\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Zcmp compares two files ('\-' means standard input), and if they differ,
|
||||
tells the first byte and line number where they differ. Bytes and lines
|
||||
are numbered starting with 1. If any given file is compressed, its
|
||||
decompressed content is used. Compressed files are decompressed on the
|
||||
fly; no temporary files are created.
|
||||
zcmp compares two files and, if they differ, writes to standard output the
|
||||
first byte and line number where they differ. Bytes and lines are numbered
|
||||
starting with 1. A hyphen '\-' used as a file argument means standard input.
|
||||
If any file given is compressed, its decompressed content is used. Compressed
|
||||
files are decompressed on the fly; no temporary files are created.
|
||||
.PP
|
||||
The formats supported are bzip2, gzip, lzip and xz.
|
||||
The formats supported are bzip2, gzip, lzip, and xz.
|
||||
.PP
|
||||
Zcmp compares file1 to file2. If file2 is omitted zcmp tries the
|
||||
zcmp compares file1 to file2. The standard input is used only if file1 or
|
||||
file2 refers to standard input. If file2 is omitted zcmp tries the
|
||||
following:
|
||||
.IP
|
||||
1. If file1 is compressed, compares its decompressed contents with
|
||||
\- If file1 is compressed, compares its decompressed contents with
|
||||
the corresponding uncompressed file (the name of file1 with the
|
||||
extension removed).
|
||||
.IP
|
||||
2. If file1 is uncompressed, compares it with the decompressed
|
||||
\- If file1 is uncompressed, compares it with the decompressed
|
||||
contents of file1.[lz|bz2|gz|xz] (the first one that is found).
|
||||
.IP
|
||||
3. If no suitable file is found, compares file1 with data read from
|
||||
standard input.
|
||||
.PP
|
||||
Exit status is 0 if inputs are identical, 1 if different, 2 if trouble.
|
||||
.SH OPTIONS
|
||||
|
@ -55,7 +53,7 @@ compare at most <n> bytes
|
|||
don't read runtime configuration file
|
||||
.TP
|
||||
\fB\-O\fR, \fB\-\-force\-format\fR=\fI\,[\/\fR<f1>][,<f2>]
|
||||
force given formats (bz2, gz, lz, xz)
|
||||
force the formats given (bz2, gz, lz, xz)
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR
|
||||
suppress all messages
|
||||
|
@ -85,7 +83,7 @@ Report bugs to zutils\-bug@nongnu.org
|
|||
.br
|
||||
Zutils home page: http://www.nongnu.org/zutils/zutils.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2019 Antonio Diaz Diaz.
|
||||
Copyright \(co 2020 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.
|
||||
|
|
35
doc/zdiff.1
35
doc/zdiff.1
|
@ -1,33 +1,32 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
|
||||
.TH ZDIFF "1" "January 2019" "zdiff (zutils) 1.8" "User Commands"
|
||||
.TH ZDIFF "1" "June 2020" "zdiff (zutils) 1.9" "User Commands"
|
||||
.SH NAME
|
||||
zdiff \- decompress and compare two files line by line
|
||||
.SH SYNOPSIS
|
||||
.B zdiff
|
||||
[\fI\,options\/\fR] \fI\,file1 \/\fR[\fI\,file2\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Zdiff compares two files ('\-' means standard input), and if they
|
||||
differ, shows the differences line by line. If any given file is
|
||||
compressed, its decompressed content is used. Zdiff is a front end to
|
||||
the diff program and has the limitation that messages from diff refer to
|
||||
temporary filenames instead of those specified.
|
||||
zdiff compares two files and, if they differ, writes to standard output the
|
||||
differences line by line. A hyphen '\-' used as a file argument means standard
|
||||
input. If any file given is compressed, its decompressed content is used.
|
||||
zdiff is a front end to the program diff and has the limitation that messages
|
||||
from diff refer to temporary file names instead of those specified.
|
||||
.PP
|
||||
The formats supported are bzip2, gzip, lzip and xz.
|
||||
The formats supported are bzip2, gzip, lzip, and xz.
|
||||
.PP
|
||||
Zdiff compares file1 to file2. If file2 is omitted zdiff tries the
|
||||
zdiff compares file1 to file2. The standard input is used only if file1 or
|
||||
file2 refers to standard input. If file2 is omitted zdiff tries the
|
||||
following:
|
||||
.IP
|
||||
1. If file1 is compressed, compares its decompressed contents with
|
||||
\- If file1 is compressed, compares its decompressed contents with
|
||||
the corresponding uncompressed file (the name of file1 with the
|
||||
extension removed).
|
||||
.IP
|
||||
2. If file1 is uncompressed, compares it with the decompressed
|
||||
\- If file1 is uncompressed, compares it with the decompressed
|
||||
contents of file1.[lz|bz2|gz|xz] (the first one that is found).
|
||||
.IP
|
||||
3. If no suitable file is found, compares file1 with data read from
|
||||
standard input.
|
||||
.PP
|
||||
Exit status is 0 if inputs are identical, 1 if different, 2 if trouble.
|
||||
Some options only work if the diff program used supports them.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
|
@ -67,7 +66,7 @@ process only the formats in <list>
|
|||
don't read runtime configuration file
|
||||
.TP
|
||||
\fB\-O\fR, \fB\-\-force\-format\fR=\fI\,[\/\fR<f1>][,<f2>]
|
||||
force given formats (bz2, gz, lz, xz)
|
||||
force the formats given (bz2, gz, lz, xz)
|
||||
.TP
|
||||
\fB\-p\fR, \fB\-\-show\-c\-function\fR
|
||||
show which C function each change is in
|
||||
|
@ -93,6 +92,12 @@ same as \fB\-u\fR but use <n> lines of context
|
|||
\fB\-w\fR, \fB\-\-ignore\-all\-space\fR
|
||||
ignore all white space
|
||||
.TP
|
||||
\fB\-W\fR, \fB\-\-width=\fR<n>
|
||||
output at most <n> print columns
|
||||
.TP
|
||||
\fB\-y\fR, \fB\-\-side\-by\-side\fR
|
||||
output in two columns
|
||||
.TP
|
||||
\fB\-\-bz2=\fR<command>
|
||||
set compressor and options for bzip2 format
|
||||
.TP
|
||||
|
@ -109,7 +114,7 @@ Report bugs to zutils\-bug@nongnu.org
|
|||
.br
|
||||
Zutils home page: http://www.nongnu.org/zutils/zutils.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2019 Antonio Diaz Diaz.
|
||||
Copyright \(co 2020 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.
|
||||
|
|
20
doc/zgrep.1
20
doc/zgrep.1
|
@ -1,29 +1,31 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
|
||||
.TH ZGREP "1" "January 2019" "zgrep (zutils) 1.8" "User Commands"
|
||||
.TH ZGREP "1" "June 2020" "zgrep (zutils) 1.9" "User Commands"
|
||||
.SH NAME
|
||||
zgrep \- search compressed files for a regular expression
|
||||
.SH SYNOPSIS
|
||||
.B zgrep
|
||||
[\fI\,options\/\fR] \fI\,<pattern> \/\fR[\fI\,files\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Zgrep is a front end to the grep program that allows transparent search
|
||||
on any combination of compressed and uncompressed files. If any given
|
||||
file is compressed, its decompressed content is used. If a given file
|
||||
zgrep is a front end to the program grep that allows transparent search
|
||||
on any combination of compressed and uncompressed files. If any file
|
||||
given is compressed, its decompressed content is used. If a file given
|
||||
does not exist, and its name does not end with one of the known
|
||||
extensions, zgrep tries the compressed file names corresponding to the
|
||||
formats supported.
|
||||
formats supported. If a file fails to decompress, zgrep continues
|
||||
searching the rest of the files.
|
||||
.PP
|
||||
If a file is specified as '\-', data are read from standard input,
|
||||
decompressed if needed, and fed to grep. Data read from standard input
|
||||
must be of the same type; all uncompressed or all in the same
|
||||
compression format.
|
||||
compressed format.
|
||||
.PP
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
.PP
|
||||
The formats supported are bzip2, gzip, lzip and xz.
|
||||
The formats supported are bzip2, gzip, lzip, and xz.
|
||||
.PP
|
||||
Exit status is 0 if match, 1 if no match, 2 if trouble.
|
||||
Some options only work if the grep program used supports them.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
|
@ -99,7 +101,7 @@ don't read runtime configuration file
|
|||
show only the part of a line matching <pattern>
|
||||
.TP
|
||||
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
||||
force given format (bz2, gz, lz, xz)
|
||||
force the format given (bz2, gz, lz, xz)
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR
|
||||
suppress all messages
|
||||
|
@ -144,7 +146,7 @@ Report bugs to zutils\-bug@nongnu.org
|
|||
.br
|
||||
Zutils home page: http://www.nongnu.org/zutils/zutils.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2019 Antonio Diaz Diaz.
|
||||
Copyright \(co 2020 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.
|
||||
|
|
16
doc/ztest.1
16
doc/ztest.1
|
@ -1,20 +1,24 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
|
||||
.TH ZTEST "1" "January 2019" "ztest (zutils) 1.8" "User Commands"
|
||||
.TH ZTEST "1" "June 2020" "ztest (zutils) 1.9" "User Commands"
|
||||
.SH NAME
|
||||
ztest \- verify the integrity of compressed files
|
||||
.SH SYNOPSIS
|
||||
.B ztest
|
||||
[\fI\,options\/\fR] [\fI\,files\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Ztest verifies the integrity of the specified compressed files.
|
||||
ztest verifies the integrity of the compressed files specified.
|
||||
Uncompressed files are ignored. If a file is specified as '\-', the
|
||||
integrity of compressed data read from standard input is verified. Data
|
||||
read from standard input must be all in the same compression format.
|
||||
read from standard input must be all in the same compressed format. If
|
||||
a file fails to decompress, does not exist, can't be opened, or is a
|
||||
terminal, ztest continues verifying 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.
|
||||
.PP
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
.PP
|
||||
The formats supported are bzip2, gzip, lzip and xz.
|
||||
The formats supported are bzip2, gzip, lzip, and xz.
|
||||
.PP
|
||||
Note that error detection in the xz format is broken. First, some xz
|
||||
files lack integrity information. Second, not all xz decompressors can
|
||||
|
@ -41,7 +45,7 @@ process only the formats in <list>
|
|||
don't read runtime configuration file
|
||||
.TP
|
||||
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
||||
force given format (bz2, gz, lz, xz)
|
||||
force the format given (bz2, gz, lz, xz)
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR
|
||||
suppress all messages
|
||||
|
@ -71,7 +75,7 @@ Report bugs to zutils\-bug@nongnu.org
|
|||
.br
|
||||
Zutils home page: http://www.nongnu.org/zutils/zutils.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2019 Antonio Diaz Diaz.
|
||||
Copyright \(co 2020 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.
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
|
||||
.TH ZUPDATE "1" "January 2019" "zupdate (zutils) 1.8" "User Commands"
|
||||
.TH ZUPDATE "1" "June 2020" "zupdate (zutils) 1.9" "User Commands"
|
||||
.SH NAME
|
||||
zupdate \- recompress bzip2, gzip, xz files to lzip format
|
||||
.SH SYNOPSIS
|
||||
.B zupdate
|
||||
[\fI\,options\/\fR] [\fI\,files\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Zupdate recompresses files from bzip2, gzip, and xz formats to lzip
|
||||
zupdate recompresses files from bzip2, gzip, and xz formats to lzip
|
||||
format. Each original is compared with the new file and then deleted.
|
||||
Only regular files with standard file name extensions are recompressed,
|
||||
other files are ignored. Compressed files are decompressed and then
|
||||
|
@ -18,15 +18,18 @@ If no files are specified, recursive searches examine the current
|
|||
working directory, and nonrecursive searches do nothing.
|
||||
.PP
|
||||
If the lzip compressed version of a file already exists, the file is
|
||||
skipped unless the '\-\-force' option is given. In this case, if the
|
||||
skipped unless the option '\-\-force' is given. In this case, if the
|
||||
comparison with the existing lzip version fails, an error is returned
|
||||
and the original file is not deleted. The operation of zupdate is meant
|
||||
to be safe and not produce any data loss. Therefore, existing lzip
|
||||
to be safe and not cause any data loss. Therefore, existing lzip
|
||||
compressed files are never overwritten nor deleted.
|
||||
.PP
|
||||
Exit status is 0 if all the compressed files were successfully
|
||||
recompressed (if needed), compared and deleted (if requested). Non\-zero
|
||||
otherwise.
|
||||
The names of the original files must have one of the following extensions:
|
||||
\&'.bz2', '.gz', and '.xz' are recompressed to '.lz'.
|
||||
\&'.tbz', '.tbz2', '.tgz', and '.txz' are recompressed to '.tlz'.
|
||||
.PP
|
||||
Exit status is 0 if all the compressed files were successfully recompressed
|
||||
(if needed), compared, and deleted (if requested). Non\-zero otherwise.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
|
@ -42,7 +45,7 @@ don't skip a file even if the .lz exists
|
|||
keep (don't delete) input files
|
||||
.TP
|
||||
\fB\-l\fR, \fB\-\-lzip\-verbose\fR
|
||||
pass a \fB\-v\fR option to the lzip compressor
|
||||
pass one option \fB\-v\fR to the lzip compressor
|
||||
.TP
|
||||
\fB\-M\fR, \fB\-\-format=\fR<list>
|
||||
process only the formats in <list>
|
||||
|
@ -81,7 +84,7 @@ Report bugs to zutils\-bug@nongnu.org
|
|||
.br
|
||||
Zutils home page: http://www.nongnu.org/zutils/zutils.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2019 Antonio Diaz Diaz.
|
||||
Copyright \(co 2020 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.
|
||||
|
|
507
doc/zutils.info
507
doc/zutils.info
|
@ -1,5 +1,4 @@
|
|||
This is zutils.info, produced by makeinfo version 4.13+ from
|
||||
zutils.texi.
|
||||
This is zutils.info, produced by makeinfo version 4.13+ from zutils.texi.
|
||||
|
||||
INFO-DIR-SECTION Data Compression
|
||||
START-INFO-DIR-ENTRY
|
||||
|
@ -12,7 +11,7 @@ File: zutils.info, Node: Top, Next: Introduction, Up: (dir)
|
|||
Zutils Manual
|
||||
*************
|
||||
|
||||
This manual is for Zutils (version 1.8, 1 January 2019).
|
||||
This manual is for Zutils (version 1.9, 27 June 2020).
|
||||
|
||||
* Menu:
|
||||
|
||||
|
@ -29,10 +28,10 @@ This manual is for Zutils (version 1.8, 1 January 2019).
|
|||
* Concept index:: Index of concepts
|
||||
|
||||
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 Antonio Diaz Diaz.
|
||||
|
||||
This manual is free documentation: you have unlimited permission to
|
||||
copy, distribute and modify it.
|
||||
This manual is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
||||
|
||||
File: zutils.info, Node: Introduction, Next: Common options, Prev: Top, Up: Top
|
||||
|
@ -41,45 +40,45 @@ File: zutils.info, Node: Introduction, Next: Common options, Prev: Top, Up:
|
|||
**************
|
||||
|
||||
Zutils is a collection of utilities able to process any combination of
|
||||
compressed and uncompressed files transparently. If any given file,
|
||||
including standard input, is compressed, its decompressed content is
|
||||
used. Compressed files are decompressed on the fly; no temporary files
|
||||
are created.
|
||||
compressed and uncompressed files transparently. If any file given,
|
||||
including standard input, is compressed, its decompressed content is used.
|
||||
Compressed files are decompressed on the fly; no temporary files are
|
||||
created.
|
||||
|
||||
These utilities are not wrapper scripts but safer and more efficient
|
||||
C++ programs. In particular the '--recursive' option is very efficient
|
||||
in those utilities supporting it.
|
||||
These utilities are not wrapper scripts but safer and more efficient C++
|
||||
programs. In particular the option '--recursive' is very efficient in those
|
||||
utilities supporting it.
|
||||
|
||||
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest and zupdate.
|
||||
The formats supported are bzip2, gzip, lzip and xz.
|
||||
Zutils uses external compressors. The compressor to be used for each
|
||||
format is configurable at runtime.
|
||||
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest, and zupdate.
|
||||
The formats supported are bzip2, gzip, lzip, and xz.
|
||||
Zutils uses external compressors. The compressor to be used for each format
|
||||
is configurable at runtime.
|
||||
|
||||
zcat, zcmp, zdiff, and zgrep are improved replacements for the shell
|
||||
scripts provided by GNU gzip. ztest is unique to zutils. zupdate is
|
||||
similar to gzip's znew.
|
||||
scripts provided by GNU gzip. ztest is unique to zutils. zupdate is similar
|
||||
to gzip's znew.
|
||||
|
||||
NOTE: Bzip2 and lzip provide well-defined values of exit status,
|
||||
which makes them safe to use with zutils. Gzip and xz may return
|
||||
ambiguous warning values, making them less reliable back ends for
|
||||
zutils. *Note compressor-requirements::.
|
||||
NOTE: Bzip2 and lzip provide well-defined values of exit status, which
|
||||
makes them safe to use with zutils. Gzip and xz may return ambiguous warning
|
||||
values, making them less reliable back ends for zutils. *Note
|
||||
compressor-requirements::.
|
||||
|
||||
FORMAT NOTE 1: The '--format' option allows the processing of a
|
||||
subset of formats in recursive mode and when trying compressed file
|
||||
names: 'zgrep foo -r --format=bz2,lz somedir somefile.tar'.
|
||||
FORMAT NOTE 1: The option '--format' allows the processing of a subset
|
||||
of formats in recursive mode and when trying compressed file names:
|
||||
'zgrep foo -r --format=bz2,lz somedir somefile.tar'.
|
||||
|
||||
FORMAT NOTE 2: If the '--force-format' option is given, the files
|
||||
are passed to the corresponding decompressor without verifying their
|
||||
format, allowing for example the processing of compress'd (.Z) files
|
||||
with gzip: 'zcmp --force-format=gz file.Z file.lz'.
|
||||
FORMAT NOTE 2: If the option '--force-format' is given, the files are
|
||||
passed to the corresponding decompressor without verifying their format,
|
||||
allowing for example the processing of compress'd (.Z) files with gzip:
|
||||
'zcmp --force-format=gz file.Z file.lz'.
|
||||
|
||||
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may
|
||||
never have been compressed. Decompressed is used to refer to data which
|
||||
have undergone the process of decompression.
|
||||
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never
|
||||
have been compressed. Decompressed is used to refer to data which have
|
||||
undergone the process of decompression.
|
||||
|
||||
|
||||
Numbers given as arguments to options (positions, sizes) may be
|
||||
followed by a multiplier and an optional 'B' for "byte".
|
||||
Numbers given as arguments to options (positions, sizes) may be followed
|
||||
by a multiplier and an optional 'B' for "byte".
|
||||
|
||||
Table of SI and binary prefixes (unit multipliers):
|
||||
|
||||
|
@ -99,9 +98,9 @@ File: zutils.info, Node: Common options, Next: The zutilsrc file, Prev: Intro
|
|||
2 Common options
|
||||
****************
|
||||
|
||||
The following options are available in all the utilities. Rather than
|
||||
writing identical descriptions for each of the programs, they are
|
||||
described here.
|
||||
The following options: are available in all the utilities. Rather than
|
||||
writing identical descriptions for each of the programs, they are described
|
||||
here. *Note Argument syntax: (arg_parser)Argument syntax.
|
||||
|
||||
'-h'
|
||||
'--help'
|
||||
|
@ -110,19 +109,19 @@ described here.
|
|||
|
||||
'-V'
|
||||
'--version'
|
||||
Print the version number on the standard output and exit. This
|
||||
version number should be included in all bug reports.
|
||||
Print the version number on the standard output and exit. This version
|
||||
number should be included in all bug reports.
|
||||
|
||||
'-M FORMAT_LIST'
|
||||
'--format=FORMAT_LIST'
|
||||
Process only the formats listed in the comma-separated
|
||||
FORMAT_LIST. Valid formats are 'bz2', 'gz', 'lz', 'xz' and 'un'
|
||||
for 'uncompressed', meaning "any file name without a known
|
||||
extension". This option excludes files based on extension, instead
|
||||
of format, because it is more efficient. The exclusion only
|
||||
applies to names generated automatically (for example when adding
|
||||
extensions to a file name or when operating recursively on
|
||||
directories). Files given in the command line are always processed.
|
||||
Process only the formats listed in the comma-separated FORMAT_LIST.
|
||||
Valid formats are 'bz2', 'gz', 'lz', 'xz', and 'un' for
|
||||
'uncompressed', meaning "any file name without a known extension".
|
||||
This option excludes files based on extension, instead of format,
|
||||
because it is more efficient. The exclusion only applies to names
|
||||
generated automatically (for example when adding extensions to a file
|
||||
name or when operating recursively on directories). Files given in the
|
||||
command line are always processed.
|
||||
|
||||
Each format in FORMAT_LIST enables file names with the following
|
||||
extensions:
|
||||
|
@ -141,17 +140,20 @@ described here.
|
|||
'--gz=COMMAND'
|
||||
'--lz=COMMAND'
|
||||
'--xz=COMMAND'
|
||||
Set program (may include arguments) to be used as (de)compressor
|
||||
for the given format. The name of the program can't begin with
|
||||
'-'. These options override the values set in 'zutilsrc'. The
|
||||
compression program used must meet three requirements:
|
||||
Set program to be used as (de)compressor for the corresponding format.
|
||||
COMMAND may include arguments. For example '--lz='plzip --threads=2''.
|
||||
The program set with '--lz' is used for both compression and
|
||||
decompression. The other three are used only for decompression. The
|
||||
name of the program can't begin with '-'. These options override the
|
||||
values set in 'zutilsrc'. The compression program used must meet three
|
||||
requirements:
|
||||
|
||||
1. When called with the '-d' option, it must read compressed
|
||||
data from the standard input and produce decompressed data on
|
||||
the standard output.
|
||||
1. When called with the option '-d', it must read compressed data
|
||||
from the standard input and produce decompressed data on the
|
||||
standard output.
|
||||
|
||||
2. If the '-q' option is passed to zutils, the compression
|
||||
program must also accept it.
|
||||
2. If the option '-q' is passed to zutils, the compression program
|
||||
must also accept it.
|
||||
|
||||
3. It must return 0 if no errors occurred, and a non-zero value
|
||||
otherwise.
|
||||
|
@ -165,22 +167,22 @@ File: zutils.info, Node: The zutilsrc file, Next: Zcat, Prev: Common options,
|
|||
|
||||
'zutilsrc' is the runtime configuration file for zutils. In it you may
|
||||
define the compressor name and options to be used for each format. The
|
||||
'zutilsrc' file is optional; you don't need to install it in order to
|
||||
run zutils.
|
||||
'zutilsrc' file is optional; you don't need to install it in order to run
|
||||
zutils.
|
||||
|
||||
The compressors specified in the command line override those
|
||||
specified in the 'zutilsrc' file.
|
||||
The compressors specified in the command line override those specified
|
||||
in the 'zutilsrc' file.
|
||||
|
||||
You may copy the system 'zutilsrc' file '${sysconfdir}/zutilsrc' to
|
||||
'$HOME/.zutilsrc' and customize these options as you like. The file
|
||||
syntax is fairly obvious (and there are further instructions in it):
|
||||
'$HOME/.zutilsrc' and customize these options as you like. The file syntax
|
||||
is fairly obvious (and there are further instructions in it):
|
||||
|
||||
1. Any line beginning with '#' is a comment line.
|
||||
|
||||
2. Each non-comment line defines the command to be used for the given
|
||||
format, with the syntax:
|
||||
2. Each non-comment line defines the command to be used for the
|
||||
corresponding format, with the syntax:
|
||||
<format> = <compressor> [options]
|
||||
where <format> is one of 'bz2', 'gz', 'lz' or 'xz'.
|
||||
where <format> is one of 'bz2', 'gz', 'lz', or 'xz'.
|
||||
|
||||
|
||||
File: zutils.info, Node: Zcat, Next: Zcmp, Prev: The zutilsrc file, Up: Top
|
||||
|
@ -188,26 +190,26 @@ File: zutils.info, Node: Zcat, Next: Zcmp, Prev: The zutilsrc file, Up: Top
|
|||
4 Zcat
|
||||
******
|
||||
|
||||
zcat copies each given file to standard output. If any given file is
|
||||
compressed, its decompressed content is used. If a given file does not
|
||||
exist, and its name does not end with one of the known extensions, zcat
|
||||
tries the compressed file names corresponding to the formats supported.
|
||||
If a file fails to decompress, zcat continues copying the rest of the
|
||||
files.
|
||||
zcat copies each FILE argument to standard output in sequence. If any file
|
||||
given is compressed, its decompressed content is copied. If a file given
|
||||
does not exist, and its name does not end with one of the known extensions,
|
||||
zcat tries the compressed file names corresponding to the formats
|
||||
supported. If a file fails to decompress, zcat continues copying the rest
|
||||
of the files.
|
||||
|
||||
If a file is specified as '-', data are read from standard input,
|
||||
decompressed if needed, and sent to standard output. Data read from
|
||||
standard input must be of the same type; all uncompressed or all in the
|
||||
same compression format.
|
||||
same compressed format.
|
||||
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
If no files are specified, recursive searches examine the current working
|
||||
directory, and nonrecursive searches read standard input.
|
||||
|
||||
The format for running zcat is:
|
||||
|
||||
zcat [OPTIONS] [FILES]
|
||||
|
||||
Exit status is 0 if no errors occurred, non-zero otherwise.
|
||||
Exit status is 0 if no errors occurred, 1 otherwise.
|
||||
|
||||
zcat supports the following options:
|
||||
|
||||
|
@ -217,8 +219,8 @@ Exit status is 0 if no errors occurred, non-zero otherwise.
|
|||
|
||||
'-b'
|
||||
'--number-nonblank'
|
||||
Number all nonblank output lines, starting with 1. The line count
|
||||
is unlimited.
|
||||
Number all nonblank output lines, starting with 1. The line count is
|
||||
unlimited.
|
||||
|
||||
'-e'
|
||||
Equivalent to '-vE'.
|
||||
|
@ -229,16 +231,14 @@ Exit status is 0 if no errors occurred, non-zero otherwise.
|
|||
|
||||
'-n'
|
||||
'--number'
|
||||
Number all output lines, starting with 1. The line count is
|
||||
unlimited.
|
||||
Number all output lines, starting with 1. The line count is unlimited.
|
||||
|
||||
'-O FORMAT'
|
||||
'--force-format=FORMAT'
|
||||
Force the given compression format. Valid values for FORMAT are
|
||||
'bz2', 'gz', 'lz' and 'xz'. If this option is used, the files are
|
||||
passed to the corresponding decompressor without verifying their
|
||||
format, and the exact file name must be given. Other names won't
|
||||
be tried.
|
||||
Force the compressed format given. Valid values for FORMAT are 'bz2',
|
||||
'gz', 'lz', and 'xz'. If this option is used, the files are passed to
|
||||
the corresponding decompressor without verifying their format, and the
|
||||
exact file name must be given. Other names won't be tried.
|
||||
|
||||
'-q'
|
||||
'--quiet'
|
||||
|
@ -247,8 +247,8 @@ Exit status is 0 if no errors occurred, non-zero otherwise.
|
|||
'-r'
|
||||
'--recursive'
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively. Follow symbolic links in the command line,
|
||||
but skip symlinks that are encountered recursively.
|
||||
directory, recursively. Follow symbolic links given in the command
|
||||
line, but skip symbolic links that are encountered recursively.
|
||||
|
||||
'-R'
|
||||
'--dereference-recursive'
|
||||
|
@ -282,28 +282,27 @@ File: zutils.info, Node: Zcmp, Next: Zdiff, Prev: Zcat, Up: Top
|
|||
5 Zcmp
|
||||
******
|
||||
|
||||
zcmp compares two files ('-' means standard input), and if they differ,
|
||||
tells the first byte and line number where they differ. Bytes and lines
|
||||
are numbered starting with 1. If any given file is compressed, its
|
||||
decompressed content is used. Compressed files are decompressed on the
|
||||
fly; no temporary files are created.
|
||||
zcmp compares two files and, if they differ, writes to standard output the
|
||||
first byte and line number where they differ. Bytes and lines are numbered
|
||||
starting with 1. A hyphen '-' used as a FILE argument means standard input.
|
||||
If any file given is compressed, its decompressed content is used.
|
||||
Compressed files are decompressed on the fly; no temporary files are
|
||||
created.
|
||||
|
||||
The format for running zcmp is:
|
||||
|
||||
zcmp [OPTIONS] FILE1 [FILE2]
|
||||
|
||||
This compares FILE1 to FILE2. If FILE2 is omitted zcmp tries the
|
||||
This compares FILE1 to FILE2. The standard input is used only if FILE1 or
|
||||
FILE2 refers to standard input. If FILE2 is omitted zcmp tries the
|
||||
following:
|
||||
|
||||
1. If FILE1 is compressed, compares its decompressed contents with
|
||||
the corresponding uncompressed file (the name of FILE1 with the
|
||||
extension removed).
|
||||
- If FILE1 is compressed, compares its decompressed contents with the
|
||||
corresponding uncompressed file (the name of FILE1 with the extension
|
||||
removed).
|
||||
|
||||
2. If FILE1 is uncompressed, compares it with the decompressed
|
||||
contents of FILE1.[lz|bz2|gz|xz] (the first one that is found).
|
||||
|
||||
3. If no suitable file is found, compares FILE1 with data read from
|
||||
standard input.
|
||||
- If FILE1 is uncompressed, compares it with the decompressed contents
|
||||
of FILE1.[lz|bz2|gz|xz] (the first one that is found).
|
||||
|
||||
An exit status of 0 means no differences were found, 1 means some
|
||||
differences were found, and 2 means trouble.
|
||||
|
@ -312,17 +311,16 @@ differences were found, and 2 means trouble.
|
|||
|
||||
'-b'
|
||||
'--print-bytes'
|
||||
Print the differing bytes. Print control bytes as a '^' followed by
|
||||
a letter, and precede bytes larger than 127 with 'M-' (which stands
|
||||
for "meta").
|
||||
Print the differing bytes. Print control bytes as a '^' followed by a
|
||||
letter, and precede bytes larger than 127 with 'M-' (which stands for
|
||||
"meta").
|
||||
|
||||
'-i SIZE'
|
||||
'--ignore-initial=SIZE'
|
||||
Ignore any differences in the first SIZE bytes of the input files.
|
||||
Treat files with fewer than SIZE bytes as if they were empty. If
|
||||
SIZE is in the form 'SIZE1:SIZE2', ignore the first SIZE1 bytes of
|
||||
the first input file and the first SIZE2 bytes of the second input
|
||||
file.
|
||||
Treat files with fewer than SIZE bytes as if they were empty. If SIZE
|
||||
is in the form 'SIZE1:SIZE2', ignore the first SIZE1 bytes of the
|
||||
first input file and the first SIZE2 bytes of the second input file.
|
||||
|
||||
'-l'
|
||||
'-v'
|
||||
|
@ -337,20 +335,20 @@ differences were found, and 2 means trouble.
|
|||
|
||||
'-O [FORMAT1][,FORMAT2]'
|
||||
'--force-format=[FORMAT1][,FORMAT2]'
|
||||
Force the given compression formats. Any of FORMAT1 or FORMAT2 may
|
||||
be omitted and the corresponding format will be automatically
|
||||
detected. Valid values for FORMAT are 'bz2', 'gz', 'lz' and 'xz'.
|
||||
If at least one format is specified with this option, the file is
|
||||
passed to the corresponding decompressor without verifying its
|
||||
format, and the exact file names of both FILE1 and FILE2 must be
|
||||
given. Other names won't be tried.
|
||||
Force the compressed formats given. Any of FORMAT1 or FORMAT2 may be
|
||||
omitted and the corresponding format will be automatically detected.
|
||||
Valid values for FORMAT are 'bz2', 'gz', 'lz', and 'xz'. If at least
|
||||
one format is specified with this option, the file is passed to the
|
||||
corresponding decompressor without verifying its format, and the exact
|
||||
file names of both FILE1 and FILE2 must be given. Other names won't be
|
||||
tried.
|
||||
|
||||
'-q'
|
||||
'-s'
|
||||
'--quiet'
|
||||
'--silent'
|
||||
Don't print anything; only return an exit status indicating
|
||||
whether the files differ.
|
||||
Don't print anything; only return an exit status indicating whether the
|
||||
files differ.
|
||||
|
||||
|
||||
|
||||
|
@ -359,34 +357,33 @@ File: zutils.info, Node: Zdiff, Next: Zgrep, Prev: Zcmp, Up: Top
|
|||
6 Zdiff
|
||||
*******
|
||||
|
||||
zdiff compares two files ('-' means standard input), and if they
|
||||
differ, shows the differences line by line. If any given file is
|
||||
compressed, its decompressed content is used. zdiff is a front end to
|
||||
the diff program and has the limitation that messages from diff refer to
|
||||
temporary file names instead of those specified.
|
||||
zdiff compares two files and, if they differ, writes to standard output the
|
||||
differences line by line. A hyphen '-' used as a FILE argument means
|
||||
standard input. If any file given is compressed, its decompressed content
|
||||
is used. zdiff is a front end to the program diff and has the limitation
|
||||
that messages from diff refer to temporary file names instead of those
|
||||
specified.
|
||||
|
||||
The format for running zdiff is:
|
||||
|
||||
zdiff [OPTIONS] FILE1 [FILE2]
|
||||
|
||||
This compares FILE1 to FILE2. If FILE2 is omitted zdiff tries the
|
||||
This compares FILE1 to FILE2. The standard input is used only if FILE1 or
|
||||
FILE2 refers to standard input. If FILE2 is omitted zdiff tries the
|
||||
following:
|
||||
|
||||
1. If FILE1 is compressed, compares its decompressed contents with
|
||||
the corresponding uncompressed file (the name of FILE1 with the
|
||||
extension removed).
|
||||
- If FILE1 is compressed, compares its decompressed contents with the
|
||||
corresponding uncompressed file (the name of FILE1 with the extension
|
||||
removed).
|
||||
|
||||
2. If FILE1 is uncompressed, compares it with the decompressed
|
||||
contents of FILE1.[lz|bz2|gz|xz] (the first one that is found).
|
||||
|
||||
3. If no suitable file is found, compares FILE1 with data read from
|
||||
standard input.
|
||||
- If FILE1 is uncompressed, compares it with the decompressed contents
|
||||
of FILE1.[lz|bz2|gz|xz] (the first one that is found).
|
||||
|
||||
An exit status of 0 means no differences were found, 1 means some
|
||||
differences were found, and 2 means trouble.
|
||||
|
||||
zdiff supports the following options (some options only work if the
|
||||
diff program used supports them):
|
||||
zdiff supports the following options (some options only work if the diff
|
||||
program used supports them):
|
||||
|
||||
'-a'
|
||||
'--text'
|
||||
|
@ -421,13 +418,13 @@ diff program used supports them):
|
|||
|
||||
'-O [FORMAT1][,FORMAT2]'
|
||||
'--force-format=[FORMAT1][,FORMAT2]'
|
||||
Force the given compression formats. Any of FORMAT1 or FORMAT2 may
|
||||
be omitted and the corresponding format will be automatically
|
||||
detected. Valid values for FORMAT are 'bz2', 'gz', 'lz' and 'xz'.
|
||||
If at least one format is specified with this option, the file is
|
||||
passed to the corresponding decompressor without verifying its
|
||||
format, and the exact file names of both FILE1 and FILE2 must be
|
||||
given. Other names won't be tried.
|
||||
Force the compressed formats given. Any of FORMAT1 or FORMAT2 may be
|
||||
omitted and the corresponding format will be automatically detected.
|
||||
Valid values for FORMAT are 'bz2', 'gz', 'lz', and 'xz'. If at least
|
||||
one format is specified with this option, the file is passed to the
|
||||
corresponding decompressor without verifying its format, and the exact
|
||||
file names of both FILE1 and FILE2 must be given. Other names won't be
|
||||
tried.
|
||||
|
||||
'-p'
|
||||
'--show-c-function'
|
||||
|
@ -467,31 +464,29 @@ File: zutils.info, Node: Zgrep, Next: Ztest, Prev: Zdiff, Up: Top
|
|||
7 Zgrep
|
||||
*******
|
||||
|
||||
zgrep is a front end to the grep program that allows transparent search
|
||||
on any combination of compressed and uncompressed files. If any given
|
||||
file is compressed, its decompressed content is used. If a given file
|
||||
does not exist, and its name does not end with one of the known
|
||||
extensions, zgrep tries the compressed file names corresponding to the
|
||||
formats supported. If a file fails to decompress, zgrep continues
|
||||
searching the rest of the files.
|
||||
zgrep is a front end to the program grep that allows transparent search on
|
||||
any combination of compressed and uncompressed files. If any file given is
|
||||
compressed, its decompressed content is used. If a file given does not
|
||||
exist, and its name does not end with one of the known extensions, zgrep
|
||||
tries the compressed file names corresponding to the formats supported. If
|
||||
a file fails to decompress, zgrep continues searching the rest of the files.
|
||||
|
||||
If a file is specified as '-', data are read from standard input,
|
||||
decompressed if needed, and fed to grep. Data read from standard input
|
||||
must be of the same type; all uncompressed or all in the same
|
||||
compression format.
|
||||
decompressed if needed, and fed to grep. Data read from standard input must
|
||||
be of the same type; all uncompressed or all in the same compressed format.
|
||||
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
If no files are specified, recursive searches examine the current working
|
||||
directory, and nonrecursive searches read standard input.
|
||||
|
||||
The format for running zgrep is:
|
||||
|
||||
zgrep [OPTIONS] PATTERN [FILES]
|
||||
|
||||
An exit status of 0 means at least one match was found, 1 means no
|
||||
matches were found, and 2 means trouble.
|
||||
An exit status of 0 means at least one match was found, 1 means no matches
|
||||
were found, and 2 means trouble.
|
||||
|
||||
zgrep supports the following options (some options only work if the
|
||||
grep program used supports them):
|
||||
zgrep supports the following options (some options only work if the grep
|
||||
program used supports them):
|
||||
|
||||
'-a'
|
||||
'--text'
|
||||
|
@ -518,7 +513,7 @@ grep program used supports them):
|
|||
Print N lines of output context.
|
||||
|
||||
'--color[=WHEN]'
|
||||
Show matched strings in color. WHEN is 'never', 'always' or 'auto'.
|
||||
Show matched strings in color. WHEN is 'never', 'always', or 'auto'.
|
||||
|
||||
'-e PATTERN'
|
||||
'--regexp=PATTERN'
|
||||
|
@ -531,9 +526,9 @@ grep program used supports them):
|
|||
'-f FILE'
|
||||
'--file=FILE'
|
||||
Obtain patterns from FILE, one per line.
|
||||
When searching in several files at once, command substitution can
|
||||
be used with '-e' to read FILE only once, for example if FILE is
|
||||
not a regular file: 'zgrep -e "$(cat FILE)" file1.lz file2.gz'
|
||||
When searching in several files at once, command substitution can be
|
||||
used with '-e' to read FILE only once, for example if FILE is not a
|
||||
regular file: 'zgrep -e "$(cat FILE)" file1.lz file2.gz'
|
||||
|
||||
'-F'
|
||||
'--fixed-strings'
|
||||
|
@ -541,8 +536,8 @@ grep program used supports them):
|
|||
|
||||
'-h'
|
||||
'--no-filename'
|
||||
Suppress the prefixing of file names on output when multiple files
|
||||
are searched.
|
||||
Suppress the prefixing of file names on output when multiple files are
|
||||
searched.
|
||||
|
||||
'-H'
|
||||
'--with-filename'
|
||||
|
@ -577,22 +572,21 @@ grep program used supports them):
|
|||
|
||||
'-O FORMAT'
|
||||
'--force-format=FORMAT'
|
||||
Force the given compression format. Valid values for FORMAT are
|
||||
'bz2', 'gz', 'lz' and 'xz'. If this option is used, the files are
|
||||
passed to the corresponding decompressor without verifying their
|
||||
format, and the exact file name must be given. Other names won't
|
||||
be tried.
|
||||
Force the compressed format given. Valid values for FORMAT are 'bz2',
|
||||
'gz', 'lz', and 'xz'. If this option is used, the files are passed to
|
||||
the corresponding decompressor without verifying their format, and the
|
||||
exact file name must be given. Other names won't be tried.
|
||||
|
||||
'-q'
|
||||
'--quiet'
|
||||
Suppress all messages. Exit immediately with zero status if any
|
||||
match is found, even if an error was detected.
|
||||
Suppress all messages. Exit immediately with zero status if any match
|
||||
is found, even if an error was detected.
|
||||
|
||||
'-r'
|
||||
'--recursive'
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively. Follow symbolic links in the command line,
|
||||
but skip symlinks that are encountered recursively.
|
||||
directory, recursively. Follow symbolic links given in the command
|
||||
line, but skip symbolic links that are encountered recursively.
|
||||
|
||||
'-R'
|
||||
'--dereference-recursive'
|
||||
|
@ -625,42 +619,43 @@ File: zutils.info, Node: Ztest, Next: Zupdate, Prev: Zgrep, Up: Top
|
|||
8 Ztest
|
||||
*******
|
||||
|
||||
ztest verifies the integrity of the specified compressed files.
|
||||
ztest verifies the integrity of the compressed files specified.
|
||||
Uncompressed files are ignored. If a file is specified as '-', the
|
||||
integrity of compressed data read from standard input is verified. Data
|
||||
read from standard input must be all in the same compression format. If
|
||||
a file fails to decompress, ztest continues verifying the rest of the
|
||||
files.
|
||||
read from standard input must be all in the same compressed format. If a
|
||||
file fails to decompress, does not exist, can't be opened, or is a
|
||||
terminal, ztest continues verifying 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.
|
||||
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
If no files are specified, recursive searches examine the current working
|
||||
directory, and nonrecursive searches read standard input.
|
||||
|
||||
Note that error detection in the xz format is broken. First, some xz
|
||||
files lack integrity information. Second, not all xz decompressors can
|
||||
verify the integrity of all xz files. Third, section 2.1.1.2 'Stream
|
||||
Flags' of the xz format specification allows xz decompressors to
|
||||
produce garbage output without issuing any warning. Therefore, xz files
|
||||
can't always be verified as reliably as files in the other formats can.
|
||||
verify the integrity of all xz files. Third, section 2.1.1.2 'Stream Flags'
|
||||
of the xz format specification allows xz decompressors to produce garbage
|
||||
output without issuing any warning. Therefore, xz files can't always be
|
||||
verified as reliably as files in the other formats can.
|
||||
|
||||
The format for running ztest is:
|
||||
|
||||
ztest [OPTIONS] [FILES]
|
||||
|
||||
The exit status is 0 if all compressed files verify OK, 1 if
|
||||
environmental problems (file not found, invalid flags, I/O errors, etc),
|
||||
2 if any compressed file is corrupt or invalid.
|
||||
The exit status is 0 if all compressed files verify OK, 1 if environmental
|
||||
problems (file not found, invalid flags, I/O errors, etc), 2 if any
|
||||
compressed file is corrupt or invalid.
|
||||
|
||||
ztest supports the following options:
|
||||
|
||||
'-O FORMAT'
|
||||
'--force-format=FORMAT'
|
||||
Force the given compression format. Valid values for FORMAT are
|
||||
'bz2', 'gz', 'lz' and 'xz'. If this option is used, the files are
|
||||
passed to the corresponding decompressor without verifying their
|
||||
format, and any files in a format that the decompressor can't
|
||||
understand will fail. For example, '--force-format=gz' can test
|
||||
gzipped (.gz) and compress'd (.Z) files if the compressor used is
|
||||
GNU gzip.
|
||||
Force the compressed format given. Valid values for FORMAT are 'bz2',
|
||||
'gz', 'lz', and 'xz'. If this option is used, the files are passed to
|
||||
the corresponding decompressor without verifying their format, and any
|
||||
files in a format that the decompressor can't understand will fail.
|
||||
For example, '--force-format=gz' can test gzipped (.gz) and compress'd
|
||||
(.Z) files if the compressor used is GNU gzip.
|
||||
|
||||
'-q'
|
||||
'--quiet'
|
||||
|
@ -669,8 +664,8 @@ environmental problems (file not found, invalid flags, I/O errors, etc),
|
|||
'-r'
|
||||
'--recursive'
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively. Follow symbolic links in the command line,
|
||||
but skip symlinks that are encountered recursively.
|
||||
directory, recursively. Follow symbolic links given in the command
|
||||
line, but skip symbolic links that are encountered recursively.
|
||||
|
||||
'-R'
|
||||
'--dereference-recursive'
|
||||
|
@ -689,68 +684,69 @@ File: zutils.info, Node: Zupdate, Next: Problems, Prev: Ztest, Up: Top
|
|||
9 Zupdate
|
||||
*********
|
||||
|
||||
zupdate recompresses files from bzip2, gzip, and xz formats to lzip
|
||||
format. Each original is compared with the new file and then deleted.
|
||||
Only regular files with standard file name extensions are recompressed,
|
||||
other files are ignored. Compressed files are decompressed and then
|
||||
recompressed on the fly; no temporary files are created. If an error
|
||||
happens while recompressing a file, zupdate exits immediately without
|
||||
recompressing the rest of the files. The lzip format is chosen as
|
||||
destination because it is the most appropriate for long-term data
|
||||
archiving.
|
||||
zupdate recompresses files from bzip2, gzip, and xz formats to lzip format.
|
||||
Each original is compared with the new file and then deleted. Only regular
|
||||
files with standard file name extensions are recompressed, other files are
|
||||
ignored. Compressed files are decompressed and then recompressed on the fly;
|
||||
no temporary files are created. If an error happens while recompressing a
|
||||
file, zupdate exits immediately without recompressing the rest of the files.
|
||||
The lzip format is chosen as destination because it is the most appropriate
|
||||
for long-term data archiving.
|
||||
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches do nothing.
|
||||
If no files are specified, recursive searches examine the current working
|
||||
directory, and nonrecursive searches do nothing.
|
||||
|
||||
If the lzip compressed version of a file already exists, the file is
|
||||
skipped unless the '--force' option is given. In this case, if the
|
||||
comparison with the existing lzip version fails, an error is returned
|
||||
and the original file is not deleted. The operation of zupdate is meant
|
||||
to be safe and not produce any data loss. Therefore, existing lzip
|
||||
compressed files are never overwritten nor deleted.
|
||||
skipped unless the option '--force' is given. In this case, if the
|
||||
comparison with the existing lzip version fails, an error is returned and
|
||||
the original file is not deleted. The operation of zupdate is meant to be
|
||||
safe and not cause any data loss. Therefore, existing lzip compressed files
|
||||
are never overwritten nor deleted.
|
||||
|
||||
Combining the '--force' and '--keep' options, as in
|
||||
'zupdate -f -k *.gz', verifies that there are no differences between
|
||||
each pair of files in a multiformat set of files.
|
||||
Combining the options '--force' and '--keep', as in
|
||||
'zupdate -f -k *.gz', verifies that there are no differences between each
|
||||
pair of files in a multiformat set of files.
|
||||
|
||||
The names of the original files must have one of the following
|
||||
extensions: '.bz2', '.tbz', '.tbz2', '.gz', '.tgz', '.xz', '.txz'. The
|
||||
files produced have the extensions '.lz' or '.tar.lz'.
|
||||
extensions:
|
||||
'.bz2', '.gz', and '.xz' are recompressed to '.lz'.
|
||||
'.tbz', '.tbz2', '.tgz', and '.txz' are recompressed to '.tlz'.
|
||||
Keeping the combined extensions ('.tgz' -> '.tlz') may be useful when
|
||||
recompressing Slackware packages, for example.
|
||||
|
||||
Recompressing a file is much like copying or moving it; therefore
|
||||
zupdate 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).
|
||||
Recompressing a file is much like copying or moving it; therefore zupdate
|
||||
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).
|
||||
|
||||
The format for running zupdate is:
|
||||
|
||||
zupdate [OPTIONS] [FILES]
|
||||
|
||||
Exit status is 0 if all the compressed files were successfully
|
||||
recompressed (if needed), compared and deleted (if requested). Non-zero
|
||||
otherwise.
|
||||
Exit status is 0 if all the compressed files were successfully recompressed
|
||||
(if needed), compared, and deleted (if requested). Non-zero otherwise.
|
||||
|
||||
zupdate supports the following options:
|
||||
|
||||
'-f'
|
||||
'--force'
|
||||
Don't skip a file for which a lzip compressed version already
|
||||
exists. '--force' compares the content of the input file with the
|
||||
content of the existing lzip file and deletes the input file if
|
||||
both contents are identical.
|
||||
Don't skip a file for which a lzip compressed version already exists.
|
||||
'--force' compares the content of the input file with the content of
|
||||
the existing lzip file and deletes the input file if both contents are
|
||||
identical.
|
||||
|
||||
'-k'
|
||||
'--keep'
|
||||
Keep (don't delete) the input file after comparing it with the
|
||||
lzip file.
|
||||
Keep (don't delete) the input file after comparing it with the lzip
|
||||
file.
|
||||
|
||||
'-l'
|
||||
'--lzip-verbose'
|
||||
Pass a '-v' option to the lzip compressor so that it shows the
|
||||
compression ratio for each file processed. Using lzip 1.15 and
|
||||
newer, a second '-l' shows the progress of compression. Use it
|
||||
together with '-v' to see the name of the file.
|
||||
Pass one option '-v' to the lzip compressor so that it shows the
|
||||
compression ratio for each file processed. Using lzip 1.15 or newer, a
|
||||
second '-l' shows the progress of compression. Use it together with
|
||||
'-v' to see the name of the file.
|
||||
|
||||
'-q'
|
||||
'--quiet'
|
||||
|
@ -759,8 +755,8 @@ otherwise.
|
|||
'-r'
|
||||
'--recursive'
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively. Follow symbolic links in the command line,
|
||||
but skip symlinks that are encountered recursively.
|
||||
directory, recursively. Follow symbolic links given in the command
|
||||
line, but skip symbolic links that are encountered recursively.
|
||||
|
||||
'-R'
|
||||
'--dereference-recursive'
|
||||
|
@ -769,12 +765,13 @@ otherwise.
|
|||
|
||||
'-v'
|
||||
'--verbose'
|
||||
Verbose mode. Show the files being processed. A second '-v' also
|
||||
shows the files being ignored.
|
||||
Verbose mode. Show the files being processed. A second '-v' also shows
|
||||
the files being ignored.
|
||||
|
||||
'-0 .. -9'
|
||||
Set the compression level of lzip. By default zupdate passes '-9'
|
||||
to lzip.
|
||||
Set the compression level of lzip. By default zupdate passes '-9' to
|
||||
lzip. Custom compression options can be passed to lzip with the option
|
||||
'--lz'. For example '--lz='lzip -9 -s64MiB''.
|
||||
|
||||
|
||||
|
||||
|
@ -783,14 +780,14 @@ File: zutils.info, Node: Problems, Next: Concept index, Prev: Zupdate, Up: T
|
|||
10 Reporting bugs
|
||||
*****************
|
||||
|
||||
There are probably bugs in zutils. There are certainly errors and
|
||||
omissions in this manual. If you report them, they will get fixed. If
|
||||
you don't, no one will ever know about them and they will remain unfixed
|
||||
for all eternity, if not longer.
|
||||
There are probably bugs in zutils. There are certainly errors and omissions
|
||||
in this manual. If you report them, they will get fixed. If you don't, no
|
||||
one will ever know about them and they will remain unfixed for all
|
||||
eternity, if not longer.
|
||||
|
||||
If you find a bug in zutils, please send electronic mail to
|
||||
<zutils-bug@nongnu.org>. Include the version number, which you can find
|
||||
by running 'zupdate --version'.
|
||||
<zutils-bug@nongnu.org>. Include the version number, which you can find by
|
||||
running 'zupdate --version'.
|
||||
|
||||
|
||||
File: zutils.info, Node: Concept index, Prev: Problems, Up: Top
|
||||
|
@ -817,18 +814,18 @@ Concept index
|
|||
|
||||
Tag Table:
|
||||
Node: Top222
|
||||
Node: Introduction1149
|
||||
Node: Introduction1148
|
||||
Node: Common options3773
|
||||
Ref: compressor-requirements5596
|
||||
Node: The zutilsrc file5968
|
||||
Node: Zcat6893
|
||||
Node: Zcmp9445
|
||||
Node: Zdiff11904
|
||||
Node: Zgrep14608
|
||||
Node: Ztest18603
|
||||
Node: Zupdate20938
|
||||
Node: Problems24364
|
||||
Node: Concept index24898
|
||||
Ref: compressor-requirements5844
|
||||
Node: The zutilsrc file6216
|
||||
Node: Zcat7149
|
||||
Node: Zcmp9712
|
||||
Node: Zdiff12202
|
||||
Node: Zgrep14942
|
||||
Node: Ztest18944
|
||||
Node: Zupdate21451
|
||||
Node: Problems25123
|
||||
Node: Concept index25657
|
||||
|
||||
End Tag Table
|
||||
|
||||
|
|
330
doc/zutils.texi
330
doc/zutils.texi
|
@ -6,8 +6,8 @@
|
|||
@finalout
|
||||
@c %**end of header
|
||||
|
||||
@set UPDATED 1 January 2019
|
||||
@set VERSION 1.8
|
||||
@set UPDATED 27 June 2020
|
||||
@set VERSION 1.9
|
||||
|
||||
@dircategory Data Compression
|
||||
@direntry
|
||||
|
@ -49,53 +49,54 @@ This manual is for Zutils (version @value{VERSION}, @value{UPDATED}).
|
|||
@end menu
|
||||
|
||||
@sp 1
|
||||
Copyright @copyright{} 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright @copyright{} 2009-2020 Antonio Diaz Diaz.
|
||||
|
||||
This manual is free documentation: you have unlimited permission
|
||||
to copy, distribute and modify it.
|
||||
This manual is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
||||
|
||||
@node Introduction
|
||||
@chapter Introduction
|
||||
@cindex introduction
|
||||
|
||||
Zutils is a collection of utilities able to process any combination of
|
||||
compressed and uncompressed files transparently. If any given file,
|
||||
including standard input, is compressed, its decompressed content is
|
||||
used. Compressed files are decompressed on the fly; no temporary files
|
||||
are created.
|
||||
@uref{http://www.nongnu.org/zutils/zutils.html,,Zutils}
|
||||
is a collection of utilities able to process any combination of
|
||||
compressed and uncompressed files transparently. If any file given,
|
||||
including standard input, is compressed, its decompressed content is used.
|
||||
Compressed files are decompressed on the fly; no temporary files are
|
||||
created.
|
||||
|
||||
These utilities are not wrapper scripts but safer and more efficient C++
|
||||
programs. In particular the @samp{--recursive} option is very efficient
|
||||
in those utilities supporting it.
|
||||
programs. In particular the option @samp{--recursive} is very efficient in
|
||||
those utilities supporting it.
|
||||
|
||||
@noindent
|
||||
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest and zupdate.@*
|
||||
The formats supported are bzip2, gzip, lzip and xz.@*
|
||||
Zutils uses external compressors. The compressor to be used for each
|
||||
format is configurable at runtime.
|
||||
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest, and zupdate.@*
|
||||
The formats supported are bzip2, gzip, lzip, and xz.@*
|
||||
Zutils uses external compressors. The compressor to be used for each format
|
||||
is configurable at runtime.
|
||||
|
||||
zcat, zcmp, zdiff, and zgrep are improved replacements for the shell
|
||||
scripts provided by GNU gzip. ztest is unique to zutils. zupdate is
|
||||
similar to gzip's znew.
|
||||
zcat, zcmp, zdiff, and zgrep are improved replacements for the shell scripts
|
||||
provided by GNU gzip. ztest is unique to zutils. zupdate is similar to
|
||||
gzip's znew.
|
||||
|
||||
NOTE: Bzip2 and lzip provide well-defined values of exit status, which
|
||||
makes them safe to use with zutils. Gzip and xz may return ambiguous
|
||||
warning values, making them less reliable back ends for zutils.
|
||||
NOTE: Bzip2 and lzip provide well-defined values of exit status, which makes
|
||||
them safe to use with zutils. Gzip and xz may return ambiguous warning
|
||||
values, making them less reliable back ends for zutils.
|
||||
@xref{compressor-requirements}.
|
||||
|
||||
FORMAT NOTE 1: The @samp{--format} option allows the processing of a
|
||||
subset of formats in recursive mode and when trying compressed file
|
||||
names: @w{@samp{zgrep foo -r --format=bz2,lz somedir somefile.tar}}.
|
||||
FORMAT NOTE 1: The option @samp{--format} allows the processing of a subset
|
||||
of formats in recursive mode and when trying compressed file names:
|
||||
@w{@samp{zgrep foo -r --format=bz2,lz somedir somefile.tar}}.
|
||||
|
||||
FORMAT NOTE 2: If the @samp{--force-format} option is given, the files
|
||||
are passed to the corresponding decompressor without verifying their
|
||||
format, allowing for example the processing of compress'd (.Z) files
|
||||
with gzip: @w{@samp{zcmp --force-format=gz file.Z file.lz}}.
|
||||
FORMAT NOTE 2: If the option @samp{--force-format} is given, the files are
|
||||
passed to the corresponding decompressor without verifying their format,
|
||||
allowing for example the processing of compress'd (.Z) files with gzip:
|
||||
@w{@samp{zcmp --force-format=gz file.Z file.lz}}.
|
||||
|
||||
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never
|
||||
have been compressed. Decompressed is used to refer to data which have
|
||||
undergone the process of decompression.
|
||||
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never have
|
||||
been compressed. Decompressed is used to refer to data which have undergone
|
||||
the process of decompression.
|
||||
|
||||
@sp 1
|
||||
Numbers given as arguments to options (positions, sizes) may be followed
|
||||
|
@ -120,9 +121,13 @@ Table of SI and binary prefixes (unit multipliers):
|
|||
@chapter Common options
|
||||
@cindex common options
|
||||
|
||||
The following options are available in all the utilities. Rather than
|
||||
writing identical descriptions for each of the programs, they are
|
||||
described here.
|
||||
The following
|
||||
@uref{http://www.nongnu.org/arg-parser/manual/arg_parser_manual.html#Argument-syntax,,options}:
|
||||
are available in all the utilities. Rather than writing identical
|
||||
descriptions for each of the programs, they are described here.
|
||||
@ifnothtml
|
||||
@xref{Argument syntax,,,arg_parser}.
|
||||
@end ifnothtml
|
||||
|
||||
@table @code
|
||||
@item -h
|
||||
|
@ -139,7 +144,7 @@ This version number should be included in all bug reports.
|
|||
@itemx --format=@var{format_list}
|
||||
Process only the formats listed in the comma-separated
|
||||
@var{format_list}. Valid formats are @samp{bz2}, @samp{gz}, @samp{lz},
|
||||
@samp{xz} and @samp{un} for @samp{uncompressed}, meaning "any file name
|
||||
@samp{xz}, and @samp{un} for @samp{uncompressed}, meaning "any file name
|
||||
without a known extension". This option excludes files based on
|
||||
extension, instead of format, because it is more efficient. The
|
||||
exclusion only applies to names generated automatically (for example
|
||||
|
@ -165,19 +170,22 @@ Don't read the runtime configuration file @samp{zutilsrc}.
|
|||
@itemx --gz=@var{command}
|
||||
@itemx --lz=@var{command}
|
||||
@itemx --xz=@var{command}
|
||||
Set program (may include arguments) to be used as (de)compressor for the
|
||||
given format. The name of the program can't begin with @samp{-}. These
|
||||
options override the values set in @file{zutilsrc}. The compression
|
||||
program used must meet three requirements:
|
||||
Set program to be used as (de)compressor for the corresponding format.
|
||||
@var{command} may include arguments. For example
|
||||
@w{@samp{--lz='plzip --threads=2'}}. The program set with @samp{--lz} is
|
||||
used for both compression and decompression. The other three are used only
|
||||
for decompression. The name of the program can't begin with @samp{-}. These
|
||||
options override the values set in @file{zutilsrc}. The compression program
|
||||
used must meet three requirements:
|
||||
|
||||
@anchor{compressor-requirements}
|
||||
@enumerate
|
||||
@item
|
||||
When called with the @samp{-d} option, it must read compressed data from
|
||||
When called with the option @samp{-d}, it must read compressed data from
|
||||
the standard input and produce decompressed data on the standard output.
|
||||
@item
|
||||
If the @samp{-q} option is passed to zutils, the compression program
|
||||
must also accept it.
|
||||
If the option @samp{-q} is passed to zutils, the compression program must
|
||||
also accept it.
|
||||
@item
|
||||
It must return 0 if no errors occurred, and a non-zero value otherwise.
|
||||
@end enumerate
|
||||
|
@ -206,12 +214,12 @@ are further instructions in it):
|
|||
@item
|
||||
Any line beginning with @samp{#} is a comment line.
|
||||
@item
|
||||
Each non-comment line defines the command to be used for the given
|
||||
Each non-comment line defines the command to be used for the corresponding
|
||||
format, with the syntax:
|
||||
@example
|
||||
<format> = <compressor> [options]
|
||||
@end example
|
||||
where <format> is one of @samp{bz2}, @samp{gz}, @samp{lz} or @samp{xz}.
|
||||
where <format> is one of @samp{bz2}, @samp{gz}, @samp{lz}, or @samp{xz}.
|
||||
@end enumerate
|
||||
|
||||
|
||||
|
@ -219,20 +227,20 @@ where <format> is one of @samp{bz2}, @samp{gz}, @samp{lz} or @samp{xz}.
|
|||
@chapter Zcat
|
||||
@cindex zcat
|
||||
|
||||
zcat copies each given file to standard output. If any given file is
|
||||
compressed, its decompressed content is used. If a given file does not
|
||||
exist, and its name does not end with one of the known extensions, zcat
|
||||
tries the compressed file names corresponding to the formats supported.
|
||||
If a file fails to decompress, zcat continues copying the rest of the
|
||||
files.
|
||||
zcat copies each @var{file} argument to standard output in sequence. If any
|
||||
file given is compressed, its decompressed content is copied. If a file
|
||||
given does not exist, and its name does not end with one of the known
|
||||
extensions, zcat tries the compressed file names corresponding to the
|
||||
formats supported. If a file fails to decompress, zcat continues copying the
|
||||
rest of the files.
|
||||
|
||||
If a file is specified as @samp{-}, data are read from standard input,
|
||||
decompressed if needed, and sent to standard output. Data read from
|
||||
standard input must be of the same type; all uncompressed or all in the
|
||||
same compression format.
|
||||
same compressed format.
|
||||
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
If no files are specified, recursive searches examine the current working
|
||||
directory, and nonrecursive searches read standard input.
|
||||
|
||||
The format for running zcat is:
|
||||
|
||||
|
@ -241,7 +249,7 @@ zcat [@var{options}] [@var{files}]
|
|||
@end example
|
||||
|
||||
@noindent
|
||||
Exit status is 0 if no errors occurred, non-zero otherwise.
|
||||
Exit status is 0 if no errors occurred, 1 otherwise.
|
||||
|
||||
zcat supports the following options:
|
||||
|
||||
|
@ -268,8 +276,8 @@ Number all output lines, starting with 1. The line count is unlimited.
|
|||
|
||||
@item -O @var{format}
|
||||
@itemx --force-format=@var{format}
|
||||
Force the given compression format. Valid values for @var{format} are
|
||||
@samp{bz2}, @samp{gz}, @samp{lz} and @samp{xz}. If this option is used,
|
||||
Force the compressed format given. Valid values for @var{format} are
|
||||
@samp{bz2}, @samp{gz}, @samp{lz}, and @samp{xz}. If this option is used,
|
||||
the files are passed to the corresponding decompressor without verifying
|
||||
their format, and the exact file name must be given. Other names won't
|
||||
be tried.
|
||||
|
@ -280,14 +288,14 @@ Quiet operation. Suppress all messages.
|
|||
|
||||
@item -r
|
||||
@itemx --recursive
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively. Follow symbolic links in the command line, but
|
||||
skip symlinks that are encountered recursively.
|
||||
For each directory operand, read and process all files in that directory,
|
||||
recursively. Follow symbolic links given in the command line, but skip
|
||||
symbolic links that are encountered recursively.
|
||||
|
||||
@item -R
|
||||
@itemx --dereference-recursive
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively, following all symbolic links.
|
||||
For each directory operand, read and process all files in that directory,
|
||||
recursively, following all symbolic links.
|
||||
|
||||
@item -s
|
||||
@itemx --squeeze-blank
|
||||
|
@ -316,11 +324,12 @@ Verbose mode. Show error messages.
|
|||
@chapter Zcmp
|
||||
@cindex zcmp
|
||||
|
||||
zcmp compares two files (@samp{-} means standard input), and if they
|
||||
differ, tells the first byte and line number where they differ. Bytes
|
||||
and lines are numbered starting with 1. If any given file is compressed,
|
||||
its decompressed content is used. Compressed files are decompressed on
|
||||
the fly; no temporary files are created.
|
||||
zcmp compares two files and, if they differ, writes to standard output the
|
||||
first byte and line number where they differ. Bytes and lines are numbered
|
||||
starting with 1. A hyphen @samp{-} used as a @var{file} argument means
|
||||
standard input. If any file given is compressed, its decompressed content is
|
||||
used. Compressed files are decompressed on the fly; no temporary files are
|
||||
created.
|
||||
|
||||
The format for running zcmp is:
|
||||
|
||||
|
@ -329,10 +338,11 @@ zcmp [@var{options}] @var{file1} [@var{file2}]
|
|||
@end example
|
||||
|
||||
@noindent
|
||||
This compares @var{file1} to @var{file2}. If @var{file2} is omitted zcmp
|
||||
tries the following:
|
||||
This compares @var{file1} to @var{file2}. The standard input is used only if
|
||||
@var{file1} or @var{file2} refers to standard input. If @var{file2} is
|
||||
omitted zcmp tries the following:
|
||||
|
||||
@enumerate
|
||||
@itemize -
|
||||
@item
|
||||
If @var{file1} is compressed, compares its decompressed contents with
|
||||
the corresponding uncompressed file (the name of @var{file1} with the
|
||||
|
@ -340,10 +350,7 @@ extension removed).
|
|||
@item
|
||||
If @var{file1} is uncompressed, compares it with the decompressed
|
||||
contents of @var{file1}.[lz|bz2|gz|xz] (the first one that is found).
|
||||
@item
|
||||
If no suitable file is found, compares @var{file1} with data read from
|
||||
standard input.
|
||||
@end enumerate
|
||||
@end itemize
|
||||
|
||||
@noindent
|
||||
An exit status of 0 means no differences were found, 1 means some
|
||||
|
@ -379,10 +386,10 @@ Compare at most @var{count} input bytes.
|
|||
|
||||
@item -O [@var{format1}][,@var{format2}]
|
||||
@itemx --force-format=[@var{format1}][,@var{format2}]
|
||||
Force the given compression formats. Any of @var{format1} or
|
||||
Force the compressed formats given. Any of @var{format1} or
|
||||
@var{format2} may be omitted and the corresponding format will be
|
||||
automatically detected. Valid values for @var{format} are @samp{bz2},
|
||||
@samp{gz}, @samp{lz} and @samp{xz}. If at least one format is specified
|
||||
@samp{gz}, @samp{lz}, and @samp{xz}. If at least one format is specified
|
||||
with this option, the file is passed to the corresponding decompressor
|
||||
without verifying its format, and the exact file names of both
|
||||
@var{file1} and @var{file2} must be given. Other names won't be tried.
|
||||
|
@ -401,11 +408,12 @@ files differ.
|
|||
@chapter Zdiff
|
||||
@cindex zdiff
|
||||
|
||||
zdiff compares two files (@samp{-} means standard input), and if they
|
||||
differ, shows the differences line by line. If any given file is
|
||||
compressed, its decompressed content is used. zdiff is a front end to
|
||||
the diff program and has the limitation that messages from diff refer to
|
||||
temporary file names instead of those specified.
|
||||
zdiff compares two files and, if they differ, writes to standard output the
|
||||
differences line by line. A hyphen @samp{-} used as a @var{file} argument
|
||||
means standard input. If any file given is compressed, its decompressed
|
||||
content is used. zdiff is a front end to the program diff and has the
|
||||
limitation that messages from diff refer to temporary file names instead of
|
||||
those specified.
|
||||
|
||||
The format for running zdiff is:
|
||||
|
||||
|
@ -414,10 +422,11 @@ zdiff [@var{options}] @var{file1} [@var{file2}]
|
|||
@end example
|
||||
|
||||
@noindent
|
||||
This compares @var{file1} to @var{file2}. If @var{file2} is omitted
|
||||
zdiff tries the following:
|
||||
This compares @var{file1} to @var{file2}. The standard input is used only if
|
||||
@var{file1} or @var{file2} refers to standard input. If @var{file2} is
|
||||
omitted zdiff tries the following:
|
||||
|
||||
@enumerate
|
||||
@itemize -
|
||||
@item
|
||||
If @var{file1} is compressed, compares its decompressed contents with
|
||||
the corresponding uncompressed file (the name of @var{file1} with the
|
||||
|
@ -425,10 +434,7 @@ extension removed).
|
|||
@item
|
||||
If @var{file1} is uncompressed, compares it with the decompressed
|
||||
contents of @var{file1}.[lz|bz2|gz|xz] (the first one that is found).
|
||||
@item
|
||||
If no suitable file is found, compares @var{file1} with data read from
|
||||
standard input.
|
||||
@end enumerate
|
||||
@end itemize
|
||||
|
||||
@noindent
|
||||
An exit status of 0 means no differences were found, 1 means some
|
||||
|
@ -471,10 +477,10 @@ Ignore case differences in file contents.
|
|||
|
||||
@item -O [@var{format1}][,@var{format2}]
|
||||
@itemx --force-format=[@var{format1}][,@var{format2}]
|
||||
Force the given compression formats. Any of @var{format1} or
|
||||
Force the compressed formats given. Any of @var{format1} or
|
||||
@var{format2} may be omitted and the corresponding format will be
|
||||
automatically detected. Valid values for @var{format} are @samp{bz2},
|
||||
@samp{gz}, @samp{lz} and @samp{xz}. If at least one format is specified
|
||||
@samp{gz}, @samp{lz}, and @samp{xz}. If at least one format is specified
|
||||
with this option, the file is passed to the corresponding decompressor
|
||||
without verifying its format, and the exact file names of both
|
||||
@var{file1} and @var{file2} must be given. Other names won't be tried.
|
||||
|
@ -517,9 +523,9 @@ Ignore all white space.
|
|||
@chapter Zgrep
|
||||
@cindex zgrep
|
||||
|
||||
zgrep is a front end to the grep program that allows transparent search
|
||||
on any combination of compressed and uncompressed files. If any given
|
||||
file is compressed, its decompressed content is used. If a given file
|
||||
zgrep is a front end to the program grep that allows transparent search
|
||||
on any combination of compressed and uncompressed files. If any file
|
||||
given is compressed, its decompressed content is used. If a file given
|
||||
does not exist, and its name does not end with one of the known
|
||||
extensions, zgrep tries the compressed file names corresponding to the
|
||||
formats supported. If a file fails to decompress, zgrep continues
|
||||
|
@ -528,10 +534,10 @@ searching the rest of the files.
|
|||
If a file is specified as @samp{-}, data are read from standard input,
|
||||
decompressed if needed, and fed to grep. Data read from standard input
|
||||
must be of the same type; all uncompressed or all in the same
|
||||
compression format.
|
||||
compressed format.
|
||||
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
If no files are specified, recursive searches examine the current working
|
||||
directory, and nonrecursive searches read standard input.
|
||||
|
||||
The format for running zgrep is:
|
||||
|
||||
|
@ -572,7 +578,7 @@ Only print a count of matching lines per file.
|
|||
Print @var{n} lines of output context.
|
||||
|
||||
@item --color[=@var{when}]
|
||||
Show matched strings in color. @var{when} is @samp{never}, @samp{always}
|
||||
Show matched strings in color. @var{when} is @samp{never}, @samp{always},
|
||||
or @samp{auto}.
|
||||
|
||||
@item -e @var{pattern}
|
||||
|
@ -587,9 +593,9 @@ Treat @var{pattern} as an extended regular expression.
|
|||
@itemx --file=@var{file}
|
||||
Obtain patterns from @var{file}, one per line.@*
|
||||
When searching in several files at once, command substitution can be
|
||||
used with @code{-e} to read @var{file} only once, for example if
|
||||
used with @samp{-e} to read @var{file} only once, for example if
|
||||
@var{file} is not a regular file:
|
||||
@w{@code{zgrep -e "$(cat @var{file})" file1.lz file2.gz}}
|
||||
@w{@samp{zgrep -e "$(cat @var{file})" file1.lz file2.gz}}
|
||||
|
||||
@item -F
|
||||
@itemx --fixed-strings
|
||||
|
@ -633,8 +639,8 @@ Show only the part of matching lines that actually matches @var{pattern}.
|
|||
|
||||
@item -O @var{format}
|
||||
@itemx --force-format=@var{format}
|
||||
Force the given compression format. Valid values for @var{format} are
|
||||
@samp{bz2}, @samp{gz}, @samp{lz} and @samp{xz}. If this option is used,
|
||||
Force the compressed format given. Valid values for @var{format} are
|
||||
@samp{bz2}, @samp{gz}, @samp{lz}, and @samp{xz}. If this option is used,
|
||||
the files are passed to the corresponding decompressor without verifying
|
||||
their format, and the exact file name must be given. Other names won't
|
||||
be tried.
|
||||
|
@ -646,14 +652,14 @@ found, even if an error was detected.
|
|||
|
||||
@item -r
|
||||
@itemx --recursive
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively. Follow symbolic links in the command line, but
|
||||
skip symlinks that are encountered recursively.
|
||||
For each directory operand, read and process all files in that directory,
|
||||
recursively. Follow symbolic links given in the command line, but skip
|
||||
symbolic links that are encountered recursively.
|
||||
|
||||
@item -R
|
||||
@itemx --dereference-recursive
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively, following all symbolic links.
|
||||
For each directory operand, read and process all files in that directory,
|
||||
recursively, following all symbolic links.
|
||||
|
||||
@item -s
|
||||
@itemx --no-messages
|
||||
|
@ -681,15 +687,17 @@ Match only whole lines.
|
|||
@chapter Ztest
|
||||
@cindex ztest
|
||||
|
||||
ztest verifies the integrity of the specified compressed files.
|
||||
ztest verifies the integrity of the compressed files specified.
|
||||
Uncompressed files are ignored. If a file is specified as @samp{-}, the
|
||||
integrity of compressed data read from standard input is verified. Data
|
||||
read from standard input must be all in the same compression format. If
|
||||
a file fails to decompress, ztest continues verifying the rest of the
|
||||
files.
|
||||
read from standard input must be all in the same compressed format. If
|
||||
a file fails to decompress, does not exist, can't be opened, or is a
|
||||
terminal, ztest continues verifying 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.
|
||||
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches read standard input.
|
||||
If no files are specified, recursive searches examine the current working
|
||||
directory, and nonrecursive searches read standard input.
|
||||
|
||||
Note that error detection in the xz format is broken. First, some xz
|
||||
files lack integrity information. Second, not all xz decompressors can
|
||||
|
@ -717,13 +725,12 @@ ztest supports the following options:
|
|||
@table @code
|
||||
@item -O @var{format}
|
||||
@itemx --force-format=@var{format}
|
||||
Force the given compression format. Valid values for @var{format} are
|
||||
@samp{bz2}, @samp{gz}, @samp{lz} and @samp{xz}. If this option is used,
|
||||
the files are passed to the corresponding decompressor without verifying
|
||||
their format, and any files in a format that the decompressor can't
|
||||
understand will fail. For example, @samp{--force-format=gz} can test
|
||||
gzipped (.gz) and compress'd (.Z) files if the compressor used is GNU
|
||||
gzip.
|
||||
Force the compressed format given. Valid values for @var{format} are
|
||||
@samp{bz2}, @samp{gz}, @samp{lz}, and @samp{xz}. If this option is used, the
|
||||
files are passed to the corresponding decompressor without verifying their
|
||||
format, and any files in a format that the decompressor can't understand
|
||||
will fail. For example, @samp{--force-format=gz} can test gzipped (.gz) and
|
||||
compress'd (.Z) files if the compressor used is GNU gzip.
|
||||
|
||||
@item -q
|
||||
@itemx --quiet
|
||||
|
@ -731,14 +738,14 @@ Quiet operation. Suppress all messages.
|
|||
|
||||
@item -r
|
||||
@itemx --recursive
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively. Follow symbolic links in the command line, but
|
||||
skip symlinks that are encountered recursively.
|
||||
For each directory operand, read and process all files in that directory,
|
||||
recursively. Follow symbolic links given in the command line, but skip
|
||||
symbolic links that are encountered recursively.
|
||||
|
||||
@item -R
|
||||
@itemx --dereference-recursive
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively, following all symbolic links.
|
||||
For each directory operand, read and process all files in that directory,
|
||||
recursively, following all symbolic links.
|
||||
|
||||
@item -v
|
||||
@itemx --verbose
|
||||
|
@ -752,40 +759,41 @@ Further -v's increase the verbosity level.
|
|||
@chapter Zupdate
|
||||
@cindex zupdate
|
||||
|
||||
zupdate recompresses files from bzip2, gzip, and xz formats to lzip
|
||||
format. Each original is compared with the new file and then deleted.
|
||||
Only regular files with standard file name extensions are recompressed,
|
||||
other files are ignored. Compressed files are decompressed and then
|
||||
recompressed on the fly; no temporary files are created. If an error
|
||||
happens while recompressing a file, zupdate exits immediately without
|
||||
recompressing the rest of the files. The lzip format is chosen as
|
||||
destination because it is the most appropriate for long-term data
|
||||
archiving.
|
||||
zupdate recompresses files from bzip2, gzip, and xz formats to lzip format.
|
||||
Each original is compared with the new file and then deleted. Only regular
|
||||
files with standard file name extensions are recompressed, other files are
|
||||
ignored. Compressed files are decompressed and then recompressed on the fly;
|
||||
no temporary files are created. If an error happens while recompressing a
|
||||
file, zupdate exits immediately without recompressing the rest of the files.
|
||||
The lzip format is chosen as destination because it is the most appropriate
|
||||
for long-term data archiving.
|
||||
|
||||
If no files are specified, recursive searches examine the current
|
||||
working directory, and nonrecursive searches do nothing.
|
||||
If no files are specified, recursive searches examine the current working
|
||||
directory, and nonrecursive searches do nothing.
|
||||
|
||||
If the lzip compressed version of a file already exists, the file is
|
||||
skipped unless the @samp{--force} option is given. In this case, if the
|
||||
skipped unless the option @samp{--force} is given. In this case, if the
|
||||
comparison with the existing lzip version fails, an error is returned
|
||||
and the original file is not deleted. The operation of zupdate is meant
|
||||
to be safe and not produce any data loss. Therefore, existing lzip
|
||||
to be safe and not cause any data loss. Therefore, existing lzip
|
||||
compressed files are never overwritten nor deleted.
|
||||
|
||||
Combining the @samp{--force} and @samp{--keep} options, as in
|
||||
@w{@code{zupdate -f -k *.gz}}, verifies that there are no differences
|
||||
Combining the options @samp{--force} and @samp{--keep}, as in
|
||||
@w{@samp{zupdate -f -k *.gz}}, verifies that there are no differences
|
||||
between each pair of files in a multiformat set of files.
|
||||
|
||||
The names of the original files must have one of the following
|
||||
extensions: @samp{.bz2}, @samp{.tbz}, @samp{.tbz2}, @samp{.gz},
|
||||
@samp{.tgz}, @samp{.xz}, @samp{.txz}. The files produced have the
|
||||
extensions @samp{.lz} or @samp{.tar.lz}.
|
||||
The names of the original files must have one of the following extensions:@*
|
||||
@samp{.bz2}, @samp{.gz}, and @samp{.xz} are recompressed to @samp{.lz}.@*
|
||||
@samp{.tbz}, @samp{.tbz2}, @samp{.tgz}, and @samp{.txz} are recompressed to
|
||||
@samp{.tlz}.@*
|
||||
Keeping the combined extensions (@samp{.tgz} --> @samp{.tlz}) may be useful
|
||||
when recompressing Slackware packages, for example.
|
||||
|
||||
Recompressing a file is much like copying or moving it; therefore
|
||||
zupdate preserves the access and modification dates, permissions, and,
|
||||
when possible, ownership of the file just as @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).
|
||||
Recompressing a file is much like copying or moving it; therefore zupdate
|
||||
preserves the access and modification dates, permissions, and, when
|
||||
possible, ownership of the file just as @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).
|
||||
|
||||
The format for running zupdate is:
|
||||
|
||||
|
@ -794,9 +802,8 @@ zupdate [@var{options}] [@var{files}]
|
|||
@end example
|
||||
|
||||
@noindent
|
||||
Exit status is 0 if all the compressed files were successfully
|
||||
recompressed (if needed), compared and deleted (if requested). Non-zero
|
||||
otherwise.
|
||||
Exit status is 0 if all the compressed files were successfully recompressed
|
||||
(if needed), compared, and deleted (if requested). Non-zero otherwise.
|
||||
|
||||
zupdate supports the following options:
|
||||
|
||||
|
@ -814,8 +821,8 @@ Keep (don't delete) the input file after comparing it with the lzip file.
|
|||
|
||||
@item -l
|
||||
@itemx --lzip-verbose
|
||||
Pass a @samp{-v} option to the lzip compressor so that it shows the
|
||||
compression ratio for each file processed. Using lzip 1.15 and newer, a
|
||||
Pass one option @samp{-v} to the lzip compressor so that it shows the
|
||||
compression ratio for each file processed. Using lzip 1.15 or newer, a
|
||||
second @samp{-l} shows the progress of compression. Use it together with
|
||||
@samp{-v} to see the name of the file.
|
||||
|
||||
|
@ -825,14 +832,14 @@ Quiet operation. Suppress all messages.
|
|||
|
||||
@item -r
|
||||
@itemx --recursive
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively. Follow symbolic links in the command line, but
|
||||
skip symlinks that are encountered recursively.
|
||||
For each directory operand, read and process all files in that directory,
|
||||
recursively. Follow symbolic links given in the command line, but skip
|
||||
symbolic links that are encountered recursively.
|
||||
|
||||
@item -R
|
||||
@itemx --dereference-recursive
|
||||
For each directory operand, read and process all files in that
|
||||
directory, recursively, following all symbolic links.
|
||||
For each directory operand, read and process all files in that directory,
|
||||
recursively, following all symbolic links.
|
||||
|
||||
@item -v
|
||||
@itemx --verbose
|
||||
|
@ -840,8 +847,9 @@ Verbose mode. Show the files being processed. A second @samp{-v} also
|
|||
shows the files being ignored.
|
||||
|
||||
@item -0 .. -9
|
||||
Set the compression level of lzip. By default zupdate passes @samp{-9}
|
||||
to lzip.
|
||||
Set the compression level of lzip. By default zupdate passes @samp{-9} to
|
||||
lzip. Custom compression options can be passed to lzip with the option
|
||||
@samp{--lz}. For example @w{@samp{--lz='lzip -9 -s64MiB'}}.
|
||||
|
||||
@end table
|
||||
|
||||
|
@ -858,7 +866,7 @@ for all eternity, if not longer.
|
|||
|
||||
If you find a bug in zutils, please send electronic mail to
|
||||
@email{zutils-bug@@nongnu.org}. Include the version number, which you can
|
||||
find by running @w{@code{zupdate --version}}.
|
||||
find by running @w{@samp{zupdate --version}}.
|
||||
|
||||
|
||||
@node Concept index
|
||||
|
|
18
rc.cc
18
rc.cc
|
@ -1,5 +1,5 @@
|
|||
/* Zutils - Utilities dealing with compressed files
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 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
|
||||
|
@ -37,12 +37,12 @@ int verbosity = 0;
|
|||
namespace {
|
||||
|
||||
const char * const config_file_name = "zutilsrc";
|
||||
const char * const program_year = "2019";
|
||||
const char * const program_year = "2020";
|
||||
|
||||
std::string compressor_names[num_formats] =
|
||||
{ "bzip2", "gzip", "lzip", "xz" }; // default compressor names
|
||||
|
||||
// args to compressors, maybe empty
|
||||
// args to compressors read from rc or from options --[bglx]z, maybe empty
|
||||
std::vector< std::string > compressor_args[num_formats];
|
||||
|
||||
// vector of enabled formats plus [num_formats] for uncompressed.
|
||||
|
@ -93,10 +93,10 @@ bool trailing_escape( const std::string & s )
|
|||
}
|
||||
|
||||
|
||||
// Read a line discarding comments, leading whitespace and blank lines.
|
||||
// Escaped newlines are discarded.
|
||||
// Returns the empty string if at EOF.
|
||||
//
|
||||
/* Read a line discarding comments, leading whitespace, and blank lines.
|
||||
Escaped newlines are discarded.
|
||||
Returns the empty string if at EOF.
|
||||
*/
|
||||
const std::string & my_fgets( FILE * const f, int & linenum )
|
||||
{
|
||||
static std::string s;
|
||||
|
@ -237,7 +237,7 @@ void parse_format_list( const std::string & arg )
|
|||
enabled_formats[format_index] = true;
|
||||
}
|
||||
if( error )
|
||||
{ show_error( "Bad argument for '--format' option." ); std::exit( 1 ); }
|
||||
{ show_error( "Bad argument for option '--format'." ); std::exit( 1 ); }
|
||||
}
|
||||
|
||||
|
||||
|
@ -246,7 +246,7 @@ int parse_format_type( const std::string & arg )
|
|||
for( int i = 0; i < num_formats; ++i )
|
||||
if( arg == format_names[i] )
|
||||
return i;
|
||||
show_error( "Bad argument for '--force-format' option." );
|
||||
show_error( "Bad argument for option '--force-format'." );
|
||||
std::exit( 1 );
|
||||
}
|
||||
|
||||
|
|
4
rc.h
4
rc.h
|
@ -1,5 +1,5 @@
|
|||
/* Zutils - Utilities dealing with compressed files
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 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
|
||||
|
@ -15,7 +15,7 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
enum { fmt_bz2, fmt_gz, fmt_lz, fmt_xz, num_formats };
|
||||
enum { fmt_bz2, fmt_gz, fmt_lz, fmt_xz, num_formats }; // format_index
|
||||
const char * const format_names[num_formats] = { "bz2", "gz", "lz", "xz" };
|
||||
const char * const simple_extensions[num_formats] =
|
||||
{ ".bz2", ".gz", ".lz", ".xz" };
|
||||
|
|
16
recursive.cc
16
recursive.cc
|
@ -1,5 +1,5 @@
|
|||
/* Zutils - Utilities dealing with compressed files
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 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
|
||||
|
@ -15,8 +15,8 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Returns true if full_name is a regular file with an enabled extension
|
||||
// or (a link to) a directory.
|
||||
/* Returns true if full_name is a regular file with an enabled extension
|
||||
or (a link to) a directory. */
|
||||
bool test_full_name( const std::string & full_name, const struct stat * stp,
|
||||
const bool follow )
|
||||
{
|
||||
|
@ -41,12 +41,14 @@ bool test_full_name( const std::string & full_name, const struct stat * stp,
|
|||
{ loop = true; break; }
|
||||
}
|
||||
if( loop ) // full_name already visited or above tree
|
||||
show_file_error( full_name.c_str(), "warning: Recursive directory loop" );
|
||||
show_file_error( full_name.c_str(), "warning: Recursive directory loop." );
|
||||
return !loop; // (link to) directory
|
||||
}
|
||||
|
||||
|
||||
// Returns in input_filename the next filename.
|
||||
/* Returns in input_filename the next filename, or "." for stdin.
|
||||
("." was chosen because it is not a valid filename).
|
||||
Sets 'error' to true if a directory fails to open. */
|
||||
bool next_filename( std::list< std::string > & filenames,
|
||||
std::string & input_filename, bool & error,
|
||||
const int recursive, const bool ignore_stdin = false,
|
||||
|
@ -56,10 +58,10 @@ bool next_filename( std::list< std::string > & filenames,
|
|||
{
|
||||
input_filename = filenames.front();
|
||||
filenames.pop_front();
|
||||
if( input_filename.empty() || input_filename == "-" )
|
||||
if( input_filename == "-" )
|
||||
{
|
||||
if( ignore_stdin ) continue;
|
||||
input_filename.clear(); return true;
|
||||
input_filename = "."; return true;
|
||||
}
|
||||
struct stat st;
|
||||
if( stat( input_filename.c_str(), &st ) == 0 && S_ISDIR( st.st_mode ) )
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#! /bin/sh
|
||||
# check script for Zutils - Utilities dealing with compressed files
|
||||
# Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2020 Antonio Diaz Diaz.
|
||||
#
|
||||
# This script is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
@ -74,6 +74,10 @@ for i in ${extensions}; do
|
|||
test_failed $LINENO $i
|
||||
done
|
||||
|
||||
printf "LZIP\001-.............................." | "${ZCAT}" -N > /dev/null 2>&1
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
printf "LZIPxxxxxx" | "${ZCAT}" -N > /dev/null || test_failed $LINENO
|
||||
printf "BZh9xxxxxx" | "${ZCAT}" -N > /dev/null || test_failed $LINENO
|
||||
"${ZCAT}" -N -v -s "${testdir}"/zcat_vs.dat > /dev/null || test_failed $LINENO
|
||||
"${ZCAT}" -N < in > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
|
@ -91,6 +95,8 @@ cmp in copy || test_failed $LINENO
|
|||
cmp in copy || test_failed $LINENO
|
||||
"${ZCAT}" -N lz_only > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
cat in.lz in in in in | "${ZCAT}" -N > copy || test_failed $LINENO # tdata
|
||||
cmp in copy || test_failed $LINENO
|
||||
"${ZCAT}" -N in in.gz in.bz2 in.lz -- -in- -in-.lz > copy || test_failed $LINENO
|
||||
cmp in6 copy || test_failed $LINENO
|
||||
"${ZCAT}" -Nq in in.gz in.bz2 in.lz "${bad0_lz}" -- -in- -in-.lz > copy
|
||||
|
@ -105,6 +111,8 @@ cmp in6 copy || test_failed $LINENO
|
|||
"${ZCAT}" -N -R . > /dev/null || test_failed $LINENO
|
||||
"${ZCAT}" -N -R > /dev/null || test_failed $LINENO
|
||||
|
||||
"${ZCAT}" -Nq "" < in.lz > /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${ZCAT}" -Nq --format=, in.lz
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${ZCAT}" -Nq --format=,lz in.lz
|
||||
|
@ -132,11 +140,11 @@ printf "\ntesting zcmp-%s..." "$2"
|
|||
for i in ${extensions}; do
|
||||
"${ZCMP}" -N in.$i || test_failed $LINENO $i
|
||||
"${ZCMP}" -N in in.$i || test_failed $LINENO $i
|
||||
"${ZCMP}" -N -i 1kB:1000 -n 500 in6 in.$i || test_failed $LINENO $i
|
||||
"${ZCMP}" -N in in.$i --force-format=,$i || test_failed $LINENO $i
|
||||
"${ZCMP}" -N in.$i in || test_failed $LINENO $i
|
||||
"${ZCMP}" -N -i 1KiB:1024 -n 50 in.$i in6 || test_failed $LINENO $i
|
||||
"${ZCMP}" -N in.$i in --force-format=$i || test_failed $LINENO $i
|
||||
"${ZCMP}" -N -i 1kB:1000 -n 500 in6 in.$i || test_failed $LINENO $i
|
||||
"${ZCMP}" -N -i 1KiB:1024 -n 50 in.$i in6 || test_failed $LINENO $i
|
||||
done
|
||||
|
||||
"${ZCMP}" -Nq in in6
|
||||
|
@ -153,9 +161,13 @@ done
|
|||
"${ZCMP}" -N -i 0:11 -n 100 in.tar pin.tar || test_failed $LINENO
|
||||
"${ZCMP}" -N -i 0:11 -n 1Ki in.tar pin.tar || test_failed $LINENO
|
||||
"${ZCMP}" -N -i 0:11 -n 10KiB in.tar pin.tar || test_failed $LINENO
|
||||
"${ZCMP}" -N - || test_failed $LINENO
|
||||
"${ZCMP}" -N - - || test_failed $LINENO
|
||||
"${ZCMP}" -Nq -
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZCMP}" -N in in || test_failed $LINENO
|
||||
"${ZCMP}" -N in || test_failed $LINENO
|
||||
"${ZCMP}" -N --format=gz,bz2 in || test_failed $LINENO
|
||||
"${ZCMP}" -N --format=gz in || test_failed $LINENO
|
||||
"${ZCMP}" -N in.lz in.gz || test_failed $LINENO
|
||||
"${ZCMP}" -N --lz='lzip -q' in.lz in.gz || test_failed $LINENO
|
||||
"${ZCMP}" -N in.gz -- -in-.lz || test_failed $LINENO
|
||||
|
@ -166,12 +178,16 @@ done
|
|||
"${ZCMP}" -N -- -in-.lz in || test_failed $LINENO
|
||||
"${ZCMP}" -N -- -in- in || test_failed $LINENO
|
||||
"${ZCMP}" -N in -- -in- || test_failed $LINENO
|
||||
"${ZCMP}" -N lz_only.lz < in || test_failed $LINENO
|
||||
"${ZCMP}" -N in.lz - < in || test_failed $LINENO
|
||||
"${ZCMP}" -N - in.lz < in || test_failed $LINENO
|
||||
"${ZCMP}" -N in - < in.lz || test_failed $LINENO
|
||||
"${ZCMP}" -N - in < in.lz || test_failed $LINENO
|
||||
"${ZCMP}" -N -q --force-format=lz in.lz
|
||||
"${ZCMP}" -N lz_only.lz - < in || test_failed $LINENO
|
||||
"${ZCMP}" -Nq lz_only.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZCMP}" -Nq "" in
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZCMP}" -Nq --force-format=lz in.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZCMP}" -Nq --force-format=lz in.gz in.lz
|
||||
r=$?
|
||||
|
@ -184,7 +200,7 @@ r=$?
|
|||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZCMP}" -Nq -n -1 in in
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZCMP}" -Nq -n 100BB in in
|
||||
"${ZCMP}" -N -q -n 100BB in in
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZCMP}" -N --bad-option in in 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
|
@ -195,16 +211,20 @@ printf "\ntesting zdiff-%s..." "$2"
|
|||
for i in ${extensions}; do
|
||||
"${ZDIFF}" -N in.$i > /dev/null || test_failed $LINENO $i
|
||||
"${ZDIFF}" -N in in.$i > /dev/null || test_failed $LINENO $i
|
||||
"${ZDIFF}" -N --force-format=,$i in in.$i > /dev/null ||
|
||||
"${ZDIFF}" -N in in.$i --force-format=,$i > /dev/null ||
|
||||
test_failed $LINENO $i
|
||||
"${ZDIFF}" -N in.$i in > /dev/null || test_failed $LINENO $i
|
||||
"${ZDIFF}" -N --force-format=$i, in.$i in > /dev/null ||
|
||||
"${ZDIFF}" -N in.$i in --force-format=$i, > /dev/null ||
|
||||
test_failed $LINENO $i
|
||||
done
|
||||
|
||||
"${ZDIFF}" -N in in6 > /dev/null && test_failed $LINENO
|
||||
"${ZDIFF}" -N in in6 > /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
# GNU diff 3.0 returns 2 when binary files differ
|
||||
"${ZDIFF}" -N in.tar pin.tar > /dev/null && test_failed $LINENO
|
||||
"${ZDIFF}" -N - || test_failed $LINENO
|
||||
"${ZDIFF}" -N - - || test_failed $LINENO
|
||||
"${ZDIFF}" -N - 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N in in || test_failed $LINENO
|
||||
"${ZDIFF}" -N in || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=gz,bz2 in || test_failed $LINENO
|
||||
|
@ -219,14 +239,18 @@ done
|
|||
"${ZDIFF}" -N -- -in-.lz in > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N -- -in- in > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N in -- -in- > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N lz_only.lz < in > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N in.lz - < in > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N - in.lz < in > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N in - < in.lz > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N - in < in.lz > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N lz_only.lz - < in > /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N lz_only.lz 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N "" in 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N --bz2='-bzip2' in.bz2 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N -q --force-format=bz2 in.bz2 2> /dev/null
|
||||
"${ZDIFF}" -Nq --force-format=bz2 in.bz2 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N -q --force-format=,lz in.lz in.bz2 > /dev/null 2>&1
|
||||
r=$?
|
||||
|
@ -237,14 +261,14 @@ r=$?
|
|||
mkdir tmp2
|
||||
cat in > tmp2/a || framework_failure
|
||||
cat in.lz > tmp2/a.lz || framework_failure
|
||||
"${ZDIFF}" -N --format=bz2 tmp2/a < /dev/null > /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=gz tmp2/a < /dev/null > /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=lz tmp2/a.lz < /dev/null > /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=lz tmp2/a < /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=un tmp2/a.lz < /dev/null || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=bz2 tmp2/a 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=gz tmp2/a 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=lz tmp2/a.lz 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=lz tmp2/a || test_failed $LINENO
|
||||
"${ZDIFF}" -N --format=un tmp2/a.lz || test_failed $LINENO
|
||||
rm -r tmp2 || framework_failure
|
||||
|
||||
|
||||
|
@ -300,6 +324,8 @@ done
|
|||
|
||||
"${ZGREP}" -N "GNU" .
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${ZGREP}" -N "GNU" "" < in.lz 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZGREP}" -N --bad-option 2> /dev/null
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZGREP}" -N "GNU" -s nx_file
|
||||
|
@ -336,11 +362,13 @@ done
|
|||
"${ZTEST}" -Nq in.gz "${bad0_lz}" in.bz2 "${bad1_lz}" in.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
lines=`"${ZTEST}" -N in.gz "${bad0_lz}" in.bz2 "${bad1_lz}" in.lz 2>&1 | wc -l`
|
||||
[ "${lines}" -eq 2 ] || test_failed $LINENO
|
||||
[ "${lines}" -eq 2 ] || test_failed $LINENO "${lines}"
|
||||
lines=`"${ZTEST}" -Nv in.gz "${bad0_lz}" in.bz2 "${bad1_lz}" in.lz 2>&1 | wc -l`
|
||||
[ "${lines}" -eq 5 ] || test_failed $LINENO
|
||||
[ "${lines}" -eq 6 ] || test_failed $LINENO "${lines}"
|
||||
"${ZTEST}" -Nq < in
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZTEST}" -Nq "" < in.lz
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
dd if=in.lz bs=1000 count=1 2> /dev/null | "${ZTEST}" -N -q
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${ZTEST}" -Nq --force-format=lz in.bz2
|
||||
|
@ -353,6 +381,7 @@ dd if=in.lz bs=1000 count=1 2> /dev/null | "${ZTEST}" -N -q
|
|||
|
||||
printf "\ntesting zupdate-%s..." "$2"
|
||||
|
||||
"${ZUPDATE}" -N "" || test_failed $LINENO
|
||||
cat in.bz2 > a.bz2 || framework_failure
|
||||
cat in.gz > a.gz || framework_failure
|
||||
"${ZUPDATE}" -Nq --bz2=bad_command a.bz2
|
||||
|
@ -415,6 +444,24 @@ cat in.gz > a.gz || framework_failure
|
|||
[ -e a.lz ] || test_failed $LINENO
|
||||
rm -f a.lz || framework_failure
|
||||
|
||||
cat in.bz2 > a.tbz || framework_failure # keep combined extensions
|
||||
cat in.bz2 > b.tbz2 || framework_failure
|
||||
cat in.gz > c.tgz || framework_failure
|
||||
"${ZUPDATE}" -N a.tbz b.tbz2 c.tgz || test_failed $LINENO
|
||||
[ ! -e a.tbz ] || test_failed $LINENO
|
||||
[ ! -e b.tbz2 ] || test_failed $LINENO
|
||||
[ ! -e c.tgz ] || test_failed $LINENO
|
||||
[ ! -e a ] || test_failed $LINENO
|
||||
[ ! -e b ] || test_failed $LINENO
|
||||
[ ! -e c ] || test_failed $LINENO
|
||||
[ ! -e a.lz ] || test_failed $LINENO
|
||||
[ ! -e b.lz ] || test_failed $LINENO
|
||||
[ ! -e c.lz ] || test_failed $LINENO
|
||||
[ -e a.tlz ] || test_failed $LINENO
|
||||
[ -e b.tlz ] || test_failed $LINENO
|
||||
[ -e c.tlz ] || test_failed $LINENO
|
||||
rm -f a.tlz b.tlz c.tlz || framework_failure
|
||||
|
||||
cat in.bz2 > a.bz2 || framework_failure
|
||||
cat "${bad0_gz}" > b.gz || framework_failure
|
||||
cat in.gz > c.gz || framework_failure
|
||||
|
@ -434,6 +481,13 @@ cat in.bz2 > a.bz2 || framework_failure
|
|||
[ -e a.lz ] || test_failed $LINENO
|
||||
rm -f a.lz || framework_failure
|
||||
|
||||
cat in.gz > 'name with spaces.gz' || framework_failure
|
||||
"${ZUPDATE}" -N -1 -q 'name with spaces.gz' || test_failed $LINENO
|
||||
[ ! -e 'name with spaces.gz' ] || test_failed $LINENO
|
||||
[ -e 'name with spaces.lz' ] || test_failed $LINENO
|
||||
"${ZCMP}" -N in 'name with spaces.lz' || test_failed $LINENO
|
||||
rm -f 'name with spaces.lz' || framework_failure
|
||||
|
||||
mkdir tmp2
|
||||
mkdir tmp2/tmp3
|
||||
cat in.bz2 > tmp2/tmp3/a.bz2 || framework_failure
|
||||
|
|
74
zcat.cc
74
zcat.cc
|
@ -1,5 +1,5 @@
|
|||
/* Zcat - decompress and concatenate files to standard output
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010-2020 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
|
||||
|
@ -90,19 +90,21 @@ Line_number line_number;
|
|||
|
||||
void show_help()
|
||||
{
|
||||
std::printf( "Zcat copies each given file to standard output. If any given file is\n"
|
||||
"compressed, its decompressed content is used. If a given file does not\n"
|
||||
"exist, and its name does not end with one of the known extensions, zcat\n"
|
||||
"tries the compressed file names corresponding to the formats supported.\n"
|
||||
std::printf( "zcat copies each file argument to standard output in sequence. If any\n"
|
||||
"file given is compressed, its decompressed content is copied. If a file\n"
|
||||
"given does not exist, and its name does not end with one of the known\n"
|
||||
"extensions, zcat tries the compressed file names corresponding to the\n"
|
||||
"formats supported. If a file fails to decompress, zcat continues copying the\n"
|
||||
"rest of the files.\n"
|
||||
"\nIf a file is specified as '-', data are read from standard input,\n"
|
||||
"decompressed if needed, and sent to standard output. Data read from\n"
|
||||
"standard input must be of the same type; all uncompressed or all in the\n"
|
||||
"same compression format.\n"
|
||||
"same compressed format.\n"
|
||||
"\nIf no files are specified, recursive searches examine the current\n"
|
||||
"working directory, and nonrecursive searches read standard input.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip and xz.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip, and xz.\n"
|
||||
"\nUsage: zcat [options] [files]\n"
|
||||
"\nExit status is 0 if no errors occurred, non-zero otherwise.\n"
|
||||
"\nExit status is 0 if no errors occurred, 1 otherwise.\n"
|
||||
"\nOptions:\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n"
|
||||
|
@ -113,7 +115,7 @@ void show_help()
|
|||
" -M, --format=<list> process only the formats in <list>\n"
|
||||
" -n, --number number all output lines\n"
|
||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||
" -O, --force-format=<fmt> force given format (bz2, gz, lz, xz)\n"
|
||||
" -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz)\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
" -r, --recursive operate recursively on directories\n"
|
||||
" -R, --dereference-recursive recursively follow symbolic links\n"
|
||||
|
@ -130,7 +132,7 @@ void show_help()
|
|||
}
|
||||
|
||||
|
||||
int do_cat( const int infd, const int buffer_size,
|
||||
bool do_cat( const int infd, const int buffer_size,
|
||||
uint8_t * const inbuf, uint8_t * const outbuf,
|
||||
const std::string & input_filename,
|
||||
const Cat_options & cat_options )
|
||||
|
@ -148,7 +150,7 @@ int do_cat( const int infd, const int buffer_size,
|
|||
if( outpos >= buffer_size )
|
||||
{
|
||||
if( writeblock( STDOUT_FILENO, outbuf, outpos ) != outpos )
|
||||
{ show_error( "Write error", errno ); return 1; }
|
||||
{ show_error( "Write error", errno ); return false; }
|
||||
outpos = 0;
|
||||
}
|
||||
if( inpos > rd ) // inbuf is empty
|
||||
|
@ -157,14 +159,14 @@ int do_cat( const int infd, const int buffer_size,
|
|||
if( rd != buffer_size && errno )
|
||||
{
|
||||
show_file_error( input_filename.c_str(), "Read error", errno );
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
if( rd == 0 )
|
||||
{
|
||||
if( writeblock( STDOUT_FILENO, outbuf, outpos ) != outpos )
|
||||
{ show_error( "Write error", errno ); return 1; }
|
||||
{ show_error( "Write error", errno ); return false; }
|
||||
outpos = 0;
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
inpos = 0;
|
||||
inbuf[rd] = '\n'; // sentinel newline
|
||||
|
@ -226,32 +228,27 @@ int do_cat( const int infd, const int buffer_size,
|
|||
}
|
||||
|
||||
|
||||
int cat( int infd, const int format_index, const std::string & input_filename,
|
||||
bool cat( int infd, const int format_index, const std::string & input_filename,
|
||||
const Cat_options & cat_options )
|
||||
{
|
||||
enum { buffer_size = 4096, outbuf_size = (5 * buffer_size) + 256 + 1 };
|
||||
// buffer with space for sentinel newline at the end
|
||||
// input buffer with space for sentinel newline at the end
|
||||
uint8_t * const inbuf = new uint8_t[buffer_size+1];
|
||||
// buffer with space for character quoting, 255-digit line number,
|
||||
// output buffer with space for character quoting, 255-digit line number,
|
||||
// worst case flushing respect to inbuf, and a canary byte.
|
||||
uint8_t * const outbuf = new uint8_t[outbuf_size];
|
||||
outbuf[outbuf_size-1] = 0;
|
||||
int retval = 0;
|
||||
Children children;
|
||||
if( !set_data_feeder( input_filename, &infd, children, format_index ) )
|
||||
retval = 1;
|
||||
else
|
||||
retval = do_cat( infd, buffer_size, inbuf, outbuf,
|
||||
input_filename, cat_options );
|
||||
bool error = false;
|
||||
|
||||
if( !good_status( children, retval == 0 ) ) retval = 1;
|
||||
|
||||
if( retval == 0 && close( infd ) != 0 )
|
||||
{ show_close_error(); retval = 1; }
|
||||
if( outbuf[outbuf_size-1] != 0 )
|
||||
internal_error( "buffer overflow." );
|
||||
if( !set_data_feeder( input_filename, &infd, children, format_index ) ||
|
||||
!do_cat( infd, buffer_size, inbuf, outbuf, input_filename, cat_options ) )
|
||||
error = true;
|
||||
if( !good_status( children, !error ) ) error = true;
|
||||
if( !error && close( infd ) != 0 ) { show_close_error(); error = true; }
|
||||
if( outbuf[outbuf_size-1] != 0 ) internal_error( "buffer overflow." );
|
||||
delete[] outbuf; delete[] inbuf;
|
||||
return retval;
|
||||
return !error;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
@ -264,8 +261,8 @@ int main( const int argc, const char * const argv[] )
|
|||
int recursive = 0; // 1 = '-r', 2 = '-R'
|
||||
std::list< std::string > filenames;
|
||||
Cat_options cat_options;
|
||||
invocation_name = argv[0];
|
||||
program_name = "zcat";
|
||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
|
@ -357,16 +354,15 @@ int main( const int argc, const char * const argv[] )
|
|||
if( filenames.empty() ) filenames.push_back( recursive ? "." : "-" );
|
||||
|
||||
std::string input_filename;
|
||||
int retval = 0;
|
||||
bool error = false;
|
||||
bool stdin_used = false;
|
||||
while( next_filename( filenames, input_filename, error, recursive ) )
|
||||
{
|
||||
int infd;
|
||||
if( input_filename.empty() )
|
||||
if( input_filename == "." )
|
||||
{
|
||||
if( stdin_used ) continue; else stdin_used = true;
|
||||
infd = STDIN_FILENO;
|
||||
infd = STDIN_FILENO; input_filename = "-";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -374,10 +370,11 @@ int main( const int argc, const char * const argv[] )
|
|||
if( infd < 0 ) { error = true; continue; }
|
||||
}
|
||||
|
||||
const int tmp = cat( infd, format_index, input_filename, cat_options );
|
||||
if( tmp > retval ) retval = tmp;
|
||||
if( !cat( infd, format_index, input_filename, cat_options ) ) error = true;
|
||||
|
||||
if( input_filename.size() ) close( infd );
|
||||
if( close( infd ) != 0 )
|
||||
{ show_file_error( input_filename.c_str(), "Error closing input file",
|
||||
errno ); error = true; }
|
||||
}
|
||||
|
||||
if( std::fclose( stdout ) != 0 )
|
||||
|
@ -385,6 +382,5 @@ int main( const int argc, const char * const argv[] )
|
|||
show_error( "Error closing stdout", errno );
|
||||
error = true;
|
||||
}
|
||||
if( error && retval == 0 ) retval = 1;
|
||||
return retval;
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Common code for zcat and zgrep
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010-2020 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
zcmp.cc
48
zcmp.cc
|
@ -1,5 +1,5 @@
|
|||
/* Zcmp - decompress and compare two files byte by byte
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010-2020 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
|
||||
|
@ -50,22 +50,21 @@ namespace {
|
|||
|
||||
void show_help()
|
||||
{
|
||||
std::printf( "Zcmp compares two files ('-' means standard input), and if they differ,\n"
|
||||
"tells the first byte and line number where they differ. Bytes and lines\n"
|
||||
"are numbered starting with 1. If any given file is compressed, its\n"
|
||||
"decompressed content is used. Compressed files are decompressed on the\n"
|
||||
"fly; no temporary files are created.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip and xz.\n"
|
||||
std::printf( "zcmp compares two files and, if they differ, writes to standard output the\n"
|
||||
"first byte and line number where they differ. Bytes and lines are numbered\n"
|
||||
"starting with 1. A hyphen '-' used as a file argument means standard input.\n"
|
||||
"If any file given is compressed, its decompressed content is used. Compressed\n"
|
||||
"files are decompressed on the fly; no temporary files are created.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip, and xz.\n"
|
||||
"\nUsage: zcmp [options] file1 [file2]\n"
|
||||
"\nZcmp compares file1 to file2. If file2 is omitted zcmp tries the\n"
|
||||
"\nzcmp compares file1 to file2. The standard input is used only if file1 or\n"
|
||||
"file2 refers to standard input. If file2 is omitted zcmp tries the\n"
|
||||
"following:\n"
|
||||
"\n 1. If file1 is compressed, compares its decompressed contents with\n"
|
||||
"\n - If file1 is compressed, compares its decompressed contents with\n"
|
||||
" the corresponding uncompressed file (the name of file1 with the\n"
|
||||
" extension removed).\n"
|
||||
"\n 2. If file1 is uncompressed, compares it with the decompressed\n"
|
||||
"\n - If file1 is uncompressed, compares it with the decompressed\n"
|
||||
" contents of file1.[lz|bz2|gz|xz] (the first one that is found).\n"
|
||||
"\n 3. If no suitable file is found, compares file1 with data read from\n"
|
||||
" standard input.\n"
|
||||
"\nExit status is 0 if inputs are identical, 1 if different, 2 if trouble.\n"
|
||||
"\nOptions:\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
|
@ -76,7 +75,7 @@ void show_help()
|
|||
" -M, --format=<list> process only the formats in <list>\n"
|
||||
" -n, --bytes=<n> compare at most <n> bytes\n"
|
||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||
" -O, --force-format=[<f1>][,<f2>] force given formats (bz2, gz, lz, xz)\n"
|
||||
" -O, --force-format=[<f1>][,<f2>] force the formats given (bz2, gz, lz, xz)\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
" -s, --silent (same as --quiet)\n"
|
||||
" -v, --verbose verbose mode (same as --list)\n"
|
||||
|
@ -84,7 +83,7 @@ void show_help()
|
|||
" --gz=<command> set compressor and options for gzip format\n"
|
||||
" --lz=<command> set compressor and options for lzip format\n"
|
||||
" --xz=<command> set compressor and options for xz format\n"
|
||||
"Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n"
|
||||
"\nNumbers 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" );
|
||||
show_help_addr();
|
||||
}
|
||||
|
@ -326,8 +325,8 @@ int main( const int argc, const char * const argv[] )
|
|||
long long max_size = -1; // < 0 means unlimited size
|
||||
int format_types[2] = { -1, -1 };
|
||||
bool print_bytes = false;
|
||||
invocation_name = argv[0];
|
||||
program_name = "zcmp";
|
||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
|
@ -403,28 +402,33 @@ int main( const int argc, const char * const argv[] )
|
|||
STDIN_FILENO : open_instream( filenames[0] );
|
||||
if( infd[0] < 0 ) return 2;
|
||||
|
||||
if( ( files == 1 && filenames[0] == "-" ) ||
|
||||
( files == 2 && check_identical( filenames[0].c_str(),
|
||||
filenames[1].c_str() ) ) )
|
||||
if( files == 2 )
|
||||
{
|
||||
if( check_identical( filenames[0].c_str(), filenames[1].c_str() ) )
|
||||
{
|
||||
if( ignore_initial[0] == ignore_initial[1] ) return 0;
|
||||
else { show_error( "Can't compare parts of same file." ); return 2; }
|
||||
}
|
||||
|
||||
if( files == 2 )
|
||||
{
|
||||
infd[1] = ( filenames[1] == "-" ) ?
|
||||
STDIN_FILENO : open_instream( filenames[1] );
|
||||
if( infd[1] < 0 ) return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( filenames[0] == "-" )
|
||||
{ show_error( "Missing operand after '-'.", 0, true ); return 2; }
|
||||
if( format_types[0] >= 0 || format_types[1] >= 0 )
|
||||
{ show_error( "Two files must be given when format is specified.", 0, true );
|
||||
return 2; }
|
||||
filenames[1] = filenames[0];
|
||||
infd[1] = open_other_instream( filenames[1] );
|
||||
if( infd[1] < 0 ) { infd[1] = STDIN_FILENO; filenames[1] = "-"; }
|
||||
if( infd[1] < 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Can't find file to compare with '%s'.\n",
|
||||
program_name, filenames[0].c_str() );
|
||||
show_error( 0, 0, true ); return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int old_infd[2]; // copy of file descriptors of the two files
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Common code for zcmp and zdiff
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010-2020 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
|
||||
|
@ -38,10 +38,10 @@ int open_other_instream( std::string & name )
|
|||
name += extension_to( eindex );
|
||||
return open( name.c_str(), O_RDONLY | O_BINARY );
|
||||
}
|
||||
if( eindex < 0 )
|
||||
if( eindex < 0 ) // search compressed version
|
||||
for( int i = 0; i < num_formats; ++i )
|
||||
if( enabled_format( format_order[i] ) )
|
||||
{ // search compressed version
|
||||
{
|
||||
const std::string s( name + simple_extensions[format_order[i]] );
|
||||
const int infd = open( s.c_str(), O_RDONLY | O_BINARY );
|
||||
if( infd >= 0 ) { name = s; return infd; }
|
||||
|
@ -63,7 +63,7 @@ void parse_format_types2( const std::string & arg, int format_types[2] )
|
|||
|
||||
bool check_identical( const char * const name1, const char * const name2 )
|
||||
{
|
||||
if( !std::strcmp( name1, name2 ) ) return true;
|
||||
if( std::strcmp( name1, name2 ) == 0 ) return true;
|
||||
struct stat stat1, stat2;
|
||||
if( stat( name1, &stat1 ) || stat( name2, &stat2 ) ) return false;
|
||||
return ( stat1.st_ino == stat2.st_ino && stat1.st_dev == stat2.st_dev );
|
||||
|
|
61
zdiff.cc
61
zdiff.cc
|
@ -1,5 +1,5 @@
|
|||
/* Zdiff - decompress and compare two files line by line
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010-2020 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
|
||||
|
@ -39,6 +39,7 @@
|
|||
#include "rc.h"
|
||||
#include "zutils.h"
|
||||
|
||||
// 'verbosity' is always 0 in zdiff; no --verbose or --quiet available.
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -48,23 +49,23 @@ std::string fifonames[2]; // names of the two fifos passed to diff
|
|||
|
||||
void show_help()
|
||||
{
|
||||
std::printf( "Zdiff compares two files ('-' means standard input), and if they\n"
|
||||
"differ, shows the differences line by line. If any given file is\n"
|
||||
"compressed, its decompressed content is used. Zdiff is a front end to\n"
|
||||
"the diff program and has the limitation that messages from diff refer to\n"
|
||||
"temporary filenames instead of those specified.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip and xz.\n"
|
||||
std::printf( "zdiff compares two files and, if they differ, writes to standard output the\n"
|
||||
"differences line by line. A hyphen '-' used as a file argument means standard\n"
|
||||
"input. If any file given is compressed, its decompressed content is used.\n"
|
||||
"zdiff is a front end to the program diff and has the limitation that messages\n"
|
||||
"from diff refer to temporary file names instead of those specified.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip, and xz.\n"
|
||||
"\nUsage: zdiff [options] file1 [file2]\n"
|
||||
"\nZdiff compares file1 to file2. If file2 is omitted zdiff tries the\n"
|
||||
"\nzdiff compares file1 to file2. The standard input is used only if file1 or\n"
|
||||
"file2 refers to standard input. If file2 is omitted zdiff tries the\n"
|
||||
"following:\n"
|
||||
"\n 1. If file1 is compressed, compares its decompressed contents with\n"
|
||||
"\n - If file1 is compressed, compares its decompressed contents with\n"
|
||||
" the corresponding uncompressed file (the name of file1 with the\n"
|
||||
" extension removed).\n"
|
||||
"\n 2. If file1 is uncompressed, compares it with the decompressed\n"
|
||||
"\n - If file1 is uncompressed, compares it with the decompressed\n"
|
||||
" contents of file1.[lz|bz2|gz|xz] (the first one that is found).\n"
|
||||
"\n 3. If no suitable file is found, compares file1 with data read from\n"
|
||||
" standard input.\n"
|
||||
"\nExit status is 0 if inputs are identical, 1 if different, 2 if trouble.\n"
|
||||
"Some options only work if the diff program used supports them.\n"
|
||||
"\nOptions:\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n"
|
||||
|
@ -78,7 +79,7 @@ void show_help()
|
|||
" -i, --ignore-case ignore case differences in file contents\n"
|
||||
" -M, --format=<list> process only the formats in <list>\n"
|
||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||
" -O, --force-format=[<f1>][,<f2>] force given formats (bz2, gz, lz, xz)\n"
|
||||
" -O, --force-format=[<f1>][,<f2>] force the formats given (bz2, gz, lz, xz)\n"
|
||||
" -p, --show-c-function show which C function each change is in\n"
|
||||
" -q, --brief output only whether files differ\n"
|
||||
" -s, --report-identical-files report when two files are identical\n"
|
||||
|
@ -87,6 +88,8 @@ void show_help()
|
|||
" -u use the unified output format\n"
|
||||
" -U, --unified=<n> same as -u but use <n> lines of context\n"
|
||||
" -w, --ignore-all-space ignore all white space\n"
|
||||
" -W, --width=<n> output at most <n> print columns\n"
|
||||
" -y, --side-by-side output in two columns\n"
|
||||
" --bz2=<command> set compressor and options for bzip2 format\n"
|
||||
" --gz=<command> set compressor and options for gzip format\n"
|
||||
" --lz=<command> set compressor and options for lzip format\n"
|
||||
|
@ -112,8 +115,8 @@ extern "C" void remove_fifos()
|
|||
}
|
||||
|
||||
|
||||
// Set fifonames[i] to "${TMPDIR}/<coded_pid>[_-]<basename(filenames[i])>"
|
||||
// and create FIFOs.
|
||||
/* Set fifonames[i] to "${TMPDIR}/<coded_pid>[_-]<basename(filenames[i])>"
|
||||
and create FIFOs. */
|
||||
bool set_fifonames( const std::string filenames[2] )
|
||||
{
|
||||
enum { num_codes = 36 };
|
||||
|
@ -152,10 +155,10 @@ bool set_data_feeder( const std::string & filename,
|
|||
const std::string & fifoname, const int infd,
|
||||
Children & children, int format_index )
|
||||
{
|
||||
const uint8_t * magic_data = 0;
|
||||
uint8_t magic_data[magic_buf_size];
|
||||
int magic_size = 0;
|
||||
if( format_index < 0 )
|
||||
format_index = test_format( infd, &magic_data, &magic_size );
|
||||
format_index = test_format( infd, magic_data, &magic_size );
|
||||
children.compressor_name = get_compressor_name( format_index );
|
||||
|
||||
if( children.compressor_name ) // compressed
|
||||
|
@ -264,8 +267,8 @@ int main( const int argc, const char * const argv[] )
|
|||
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt };
|
||||
std::vector< const char * > diff_args; // args to diff, maybe empty
|
||||
int format_types[2] = { -1, -1 };
|
||||
invocation_name = argv[0];
|
||||
program_name = "zdiff";
|
||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
|
@ -290,6 +293,8 @@ int main( const int argc, const char * const argv[] )
|
|||
{ 'U', "unified", Arg_parser::yes },
|
||||
{ 'V', "version", Arg_parser::no },
|
||||
{ 'w', "ignore-all-space", Arg_parser::no },
|
||||
{ 'W', "width", Arg_parser::yes },
|
||||
{ 'y', "side-by-side", Arg_parser::no },
|
||||
{ bz2_opt, "bz2", Arg_parser::yes },
|
||||
{ gz_opt, "gz", Arg_parser::yes },
|
||||
{ lz_opt, "lz", Arg_parser::yes },
|
||||
|
@ -333,6 +338,9 @@ int main( const int argc, const char * const argv[] )
|
|||
diff_args.push_back( arg.c_str() ); break;
|
||||
case 'V': show_version(); return 0;
|
||||
case 'w': diff_args.push_back( "-w" ); break;
|
||||
case 'W': diff_args.push_back( "-W" );
|
||||
diff_args.push_back( arg.c_str() ); break;
|
||||
case 'y': diff_args.push_back( "-y" ); break;
|
||||
case bz2_opt: parse_compressor( arg, fmt_bz2 ); break;
|
||||
case gz_opt: parse_compressor( arg, fmt_gz ); break;
|
||||
case lz_opt: parse_compressor( arg, fmt_lz ); break;
|
||||
|
@ -361,25 +369,30 @@ int main( const int argc, const char * const argv[] )
|
|||
STDIN_FILENO : open_instream( filenames[0] );
|
||||
if( infd[0] < 0 ) return 2;
|
||||
|
||||
if( ( files == 1 && filenames[0] == "-" ) ||
|
||||
( files == 2 && check_identical( filenames[0].c_str(),
|
||||
filenames[1].c_str() ) ) )
|
||||
return 0;
|
||||
|
||||
if( files == 2 )
|
||||
{
|
||||
if( check_identical( filenames[0].c_str(), filenames[1].c_str() ) )
|
||||
return 0;
|
||||
infd[1] = ( filenames[1] == "-" ) ?
|
||||
STDIN_FILENO : open_instream( filenames[1] );
|
||||
if( infd[1] < 0 ) return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( filenames[0] == "-" )
|
||||
{ show_error( "Missing operand after '-'.", 0, true ); return 2; }
|
||||
if( format_types[0] >= 0 || format_types[1] >= 0 )
|
||||
{ show_error( "Two files must be given when format is specified.", 0, true );
|
||||
return 2; }
|
||||
filenames[1] = filenames[0];
|
||||
infd[1] = open_other_instream( filenames[1] );
|
||||
if( infd[1] < 0 ) { infd[1] = STDIN_FILENO; filenames[1] = "-"; }
|
||||
if( infd[1] < 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Can't find file to compare with '%s'.\n",
|
||||
program_name, filenames[0].c_str() );
|
||||
show_error( 0, 0, true ); return 2;
|
||||
}
|
||||
}
|
||||
|
||||
std::atexit( remove_fifos );
|
||||
|
|
32
zgrep.cc
32
zgrep.cc
|
@ -1,5 +1,5 @@
|
|||
/* Zgrep - search compressed files for a regular expression
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010-2020 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
|
||||
|
@ -47,21 +47,23 @@ namespace {
|
|||
|
||||
void show_help()
|
||||
{
|
||||
std::printf( "Zgrep is a front end to the grep program that allows transparent search\n"
|
||||
"on any combination of compressed and uncompressed files. If any given\n"
|
||||
"file is compressed, its decompressed content is used. If a given file\n"
|
||||
std::printf( "zgrep is a front end to the program grep that allows transparent search\n"
|
||||
"on any combination of compressed and uncompressed files. If any file\n"
|
||||
"given is compressed, its decompressed content is used. If a file given\n"
|
||||
"does not exist, and its name does not end with one of the known\n"
|
||||
"extensions, zgrep tries the compressed file names corresponding to the\n"
|
||||
"formats supported.\n"
|
||||
"formats supported. If a file fails to decompress, zgrep continues\n"
|
||||
"searching the rest of the files.\n"
|
||||
"\nIf a file is specified as '-', data are read from standard input,\n"
|
||||
"decompressed if needed, and fed to grep. Data read from standard input\n"
|
||||
"must be of the same type; all uncompressed or all in the same\n"
|
||||
"compression format.\n"
|
||||
"compressed format.\n"
|
||||
"\nIf no files are specified, recursive searches examine the current\n"
|
||||
"working directory, and nonrecursive searches read standard input.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip and xz.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip, and xz.\n"
|
||||
"\nUsage: zgrep [options] <pattern> [files]\n"
|
||||
"\nExit status is 0 if match, 1 if no match, 2 if trouble.\n"
|
||||
"Some options only work if the grep program used supports them.\n"
|
||||
"\nOptions:\n"
|
||||
" --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n"
|
||||
|
@ -87,7 +89,7 @@ void show_help()
|
|||
" -n, --line-number print the line number of each line\n"
|
||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||
" -o, --only-matching show only the part of a line matching <pattern>\n"
|
||||
" -O, --force-format=<fmt> force given format (bz2, gz, lz, xz)\n"
|
||||
" -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz)\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
" -r, --recursive operate recursively on directories\n"
|
||||
" -R, --dereference-recursive recursively follow symbolic links\n"
|
||||
|
@ -100,7 +102,7 @@ void show_help()
|
|||
" --gz=<command> set compressor and options for gzip format\n"
|
||||
" --lz=<command> set compressor and options for lzip format\n"
|
||||
" --xz=<command> set compressor and options for xz format\n"
|
||||
"Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n"
|
||||
"\nNumbers 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" );
|
||||
show_help_addr();
|
||||
}
|
||||
|
@ -217,15 +219,15 @@ int main( const int argc, const char * const argv[] )
|
|||
enum { help_opt = 256, verbose_opt, color_opt,
|
||||
bz2_opt, gz_opt, lz_opt, xz_opt };
|
||||
int format_index = -1;
|
||||
int list_mode = 0; // 1 = list matches, -1 = list non matches
|
||||
int list_mode = 0; // 1 = list matches, -1 = list non-matches
|
||||
int recursive = 0; // 1 = '-r', 2 = '-R'
|
||||
int show_name = -1; // tri-state bool
|
||||
bool no_messages = false;
|
||||
std::list< std::string > filenames;
|
||||
std::vector< const char * > grep_args; // args to grep, maybe empty
|
||||
std::string color_option; // needed because of optional arg
|
||||
invocation_name = argv[0];
|
||||
program_name = "zgrep";
|
||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
|
@ -365,10 +367,10 @@ int main( const int argc, const char * const argv[] )
|
|||
false, no_messages ) )
|
||||
{
|
||||
int infd;
|
||||
if( input_filename.empty() )
|
||||
if( input_filename == "." )
|
||||
{
|
||||
if( stdin_used ) continue; else stdin_used = true;
|
||||
infd = STDIN_FILENO;
|
||||
infd = STDIN_FILENO; input_filename = "-";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -383,7 +385,9 @@ int main( const int argc, const char * const argv[] )
|
|||
list_mode, show_name );
|
||||
if( tmp == 0 || ( tmp == 2 && retval == 1 ) ) retval = tmp;
|
||||
|
||||
if( input_filename.size() ) close( infd );
|
||||
if( close( infd ) != 0 )
|
||||
{ show_file_error( input_filename.c_str(), "Error closing input file",
|
||||
errno ); error = true; }
|
||||
if( retval == 0 && verbosity < 0 ) break;
|
||||
}
|
||||
|
||||
|
|
45
ztest.cc
45
ztest.cc
|
@ -1,5 +1,5 @@
|
|||
/* Ztest - verify the integrity of compressed files
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010-2020 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
|
||||
|
@ -50,13 +50,17 @@ namespace {
|
|||
|
||||
void show_help()
|
||||
{
|
||||
std::printf( "Ztest verifies the integrity of the specified compressed files.\n"
|
||||
std::printf( "ztest verifies the integrity of the compressed files specified.\n"
|
||||
"Uncompressed files are ignored. If a file is specified as '-', the\n"
|
||||
"integrity of compressed data read from standard input is verified. Data\n"
|
||||
"read from standard input must be all in the same compression format.\n"
|
||||
"read from standard input must be all in the same compressed format. If\n"
|
||||
"a file fails to decompress, does not exist, can't be opened, or is a\n"
|
||||
"terminal, ztest continues verifying the rest of the files. A final\n"
|
||||
"diagnostic is shown at verbosity level 1 or higher if any file fails the\n"
|
||||
"test when testing multiple files.\n"
|
||||
"\nIf no files are specified, recursive searches examine the current\n"
|
||||
"working directory, and nonrecursive searches read standard input.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip and xz.\n"
|
||||
"\nThe formats supported are bzip2, gzip, lzip, and xz.\n"
|
||||
"\nNote that error detection in the xz format is broken. First, some xz\n"
|
||||
"files lack integrity information. Second, not all xz decompressors can\n"
|
||||
"verify the integrity of all xz files. Third, section 2.1.1.2 'Stream\n"
|
||||
|
@ -72,7 +76,7 @@ void show_help()
|
|||
" -V, --version output version information and exit\n"
|
||||
" -M, --format=<list> process only the formats in <list>\n"
|
||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||
" -O, --force-format=<fmt> force given format (bz2, gz, lz, xz)\n"
|
||||
" -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz)\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
" -r, --recursive operate recursively on directories\n"
|
||||
" -R, --dereference-recursive recursively follow symbolic links\n"
|
||||
|
@ -97,10 +101,10 @@ int open_instream( const std::string & input_filename )
|
|||
int ztest_stdin( const int infd, int format_index,
|
||||
const std::vector< const char * > & ztest_args )
|
||||
{
|
||||
const uint8_t * magic_data = 0;
|
||||
uint8_t magic_data[magic_buf_size];
|
||||
int magic_size = 0;
|
||||
if( format_index < 0 )
|
||||
format_index = test_format( infd, &magic_data, &magic_size );
|
||||
format_index = test_format( infd, magic_data, &magic_size );
|
||||
const char * const compressor_name = get_compressor_name( format_index );
|
||||
if( !compressor_name )
|
||||
{ show_error( "Unknown data format read from stdin." ); return 2; }
|
||||
|
@ -161,10 +165,10 @@ int ztest_file( const int infd, int format_index,
|
|||
const std::vector< const char * > & ztest_args )
|
||||
{
|
||||
static int disable_xz = -1; // tri-state bool
|
||||
const uint8_t * magic_data = 0;
|
||||
uint8_t magic_data[magic_buf_size];
|
||||
int magic_size = 0;
|
||||
if( format_index < 0 )
|
||||
format_index = test_format( infd, &magic_data, &magic_size );
|
||||
format_index = test_format( infd, magic_data, &magic_size );
|
||||
const char * const compressor_name = get_compressor_name( format_index );
|
||||
if( !compressor_name )
|
||||
return 0; // ignore this file
|
||||
|
@ -217,8 +221,8 @@ int main( const int argc, const char * const argv[] )
|
|||
int recursive = 0; // 1 = '-r', 2 = '-R'
|
||||
std::list< std::string > filenames;
|
||||
std::vector< const char * > ztest_args; // args to ztest, maybe empty
|
||||
invocation_name = argv[0];
|
||||
program_name = "ztest";
|
||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
|
@ -280,16 +284,17 @@ int main( const int argc, const char * const argv[] )
|
|||
if( filenames.empty() ) filenames.push_back( recursive ? "." : "-" );
|
||||
|
||||
std::string input_filename;
|
||||
int files_tested = 0, failed_tests = 0;
|
||||
int retval = 0;
|
||||
bool error = false;
|
||||
bool stdin_used = false;
|
||||
while( next_filename( filenames, input_filename, error, recursive ) )
|
||||
{
|
||||
int infd;
|
||||
if( input_filename.empty() )
|
||||
if( input_filename == "." )
|
||||
{
|
||||
if( stdin_used ) continue; else stdin_used = true;
|
||||
infd = STDIN_FILENO;
|
||||
infd = STDIN_FILENO; input_filename = "-";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -297,13 +302,23 @@ int main( const int argc, const char * const argv[] )
|
|||
if( infd < 0 ) { error = true; continue; }
|
||||
}
|
||||
|
||||
if( isatty( infd ) ) // for example /dev/tty
|
||||
{
|
||||
show_file_error( input_filename == "-" ? "(stdin)" : input_filename.c_str(),
|
||||
"I won't read compressed data from a terminal." );
|
||||
close( infd ); error = true; continue;
|
||||
}
|
||||
|
||||
int tmp;
|
||||
if( infd == STDIN_FILENO )
|
||||
tmp = ztest_stdin( infd, format_index, ztest_args );
|
||||
else tmp = ztest_file( infd, format_index, input_filename, ztest_args );
|
||||
if( tmp > retval ) retval = tmp;
|
||||
++files_tested; if( tmp ) ++failed_tests;
|
||||
|
||||
if( input_filename.size() ) close( infd );
|
||||
if( close( infd ) != 0 )
|
||||
{ show_file_error( input_filename.c_str(), "Error closing input file",
|
||||
errno ); error = true; }
|
||||
}
|
||||
|
||||
if( std::fclose( stdout ) != 0 ) // in case decompressor writes to stdout
|
||||
|
@ -312,5 +327,9 @@ int main( const int argc, const char * const argv[] )
|
|||
error = true;
|
||||
}
|
||||
if( error && retval == 0 ) retval = 1;
|
||||
if( failed_tests > 0 && verbosity >= 1 && files_tested > 1 )
|
||||
std::fprintf( stderr, "%s: warning: %d %s failed the test.\n",
|
||||
program_name, failed_tests,
|
||||
( failed_tests == 1 ) ? "file" : "files" );
|
||||
return retval;
|
||||
}
|
||||
|
|
53
zupdate.cc
53
zupdate.cc
|
@ -1,5 +1,5 @@
|
|||
/* Zupdate - recompress bzip2, gzip, xz files to lzip format
|
||||
Copyright (C) 2013-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2013-2020 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
|
||||
|
@ -51,7 +51,7 @@ namespace {
|
|||
|
||||
void show_help()
|
||||
{
|
||||
std::printf( "Zupdate recompresses files from bzip2, gzip, and xz formats to lzip\n"
|
||||
std::printf( "zupdate recompresses files from bzip2, gzip, and xz formats to lzip\n"
|
||||
"format. Each original is compared with the new file and then deleted.\n"
|
||||
"Only regular files with standard file name extensions are recompressed,\n"
|
||||
"other files are ignored. Compressed files are decompressed and then\n"
|
||||
|
@ -61,21 +61,23 @@ void show_help()
|
|||
"\nIf no files are specified, recursive searches examine the current\n"
|
||||
"working directory, and nonrecursive searches do nothing.\n"
|
||||
"\nIf the lzip compressed version of a file already exists, the file is\n"
|
||||
"skipped unless the '--force' option is given. In this case, if the\n"
|
||||
"skipped unless the option '--force' is given. In this case, if the\n"
|
||||
"comparison with the existing lzip version fails, an error is returned\n"
|
||||
"and the original file is not deleted. The operation of zupdate is meant\n"
|
||||
"to be safe and not produce any data loss. Therefore, existing lzip\n"
|
||||
"to be safe and not cause any data loss. Therefore, existing lzip\n"
|
||||
"compressed files are never overwritten nor deleted.\n"
|
||||
"\nThe names of the original files must have one of the following extensions:\n"
|
||||
"'.bz2', '.gz', and '.xz' are recompressed to '.lz'.\n"
|
||||
"'.tbz', '.tbz2', '.tgz', and '.txz' are recompressed to '.tlz'.\n"
|
||||
"\nUsage: zupdate [options] [files]\n"
|
||||
"\nExit status is 0 if all the compressed files were successfully\n"
|
||||
"recompressed (if needed), compared and deleted (if requested). Non-zero\n"
|
||||
"otherwise.\n"
|
||||
"\nExit status is 0 if all the compressed files were successfully recompressed\n"
|
||||
"(if needed), compared, and deleted (if requested). Non-zero otherwise.\n"
|
||||
"\nOptions:\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n"
|
||||
" -f, --force don't skip a file even if the .lz exists\n"
|
||||
" -k, --keep keep (don't delete) input files\n"
|
||||
" -l, --lzip-verbose pass a -v option to the lzip compressor\n"
|
||||
" -l, --lzip-verbose pass one option -v to the lzip compressor\n"
|
||||
" -M, --format=<list> process only the formats in <list>\n"
|
||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
|
@ -106,7 +108,7 @@ int cant_execute( const std::string & command, const int status )
|
|||
}
|
||||
|
||||
|
||||
// Set permissions, owner and times.
|
||||
// Set permissions, owner, and times.
|
||||
void set_permissions( const char * const rname, const struct stat & in_stats )
|
||||
{
|
||||
bool warning = false;
|
||||
|
@ -135,7 +137,7 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
|||
{
|
||||
static int disable_xz = -1; // tri-state bool
|
||||
int format_index = -1;
|
||||
std::string dname; // decompressed_name
|
||||
std::string rname; // recompressed name
|
||||
|
||||
const int eindex = extension_index( name ); // search extension
|
||||
if( eindex >= 0 )
|
||||
|
@ -148,8 +150,9 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
|||
program_name, name.c_str(), extension_from( eindex ) );
|
||||
return 0; // ignore this file
|
||||
}
|
||||
dname.assign( name, 0, name.size() - std::strlen( extension_from( eindex ) ) );
|
||||
dname += extension_to( eindex );
|
||||
rname.assign( name, 0, name.size() - std::strlen( extension_from( eindex ) ) );
|
||||
rname += ( std::strcmp( extension_to( eindex ), ".tar" ) == 0 ) ?
|
||||
".tlz" : ".lz"; // keep combined extension
|
||||
}
|
||||
const char * const compressor_name = get_compressor_name( format_index );
|
||||
if( !compressor_name )
|
||||
|
@ -176,9 +179,11 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
|||
return 1;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
std::string rname( dname ); rname += ".lz"; // recompressed_name
|
||||
struct stat st; // not used
|
||||
const std::string rname2( rname + ".lz" ); // produced by lzip < 1.20
|
||||
const bool lz_exists = ( stat( rname.c_str(), &st ) == 0 );
|
||||
// don't modify an existing 'rname.lz'
|
||||
const bool lz_lz_exists = ( stat( rname2.c_str(), &st ) == 0 );
|
||||
if( lz_exists && !force )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
|
@ -245,7 +250,7 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
|||
for( int i = 0; i < size; ++i ) argv[i+2] = lzip_args[i].c_str();
|
||||
for( int i = 0; i < size2; ++i ) argv[i+size+2] = lzip_args2[i].c_str();
|
||||
argv[size+size2+2] = "-o";
|
||||
argv[size+size2+3] = dname.c_str();
|
||||
argv[size+size2+3] = rname.c_str();
|
||||
argv[size+size2+4] = 0;
|
||||
execvp( argv[0], (char **)argv );
|
||||
}
|
||||
|
@ -258,7 +263,14 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
|||
close( fda[0] ); close( fda[1] );
|
||||
int retval = wait_for_child( pid, compressor_name );
|
||||
int retval2 = wait_for_child( pid2, lzip_name );
|
||||
if( retval || retval2 ) { std::remove( rname.c_str() ); return 1; }
|
||||
if( retval || retval2 )
|
||||
{ if( !lz_lz_exists ) std::remove( rname2.c_str() ); // lzip < 1.20
|
||||
std::remove( rname.c_str() ); return 1; }
|
||||
if( stat( rname.c_str(), &st ) != 0 &&
|
||||
( lz_lz_exists || stat( rname2.c_str(), &st ) != 0 ||
|
||||
std::rename( rname2.c_str(), rname.c_str() ) != 0 ) )
|
||||
{ show_file_error( rname.c_str(), "Error renaming output file", errno );
|
||||
return 1; } // lzip < 1.11
|
||||
set_permissions( rname.c_str(), in_stats );
|
||||
}
|
||||
|
||||
|
@ -268,11 +280,12 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
|||
std::string zcmp_command( invocation_name );
|
||||
unsigned i = zcmp_command.size();
|
||||
while( i > 0 && zcmp_command[i-1] != '/' ) --i;
|
||||
zcmp_command.resize( i );
|
||||
zcmp_command += "zcmp "; // ${bindir}zcmp
|
||||
zcmp_command.resize( i ); zcmp_command.insert( 0U, 1, '\'' );
|
||||
zcmp_command += "zcmp' "; // '[dir/]zcmp'
|
||||
if( no_rcfile ) zcmp_command += "-N ";
|
||||
if( verbosity < 0 ) zcmp_command += "-q ";
|
||||
zcmp_command += name; zcmp_command += ' '; zcmp_command += rname;
|
||||
zcmp_command += '\''; zcmp_command += name;
|
||||
zcmp_command += "' '"; zcmp_command += rname; zcmp_command += '\'';
|
||||
int status = std::system( zcmp_command.c_str() );
|
||||
if( status != 0 )
|
||||
{ if( !lz_exists ) std::remove( rname.c_str() );
|
||||
|
@ -301,8 +314,8 @@ int main( const int argc, const char * const argv[] )
|
|||
bool force = false;
|
||||
bool keep_input_files = false;
|
||||
bool no_rcfile = false;
|
||||
invocation_name = argv[0];
|
||||
program_name = "zupdate";
|
||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
|
|
119
zutils.cc
119
zutils.cc
|
@ -1,5 +1,5 @@
|
|||
/* Zutils - Utilities dealing with compressed files
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 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,24 +34,21 @@
|
|||
|
||||
namespace {
|
||||
|
||||
// first magic byte must be different among formats
|
||||
enum { bzip2_magic_size = 3,
|
||||
gzip_magic_size = 2,
|
||||
lzip_magic_size = 4,
|
||||
xz_magic_size = 5 };
|
||||
const uint8_t bzip2_magic[bzip2_magic_size] =
|
||||
{ 0x42, 0x5A, 0x68 }; // "BZh"
|
||||
const uint8_t gzip_magic[gzip_magic_size] =
|
||||
{ 0x1F, 0x8B };
|
||||
const uint8_t lzip_magic[lzip_magic_size] =
|
||||
{ 0x4C, 0x5A, 0x49, 0x50 }; // "LZIP"
|
||||
const uint8_t xz_magic[xz_magic_size] =
|
||||
{ 0xFD, 0x37, 0x7A, 0x58, 0x5A }; // 0xFD, "7zXZ"
|
||||
inline bool isvalid_ds( const uint8_t ds ) // lzip valid dictionary_size
|
||||
{
|
||||
enum { min_dictionary_size = 1 << 12,
|
||||
max_dictionary_size = 1 << 29 };
|
||||
unsigned dictionary_size = ( 1 << ( ds & 0x1F ) );
|
||||
if( dictionary_size > min_dictionary_size )
|
||||
dictionary_size -= ( dictionary_size / 16 ) * ( ( ds >> 5 ) & 7 );
|
||||
return ( dictionary_size >= min_dictionary_size &&
|
||||
dictionary_size <= max_dictionary_size );
|
||||
}
|
||||
|
||||
|
||||
// Returns -1 if child not terminated, 2 in case of error, or
|
||||
// exit status of child process 'pid'.
|
||||
//
|
||||
/* Returns -1 if child not terminated, 2 in case of error, or exit status of
|
||||
child process 'pid'.
|
||||
*/
|
||||
int child_status( const pid_t pid, const char * const name )
|
||||
{
|
||||
int status;
|
||||
|
@ -69,15 +66,16 @@ int child_status( const pid_t pid, const char * const name )
|
|||
if( tmp == pid ) break; // child terminated
|
||||
}
|
||||
if( WIFEXITED( status ) ) return WEXITSTATUS( status );
|
||||
if( WIFSIGNALED( status ) && WTERMSIG( status ) == SIGPIPE ) return 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
|
||||
// Returns the number of bytes really read.
|
||||
// If (returned value < size) and (errno == 0), means EOF was reached.
|
||||
//
|
||||
/* Returns the number of bytes really read.
|
||||
If (returned value < size) and (errno == 0), means EOF was reached.
|
||||
*/
|
||||
int readblock( const int fd, uint8_t * const buf, const int size )
|
||||
{
|
||||
int sz = 0;
|
||||
|
@ -94,9 +92,9 @@ int readblock( const int fd, uint8_t * const buf, const int size )
|
|||
}
|
||||
|
||||
|
||||
// Returns the number of bytes really written.
|
||||
// If (returned value < size), it is always an error.
|
||||
//
|
||||
/* Returns the number of bytes really written.
|
||||
If (returned value < size), it is always an error.
|
||||
*/
|
||||
int writeblock( const int fd, const uint8_t * const buf, const int size )
|
||||
{
|
||||
int sz = 0;
|
||||
|
@ -144,8 +142,9 @@ bool good_status( const Children & children, const bool finished )
|
|||
if( pid )
|
||||
{
|
||||
const char * const name =
|
||||
( i & 1 ) ? children.compressor_name : "data feeder";
|
||||
if( !finished )
|
||||
( i == 0 ) ? "data feeder" : children.compressor_name;
|
||||
// even if compressor finished, trailing data may remain in data feeder
|
||||
if( i == 0 || !finished )
|
||||
{
|
||||
const int tmp = child_status( pid, name );
|
||||
if( tmp < 0 ) // child not terminated
|
||||
|
@ -163,10 +162,10 @@ bool good_status( const Children & children, const bool finished )
|
|||
bool set_data_feeder( const std::string & filename, int * const infdp,
|
||||
Children & children, int format_index )
|
||||
{
|
||||
const uint8_t * magic_data = 0;
|
||||
uint8_t magic_data[magic_buf_size];
|
||||
int magic_size = 0;
|
||||
if( format_index < 0 )
|
||||
format_index = test_format( *infdp, &magic_data, &magic_size );
|
||||
format_index = test_format( *infdp, magic_data, &magic_size );
|
||||
children.compressor_name = get_compressor_name( format_index );
|
||||
|
||||
if( children.compressor_name ) // compressed
|
||||
|
@ -247,46 +246,38 @@ bool set_data_feeder( const std::string & filename, int * const infdp,
|
|||
}
|
||||
|
||||
|
||||
int test_format( const int infd, const uint8_t ** const magic_datap,
|
||||
// Returns format index or -1 if uncompressed
|
||||
//
|
||||
int test_format( const int infd, uint8_t magic_data[],
|
||||
int * const magic_sizep )
|
||||
{
|
||||
enum { buf_size = 5 };
|
||||
static uint8_t buf[buf_size];
|
||||
int i = 0;
|
||||
if( readblock( infd, buf, 1 ) == 1 )
|
||||
enum { bzip2_magic_size = 3,
|
||||
gzip_magic_size = 2,
|
||||
lzip_magic_size = 5,
|
||||
xz_magic_size = 5 };
|
||||
const uint8_t bzip2_magic[bzip2_magic_size] =
|
||||
{ 0x42, 0x5A, 0x68 }; // "BZh"
|
||||
const uint8_t gzip_magic[gzip_magic_size] =
|
||||
{ 0x1F, 0x8B };
|
||||
const uint8_t lzip_magic[lzip_magic_size] =
|
||||
{ 0x4C, 0x5A, 0x49, 0x50, 0x01 }; // "LZIP\001"
|
||||
const uint8_t xz_magic[xz_magic_size] =
|
||||
{ 0xFD, 0x37, 0x7A, 0x58, 0x5A }; // 0xFD, "7zXZ"
|
||||
|
||||
*magic_sizep = readblock( infd, magic_data, magic_buf_size );
|
||||
if( *magic_sizep == magic_buf_size )
|
||||
{
|
||||
++i;
|
||||
if( buf[0] == bzip2_magic[0] )
|
||||
{
|
||||
if( readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == bzip2_magic[1] &&
|
||||
readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == bzip2_magic[2] )
|
||||
{ *magic_datap = bzip2_magic; *magic_sizep = bzip2_magic_size;
|
||||
return fmt_bz2; }
|
||||
if( std::memcmp( magic_data, bzip2_magic, bzip2_magic_size ) == 0 &&
|
||||
magic_data[3] >= '1' && magic_data[3] <= '9' &&
|
||||
std::memcmp( magic_data + 4, "1AY&SY", 6 ) == 0 )
|
||||
return fmt_bz2;
|
||||
if( std::memcmp( magic_data, gzip_magic, gzip_magic_size ) == 0 )
|
||||
return fmt_gz;
|
||||
if( std::memcmp( magic_data, lzip_magic, lzip_magic_size ) == 0 &&
|
||||
isvalid_ds( magic_data[lzip_magic_size] ) )
|
||||
return fmt_lz;
|
||||
if( std::memcmp( magic_data, xz_magic, xz_magic_size ) == 0 )
|
||||
return fmt_xz;
|
||||
}
|
||||
else if( buf[0] == gzip_magic[0] )
|
||||
{
|
||||
if( readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == gzip_magic[1] )
|
||||
{ *magic_datap = gzip_magic; *magic_sizep = gzip_magic_size;
|
||||
return fmt_gz; }
|
||||
}
|
||||
else if( buf[0] == lzip_magic[0] )
|
||||
{
|
||||
if( readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == lzip_magic[1] &&
|
||||
readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == lzip_magic[2] &&
|
||||
readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == lzip_magic[3] )
|
||||
{ *magic_datap = lzip_magic; *magic_sizep = lzip_magic_size;
|
||||
return fmt_lz; }
|
||||
}
|
||||
else if( buf[0] == xz_magic[0] )
|
||||
{
|
||||
if( readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == xz_magic[1] &&
|
||||
readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == xz_magic[2] &&
|
||||
readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == xz_magic[3] &&
|
||||
readblock( infd, &buf[i], 1 ) == 1 && buf[i++] == xz_magic[4] )
|
||||
{ *magic_datap = xz_magic; *magic_sizep = xz_magic_size;
|
||||
return fmt_xz; }
|
||||
}
|
||||
}
|
||||
*magic_datap = buf; *magic_sizep = i;
|
||||
return -1;
|
||||
}
|
||||
|
|
6
zutils.h
6
zutils.h
|
@ -1,5 +1,5 @@
|
|||
/* Zutils - Utilities dealing with compressed files
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2020 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
|
||||
|
@ -29,7 +29,9 @@ bool good_status( const Children & children, const bool finished );
|
|||
bool set_data_feeder( const std::string & filename, int * const infdp,
|
||||
Children & children, int format_index );
|
||||
|
||||
enum { magic_buf_size = 10 }; // >= longest extended magic (bzip2)
|
||||
|
||||
// Returns format index or -1 if uncompressed
|
||||
//
|
||||
int test_format( const int infd, const uint8_t ** const magic_datap,
|
||||
int test_format( const int infd, uint8_t magic_data[],
|
||||
int * const magic_sizep );
|
||||
|
|
Loading…
Add table
Reference in a new issue