Merging upstream version 1.12~rc1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
411f37263d
commit
d5110769e8
29 changed files with 1120 additions and 662 deletions
34
ChangeLog
34
ChangeLog
|
@ -1,9 +1,29 @@
|
||||||
|
2022-12-05 Antonio Diaz Diaz <antonio@gnu.org>
|
||||||
|
|
||||||
|
* Version 1.12-rc1 released.
|
||||||
|
* zutilsrc: Rename to zutils.conf. Search for it in $XDG_CONFIG_HOME.
|
||||||
|
(Suggested by Adam Tuja).
|
||||||
|
* Allow '-O, --force-format' force also uncompressed format.
|
||||||
|
* zcmp.cc: New option '-H, --hexadecimal'.
|
||||||
|
Change long name of option '-s' to '--script'.
|
||||||
|
(Following a similar change made to GNU ed).
|
||||||
|
Assign short name '-q' to options '--quiet' and '--silent'.
|
||||||
|
Separate option '-l, --list' from '-v, --verbose'.
|
||||||
|
(cmp): Print byte and line in EOF message like GNU cmp.
|
||||||
|
* ztest.cc: Exit with status 2 if a file has wrong extension.
|
||||||
|
* zupdate.cc: New option '-d, --destdir'.
|
||||||
|
(zupdate_file): Pass '-q -s' to zcmp if verbosity < 0.
|
||||||
|
* rc.cc (show_version): Print the versions of the compressors used.
|
||||||
|
(show_option_error): New function showing argument and option name.
|
||||||
|
* zutils.texi: Document that format is detected by its magic bytes.
|
||||||
|
* check.sh: Test tarlz (if available) as compressor for zupdate.
|
||||||
|
|
||||||
2022-04-12 Antonio Diaz Diaz <antonio@gnu.org>
|
2022-04-12 Antonio Diaz Diaz <antonio@gnu.org>
|
||||||
|
|
||||||
* Version 1.12-pre2 released.
|
* Version 1.12-pre2 released.
|
||||||
* zgrep.cc: Accept option '-Z, --null'. (Reported by Leah Neukirchen).
|
* zgrep.cc: Accept option '-Z, --null'. (Reported by Leah Neukirchen).
|
||||||
* zupdate.cc: New options '-e, --expand-extensions',
|
* zupdate.cc: New options '-e, --expand-extensions',
|
||||||
'-i, --ignore-errors'.
|
'-i, --ignore-errors'. ('-i' suggested by Antoni Sawicki).
|
||||||
* Support compress'd (.Z) files through gzip in all utilities.
|
* Support compress'd (.Z) files through gzip in all utilities.
|
||||||
|
|
||||||
2022-03-06 Antonio Diaz Diaz <antonio@gnu.org>
|
2022-03-06 Antonio Diaz Diaz <antonio@gnu.org>
|
||||||
|
@ -126,13 +146,13 @@
|
||||||
|
|
||||||
* Version 1.0 released.
|
* Version 1.0 released.
|
||||||
* Add 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
|
* main.cc (main): Make 'grep_show_name' tri-state so that file name
|
||||||
name is no prefixed to output by default when searching one
|
is not prefixed to the output by default when searching one file
|
||||||
file and '--recursive' has not been selected.
|
and '--recursive' has not been selected.
|
||||||
* zgrep.cc: Fix output of option '-L' (it behaved like '-l').
|
* zgrep.cc: Fix output of option '-L' (it behaved like '-l').
|
||||||
* zcmp.cc: Fix deadlock when option '-n' is used.
|
* zcmp.cc: Fix deadlock when option '-n' is used.
|
||||||
* zdiff.cc (set_data_feeder): Call compressor with option '-q'
|
* zdiff.cc (set_data_feeder): Call compressor with option '-q' only
|
||||||
only if verbosity < 0.
|
if verbosity < 0.
|
||||||
* zutils.cc (set_data_feeder): Likewise.
|
* zutils.cc (set_data_feeder): Likewise.
|
||||||
* Change 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: Options now accept a separate argument.
|
||||||
|
@ -145,7 +165,7 @@
|
||||||
2011-01-11 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
2011-01-11 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||||
|
|
||||||
* Version 0.9 released.
|
* Version 0.9 released.
|
||||||
* configure: New options 'DIFF' and 'GREP'.
|
* configure: New variables 'DIFF' and 'GREP'.
|
||||||
* zcmp.cc: Fix deadlock when files differ.
|
* zcmp.cc: Fix deadlock when files differ.
|
||||||
* zgrep.cc: Fix deadlock when binary file matches.
|
* zgrep.cc: Fix deadlock when binary file matches.
|
||||||
|
|
||||||
|
|
10
INSTALL
10
INSTALL
|
@ -1,6 +1,6 @@
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
You will need a C++98 compiler with suport for 'long long'.
|
You will need a C++98 compiler with support for 'long long'.
|
||||||
(gcc 3.3.6 or newer is recommended).
|
(gcc 3.3.6 or newer is recommended).
|
||||||
I use gcc 6.1.0 and 3.3.6, but the code should compile with any standards
|
I use gcc 6.1.0 and 3.3.6, but the code should compile with any standards
|
||||||
compliant compiler.
|
compliant compiler.
|
||||||
|
@ -32,8 +32,8 @@ Procedure
|
||||||
or
|
or
|
||||||
lzip -cd zutils[version].tar.lz | tar -xf -
|
lzip -cd zutils[version].tar.lz | tar -xf -
|
||||||
|
|
||||||
This creates the directory ./zutils[version] containing the source from
|
This creates the directory ./zutils[version] containing the source code
|
||||||
the main archive.
|
extracted from the archive.
|
||||||
|
|
||||||
2. Change to zutils directory and run configure.
|
2. Change to zutils directory and run configure.
|
||||||
(Try 'configure --help' for usage instructions).
|
(Try 'configure --help' for usage instructions).
|
||||||
|
@ -68,8 +68,8 @@ object files and executables to go and run the 'configure' script.
|
||||||
'configure' automatically checks for the source code in '.', in '..', and
|
'configure' automatically checks for the source code in '.', in '..', and
|
||||||
in the directory that 'configure' is in.
|
in the directory that 'configure' is in.
|
||||||
|
|
||||||
'configure' recognizes the option '--srcdir=DIR' to control where to
|
'configure' recognizes the option '--srcdir=DIR' to control where to look
|
||||||
look for the sources. Usually 'configure' can determine that directory
|
for the source code. Usually 'configure' can determine that directory
|
||||||
automatically.
|
automatically.
|
||||||
|
|
||||||
After running 'configure', you can run 'make' and 'make install' as
|
After running 'configure', you can run 'make' and 'make install' as
|
||||||
|
|
10
Makefile.in
10
Makefile.in
|
@ -84,7 +84,7 @@ doc : info man
|
||||||
info : $(VPATH)/doc/$(pkgname).info
|
info : $(VPATH)/doc/$(pkgname).info
|
||||||
|
|
||||||
$(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texi
|
$(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texi
|
||||||
cd $(VPATH)/doc && makeinfo $(pkgname).texi
|
cd $(VPATH)/doc && $(MAKEINFO) $(pkgname).texi
|
||||||
|
|
||||||
man : $(VPATH)/doc/zcat.1 $(VPATH)/doc/zcmp.1 $(VPATH)/doc/zdiff.1 \
|
man : $(VPATH)/doc/zcat.1 $(VPATH)/doc/zcmp.1 $(VPATH)/doc/zdiff.1 \
|
||||||
$(VPATH)/doc/zgrep.1 $(VPATH)/doc/ztest.1 $(VPATH)/doc/zupdate.1
|
$(VPATH)/doc/zgrep.1 $(VPATH)/doc/ztest.1 $(VPATH)/doc/zupdate.1
|
||||||
|
@ -134,9 +134,9 @@ install-bin : all
|
||||||
$(INSTALL_PROGRAM) ./zgrep "$(DESTDIR)$(bindir)/zgrep"
|
$(INSTALL_PROGRAM) ./zgrep "$(DESTDIR)$(bindir)/zgrep"
|
||||||
$(INSTALL_PROGRAM) ./ztest "$(DESTDIR)$(bindir)/ztest"
|
$(INSTALL_PROGRAM) ./ztest "$(DESTDIR)$(bindir)/ztest"
|
||||||
$(INSTALL_PROGRAM) ./zupdate "$(DESTDIR)$(bindir)/zupdate"
|
$(INSTALL_PROGRAM) ./zupdate "$(DESTDIR)$(bindir)/zupdate"
|
||||||
if [ ! -e "$(DESTDIR)$(sysconfdir)/$(pkgname)rc" ] ; then \
|
if [ ! -e "$(DESTDIR)$(sysconfdir)/$(pkgname).conf" ] ; then \
|
||||||
if [ ! -d "$(DESTDIR)$(sysconfdir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(sysconfdir)" ; fi ; \
|
if [ ! -d "$(DESTDIR)$(sysconfdir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(sysconfdir)" ; fi ; \
|
||||||
$(INSTALL_DATA) $(VPATH)/$(pkgname)rc "$(DESTDIR)$(sysconfdir)/$(pkgname)rc" ; \
|
$(INSTALL_DATA) $(VPATH)/$(pkgname).conf "$(DESTDIR)$(sysconfdir)/$(pkgname).conf" ; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
install-bin-strip : all
|
install-bin-strip : all
|
||||||
|
@ -187,7 +187,7 @@ uninstall-bin :
|
||||||
-rm -f "$(DESTDIR)$(bindir)/zgrep"
|
-rm -f "$(DESTDIR)$(bindir)/zgrep"
|
||||||
-rm -f "$(DESTDIR)$(bindir)/ztest"
|
-rm -f "$(DESTDIR)$(bindir)/ztest"
|
||||||
-rm -f "$(DESTDIR)$(bindir)/zupdate"
|
-rm -f "$(DESTDIR)$(bindir)/zupdate"
|
||||||
-rm -f "$(DESTDIR)$(sysconfdir)/$(pkgname)rc"
|
-rm -f "$(DESTDIR)$(sysconfdir)/$(pkgname).conf"
|
||||||
|
|
||||||
uninstall-info :
|
uninstall-info :
|
||||||
-if $(CAN_RUN_INSTALLINFO) ; then \
|
-if $(CAN_RUN_INSTALLINFO) ; then \
|
||||||
|
@ -217,7 +217,7 @@ dist : doc
|
||||||
$(DISTNAME)/doc/*.1 \
|
$(DISTNAME)/doc/*.1 \
|
||||||
$(DISTNAME)/doc/$(pkgname).info \
|
$(DISTNAME)/doc/$(pkgname).info \
|
||||||
$(DISTNAME)/doc/$(pkgname).texi \
|
$(DISTNAME)/doc/$(pkgname).texi \
|
||||||
$(DISTNAME)/$(pkgname)rc \
|
$(DISTNAME)/$(pkgname).conf \
|
||||||
$(DISTNAME)/*.h \
|
$(DISTNAME)/*.h \
|
||||||
$(DISTNAME)/*.cc \
|
$(DISTNAME)/*.cc \
|
||||||
$(DISTNAME)/z*.in \
|
$(DISTNAME)/z*.in \
|
||||||
|
|
50
NEWS
50
NEWS
|
@ -1,16 +1,64 @@
|
||||||
Changes in version 1.12:
|
Changes in version 1.12:
|
||||||
|
|
||||||
|
The zutils configuration file 'zutilsrc' has been renamed to 'zutils.conf'.
|
||||||
|
Zutils now looks for the configuration file in $XDG_CONFIG_HOME/zutils.conf
|
||||||
|
instead of $HOME/.zutilsrc. (XDG_CONFIG_HOME defaults to $HOME/.config).
|
||||||
|
(Suggested by Adam Tuja).
|
||||||
|
|
||||||
|
In zcat, zcmp, zdiff, and zgrep, the option '-O, --force-format' now can
|
||||||
|
force also "uncompressed" format.
|
||||||
|
|
||||||
|
zcmp now accepts the option '-H, --hexadecimal' to print byte values in
|
||||||
|
hexadecimal instead of octal.
|
||||||
|
|
||||||
|
In zcmp:
|
||||||
|
The long name of option '-s' has been changed to '--script' following a
|
||||||
|
similar change made to GNU ed.
|
||||||
|
|
||||||
|
The short name '-q' has been assigned to options '--quiet' and '--silent'.
|
||||||
|
|
||||||
|
Option '-q' now only suppresses diagnostic messages written to stderr.
|
||||||
|
|
||||||
|
Option '-s' now only suppresses messages about file differences written to
|
||||||
|
stdout or stderr.
|
||||||
|
|
||||||
|
Option '-l, --list' is now different from option '-v, --verbose', which
|
||||||
|
now undoes the effect of '--quiet'.
|
||||||
|
|
||||||
|
zcmp now prints byte and line in EOF message like GNU cmp:
|
||||||
|
"zcmp: EOF on FILE after byte B, in line L".
|
||||||
|
|
||||||
zgrep now also accepts the following options: '-G, --basic-regexp',
|
zgrep now also accepts the following options: '-G, --basic-regexp',
|
||||||
'--label=<label>', '--line-buffered', '-P, --perl-regexp', '--silent',
|
'--label=<label>', '--line-buffered', '-P, --perl-regexp', '--silent',
|
||||||
'-T, --initial-tab', '-U, --binary', and '-Z, --null'.
|
'-T, --initial-tab', '-U, --binary', and '-Z, --null'.
|
||||||
(Reported by Chris Jamboretz and Leah Neukirchen).
|
(Reported by Chris Jamboretz and Leah Neukirchen).
|
||||||
|
|
||||||
|
ztest now exits with status 2 if an uncompressed file has a compressed file
|
||||||
|
name extension, or if a compressed file has a wrong compressed extension.
|
||||||
|
|
||||||
|
zupdate now accepts option '-d, --destdir' to write recompressed files to
|
||||||
|
another directory. This allows, for example, recompressing files from a
|
||||||
|
read-only file system to another place without needing to copy or link them
|
||||||
|
to the destination directory first.
|
||||||
|
|
||||||
zupdate now accepts option '-e, --expand-extensions', which makes it expand
|
zupdate now accepts option '-e, --expand-extensions', which makes it expand
|
||||||
combined file name extensions; tgz -> tar.lz.
|
combined file name extensions; tgz -> tar.lz.
|
||||||
|
|
||||||
zupdate now also accepts option '-i, --ignore-errors', which makes it ignore
|
zupdate now also accepts option '-i, --ignore-errors', which makes it ignore
|
||||||
non-fatal errors.
|
non-fatal errors. (Suggested by Antoni Sawicki).
|
||||||
|
|
||||||
All utilities now support compress'd (.Z) files through gzip. For this to
|
All utilities now support compress'd (.Z) files through gzip. For this to
|
||||||
work, the gzip program used (for example GNU gzip) must be able to
|
work, the gzip program used (for example GNU gzip) must be able to
|
||||||
decompress .Z files.
|
decompress .Z files.
|
||||||
|
|
||||||
|
At verbosity level 1 (2 for zdiff and zgrep) or higher, '-V, --version' now
|
||||||
|
prints the versions of the compressors used (limited by option '-M, --format').
|
||||||
|
(The compressors used must support option '-V' for this to work).
|
||||||
|
|
||||||
|
Diagnostics caused by invalid arguments to command line options now show the
|
||||||
|
argument and the name of the option.
|
||||||
|
|
||||||
|
It has been documented in the manual that the data format is detected by its
|
||||||
|
magic bytes, not by the file name extension.
|
||||||
|
|
||||||
|
The testsuite now tests tarlz (if available) as compressor for zupdate.
|
||||||
|
|
3
README
3
README
|
@ -4,7 +4,8 @@ Zutils is a collection of utilities able to process any combination of
|
||||||
compressed and uncompressed files transparently. If any file given,
|
compressed and uncompressed files transparently. If any file given,
|
||||||
including standard input, is compressed, its decompressed content is used.
|
including standard input, is compressed, its decompressed content is used.
|
||||||
Compressed files are decompressed on the fly; no temporary files are
|
Compressed files are decompressed on the fly; no temporary files are
|
||||||
created.
|
created. Data format is detected by its magic bytes, not by the file name
|
||||||
|
extension.
|
||||||
|
|
||||||
These utilities are not wrapper scripts but safer and more efficient C++
|
These utilities are not wrapper scripts but safer and more efficient C++
|
||||||
programs. In particular the option '--recursive' is very efficient in
|
programs. In particular the option '--recursive' is very efficient in
|
||||||
|
|
13
configure
vendored
13
configure
vendored
|
@ -6,7 +6,7 @@
|
||||||
# to copy, distribute, and modify it.
|
# to copy, distribute, and modify it.
|
||||||
|
|
||||||
pkgname=zutils
|
pkgname=zutils
|
||||||
pkgversion=1.12-pre2
|
pkgversion=1.12-rc1
|
||||||
srctrigger=doc/${pkgname}.texi
|
srctrigger=doc/${pkgname}.texi
|
||||||
|
|
||||||
# clear some things potentially inherited from environment.
|
# clear some things potentially inherited from environment.
|
||||||
|
@ -24,6 +24,7 @@ CXX=g++
|
||||||
CPPFLAGS=
|
CPPFLAGS=
|
||||||
CXXFLAGS='-Wall -W -O2'
|
CXXFLAGS='-Wall -W -O2'
|
||||||
LDFLAGS=
|
LDFLAGS=
|
||||||
|
MAKEINFO=makeinfo
|
||||||
DIFF=diff
|
DIFF=diff
|
||||||
GREP=grep
|
GREP=grep
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ while [ $# != 0 ] ; do
|
||||||
echo "Options and variables: [defaults in brackets]"
|
echo "Options and variables: [defaults in brackets]"
|
||||||
echo " -h, --help display this help and exit"
|
echo " -h, --help display this help and exit"
|
||||||
echo " -V, --version output version information and exit"
|
echo " -V, --version output version information and exit"
|
||||||
echo " --srcdir=DIR find the sources in DIR [. or ..]"
|
echo " --srcdir=DIR find the source code in DIR [. or ..]"
|
||||||
echo " --prefix=DIR install into DIR [${prefix}]"
|
echo " --prefix=DIR install into DIR [${prefix}]"
|
||||||
echo " --exec-prefix=DIR base directory for arch-dependent files [${exec_prefix}]"
|
echo " --exec-prefix=DIR base directory for arch-dependent files [${exec_prefix}]"
|
||||||
echo " --bindir=DIR user executables directory [${bindir}]"
|
echo " --bindir=DIR user executables directory [${bindir}]"
|
||||||
|
@ -72,6 +73,7 @@ while [ $# != 0 ] ; do
|
||||||
echo " CXXFLAGS=OPTIONS command line options for the C++ compiler [${CXXFLAGS}]"
|
echo " CXXFLAGS=OPTIONS command line options for the C++ compiler [${CXXFLAGS}]"
|
||||||
echo " CXXFLAGS+=OPTIONS append options to the current value of CXXFLAGS"
|
echo " CXXFLAGS+=OPTIONS append options to the current value of CXXFLAGS"
|
||||||
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
|
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
|
||||||
|
echo " MAKEINFO=NAME makeinfo program to use [${MAKEINFO}]"
|
||||||
echo " DIFF=NAME diff program to use with zdiff [${DIFF}]"
|
echo " DIFF=NAME diff program to use with zdiff [${DIFF}]"
|
||||||
echo " GREP=NAME grep program to use with zgrep [${GREP}]"
|
echo " GREP=NAME grep program to use with zgrep [${GREP}]"
|
||||||
echo
|
echo
|
||||||
|
@ -103,6 +105,7 @@ while [ $# != 0 ] ; do
|
||||||
CXXFLAGS=*) CXXFLAGS=${optarg} ;;
|
CXXFLAGS=*) CXXFLAGS=${optarg} ;;
|
||||||
CXXFLAGS+=*) CXXFLAGS="${CXXFLAGS} ${optarg}" ;;
|
CXXFLAGS+=*) CXXFLAGS="${CXXFLAGS} ${optarg}" ;;
|
||||||
LDFLAGS=*) LDFLAGS=${optarg} ;;
|
LDFLAGS=*) LDFLAGS=${optarg} ;;
|
||||||
|
MAKEINFO=*) MAKEINFO=${optarg} ;;
|
||||||
DIFF=*) DIFF=${optarg} ;;
|
DIFF=*) DIFF=${optarg} ;;
|
||||||
GREP=*) GREP=${optarg} ;;
|
GREP=*) GREP=${optarg} ;;
|
||||||
|
|
||||||
|
@ -124,7 +127,7 @@ while [ $# != 0 ] ; do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Find the source files, if location was not specified.
|
# Find the source code, if location was not specified.
|
||||||
srcdirtext=
|
srcdirtext=
|
||||||
if [ -z "${srcdir}" ] ; then
|
if [ -z "${srcdir}" ] ; then
|
||||||
srcdirtext="or . or .." ; srcdir=.
|
srcdirtext="or . or .." ; srcdir=.
|
||||||
|
@ -136,7 +139,7 @@ if [ -z "${srcdir}" ] ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
|
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
|
||||||
echo "configure: Can't find sources in ${srcdir} ${srcdirtext}" 1>&2
|
echo "configure: Can't find source code in ${srcdir} ${srcdirtext}" 1>&2
|
||||||
echo "configure: (At least ${srctrigger} is missing)." 1>&2
|
echo "configure: (At least ${srctrigger} is missing)." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -174,6 +177,7 @@ echo "CXX = ${CXX}"
|
||||||
echo "CPPFLAGS = ${CPPFLAGS}"
|
echo "CPPFLAGS = ${CPPFLAGS}"
|
||||||
echo "CXXFLAGS = ${CXXFLAGS}"
|
echo "CXXFLAGS = ${CXXFLAGS}"
|
||||||
echo "LDFLAGS = ${LDFLAGS}"
|
echo "LDFLAGS = ${LDFLAGS}"
|
||||||
|
echo "MAKEINFO = ${MAKEINFO}"
|
||||||
echo "DIFF = ${DIFF}"
|
echo "DIFF = ${DIFF}"
|
||||||
echo "GREP = ${GREP}"
|
echo "GREP = ${GREP}"
|
||||||
rm -f Makefile
|
rm -f Makefile
|
||||||
|
@ -199,6 +203,7 @@ CXX = ${CXX}
|
||||||
CPPFLAGS = ${CPPFLAGS}
|
CPPFLAGS = ${CPPFLAGS}
|
||||||
CXXFLAGS = ${CXXFLAGS}
|
CXXFLAGS = ${CXXFLAGS}
|
||||||
LDFLAGS = ${LDFLAGS}
|
LDFLAGS = ${LDFLAGS}
|
||||||
|
MAKEINFO = ${MAKEINFO}
|
||||||
DIFF = ${DIFF}
|
DIFF = ${DIFF}
|
||||||
GREP = ${GREP}
|
GREP = ${GREP}
|
||||||
EOF
|
EOF
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||||
.TH ZCAT "1" "April 2022" "zutils 1.12-pre2" "User Commands"
|
.TH ZCAT "1" "December 2022" "zutils 1.12-rc1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
zcat \- decompress and concatenate files to standard output
|
zcat \- decompress and concatenate files to standard output
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -54,7 +54,7 @@ number all output lines
|
||||||
don't read runtime configuration file
|
don't read runtime configuration file
|
||||||
.TP
|
.TP
|
||||||
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
||||||
force the format given (bz2, gz, lz, xz, zst)
|
force the input format
|
||||||
.TP
|
.TP
|
||||||
\fB\-q\fR, \fB\-\-quiet\fR
|
\fB\-q\fR, \fB\-\-quiet\fR
|
||||||
suppress all messages
|
suppress all messages
|
||||||
|
@ -94,6 +94,9 @@ set compressor and options for xz format
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-zst=\fR<command>
|
\fB\-\-zst=\fR<command>
|
||||||
set compressor and options for zstd format
|
set compressor and options for zstd format
|
||||||
|
.PP
|
||||||
|
Valid formats for options '\-M' and '\-O' are 'bz2', 'gz', 'lz', 'xz', 'zst',
|
||||||
|
and 'un' for uncompressed.
|
||||||
.SH "REPORTING BUGS"
|
.SH "REPORTING BUGS"
|
||||||
Report bugs to zutils\-bug@nongnu.org
|
Report bugs to zutils\-bug@nongnu.org
|
||||||
.br
|
.br
|
||||||
|
|
26
doc/zcmp.1
26
doc/zcmp.1
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||||
.TH ZCMP "1" "April 2022" "zutils 1.12-pre2" "User Commands"
|
.TH ZCMP "1" "December 2022" "zutils 1.12-rc1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
zcmp \- decompress and compare two files byte by byte
|
zcmp \- decompress and compare two files byte by byte
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -37,6 +37,9 @@ output version information and exit
|
||||||
\fB\-b\fR, \fB\-\-print\-bytes\fR
|
\fB\-b\fR, \fB\-\-print\-bytes\fR
|
||||||
print differing bytes
|
print differing bytes
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-H\fR, \fB\-\-hexadecimal\fR
|
||||||
|
print hexadecimal values instead of octal
|
||||||
|
.TP
|
||||||
\fB\-i\fR, \fB\-\-ignore\-initial=\fR<n>[:<n2>]
|
\fB\-i\fR, \fB\-\-ignore\-initial=\fR<n>[:<n2>]
|
||||||
ignore differences in the first <n> bytes
|
ignore differences in the first <n> bytes
|
||||||
.TP
|
.TP
|
||||||
|
@ -53,16 +56,16 @@ compare at most <n> bytes
|
||||||
don't read runtime configuration file
|
don't read runtime configuration file
|
||||||
.TP
|
.TP
|
||||||
\fB\-O\fR, \fB\-\-force\-format\fR=\fI\,[\/\fR<f1>][,<f2>]
|
\fB\-O\fR, \fB\-\-force\-format\fR=\fI\,[\/\fR<f1>][,<f2>]
|
||||||
force the formats given (bz2,gz,lz,xz,zst)
|
force one or both input formats
|
||||||
.TP
|
.TP
|
||||||
\fB\-q\fR, \fB\-\-quiet\fR
|
\fB\-q\fR, \fB\-\-quiet\fR, \fB\-\-silent\fR
|
||||||
suppress all messages
|
suppress diagnostics written to stderr
|
||||||
.TP
|
.TP
|
||||||
\fB\-s\fR, \fB\-\-silent\fR
|
\fB\-s\fR, \fB\-\-script\fR
|
||||||
(same as \fB\-\-quiet\fR)
|
suppress messages about file differences
|
||||||
.TP
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-verbose\fR
|
\fB\-v\fR, \fB\-\-verbose\fR
|
||||||
verbose mode (same as \fB\-\-list\fR)
|
verbose mode (opposite of \fB\-\-quiet\fR)
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-bz2=\fR<command>
|
\fB\-\-bz2=\fR<command>
|
||||||
set compressor and options for bzip2 format
|
set compressor and options for bzip2 format
|
||||||
|
@ -79,8 +82,13 @@ set compressor and options for xz format
|
||||||
\fB\-\-zst=\fR<command>
|
\fB\-\-zst=\fR<command>
|
||||||
set compressor and options for zstd format
|
set compressor and options for zstd format
|
||||||
.PP
|
.PP
|
||||||
Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,
|
Valid formats for options '\-M' and '\-O' are 'bz2', 'gz', 'lz', 'xz', 'zst',
|
||||||
Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...
|
and 'un' for uncompressed.
|
||||||
|
.PP
|
||||||
|
Byte counts given as arguments to options may be expressed in decimal,
|
||||||
|
hexadecimal, or octal (using the same syntax as integer constants in C++),
|
||||||
|
and may be followed by a multiplier: k = kB = 10^3 = 1000,
|
||||||
|
Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc.
|
||||||
.SH "REPORTING BUGS"
|
.SH "REPORTING BUGS"
|
||||||
Report bugs to zutils\-bug@nongnu.org
|
Report bugs to zutils\-bug@nongnu.org
|
||||||
.br
|
.br
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||||
.TH ZDIFF "1" "April 2022" "zutils 1.12-pre2" "User Commands"
|
.TH ZDIFF "1" "December 2022" "zutils 1.12-rc1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
zdiff \- decompress and compare two files line by line
|
zdiff \- decompress and compare two files line by line
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -68,7 +68,7 @@ process only the formats in <list>
|
||||||
don't read runtime configuration file
|
don't read runtime configuration file
|
||||||
.TP
|
.TP
|
||||||
\fB\-O\fR, \fB\-\-force\-format\fR=\fI\,[\/\fR<f1>][,<f2>]
|
\fB\-O\fR, \fB\-\-force\-format\fR=\fI\,[\/\fR<f1>][,<f2>]
|
||||||
force the formats given (bz2,gz,lz,xz,zst)
|
force one or both input formats
|
||||||
.TP
|
.TP
|
||||||
\fB\-p\fR, \fB\-\-show\-c\-function\fR
|
\fB\-p\fR, \fB\-\-show\-c\-function\fR
|
||||||
show which C function each change is in
|
show which C function each change is in
|
||||||
|
@ -117,6 +117,9 @@ set compressor and options for xz format
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-zst=\fR<command>
|
\fB\-\-zst=\fR<command>
|
||||||
set compressor and options for zstd format
|
set compressor and options for zstd format
|
||||||
|
.PP
|
||||||
|
Valid formats for options '\-M' and '\-O' are 'bz2', 'gz', 'lz', 'xz', 'zst',
|
||||||
|
and 'un' for uncompressed.
|
||||||
.SH "REPORTING BUGS"
|
.SH "REPORTING BUGS"
|
||||||
Report bugs to zutils\-bug@nongnu.org
|
Report bugs to zutils\-bug@nongnu.org
|
||||||
.br
|
.br
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||||
.TH ZGREP "1" "April 2022" "zutils 1.12-pre2" "User Commands"
|
.TH ZGREP "1" "December 2022" "zutils 1.12-rc1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
zgrep \- search compressed files for a regular expression
|
zgrep \- search compressed files for a regular expression
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -112,7 +112,7 @@ don't read runtime configuration file
|
||||||
show only the part of a line matching <pattern>
|
show only the part of a line matching <pattern>
|
||||||
.TP
|
.TP
|
||||||
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
||||||
force the format given (bz2, gz, lz, xz, zst)
|
force the input format
|
||||||
.TP
|
.TP
|
||||||
\fB\-P\fR, \fB\-\-perl\-regexp\fR
|
\fB\-P\fR, \fB\-\-perl\-regexp\fR
|
||||||
<pattern> is a Perl regular expression
|
<pattern> is a Perl regular expression
|
||||||
|
@ -165,6 +165,9 @@ set compressor and options for xz format
|
||||||
\fB\-\-zst=\fR<command>
|
\fB\-\-zst=\fR<command>
|
||||||
set compressor and options for zstd format
|
set compressor and options for zstd format
|
||||||
.PP
|
.PP
|
||||||
|
Valid formats for options '\-M' and '\-O' are 'bz2', 'gz', 'lz', 'xz', 'zst',
|
||||||
|
and 'un' for uncompressed.
|
||||||
|
.PP
|
||||||
Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,
|
Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,
|
||||||
Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...
|
Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...
|
||||||
.SH "REPORTING BUGS"
|
.SH "REPORTING BUGS"
|
||||||
|
|
29
doc/ztest.1
29
doc/ztest.1
|
@ -1,19 +1,21 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||||
.TH ZTEST "1" "April 2022" "zutils 1.12-pre2" "User Commands"
|
.TH ZTEST "1" "December 2022" "zutils 1.12-rc1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ztest \- verify the integrity of compressed files
|
ztest \- verify the integrity of compressed files
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B ztest
|
.B ztest
|
||||||
[\fI\,options\/\fR] [\fI\,files\/\fR]
|
[\fI\,options\/\fR] [\fI\,files\/\fR]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
ztest verifies the integrity of the compressed files specified.
|
ztest verifies the integrity of the compressed files specified. It
|
||||||
Uncompressed files are ignored. If a file is specified as '\-', the
|
also warns if an uncompressed file has a compressed file name extension, or
|
||||||
integrity of compressed data read from standard input is verified. Data
|
if a compressed file has a wrong compressed extension. Uncompressed files
|
||||||
read from standard input must be all in the same compressed format. If
|
are otherwise ignored. If a file is specified as '\-', the integrity of
|
||||||
a file fails to decompress, does not exist, can't be opened, or is a
|
compressed data read from standard input is verified. Data read from
|
||||||
terminal, ztest continues verifying the rest of the files. A final
|
standard input must be all in the same compressed format. If a file fails to
|
||||||
diagnostic is shown at verbosity level 1 or higher if any file fails the
|
decompress, does not exist, can't be opened, or is a terminal, ztest
|
||||||
test when testing multiple files.
|
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
|
.PP
|
||||||
If no files are specified, recursive searches examine the current
|
If no files are specified, recursive searches examine the current
|
||||||
working directory, and nonrecursive searches read standard input.
|
working directory, and nonrecursive searches read standard input.
|
||||||
|
@ -28,8 +30,9 @@ garbage output without issuing any warning. Therefore, xz files can't
|
||||||
always be verified as reliably as files in the other formats can.
|
always be verified as reliably as files in the other formats can.
|
||||||
.PP
|
.PP
|
||||||
Exit status is 0 if all compressed files verify OK, 1 if environmental
|
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
|
problems (file not found, invalid command line options, I/O errors, etc),
|
||||||
compressed file is corrupt or invalid.
|
2 if any compressed file is corrupt or invalid, or if any file has an
|
||||||
|
incorrect file name extension.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
\fB\-h\fR, \fB\-\-help\fR
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
|
@ -45,7 +48,7 @@ process only the formats in <list>
|
||||||
don't read runtime configuration file
|
don't read runtime configuration file
|
||||||
.TP
|
.TP
|
||||||
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
\fB\-O\fR, \fB\-\-force\-format=\fR<fmt>
|
||||||
force the format given (bz2, gz, lz, xz, zst)
|
force the input format
|
||||||
.TP
|
.TP
|
||||||
\fB\-q\fR, \fB\-\-quiet\fR
|
\fB\-q\fR, \fB\-\-quiet\fR
|
||||||
suppress all messages
|
suppress all messages
|
||||||
|
@ -73,6 +76,8 @@ set compressor and options for xz format
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-zst=\fR<command>
|
\fB\-\-zst=\fR<command>
|
||||||
set compressor and options for zstd format
|
set compressor and options for zstd format
|
||||||
|
.PP
|
||||||
|
Valid formats for options '\-M' and '\-O' are 'bz2', 'gz', 'lz', 'xz', and 'zst'.
|
||||||
.SH "REPORTING BUGS"
|
.SH "REPORTING BUGS"
|
||||||
Report bugs to zutils\-bug@nongnu.org
|
Report bugs to zutils\-bug@nongnu.org
|
||||||
.br
|
.br
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||||
.TH ZUPDATE "1" "April 2022" "zutils 1.12-pre2" "User Commands"
|
.TH ZUPDATE "1" "December 2022" "zutils 1.12-rc1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
zupdate \- recompress bzip2, gzip, xz, zstd files to lzip format
|
zupdate \- recompress bzip2, gzip, xz, zstd files to lzip format
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -33,8 +33,8 @@ The names of the original files must have one of the following extensions:
|
||||||
Exit status is 0 if all the compressed files were successfully recompressed
|
Exit status is 0 if all the compressed files were successfully recompressed
|
||||||
(if needed), compared, and deleted (if requested). 1 if a non\-fatal error
|
(if needed), compared, and deleted (if requested). 1 if a non\-fatal error
|
||||||
occurred (file not found or not regular, or has invalid format, or can't be
|
occurred (file not found or not regular, or has invalid format, or can't be
|
||||||
deleted). 2 if a fatal error occurred (compressor can't be run, or
|
deleted). 2 if a fatal error occurred (invalid command line options,
|
||||||
comparison fails).
|
compressor can't be run, or comparison fails).
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
\fB\-h\fR, \fB\-\-help\fR
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
|
@ -43,6 +43,9 @@ display this help and exit
|
||||||
\fB\-V\fR, \fB\-\-version\fR
|
\fB\-V\fR, \fB\-\-version\fR
|
||||||
output version information and exit
|
output version information and exit
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-d\fR, \fB\-\-destdir=\fR<dir>
|
||||||
|
write recompressed files into <dir>
|
||||||
|
.TP
|
||||||
\fB\-e\fR, \fB\-\-expand\-extensions\fR
|
\fB\-e\fR, \fB\-\-expand\-extensions\fR
|
||||||
expand combined extensions; tgz \-> tar.lz
|
expand combined extensions; tgz \-> tar.lz
|
||||||
.TP
|
.TP
|
||||||
|
@ -93,6 +96,8 @@ set compressor and options for xz format
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-zst=\fR<command>
|
\fB\-\-zst=\fR<command>
|
||||||
set compressor and options for zstd format
|
set compressor and options for zstd format
|
||||||
|
.PP
|
||||||
|
Valid formats for option '\-M' are 'bz2', 'gz', 'lz', 'xz', and 'zst'.
|
||||||
.SH "REPORTING BUGS"
|
.SH "REPORTING BUGS"
|
||||||
Report bugs to zutils\-bug@nongnu.org
|
Report bugs to zutils\-bug@nongnu.org
|
||||||
.br
|
.br
|
||||||
|
|
364
doc/zutils.info
364
doc/zutils.info
|
@ -11,13 +11,13 @@ File: zutils.info, Node: Top, Next: Introduction, Up: (dir)
|
||||||
Zutils Manual
|
Zutils Manual
|
||||||
*************
|
*************
|
||||||
|
|
||||||
This manual is for Zutils (version 1.12-pre2, 12 April 2022).
|
This manual is for Zutils (version 1.12-rc1, 5 December 2022).
|
||||||
|
|
||||||
* Menu:
|
* Menu:
|
||||||
|
|
||||||
* Introduction:: Purpose and features of zutils
|
* Introduction:: Purpose and features of zutils
|
||||||
* Common options:: Options common to all utilities
|
* Common options:: Options common to all utilities
|
||||||
* The zutilsrc file:: The zutils configuration file
|
* Configuration:: The configuration file zutils.conf
|
||||||
* Zcat:: Concatenating compressed files
|
* Zcat:: Concatenating compressed files
|
||||||
* Zcmp:: Comparing compressed files byte by byte
|
* Zcmp:: Comparing compressed files byte by byte
|
||||||
* Zdiff:: Comparing compressed files line by line
|
* Zdiff:: Comparing compressed files line by line
|
||||||
|
@ -43,20 +43,22 @@ Zutils is a collection of utilities able to process any combination of
|
||||||
compressed and uncompressed files transparently. If any file given,
|
compressed and uncompressed files transparently. If any file given,
|
||||||
including standard input, is compressed, its decompressed content is used.
|
including standard input, is compressed, its decompressed content is used.
|
||||||
Compressed files are decompressed on the fly; no temporary files are
|
Compressed files are decompressed on the fly; no temporary files are
|
||||||
created.
|
created. Data format is detected by its magic bytes, not by the file name
|
||||||
|
extension.
|
||||||
|
|
||||||
These utilities are not wrapper scripts but safer and more efficient C++
|
These utilities are not wrapper scripts but safer and more efficient C++
|
||||||
programs. In particular the option '--recursive' is very efficient in those
|
programs. In particular the option '--recursive' is very efficient in those
|
||||||
utilities supporting it.
|
utilities supporting it.
|
||||||
|
|
||||||
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest, and zupdate.
|
The utilities provided are 'zcat', 'zcmp', 'zdiff', 'zgrep', 'ztest', and
|
||||||
|
'zupdate'.
|
||||||
The formats supported are bzip2, gzip, lzip, xz, and zstd.
|
The formats supported are bzip2, gzip, lzip, xz, and zstd.
|
||||||
Zutils uses external compressors. The compressor to be used for each format
|
Zutils uses external compressors. The compressor to be used for each format
|
||||||
is configurable at runtime.
|
is configurable at runtime.
|
||||||
|
|
||||||
zcat, zcmp, zdiff, and zgrep are improved replacements for the shell
|
'zcat', 'zcmp', 'zdiff', and 'zgrep' are improved replacements for the
|
||||||
scripts provided by GNU gzip. ztest is unique to zutils. zupdate is similar
|
shell scripts provided by GNU gzip. 'ztest' is unique to zutils. 'zupdate'
|
||||||
to gzip's znew.
|
is similar to gzip's znew.
|
||||||
|
|
||||||
NOTE: Bzip2 and lzip provide well-defined values of exit status, which
|
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
|
makes them safe to use with zutils. Gzip and xz may return ambiguous warning
|
||||||
|
@ -94,7 +96,7 @@ Z zettabyte (10^21) | Zi zebibyte (2^70)
|
||||||
Y yottabyte (10^24) | Yi yobibyte (2^80)
|
Y yottabyte (10^24) | Yi yobibyte (2^80)
|
||||||
|
|
||||||
|
|
||||||
File: zutils.info, Node: Common options, Next: The zutilsrc file, Prev: Introduction, Up: Top
|
File: zutils.info, Node: Common options, Next: Configuration, Prev: Introduction, Up: Top
|
||||||
|
|
||||||
2 Common options
|
2 Common options
|
||||||
****************
|
****************
|
||||||
|
@ -106,14 +108,17 @@ here. *Note Argument syntax: (arg_parser)Argument syntax.
|
||||||
'-h'
|
'-h'
|
||||||
'--help'
|
'--help'
|
||||||
Print an informative help message describing the options and exit.
|
Print an informative help message describing the options and exit.
|
||||||
zgrep only supports the '--help' form of this option.
|
'zgrep' only supports the '--help' form of this option.
|
||||||
|
|
||||||
'-V'
|
'-V'
|
||||||
'--version'
|
'--version'
|
||||||
Print the version number on the standard output and exit. This version
|
Print the version number on the standard output and exit. This version
|
||||||
number should be included in all bug reports. In verbose mode, zdiff
|
number should be included in all bug reports. In verbose mode, 'zdiff'
|
||||||
and zgrep print also the version of the diff or grep program used
|
and 'zgrep' print also the version of the diff or grep program used
|
||||||
respectively.
|
respectively. At verbosity level 1 (2 for 'zdiff' and 'zgrep') or
|
||||||
|
higher, print also the versions of the compressors used (perhaps
|
||||||
|
limited by option '--format'). (The compressors used must support the
|
||||||
|
option '-V' for this to work).
|
||||||
|
|
||||||
'-M FORMAT_LIST'
|
'-M FORMAT_LIST'
|
||||||
'--format=FORMAT_LIST'
|
'--format=FORMAT_LIST'
|
||||||
|
@ -138,20 +143,19 @@ here. *Note Argument syntax: (arg_parser)Argument syntax.
|
||||||
|
|
||||||
'-N'
|
'-N'
|
||||||
'--no-rcfile'
|
'--no-rcfile'
|
||||||
Don't read the runtime configuration file 'zutilsrc'.
|
Don't read the runtime configuration file 'zutils.conf'.
|
||||||
|
|
||||||
'--bz2=COMMAND'
|
'--bz2=COMMAND'
|
||||||
'--gz=COMMAND'
|
'--gz=COMMAND'
|
||||||
'--lz=COMMAND'
|
'--lz=COMMAND'
|
||||||
'--xz=COMMAND'
|
'--xz=COMMAND'
|
||||||
'--zst=COMMAND'
|
'--zst=COMMAND'
|
||||||
Set program to be used as (de)compressor for the corresponding format.
|
Set program to be used as decompressor for the corresponding format.
|
||||||
COMMAND may include arguments. For example '--lz='plzip --threads=2''.
|
COMMAND may include arguments. For example '--lz='plzip --threads=2''.
|
||||||
The program set with '--lz' is used for both compression and
|
'zupdate' uses '--lz' for compression, not for decompression (*note
|
||||||
decompression. The others are used only for decompression. The name of
|
lz-compressor::). The name of the program can't begin with '-'. These
|
||||||
the program can't begin with '-'. These options override the values
|
options override the values set in 'zutils.conf'. The compression
|
||||||
set in 'zutilsrc'. The compression program used must meet three
|
program used must meet three requirements:
|
||||||
requirements:
|
|
||||||
|
|
||||||
1. When called with the option '-d' and without file names, it must
|
1. When called with the option '-d' and without file names, it must
|
||||||
read compressed data from the standard input and produce
|
read compressed data from the standard input and produce
|
||||||
|
@ -165,21 +169,23 @@ here. *Note Argument syntax: (arg_parser)Argument syntax.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File: zutils.info, Node: The zutilsrc file, Next: Zcat, Prev: Common options, Up: Top
|
File: zutils.info, Node: Configuration, Next: Zcat, Prev: Common options, Up: Top
|
||||||
|
|
||||||
3 The zutils configuration file 'zutilsrc'
|
3 The configuration file 'zutils.conf'
|
||||||
******************************************
|
**************************************
|
||||||
|
|
||||||
'zutilsrc' is the runtime configuration file for zutils. In it you may
|
'zutils.conf' is the runtime configuration file for zutils. In it you may
|
||||||
define the compressor name and options to be used for each format.
|
define the compressor name and options to be used for each format.
|
||||||
'zutilsrc' is optional; you don't need to install it in order to run zutils.
|
'zutils.conf' is optional; you don't need to install it in order to run
|
||||||
|
zutils.
|
||||||
|
|
||||||
The compressors specified in the command line override those specified
|
The compressors specified in the command line override those specified
|
||||||
in 'zutilsrc'.
|
in 'zutils.conf'.
|
||||||
|
|
||||||
You may copy the system 'zutilsrc' file '${sysconfdir}/zutilsrc' to
|
You may copy the system 'zutils.conf' file '${sysconfdir}/zutils.conf'
|
||||||
'$HOME/.zutilsrc' and customize these options as you like. The file syntax
|
to '$XDG_CONFIG_HOME/zutils.conf' and customize these options as you like.
|
||||||
is fairly obvious (and there are further instructions in it):
|
('XDG_CONFIG_HOME' defaults to '$HOME/.config'). The file syntax is fairly
|
||||||
|
obvious (and there are further instructions in it):
|
||||||
|
|
||||||
1. Any line beginning with '#' is a comment line.
|
1. Any line beginning with '#' is a comment line.
|
||||||
|
|
||||||
|
@ -189,17 +195,17 @@ is fairly obvious (and there are further instructions in it):
|
||||||
where <format> is one of 'bz2', 'gz', 'lz', 'xz', or 'zst'.
|
where <format> is one of 'bz2', 'gz', 'lz', 'xz', or 'zst'.
|
||||||
|
|
||||||
|
|
||||||
File: zutils.info, Node: Zcat, Next: Zcmp, Prev: The zutilsrc file, Up: Top
|
File: zutils.info, Node: Zcat, Next: Zcmp, Prev: Configuration, Up: Top
|
||||||
|
|
||||||
4 Zcat
|
4 Zcat
|
||||||
******
|
******
|
||||||
|
|
||||||
zcat copies each FILE argument to standard output in sequence. If any file
|
'zcat' copies each FILE argument to standard output in sequence. If any
|
||||||
given is compressed, its decompressed content is copied. If a file given
|
file given is compressed, its decompressed content is copied. If a file
|
||||||
does not exist, and its name does not end with one of the known extensions,
|
given does not exist, and its name does not end with one of the known
|
||||||
zcat tries the compressed file names corresponding to the formats
|
extensions, 'zcat' tries the compressed file names corresponding to the
|
||||||
supported. If a file fails to decompress, zcat continues copying the rest
|
formats supported. If a file fails to decompress, 'zcat' continues copying
|
||||||
of the files.
|
the rest of the files.
|
||||||
|
|
||||||
If a file is specified as '-', data are read from standard input,
|
If a file is specified as '-', data are read from standard input,
|
||||||
decompressed if needed, and sent to standard output. Data read from
|
decompressed if needed, and sent to standard output. Data read from
|
||||||
|
@ -209,13 +215,13 @@ same compressed format.
|
||||||
If no files are specified, recursive searches examine the current working
|
If no files are specified, recursive searches examine the current working
|
||||||
directory, and nonrecursive searches read standard input.
|
directory, and nonrecursive searches read standard input.
|
||||||
|
|
||||||
The format for running zcat is:
|
The format for running 'zcat' is:
|
||||||
|
|
||||||
zcat [OPTIONS] [FILES]
|
zcat [OPTIONS] [FILES]
|
||||||
|
|
||||||
Exit status is 0 if no errors occurred, 1 otherwise.
|
Exit status is 0 if no errors occurred, 1 otherwise.
|
||||||
|
|
||||||
zcat supports the following options:
|
'zcat' supports the following options:
|
||||||
|
|
||||||
'-A'
|
'-A'
|
||||||
'--show-all'
|
'--show-all'
|
||||||
|
@ -240,10 +246,10 @@ Exit status is 0 if no errors occurred, 1 otherwise.
|
||||||
'-O FORMAT'
|
'-O FORMAT'
|
||||||
'--force-format=FORMAT'
|
'--force-format=FORMAT'
|
||||||
Force the compressed format given. Valid values for FORMAT are 'bz2',
|
Force the compressed format given. Valid values for FORMAT are 'bz2',
|
||||||
'gz', 'lz', 'xz', and 'zst'. If this option is used, the files are
|
'gz', 'lz', 'xz', 'zst', and 'un' for 'uncompressed'. If this option
|
||||||
passed to the corresponding decompressor without verifying their
|
is used, the files are passed to the corresponding decompressor (or
|
||||||
format, and the exact file name must be given. Other names won't be
|
transmitted unmodified) without verifying their format, and the exact
|
||||||
tried.
|
file name must be given. Other names won't be tried.
|
||||||
|
|
||||||
'-q'
|
'-q'
|
||||||
'--quiet'
|
'--quiet'
|
||||||
|
@ -278,7 +284,8 @@ Exit status is 0 if no errors occurred, 1 otherwise.
|
||||||
stands for "meta").
|
stands for "meta").
|
||||||
|
|
||||||
'--verbose'
|
'--verbose'
|
||||||
Verbose mode. Show error messages.
|
Verbose mode. Show error messages. Repeating it increases the verbosity
|
||||||
|
level. *Note version::.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -287,19 +294,19 @@ File: zutils.info, Node: Zcmp, Next: Zdiff, Prev: Zcat, Up: Top
|
||||||
5 Zcmp
|
5 Zcmp
|
||||||
******
|
******
|
||||||
|
|
||||||
zcmp compares two files and, if they differ, writes to standard output the
|
'zcmp' compares two files and, if they differ, writes to standard output
|
||||||
first byte and line number where they differ. Bytes and lines are numbered
|
the first byte and line number where they differ. Bytes and lines are
|
||||||
starting with 1. A hyphen '-' used as a FILE argument means standard input.
|
numbered starting with 1. A hyphen '-' used as a FILE argument means
|
||||||
If any file given is compressed, its decompressed content is used.
|
standard input. If any file given is compressed, its decompressed content
|
||||||
Compressed files are decompressed on the fly; no temporary files are
|
is used. Compressed files are decompressed on the fly; no temporary files
|
||||||
created.
|
are created.
|
||||||
|
|
||||||
The format for running zcmp is:
|
The format for running 'zcmp' is:
|
||||||
|
|
||||||
zcmp [OPTIONS] FILE1 [FILE2]
|
zcmp [OPTIONS] FILE1 [FILE2]
|
||||||
|
|
||||||
This compares FILE1 to FILE2. The standard input is used only if FILE1 or
|
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
|
FILE2 refers to standard input. If FILE2 is omitted 'zcmp' tries the
|
||||||
following:
|
following:
|
||||||
|
|
||||||
- If FILE1 is compressed, compares its decompressed contents with the
|
- If FILE1 is compressed, compares its decompressed contents with the
|
||||||
|
@ -312,13 +319,19 @@ following:
|
||||||
An exit status of 0 means no differences were found, 1 means some
|
An exit status of 0 means no differences were found, 1 means some
|
||||||
differences were found, and 2 means trouble.
|
differences were found, and 2 means trouble.
|
||||||
|
|
||||||
zcmp supports the following options:
|
'zcmp' supports the following options:
|
||||||
|
|
||||||
'-b'
|
'-b'
|
||||||
'--print-bytes'
|
'--print-bytes'
|
||||||
Print the differing bytes. Print control bytes as a '^' followed by a
|
Print the values of the differing bytes (in octal by default) followed
|
||||||
letter, and precede bytes larger than 127 with 'M-' (which stands for
|
by the bytes themselves in printable form. Print control bytes as a '^'
|
||||||
"meta").
|
followed by a letter, and precede bytes larger than 127 with 'M-'
|
||||||
|
(which stands for "meta").
|
||||||
|
|
||||||
|
'-H'
|
||||||
|
'--hexadecimal'
|
||||||
|
Print the values of the differing bytes in hexadecimal instead of
|
||||||
|
octal.
|
||||||
|
|
||||||
'-i SIZE'
|
'-i SIZE'
|
||||||
'--ignore-initial=SIZE'
|
'--ignore-initial=SIZE'
|
||||||
|
@ -328,11 +341,9 @@ differences were found, and 2 means trouble.
|
||||||
first input file and the first SIZE2 bytes of the second input file.
|
first input file and the first SIZE2 bytes of the second input file.
|
||||||
|
|
||||||
'-l'
|
'-l'
|
||||||
'-v'
|
|
||||||
'--list'
|
'--list'
|
||||||
'--verbose'
|
Print the byte numbers (in decimal) and values (in octal by default)
|
||||||
Print the byte numbers (in decimal) and values (in octal) of all
|
of all differing bytes. Bytes are numbered starting with 1.
|
||||||
differing bytes.
|
|
||||||
|
|
||||||
'-n COUNT'
|
'-n COUNT'
|
||||||
'--bytes=COUNT'
|
'--bytes=COUNT'
|
||||||
|
@ -342,19 +353,50 @@ differences were found, and 2 means trouble.
|
||||||
'--force-format=[FORMAT1][,FORMAT2]'
|
'--force-format=[FORMAT1][,FORMAT2]'
|
||||||
Force the compressed formats given. Any of FORMAT1 or FORMAT2 may be
|
Force the compressed formats given. Any of FORMAT1 or FORMAT2 may be
|
||||||
omitted and the corresponding format will be automatically detected.
|
omitted and the corresponding format will be automatically detected.
|
||||||
Valid values for FORMAT are 'bz2', 'gz', 'lz', 'xz', and 'zst'. If at
|
Valid values for FORMAT are 'bz2', 'gz', 'lz', 'xz', 'zst', and 'un'
|
||||||
least one format is specified with this option, the file is passed to
|
for 'uncompressed'. If at least one format is specified with this
|
||||||
the corresponding decompressor without verifying its format, and the
|
option, the file is passed to the corresponding decompressor (or
|
||||||
exact file names of both FILE1 and FILE2 must be given. Other names
|
transmitted unmodified) without verifying its format, and the exact
|
||||||
won't be tried.
|
file names of both FILE1 and FILE2 must be given. Other names won't be
|
||||||
|
tried.
|
||||||
|
|
||||||
'-q'
|
'-q'
|
||||||
'-s'
|
|
||||||
'--quiet'
|
'--quiet'
|
||||||
'--silent'
|
'--silent'
|
||||||
Don't print anything; only return an exit status indicating whether the
|
Suppress diagnostics written to standard error, even the
|
||||||
files differ.
|
'EOF on <name_of_shorter_file>' diagnostic. Byte differences are still
|
||||||
|
written to standard output. ('-q' produces no output except byte
|
||||||
|
differences).
|
||||||
|
|
||||||
|
'-s'
|
||||||
|
'--script'
|
||||||
|
Write nothing to standard output or standard error when files differ,
|
||||||
|
not even the 'EOF on <name_of_shorter_file>' diagnostic; indicate
|
||||||
|
differing files through exit status only. Diagnostic messages are still
|
||||||
|
written to standard error when an error is encountered. ('-s' produces
|
||||||
|
no output except error messages).
|
||||||
|
|
||||||
|
'-v'
|
||||||
|
'--verbose'
|
||||||
|
Verbose mode. Undoes the effect of '--quiet'. Further -v's increase
|
||||||
|
the verbosity level. *Note version::.
|
||||||
|
|
||||||
|
|
||||||
|
Byte counts given as arguments to options may be expressed in decimal,
|
||||||
|
hexadecimal, or octal (using the same syntax as integer constants in C++),
|
||||||
|
and may be followed by a multiplier and an optional 'B' for "byte".
|
||||||
|
|
||||||
|
Table of SI and binary prefixes (unit multipliers):
|
||||||
|
|
||||||
|
Prefix Value | Prefix Value
|
||||||
|
k kilobyte (10^3 = 1000) | Ki kibibyte (2^10 = 1024)
|
||||||
|
M megabyte (10^6) | Mi mebibyte (2^20)
|
||||||
|
G gigabyte (10^9) | Gi gibibyte (2^30)
|
||||||
|
T terabyte (10^12) | Ti tebibyte (2^40)
|
||||||
|
P petabyte (10^15) | Pi pebibyte (2^50)
|
||||||
|
E exabyte (10^18) | Ei exbibyte (2^60)
|
||||||
|
Z zettabyte (10^21) | Zi zebibyte (2^70)
|
||||||
|
Y yottabyte (10^24) | Yi yobibyte (2^80)
|
||||||
|
|
||||||
|
|
||||||
File: zutils.info, Node: Zdiff, Next: Zgrep, Prev: Zcmp, Up: Top
|
File: zutils.info, Node: Zdiff, Next: Zgrep, Prev: Zcmp, Up: Top
|
||||||
|
@ -362,19 +404,19 @@ File: zutils.info, Node: Zdiff, Next: Zgrep, Prev: Zcmp, Up: Top
|
||||||
6 Zdiff
|
6 Zdiff
|
||||||
*******
|
*******
|
||||||
|
|
||||||
zdiff compares two files and, if they differ, writes to standard output the
|
'zdiff' compares two files and, if they differ, writes to standard output
|
||||||
differences line by line. A hyphen '-' used as a FILE argument means
|
the differences line by line. A hyphen '-' used as a FILE argument means
|
||||||
standard input. If any file given is compressed, its decompressed content
|
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
|
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
|
that messages from diff refer to temporary file names instead of those
|
||||||
specified.
|
specified.
|
||||||
|
|
||||||
The format for running zdiff is:
|
The format for running 'zdiff' is:
|
||||||
|
|
||||||
zdiff [OPTIONS] FILE1 [FILE2]
|
zdiff [OPTIONS] FILE1 [FILE2]
|
||||||
|
|
||||||
This compares FILE1 to FILE2. The standard input is used only if FILE1 or
|
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
|
FILE2 refers to standard input. If FILE2 is omitted 'zdiff' tries the
|
||||||
following:
|
following:
|
||||||
|
|
||||||
- If FILE1 is compressed, compares its decompressed contents with the
|
- If FILE1 is compressed, compares its decompressed contents with the
|
||||||
|
@ -387,8 +429,8 @@ following:
|
||||||
An exit status of 0 means no differences were found, 1 means some
|
An exit status of 0 means no differences were found, 1 means some
|
||||||
differences were found, and 2 means trouble.
|
differences were found, and 2 means trouble.
|
||||||
|
|
||||||
zdiff supports the following options (some options only work if the diff
|
'zdiff' supports the following options (some options only work if the
|
||||||
program used supports them):
|
diff program used supports them):
|
||||||
|
|
||||||
'-a'
|
'-a'
|
||||||
'--text'
|
'--text'
|
||||||
|
@ -425,11 +467,12 @@ program used supports them):
|
||||||
'--force-format=[FORMAT1][,FORMAT2]'
|
'--force-format=[FORMAT1][,FORMAT2]'
|
||||||
Force the compressed formats given. Any of FORMAT1 or FORMAT2 may be
|
Force the compressed formats given. Any of FORMAT1 or FORMAT2 may be
|
||||||
omitted and the corresponding format will be automatically detected.
|
omitted and the corresponding format will be automatically detected.
|
||||||
Valid values for FORMAT are 'bz2', 'gz', 'lz', 'xz', and 'zst'. If at
|
Valid values for FORMAT are 'bz2', 'gz', 'lz', 'xz', 'zst', and 'un'
|
||||||
least one format is specified with this option, the file is passed to
|
for 'uncompressed'. If at least one format is specified with this
|
||||||
the corresponding decompressor without verifying its format, and the
|
option, the file is passed to the corresponding decompressor (or
|
||||||
exact file names of both FILE1 and FILE2 must be given. Other names
|
transmitted unmodified) without verifying its format, and the exact
|
||||||
won't be tried.
|
file names of both FILE1 and FILE2 must be given. Other names won't be
|
||||||
|
tried.
|
||||||
|
|
||||||
'-p'
|
'-p'
|
||||||
'--show-c-function'
|
'--show-c-function'
|
||||||
|
@ -461,7 +504,8 @@ program used supports them):
|
||||||
'-v'
|
'-v'
|
||||||
'--verbose'
|
'--verbose'
|
||||||
When specified before '--version', print the version of the diff
|
When specified before '--version', print the version of the diff
|
||||||
program used.
|
program used. Further -v's increase the verbosity level. *Note
|
||||||
|
version::.
|
||||||
|
|
||||||
'-w'
|
'-w'
|
||||||
'--ignore-all-space'
|
'--ignore-all-space'
|
||||||
|
@ -483,12 +527,13 @@ File: zutils.info, Node: Zgrep, Next: Ztest, Prev: Zdiff, Up: Top
|
||||||
7 Zgrep
|
7 Zgrep
|
||||||
*******
|
*******
|
||||||
|
|
||||||
zgrep is a front end to the program grep that allows transparent search on
|
'zgrep' is a front end to the program grep that allows transparent search
|
||||||
any combination of compressed and uncompressed files. If any file given is
|
on any combination of compressed and uncompressed files. If any file given
|
||||||
compressed, its decompressed content is used. If a file given does not
|
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
|
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
|
tries the compressed file names corresponding to the formats supported. If
|
||||||
a file fails to decompress, zgrep continues searching the rest of the files.
|
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,
|
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
|
decompressed if needed, and fed to grep. Data read from standard input must
|
||||||
|
@ -497,16 +542,23 @@ 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
|
If no files are specified, recursive searches examine the current working
|
||||||
directory, and nonrecursive searches read standard input.
|
directory, and nonrecursive searches read standard input.
|
||||||
|
|
||||||
The format for running zgrep is:
|
For efficiency reasons, 'zgrep' does not always read all its input. For
|
||||||
|
example, the shell command 'base64 -d foo | zgrep -q X' can cause 'zgrep'
|
||||||
|
to exit immediately after reading a line containing 'X', without bothering
|
||||||
|
to read the rest of its input data. This in turn can cause base64 to exit
|
||||||
|
with a nonzero status because base64 cannot write to its output pipe after
|
||||||
|
'zgrep' exits.
|
||||||
|
|
||||||
|
The format for running 'zgrep' is:
|
||||||
|
|
||||||
zgrep [OPTIONS] PATTERN [FILES]
|
zgrep [OPTIONS] PATTERN [FILES]
|
||||||
|
|
||||||
An exit status of 0 means at least one match was found, 1 means no matches
|
An exit status of 0 means at least one match was found, 1 means no matches
|
||||||
were found, and 2 means trouble.
|
were found, and 2 means trouble.
|
||||||
|
|
||||||
zgrep supports the following options (Some options only work if the grep
|
'zgrep' supports the following options (Some options only work if the
|
||||||
program used supports them. Options -h, -H, -r, -R, and -Z are managed by
|
grep program used supports them. Options -h, -H, -r, -R, and -Z are managed
|
||||||
zgrep and not passed to grep):
|
by 'zgrep' and not passed to grep):
|
||||||
|
|
||||||
'-a'
|
'-a'
|
||||||
'--text'
|
'--text'
|
||||||
|
@ -577,11 +629,13 @@ zgrep and not passed to grep):
|
||||||
|
|
||||||
'-l'
|
'-l'
|
||||||
'--files-with-matches'
|
'--files-with-matches'
|
||||||
Only print names of files containing at least one match.
|
Only print names of files containing at least one match. Stop reading
|
||||||
|
each file on the first match.
|
||||||
|
|
||||||
'-L'
|
'-L'
|
||||||
'--files-without-match'
|
'--files-without-match'
|
||||||
Only print names of files not containing any matches.
|
Only print names of files not containing any matches. Stop reading
|
||||||
|
each file on the first match.
|
||||||
Note: option -L fails (prints wrong results, returns wrong status, and
|
Note: option -L fails (prints wrong results, returns wrong status, and
|
||||||
even hangs) when using GNU grep versions 3.2 to 3.4 inclusive because
|
even hangs) when using GNU grep versions 3.2 to 3.4 inclusive because
|
||||||
of a wrong change in the exit status of grep, which was reverted in
|
of a wrong change in the exit status of grep, which was reverted in
|
||||||
|
@ -609,10 +663,10 @@ zgrep and not passed to grep):
|
||||||
'-O FORMAT'
|
'-O FORMAT'
|
||||||
'--force-format=FORMAT'
|
'--force-format=FORMAT'
|
||||||
Force the compressed format given. Valid values for FORMAT are 'bz2',
|
Force the compressed format given. Valid values for FORMAT are 'bz2',
|
||||||
'gz', 'lz', 'xz', and 'zst'. If this option is used, the files are
|
'gz', 'lz', 'xz', 'zst', and 'un' for 'uncompressed'. If this option
|
||||||
passed to the corresponding decompressor without verifying their
|
is used, the files are passed to the corresponding decompressor (or
|
||||||
format, and the exact file name must be given. Other names won't be
|
transmitted unmodified) without verifying their format, and the exact
|
||||||
tried.
|
file name must be given. Other names won't be tried.
|
||||||
|
|
||||||
'-P'
|
'-P'
|
||||||
'--perl-regexp'
|
'--perl-regexp'
|
||||||
|
@ -655,7 +709,8 @@ zgrep and not passed to grep):
|
||||||
|
|
||||||
'--verbose'
|
'--verbose'
|
||||||
Verbose mode. Show error messages. When specified before '--version',
|
Verbose mode. Show error messages. When specified before '--version',
|
||||||
print the version of the grep program used.
|
print the version of the grep program used. Repeating it increases the
|
||||||
|
verbosity level. *Note version::.
|
||||||
|
|
||||||
'-w'
|
'-w'
|
||||||
'--word-regexp'
|
'--word-regexp'
|
||||||
|
@ -680,14 +735,16 @@ File: zutils.info, Node: Ztest, Next: Zupdate, Prev: Zgrep, Up: Top
|
||||||
8 Ztest
|
8 Ztest
|
||||||
*******
|
*******
|
||||||
|
|
||||||
ztest verifies the integrity of the compressed files specified.
|
'ztest' verifies the integrity of the compressed files specified. It also
|
||||||
Uncompressed files are ignored. If a file is specified as '-', the
|
warns if an uncompressed file has a compressed file name extension, or if a
|
||||||
integrity of compressed data read from standard input is verified. Data
|
compressed file has a wrong compressed extension. Uncompressed files are
|
||||||
read from standard input must be all in the same compressed format. If a
|
otherwise ignored. If a file is specified as '-', the integrity of
|
||||||
file fails to decompress, does not exist, can't be opened, or is a
|
compressed data read from standard input is verified. Data read from
|
||||||
terminal, ztest continues verifying the rest of the files. A final
|
standard input must be all in the same compressed format. If a file fails to
|
||||||
diagnostic is shown at verbosity level 1 or higher if any file fails the
|
decompress, does not exist, can't be opened, or is a terminal, 'ztest'
|
||||||
test when testing multiple files.
|
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
|
If no files are specified, recursive searches examine the current working
|
||||||
directory, and nonrecursive searches read standard input.
|
directory, and nonrecursive searches read standard input.
|
||||||
|
@ -703,15 +760,16 @@ of the xz format specification allows xz decompressors to produce garbage
|
||||||
output without issuing any warning. Therefore, xz files can't always be
|
output without issuing any warning. Therefore, xz files can't always be
|
||||||
verified as reliably as files in the other formats can.
|
verified as reliably as files in the other formats can.
|
||||||
|
|
||||||
The format for running ztest is:
|
The format for running 'ztest' is:
|
||||||
|
|
||||||
ztest [OPTIONS] [FILES]
|
ztest [OPTIONS] [FILES]
|
||||||
|
|
||||||
The exit status is 0 if all compressed files verify OK, 1 if environmental
|
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
|
problems (file not found, invalid command line options, I/O errors, etc), 2
|
||||||
compressed file is corrupt or invalid.
|
if any compressed file is corrupt or invalid, or if any file has an
|
||||||
|
incorrect file name extension.
|
||||||
|
|
||||||
ztest supports the following options:
|
'ztest' supports the following options:
|
||||||
|
|
||||||
'-O FORMAT'
|
'-O FORMAT'
|
||||||
'--force-format=FORMAT'
|
'--force-format=FORMAT'
|
||||||
|
@ -738,8 +796,8 @@ compressed file is corrupt or invalid.
|
||||||
|
|
||||||
'-v'
|
'-v'
|
||||||
'--verbose'
|
'--verbose'
|
||||||
Verbose mode. Show the verify status for each file processed.
|
Verbose mode. Show the verify status for each file processed. Further
|
||||||
Further -v's increase the verbosity level.
|
-v's increase the verbosity level. *Note version::.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -748,12 +806,12 @@ File: zutils.info, Node: Zupdate, Next: Problems, Prev: Ztest, Up: Top
|
||||||
9 Zupdate
|
9 Zupdate
|
||||||
*********
|
*********
|
||||||
|
|
||||||
zupdate recompresses files from bzip2, gzip, xz, and zstd formats to lzip
|
'zupdate' recompresses files from bzip2, gzip, xz, and zstd formats to lzip
|
||||||
format. Each original is compared with the new file and then deleted. Only
|
format. Each original is compared with the new file and then deleted. Only
|
||||||
regular files with standard file name extensions are recompressed, other
|
regular files with standard file name extensions are recompressed, other
|
||||||
files are ignored. Compressed files are decompressed and then recompressed
|
files are ignored. Compressed files are decompressed and then recompressed
|
||||||
on the fly; no temporary files are created. If an error happens while
|
on the fly; no temporary files are created. If an error happens while
|
||||||
recompressing a file, zupdate exits immediately without recompressing the
|
recompressing a file, 'zupdate' exits immediately without recompressing the
|
||||||
rest of the files. The lzip format is chosen as destination because it is
|
rest of the files. The lzip format is chosen as destination because it is
|
||||||
the most appropriate for long-term data archiving.
|
the most appropriate for long-term data archiving.
|
||||||
|
|
||||||
|
@ -763,7 +821,7 @@ directory, and nonrecursive searches do nothing.
|
||||||
If the lzip compressed version of a file already exists, the file is
|
If the lzip compressed version of a file already exists, the file is
|
||||||
skipped unless the option '--force' 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
|
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
|
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
|
safe and not cause any data loss. Therefore, existing lzip compressed files
|
||||||
are never overwritten nor deleted.
|
are never overwritten nor deleted.
|
||||||
|
|
||||||
|
@ -787,23 +845,40 @@ recompressing Slackware packages, for example.
|
||||||
If the decompressor for the xz or zstd formats is not found, the
|
If the decompressor for the xz or zstd formats is not found, the
|
||||||
corresponding files are ignored.
|
corresponding files are ignored.
|
||||||
|
|
||||||
Recompressing a file is much like copying or moving it. Therefore zupdate
|
Recompressing a file is much like copying or moving it. Therefore
|
||||||
preserves the access and modification dates, permissions, and, if you have
|
'zupdate' preserves the access and modification dates, permissions, and, if
|
||||||
appropriate privileges, ownership of the file just as 'cp -p' does. (If the
|
you have appropriate privileges, ownership of the file just as 'cp -p'
|
||||||
user ID or the group ID can't be duplicated, the file permission bits
|
does. (If the user ID or the group ID can't be duplicated, the file
|
||||||
S_ISUID and S_ISGID are cleared).
|
permission bits S_ISUID and S_ISGID are cleared).
|
||||||
|
|
||||||
The format for running zupdate is:
|
The format for running 'zupdate' is:
|
||||||
|
|
||||||
zupdate [OPTIONS] [FILES]
|
zupdate [OPTIONS] [FILES]
|
||||||
|
|
||||||
Exit status is 0 if all the compressed files were successfully recompressed
|
Exit status is 0 if all the compressed files were successfully recompressed
|
||||||
(if needed), compared, and deleted (if requested). 1 if a non-fatal error
|
(if needed), compared, and deleted (if requested). 1 if a non-fatal error
|
||||||
occurred (file not found or not regular, or has invalid format, or can't be
|
occurred (file not found or not regular, or has invalid format, or can't be
|
||||||
deleted). 2 if a fatal error occurred (compressor can't be run, or
|
deleted). 2 if a fatal error occurred (invalid command line options,
|
||||||
comparison fails).
|
compressor can't be run, or comparison fails).
|
||||||
|
|
||||||
zupdate supports the following options:
|
'zupdate' supports the following options:
|
||||||
|
|
||||||
|
'-d DIR'
|
||||||
|
'--destdir=DIR'
|
||||||
|
Write recompressed files to another directory, using DIR as base
|
||||||
|
directory, instead of writing them in the same directory as the
|
||||||
|
original files. In recursive mode, this is done by replacing each
|
||||||
|
directory specified in the command line with DIR to produce the
|
||||||
|
recompressed file names. For example, 'zupdate -r -d DIR ../a'
|
||||||
|
recompresses a file named '../a/b/c.gz' to 'DIR/b/c.lz'. Regular files
|
||||||
|
specified in the command line are recompressed directly into DIR. For
|
||||||
|
example, 'zupdate -d DIR ../a/b/c.gz' writes the recompressed file to
|
||||||
|
'DIR/c.lz'.
|
||||||
|
|
||||||
|
This option allows recompressing files from a read-only file system to
|
||||||
|
another place without the need to copy or link them to the destination
|
||||||
|
directory first. (Remember to use option '--keep' when recompressing
|
||||||
|
read-only files to avoid warnings about files that can't be deleted).
|
||||||
|
|
||||||
'-e'
|
'-e'
|
||||||
'--expand-extensions'
|
'--expand-extensions'
|
||||||
|
@ -851,13 +926,26 @@ comparison fails).
|
||||||
'-v'
|
'-v'
|
||||||
'--verbose'
|
'--verbose'
|
||||||
Verbose mode. Show the files being processed. A second '-v' also shows
|
Verbose mode. Show the files being processed. A second '-v' also shows
|
||||||
the files being ignored.
|
the files being ignored and increases the verbosity level. *Note
|
||||||
|
version::.
|
||||||
|
|
||||||
'-0 .. -9'
|
'-0 .. -9'
|
||||||
Set the compression level of lzip. By default zupdate passes '-9' to
|
Set the compression level of lzip. By default 'zupdate' passes '-9' to
|
||||||
lzip. Custom compression options can be passed to lzip with the option
|
lzip. Custom compression options can be passed to lzip with the option
|
||||||
'--lz'. For example '--lz='lzip -9 -s64MiB''.
|
'--lz'. For example '--lz='lzip -9 -s64MiB''.
|
||||||
|
|
||||||
|
'--lz=COMMAND'
|
||||||
|
Set compression command. COMMAND may include arguments. For example
|
||||||
|
'--lz='plzip --threads=2''. The name of the program can't begin with
|
||||||
|
'-'. This option overrides the value set in 'zutils.conf'. The
|
||||||
|
compression program used does not need to implement decompression
|
||||||
|
(*note compressor-requirements::), but it must implement at least the
|
||||||
|
compression level option '-9' and the option '-o FILE' to write the
|
||||||
|
compressed output to FILE. tarlz meets these requirements, and
|
||||||
|
therefore can be used to recompress POSIX tar archives by using a
|
||||||
|
command like 'zupdate --lz='tarlz -9 -z --no-solid' archive.tar.gz'.
|
||||||
|
*Note tarlz manual: (tarlz)Top.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File: zutils.info, Node: Problems, Next: Concept index, Prev: Zupdate, Up: Top
|
File: zutils.info, Node: Problems, Next: Concept index, Prev: Zupdate, Up: Top
|
||||||
|
@ -893,24 +981,26 @@ Concept index
|
||||||
* zgrep: Zgrep. (line 6)
|
* zgrep: Zgrep. (line 6)
|
||||||
* ztest: Ztest. (line 6)
|
* ztest: Ztest. (line 6)
|
||||||
* zupdate: Zupdate. (line 6)
|
* zupdate: Zupdate. (line 6)
|
||||||
* zutilsrc: The zutilsrc file. (line 6)
|
* zutils.conf: Configuration. (line 6)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Tag Table:
|
Tag Table:
|
||||||
Node: Top217
|
Node: Top217
|
||||||
Node: Introduction1150
|
Node: Introduction1156
|
||||||
Node: Common options3897
|
Node: Common options4003
|
||||||
Ref: compressor-requirements6134
|
Ref: version4489
|
||||||
Node: The zutilsrc file6529
|
Ref: compressor-requirements6440
|
||||||
Node: Zcat7497
|
Node: Configuration6835
|
||||||
Node: Zcmp10072
|
Node: Zcat7868
|
||||||
Node: Zdiff12573
|
Node: Zcmp10568
|
||||||
Node: Zgrep15623
|
Node: Zdiff14825
|
||||||
Node: Ztest21115
|
Node: Zgrep18008
|
||||||
Node: Zupdate23681
|
Node: Ztest24116
|
||||||
Node: Problems28191
|
Node: Zupdate26915
|
||||||
Node: Concept index28725
|
Ref: lz-compressor32442
|
||||||
|
Node: Problems33143
|
||||||
|
Node: Concept index33677
|
||||||
|
|
||||||
End Tag Table
|
End Tag Table
|
||||||
|
|
||||||
|
|
424
doc/zutils.texi
424
doc/zutils.texi
|
@ -6,8 +6,8 @@
|
||||||
@finalout
|
@finalout
|
||||||
@c %**end of header
|
@c %**end of header
|
||||||
|
|
||||||
@set UPDATED 12 April 2022
|
@set UPDATED 5 December 2022
|
||||||
@set VERSION 1.12-pre2
|
@set VERSION 1.12-rc1
|
||||||
|
|
||||||
@dircategory Compression
|
@dircategory Compression
|
||||||
@direntry
|
@direntry
|
||||||
|
@ -38,7 +38,7 @@ This manual is for Zutils (version @value{VERSION}, @value{UPDATED}).
|
||||||
@menu
|
@menu
|
||||||
* Introduction:: Purpose and features of zutils
|
* Introduction:: Purpose and features of zutils
|
||||||
* Common options:: Options common to all utilities
|
* Common options:: Options common to all utilities
|
||||||
* The zutilsrc file:: The zutils configuration file
|
* Configuration:: The configuration file zutils.conf
|
||||||
* Zcat:: Concatenating compressed files
|
* Zcat:: Concatenating compressed files
|
||||||
* Zcmp:: Comparing compressed files byte by byte
|
* Zcmp:: Comparing compressed files byte by byte
|
||||||
* Zdiff:: Comparing compressed files line by line
|
* Zdiff:: Comparing compressed files line by line
|
||||||
|
@ -66,21 +66,25 @@ is a collection of utilities able to process any combination of
|
||||||
compressed and uncompressed files transparently. If any file given,
|
compressed and uncompressed files transparently. If any file given,
|
||||||
including standard input, is compressed, its decompressed content is used.
|
including standard input, is compressed, its decompressed content is used.
|
||||||
Compressed files are decompressed on the fly; no temporary files are
|
Compressed files are decompressed on the fly; no temporary files are
|
||||||
created.
|
created. Data format is detected by its magic bytes, not by the file name
|
||||||
|
extension.
|
||||||
|
|
||||||
These utilities are not wrapper scripts but safer and more efficient C++
|
These utilities are not wrapper scripts but safer and more efficient C++
|
||||||
programs. In particular the option @samp{--recursive} is very efficient in
|
programs. In particular the option @option{--recursive} is very efficient in
|
||||||
those utilities supporting it.
|
those utilities supporting it.
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest, and zupdate.@*
|
The utilities provided are @command{zcat}, @command{zcmp}, @command{zdiff},
|
||||||
The formats supported are bzip2, gzip, lzip, xz, and zstd.@*
|
@command{zgrep}, @command{ztest}, and @command{zupdate}.@*
|
||||||
|
The formats supported are bzip2, gzip,
|
||||||
|
@uref{http://www.nongnu.org/lzip/lzip.html,,lzip}, xz, and zstd.@*
|
||||||
Zutils uses external compressors. The compressor to be used for each format
|
Zutils uses external compressors. The compressor to be used for each format
|
||||||
is configurable at runtime.
|
is configurable at runtime.
|
||||||
|
|
||||||
zcat, zcmp, zdiff, and zgrep are improved replacements for the shell scripts
|
@command{zcat}, @command{zcmp}, @command{zdiff}, and @command{zgrep} are
|
||||||
provided by GNU gzip. ztest is unique to zutils. zupdate is similar to
|
improved replacements for the shell scripts provided by GNU gzip.
|
||||||
gzip's znew.
|
@command{ztest} is unique to zutils. @command{zupdate} is similar to gzip's
|
||||||
|
znew.
|
||||||
|
|
||||||
NOTE: Bzip2 and lzip provide well-defined values of exit status, which makes
|
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
|
them safe to use with zutils. Gzip and xz may return ambiguous warning
|
||||||
|
@ -88,7 +92,7 @@ values, making them less reliable back ends for zutils. Zstd currently does
|
||||||
not even document its exit status in its man page.
|
not even document its exit status in its man page.
|
||||||
@xref{compressor-requirements}.
|
@xref{compressor-requirements}.
|
||||||
|
|
||||||
FORMAT NOTE 1: The option @samp{--format} allows the processing of a subset
|
FORMAT NOTE 1: The option @option{--format} allows the processing of a subset
|
||||||
of formats in recursive mode and when trying compressed file names. For
|
of formats in recursive mode and when trying compressed file names. For
|
||||||
example, use the following command to search for the string @samp{foo} in
|
example, use the following command to search for the string @samp{foo} in
|
||||||
gzip and lzip files only:
|
gzip and lzip files only:
|
||||||
|
@ -136,15 +140,19 @@ descriptions for each of the programs, they are described here.
|
||||||
@table @code
|
@table @code
|
||||||
@item -h
|
@item -h
|
||||||
@itemx --help
|
@itemx --help
|
||||||
Print an informative help message describing the options and exit. zgrep
|
Print an informative help message describing the options and exit.
|
||||||
only supports the @samp{--help} form of this option.
|
@command{zgrep} only supports the @option{--help} form of this option.
|
||||||
|
|
||||||
|
@anchor{version}
|
||||||
@item -V
|
@item -V
|
||||||
@itemx --version
|
@itemx --version
|
||||||
Print the version number on the standard output and exit.
|
Print the version number on the standard output and exit.
|
||||||
This version number should be included in all bug reports.
|
This version number should be included in all bug reports.
|
||||||
In verbose mode, zdiff and zgrep print also the version of the diff or grep
|
In verbose mode, @command{zdiff} and @command{zgrep} print also the version
|
||||||
program used respectively.
|
of the diff or grep program used respectively. At verbosity level 1 (2 for
|
||||||
|
@command{zdiff} and @command{zgrep}) or higher, print also the versions of
|
||||||
|
the compressors used (perhaps limited by option @option{--format}). (The
|
||||||
|
compressors used must support the option @option{-V} for this to work).
|
||||||
|
|
||||||
@item -M @var{format_list}
|
@item -M @var{format_list}
|
||||||
@itemx --format=@var{format_list}
|
@itemx --format=@var{format_list}
|
||||||
|
@ -171,29 +179,29 @@ extensions:
|
||||||
|
|
||||||
@item -N
|
@item -N
|
||||||
@itemx --no-rcfile
|
@itemx --no-rcfile
|
||||||
Don't read the runtime configuration file @samp{zutilsrc}.
|
Don't read the runtime configuration file @file{zutils.conf}.
|
||||||
|
|
||||||
@item --bz2=@var{command}
|
@item --bz2=@var{command}
|
||||||
@itemx --gz=@var{command}
|
@itemx --gz=@var{command}
|
||||||
@itemx --lz=@var{command}
|
@itemx --lz=@var{command}
|
||||||
@itemx --xz=@var{command}
|
@itemx --xz=@var{command}
|
||||||
@itemx --zst=@var{command}
|
@itemx --zst=@var{command}
|
||||||
Set program to be used as (de)compressor for the corresponding format.
|
Set program to be used as decompressor for the corresponding format.
|
||||||
@var{command} may include arguments. For example
|
@var{command} may include arguments. For example
|
||||||
@w{@samp{--lz='plzip --threads=2'}}. The program set with @samp{--lz} is
|
@w{@option{--lz='plzip --threads=2'}}. @command{zupdate} uses @option{--lz}
|
||||||
used for both compression and decompression. The others are used only for
|
for compression, not for decompression (@pxref{lz-compressor}). The name of
|
||||||
decompression. The name of the program can't begin with @samp{-}. These
|
the program can't begin with @samp{-}. These options override the values set
|
||||||
options override the values set in @file{zutilsrc}. The compression program
|
in @file{zutils.conf}. The compression program used must meet three
|
||||||
used must meet three requirements:
|
requirements:
|
||||||
|
|
||||||
@anchor{compressor-requirements}
|
@anchor{compressor-requirements}
|
||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
When called with the option @samp{-d} and without file names, it must read
|
When called with the option @option{-d} and without file names, it must read
|
||||||
compressed data from the standard input and produce decompressed data on the
|
compressed data from the standard input and produce decompressed data on the
|
||||||
standard output.
|
standard output.
|
||||||
@item
|
@item
|
||||||
If the option @samp{-q} is passed to zutils, the compression program must
|
If the option @option{-q} is passed to zutils, the compression program must
|
||||||
also accept it.
|
also accept it.
|
||||||
@item
|
@item
|
||||||
It must return 0 if no errors occurred, and a non-zero value otherwise.
|
It must return 0 if no errors occurred, and a non-zero value otherwise.
|
||||||
|
@ -202,21 +210,22 @@ It must return 0 if no errors occurred, and a non-zero value otherwise.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
@node The zutilsrc file
|
@node Configuration
|
||||||
@chapter The zutils configuration file 'zutilsrc'
|
@chapter The configuration file 'zutils.conf'
|
||||||
@cindex zutilsrc
|
@cindex zutils.conf
|
||||||
|
|
||||||
@file{zutilsrc} is the runtime configuration file for zutils. In it you
|
@file{zutils.conf} is the runtime configuration file for zutils. In it you
|
||||||
may define the compressor name and options to be used for each format.
|
may define the compressor name and options to be used for each format.
|
||||||
@file{zutilsrc} is optional; you don't need to install it in order to run
|
@file{zutils.conf} is optional; you don't need to install it in order to run
|
||||||
zutils.
|
zutils.
|
||||||
|
|
||||||
The compressors specified in the command line override those specified
|
The compressors specified in the command line override those specified
|
||||||
in @file{zutilsrc}.
|
in @file{zutils.conf}.
|
||||||
|
|
||||||
You may copy the system @file{zutilsrc} file @file{$@{sysconfdir@}/zutilsrc}
|
You may copy the system @file{zutils.conf} file @file{$@{sysconfdir@}/zutils.conf}
|
||||||
to @file{$HOME/.zutilsrc} and customize these options as you like. The file
|
to @file{$XDG_CONFIG_HOME/zutils.conf} and customize these options as you like.
|
||||||
syntax is fairly obvious (and there are further instructions in it):
|
(@env{XDG_CONFIG_HOME} defaults to @file{$HOME/.config}). The file syntax is
|
||||||
|
fairly obvious (and there are further instructions in it):
|
||||||
|
|
||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
|
@ -236,12 +245,12 @@ where <format> is one of @samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, or
|
||||||
@chapter Zcat
|
@chapter Zcat
|
||||||
@cindex zcat
|
@cindex zcat
|
||||||
|
|
||||||
zcat copies each @var{file} argument to standard output in sequence. If any
|
@command{zcat} copies each @var{file} argument to standard output in
|
||||||
file given is compressed, its decompressed content is copied. If a file
|
sequence. If any file given is compressed, its decompressed content is
|
||||||
given does not exist, and its name does not end with one of the known
|
copied. If a file given does not exist, and its name does not end with one
|
||||||
extensions, zcat tries the compressed file names corresponding to the
|
of the known extensions, @command{zcat} tries the compressed file names
|
||||||
formats supported. If a file fails to decompress, zcat continues copying the
|
corresponding to the formats supported. If a file fails to decompress,
|
||||||
rest of the files.
|
@command{zcat} continues copying the rest of the files.
|
||||||
|
|
||||||
If a file is specified as @samp{-}, data are read from standard input,
|
If a file is specified as @samp{-}, data are read from standard input,
|
||||||
decompressed if needed, and sent to standard output. Data read from
|
decompressed if needed, and sent to standard output. Data read from
|
||||||
|
@ -251,7 +260,7 @@ same compressed format.
|
||||||
If no files are specified, recursive searches examine the current working
|
If no files are specified, recursive searches examine the current working
|
||||||
directory, and nonrecursive searches read standard input.
|
directory, and nonrecursive searches read standard input.
|
||||||
|
|
||||||
The format for running zcat is:
|
The format for running @command{zcat} is:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
zcat [@var{options}] [@var{files}]
|
zcat [@var{options}] [@var{files}]
|
||||||
|
@ -260,12 +269,12 @@ zcat [@var{options}] [@var{files}]
|
||||||
@noindent
|
@noindent
|
||||||
Exit status is 0 if no errors occurred, 1 otherwise.
|
Exit status is 0 if no errors occurred, 1 otherwise.
|
||||||
|
|
||||||
zcat supports the following options:
|
@command{zcat} supports the following options:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item -A
|
@item -A
|
||||||
@itemx --show-all
|
@itemx --show-all
|
||||||
Equivalent to @samp{-vET}.
|
Equivalent to @option{-vET}.
|
||||||
|
|
||||||
@item -b
|
@item -b
|
||||||
@itemx --number-nonblank
|
@itemx --number-nonblank
|
||||||
|
@ -273,7 +282,7 @@ Number all nonblank output lines, starting with 1. The line count is
|
||||||
unlimited.
|
unlimited.
|
||||||
|
|
||||||
@item -e
|
@item -e
|
||||||
Equivalent to @samp{-vE}.
|
Equivalent to @option{-vE}.
|
||||||
|
|
||||||
@item -E
|
@item -E
|
||||||
@itemx --show-ends
|
@itemx --show-ends
|
||||||
|
@ -286,10 +295,11 @@ Number all output lines, starting with 1. The line count is unlimited.
|
||||||
@item -O @var{format}
|
@item -O @var{format}
|
||||||
@itemx --force-format=@var{format}
|
@itemx --force-format=@var{format}
|
||||||
Force the compressed format given. Valid values for @var{format} are
|
Force the compressed format given. Valid values for @var{format} are
|
||||||
@samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, and @samp{zst}. If this option
|
@samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, @samp{zst}, and @samp{un} for
|
||||||
is used, the files are passed to the corresponding decompressor without
|
@samp{uncompressed}. If this option is used, the files are passed to the
|
||||||
verifying their format, and the exact file name must be given. Other names
|
corresponding decompressor (or transmitted unmodified) without verifying
|
||||||
won't be tried.
|
their format, and the exact file name must be given. Other names won't be
|
||||||
|
tried.
|
||||||
|
|
||||||
@item -q
|
@item -q
|
||||||
@itemx --quiet
|
@itemx --quiet
|
||||||
|
@ -311,7 +321,7 @@ recursively, following all symbolic links.
|
||||||
Replace multiple adjacent blank lines with a single blank line.
|
Replace multiple adjacent blank lines with a single blank line.
|
||||||
|
|
||||||
@item -t
|
@item -t
|
||||||
Equivalent to @samp{-vT}.
|
Equivalent to @option{-vT}.
|
||||||
|
|
||||||
@item -T
|
@item -T
|
||||||
@itemx --show-tabs
|
@itemx --show-tabs
|
||||||
|
@ -324,7 +334,8 @@ notation and precede characters larger than 127 with @samp{M-} (which
|
||||||
stands for "meta").
|
stands for "meta").
|
||||||
|
|
||||||
@item --verbose
|
@item --verbose
|
||||||
Verbose mode. Show error messages.
|
Verbose mode. Show error messages. Repeating it increases the verbosity
|
||||||
|
level. @xref{version}.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@ -333,14 +344,14 @@ Verbose mode. Show error messages.
|
||||||
@chapter Zcmp
|
@chapter Zcmp
|
||||||
@cindex zcmp
|
@cindex zcmp
|
||||||
|
|
||||||
zcmp compares two files and, if they differ, writes to standard output the
|
@command{zcmp} compares two files and, if they differ, writes to standard
|
||||||
first byte and line number where they differ. Bytes and lines are numbered
|
output the first byte and line number where they differ. Bytes and lines are
|
||||||
starting with 1. A hyphen @samp{-} used as a @var{file} argument means
|
numbered starting with 1. A hyphen @samp{-} used as a @var{file} argument
|
||||||
standard input. If any file given is compressed, its decompressed content is
|
means standard input. If any file given is compressed, its decompressed
|
||||||
used. Compressed files are decompressed on the fly; no temporary files are
|
content is used. Compressed files are decompressed on the fly; no temporary
|
||||||
created.
|
files are created.
|
||||||
|
|
||||||
The format for running zcmp is:
|
The format for running @command{zcmp} is:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
zcmp [@var{options}] @var{file1} [@var{file2}]
|
zcmp [@var{options}] @var{file1} [@var{file2}]
|
||||||
|
@ -349,7 +360,7 @@ zcmp [@var{options}] @var{file1} [@var{file2}]
|
||||||
@noindent
|
@noindent
|
||||||
This compares @var{file1} to @var{file2}. The standard input is used only if
|
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
|
@var{file1} or @var{file2} refers to standard input. If @var{file2} is
|
||||||
omitted zcmp tries the following:
|
omitted @command{zcmp} tries the following:
|
||||||
|
|
||||||
@itemize -
|
@itemize -
|
||||||
@item
|
@item
|
||||||
|
@ -365,14 +376,19 @@ contents of @var{file1}.[lz|bz2|gz|zst|xz] (the first one that is found).
|
||||||
An exit status of 0 means no differences were found, 1 means some
|
An exit status of 0 means no differences were found, 1 means some
|
||||||
differences were found, and 2 means trouble.
|
differences were found, and 2 means trouble.
|
||||||
|
|
||||||
zcmp supports the following options:
|
@command{zcmp} supports the following options:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item -b
|
@item -b
|
||||||
@itemx --print-bytes
|
@itemx --print-bytes
|
||||||
Print the differing bytes. Print control bytes as a @samp{^} followed by
|
Print the values of the differing bytes (in octal by default) followed by
|
||||||
a letter, and precede bytes larger than 127 with @samp{M-} (which stands
|
the bytes themselves in printable form. Print control bytes as a @samp{^}
|
||||||
for "meta").
|
followed by a letter, and precede bytes larger than 127 with @samp{M-}
|
||||||
|
(which stands for "meta").
|
||||||
|
|
||||||
|
@item -H
|
||||||
|
@itemx --hexadecimal
|
||||||
|
Print the values of the differing bytes in hexadecimal instead of octal.
|
||||||
|
|
||||||
@item -i @var{size}
|
@item -i @var{size}
|
||||||
@itemx --ignore-initial=@var{size}
|
@itemx --ignore-initial=@var{size}
|
||||||
|
@ -383,11 +399,9 @@ first @var{size1} bytes of the first input file and the first
|
||||||
@var{size2} bytes of the second input file.
|
@var{size2} bytes of the second input file.
|
||||||
|
|
||||||
@item -l
|
@item -l
|
||||||
@itemx -v
|
|
||||||
@itemx --list
|
@itemx --list
|
||||||
@itemx --verbose
|
Print the byte numbers (in decimal) and values (in octal by default) of all
|
||||||
Print the byte numbers (in decimal) and values (in octal) of all
|
differing bytes. Bytes are numbered starting with 1.
|
||||||
differing bytes.
|
|
||||||
|
|
||||||
@item -n @var{count}
|
@item -n @var{count}
|
||||||
@itemx --bytes=@var{count}
|
@itemx --bytes=@var{count}
|
||||||
|
@ -398,33 +412,66 @@ Compare at most @var{count} input bytes.
|
||||||
Force the compressed formats given. Any of @var{format1} or @var{format2}
|
Force the compressed formats given. Any of @var{format1} or @var{format2}
|
||||||
may be omitted and the corresponding format will be automatically detected.
|
may be omitted and the corresponding format will be automatically detected.
|
||||||
Valid values for @var{format} are @samp{bz2}, @samp{gz}, @samp{lz},
|
Valid values for @var{format} are @samp{bz2}, @samp{gz}, @samp{lz},
|
||||||
@samp{xz}, and @samp{zst}. If at least one format is specified with this
|
@samp{xz}, @samp{zst}, and @samp{un} for @samp{uncompressed}. If at least
|
||||||
option, the file is passed to the corresponding decompressor without
|
one format is specified with this option, the file is passed to the
|
||||||
verifying its format, and the exact file names of both @var{file1} and
|
corresponding decompressor (or transmitted unmodified) without verifying its
|
||||||
@var{file2} must be given. Other names won't be tried.
|
format, and the exact file names of both @var{file1} and @var{file2} must be
|
||||||
|
given. Other names won't be tried.
|
||||||
|
|
||||||
@item -q
|
@item -q
|
||||||
@itemx -s
|
|
||||||
@itemx --quiet
|
@itemx --quiet
|
||||||
@itemx --silent
|
@itemx --silent
|
||||||
Don't print anything; only return an exit status indicating whether the
|
Suppress diagnostics written to standard error, even the
|
||||||
files differ.
|
@w{@samp{EOF on <name_of_shorter_file>}} diagnostic. Byte differences are
|
||||||
|
still written to standard output. (@option{-q} produces no output except
|
||||||
|
byte differences).
|
||||||
|
|
||||||
|
@item -s
|
||||||
|
@itemx --script
|
||||||
|
Write nothing to standard output or standard error when files differ, not
|
||||||
|
even the @w{@samp{EOF on <name_of_shorter_file>}} diagnostic; indicate
|
||||||
|
differing files through exit status only. Diagnostic messages are still
|
||||||
|
written to standard error when an error is encountered. (@option{-s}
|
||||||
|
produces no output except error messages).
|
||||||
|
|
||||||
|
@item -v
|
||||||
|
@itemx --verbose
|
||||||
|
Verbose mode. Undoes the effect of @option{--quiet}. Further -v's increase
|
||||||
|
the verbosity level. @xref{version}.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
Byte counts given as arguments to options may be expressed in decimal,
|
||||||
|
hexadecimal, or octal (using the same syntax as integer constants in C++),
|
||||||
|
and may be followed by a multiplier and an optional @samp{B} for "byte".
|
||||||
|
|
||||||
|
Table of SI and binary prefixes (unit multipliers):
|
||||||
|
|
||||||
|
@multitable {Prefix} {kilobyte (10^3 = 1000)} {|} {Prefix} {kibibyte (2^10 = 1024)}
|
||||||
|
@item Prefix @tab Value @tab | @tab Prefix @tab Value
|
||||||
|
@item k @tab kilobyte (10^3 = 1000) @tab | @tab Ki @tab kibibyte (2^10 = 1024)
|
||||||
|
@item M @tab megabyte (10^6) @tab | @tab Mi @tab mebibyte (2^20)
|
||||||
|
@item G @tab gigabyte (10^9) @tab | @tab Gi @tab gibibyte (2^30)
|
||||||
|
@item T @tab terabyte (10^12) @tab | @tab Ti @tab tebibyte (2^40)
|
||||||
|
@item P @tab petabyte (10^15) @tab | @tab Pi @tab pebibyte (2^50)
|
||||||
|
@item E @tab exabyte (10^18) @tab | @tab Ei @tab exbibyte (2^60)
|
||||||
|
@item Z @tab zettabyte (10^21) @tab | @tab Zi @tab zebibyte (2^70)
|
||||||
|
@item Y @tab yottabyte (10^24) @tab | @tab Yi @tab yobibyte (2^80)
|
||||||
|
@end multitable
|
||||||
|
|
||||||
|
|
||||||
@node Zdiff
|
@node Zdiff
|
||||||
@chapter Zdiff
|
@chapter Zdiff
|
||||||
@cindex zdiff
|
@cindex zdiff
|
||||||
|
|
||||||
zdiff compares two files and, if they differ, writes to standard output the
|
@command{zdiff} compares two files and, if they differ, writes to standard
|
||||||
differences line by line. A hyphen @samp{-} used as a @var{file} argument
|
output the differences line by line. A hyphen @samp{-} used as a @var{file}
|
||||||
means standard input. If any file given is compressed, its decompressed
|
argument means standard input. If any file given is compressed, its
|
||||||
content is used. zdiff is a front end to the program diff and has the
|
decompressed content is used. @command{zdiff} is a front end to the program
|
||||||
limitation that messages from diff refer to temporary file names instead of
|
diff and has the limitation that messages from diff refer to temporary file
|
||||||
those specified.
|
names instead of those specified.
|
||||||
|
|
||||||
The format for running zdiff is:
|
The format for running @command{zdiff} is:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
zdiff [@var{options}] @var{file1} [@var{file2}]
|
zdiff [@var{options}] @var{file1} [@var{file2}]
|
||||||
|
@ -433,7 +480,7 @@ zdiff [@var{options}] @var{file1} [@var{file2}]
|
||||||
@noindent
|
@noindent
|
||||||
This compares @var{file1} to @var{file2}. The standard input is used only if
|
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
|
@var{file1} or @var{file2} refers to standard input. If @var{file2} is
|
||||||
omitted zdiff tries the following:
|
omitted @command{zdiff} tries the following:
|
||||||
|
|
||||||
@itemize -
|
@itemize -
|
||||||
@item
|
@item
|
||||||
|
@ -449,8 +496,8 @@ contents of @var{file1}.[lz|bz2|gz|zst|xz] (the first one that is found).
|
||||||
An exit status of 0 means no differences were found, 1 means some
|
An exit status of 0 means no differences were found, 1 means some
|
||||||
differences were found, and 2 means trouble.
|
differences were found, and 2 means trouble.
|
||||||
|
|
||||||
zdiff supports the following options (some options only work if the diff
|
@command{zdiff} supports the following options (some options only work if
|
||||||
program used supports them):
|
the diff program used supports them):
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item -a
|
@item -a
|
||||||
|
@ -465,7 +512,7 @@ Ignore changes in the amount of white space.
|
||||||
@itemx --ignore-blank-lines
|
@itemx --ignore-blank-lines
|
||||||
Ignore changes whose lines are all blank.
|
Ignore changes whose lines are all blank.
|
||||||
|
|
||||||
@itemx -c
|
@item -c
|
||||||
Use the context output format.
|
Use the context output format.
|
||||||
|
|
||||||
@item -C @var{n}
|
@item -C @var{n}
|
||||||
|
@ -489,10 +536,11 @@ Ignore case differences in file contents.
|
||||||
Force the compressed formats given. Any of @var{format1} or @var{format2}
|
Force the compressed formats given. Any of @var{format1} or @var{format2}
|
||||||
may be omitted and the corresponding format will be automatically detected.
|
may be omitted and the corresponding format will be automatically detected.
|
||||||
Valid values for @var{format} are @samp{bz2}, @samp{gz}, @samp{lz},
|
Valid values for @var{format} are @samp{bz2}, @samp{gz}, @samp{lz},
|
||||||
@samp{xz}, and @samp{zst}. If at least one format is specified with this
|
@samp{xz}, @samp{zst}, and @samp{un} for @samp{uncompressed}. If at least
|
||||||
option, the file is passed to the corresponding decompressor without
|
one format is specified with this option, the file is passed to the
|
||||||
verifying its format, and the exact file names of both @var{file1} and
|
corresponding decompressor (or transmitted unmodified) without verifying its
|
||||||
@var{file2} must be given. Other names won't be tried.
|
format, and the exact file names of both @var{file1} and @var{file2} must be
|
||||||
|
given. Other names won't be tried.
|
||||||
|
|
||||||
@item -p
|
@item -p
|
||||||
@itemx --show-c-function
|
@itemx --show-c-function
|
||||||
|
@ -523,8 +571,8 @@ Same as -u but use @var{n} lines of context.
|
||||||
|
|
||||||
@item -v
|
@item -v
|
||||||
@itemx --verbose
|
@itemx --verbose
|
||||||
When specified before @samp{--version}, print the version of the diff
|
When specified before @option{--version}, print the version of the diff
|
||||||
program used.
|
program used. Further -v's increase the verbosity level. @xref{version}.
|
||||||
|
|
||||||
@item -w
|
@item -w
|
||||||
@itemx --ignore-all-space
|
@itemx --ignore-all-space
|
||||||
|
@ -546,12 +594,12 @@ Use the side by side output format.
|
||||||
@chapter Zgrep
|
@chapter Zgrep
|
||||||
@cindex zgrep
|
@cindex zgrep
|
||||||
|
|
||||||
zgrep is a front end to the program grep that allows transparent search
|
@command{zgrep} is a front end to the program grep that allows transparent
|
||||||
on any combination of compressed and uncompressed files. If any file
|
search on any combination of compressed and uncompressed files. If any file
|
||||||
given is compressed, its decompressed content is used. If a file given
|
given is compressed, its decompressed content is used. If a file given does
|
||||||
does not exist, and its name does not end with one of the known
|
not exist, and its name does not end with one of the known extensions,
|
||||||
extensions, zgrep tries the compressed file names corresponding to the
|
@command{zgrep} tries the compressed file names corresponding to the formats
|
||||||
formats supported. If a file fails to decompress, zgrep continues
|
supported. If a file fails to decompress, @command{zgrep} continues
|
||||||
searching the rest of the files.
|
searching the rest of the files.
|
||||||
|
|
||||||
If a file is specified as @samp{-}, data are read from standard input,
|
If a file is specified as @samp{-}, data are read from standard input,
|
||||||
|
@ -562,7 +610,14 @@ compressed format.
|
||||||
If no files are specified, recursive searches examine the current working
|
If no files are specified, recursive searches examine the current working
|
||||||
directory, and nonrecursive searches read standard input.
|
directory, and nonrecursive searches read standard input.
|
||||||
|
|
||||||
The format for running zgrep is:
|
For efficiency reasons, @command{zgrep} does not always read all its input.
|
||||||
|
For example, the shell command @w{@samp{base64 -d foo | zgrep -q X}} can
|
||||||
|
cause @command{zgrep} to exit immediately after reading a line containing
|
||||||
|
@samp{X}, without bothering to read the rest of its input data. This in turn
|
||||||
|
can cause base64 to exit with a nonzero status because base64 cannot write
|
||||||
|
to its output pipe after @command{zgrep} exits.
|
||||||
|
|
||||||
|
The format for running @command{zgrep} is:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
zgrep [@var{options}] @var{pattern} [@var{files}]
|
zgrep [@var{options}] @var{pattern} [@var{files}]
|
||||||
|
@ -572,9 +627,9 @@ zgrep [@var{options}] @var{pattern} [@var{files}]
|
||||||
An exit status of 0 means at least one match was found, 1 means no
|
An exit status of 0 means at least one match was found, 1 means no
|
||||||
matches were found, and 2 means trouble.
|
matches were found, and 2 means trouble.
|
||||||
|
|
||||||
zgrep supports the following options (Some options only work if the grep
|
@command{zgrep} supports the following options (Some options only work if
|
||||||
program used supports them. Options -h, -H, -r, -R, and -Z are managed by
|
the grep program used supports them. Options -h, -H, -r, -R, and -Z are
|
||||||
zgrep and not passed to grep):
|
managed by @command{zgrep} and not passed to grep):
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item -a
|
@item -a
|
||||||
|
@ -616,9 +671,9 @@ Interpret @var{pattern} as an extended regular expression (ERE).
|
||||||
@item -f @var{file}
|
@item -f @var{file}
|
||||||
@itemx --file=@var{file}
|
@itemx --file=@var{file}
|
||||||
Obtain patterns from @var{file}, one per line.@*
|
Obtain patterns from @var{file}, one per line.@*
|
||||||
When searching in several files at once, command substitution can be
|
When searching in several files at once, command substitution can be used
|
||||||
used with @samp{-e} to read @var{file} only once, for example if
|
with @option{-e} to read @var{file} only once, for example if @var{file} is
|
||||||
@var{file} is not a regular file:
|
not a regular file:
|
||||||
@w{@samp{zgrep -e "$(cat @var{file})" file1.lz file2.gz}}
|
@w{@samp{zgrep -e "$(cat @var{file})" file1.lz file2.gz}}
|
||||||
|
|
||||||
@item -F
|
@item -F
|
||||||
|
@ -648,11 +703,13 @@ Ignore binary files.
|
||||||
|
|
||||||
@item -l
|
@item -l
|
||||||
@itemx --files-with-matches
|
@itemx --files-with-matches
|
||||||
Only print names of files containing at least one match.
|
Only print names of files containing at least one match. Stop reading each
|
||||||
|
file on the first match.
|
||||||
|
|
||||||
@item -L
|
@item -L
|
||||||
@itemx --files-without-match
|
@itemx --files-without-match
|
||||||
Only print names of files not containing any matches.@*
|
Only print names of files not containing any matches. Stop reading each file
|
||||||
|
on the first match.@*
|
||||||
Note: option -L fails (prints wrong results, returns wrong status, and even
|
Note: option -L fails (prints wrong results, returns wrong status, and even
|
||||||
hangs) when using GNU grep versions 3.2 to 3.4 inclusive because of a wrong
|
hangs) when using GNU grep versions 3.2 to 3.4 inclusive because of a wrong
|
||||||
change in the exit status of grep, which was reverted in GNU grep 3.5.
|
change in the exit status of grep, which was reverted in GNU grep 3.5.
|
||||||
|
@ -679,10 +736,11 @@ Show only the part of matching lines that actually matches @var{pattern}.
|
||||||
@item -O @var{format}
|
@item -O @var{format}
|
||||||
@itemx --force-format=@var{format}
|
@itemx --force-format=@var{format}
|
||||||
Force the compressed format given. Valid values for @var{format} are
|
Force the compressed format given. Valid values for @var{format} are
|
||||||
@samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, and @samp{zst}. If this option
|
@samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, @samp{zst}, and @samp{un} for
|
||||||
is used, the files are passed to the corresponding decompressor without
|
@samp{uncompressed}. If this option is used, the files are passed to the
|
||||||
verifying their format, and the exact file name must be given. Other names
|
corresponding decompressor (or transmitted unmodified) without verifying
|
||||||
won't be tried.
|
their format, and the exact file name must be given. Other names won't be
|
||||||
|
tried.
|
||||||
|
|
||||||
@item -P
|
@item -P
|
||||||
@itemx --perl-regexp
|
@itemx --perl-regexp
|
||||||
|
@ -724,8 +782,9 @@ Use binary I/O on platforms affected by the bug known as "text mode I/O".
|
||||||
Select non-matching lines.
|
Select non-matching lines.
|
||||||
|
|
||||||
@item --verbose
|
@item --verbose
|
||||||
Verbose mode. Show error messages. When specified before @samp{--version},
|
Verbose mode. Show error messages. When specified before @option{--version},
|
||||||
print the version of the grep program used.
|
print the version of the grep program used. Repeating it increases the
|
||||||
|
verbosity level. @xref{version}.
|
||||||
|
|
||||||
@item -w
|
@item -w
|
||||||
@itemx --word-regexp
|
@itemx --word-regexp
|
||||||
|
@ -738,10 +797,10 @@ Match only whole lines.
|
||||||
@item -Z
|
@item -Z
|
||||||
@itemx --null
|
@itemx --null
|
||||||
Output a zero byte (the ASCII NUL character) instead of the character that
|
Output a zero byte (the ASCII NUL character) instead of the character that
|
||||||
normally follows a file name. For example, 'zgrep -lZ' outputs a zero byte
|
normally follows a file name. For example, @w{@samp{zgrep -lZ}} outputs a
|
||||||
after each file name instead of the usual newline. This option makes the
|
zero byte after each file name instead of the usual newline. This option
|
||||||
output unambiguous, even in the presence of file names containing unusual
|
makes the output unambiguous, even in the presence of file names containing
|
||||||
characters like newlines.
|
unusual characters like newlines.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@ -750,14 +809,16 @@ characters like newlines.
|
||||||
@chapter Ztest
|
@chapter Ztest
|
||||||
@cindex ztest
|
@cindex ztest
|
||||||
|
|
||||||
ztest verifies the integrity of the compressed files specified.
|
@command{ztest} verifies the integrity of the compressed files specified. It
|
||||||
Uncompressed files are ignored. If a file is specified as @samp{-}, the
|
also warns if an uncompressed file has a compressed file name extension, or
|
||||||
integrity of compressed data read from standard input is verified. Data
|
if a compressed file has a wrong compressed extension. Uncompressed files
|
||||||
read from standard input must be all in the same compressed format. If
|
are otherwise ignored. If a file is specified as @samp{-}, the integrity of
|
||||||
a file fails to decompress, does not exist, can't be opened, or is a
|
compressed data read from standard input is verified. Data read from
|
||||||
terminal, ztest continues verifying the rest of the files. A final
|
standard input must be all in the same compressed format. If a file fails to
|
||||||
diagnostic is shown at verbosity level 1 or higher if any file fails the
|
decompress, does not exist, can't be opened, or is a terminal, @command{ztest}
|
||||||
test when testing multiple files.
|
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
|
If no files are specified, recursive searches examine the current working
|
||||||
directory, and nonrecursive searches read standard input.
|
directory, and nonrecursive searches read standard input.
|
||||||
|
@ -776,18 +837,19 @@ warning. Therefore, xz files can't always be verified as reliably as
|
||||||
files in the other formats can.
|
files in the other formats can.
|
||||||
@c We can only hope that xz is soon abandoned.
|
@c We can only hope that xz is soon abandoned.
|
||||||
|
|
||||||
The format for running ztest is:
|
The format for running @command{ztest} is:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
ztest [@var{options}] [@var{files}]
|
ztest [@var{options}] [@var{files}]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
The exit status is 0 if all compressed files verify OK, 1 if
|
Exit status is 0 if all compressed files verify OK, 1 if environmental
|
||||||
environmental problems (file not found, invalid flags, I/O errors, etc),
|
problems (file not found, invalid command line options, I/O errors, etc),
|
||||||
2 if any compressed file is corrupt or invalid.
|
2 if any compressed file is corrupt or invalid, or if any file has an
|
||||||
|
incorrect file name extension.
|
||||||
|
|
||||||
ztest supports the following options:
|
@command{ztest} supports the following options:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item -O @var{format}
|
@item -O @var{format}
|
||||||
|
@ -815,8 +877,8 @@ recursively, following all symbolic links.
|
||||||
|
|
||||||
@item -v
|
@item -v
|
||||||
@itemx --verbose
|
@itemx --verbose
|
||||||
Verbose mode. Show the verify status for each file processed.@*
|
Verbose mode. Show the verify status for each file processed. Further -v's
|
||||||
Further -v's increase the verbosity level.
|
increase the verbosity level. @xref{version}.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@ -825,30 +887,30 @@ Further -v's increase the verbosity level.
|
||||||
@chapter Zupdate
|
@chapter Zupdate
|
||||||
@cindex zupdate
|
@cindex zupdate
|
||||||
|
|
||||||
zupdate recompresses files from bzip2, gzip, xz, and zstd formats to lzip
|
@command{zupdate} recompresses files from bzip2, gzip, xz, and zstd formats
|
||||||
format. Each original is compared with the new file and then deleted. Only
|
to lzip format. Each original is compared with the new file and then
|
||||||
regular files with standard file name extensions are recompressed, other
|
deleted. Only regular files with standard file name extensions are
|
||||||
files are ignored. Compressed files are decompressed and then recompressed
|
recompressed, other files are ignored. Compressed files are decompressed and
|
||||||
on the fly; no temporary files are created. If an error happens while
|
then recompressed on the fly; no temporary files are created. If an error
|
||||||
recompressing a file, zupdate exits immediately without recompressing the
|
happens while recompressing a file, @command{zupdate} exits immediately
|
||||||
rest of the files. The lzip format is chosen as destination because it is
|
without recompressing the rest of the files. The lzip format is chosen as
|
||||||
the most appropriate for long-term data archiving.
|
destination because it is the most appropriate for long-term data archiving.
|
||||||
|
|
||||||
If no files are specified, recursive searches examine the current working
|
If no files are specified, recursive searches examine the current working
|
||||||
directory, and nonrecursive searches do nothing.
|
directory, and nonrecursive searches do nothing.
|
||||||
|
|
||||||
If the lzip compressed version of a file already exists, the file is
|
If the lzip compressed version of a file already exists, the file is skipped
|
||||||
skipped unless the option @samp{--force} is given. In this case, if the
|
unless the option @option{--force} is given. In this case, if the comparison
|
||||||
comparison with the existing lzip version fails, an error is returned
|
with the existing lzip version fails, an error is returned and the original
|
||||||
and the original file is not deleted. The operation of zupdate is meant
|
file is not deleted. The operation of @command{zupdate} is meant to be safe
|
||||||
to be safe and not cause any data loss. Therefore, existing lzip
|
and not cause any data loss. Therefore, existing lzip compressed files are
|
||||||
compressed files are never overwritten nor deleted.
|
never overwritten nor deleted.
|
||||||
|
|
||||||
Recompressing files from a read-only file system to another place can be
|
Recompressing files from a read-only file system to another place can be
|
||||||
done by first linking the files from the destination directory and then
|
done by first linking the files from the destination directory and then
|
||||||
compressing the links: @w{@samp{ln -s /src/foo.gz . && zupdate foo.gz}}
|
compressing the links: @w{@samp{ln -s /src/foo.gz . && zupdate foo.gz}}
|
||||||
|
|
||||||
Combining the options @samp{--force} and @samp{--keep}, as in
|
Combining the options @option{--force} and @option{--keep}, as in
|
||||||
@w{@samp{zupdate -f -k *.gz}}, verifies that there are no differences
|
@w{@samp{zupdate -f -k *.gz}}, verifies that there are no differences
|
||||||
between each pair of files in a multiformat set of files.
|
between each pair of files in a multiformat set of files.
|
||||||
|
|
||||||
|
@ -857,20 +919,20 @@ The names of the original files must have one of the following extensions:@*
|
||||||
recompressed to @samp{.lz};@*
|
recompressed to @samp{.lz};@*
|
||||||
@samp{.tbz}, @samp{.tbz2}, @samp{.tgz}, @samp{.txz}, or @samp{.tzst}, which
|
@samp{.tbz}, @samp{.tbz2}, @samp{.tgz}, @samp{.txz}, or @samp{.tzst}, which
|
||||||
are recompressed to @samp{.tlz}.@*
|
are recompressed to @samp{.tlz}.@*
|
||||||
Keeping the combined extensions (@samp{.tgz} --> @samp{.tlz}) may be useful
|
Keeping the combined extensions @w{(@samp{.tgz} --> @samp{.tlz})} may be
|
||||||
when recompressing Slackware packages, for example.
|
useful when recompressing Slackware packages, for example.
|
||||||
|
|
||||||
Bzip2, gzip, and lzip are the primary formats. Xz and zstd are optional. If
|
Bzip2, gzip, and lzip are the primary formats. Xz and zstd are optional. If
|
||||||
the decompressor for the xz or zstd formats is not found, the corresponding
|
the decompressor for the xz or zstd formats is not found, the corresponding
|
||||||
files are ignored.
|
files are ignored.
|
||||||
|
|
||||||
Recompressing a file is much like copying or moving it. Therefore zupdate
|
Recompressing a file is much like copying or moving it. Therefore
|
||||||
preserves the access and modification dates, permissions, and, if you have
|
@command{zupdate} preserves the access and modification dates, permissions,
|
||||||
appropriate privileges, ownership of the file just as @w{@samp{cp -p}} does.
|
and, if you have appropriate privileges, ownership of the file just as
|
||||||
(If the user ID or the group ID can't be duplicated, the file permission
|
@w{@samp{cp -p}} does. (If the user ID or the group ID can't be duplicated,
|
||||||
bits S_ISUID and S_ISGID are cleared).
|
the file permission bits S_ISUID and S_ISGID are cleared).
|
||||||
|
|
||||||
The format for running zupdate is:
|
The format for running @command{zupdate} is:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
zupdate [@var{options}] [@var{files}]
|
zupdate [@var{options}] [@var{files}]
|
||||||
|
@ -880,12 +942,29 @@ zupdate [@var{options}] [@var{files}]
|
||||||
Exit status is 0 if all the compressed files were successfully recompressed
|
Exit status is 0 if all the compressed files were successfully recompressed
|
||||||
(if needed), compared, and deleted (if requested). 1 if a non-fatal error
|
(if needed), compared, and deleted (if requested). 1 if a non-fatal error
|
||||||
occurred (file not found or not regular, or has invalid format, or can't be
|
occurred (file not found or not regular, or has invalid format, or can't be
|
||||||
deleted). 2 if a fatal error occurred (compressor can't be run, or
|
deleted). 2 if a fatal error occurred (invalid command line options,
|
||||||
comparison fails).
|
compressor can't be run, or comparison fails).
|
||||||
|
|
||||||
zupdate supports the following options:
|
@command{zupdate} supports the following options:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
|
@item -d @var{dir}
|
||||||
|
@itemx --destdir=@var{dir}
|
||||||
|
Write recompressed files to another directory, using @var{dir} as base
|
||||||
|
directory, instead of writing them in the same directory as the original
|
||||||
|
files. In recursive mode, this is done by replacing each directory specified
|
||||||
|
in the command line with @var{dir} to produce the recompressed file names.
|
||||||
|
For example, @w{@samp{zupdate -r -d @var{dir} ../a}} recompresses a file
|
||||||
|
named @file{../a/b/c.gz} to @file{@var{dir}/b/c.lz}. Regular files specified
|
||||||
|
in the command line are recompressed directly into @var{dir}. For example,
|
||||||
|
@w{@samp{zupdate -d @var{dir} ../a/b/c.gz}} writes the recompressed file to
|
||||||
|
@file{@var{dir}/c.lz}.
|
||||||
|
|
||||||
|
This option allows recompressing files from a read-only file system to
|
||||||
|
another place without the need to copy or link them to the destination
|
||||||
|
directory first. (Remember to use option @option{--keep} when recompressing
|
||||||
|
read-only files to avoid warnings about files that can't be deleted).
|
||||||
|
|
||||||
@item -e
|
@item -e
|
||||||
@itemx --expand-extensions
|
@itemx --expand-extensions
|
||||||
Expand combined file name extensions; recompress @samp{.tbz}, @samp{.tbz2},
|
Expand combined file name extensions; recompress @samp{.tbz}, @samp{.tbz2},
|
||||||
|
@ -894,7 +973,7 @@ Expand combined file name extensions; recompress @samp{.tbz}, @samp{.tbz2},
|
||||||
@item -f
|
@item -f
|
||||||
@itemx --force
|
@itemx --force
|
||||||
Don't skip a file for which a lzip compressed version already exists.
|
Don't skip a file for which a lzip compressed version already exists.
|
||||||
@samp{--force} compares the content of the input file with the content
|
@option{--force} compares the content of the input file with the content
|
||||||
of the existing lzip file and deletes the input file if both contents
|
of the existing lzip file and deletes the input file if both contents
|
||||||
are identical.
|
are identical.
|
||||||
|
|
||||||
|
@ -908,10 +987,10 @@ Keep (don't delete) the input file after comparing it with the lzip file.
|
||||||
|
|
||||||
@item -l
|
@item -l
|
||||||
@itemx --lzip-verbose
|
@itemx --lzip-verbose
|
||||||
Pass one option @samp{-v} to the lzip compressor so that it shows the
|
Pass one option @option{-v} to the lzip compressor so that it shows the
|
||||||
compression ratio for each file processed. Using lzip 1.15 or newer, a
|
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
|
second @option{-l} shows the progress of compression. Use it together with
|
||||||
@samp{-v} to see the name of the file.
|
@option{-v} to see the name of the file.
|
||||||
|
|
||||||
@item -q
|
@item -q
|
||||||
@itemx --quiet
|
@itemx --quiet
|
||||||
|
@ -930,13 +1009,30 @@ recursively, following all symbolic links.
|
||||||
|
|
||||||
@item -v
|
@item -v
|
||||||
@itemx --verbose
|
@itemx --verbose
|
||||||
Verbose mode. Show the files being processed. A second @samp{-v} also
|
Verbose mode. Show the files being processed. A second @option{-v} also shows
|
||||||
shows the files being ignored.
|
the files being ignored and increases the verbosity level. @xref{version}.
|
||||||
|
|
||||||
@item -0 .. -9
|
@item -0 .. -9
|
||||||
Set the compression level of lzip. By default zupdate passes @samp{-9} to
|
Set the compression level of lzip. By default @command{zupdate} passes
|
||||||
lzip. Custom compression options can be passed to lzip with the option
|
@option{-9} to lzip. Custom compression options can be passed to lzip with
|
||||||
@samp{--lz}. For example @w{@samp{--lz='lzip -9 -s64MiB'}}.
|
the option @option{--lz}. For example @w{@option{--lz='lzip -9 -s64MiB'}}.
|
||||||
|
|
||||||
|
@anchor{lz-compressor}
|
||||||
|
@item --lz=@var{command}
|
||||||
|
Set compression command. @var{command} may include arguments. For example
|
||||||
|
@w{@option{--lz='plzip --threads=2'}}. The name of the program can't begin
|
||||||
|
with @samp{-}. This option overrides the value set in @file{zutils.conf}.
|
||||||
|
The compression program used does not need to implement decompression
|
||||||
|
(@pxref{compressor-requirements}), but it must implement at least the
|
||||||
|
compression level option @option{-9} and the option @w{@option{-o @var{file}}}
|
||||||
|
to write the compressed output to @var{file}.
|
||||||
|
@uref{http://www.nongnu.org/lzip/manual/tarlz_manual.html,,tarlz} meets
|
||||||
|
these requirements, and therefore can be used to recompress POSIX tar
|
||||||
|
archives by using a command like
|
||||||
|
@w{@samp{zupdate --lz='tarlz -9 -z --no-solid' archive.tar.gz}}.
|
||||||
|
@ifnothtml
|
||||||
|
@xref{Top,tarlz manual,,tarlz}.
|
||||||
|
@end ifnothtml
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
88
rc.cc
88
rc.cc
|
@ -36,13 +36,13 @@ int verbosity = 0;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const char * const config_file_name = "zutilsrc";
|
const char * const config_file_name = "zutils.conf";
|
||||||
const char * const program_year = "2022";
|
const char * const program_year = "2022";
|
||||||
|
|
||||||
std::string compressor_names[num_formats] =
|
std::string compressor_names[num_formats] =
|
||||||
{ "bzip2", "gzip", "lzip", "xz", "zstd" }; // default compressor names
|
{ "bzip2", "gzip", "lzip", "xz", "zstd" }; // default compressor names
|
||||||
|
|
||||||
// args to compressors read from rc or from options like --lz, maybe empty
|
// args to compressors read from .conf or from options like --lz, maybe empty
|
||||||
std::vector< std::string > compressor_args[num_formats];
|
std::vector< std::string > compressor_args[num_formats];
|
||||||
|
|
||||||
// vector of enabled formats plus [num_formats] for uncompressed.
|
// vector of enabled formats plus [num_formats] for uncompressed.
|
||||||
|
@ -189,7 +189,7 @@ bool parse_rc_line( const std::string & line,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Return 0 if success, 1 if file not found, 2 if syntax error.
|
// Return 0 if success, 1 if file not found, 2 if syntax or I/O error.
|
||||||
int process_rcfile( const std::string & name )
|
int process_rcfile( const std::string & name )
|
||||||
{
|
{
|
||||||
FILE * const f = std::fopen( name.c_str(), "r" );
|
FILE * const f = std::fopen( name.c_str(), "r" );
|
||||||
|
@ -205,24 +205,42 @@ int process_rcfile( const std::string & name )
|
||||||
if( !parse_rc_line( line, name.c_str(), linenum ) )
|
if( !parse_rc_line( line, name.c_str(), linenum ) )
|
||||||
{ retval = 2; break; }
|
{ retval = 2; break; }
|
||||||
}
|
}
|
||||||
std::fclose( f );
|
if( std::fclose( f ) != 0 && retval == 0 )
|
||||||
|
{ show_file_error( name.c_str(), "Error closing config file", errno );
|
||||||
|
retval = 2; }
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void show_using_version( const char * const command )
|
||||||
|
{
|
||||||
|
FILE * const f = popen( command, "r" );
|
||||||
|
if( f )
|
||||||
|
{
|
||||||
|
char command_version[1024] = { 0 };
|
||||||
|
const int rd = std::fread( command_version, 1, sizeof command_version, f );
|
||||||
|
pclose( f );
|
||||||
|
int i = 0;
|
||||||
|
while( i + 1 < rd && command_version[i] != '\n' ) ++i;
|
||||||
|
command_version[i] = 0;
|
||||||
|
if( command_version[0] ) std::printf( "Using %s\n", command_version );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
||||||
|
|
||||||
bool enabled_format( const int format_index )
|
bool enabled_format( const int format_index )
|
||||||
{
|
{
|
||||||
if( enabled_formats.size() <= num_formats ) return true; // all enabled
|
if( enabled_formats.size() <= num_formats ) return true; // all enabled
|
||||||
if( format_index < 0 ) return enabled_formats[num_formats]; // uncompressed
|
if( format_index < 0 || format_index >= num_formats )
|
||||||
|
return enabled_formats[num_formats]; // uncompressed
|
||||||
return enabled_formats[format_index];
|
return enabled_formats[format_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_format_list( const std::string & arg, const char * const pn )
|
void parse_format_list( const std::string & arg, const char * const pn )
|
||||||
{
|
{
|
||||||
const std::string un( "uncompressed" );
|
|
||||||
bool error = arg.empty();
|
bool error = arg.empty();
|
||||||
enabled_formats.assign( num_formats + 1, false );
|
enabled_formats.assign( num_formats + 1, false );
|
||||||
|
|
||||||
|
@ -235,26 +253,25 @@ void parse_format_list( const std::string & arg, const char * const pn )
|
||||||
for( int i = 0; i < num_formats; ++i )
|
for( int i = 0; i < num_formats; ++i )
|
||||||
if( s == format_names[i] )
|
if( s == format_names[i] )
|
||||||
{ format_index = i; break; }
|
{ format_index = i; break; }
|
||||||
if( format_index == num_formats && un.find( s ) != 0 )
|
if( format_index == num_formats && s != "un" ) // uncompressed
|
||||||
{ error = true; break; }
|
{ error = true; break; }
|
||||||
enabled_formats[format_index] = true;
|
enabled_formats[format_index] = true;
|
||||||
}
|
}
|
||||||
if( !error ) return;
|
if( !error ) return;
|
||||||
if( verbosity >= 0 )
|
show_option_error( arg.c_str(), "Invalid format in", pn );
|
||||||
std::fprintf( stderr, "%s: Bad argument in option '%s'.\n",
|
|
||||||
program_name, pn );
|
|
||||||
std::exit( 1 );
|
std::exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int parse_format_type( const std::string & arg, const char * const pn )
|
int parse_format_type( const std::string & arg, const char * const pn,
|
||||||
|
const bool allow_uncompressed )
|
||||||
{
|
{
|
||||||
for( int i = 0; i < num_formats; ++i )
|
for( int i = 0; i < num_formats; ++i )
|
||||||
if( arg == format_names[i] )
|
if( arg == format_names[i] )
|
||||||
return i;
|
return i;
|
||||||
if( verbosity >= 0 )
|
if( allow_uncompressed && arg == "un" ) return num_formats;
|
||||||
std::fprintf( stderr, "%s: Bad argument in option '%s'.\n",
|
show_option_error( arg.c_str(), ( arg.find( ',' ) < arg.size() ) ?
|
||||||
program_name, pn );
|
"Too many formats in" : "Invalid format in", pn );
|
||||||
std::exit( 1 );
|
std::exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,10 +303,11 @@ void maybe_process_config_file( const Arg_parser & parser )
|
||||||
for( int i = 0; i < parser.arguments(); ++i )
|
for( int i = 0; i < parser.arguments(); ++i )
|
||||||
if( parser.code( i ) == 'N' ) return;
|
if( parser.code( i ) == 'N' ) return;
|
||||||
std::string name;
|
std::string name;
|
||||||
const char * p = std::getenv( "HOME" ); if( p ) name = p;
|
const char * p = std::getenv( "XDG_CONFIG_HOME" ); if( p ) name = p;
|
||||||
|
else { p = std::getenv( "HOME" ); if( p ) { name = p; name += "/.config"; } }
|
||||||
if( name.size() )
|
if( name.size() )
|
||||||
{
|
{
|
||||||
name += "/."; name += config_file_name;
|
name += '/'; name += config_file_name;
|
||||||
const int retval = process_rcfile( name );
|
const int retval = process_rcfile( name );
|
||||||
if( retval == 0 ) return;
|
if( retval == 0 ) return;
|
||||||
if( retval == 2 ) std::exit( 2 );
|
if( retval == 2 ) std::exit( 2 );
|
||||||
|
@ -300,11 +318,12 @@ void maybe_process_config_file( const Arg_parser & parser )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_compressor( const std::string & arg, const int format_index,
|
void parse_compressor( const std::string & arg, const char * const pn,
|
||||||
const int eretval )
|
const int format_index, const int eretval )
|
||||||
{
|
{
|
||||||
if( !parse_compressor_command( arg, 0, format_index ) )
|
if( !parse_compressor_command( arg, 0, format_index ) )
|
||||||
{ show_error( "Missing compressor name." ); std::exit( eretval ); }
|
{ show_option_error( arg.c_str(), "Invalid compressor command in", pn );
|
||||||
|
std::exit( eretval ); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -313,7 +332,7 @@ const char * get_compressor_name( const int format_index )
|
||||||
if( format_index >= 0 && format_index < num_formats &&
|
if( format_index >= 0 && format_index < num_formats &&
|
||||||
compressor_names[format_index].size() )
|
compressor_names[format_index].size() )
|
||||||
return compressor_names[format_index].c_str();
|
return compressor_names[format_index].c_str();
|
||||||
return 0;
|
return 0; // uncompressed/unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -334,20 +353,16 @@ void show_version( const char * const command )
|
||||||
{
|
{
|
||||||
std::printf( "%s (zutils) %s\n", program_name, PROGVERSION );
|
std::printf( "%s (zutils) %s\n", program_name, PROGVERSION );
|
||||||
std::printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
|
std::printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
|
||||||
if( command && verbosity >= 1 )
|
if( command && verbosity >= 1 ) show_using_version( command );
|
||||||
{
|
if( verbosity >= 1 + ( command != 0 ) )
|
||||||
FILE * const f = popen( command, "r" );
|
for( int format_index = 0; format_index < num_formats; ++format_index )
|
||||||
if( f )
|
|
||||||
{
|
{
|
||||||
char command_version[1024] = { 0 };
|
if( !enabled_format( format_index ) ) continue;
|
||||||
const int rd = std::fread( command_version, 1, sizeof command_version, f );
|
std::string compressor_command( compressor_names[format_index] );
|
||||||
pclose( f );
|
if( compressor_command.empty() ) continue;
|
||||||
int i = 0;
|
compressor_command += " -V 2> /dev/null";
|
||||||
while( i + 1 < rd && command_version[i] != '\n' ) ++i;
|
show_using_version( compressor_command.c_str() );
|
||||||
command_version[i] = 0;
|
|
||||||
if( command_version[0] ) std::printf( "Using %s\n", command_version );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
std::printf( "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>\n"
|
std::printf( "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>\n"
|
||||||
"This is free software: you are free to change and redistribute it.\n"
|
"This is free software: you are free to change and redistribute it.\n"
|
||||||
"There is NO WARRANTY, to the extent permitted by law.\n" );
|
"There is NO WARRANTY, to the extent permitted by law.\n" );
|
||||||
|
@ -385,6 +400,15 @@ void internal_error( const char * const msg )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void show_option_error( const char * const arg, const char * const msg,
|
||||||
|
const char * const option_name )
|
||||||
|
{
|
||||||
|
if( verbosity >= 0 )
|
||||||
|
std::fprintf( stderr, "%s: '%s': %s option '%s'.\n",
|
||||||
|
program_name, arg, msg, option_name );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void show_close_error( const char * const prog_name )
|
void show_close_error( const char * const prog_name )
|
||||||
{
|
{
|
||||||
if( verbosity >= 0 )
|
if( verbosity >= 0 )
|
||||||
|
|
21
rc.h
21
rc.h
|
@ -15,7 +15,9 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum { fmt_bz2, fmt_gz, fmt_lz, fmt_xz, fmt_zst, num_formats }; // format_index
|
// format_index; < 0 means undefined, >= num_formats means uncompressed
|
||||||
|
enum { fmt_bz2, fmt_gz, fmt_lz, fmt_xz, fmt_zst, num_formats };
|
||||||
|
|
||||||
const char * const format_names[num_formats] =
|
const char * const format_names[num_formats] =
|
||||||
{ "bz2", "gz", "lz", "xz", "zst" };
|
{ "bz2", "gz", "lz", "xz", "zst" };
|
||||||
const char * const simple_extensions[num_formats] =
|
const char * const simple_extensions[num_formats] =
|
||||||
|
@ -23,15 +25,22 @@ const char * const simple_extensions[num_formats] =
|
||||||
const int format_order[num_formats] =
|
const int format_order[num_formats] =
|
||||||
{ fmt_lz, fmt_bz2, fmt_gz, fmt_zst, fmt_xz }; // search order
|
{ fmt_lz, fmt_bz2, fmt_gz, fmt_zst, fmt_xz }; // search order
|
||||||
|
|
||||||
bool enabled_format( const int format_index );
|
bool enabled_format( const int format_index ); // -1 == uncompressed
|
||||||
void parse_format_list( const std::string & arg, const char * const pn );
|
void parse_format_list( const std::string & arg, const char * const pn );
|
||||||
int parse_format_type( const std::string & arg, const char * const pn );
|
// Return num_formats if arg == "un" (uncompressed).
|
||||||
|
int parse_format_type( const std::string & arg, const char * const pn,
|
||||||
|
const bool allow_uncompressed = true );
|
||||||
|
|
||||||
int extension_index( const std::string & name ); // -1 if unknown
|
int extension_index( const std::string & name ); // -1 if unknown
|
||||||
int extension_format( const int eindex ); // -1 if uncompressed
|
int extension_format( const int eindex ); // -1 if uncompressed
|
||||||
const char * extension_from( const int eindex );
|
const char * extension_from( const int eindex );
|
||||||
const char * extension_to( const int eindex );
|
const char * extension_to( const int eindex );
|
||||||
|
|
||||||
|
// Return format_index, or -1 if uncompressed.
|
||||||
|
//
|
||||||
|
inline int test_extension( const std::string & name )
|
||||||
|
{ return extension_format( extension_index( name ) ); }
|
||||||
|
|
||||||
extern const char * invocation_name;
|
extern const char * invocation_name;
|
||||||
extern const char * program_name;
|
extern const char * program_name;
|
||||||
extern int verbosity;
|
extern int verbosity;
|
||||||
|
@ -40,8 +49,8 @@ class Arg_parser;
|
||||||
|
|
||||||
void maybe_process_config_file( const Arg_parser & parser );
|
void maybe_process_config_file( const Arg_parser & parser );
|
||||||
|
|
||||||
void parse_compressor( const std::string & arg, const int format_index,
|
void parse_compressor( const std::string & arg, const char * const pn,
|
||||||
const int eretval = 2 );
|
const int format_index, const int eretval = 2 );
|
||||||
|
|
||||||
const char * get_compressor_name( const int format_index );
|
const char * get_compressor_name( const int format_index );
|
||||||
const std::vector< std::string > & get_compressor_args( const int format_index );
|
const std::vector< std::string > & get_compressor_args( const int format_index );
|
||||||
|
@ -53,6 +62,8 @@ void show_error( const char * const msg, const int errcode = 0,
|
||||||
void show_file_error( const char * const filename, const char * const msg,
|
void show_file_error( const char * const filename, const char * const msg,
|
||||||
const int errcode = 0 );
|
const int errcode = 0 );
|
||||||
void internal_error( const char * const msg );
|
void internal_error( const char * const msg );
|
||||||
|
void show_option_error( const char * const arg, const char * const msg,
|
||||||
|
const char * const option_name );
|
||||||
void show_close_error( const char * const prog_name = "data feeder" );
|
void show_close_error( const char * const prog_name = "data feeder" );
|
||||||
void show_exec_error( const char * const prog_name );
|
void show_exec_error( const char * const prog_name );
|
||||||
void show_fork_error( const char * const prog_name );
|
void show_fork_error( const char * const prog_name );
|
||||||
|
|
|
@ -79,7 +79,7 @@ bool next_filename( std::list< std::string > & filenames,
|
||||||
i > 1 && input_filename[i-1] == '/'; --i )
|
i > 1 && input_filename[i-1] == '/'; --i )
|
||||||
input_filename.resize( i - 1 ); // remove trailing slashes
|
input_filename.resize( i - 1 ); // remove trailing slashes
|
||||||
struct stat stdot, *stdotp = 0;
|
struct stat stdot, *stdotp = 0;
|
||||||
if( input_filename[0] != '/' ) // relative path
|
if( input_filename[0] != '/' ) // relative file name
|
||||||
{
|
{
|
||||||
if( input_filename == "." ) input_filename.clear();
|
if( input_filename == "." ) input_filename.clear();
|
||||||
if( stat( ".", &stdot ) == 0 && S_ISDIR( stdot.st_mode ) )
|
if( stat( ".", &stdot ) == 0 && S_ISDIR( stdot.st_mode ) )
|
||||||
|
|
|
@ -47,8 +47,8 @@ done
|
||||||
|
|
||||||
cat "${testdir}"/test.txt > in || framework_failure
|
cat "${testdir}"/test.txt > in || framework_failure
|
||||||
cat "${testdir}"/test.txt.tar > in.tar || framework_failure
|
cat "${testdir}"/test.txt.tar > in.tar || framework_failure
|
||||||
printf "01234567890" > pin.tar || framework_failure
|
printf "01234567890" > pin.tar4 || framework_failure
|
||||||
cat in.tar in.tar in.tar in.tar >> pin.tar || framework_failure
|
cat in.tar in.tar in.tar in.tar >> pin.tar4 || framework_failure
|
||||||
cat in > -in- || framework_failure
|
cat in > -in- || framework_failure
|
||||||
cat in.lz > -in-.lz || framework_failure
|
cat in.lz > -in-.lz || framework_failure
|
||||||
cat in.lz > lz_only.lz || framework_failure
|
cat in.lz > lz_only.lz || framework_failure
|
||||||
|
@ -92,6 +92,8 @@ cmp in copy || test_failed $LINENO
|
||||||
cmp in copy || test_failed $LINENO
|
cmp in copy || test_failed $LINENO
|
||||||
"${ZCAT}" -N -O lz - - < in.lz > copy || test_failed $LINENO
|
"${ZCAT}" -N -O lz - - < in.lz > copy || test_failed $LINENO
|
||||||
cmp in copy || test_failed $LINENO
|
cmp in copy || test_failed $LINENO
|
||||||
|
"${ZCAT}" -N -O un in.lz | lzip -d > copy || test_failed $LINENO
|
||||||
|
cmp in copy || test_failed $LINENO
|
||||||
"${ZCAT}" -N --lz='lzip -q' < in.lz > copy || test_failed $LINENO
|
"${ZCAT}" -N --lz='lzip -q' < in.lz > copy || test_failed $LINENO
|
||||||
cmp in copy || test_failed $LINENO
|
cmp in copy || test_failed $LINENO
|
||||||
"${ZCAT}" -N in > copy || test_failed $LINENO
|
"${ZCAT}" -N in > copy || test_failed $LINENO
|
||||||
|
@ -151,28 +153,31 @@ for i in ${extensions}; do
|
||||||
"${ZCMP}" -N empty empty.$i || test_failed $LINENO $i
|
"${ZCMP}" -N empty empty.$i || test_failed $LINENO $i
|
||||||
done
|
done
|
||||||
|
|
||||||
"${ZCMP}" -Nq in in6
|
"${ZCMP}" -N -q in in6
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -N -n 0 in in6 || test_failed $LINENO
|
"${ZCMP}" -N -n 0 in in6 || test_failed $LINENO
|
||||||
"${ZCMP}" -N -n 100B in in6 || test_failed $LINENO
|
"${ZCMP}" -N -n 100B in in6 || test_failed $LINENO
|
||||||
"${ZCMP}" -N -n 1k in in6 || test_failed $LINENO
|
"${ZCMP}" -N -n 1k in in6 || test_failed $LINENO
|
||||||
"${ZCMP}" -N -n 10kB in in6 || test_failed $LINENO
|
"${ZCMP}" -N -n 10kB in in6 || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq in.tar pin.tar
|
"${ZCMP}" -N -n 01750 in in6 || test_failed $LINENO
|
||||||
|
"${ZCMP}" -N -n 0x3E8 in in6 || test_failed $LINENO
|
||||||
|
"${ZCMP}" -N -s in.tar pin.tar4
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq -i 0B:11B in.tar pin.tar
|
"${ZCMP}" -N -q -i 0B:11B in.tar pin.tar4
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -N -i 0:11 -n 0 in.tar pin.tar || test_failed $LINENO
|
"${ZCMP}" -N -i 0:11 -n 0 in.tar pin.tar4 || test_failed $LINENO
|
||||||
"${ZCMP}" -N -i 0:11 -n 100 in.tar pin.tar || test_failed $LINENO
|
"${ZCMP}" -N -i 0:11 -n 100 in.tar pin.tar4 || test_failed $LINENO
|
||||||
"${ZCMP}" -N -i 0:11 -n 1Ki in.tar pin.tar || test_failed $LINENO
|
"${ZCMP}" -N -i 0:013 -n 1Ki in.tar pin.tar4 || test_failed $LINENO
|
||||||
"${ZCMP}" -N -i 0:11 -n 10KiB in.tar pin.tar || test_failed $LINENO
|
"${ZCMP}" -N -i 0:0xB -n 10KiB in.tar pin.tar4 || test_failed $LINENO
|
||||||
"${ZCMP}" -N - - || test_failed $LINENO
|
"${ZCMP}" -N - - || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq -
|
"${ZCMP}" -N -q -
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -N in in || test_failed $LINENO
|
"${ZCMP}" -N in in || test_failed $LINENO
|
||||||
"${ZCMP}" -N in || test_failed $LINENO
|
"${ZCMP}" -N in || test_failed $LINENO
|
||||||
"${ZCMP}" -N --format=gz,bz2 in || test_failed $LINENO
|
"${ZCMP}" -N --format=gz,bz2 in || test_failed $LINENO
|
||||||
"${ZCMP}" -N --format=gz in || test_failed $LINENO
|
"${ZCMP}" -N --format=gz in || test_failed $LINENO
|
||||||
"${ZCMP}" -N in.lz in.gz || test_failed $LINENO
|
"${ZCMP}" -N in.lz in.gz || test_failed $LINENO
|
||||||
|
cat in.lz | "${ZCMP}" -N -O un,un in.lz - || test_failed $LINENO
|
||||||
"${ZCMP}" -N --lz='lzip -q' 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
|
"${ZCMP}" -N in.gz -- -in-.lz || test_failed $LINENO
|
||||||
"${ZCMP}" -N -- -in-.lz in.gz || test_failed $LINENO
|
"${ZCMP}" -N -- -in-.lz in.gz || test_failed $LINENO
|
||||||
|
@ -187,25 +192,25 @@ done
|
||||||
"${ZCMP}" -N in - < in.lz || test_failed $LINENO
|
"${ZCMP}" -N in - < in.lz || test_failed $LINENO
|
||||||
"${ZCMP}" -N - in < in.lz || test_failed $LINENO
|
"${ZCMP}" -N - in < in.lz || test_failed $LINENO
|
||||||
"${ZCMP}" -N lz_only.lz - < in || test_failed $LINENO
|
"${ZCMP}" -N lz_only.lz - < in || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq lz_only.lz
|
"${ZCMP}" -N -q lz_only.lz
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq "" in
|
"${ZCMP}" -N -q "" in
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq --force-format=lz in.lz
|
"${ZCMP}" -N -q --force-format=lz in.lz
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq --force-format=lz in.gz in.lz
|
"${ZCMP}" -N -q --force-format=lz in.gz in.lz
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq -i 100BB in in
|
"${ZCMP}" -N -q -i 100BB in in
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq -i 100BB:100 in in
|
"${ZCMP}" -N -q -i 100BB:100 in in
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq -i 100: in in
|
"${ZCMP}" -N -q -i 100: in in
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq -n -1 in in
|
"${ZCMP}" -N -q -n -1 in in
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -N -q -n 100BB in in
|
"${ZCMP}" -N -q -n 100BB in in
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -Nq --gz=bad-gzip in.gz in.lz
|
"${ZCMP}" -N -q --gz=bad-gzip in.gz in.lz
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZCMP}" -N --bad-option in in 2> /dev/null
|
"${ZCMP}" -N --bad-option in in 2> /dev/null
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
@ -227,7 +232,7 @@ done
|
||||||
"${ZDIFF}" -N in in6 > /dev/null
|
"${ZDIFF}" -N in in6 > /dev/null
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
# GNU diff 3.0 returns 2 when binary files differ
|
# GNU diff 3.0 returns 2 when binary files differ
|
||||||
"${ZDIFF}" -N in.tar pin.tar > /dev/null && test_failed $LINENO
|
"${ZDIFF}" -N in.tar pin.tar4 > /dev/null && test_failed $LINENO
|
||||||
"${ZDIFF}" -N - - || test_failed $LINENO
|
"${ZDIFF}" -N - - || test_failed $LINENO
|
||||||
"${ZDIFF}" -N - 2> /dev/null
|
"${ZDIFF}" -N - 2> /dev/null
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
@ -236,6 +241,7 @@ done
|
||||||
"${ZDIFF}" -N --format=gz,bz2 in || test_failed $LINENO
|
"${ZDIFF}" -N --format=gz,bz2 in || test_failed $LINENO
|
||||||
"${ZDIFF}" -N --format=gz in || test_failed $LINENO
|
"${ZDIFF}" -N --format=gz in || test_failed $LINENO
|
||||||
"${ZDIFF}" -N in.lz in.gz > /dev/null || test_failed $LINENO
|
"${ZDIFF}" -N in.lz in.gz > /dev/null || test_failed $LINENO
|
||||||
|
cat in.gz | "${ZDIFF}" -N -O un,un - in.gz || test_failed $LINENO
|
||||||
"${ZDIFF}" -N --lz='lzip -q' in.lz in.gz > /dev/null || test_failed $LINENO
|
"${ZDIFF}" -N --lz='lzip -q' in.lz in.gz > /dev/null || test_failed $LINENO
|
||||||
"${ZDIFF}" -N in.gz -- -in-.lz > /dev/null || test_failed $LINENO
|
"${ZDIFF}" -N in.gz -- -in-.lz > /dev/null || test_failed $LINENO
|
||||||
"${ZDIFF}" -N -- -in-.lz in.gz > /dev/null || test_failed $LINENO
|
"${ZDIFF}" -N -- -in-.lz in.gz > /dev/null || test_failed $LINENO
|
||||||
|
@ -303,8 +309,8 @@ for i in ${extensions}; do
|
||||||
"${ZGREP}" -N "nx_pattern" empty.$i && test_failed $LINENO $i
|
"${ZGREP}" -N "nx_pattern" empty.$i && test_failed $LINENO $i
|
||||||
done
|
done
|
||||||
|
|
||||||
"${ZGREP}" -N pin.tar -e "GNU" > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N pin.tar4 -e "GNU" > /dev/null || test_failed $LINENO
|
||||||
"${ZGREP}" -N "GNU" < pin.tar > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N "GNU" < pin.tar4 > /dev/null || test_failed $LINENO
|
||||||
"${ZGREP}" -N -r "GNU" . > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N -r "GNU" . > /dev/null || test_failed $LINENO
|
||||||
"${ZGREP}" -N -r "GNU" > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N -r "GNU" > /dev/null || test_failed $LINENO
|
||||||
"${ZGREP}" -N -R "GNU" . > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N -R "GNU" . > /dev/null || test_failed $LINENO
|
||||||
|
@ -313,6 +319,7 @@ done
|
||||||
"${ZGREP}" -N -e "GNU" in > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N -e "GNU" in > /dev/null || test_failed $LINENO
|
||||||
"${ZGREP}" -N "GNU" < in > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N "GNU" < in > /dev/null || test_failed $LINENO
|
||||||
"${ZGREP}" -N -O lz "nx_pattern" - - < in.lz > /dev/null && test_failed $LINENO
|
"${ZGREP}" -N -O lz "nx_pattern" - - < in.lz > /dev/null && test_failed $LINENO
|
||||||
|
"${ZGREP}" -N -O un "LZIP" in.lz > /dev/null || test_failed $LINENO
|
||||||
"${ZGREP}" -N -e "-free" --lz='lzip -q' < in.lz > /dev/null ||
|
"${ZGREP}" -N -e "-free" --lz='lzip -q' < in.lz > /dev/null ||
|
||||||
test_failed $LINENO
|
test_failed $LINENO
|
||||||
"${ZGREP}" -N -- "-free" -in- > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N -- "-free" -in- > /dev/null || test_failed $LINENO
|
||||||
|
@ -329,7 +336,7 @@ done
|
||||||
"${ZGREP}" -N -L "nx_pattern" in in.gz in.bz2 in.lz -- -in- > /dev/null &&
|
"${ZGREP}" -N -L "nx_pattern" in in.gz in.bz2 in.lz -- -in- > /dev/null &&
|
||||||
test_failed $LINENO
|
test_failed $LINENO
|
||||||
"${ZGREP}" -Nq -l "01234567890" in "${bad1_lz}" in.lz && test_failed $LINENO
|
"${ZGREP}" -Nq -l "01234567890" in "${bad1_lz}" in.lz && test_failed $LINENO
|
||||||
"${ZGREP}" -Nq -l "01234567890" in "${bad1_lz}" in.lz pin.tar > /dev/null ||
|
"${ZGREP}" -Nq -l "01234567890" in "${bad1_lz}" in.lz pin.tar4 > /dev/null ||
|
||||||
test_failed $LINENO
|
test_failed $LINENO
|
||||||
|
|
||||||
"${ZGREP}" -N "GNU" .
|
"${ZGREP}" -N "GNU" .
|
||||||
|
@ -355,8 +362,11 @@ for i in ${extensions}; do
|
||||||
[ $? = 2 ] || test_failed $LINENO $i
|
[ $? = 2 ] || test_failed $LINENO $i
|
||||||
"${ZTEST}" -N --force-format=$i in 2> /dev/null
|
"${ZTEST}" -N --force-format=$i in 2> /dev/null
|
||||||
[ $? = 2 ] || test_failed $LINENO $i
|
[ $? = 2 ] || test_failed $LINENO $i
|
||||||
|
"${ZTEST}" -N empty.$i 2> /dev/null
|
||||||
|
[ $? = 2 ] || test_failed $LINENO $i
|
||||||
done
|
done
|
||||||
|
|
||||||
|
rm -f empty.bz2 empty.gz empty.lz || framework_failure
|
||||||
"${ZTEST}" -N in in.gz in.bz2 in.lz -- -in- || test_failed $LINENO
|
"${ZTEST}" -N in in.gz in.bz2 in.lz -- -in- || test_failed $LINENO
|
||||||
"${ZTEST}" -N < in.gz || test_failed $LINENO
|
"${ZTEST}" -N < in.gz || test_failed $LINENO
|
||||||
"${ZTEST}" -N < in.bz2 || test_failed $LINENO
|
"${ZTEST}" -N < in.bz2 || test_failed $LINENO
|
||||||
|
@ -368,7 +378,23 @@ done
|
||||||
"${ZTEST}" -N -r || test_failed $LINENO
|
"${ZTEST}" -N -r || test_failed $LINENO
|
||||||
"${ZTEST}" -N -R . || test_failed $LINENO
|
"${ZTEST}" -N -R . || test_failed $LINENO
|
||||||
"${ZTEST}" -N -R || test_failed $LINENO
|
"${ZTEST}" -N -R || test_failed $LINENO
|
||||||
"${ZTEST}" -N empty empty.bz2 empty.gz empty.lz || test_failed $LINENO
|
"${ZTEST}" -N empty || test_failed $LINENO
|
||||||
|
rm -f empty || framework_failure
|
||||||
|
|
||||||
|
# test wrong compressed extensions
|
||||||
|
cat in.bz2 > in_bz2.gz || framework_failure
|
||||||
|
cat in.gz > in_gz.lz || framework_failure
|
||||||
|
cat in.lz > in_lz.bz2 || framework_failure
|
||||||
|
cat in > in_un.lz || framework_failure
|
||||||
|
"${ZTEST}" -Nq in_bz2.gz
|
||||||
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
"${ZTEST}" -Nq in_gz.lz
|
||||||
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
"${ZTEST}" -Nq in_lz.bz2
|
||||||
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
"${ZTEST}" -Nq in_un.lz
|
||||||
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
rm -f in_bz2.gz in_gz.lz in_lz.bz2 in_un.lz || framework_failure
|
||||||
|
|
||||||
"${ZTEST}" -Nq in.gz "${bad0_lz}" in.bz2 "${bad1_lz}" in.lz
|
"${ZTEST}" -Nq in.gz "${bad0_lz}" in.bz2 "${bad1_lz}" in.lz
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
@ -378,12 +404,16 @@ lines=`"${ZTEST}" -Nv in.gz "${bad0_lz}" in.bz2 "${bad1_lz}" in.lz 2>&1 | wc -l`
|
||||||
[ "${lines}" -eq 6 ] || test_failed $LINENO "${lines}"
|
[ "${lines}" -eq 6 ] || test_failed $LINENO "${lines}"
|
||||||
"${ZTEST}" -Nq < in
|
"${ZTEST}" -Nq < in
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
"${ZTEST}" -Nq --force-format=un < in.gz
|
||||||
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
"${ZTEST}" -Nq "" < in.lz
|
"${ZTEST}" -Nq "" < in.lz
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
dd if=in.lz bs=1000 count=1 2> /dev/null | "${ZTEST}" -N -q
|
dd if=in.lz bs=1000 count=1 2> /dev/null | "${ZTEST}" -N -q
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
"${ZTEST}" -Nq --force-format=lz in.bz2
|
"${ZTEST}" -Nq --force-format=lz in.bz2
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
"${ZTEST}" -Nq --force-format=un in.gz
|
||||||
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
"${ZTEST}" -N --lz='lzip --bad-option' in.lz 2> /dev/null
|
"${ZTEST}" -N --lz='lzip --bad-option' in.lz 2> /dev/null
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
"${ZTEST}" -N --bad-option 2> /dev/null
|
"${ZTEST}" -N --bad-option 2> /dev/null
|
||||||
|
@ -410,20 +440,30 @@ cat in.gz > a.gz || framework_failure
|
||||||
"${ZUPDATE}" -N --bad-option 2> /dev/null
|
"${ZUPDATE}" -N --bad-option 2> /dev/null
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
|
|
||||||
|
if /bin/sh -c "tarlz -V" > /dev/null 2>&1; then
|
||||||
|
printf .
|
||||||
|
gzip < in.tar > in.tar.gz || framework_failure
|
||||||
|
"${ZUPDATE}" -N -k --lz='tarlz -0 -z --no-solid' in.tar.gz ||
|
||||||
|
test_failed $LINENO
|
||||||
|
[ -e in.tar ] || test_failed $LINENO
|
||||||
|
"${ZCMP}" -N in.tar.gz in.tar.lz || test_failed $LINENO
|
||||||
|
rm -f in.tar.gz in.tar.lz || framework_failure
|
||||||
|
fi
|
||||||
|
|
||||||
cat in.lz in.lz > a.lz || framework_failure
|
cat in.lz in.lz > a.lz || framework_failure
|
||||||
"${ZUPDATE}" -Nq -f a.bz2 a.gz
|
"${ZUPDATE}" -N -q -f a.bz2 a.gz
|
||||||
[ $? = 2 ] || test_failed $LINENO
|
[ $? = 2 ] || test_failed $LINENO
|
||||||
[ -e a.bz2 ] || test_failed $LINENO
|
[ -e a.bz2 ] || test_failed $LINENO
|
||||||
[ -e a.gz ] || test_failed $LINENO
|
[ -e a.gz ] || test_failed $LINENO
|
||||||
[ -e a.lz ] || test_failed $LINENO
|
[ -e a.lz ] || test_failed $LINENO
|
||||||
rm -f a.lz || framework_failure
|
rm -f a.lz || framework_failure
|
||||||
|
|
||||||
"${ZUPDATE}" -N a.bz2 || test_failed $LINENO
|
"${ZUPDATE}" -N -0 a.bz2 || test_failed $LINENO
|
||||||
[ ! -e a.bz2 ] || test_failed $LINENO
|
[ ! -e a.bz2 ] || test_failed $LINENO
|
||||||
[ -e a.gz ] || test_failed $LINENO
|
[ -e a.gz ] || test_failed $LINENO
|
||||||
[ -e a.lz ] || test_failed $LINENO
|
[ -e a.lz ] || test_failed $LINENO
|
||||||
rm -f a.lz || framework_failure
|
rm -f a.lz || framework_failure
|
||||||
"${ZUPDATE}" -N a.gz || test_failed $LINENO
|
"${ZUPDATE}" -N -0 a.gz || test_failed $LINENO
|
||||||
[ ! -e a.bz2 ] || test_failed $LINENO
|
[ ! -e a.bz2 ] || test_failed $LINENO
|
||||||
[ ! -e a.gz ] || test_failed $LINENO
|
[ ! -e a.gz ] || test_failed $LINENO
|
||||||
[ -e a.lz ] || test_failed $LINENO
|
[ -e a.lz ] || test_failed $LINENO
|
||||||
|
@ -431,7 +471,7 @@ rm -f a.lz || framework_failure
|
||||||
|
|
||||||
cat in.bz2 > a.bz2 || framework_failure
|
cat in.bz2 > a.bz2 || framework_failure
|
||||||
cat in.gz > a.gz || framework_failure
|
cat in.gz > a.gz || framework_failure
|
||||||
"${ZUPDATE}" -Nq a.bz2 a.gz
|
"${ZUPDATE}" -N -q -0 a.bz2 a.gz
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
[ ! -e a.bz2 ] || test_failed $LINENO
|
[ ! -e a.bz2 ] || test_failed $LINENO
|
||||||
[ -e a.gz ] || test_failed $LINENO
|
[ -e a.gz ] || test_failed $LINENO
|
||||||
|
@ -440,7 +480,7 @@ rm -f a.lz || framework_failure
|
||||||
|
|
||||||
cat in.bz2 > a.bz2 || framework_failure
|
cat in.bz2 > a.bz2 || framework_failure
|
||||||
cat in.gz > a.gz || framework_failure
|
cat in.gz > a.gz || framework_failure
|
||||||
"${ZUPDATE}" -N -f -k a.bz2 a.gz || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -f -k a.bz2 a.gz || test_failed $LINENO
|
||||||
[ -e a.bz2 ] || test_failed $LINENO
|
[ -e a.bz2 ] || test_failed $LINENO
|
||||||
[ -e a.gz ] || test_failed $LINENO
|
[ -e a.gz ] || test_failed $LINENO
|
||||||
[ -e a.lz ] || test_failed $LINENO
|
[ -e a.lz ] || test_failed $LINENO
|
||||||
|
@ -448,7 +488,7 @@ rm -f a.lz || framework_failure
|
||||||
|
|
||||||
cat in.bz2 > a.bz2 || framework_failure
|
cat in.bz2 > a.bz2 || framework_failure
|
||||||
cat in.gz > a.gz || framework_failure
|
cat in.gz > a.gz || framework_failure
|
||||||
"${ZUPDATE}" -N -f a.bz2 a.gz || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -f a.bz2 a.gz || test_failed $LINENO
|
||||||
[ ! -e a.bz2 ] || test_failed $LINENO
|
[ ! -e a.bz2 ] || test_failed $LINENO
|
||||||
[ ! -e a.gz ] || test_failed $LINENO
|
[ ! -e a.gz ] || test_failed $LINENO
|
||||||
[ ! -e a ] || test_failed $LINENO
|
[ ! -e a ] || test_failed $LINENO
|
||||||
|
@ -458,7 +498,7 @@ rm -f a.lz || framework_failure
|
||||||
cat in.bz2 > a.tbz || framework_failure # keep combined extensions
|
cat in.bz2 > a.tbz || framework_failure # keep combined extensions
|
||||||
cat in.bz2 > b.tbz2 || framework_failure
|
cat in.bz2 > b.tbz2 || framework_failure
|
||||||
cat in.gz > c.tgz || framework_failure
|
cat in.gz > c.tgz || framework_failure
|
||||||
"${ZUPDATE}" -N a.tbz b.tbz2 c.tgz || test_failed $LINENO
|
"${ZUPDATE}" -N -0 a.tbz b.tbz2 c.tgz || test_failed $LINENO
|
||||||
[ ! -e a.tbz ] || test_failed $LINENO
|
[ ! -e a.tbz ] || test_failed $LINENO
|
||||||
[ ! -e b.tbz2 ] || test_failed $LINENO
|
[ ! -e b.tbz2 ] || test_failed $LINENO
|
||||||
[ ! -e c.tgz ] || test_failed $LINENO
|
[ ! -e c.tgz ] || test_failed $LINENO
|
||||||
|
@ -476,7 +516,7 @@ rm -f a.tlz b.tlz c.tlz || framework_failure
|
||||||
cat in.bz2 > a.tbz || framework_failure # expand combined extensions
|
cat in.bz2 > a.tbz || framework_failure # expand combined extensions
|
||||||
cat in.bz2 > b.tbz2 || framework_failure
|
cat in.bz2 > b.tbz2 || framework_failure
|
||||||
cat in.gz > c.tgz || framework_failure
|
cat in.gz > c.tgz || framework_failure
|
||||||
"${ZUPDATE}" -N -e a.tbz b.tbz2 c.tgz || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -e a.tbz b.tbz2 c.tgz || test_failed $LINENO
|
||||||
[ ! -e a.tbz ] || test_failed $LINENO
|
[ ! -e a.tbz ] || test_failed $LINENO
|
||||||
[ ! -e b.tbz2 ] || test_failed $LINENO
|
[ ! -e b.tbz2 ] || test_failed $LINENO
|
||||||
[ ! -e c.tgz ] || test_failed $LINENO
|
[ ! -e c.tgz ] || test_failed $LINENO
|
||||||
|
@ -495,7 +535,7 @@ rm -f a.tar.lz b.tar.lz c.tar.lz || framework_failure
|
||||||
cat in.bz2 > a.bz2 || framework_failure
|
cat in.bz2 > a.bz2 || framework_failure
|
||||||
cat "${bad0_gz}" > b.gz || framework_failure
|
cat "${bad0_gz}" > b.gz || framework_failure
|
||||||
cat in.gz > c.gz || framework_failure
|
cat in.gz > c.gz || framework_failure
|
||||||
"${ZUPDATE}" -N -f a.bz2 b.gz c.gz 2> /dev/null
|
"${ZUPDATE}" -N -0 -f a.bz2 b.gz c.gz 2> /dev/null
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
[ ! -e a.bz2 ] || test_failed $LINENO
|
[ ! -e a.bz2 ] || test_failed $LINENO
|
||||||
[ -e b.gz ] || test_failed $LINENO
|
[ -e b.gz ] || test_failed $LINENO
|
||||||
|
@ -508,7 +548,7 @@ cat in.gz > c.gz || framework_failure
|
||||||
cat in.bz2 > a.bz2 || framework_failure
|
cat in.bz2 > a.bz2 || framework_failure
|
||||||
cat "${bad0_gz}" > b.gz || framework_failure
|
cat "${bad0_gz}" > b.gz || framework_failure
|
||||||
cat in.gz > c.gz || framework_failure
|
cat in.gz > c.gz || framework_failure
|
||||||
"${ZUPDATE}" -N -f -i a.bz2 b.gz c.gz 2> /dev/null
|
"${ZUPDATE}" -N -0 -f -i a.bz2 b.gz c.gz 2> /dev/null
|
||||||
[ $? = 1 ] || test_failed $LINENO
|
[ $? = 1 ] || test_failed $LINENO
|
||||||
[ ! -e a.bz2 ] || test_failed $LINENO
|
[ ! -e a.bz2 ] || test_failed $LINENO
|
||||||
[ -e b.gz ] || test_failed $LINENO
|
[ -e b.gz ] || test_failed $LINENO
|
||||||
|
@ -517,13 +557,13 @@ cat in.gz > c.gz || framework_failure
|
||||||
rm -f a.lz b.gz c.gz || framework_failure
|
rm -f a.lz b.gz c.gz || framework_failure
|
||||||
|
|
||||||
cat in.bz2 > a.bz2 || framework_failure
|
cat in.bz2 > a.bz2 || framework_failure
|
||||||
"${ZUPDATE}" -N -1 -q a.bz2 || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -q a.bz2 || test_failed $LINENO
|
||||||
[ ! -e a.bz2 ] || test_failed $LINENO
|
[ ! -e a.bz2 ] || test_failed $LINENO
|
||||||
[ -e a.lz ] || test_failed $LINENO
|
[ -e a.lz ] || test_failed $LINENO
|
||||||
rm -f a.lz || framework_failure
|
rm -f a.lz || framework_failure
|
||||||
|
|
||||||
cat in.gz > 'name with spaces.gz' || framework_failure
|
cat in.gz > 'name with spaces.gz' || framework_failure
|
||||||
"${ZUPDATE}" -N -1 -q 'name with spaces.gz' || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -q 'name with spaces.gz' || test_failed $LINENO
|
||||||
[ ! -e 'name with spaces.gz' ] || test_failed $LINENO
|
[ ! -e 'name with spaces.gz' ] || test_failed $LINENO
|
||||||
[ -e 'name with spaces.lz' ] || test_failed $LINENO
|
[ -e 'name with spaces.lz' ] || test_failed $LINENO
|
||||||
"${ZCMP}" -N in 'name with spaces.lz' || test_failed $LINENO
|
"${ZCMP}" -N in 'name with spaces.lz' || test_failed $LINENO
|
||||||
|
@ -533,12 +573,34 @@ mkdir tmp2
|
||||||
mkdir tmp2/tmp3
|
mkdir tmp2/tmp3
|
||||||
cat in.bz2 > tmp2/tmp3/a.bz2 || framework_failure
|
cat in.bz2 > tmp2/tmp3/a.bz2 || framework_failure
|
||||||
cat in.gz > tmp2/tmp3/a.gz || framework_failure
|
cat in.gz > tmp2/tmp3/a.gz || framework_failure
|
||||||
"${ZUPDATE}" -N -r --format=gz tmp2 || test_failed $LINENO
|
# test recursive to destdir
|
||||||
|
"${ZUPDATE}" -N -0 -k -r --format=gz --destdir=ddir1 tmp2 || test_failed $LINENO
|
||||||
|
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
|
[ -e tmp2/tmp3/a.gz ] || test_failed $LINENO
|
||||||
|
[ -e ddir1/tmp3/a.lz ] || test_failed $LINENO
|
||||||
|
"${ZUPDATE}" -N -0 -k -r --format=bz2 --destdir="${objdir}"/tmp/ddir2 tmp2 ||
|
||||||
|
test_failed $LINENO
|
||||||
|
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
|
[ -e tmp2/tmp3/a.gz ] || test_failed $LINENO
|
||||||
|
[ -e ddir2/tmp3/a.lz ] || test_failed $LINENO
|
||||||
|
# test non-recursive to destdir
|
||||||
|
"${ZUPDATE}" -N -0 -k --destdir=ddir3 tmp2/tmp3/a.gz || test_failed $LINENO
|
||||||
|
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
|
[ -e tmp2/tmp3/a.gz ] || test_failed $LINENO
|
||||||
|
[ -e ddir3/a.lz ] || test_failed $LINENO
|
||||||
|
"${ZUPDATE}" -N -0 -k --destdir=ddir4/tmp2/tmp3 tmp2/tmp3/a.gz ||
|
||||||
|
test_failed $LINENO
|
||||||
|
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
|
[ -e tmp2/tmp3/a.gz ] || test_failed $LINENO
|
||||||
|
[ -e ddir4/tmp2/tmp3/a.lz ] || test_failed $LINENO
|
||||||
|
rm -rf ddir1 ddir2 ddir3 ddir4 || framework_failure
|
||||||
|
# test recursive in place
|
||||||
|
"${ZUPDATE}" -N -0 -r --format=gz tmp2 || test_failed $LINENO
|
||||||
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
|
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
[ ! -e tmp2/tmp3/a.gz ] || test_failed $LINENO
|
[ ! -e tmp2/tmp3/a.gz ] || test_failed $LINENO
|
||||||
[ -e tmp2/tmp3/a.lz ] || test_failed $LINENO
|
[ -e tmp2/tmp3/a.lz ] || test_failed $LINENO
|
||||||
rm -f tmp2/tmp3/a.lz || framework_failure
|
rm -f tmp2/tmp3/a.lz || framework_failure
|
||||||
"${ZUPDATE}" -N -r --format=bz2 tmp2 || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -r --format=bz2 tmp2 || test_failed $LINENO
|
||||||
[ ! -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
|
[ ! -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
[ ! -e tmp2/tmp3/a.gz ] || test_failed $LINENO
|
[ ! -e tmp2/tmp3/a.gz ] || test_failed $LINENO
|
||||||
[ -e tmp2/tmp3/a.lz ] || test_failed $LINENO
|
[ -e tmp2/tmp3/a.lz ] || test_failed $LINENO
|
||||||
|
@ -546,34 +608,33 @@ rm -f tmp2/tmp3/a.lz || framework_failure
|
||||||
cat in.bz2 > tmp2/tmp3/a.bz2 || framework_failure
|
cat in.bz2 > tmp2/tmp3/a.bz2 || framework_failure
|
||||||
cat in.gz > tmp2/tmp3/a.gz || framework_failure
|
cat in.gz > tmp2/tmp3/a.gz || framework_failure
|
||||||
cd tmp2 || framework_failure
|
cd tmp2 || framework_failure
|
||||||
"${ZUPDATE}" -N -r -k -f . || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -r -k -f . || test_failed $LINENO
|
||||||
[ -e tmp3/a.bz2 ] || test_failed $LINENO
|
[ -e tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.gz ] || test_failed $LINENO
|
[ -e tmp3/a.gz ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.lz ] || test_failed $LINENO
|
[ -e tmp3/a.lz ] || test_failed $LINENO
|
||||||
rm -f tmp3/a.lz || framework_failure
|
rm -f tmp3/a.lz || framework_failure
|
||||||
"${ZUPDATE}" -N -r -k -f || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -r -k -f || test_failed $LINENO
|
||||||
[ -e tmp3/a.bz2 ] || test_failed $LINENO
|
[ -e tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.gz ] || test_failed $LINENO
|
[ -e tmp3/a.gz ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.lz ] || test_failed $LINENO
|
[ -e tmp3/a.lz ] || test_failed $LINENO
|
||||||
rm -f tmp3/a.lz || framework_failure
|
rm -f tmp3/a.lz || framework_failure
|
||||||
"${ZUPDATE}" -N -R -k -f . || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -R -k -f . || test_failed $LINENO
|
||||||
[ -e tmp3/a.bz2 ] || test_failed $LINENO
|
[ -e tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.gz ] || test_failed $LINENO
|
[ -e tmp3/a.gz ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.lz ] || test_failed $LINENO
|
[ -e tmp3/a.lz ] || test_failed $LINENO
|
||||||
rm -f tmp3/a.lz || framework_failure
|
rm -f tmp3/a.lz || framework_failure
|
||||||
"${ZUPDATE}" -N -R -k -f || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -R -k -f || test_failed $LINENO
|
||||||
[ -e tmp3/a.bz2 ] || test_failed $LINENO
|
[ -e tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.gz ] || test_failed $LINENO
|
[ -e tmp3/a.gz ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.lz ] || test_failed $LINENO
|
[ -e tmp3/a.lz ] || test_failed $LINENO
|
||||||
rm -f tmp3/a.lz || framework_failure
|
rm -f tmp3/a.lz || framework_failure
|
||||||
"${ZUPDATE}" -N -r -f . || test_failed $LINENO
|
"${ZUPDATE}" -N -0 -r -f . || test_failed $LINENO
|
||||||
[ ! -e tmp3/a.bz2 ] || test_failed $LINENO
|
[ ! -e tmp3/a.bz2 ] || test_failed $LINENO
|
||||||
[ ! -e tmp3/a.gz ] || test_failed $LINENO
|
[ ! -e tmp3/a.gz ] || test_failed $LINENO
|
||||||
[ -e tmp3/a.lz ] || test_failed $LINENO
|
[ -e tmp3/a.lz ] || test_failed $LINENO
|
||||||
cd .. || framework_failure
|
cd .. || framework_failure
|
||||||
rm -r tmp2 || framework_failure
|
rm -r tmp2 || framework_failure
|
||||||
|
|
||||||
rm -f empty empty.bz2 empty.gz empty.lz || framework_failure
|
|
||||||
if ln -s '.' slink 2> /dev/null ; then
|
if ln -s '.' slink 2> /dev/null ; then
|
||||||
"${ZCAT}" -N -r slink > /dev/null || test_failed $LINENO
|
"${ZCAT}" -N -r slink > /dev/null || test_failed $LINENO
|
||||||
"${ZGREP}" -N -r "GNU" slink > /dev/null || test_failed $LINENO
|
"${ZGREP}" -N -r "GNU" slink > /dev/null || test_failed $LINENO
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
Worst case test file for zcat -vs.
|
Worst case test file for zcat -vs.
|
||||||
First 4096 input bytes produce 4095 output bytes because of -s.
|
First 4096 input bytes produce 4095 output bytes because of -s.
|
||||||
Next 4096 input bytes produce 16384 output bytes, accumulating a total
|
Next 4096 input bytes produce 16384 output bytes, accumulating a total
|
||||||
of 20479 bytes in the output buffer.
|
of 20479 bytes (5 * 4096 - 1) in the output buffer.
|
||||||
----------------------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
|
||||||
...............................................................
|
...............................................................
|
||||||
|
|
24
zcat.cc
24
zcat.cc
|
@ -115,7 +115,7 @@ void show_help()
|
||||||
" -M, --format=<list> process only the formats in <list>\n"
|
" -M, --format=<list> process only the formats in <list>\n"
|
||||||
" -n, --number number all output lines\n"
|
" -n, --number number all output lines\n"
|
||||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||||
" -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz, zst)\n"
|
" -O, --force-format=<fmt> force the input format\n"
|
||||||
" -q, --quiet suppress all messages\n"
|
" -q, --quiet suppress all messages\n"
|
||||||
" -r, --recursive operate recursively on directories\n"
|
" -r, --recursive operate recursively on directories\n"
|
||||||
" -R, --dereference-recursive recursively follow symbolic links\n"
|
" -R, --dereference-recursive recursively follow symbolic links\n"
|
||||||
|
@ -128,7 +128,9 @@ void show_help()
|
||||||
" --gz=<command> set compressor and options for gzip format\n"
|
" --gz=<command> set compressor and options for gzip format\n"
|
||||||
" --lz=<command> set compressor and options for lzip format\n"
|
" --lz=<command> set compressor and options for lzip format\n"
|
||||||
" --xz=<command> set compressor and options for xz format\n"
|
" --xz=<command> set compressor and options for xz format\n"
|
||||||
" --zst=<command> set compressor and options for zstd format\n" );
|
" --zst=<command> set compressor and options for zstd format\n"
|
||||||
|
"\nValid formats for options '-M' and '-O' are 'bz2', 'gz', 'lz', 'xz', 'zst',\n"
|
||||||
|
"and 'un' for uncompressed.\n" );
|
||||||
show_help_addr();
|
show_help_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,10 +237,10 @@ bool cat( int infd, const int format_index, const std::string & input_filename,
|
||||||
enum { buffer_size = 4096, outbuf_size = (5 * buffer_size) + 256 + 1 };
|
enum { buffer_size = 4096, outbuf_size = (5 * buffer_size) + 256 + 1 };
|
||||||
// input 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];
|
uint8_t * const inbuf = new uint8_t[buffer_size+1];
|
||||||
// output 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.
|
worst case flushing respect to inbuf, and a canary byte. */
|
||||||
uint8_t * const outbuf = new uint8_t[outbuf_size];
|
uint8_t * const outbuf = new uint8_t[outbuf_size];
|
||||||
outbuf[outbuf_size-1] = 0;
|
outbuf[outbuf_size-1] = 0; // canary byte; quoting does not print 0
|
||||||
Children children;
|
Children children;
|
||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
|
@ -258,7 +260,7 @@ bool cat( int infd, const int format_index, const std::string & input_filename,
|
||||||
int main( const int argc, const char * const argv[] )
|
int main( const int argc, const char * const argv[] )
|
||||||
{
|
{
|
||||||
enum { verbose_opt = 256, bz2_opt, gz_opt, lz_opt, xz_opt, zst_opt };
|
enum { verbose_opt = 256, bz2_opt, gz_opt, lz_opt, xz_opt, zst_opt };
|
||||||
int format_index = -1;
|
int format_index = -1; // undefined
|
||||||
int recursive = 0; // 1 = '-r', 2 = '-R'
|
int recursive = 0; // 1 = '-r', 2 = '-R'
|
||||||
std::list< std::string > filenames;
|
std::list< std::string > filenames;
|
||||||
Cat_options cat_options;
|
Cat_options cat_options;
|
||||||
|
@ -338,11 +340,11 @@ int main( const int argc, const char * const argv[] )
|
||||||
case 'v': cat_options.show_nonprinting = true; break;
|
case 'v': cat_options.show_nonprinting = true; break;
|
||||||
case 'V': show_version(); return 0;
|
case 'V': show_version(); return 0;
|
||||||
case verbose_opt: if( verbosity < 4 ) ++verbosity; break;
|
case verbose_opt: if( verbosity < 4 ) ++verbosity; break;
|
||||||
case bz2_opt: parse_compressor( arg, fmt_bz2, 1 ); break;
|
case bz2_opt: parse_compressor( arg, pn, fmt_bz2, 1 ); break;
|
||||||
case gz_opt: parse_compressor( arg, fmt_gz, 1 ); break;
|
case gz_opt: parse_compressor( arg, pn, fmt_gz, 1 ); break;
|
||||||
case lz_opt: parse_compressor( arg, fmt_lz, 1 ); break;
|
case lz_opt: parse_compressor( arg, pn, fmt_lz, 1 ); break;
|
||||||
case xz_opt: parse_compressor( arg, fmt_xz, 1 ); break;
|
case xz_opt: parse_compressor( arg, pn, fmt_xz, 1 ); break;
|
||||||
case zst_opt: parse_compressor( arg, fmt_zst, 1 ); break;
|
case zst_opt: parse_compressor( arg, pn, fmt_zst, 1 ); break;
|
||||||
default : internal_error( "uncaught option." );
|
default : internal_error( "uncaught option." );
|
||||||
}
|
}
|
||||||
} // end process options
|
} // end process options
|
||||||
|
|
148
zcmp.cc
148
zcmp.cc
|
@ -40,7 +40,7 @@
|
||||||
#include "zutils.h"
|
#include "zutils.h"
|
||||||
|
|
||||||
#ifndef LLONG_MAX
|
#ifndef LLONG_MAX
|
||||||
#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
|
#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,27 +70,32 @@ void show_help()
|
||||||
" -h, --help display this help and exit\n"
|
" -h, --help display this help and exit\n"
|
||||||
" -V, --version output version information and exit\n"
|
" -V, --version output version information and exit\n"
|
||||||
" -b, --print-bytes print differing bytes\n"
|
" -b, --print-bytes print differing bytes\n"
|
||||||
|
" -H, --hexadecimal print hexadecimal values instead of octal\n"
|
||||||
" -i, --ignore-initial=<n>[:<n2>] ignore differences in the first <n> bytes\n"
|
" -i, --ignore-initial=<n>[:<n2>] ignore differences in the first <n> bytes\n"
|
||||||
" -l, --list list position, value of all differing bytes\n"
|
" -l, --list list position, value of all differing bytes\n"
|
||||||
" -M, --format=<list> process only the formats in <list>\n"
|
" -M, --format=<list> process only the formats in <list>\n"
|
||||||
" -n, --bytes=<n> compare at most <n> bytes\n"
|
" -n, --bytes=<n> compare at most <n> bytes\n"
|
||||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||||
" -O, --force-format=[<f1>][,<f2>] force the formats given (bz2,gz,lz,xz,zst)\n"
|
" -O, --force-format=[<f1>][,<f2>] force one or both input formats\n"
|
||||||
" -q, --quiet suppress all messages\n"
|
" -q, --quiet, --silent suppress diagnostics written to stderr\n"
|
||||||
" -s, --silent (same as --quiet)\n"
|
" -s, --script suppress messages about file differences\n"
|
||||||
" -v, --verbose verbose mode (same as --list)\n"
|
" -v, --verbose verbose mode (opposite of --quiet)\n"
|
||||||
" --bz2=<command> set compressor and options for bzip2 format\n"
|
" --bz2=<command> set compressor and options for bzip2 format\n"
|
||||||
" --gz=<command> set compressor and options for gzip format\n"
|
" --gz=<command> set compressor and options for gzip format\n"
|
||||||
" --lz=<command> set compressor and options for lzip format\n"
|
" --lz=<command> set compressor and options for lzip format\n"
|
||||||
" --xz=<command> set compressor and options for xz format\n"
|
" --xz=<command> set compressor and options for xz format\n"
|
||||||
" --zst=<command> set compressor and options for zstd format\n"
|
" --zst=<command> set compressor and options for zstd format\n"
|
||||||
"\nNumbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n"
|
"\nValid formats for options '-M' and '-O' are 'bz2', 'gz', 'lz', 'xz', 'zst',\n"
|
||||||
"Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n" );
|
"and 'un' for uncompressed.\n"
|
||||||
|
"\nByte counts given as arguments to options may be expressed in decimal,\n"
|
||||||
|
"hexadecimal, or octal (using the same syntax as integer constants in C++),\n"
|
||||||
|
"and 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();
|
show_help_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// separate large numbers >= 100_000 in groups of 3 digits using '_'
|
// separate numbers of 5 or more digits in groups of 3 digits using '_'
|
||||||
const char * format_num3( long long num )
|
const char * format_num3( long long num )
|
||||||
{
|
{
|
||||||
const char * const si_prefix = "kMGTPEZY";
|
const char * const si_prefix = "kMGTPEZY";
|
||||||
|
@ -103,20 +108,20 @@ const char * format_num3( long long num )
|
||||||
char * p = buf + bufsize - 1; // fill the buffer backwards
|
char * p = buf + bufsize - 1; // fill the buffer backwards
|
||||||
*p = 0; // terminator
|
*p = 0; // terminator
|
||||||
const bool negative = num < 0;
|
const bool negative = num < 0;
|
||||||
if( negative ) num = -num;
|
|
||||||
char prefix = 0; // try binary first, then si
|
char prefix = 0; // try binary first, then si
|
||||||
for( int i = 0; i < 8 && num >= 1024 && num % 1024 == 0; ++i )
|
for( int i = 0; i < 8 && num != 0 && ( num / 1024 ) * 1024 == num; ++i )
|
||||||
{ num /= 1024; prefix = binary_prefix[i]; }
|
{ num /= 1024; prefix = binary_prefix[i]; }
|
||||||
if( prefix ) *(--p) = 'i';
|
if( prefix ) *(--p) = 'i';
|
||||||
else
|
else
|
||||||
for( int i = 0; i < 8 && num >= 1000 && num % 1000 == 0; ++i )
|
for( int i = 0; i < 8 && num != 0 && ( num / 1000 ) * 1000 == num; ++i )
|
||||||
{ num /= 1000; prefix = si_prefix[i]; }
|
{ num /= 1000; prefix = si_prefix[i]; }
|
||||||
if( prefix ) *(--p) = prefix;
|
if( prefix ) *(--p) = prefix;
|
||||||
const bool split = num >= 100000;
|
const bool split = num >= 10000 || num <= -10000;
|
||||||
|
|
||||||
for( int i = 0; ; )
|
for( int i = 0; ; )
|
||||||
{
|
{
|
||||||
*(--p) = num % 10 + '0'; num /= 10; if( num == 0 ) break;
|
long long onum = num; num /= 10;
|
||||||
|
*(--p) = llabs( onum - ( 10 * num ) ) + '0'; if( num == 0 ) break;
|
||||||
if( split && ++i >= 3 ) { i = 0; *(--p) = '_'; }
|
if( split && ++i >= 3 ) { i = 0; *(--p) = '_'; }
|
||||||
}
|
}
|
||||||
if( negative ) *(--p) = '-';
|
if( negative ) *(--p) = '-';
|
||||||
|
@ -133,12 +138,8 @@ long long getnum( const char * const arg, const char * const option_name,
|
||||||
errno = 0;
|
errno = 0;
|
||||||
long long result = strtoll( arg, &tail, 0 );
|
long long result = strtoll( arg, &tail, 0 );
|
||||||
if( tail == arg )
|
if( tail == arg )
|
||||||
{
|
{ show_option_error( arg, "Bad or missing numerical argument in",
|
||||||
if( verbosity >= 0 )
|
option_name ); std::exit( 2 ); }
|
||||||
std::fprintf( stderr, "%s: Bad or missing numerical argument in "
|
|
||||||
"option '%s'.\n", program_name, option_name );
|
|
||||||
std::exit( 2 );
|
|
||||||
}
|
|
||||||
if( result < 0 ) errno = ERANGE;
|
if( result < 0 ) errno = ERANGE;
|
||||||
|
|
||||||
if( !errno && tail[0] && std::isalpha( tail[0] ) )
|
if( !errno && tail[0] && std::isalpha( tail[0] ) )
|
||||||
|
@ -163,12 +164,8 @@ long long getnum( const char * const arg, const char * const option_name,
|
||||||
case 'B': if( factor == 1000 && !bsuf ) exponent = 0; break;
|
case 'B': if( factor == 1000 && !bsuf ) exponent = 0; break;
|
||||||
}
|
}
|
||||||
if( exponent < 0 )
|
if( exponent < 0 )
|
||||||
{
|
{ show_option_error( arg, "Bad multiplier in numerical argument of",
|
||||||
if( verbosity >= 0 )
|
option_name ); std::exit( 2 ); }
|
||||||
std::fprintf( stderr, "%s: Bad multiplier in numerical argument of "
|
|
||||||
"option '%s'.\n", program_name, option_name );
|
|
||||||
std::exit( 2 );
|
|
||||||
}
|
|
||||||
for( int i = 0; i < exponent; ++i )
|
for( int i = 0; i < exponent; ++i )
|
||||||
{
|
{
|
||||||
if( ulimit / factor >= result ) result *= factor;
|
if( ulimit / factor >= result ) result *= factor;
|
||||||
|
@ -179,8 +176,8 @@ long long getnum( const char * const arg, const char * const option_name,
|
||||||
if( errno )
|
if( errno )
|
||||||
{
|
{
|
||||||
if( verbosity >= 0 )
|
if( verbosity >= 0 )
|
||||||
std::fprintf( stderr, "%s: Numerical argument out of limits [%s,%s] "
|
std::fprintf( stderr, "%s: '%s': Value out of limits [%s,%s] in "
|
||||||
"in option '%s'.\n", program_name, format_num3( llimit ),
|
"option '%s'.\n", program_name, arg, format_num3( llimit ),
|
||||||
format_num3( ulimit ), option_name );
|
format_num3( ulimit ), option_name );
|
||||||
std::exit( 2 );
|
std::exit( 2 );
|
||||||
}
|
}
|
||||||
|
@ -197,13 +194,7 @@ void parse_ignore_initial( const char * const arg, const char * const pn,
|
||||||
if( *tail == ':' || *tail == ',' )
|
if( *tail == ':' || *tail == ',' )
|
||||||
ignore_initial[1] = getnum( ++tail, pn );
|
ignore_initial[1] = getnum( ++tail, pn );
|
||||||
else if( *tail == 0 ) ignore_initial[1] = ignore_initial[0];
|
else if( *tail == 0 ) ignore_initial[1] = ignore_initial[0];
|
||||||
else
|
else { show_option_error( arg, "Missing colon in", pn ); std::exit( 2 ); }
|
||||||
{
|
|
||||||
if( verbosity >= 0 )
|
|
||||||
std::fprintf( stderr, "%s: Bad separator in argument of option '%s'.\n",
|
|
||||||
program_name, pn );
|
|
||||||
std::exit( 2 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,8 +218,8 @@ bool skip_ignore_initial( const long long ignore_initial, const int infd )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Put into buf the unsigned char c, making unprintable bytes
|
/* Put into buf the unsigned char c, making unprintable bytes visible by
|
||||||
// visible by quoting like cat -t does.
|
quoting like cat -t does. */
|
||||||
void sprintc( char * const buf, unsigned char c )
|
void sprintc( char * const buf, unsigned char c )
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -251,7 +242,7 @@ int block_compare( const uint8_t * const buffer0,
|
||||||
const uint8_t * p0 = buffer0;
|
const uint8_t * p0 = buffer0;
|
||||||
const uint8_t * p1 = buffer1;
|
const uint8_t * p1 = buffer1;
|
||||||
|
|
||||||
if( verbosity == 0 )
|
if( line_numberp )
|
||||||
{
|
{
|
||||||
int nl_count = 0;
|
int nl_count = 0;
|
||||||
while( *p0 == *p1 )
|
while( *p0 == *p1 )
|
||||||
|
@ -265,7 +256,8 @@ int block_compare( const uint8_t * const buffer0,
|
||||||
|
|
||||||
int cmp( const long long max_size, const int infd[2],
|
int cmp( const long long max_size, const int infd[2],
|
||||||
const std::string filenames[2], bool finished[2],
|
const std::string filenames[2], bool finished[2],
|
||||||
const bool print_bytes )
|
const bool hexadecimal, const bool list, const bool print_bytes,
|
||||||
|
const bool scripted )
|
||||||
{
|
{
|
||||||
const int buffer_size = 4096;
|
const int buffer_size = 4096;
|
||||||
unsigned long long byte_number = 1;
|
unsigned long long byte_number = 1;
|
||||||
|
@ -277,7 +269,7 @@ int cmp( const long long max_size, const int infd[2],
|
||||||
uint8_t * const buffer1 = buffer0 + buffer_size + 1;
|
uint8_t * const buffer1 = buffer0 + buffer_size + 1;
|
||||||
uint8_t * buffer[2];
|
uint8_t * buffer[2];
|
||||||
buffer[0] = buffer0; buffer[1] = buffer1;
|
buffer[0] = buffer0; buffer[1] = buffer1;
|
||||||
int different = 0;
|
int retval = 0;
|
||||||
|
|
||||||
while( rest > 0 )
|
while( rest > 0 )
|
||||||
{
|
{
|
||||||
|
@ -289,7 +281,7 @@ int cmp( const long long max_size, const int infd[2],
|
||||||
rd[i] = readblock( infd[i], buffer[i], size );
|
rd[i] = readblock( infd[i], buffer[i], size );
|
||||||
if( rd[i] != size && errno )
|
if( rd[i] != size && errno )
|
||||||
{ show_file_error( filenames[i].c_str(), "Read error", errno );
|
{ show_file_error( filenames[i].c_str(), "Read error", errno );
|
||||||
return 2; }
|
retval = 2; goto done; }
|
||||||
}
|
}
|
||||||
for( int i = 0; i < 2; ++i )
|
for( int i = 0; i < 2; ++i )
|
||||||
if( rd[i] < size ) finished[i] = true;
|
if( rd[i] < size ) finished[i] = true;
|
||||||
|
@ -298,13 +290,14 @@ int cmp( const long long max_size, const int infd[2],
|
||||||
buffer0[min_rd] = 0; // sentinels for the block compare
|
buffer0[min_rd] = 0; // sentinels for the block compare
|
||||||
buffer1[min_rd] = 1;
|
buffer1[min_rd] = 1;
|
||||||
|
|
||||||
int first_diff = block_compare( buffer0, buffer1, &line_number );
|
int first_diff = block_compare( buffer0, buffer1, list ? 0 : &line_number );
|
||||||
byte_number += first_diff;
|
byte_number += first_diff;
|
||||||
|
|
||||||
if( first_diff < min_rd )
|
if( first_diff < min_rd )
|
||||||
{
|
{
|
||||||
if( verbosity < 0 ) return 1; // return status only
|
retval = 1; // difference found
|
||||||
if( verbosity == 0 ) // show first difference
|
if( scripted ) break; // status only
|
||||||
|
if( !list ) // show first difference
|
||||||
{
|
{
|
||||||
if( !print_bytes )
|
if( !print_bytes )
|
||||||
std::printf( "%s %s differ: byte %llu, line %llu\n",
|
std::printf( "%s %s differ: byte %llu, line %llu\n",
|
||||||
|
@ -316,16 +309,17 @@ int cmp( const long long max_size, const int infd[2],
|
||||||
const unsigned char c1 = buffer1[first_diff];
|
const unsigned char c1 = buffer1[first_diff];
|
||||||
char buf0[5], buf1[5];
|
char buf0[5], buf1[5];
|
||||||
sprintc( buf0, c0 ); sprintc( buf1, c1 );
|
sprintc( buf0, c0 ); sprintc( buf1, c1 );
|
||||||
std::printf( "%s %s differ: byte %llu, line %llu is %3o %s %3o %s\n",
|
std::printf( hexadecimal ?
|
||||||
|
"%s %s differ: byte %llu, line %llu is %02X %s %02X %s\n" :
|
||||||
|
"%s %s differ: byte %llu, line %llu is %3o %s %3o %s\n",
|
||||||
filenames[0].c_str(), filenames[1].c_str(),
|
filenames[0].c_str(), filenames[1].c_str(),
|
||||||
byte_number, line_number, c0, buf0, c1, buf1 );
|
byte_number, line_number, c0, buf0, c1, buf1 );
|
||||||
}
|
}
|
||||||
std::fflush( stdout );
|
std::fflush( stdout );
|
||||||
return 1;
|
break;
|
||||||
}
|
}
|
||||||
else // verbosity > 0 ; show all differences
|
else // list ; show all differences
|
||||||
{
|
{
|
||||||
different = 1;
|
|
||||||
for( ; first_diff < min_rd; ++byte_number, ++first_diff )
|
for( ; first_diff < min_rd; ++byte_number, ++first_diff )
|
||||||
{
|
{
|
||||||
const unsigned char c0 = buffer0[first_diff];
|
const unsigned char c0 = buffer0[first_diff];
|
||||||
|
@ -333,12 +327,14 @@ int cmp( const long long max_size, const int infd[2],
|
||||||
if( c0 != c1 )
|
if( c0 != c1 )
|
||||||
{
|
{
|
||||||
if( !print_bytes )
|
if( !print_bytes )
|
||||||
std::printf( "%llu %3o %3o\n", byte_number, c0, c1 );
|
std::printf( hexadecimal ? "%llu %02X %02X\n" : "%llu %3o %3o\n",
|
||||||
|
byte_number, c0, c1 );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buf0[5], buf1[5];
|
char buf0[5], buf1[5];
|
||||||
sprintc( buf0, c0 ); sprintc( buf1, c1 );
|
sprintc( buf0, c0 ); sprintc( buf1, c1 );
|
||||||
std::printf( "%llu %3o %-4s %3o %s\n",
|
std::printf( hexadecimal ? "%llu %02X %-4s %02X %s\n" :
|
||||||
|
"%llu %3o %-4s %3o %s\n",
|
||||||
byte_number, c0, buf0, c1, buf1 );
|
byte_number, c0, buf0, c1, buf1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,15 +346,18 @@ int cmp( const long long max_size, const int infd[2],
|
||||||
if( rd[0] != rd[1] )
|
if( rd[0] != rd[1] )
|
||||||
{
|
{
|
||||||
if( verbosity >= 0 )
|
if( verbosity >= 0 )
|
||||||
std::fprintf( stderr, "%s: EOF on %s\n",
|
std::fprintf( stderr, list ?
|
||||||
program_name, filenames[rd[1]<rd[0]].c_str() );
|
"%s: EOF on %s after byte %llu\n" :
|
||||||
return 1;
|
"%s: EOF on %s after byte %llu, in line %llu\n",
|
||||||
|
program_name, filenames[rd[1]<rd[0]].c_str(),
|
||||||
|
byte_number - 1, line_number );
|
||||||
|
retval = 1; break;
|
||||||
}
|
}
|
||||||
if( min_rd != buffer_size ) break;
|
if( min_rd != buffer_size ) break;
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
delete[] buffer0;
|
delete[] buffer0;
|
||||||
return different;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
@ -370,8 +369,11 @@ int main( const int argc, const char * const argv[] )
|
||||||
// number of initial bytes ignored for each file
|
// number of initial bytes ignored for each file
|
||||||
long long ignore_initial[2] = { 0, 0 };
|
long long ignore_initial[2] = { 0, 0 };
|
||||||
long long max_size = -1; // < 0 means unlimited size
|
long long max_size = -1; // < 0 means unlimited size
|
||||||
int format_types[2] = { -1, -1 };
|
int format_types[2] = { -1, -1 }; // < 0 means undefined
|
||||||
bool print_bytes = false;
|
bool hexadecimal = false;
|
||||||
|
bool list = false; // list position, value of all differing bytes
|
||||||
|
bool print_bytes = false; // print differing bytes
|
||||||
|
bool scripted = false; // suppress messages about file differences
|
||||||
program_name = "zcmp";
|
program_name = "zcmp";
|
||||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||||
|
|
||||||
|
@ -379,6 +381,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
{
|
{
|
||||||
{ 'b', "print-bytes", Arg_parser::no },
|
{ 'b', "print-bytes", Arg_parser::no },
|
||||||
{ 'h', "help", Arg_parser::no },
|
{ 'h', "help", Arg_parser::no },
|
||||||
|
{ 'H', "hexadecimal", Arg_parser::no },
|
||||||
{ 'i', "ignore-initial", Arg_parser::yes },
|
{ 'i', "ignore-initial", Arg_parser::yes },
|
||||||
{ 'l', "list", Arg_parser::no },
|
{ 'l', "list", Arg_parser::no },
|
||||||
{ 'M', "format", Arg_parser::yes },
|
{ 'M', "format", Arg_parser::yes },
|
||||||
|
@ -386,7 +389,8 @@ int main( const int argc, const char * const argv[] )
|
||||||
{ 'N', "no-rcfile", Arg_parser::no },
|
{ 'N', "no-rcfile", Arg_parser::no },
|
||||||
{ 'O', "force-format", Arg_parser::yes },
|
{ 'O', "force-format", Arg_parser::yes },
|
||||||
{ 'q', "quiet", Arg_parser::no },
|
{ 'q', "quiet", Arg_parser::no },
|
||||||
{ 's', "silent", Arg_parser::no },
|
{ 'q', "silent", Arg_parser::no },
|
||||||
|
{ 's', "script", Arg_parser::no },
|
||||||
{ 'v', "verbose", Arg_parser::no },
|
{ 'v', "verbose", Arg_parser::no },
|
||||||
{ 'V', "version", Arg_parser::no },
|
{ 'V', "version", Arg_parser::no },
|
||||||
{ bz2_opt, "bz2", Arg_parser::yes },
|
{ bz2_opt, "bz2", Arg_parser::yes },
|
||||||
|
@ -414,21 +418,22 @@ int main( const int argc, const char * const argv[] )
|
||||||
{
|
{
|
||||||
case 'b': print_bytes = true; break;
|
case 'b': print_bytes = true; break;
|
||||||
case 'h': show_help(); return 0;
|
case 'h': show_help(); return 0;
|
||||||
|
case 'H': hexadecimal = true; break;
|
||||||
case 'i': parse_ignore_initial( arg, pn, ignore_initial ); break;
|
case 'i': parse_ignore_initial( arg, pn, ignore_initial ); break;
|
||||||
case 'l': verbosity = 1; break;
|
case 'l': list = true; break;
|
||||||
case 'M': parse_format_list( sarg, pn ); break;
|
case 'M': parse_format_list( sarg, pn ); break;
|
||||||
case 'n': max_size = getnum( arg, pn ); break;
|
case 'n': max_size = getnum( arg, pn ); break;
|
||||||
case 'N': break;
|
case 'N': break;
|
||||||
case 'O': parse_format_types2( sarg, pn, format_types ); break;
|
case 'O': parse_format_types2( sarg, pn, format_types ); break;
|
||||||
case 'q':
|
case 'q': verbosity = -1; break;
|
||||||
case 's': verbosity = -1; break;
|
case 's': scripted = true; break;
|
||||||
case 'v': verbosity = 1; break;
|
case 'v': if( verbosity < 4 ) ++verbosity; break;
|
||||||
case 'V': show_version(); return 0;
|
case 'V': show_version(); return 0;
|
||||||
case bz2_opt: parse_compressor( sarg, fmt_bz2 ); break;
|
case bz2_opt: parse_compressor( sarg, pn, fmt_bz2 ); break;
|
||||||
case gz_opt: parse_compressor( sarg, fmt_gz ); break;
|
case gz_opt: parse_compressor( sarg, pn, fmt_gz ); break;
|
||||||
case lz_opt: parse_compressor( sarg, fmt_lz ); break;
|
case lz_opt: parse_compressor( sarg, pn, fmt_lz ); break;
|
||||||
case xz_opt: parse_compressor( sarg, fmt_xz ); break;
|
case xz_opt: parse_compressor( sarg, pn, fmt_xz ); break;
|
||||||
case zst_opt: parse_compressor( sarg, fmt_zst ); break;
|
case zst_opt: parse_compressor( sarg, pn, fmt_zst ); break;
|
||||||
default : internal_error( "uncaught option." );
|
default : internal_error( "uncaught option." );
|
||||||
}
|
}
|
||||||
} // end process options
|
} // end process options
|
||||||
|
@ -438,12 +443,10 @@ int main( const int argc, const char * const argv[] )
|
||||||
setmode( STDOUT_FILENO, O_BINARY );
|
setmode( STDOUT_FILENO, O_BINARY );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( argind >= parser.arguments() )
|
|
||||||
{ show_error( "No files given.", 0, true ); return 2; }
|
|
||||||
if( parser.arguments() - argind > 2 )
|
|
||||||
{ show_error( "Too many files.", 0, true ); return 2; }
|
|
||||||
|
|
||||||
const int files = parser.arguments() - argind;
|
const int files = parser.arguments() - argind;
|
||||||
|
if( files < 1 ) { show_error( "No files given.", 0, true ); return 2; }
|
||||||
|
if( files > 2 ) { show_error( "Too many files.", 0, true ); return 2; }
|
||||||
|
|
||||||
std::string filenames[2]; // file names of the two input files
|
std::string filenames[2]; // file names of the two input files
|
||||||
filenames[0] = parser.argument( argind );
|
filenames[0] = parser.argument( argind );
|
||||||
if( files == 2 ) filenames[1] = parser.argument( argind + 1 );
|
if( files == 2 ) filenames[1] = parser.argument( argind + 1 );
|
||||||
|
@ -498,7 +501,8 @@ int main( const int argc, const char * const argv[] )
|
||||||
}
|
}
|
||||||
|
|
||||||
bool finished[2] = { false, false };
|
bool finished[2] = { false, false };
|
||||||
int retval = cmp( max_size, infd, filenames, finished, print_bytes );
|
int retval = cmp( max_size, infd, filenames, finished, hexadecimal, list,
|
||||||
|
print_bytes, scripted );
|
||||||
|
|
||||||
for( int i = 0; i < 2; ++i )
|
for( int i = 0; i < 2; ++i )
|
||||||
if( !good_status( children[i], finished[i] ) ) retval = 2;
|
if( !good_status( children[i], finished[i] ) ) retval = 2;
|
||||||
|
|
12
zcmpdiff.cc
12
zcmpdiff.cc
|
@ -54,11 +54,13 @@ void parse_format_types2( const std::string & arg, const char * const pn,
|
||||||
int format_types[2] )
|
int format_types[2] )
|
||||||
{
|
{
|
||||||
const unsigned i = std::min( arg.find( ',' ), arg.size() );
|
const unsigned i = std::min( arg.find( ',' ), arg.size() );
|
||||||
if( i > 0 ) format_types[0] = parse_format_type( arg.substr( 0, i ), pn );
|
if( i != std::min( arg.rfind( ',' ), arg.size() ) )
|
||||||
else format_types[0] = -1;
|
{ show_option_error( arg.c_str(), "Too many formats in", pn );
|
||||||
if( i + 1 < arg.size() ) format_types[1] =
|
std::exit( 1 ); }
|
||||||
parse_format_type( arg.substr( i + 1 ), pn );
|
format_types[0] =
|
||||||
else format_types[1] = -1;
|
( i > 0 ) ? parse_format_type( arg.substr( 0, i ), pn ) : -1;
|
||||||
|
format_types[1] =
|
||||||
|
( i + 1 < arg.size() ) ? parse_format_type( arg.substr( i + 1 ), pn ) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
55
zdiff.cc
55
zdiff.cc
|
@ -79,7 +79,7 @@ void show_help()
|
||||||
" -i, --ignore-case ignore case differences in file contents\n"
|
" -i, --ignore-case ignore case differences in file contents\n"
|
||||||
" -M, --format=<list> process only the formats in <list>\n"
|
" -M, --format=<list> process only the formats in <list>\n"
|
||||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||||
" -O, --force-format=[<f1>][,<f2>] force the formats given (bz2,gz,lz,xz,zst)\n"
|
" -O, --force-format=[<f1>][,<f2>] force one or both input formats\n"
|
||||||
" -p, --show-c-function show which C function each change is in\n"
|
" -p, --show-c-function show which C function each change is in\n"
|
||||||
" -q, --brief output only whether files differ\n"
|
" -q, --brief output only whether files differ\n"
|
||||||
" -s, --report-identical-files report when two files are identical\n"
|
" -s, --report-identical-files report when two files are identical\n"
|
||||||
|
@ -95,7 +95,9 @@ void show_help()
|
||||||
" --gz=<command> set compressor and options for gzip format\n"
|
" --gz=<command> set compressor and options for gzip format\n"
|
||||||
" --lz=<command> set compressor and options for lzip format\n"
|
" --lz=<command> set compressor and options for lzip format\n"
|
||||||
" --xz=<command> set compressor and options for xz format\n"
|
" --xz=<command> set compressor and options for xz format\n"
|
||||||
" --zst=<command> set compressor and options for zstd format\n" );
|
" --zst=<command> set compressor and options for zstd format\n"
|
||||||
|
"\nValid formats for options '-M' and '-O' are 'bz2', 'gz', 'lz', 'xz', 'zst',\n"
|
||||||
|
"and 'un' for uncompressed.\n" );
|
||||||
show_help_addr();
|
show_help_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +130,7 @@ bool set_fifonames( const std::string filenames[2] )
|
||||||
|
|
||||||
if( p ) { fifonames[0] = p; fifonames[0] += '/'; }
|
if( p ) { fifonames[0] = p; fifonames[0] += '/'; }
|
||||||
else fifonames[0] = "/tmp/";
|
else fifonames[0] = "/tmp/";
|
||||||
int n = getpid();
|
unsigned n = getpid();
|
||||||
do fifonames[0] += codes[n % num_codes]; while( n /= num_codes );
|
do fifonames[0] += codes[n % num_codes]; while( n /= num_codes );
|
||||||
const unsigned pos = fifonames[0].size();
|
const unsigned pos = fifonames[0].size();
|
||||||
fifonames[0] += '_';
|
fifonames[0] += '_';
|
||||||
|
@ -186,12 +188,8 @@ bool set_data_feeder( const std::string & filename,
|
||||||
{
|
{
|
||||||
const int outfd = open( fifoname.c_str(), O_WRONLY | O_BINARY );
|
const int outfd = open( fifoname.c_str(), O_WRONLY | O_BINARY );
|
||||||
if( outfd < 0 )
|
if( outfd < 0 )
|
||||||
{
|
{ show_file_error( fifoname.c_str(), "Can't open FIFO for writing",
|
||||||
if( verbosity >= 0 )
|
errno ); _exit( 2 ); }
|
||||||
std::fprintf( stderr, "%s: Can't open FIFO '%s' for writing: %s\n",
|
|
||||||
program_name, fifoname.c_str(), std::strerror( errno ) );
|
|
||||||
_exit( 2 );
|
|
||||||
}
|
|
||||||
if( dup2( fda[0], STDIN_FILENO ) >= 0 &&
|
if( dup2( fda[0], STDIN_FILENO ) >= 0 &&
|
||||||
dup2( outfd, STDOUT_FILENO ) >= 0 &&
|
dup2( outfd, STDOUT_FILENO ) >= 0 &&
|
||||||
close( fda[0] ) == 0 && close( fda[1] ) == 0 &&
|
close( fda[0] ) == 0 && close( fda[1] ) == 0 &&
|
||||||
|
@ -225,12 +223,8 @@ bool set_data_feeder( const std::string & filename,
|
||||||
{
|
{
|
||||||
const int outfd = open( fifoname.c_str(), O_WRONLY | O_BINARY );
|
const int outfd = open( fifoname.c_str(), O_WRONLY | O_BINARY );
|
||||||
if( outfd < 0 )
|
if( outfd < 0 )
|
||||||
{
|
{ show_file_error( fifoname.c_str(), "Can't open FIFO for writing",
|
||||||
if( verbosity >= 0 )
|
errno ); _exit( 2 ); }
|
||||||
std::fprintf( stderr, "%s: Can't open FIFO '%s' for writing: %s\n",
|
|
||||||
program_name, fifoname.c_str(), std::strerror( errno ) );
|
|
||||||
_exit( 2 );
|
|
||||||
}
|
|
||||||
if( !feed_data( filename, infd, outfd, magic_data, magic_size ) )
|
if( !feed_data( filename, infd, outfd, magic_data, magic_size ) )
|
||||||
_exit( 2 );
|
_exit( 2 );
|
||||||
if( close( outfd ) != 0 )
|
if( close( outfd ) != 0 )
|
||||||
|
@ -268,7 +262,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
{
|
{
|
||||||
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt, zst_opt };
|
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt, zst_opt };
|
||||||
std::vector< const char * > diff_args; // args to diff, maybe empty
|
std::vector< const char * > diff_args; // args to diff, maybe empty
|
||||||
int format_types[2] = { -1, -1 };
|
int format_types[2] = { -1, -1 }; // < 0 means undefined
|
||||||
program_name = "zdiff";
|
program_name = "zdiff";
|
||||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||||
|
|
||||||
|
@ -325,8 +319,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
case 'b': diff_args.push_back( "-b" ); break;
|
case 'b': diff_args.push_back( "-b" ); break;
|
||||||
case 'B': diff_args.push_back( "-B" ); break;
|
case 'B': diff_args.push_back( "-B" ); break;
|
||||||
case 'c': diff_args.push_back( "-c" ); break;
|
case 'c': diff_args.push_back( "-c" ); break;
|
||||||
case 'C': diff_args.push_back( "-C" );
|
case 'C': diff_args.push_back( "-C" ); diff_args.push_back( arg ); break;
|
||||||
diff_args.push_back( arg ); break;
|
|
||||||
case 'd': diff_args.push_back( "-d" ); break;
|
case 'd': diff_args.push_back( "-d" ); break;
|
||||||
case 'E': diff_args.push_back( "-E" ); break;
|
case 'E': diff_args.push_back( "-E" ); break;
|
||||||
case 'h': show_help(); return 0;
|
case 'h': show_help(); return 0;
|
||||||
|
@ -340,19 +333,17 @@ int main( const int argc, const char * const argv[] )
|
||||||
case 't': diff_args.push_back( "-t" ); break;
|
case 't': diff_args.push_back( "-t" ); break;
|
||||||
case 'T': diff_args.push_back( "-T" ); break;
|
case 'T': diff_args.push_back( "-T" ); break;
|
||||||
case 'u': diff_args.push_back( "-u" ); break;
|
case 'u': diff_args.push_back( "-u" ); break;
|
||||||
case 'U': diff_args.push_back( "-U" );
|
case 'U': diff_args.push_back( "-U" ); diff_args.push_back( arg ); break;
|
||||||
diff_args.push_back( arg ); break;
|
case 'v': if( verbosity < 4 ) ++verbosity; break;
|
||||||
case 'v': verbosity = 1; break;
|
|
||||||
case 'V': show_version( DIFF " --version" ); return 0;
|
case 'V': show_version( DIFF " --version" ); return 0;
|
||||||
case 'w': diff_args.push_back( "-w" ); break;
|
case 'w': diff_args.push_back( "-w" ); break;
|
||||||
case 'W': diff_args.push_back( "-W" );
|
case 'W': diff_args.push_back( "-W" ); diff_args.push_back( arg ); break;
|
||||||
diff_args.push_back( arg ); break;
|
|
||||||
case 'y': diff_args.push_back( "-y" ); break;
|
case 'y': diff_args.push_back( "-y" ); break;
|
||||||
case bz2_opt: parse_compressor( sarg, fmt_bz2 ); break;
|
case bz2_opt: parse_compressor( sarg, pn, fmt_bz2 ); break;
|
||||||
case gz_opt: parse_compressor( sarg, fmt_gz ); break;
|
case gz_opt: parse_compressor( sarg, pn, fmt_gz ); break;
|
||||||
case lz_opt: parse_compressor( sarg, fmt_lz ); break;
|
case lz_opt: parse_compressor( sarg, pn, fmt_lz ); break;
|
||||||
case xz_opt: parse_compressor( sarg, fmt_xz ); break;
|
case xz_opt: parse_compressor( sarg, pn, fmt_xz ); break;
|
||||||
case zst_opt: parse_compressor( sarg, fmt_zst ); break;
|
case zst_opt: parse_compressor( sarg, pn, fmt_zst ); break;
|
||||||
default : internal_error( "uncaught option." );
|
default : internal_error( "uncaught option." );
|
||||||
}
|
}
|
||||||
} // end process options
|
} // end process options
|
||||||
|
@ -362,12 +353,10 @@ int main( const int argc, const char * const argv[] )
|
||||||
setmode( STDOUT_FILENO, O_BINARY );
|
setmode( STDOUT_FILENO, O_BINARY );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( argind >= parser.arguments() )
|
|
||||||
{ show_error( "No files given.", 0, true ); return 2; }
|
|
||||||
if( parser.arguments() - argind > 2 )
|
|
||||||
{ show_error( "Too many files.", 0, true ); return 2; }
|
|
||||||
|
|
||||||
const int files = parser.arguments() - argind;
|
const int files = parser.arguments() - argind;
|
||||||
|
if( files < 1 ) { show_error( "No files given.", 0, true ); return 2; }
|
||||||
|
if( files > 2 ) { show_error( "Too many files.", 0, true ); return 2; }
|
||||||
|
|
||||||
std::string filenames[2]; // file names of the two input files
|
std::string filenames[2]; // file names of the two input files
|
||||||
filenames[0] = parser.argument( argind );
|
filenames[0] = parser.argument( argind );
|
||||||
if( files == 2 ) filenames[1] = parser.argument( argind + 1 );
|
if( files == 2 ) filenames[1] = parser.argument( argind + 1 );
|
||||||
|
|
40
zgrep.cc
40
zgrep.cc
|
@ -93,7 +93,7 @@ void show_help()
|
||||||
" -n, --line-number print the line number of each line\n"
|
" -n, --line-number print the line number of each line\n"
|
||||||
" -N, --no-rcfile don't read runtime configuration file\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, --only-matching show only the part of a line matching <pattern>\n"
|
||||||
" -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz, zst)\n"
|
" -O, --force-format=<fmt> force the input format\n"
|
||||||
" -P, --perl-regexp <pattern> is a Perl regular expression\n"
|
" -P, --perl-regexp <pattern> is a Perl regular expression\n"
|
||||||
" -q, --quiet, --silent suppress all messages\n"
|
" -q, --quiet, --silent suppress all messages\n"
|
||||||
" -r, --recursive operate recursively on directories\n"
|
" -r, --recursive operate recursively on directories\n"
|
||||||
|
@ -111,6 +111,8 @@ void show_help()
|
||||||
" --lz=<command> set compressor and options for lzip format\n"
|
" --lz=<command> set compressor and options for lzip format\n"
|
||||||
" --xz=<command> set compressor and options for xz format\n"
|
" --xz=<command> set compressor and options for xz format\n"
|
||||||
" --zst=<command> set compressor and options for zstd format\n"
|
" --zst=<command> set compressor and options for zstd format\n"
|
||||||
|
"\nValid formats for options '-M' and '-O' are 'bz2', 'gz', 'lz', 'xz', 'zst',\n"
|
||||||
|
"and 'un' for uncompressed.\n"
|
||||||
"\nNumbers 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" );
|
"Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n" );
|
||||||
show_help_addr();
|
show_help_addr();
|
||||||
|
@ -210,7 +212,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
{
|
{
|
||||||
enum { help_opt = 256, verbose_opt, color_opt, label_opt, linebuf_opt,
|
enum { help_opt = 256, verbose_opt, color_opt, label_opt, linebuf_opt,
|
||||||
bz2_opt, gz_opt, lz_opt, xz_opt, zst_opt };
|
bz2_opt, gz_opt, lz_opt, xz_opt, zst_opt };
|
||||||
int format_index = -1;
|
int format_index = -1; // undefined
|
||||||
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 recursive = 0; // 1 = '-r', 2 = '-R'
|
||||||
int show_name = -1; // tri-state bool
|
int show_name = -1; // tri-state bool
|
||||||
|
@ -222,7 +224,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
std::vector< const char * > grep_args; // args to grep, maybe empty
|
std::vector< const char * > grep_args; // args to grep, maybe empty
|
||||||
std::string color_option; // additional args to grep
|
std::string color_option; // additional args to grep
|
||||||
std::string label_option;
|
std::string label_option;
|
||||||
std::string label = "(standard input)"; // prefix for standard input
|
const char * label = "(standard input)"; // prefix for standard input
|
||||||
program_name = "zgrep";
|
program_name = "zgrep";
|
||||||
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
|
||||||
|
|
||||||
|
@ -294,19 +296,16 @@ int main( const int argc, const char * const argv[] )
|
||||||
switch( code )
|
switch( code )
|
||||||
{
|
{
|
||||||
case 'a': grep_args.push_back( "-a" ); break;
|
case 'a': grep_args.push_back( "-a" ); break;
|
||||||
case 'A': grep_args.push_back( "-A" );
|
case 'A': grep_args.push_back( "-A" ); grep_args.push_back( arg ); break;
|
||||||
grep_args.push_back( arg ); break;
|
|
||||||
case 'b': grep_args.push_back( "-b" ); break;
|
case 'b': grep_args.push_back( "-b" ); break;
|
||||||
case 'B': grep_args.push_back( "-B" );
|
case 'B': grep_args.push_back( "-B" ); grep_args.push_back( arg ); break;
|
||||||
grep_args.push_back( arg ); break;
|
|
||||||
case 'c': grep_args.push_back( "-c" ); break;
|
case 'c': grep_args.push_back( "-c" ); break;
|
||||||
case 'C': grep_args.push_back( "-C" );
|
case 'C': grep_args.push_back( "-C" ); grep_args.push_back( arg ); break;
|
||||||
grep_args.push_back( arg ); break;
|
case 'e': grep_args.push_back( "-e" ); grep_args.push_back( arg );
|
||||||
case 'e': grep_args.push_back( "-e" );
|
pattern_found = true; break;
|
||||||
grep_args.push_back( arg ); pattern_found = true; break;
|
|
||||||
case 'E': grep_args.push_back( "-E" ); break;
|
case 'E': grep_args.push_back( "-E" ); break;
|
||||||
case 'f': grep_args.push_back( "-f" );
|
case 'f': grep_args.push_back( "-f" ); grep_args.push_back( arg );
|
||||||
grep_args.push_back( arg ); pattern_found = true; break;
|
pattern_found = true; break;
|
||||||
case 'F': grep_args.push_back( "-F" ); break;
|
case 'F': grep_args.push_back( "-F" ); break;
|
||||||
case 'G': grep_args.push_back( "-G" ); break;
|
case 'G': grep_args.push_back( "-G" ); break;
|
||||||
case 'h': show_name = false; break;
|
case 'h': show_name = false; break;
|
||||||
|
@ -315,8 +314,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
case 'I': grep_args.push_back( "-I" ); break;
|
case 'I': grep_args.push_back( "-I" ); break;
|
||||||
case 'l': grep_args.push_back( "-l" ); list_mode = 1; break;
|
case 'l': grep_args.push_back( "-l" ); list_mode = 1; break;
|
||||||
case 'L': grep_args.push_back( "-L" ); list_mode = -1; break;
|
case 'L': grep_args.push_back( "-L" ); list_mode = -1; break;
|
||||||
case 'm': grep_args.push_back( "-m" );
|
case 'm': grep_args.push_back( "-m" ); grep_args.push_back( arg ); break;
|
||||||
grep_args.push_back( arg ); break;
|
|
||||||
case 'M': parse_format_list( sarg, pn ); break;
|
case 'M': parse_format_list( sarg, pn ); break;
|
||||||
case 'n': grep_args.push_back( "-n" ); break;
|
case 'n': grep_args.push_back( "-n" ); break;
|
||||||
case 'N': break;
|
case 'N': break;
|
||||||
|
@ -340,14 +338,14 @@ int main( const int argc, const char * const argv[] )
|
||||||
case color_opt: color_option = "--color";
|
case color_opt: color_option = "--color";
|
||||||
if( !sarg.empty() ) { color_option += '='; color_option += sarg; }
|
if( !sarg.empty() ) { color_option += '='; color_option += sarg; }
|
||||||
break;
|
break;
|
||||||
case label_opt: label_option = label = sarg; break;
|
case label_opt: label_option = sarg; label = arg; break;
|
||||||
case linebuf_opt: grep_args.push_back( "--line-buffered" );
|
case linebuf_opt: grep_args.push_back( "--line-buffered" );
|
||||||
line_buffered = true; break;
|
line_buffered = true; break;
|
||||||
case bz2_opt: parse_compressor( sarg, fmt_bz2 ); break;
|
case bz2_opt: parse_compressor( sarg, pn, fmt_bz2 ); break;
|
||||||
case gz_opt: parse_compressor( sarg, fmt_gz ); break;
|
case gz_opt: parse_compressor( sarg, pn, fmt_gz ); break;
|
||||||
case lz_opt: parse_compressor( sarg, fmt_lz ); break;
|
case lz_opt: parse_compressor( sarg, pn, fmt_lz ); break;
|
||||||
case xz_opt: parse_compressor( sarg, fmt_xz ); break;
|
case xz_opt: parse_compressor( sarg, pn, fmt_xz ); break;
|
||||||
case zst_opt: parse_compressor( sarg, fmt_zst ); break;
|
case zst_opt: parse_compressor( sarg, pn, fmt_zst ); break;
|
||||||
default : internal_error( "uncaught option." );
|
default : internal_error( "uncaught option." );
|
||||||
}
|
}
|
||||||
} // end process options
|
} // end process options
|
||||||
|
|
63
ztest.cc
63
ztest.cc
|
@ -50,14 +50,16 @@ namespace {
|
||||||
|
|
||||||
void show_help()
|
void show_help()
|
||||||
{
|
{
|
||||||
std::printf( "ztest verifies the integrity of the compressed files specified.\n"
|
std::printf( "ztest verifies the integrity of the compressed files specified. It\n"
|
||||||
"Uncompressed files are ignored. If a file is specified as '-', the\n"
|
"also warns if an uncompressed file has a compressed file name extension, or\n"
|
||||||
"integrity of compressed data read from standard input is verified. Data\n"
|
"if a compressed file has a wrong compressed extension. Uncompressed files\n"
|
||||||
"read from standard input must be all in the same compressed format. If\n"
|
"are otherwise ignored. If a file is specified as '-', the integrity of\n"
|
||||||
"a file fails to decompress, does not exist, can't be opened, or is a\n"
|
"compressed data read from standard input is verified. Data read from\n"
|
||||||
"terminal, ztest continues verifying the rest of the files. A final\n"
|
"standard input must be all in the same compressed format. If a file fails to\n"
|
||||||
"diagnostic is shown at verbosity level 1 or higher if any file fails the\n"
|
"decompress, does not exist, can't be opened, or is a terminal, ztest\n"
|
||||||
"test when testing multiple files.\n"
|
"continues verifying the rest of the files. A final diagnostic is shown at\n"
|
||||||
|
"verbosity level 1 or higher if any file fails the test when testing multiple\n"
|
||||||
|
"files.\n"
|
||||||
"\nIf no files are specified, recursive searches examine the current\n"
|
"\nIf no files are specified, recursive searches examine the current\n"
|
||||||
"working directory, and nonrecursive searches read standard input.\n"
|
"working directory, and nonrecursive searches read standard input.\n"
|
||||||
"\nThe formats supported are bzip2, gzip, lzip, xz, and zstd.\n"
|
"\nThe formats supported are bzip2, gzip, lzip, xz, and zstd.\n"
|
||||||
|
@ -69,14 +71,15 @@ void show_help()
|
||||||
"always be verified as reliably as files in the other formats can.\n"
|
"always be verified as reliably as files in the other formats can.\n"
|
||||||
"\nUsage: ztest [options] [files]\n"
|
"\nUsage: ztest [options] [files]\n"
|
||||||
"\nExit status is 0 if all compressed files verify OK, 1 if environmental\n"
|
"\nExit status is 0 if all compressed files verify OK, 1 if environmental\n"
|
||||||
"problems (file not found, invalid flags, I/O errors, etc), 2 if any\n"
|
"problems (file not found, invalid command line options, I/O errors, etc),\n"
|
||||||
"compressed file is corrupt or invalid.\n"
|
"2 if any compressed file is corrupt or invalid, or if any file has an\n"
|
||||||
|
"incorrect file name extension.\n"
|
||||||
"\nOptions:\n"
|
"\nOptions:\n"
|
||||||
" -h, --help display this help and exit\n"
|
" -h, --help display this help and exit\n"
|
||||||
" -V, --version output version information and exit\n"
|
" -V, --version output version information and exit\n"
|
||||||
" -M, --format=<list> process only the formats in <list>\n"
|
" -M, --format=<list> process only the formats in <list>\n"
|
||||||
" -N, --no-rcfile don't read runtime configuration file\n"
|
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||||
" -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz, zst)\n"
|
" -O, --force-format=<fmt> force the input format\n"
|
||||||
" -q, --quiet suppress all messages\n"
|
" -q, --quiet suppress all messages\n"
|
||||||
" -r, --recursive operate recursively on directories\n"
|
" -r, --recursive operate recursively on directories\n"
|
||||||
" -R, --dereference-recursive recursively follow symbolic links\n"
|
" -R, --dereference-recursive recursively follow symbolic links\n"
|
||||||
|
@ -85,7 +88,8 @@ void show_help()
|
||||||
" --gz=<command> set compressor and options for gzip format\n"
|
" --gz=<command> set compressor and options for gzip format\n"
|
||||||
" --lz=<command> set compressor and options for lzip format\n"
|
" --lz=<command> set compressor and options for lzip format\n"
|
||||||
" --xz=<command> set compressor and options for xz format\n"
|
" --xz=<command> set compressor and options for xz format\n"
|
||||||
" --zst=<command> set compressor and options for zstd format\n" );
|
" --zst=<command> set compressor and options for zstd format\n"
|
||||||
|
"\nValid formats for options '-M' and '-O' are 'bz2', 'gz', 'lz', 'xz', and 'zst'.\n" );
|
||||||
show_help_addr();
|
show_help_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,10 +121,8 @@ int ztest_stdin( const int infd, int format_index,
|
||||||
if( pid == 0 ) // child1 (compressor feeder)
|
if( pid == 0 ) // child1 (compressor feeder)
|
||||||
{
|
{
|
||||||
if( close( fda[0] ) != 0 ||
|
if( close( fda[0] ) != 0 ||
|
||||||
!feed_data( "", infd, fda[1], magic_data, magic_size ) )
|
!feed_data( "-", infd, fda[1], magic_data, magic_size ) ) _exit( 1 );
|
||||||
_exit( 1 );
|
if( close( fda[1] ) != 0 ) { show_close_error(); _exit( 1 ); }
|
||||||
if( close( fda[1] ) != 0 )
|
|
||||||
{ show_close_error(); _exit( 1 ); }
|
|
||||||
_exit( 0 );
|
_exit( 0 );
|
||||||
}
|
}
|
||||||
if( pid < 0 ) // parent
|
if( pid < 0 ) // parent
|
||||||
|
@ -170,11 +172,17 @@ int ztest_file( const int infd, int format_index,
|
||||||
static int disable_zst = -1; // tri-state bool
|
static int disable_zst = -1; // tri-state bool
|
||||||
uint8_t magic_data[magic_buf_size];
|
uint8_t magic_data[magic_buf_size];
|
||||||
int magic_size = 0;
|
int magic_size = 0;
|
||||||
|
const int format_index_e = test_extension( input_filename );
|
||||||
if( format_index < 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 );
|
const char * const compressor_name = get_compressor_name( format_index );
|
||||||
if( !compressor_name )
|
if( !compressor_name )
|
||||||
|
{
|
||||||
|
if( format_index < 0 && format_index_e >= 0 )
|
||||||
|
{ show_file_error( input_filename.c_str(),
|
||||||
|
"Uncompressed file has compressed extension." ); return 2; }
|
||||||
return 0; // ignore this file
|
return 0; // ignore this file
|
||||||
|
}
|
||||||
if( format_index == fmt_xz )
|
if( format_index == fmt_xz )
|
||||||
{
|
{
|
||||||
if( disable_xz < 0 )
|
if( disable_xz < 0 )
|
||||||
|
@ -226,7 +234,12 @@ int ztest_file( const int infd, int format_index,
|
||||||
{ show_fork_error( compressor_name ); return 1; }
|
{ show_fork_error( compressor_name ); return 1; }
|
||||||
|
|
||||||
const bool isgzxz = ( format_index == fmt_gz || format_index == fmt_xz );
|
const bool isgzxz = ( format_index == fmt_gz || format_index == fmt_xz );
|
||||||
return wait_for_child( pid, compressor_name, 1, isgzxz );
|
int retval = wait_for_child( pid, compressor_name, 1, isgzxz );
|
||||||
|
if( retval == 0 && format_index >= 0 && format_index_e >= 0 &&
|
||||||
|
format_index != format_index_e )
|
||||||
|
{ show_file_error( input_filename.c_str(),
|
||||||
|
"Compressed file has wrong compressed extension." ); retval = 2; }
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
@ -235,7 +248,7 @@ int ztest_file( const int infd, int format_index,
|
||||||
int main( const int argc, const char * const argv[] )
|
int main( const int argc, const char * const argv[] )
|
||||||
{
|
{
|
||||||
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt, zst_opt };
|
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt, zst_opt };
|
||||||
int format_index = -1;
|
int format_index = -1; // undefined
|
||||||
int recursive = 0; // 1 = '-r', 2 = '-R'
|
int recursive = 0; // 1 = '-r', 2 = '-R'
|
||||||
std::list< std::string > filenames;
|
std::list< std::string > filenames;
|
||||||
std::vector< const char * > ztest_args; // args to ztest, maybe empty
|
std::vector< const char * > ztest_args; // args to ztest, maybe empty
|
||||||
|
@ -278,18 +291,18 @@ int main( const int argc, const char * const argv[] )
|
||||||
case 'h': show_help(); return 0;
|
case 'h': show_help(); return 0;
|
||||||
case 'M': parse_format_list( arg, pn ); break;
|
case 'M': parse_format_list( arg, pn ); break;
|
||||||
case 'N': break;
|
case 'N': break;
|
||||||
case 'O': format_index = parse_format_type( arg, pn ); break;
|
case 'O': format_index = parse_format_type( arg, pn, false ); break;
|
||||||
case 'q': verbosity = -1; ztest_args.push_back( "-q" ); break;
|
case 'q': verbosity = -1; ztest_args.push_back( "-q" ); break;
|
||||||
case 'r': recursive = 1; break;
|
case 'r': recursive = 1; break;
|
||||||
case 'R': recursive = 2; break;
|
case 'R': recursive = 2; break;
|
||||||
case 'v': if( verbosity < 4 ) ++verbosity;
|
case 'v': if( verbosity < 4 ) ++verbosity;
|
||||||
ztest_args.push_back( "-v" ); break;
|
ztest_args.push_back( "-v" ); break;
|
||||||
case 'V': show_version(); return 0;
|
case 'V': show_version(); return 0;
|
||||||
case bz2_opt: parse_compressor( arg, fmt_bz2, 1 ); break;
|
case bz2_opt: parse_compressor( arg, pn, fmt_bz2, 1 ); break;
|
||||||
case gz_opt: parse_compressor( arg, fmt_gz, 1 ); break;
|
case gz_opt: parse_compressor( arg, pn, fmt_gz, 1 ); break;
|
||||||
case lz_opt: parse_compressor( arg, fmt_lz, 1 ); break;
|
case lz_opt: parse_compressor( arg, pn, fmt_lz, 1 ); break;
|
||||||
case xz_opt: parse_compressor( arg, fmt_xz, 1 ); break;
|
case xz_opt: parse_compressor( arg, pn, fmt_xz, 1 ); break;
|
||||||
case zst_opt: parse_compressor( arg, fmt_zst, 1 ); break;
|
case zst_opt: parse_compressor( arg, pn, fmt_zst, 1 ); break;
|
||||||
default : internal_error( "uncaught option." );
|
default : internal_error( "uncaught option." );
|
||||||
}
|
}
|
||||||
} // end process options
|
} // end process options
|
||||||
|
@ -325,7 +338,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
|
|
||||||
if( isatty( infd ) ) // for example /dev/tty
|
if( isatty( infd ) ) // for example /dev/tty
|
||||||
{
|
{
|
||||||
show_file_error( input_filename == "-" ? "(stdin)" : input_filename.c_str(),
|
show_file_error( name_or_stdin( input_filename.c_str() ),
|
||||||
"I won't read compressed data from a terminal." );
|
"I won't read compressed data from a terminal." );
|
||||||
close( infd ); error = true; continue;
|
close( infd ); error = true; continue;
|
||||||
}
|
}
|
||||||
|
|
157
zupdate.cc
157
zupdate.cc
|
@ -73,11 +73,12 @@ void show_help()
|
||||||
"\nExit status is 0 if all the compressed files were successfully recompressed\n"
|
"\nExit status is 0 if all the compressed files were successfully recompressed\n"
|
||||||
"(if needed), compared, and deleted (if requested). 1 if a non-fatal error\n"
|
"(if needed), compared, and deleted (if requested). 1 if a non-fatal error\n"
|
||||||
"occurred (file not found or not regular, or has invalid format, or can't be\n"
|
"occurred (file not found or not regular, or has invalid format, or can't be\n"
|
||||||
"deleted). 2 if a fatal error occurred (compressor can't be run, or\n"
|
"deleted). 2 if a fatal error occurred (invalid command line options,\n"
|
||||||
"comparison fails).\n"
|
"compressor can't be run, or comparison fails).\n"
|
||||||
"\nOptions:\n"
|
"\nOptions:\n"
|
||||||
" -h, --help display this help and exit\n"
|
" -h, --help display this help and exit\n"
|
||||||
" -V, --version output version information and exit\n"
|
" -V, --version output version information and exit\n"
|
||||||
|
" -d, --destdir=<dir> write recompressed files into <dir>\n"
|
||||||
" -e, --expand-extensions expand combined extensions; tgz -> tar.lz\n"
|
" -e, --expand-extensions expand combined extensions; tgz -> tar.lz\n"
|
||||||
" -f, --force don't skip a file even if the .lz exists\n"
|
" -f, --force don't skip a file even if the .lz exists\n"
|
||||||
" -i, --ignore-errors ignore non-fatal errors\n"
|
" -i, --ignore-errors ignore non-fatal errors\n"
|
||||||
|
@ -94,11 +95,60 @@ void show_help()
|
||||||
" --gz=<command> set compressor and options for gzip format\n"
|
" --gz=<command> set compressor and options for gzip format\n"
|
||||||
" --lz=<command> set compressor and options for lzip format\n"
|
" --lz=<command> set compressor and options for lzip format\n"
|
||||||
" --xz=<command> set compressor and options for xz format\n"
|
" --xz=<command> set compressor and options for xz format\n"
|
||||||
" --zst=<command> set compressor and options for zstd format\n" );
|
" --zst=<command> set compressor and options for zstd format\n"
|
||||||
|
"\nValid formats for option '-M' are 'bz2', 'gz', 'lz', 'xz', and 'zst'.\n" );
|
||||||
show_help_addr();
|
show_help_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void extract_srcdir_name( const std::string & name, std::string & srcdir )
|
||||||
|
{
|
||||||
|
if( name.empty() || name == "." ) return; // leave srcdir empty
|
||||||
|
if( name[name.size()-1] == '/' ) // remove last slash
|
||||||
|
{ srcdir.assign( name, 0, name.size() - 1 ); return; }
|
||||||
|
struct stat st;
|
||||||
|
if( stat( name.c_str(), &st ) == 0 && S_ISDIR( st.st_mode ) )
|
||||||
|
{ srcdir = name; return; }
|
||||||
|
|
||||||
|
unsigned size = 0; // size of srcdir without last slash nor basename
|
||||||
|
for( unsigned i = name.size(); i > 0; --i )
|
||||||
|
if( name[i-1] == '/' ) { size = i - 1; break; }
|
||||||
|
if( size > 0 ) srcdir.assign( name, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool make_dirs( const std::string & name )
|
||||||
|
{
|
||||||
|
static std::string cached_dirname;
|
||||||
|
unsigned dirsize = name.size(); // size of dirname without last slash
|
||||||
|
|
||||||
|
for( unsigned i = name.size(); i > 0; --i )
|
||||||
|
if( name[i-1] == '/' ) { dirsize = i - 1; break; }
|
||||||
|
if( dirsize >= name.size() ) return true; // no dirname
|
||||||
|
if( dirsize == 0 ) return true; // dirname is '/'
|
||||||
|
if( cached_dirname.size() == dirsize &&
|
||||||
|
cached_dirname.compare( 0, dirsize, name ) == 0 ) return true;
|
||||||
|
|
||||||
|
for( unsigned i = 0; i < dirsize; )
|
||||||
|
{
|
||||||
|
while( i < dirsize && name[i] == '/' ) ++i;
|
||||||
|
const unsigned first = i;
|
||||||
|
while( i < dirsize && name[i] != '/' ) ++i;
|
||||||
|
if( first < i )
|
||||||
|
{
|
||||||
|
std::string partial( name, 0, i );
|
||||||
|
struct stat st;
|
||||||
|
if( stat( partial.c_str(), &st ) == 0 )
|
||||||
|
{ if( !S_ISDIR( st.st_mode ) ) return false; }
|
||||||
|
else if( mkdir( partial.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH |
|
||||||
|
S_IXOTH ) != 0 && errno != EEXIST ) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cached_dirname.assign( name, 0, dirsize );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cant_execute( const std::string & command, const int status )
|
void cant_execute( const std::string & command, const int status )
|
||||||
{
|
{
|
||||||
if( verbosity >= 0 )
|
if( verbosity >= 0 )
|
||||||
|
@ -137,13 +187,14 @@ void set_permissions( const char * const rname, const struct stat & in_stats )
|
||||||
// Return value: 0 = success, -1 = file skipped, 1 = error, 2 = fatal error.
|
// Return value: 0 = success, -1 = file skipped, 1 = error, 2 = fatal error.
|
||||||
int zupdate_file( const std::string & name, const char * const lzip_name,
|
int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
const std::vector< std::string > & lzip_args2,
|
const std::vector< std::string > & lzip_args2,
|
||||||
|
const std::string & srcdir, const std::string & destdir,
|
||||||
const bool expand, const bool force,
|
const bool expand, const bool force,
|
||||||
const bool keep_input_files, const bool no_rcfile )
|
const bool keep_input_files, const bool no_rcfile )
|
||||||
{
|
{
|
||||||
// bzip2, gzip, and lzip are the primary formats. xz and zstd are optional.
|
// bzip2, gzip, and lzip are the primary formats. xz and zstd are optional.
|
||||||
static int disable_xz = -1; // tri-state bool
|
static int disable_xz = -1; // tri-state bool
|
||||||
static int disable_zst = -1; // tri-state bool
|
static int disable_zst = -1; // tri-state bool
|
||||||
int format_index = -1;
|
int format_index = -1; // undefined
|
||||||
std::string rname; // recompressed name
|
std::string rname; // recompressed name
|
||||||
|
|
||||||
const int eindex = extension_index( name ); // search extension
|
const int eindex = extension_index( name ); // search extension
|
||||||
|
@ -157,7 +208,18 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
program_name, name.c_str(), extension_from( eindex ) );
|
program_name, name.c_str(), extension_from( eindex ) );
|
||||||
return 0; // ignore this file
|
return 0; // ignore this file
|
||||||
}
|
}
|
||||||
rname.assign( name, 0, name.size() - std::strlen( extension_from( eindex ) ) );
|
if( destdir.size() )
|
||||||
|
{
|
||||||
|
if( srcdir.size() && name.compare( 0, srcdir.size(), srcdir ) != 0 )
|
||||||
|
internal_error( "srcdir mismatch." );
|
||||||
|
rname = destdir;
|
||||||
|
if( rname[rname.size()-1] != '/' && name[srcdir.size()] != '/' )
|
||||||
|
rname += '/';
|
||||||
|
rname.append( name, srcdir.size(), name.size() - srcdir.size() -
|
||||||
|
std::strlen( extension_from( eindex ) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rname.assign( name, 0, name.size() - std::strlen( extension_from( eindex ) ) );
|
||||||
rname += ( std::strcmp( extension_to( eindex ), ".tar" ) == 0 ) ?
|
rname += ( std::strcmp( extension_to( eindex ), ".tar" ) == 0 ) ?
|
||||||
( expand ? ".tar.lz" : ".tlz" ) : ".lz";
|
( expand ? ".tar.lz" : ".tlz" ) : ".lz";
|
||||||
}
|
}
|
||||||
|
@ -172,19 +234,11 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
|
|
||||||
struct stat in_stats;
|
struct stat in_stats;
|
||||||
if( stat( name.c_str(), &in_stats ) != 0 ) // check input file
|
if( stat( name.c_str(), &in_stats ) != 0 ) // check input file
|
||||||
{
|
{ show_file_error( name.c_str(), "Can't stat input file", errno );
|
||||||
if( verbosity >= 0 )
|
return 1; }
|
||||||
std::fprintf( stderr, "%s: Can't stat input file '%s': %s\n",
|
|
||||||
program_name, name.c_str(), std::strerror( errno ) );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if( !S_ISREG( in_stats.st_mode ) )
|
if( !S_ISREG( in_stats.st_mode ) )
|
||||||
{
|
{ show_file_error( name.c_str(), "Input file is not a regular file." );
|
||||||
if( verbosity >= 0 )
|
return 1; }
|
||||||
std::fprintf( stderr, "%s: Input file '%s' is not a regular file.\n",
|
|
||||||
program_name, name.c_str() );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct stat st; // not used
|
struct stat st; // not used
|
||||||
const std::string rname2( rname + ".lz" ); // produced by lzip < 1.20
|
const std::string rname2( rname + ".lz" ); // produced by lzip < 1.20
|
||||||
|
@ -206,8 +260,8 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
std::string command( compressor_name ); command += " -V > /dev/null 2>&1";
|
std::string command( compressor_name ); command += " -V > /dev/null 2>&1";
|
||||||
disable_xz = ( std::system( command.c_str() ) != 0 );
|
disable_xz = ( std::system( command.c_str() ) != 0 );
|
||||||
if( disable_xz && verbosity >= 2 )
|
if( disable_xz && verbosity >= 2 )
|
||||||
std::fprintf( stderr, "%s: '%s' not found. Ignoring xz files.\n",
|
show_file_error( compressor_name,
|
||||||
program_name, compressor_name );
|
"Xz decompressor not found. Ignoring xz files." );
|
||||||
}
|
}
|
||||||
if( disable_xz ) return 0; // ignore this file if no xz installed
|
if( disable_xz ) return 0; // ignore this file if no xz installed
|
||||||
}
|
}
|
||||||
|
@ -218,8 +272,8 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
std::string command( compressor_name ); command += " -V > /dev/null 2>&1";
|
std::string command( compressor_name ); command += " -V > /dev/null 2>&1";
|
||||||
disable_zst = ( std::system( command.c_str() ) != 0 );
|
disable_zst = ( std::system( command.c_str() ) != 0 );
|
||||||
if( disable_zst && verbosity >= 2 )
|
if( disable_zst && verbosity >= 2 )
|
||||||
std::fprintf( stderr, "%s: '%s' not found. Ignoring zstd files.\n",
|
show_file_error( compressor_name,
|
||||||
program_name, compressor_name );
|
"Zstd decompressor not found. Ignoring zstd files." );
|
||||||
}
|
}
|
||||||
if( disable_zst ) return 0; // ignore this file if no zstd installed
|
if( disable_zst ) return 0; // ignore this file if no zstd installed
|
||||||
}
|
}
|
||||||
|
@ -228,6 +282,9 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
{
|
{
|
||||||
if( verbosity >= 1 )
|
if( verbosity >= 1 )
|
||||||
std::fprintf( stderr, "Recompressing file '%s'\n", name.c_str() );
|
std::fprintf( stderr, "Recompressing file '%s'\n", name.c_str() );
|
||||||
|
if( destdir.size() && !make_dirs( rname ) )
|
||||||
|
{ show_file_error( rname.c_str(), "Error creating intermediate directory." );
|
||||||
|
return 2; }
|
||||||
int fda[2]; // pipe between decompressor and compressor
|
int fda[2]; // pipe between decompressor and compressor
|
||||||
if( pipe( fda ) < 0 )
|
if( pipe( fda ) < 0 )
|
||||||
{ show_error( "Can't create pipe", errno ); return 2; }
|
{ show_error( "Can't create pipe", errno ); return 2; }
|
||||||
|
@ -264,8 +321,8 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
{
|
{
|
||||||
const std::vector< std::string > & lzip_args =
|
const std::vector< std::string > & lzip_args =
|
||||||
get_compressor_args( fmt_lz );
|
get_compressor_args( fmt_lz );
|
||||||
const int size = lzip_args.size();
|
const int size = lzip_args.size(); // from .conf or --lz
|
||||||
const int size2 = lzip_args2.size();
|
const int size2 = lzip_args2.size(); // from command line
|
||||||
const char ** const argv = new const char *[size+size2+5];
|
const char ** const argv = new const char *[size+size2+5];
|
||||||
argv[0] = lzip_name;
|
argv[0] = lzip_name;
|
||||||
argv[1] = "-9";
|
argv[1] = "-9";
|
||||||
|
@ -299,13 +356,14 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
{
|
{
|
||||||
if( lz_exists && verbosity >= 1 )
|
if( lz_exists && verbosity >= 1 )
|
||||||
std::fprintf( stderr, "Comparing file '%s'\n", name.c_str() );
|
std::fprintf( stderr, "Comparing file '%s'\n", name.c_str() );
|
||||||
|
// Quote names in zcmp_command to allow file/dir names with spaces.
|
||||||
std::string zcmp_command( invocation_name );
|
std::string zcmp_command( invocation_name );
|
||||||
unsigned i = zcmp_command.size();
|
unsigned i = zcmp_command.size();
|
||||||
while( i > 0 && zcmp_command[i-1] != '/' ) --i; // strip "zupdate"
|
while( i > 0 && zcmp_command[i-1] != '/' ) --i; // strip "zupdate"
|
||||||
zcmp_command.resize( i ); zcmp_command.insert( zcmp_command.begin(), '\'' );
|
zcmp_command.resize( i ); zcmp_command.insert( zcmp_command.begin(), '\'' );
|
||||||
zcmp_command += "zcmp' "; // '[dir/]zcmp'
|
zcmp_command += "zcmp' "; // '[dir/]zcmp'
|
||||||
if( no_rcfile ) zcmp_command += "-N ";
|
if( no_rcfile ) zcmp_command += "-N ";
|
||||||
if( verbosity < 0 ) zcmp_command += "-q ";
|
if( verbosity < 0 ) zcmp_command += "-q -s ";
|
||||||
zcmp_command += '\''; zcmp_command += name;
|
zcmp_command += '\''; zcmp_command += name;
|
||||||
zcmp_command += "' '"; zcmp_command += rname; zcmp_command += '\'';
|
zcmp_command += "' '"; zcmp_command += rname; zcmp_command += '\'';
|
||||||
int status = std::system( zcmp_command.c_str() );
|
int status = std::system( zcmp_command.c_str() );
|
||||||
|
@ -315,12 +373,8 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !keep_input_files && std::remove( name.c_str() ) != 0 && errno != ENOENT )
|
if( !keep_input_files && std::remove( name.c_str() ) != 0 && errno != ENOENT )
|
||||||
{
|
{ show_file_error( name.c_str(), "Can't delete input file", errno );
|
||||||
if( verbosity >= 0 )
|
return 1; }
|
||||||
std::fprintf( stderr, "%s: Can't delete input file '%s': %s\n",
|
|
||||||
program_name, name.c_str(), std::strerror( errno ) );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +385,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
{
|
{
|
||||||
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt, zst_opt };
|
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt, zst_opt };
|
||||||
int recursive = 0; // 1 = '-r', 2 = '-R'
|
int recursive = 0; // 1 = '-r', 2 = '-R'
|
||||||
std::list< std::string > filenames;
|
std::string destdir; // write recompressed files here
|
||||||
std::vector< std::string > lzip_args2; // args to lzip, maybe empty
|
std::vector< std::string > lzip_args2; // args to lzip, maybe empty
|
||||||
bool expand = false;
|
bool expand = false;
|
||||||
bool force = false;
|
bool force = false;
|
||||||
|
@ -353,6 +407,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
{ '7', 0, Arg_parser::no },
|
{ '7', 0, Arg_parser::no },
|
||||||
{ '8', 0, Arg_parser::no },
|
{ '8', 0, Arg_parser::no },
|
||||||
{ '9', 0, Arg_parser::no },
|
{ '9', 0, Arg_parser::no },
|
||||||
|
{ 'd', "destdir", Arg_parser::yes },
|
||||||
{ 'e', "expand-extensions", Arg_parser::no },
|
{ 'e', "expand-extensions", Arg_parser::no },
|
||||||
{ 'f', "force", Arg_parser::no },
|
{ 'f', "force", Arg_parser::no },
|
||||||
{ 'h', "help", Arg_parser::no },
|
{ 'h', "help", Arg_parser::no },
|
||||||
|
@ -391,6 +446,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
lzip_args2.push_back( "-" ); lzip_args2.back() += code; break;
|
lzip_args2.push_back( "-" ); lzip_args2.back() += code; break;
|
||||||
|
case 'd': destdir = arg; break;
|
||||||
case 'e': expand = true; break;
|
case 'e': expand = true; break;
|
||||||
case 'f': force = true; break;
|
case 'f': force = true; break;
|
||||||
case 'h': show_help(); return 0;
|
case 'h': show_help(); return 0;
|
||||||
|
@ -404,11 +460,11 @@ int main( const int argc, const char * const argv[] )
|
||||||
case 'R': recursive = 2; break;
|
case 'R': recursive = 2; break;
|
||||||
case 'v': if( verbosity < 4 ) ++verbosity; break;
|
case 'v': if( verbosity < 4 ) ++verbosity; break;
|
||||||
case 'V': show_version(); return 0;
|
case 'V': show_version(); return 0;
|
||||||
case bz2_opt: parse_compressor( arg, fmt_bz2, 1 ); break;
|
case bz2_opt: parse_compressor( arg, pn, fmt_bz2, 1 ); break;
|
||||||
case gz_opt: parse_compressor( arg, fmt_gz, 1 ); break;
|
case gz_opt: parse_compressor( arg, pn, fmt_gz, 1 ); break;
|
||||||
case lz_opt: parse_compressor( arg, fmt_lz, 1 ); break;
|
case lz_opt: parse_compressor( arg, pn, fmt_lz, 1 ); break;
|
||||||
case xz_opt: parse_compressor( arg, fmt_xz, 1 ); break;
|
case xz_opt: parse_compressor( arg, pn, fmt_xz, 1 ); break;
|
||||||
case zst_opt: parse_compressor( arg, fmt_zst, 1 ); break;
|
case zst_opt: parse_compressor( arg, pn, fmt_zst, 1 ); break;
|
||||||
default : internal_error( "uncaught option." );
|
default : internal_error( "uncaught option." );
|
||||||
}
|
}
|
||||||
} // end process options
|
} // end process options
|
||||||
|
@ -422,22 +478,31 @@ int main( const int argc, const char * const argv[] )
|
||||||
if( !lzip_name )
|
if( !lzip_name )
|
||||||
{ show_error( "Missing name of compressor for lzip format." ); return 2; }
|
{ show_error( "Missing name of compressor for lzip format." ); return 2; }
|
||||||
|
|
||||||
for( ; argind < parser.arguments(); ++argind )
|
std::list< std::string > filenames;
|
||||||
filenames.push_back( parser.argument( argind ) );
|
if( argind < parser.arguments() )
|
||||||
|
filenames.push_back( parser.argument( argind++ ) ); // first argument
|
||||||
if( filenames.empty() && recursive ) filenames.push_back( "." );
|
else if( recursive ) filenames.push_back( "." );
|
||||||
|
else return 0; // nothing to do
|
||||||
|
|
||||||
std::string input_filename;
|
std::string input_filename;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
bool error = false;
|
bool error = false;
|
||||||
while( next_filename( filenames, input_filename, error, recursive, true ) )
|
while( true )
|
||||||
{
|
{
|
||||||
int tmp = zupdate_file( input_filename, lzip_name, lzip_args2, expand,
|
std::string srcdir; // dirname to be replaced by destdir
|
||||||
force, keep_input_files, no_rcfile );
|
if( destdir.size() ) extract_srcdir_name( filenames.front(), srcdir );
|
||||||
if( tmp < 0 ) error = true;
|
while( next_filename( filenames, input_filename, error, recursive, true ) )
|
||||||
if( tmp > retval ) retval = tmp;
|
{
|
||||||
if( tmp >= 2 || ( tmp == 1 && !ignore_errors ) ) break;
|
int tmp = zupdate_file( input_filename, lzip_name, lzip_args2, srcdir,
|
||||||
|
destdir, expand, force, keep_input_files, no_rcfile );
|
||||||
|
if( tmp < 0 ) error = true; // file skipped
|
||||||
|
if( tmp > retval ) retval = tmp;
|
||||||
|
if( tmp >= 2 || ( tmp == 1 && !ignore_errors ) ) goto out;
|
||||||
|
}
|
||||||
|
if( argind >= parser.arguments() ) break;
|
||||||
|
filenames.push_back( parser.argument( argind++ ) );
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
if( error && retval == 0 ) retval = 1;
|
if( error && retval == 0 ) retval = 1;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
14
zutils.cc
14
zutils.cc
|
@ -110,7 +110,7 @@ int writeblock( const int fd, const uint8_t * const buf, const int size )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Empty filename means stdin.
|
// filename == "-" means stdin.
|
||||||
//
|
//
|
||||||
bool feed_data( const std::string & filename, const int infd, const int outfd,
|
bool feed_data( const std::string & filename, const int infd, const int outfd,
|
||||||
const uint8_t * magic_data, const int magic_size )
|
const uint8_t * magic_data, const int magic_size )
|
||||||
|
@ -123,8 +123,8 @@ bool feed_data( const std::string & filename, const int infd, const int outfd,
|
||||||
{
|
{
|
||||||
const int size = readblock( infd, buffer, buffer_size );
|
const int size = readblock( infd, buffer, buffer_size );
|
||||||
if( size != buffer_size && errno )
|
if( size != buffer_size && errno )
|
||||||
{ const char * const name = filename.empty() ? "-" : filename.c_str();
|
{ show_file_error( name_or_stdin( filename.c_str() ), "Read error",
|
||||||
show_file_error( name, "Read error", errno ); return false; }
|
errno ); return false; }
|
||||||
if( size > 0 && writeblock( outfd, buffer, size ) != size )
|
if( size > 0 && writeblock( outfd, buffer, size ) != size )
|
||||||
{ show_error( "Write error", errno ); return false; }
|
{ show_error( "Write error", errno ); return false; }
|
||||||
if( size < buffer_size ) break;
|
if( size < buffer_size ) break;
|
||||||
|
@ -183,8 +183,7 @@ bool set_data_feeder( const std::string & filename, int * const infdp,
|
||||||
close( fda2[0] ) != 0 || close( fda2[1] ) != 0 ||
|
close( fda2[0] ) != 0 || close( fda2[1] ) != 0 ||
|
||||||
!feed_data( filename, old_infd, fda[1], magic_data, magic_size ) )
|
!feed_data( filename, old_infd, fda[1], magic_data, magic_size ) )
|
||||||
_exit( 2 );
|
_exit( 2 );
|
||||||
if( close( fda[1] ) != 0 )
|
if( close( fda[1] ) != 0 ) { show_close_error(); _exit( 2 ); }
|
||||||
{ show_close_error(); _exit( 2 ); }
|
|
||||||
_exit( 0 );
|
_exit( 0 );
|
||||||
}
|
}
|
||||||
if( pid < 0 ) // parent
|
if( pid < 0 ) // parent
|
||||||
|
@ -232,8 +231,7 @@ bool set_data_feeder( const std::string & filename, int * const infdp,
|
||||||
if( close( fda[0] ) != 0 ||
|
if( close( fda[0] ) != 0 ||
|
||||||
!feed_data( filename, old_infd, fda[1], magic_data, magic_size ) )
|
!feed_data( filename, old_infd, fda[1], magic_data, magic_size ) )
|
||||||
_exit( 2 );
|
_exit( 2 );
|
||||||
if( close( fda[1] ) != 0 )
|
if( close( fda[1] ) != 0 ) { show_close_error(); _exit( 2 ); }
|
||||||
{ show_close_error(); _exit( 2 ); }
|
|
||||||
_exit( 0 );
|
_exit( 0 );
|
||||||
}
|
}
|
||||||
if( pid < 0 ) // parent
|
if( pid < 0 ) // parent
|
||||||
|
@ -246,7 +244,7 @@ bool set_data_feeder( const std::string & filename, int * const infdp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Return format index, or -1 if uncompressed.
|
// Return format_index, or -1 if uncompressed.
|
||||||
//
|
//
|
||||||
int test_format( const int infd, uint8_t magic_data[],
|
int test_format( const int infd, uint8_t magic_data[],
|
||||||
int * const magic_sizep )
|
int * const magic_sizep )
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
# Runtime Configuration file for Zutils
|
# Runtime Configuration file for Zutils
|
||||||
#
|
#
|
||||||
# Zutils looks for this file in:
|
# Zutils looks for this file in:
|
||||||
# 1 - $HOME/.zutilsrc
|
# 1 - $XDG_CONFIG_HOME/zutils.conf
|
||||||
# 2 - ${sysconfdir}/zutilsrc
|
# 2 - ${sysconfdir}/zutils.conf
|
||||||
|
# XDG_CONFIG_HOME defaults to $HOME/.config
|
||||||
|
|
||||||
# This file sets the compressor and options to be used for each format.
|
# This file sets the compressor and options to be used for each format.
|
||||||
# The command line options override compressors specified in this file.
|
# The command line options override compressors specified in this file.
|
5
zutils.h
5
zutils.h
|
@ -15,6 +15,9 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
inline const char * name_or_stdin( const char * const name )
|
||||||
|
{ return ( name[0] == '-' && name[1] == 0 ) ? "(stdin)" : name; }
|
||||||
|
|
||||||
int readblock( const int fd, uint8_t * const buf, const int size );
|
int readblock( const int fd, uint8_t * const buf, const int size );
|
||||||
int writeblock( const int fd, const uint8_t * const buf, const int size );
|
int writeblock( const int fd, const uint8_t * const buf, const int size );
|
||||||
bool feed_data( const std::string & filename, const int infd, const int outfd,
|
bool feed_data( const std::string & filename, const int infd, const int outfd,
|
||||||
|
@ -31,7 +34,7 @@ bool set_data_feeder( const std::string & filename, int * const infdp,
|
||||||
|
|
||||||
enum { magic_buf_size = 10 }; // >= longest extended magic (bzip2)
|
enum { magic_buf_size = 10 }; // >= longest extended magic (bzip2)
|
||||||
|
|
||||||
// Return format index, or -1 if uncompressed.
|
// Return format_index, or -1 if uncompressed.
|
||||||
//
|
//
|
||||||
int test_format( const int infd, uint8_t magic_data[],
|
int test_format( const int infd, uint8_t magic_data[],
|
||||||
int * const magic_sizep );
|
int * const magic_sizep );
|
||||||
|
|
Loading…
Add table
Reference in a new issue