Adding upstream version 1.2~pre2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
2ee9737b93
commit
c9a98be648
22 changed files with 804 additions and 87 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2013-09-04 Antonio Diaz Diaz <antonio@gnu.org>
|
||||||
|
|
||||||
|
* Version 1.2-pre2 released.
|
||||||
|
* Added new utility; zupdate.
|
||||||
|
|
||||||
2013-08-02 Antonio Diaz Diaz <antonio@gnu.org>
|
2013-08-02 Antonio Diaz Diaz <antonio@gnu.org>
|
||||||
|
|
||||||
* Version 1.1 released.
|
* Version 1.1 released.
|
||||||
|
|
3
INSTALL
3
INSTALL
|
@ -1,6 +1,7 @@
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
You will need a C++ compiler.
|
You will need a C++ compiler, (de)compressors for bzip2 and gzip
|
||||||
|
formats, and a compressor for the lzip format.
|
||||||
I use gcc 4.8.1 and 3.3.6, but the code should compile with any
|
I use gcc 4.8.1 and 3.3.6, but the code should compile with any
|
||||||
standards compliant compiler.
|
standards compliant compiler.
|
||||||
Gcc is available at http://gcc.gnu.org.
|
Gcc is available at http://gcc.gnu.org.
|
||||||
|
|
19
Makefile.in
19
Makefile.in
|
@ -10,6 +10,7 @@ SHELL = /bin/sh
|
||||||
objs = arg_parser.o rc.o zutils.o main.o
|
objs = arg_parser.o rc.o zutils.o main.o
|
||||||
zcmp_objs = arg_parser.o rc.o zutils.o zcmp.o
|
zcmp_objs = arg_parser.o rc.o zutils.o zcmp.o
|
||||||
zdiff_objs = arg_parser.o rc.o zutils.o zdiff.o
|
zdiff_objs = arg_parser.o rc.o zutils.o zdiff.o
|
||||||
|
zupdate_objs = arg_parser.o rc.o zutils.o zupdate.o
|
||||||
scripts = zcat zegrep zfgrep zgrep ztest
|
scripts = zcat zegrep zfgrep zgrep ztest
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ scripts = zcat zegrep zfgrep zgrep ztest
|
||||||
uninstall uninstall-bin uninstall-info uninstall-man \
|
uninstall uninstall-bin uninstall-info uninstall-man \
|
||||||
doc info man check dist clean distclean
|
doc info man check dist clean distclean
|
||||||
|
|
||||||
all : $(progname) zcmp zdiff $(scripts)
|
all : $(progname) zcmp zdiff zupdate $(scripts)
|
||||||
|
|
||||||
$(progname) : $(objs)
|
$(progname) : $(objs)
|
||||||
$(CXX) $(LDFLAGS) -o $@ $(objs)
|
$(CXX) $(LDFLAGS) -o $@ $(objs)
|
||||||
|
@ -51,6 +52,9 @@ ztest : ztest.in
|
||||||
cat $(VPATH)/ztest.in > $@
|
cat $(VPATH)/ztest.in > $@
|
||||||
chmod a+x ztest
|
chmod a+x ztest
|
||||||
|
|
||||||
|
zupdate : $(zupdate_objs)
|
||||||
|
$(CXX) $(LDFLAGS) -o $@ $(zupdate_objs)
|
||||||
|
|
||||||
main.o : main.cc
|
main.o : main.cc
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DGREP=\"$(GREP)\" -c -o $@ $<
|
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DGREP=\"$(GREP)\" -c -o $@ $<
|
||||||
|
|
||||||
|
@ -73,6 +77,7 @@ main.o : arg_parser.h zutils.h rc.h zcat.cc zgrep.cc ztest.cc
|
||||||
rc.o : arg_parser.h zutils.h rc.h
|
rc.o : arg_parser.h zutils.h rc.h
|
||||||
zcmp.o : arg_parser.h zutils.h rc.h zcmpdiff.cc Makefile
|
zcmp.o : arg_parser.h zutils.h rc.h zcmpdiff.cc Makefile
|
||||||
zdiff.o : arg_parser.h zutils.h rc.h zcmpdiff.cc Makefile
|
zdiff.o : arg_parser.h zutils.h rc.h zcmpdiff.cc Makefile
|
||||||
|
zupdate.o : arg_parser.h zutils.h rc.h Makefile
|
||||||
zutils.o : zutils.h rc.h
|
zutils.o : zutils.h rc.h
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,7 +89,7 @@ $(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texinfo
|
||||||
cd $(VPATH)/doc && makeinfo $(pkgname).texinfo
|
cd $(VPATH)/doc && makeinfo $(pkgname).texinfo
|
||||||
|
|
||||||
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/zgrep.1 $(VPATH)/doc/ztest.1 $(VPATH)/doc/zupdate.1
|
||||||
|
|
||||||
$(VPATH)/doc/zcat.1 : $(progname) zcat
|
$(VPATH)/doc/zcat.1 : $(progname) zcat
|
||||||
help2man -n 'decompress and concatenate files to standard output' \
|
help2man -n 'decompress and concatenate files to standard output' \
|
||||||
|
@ -106,6 +111,10 @@ $(VPATH)/doc/ztest.1 : $(progname) ztest
|
||||||
help2man -n 'verify integrity of compressed files' \
|
help2man -n 'verify integrity of compressed files' \
|
||||||
-o $@ --no-info ./ztest
|
-o $@ --no-info ./ztest
|
||||||
|
|
||||||
|
$(VPATH)/doc/zupdate.1 : zupdate
|
||||||
|
help2man -n 'recompress bzip2, gzip, xz files to lzip files' \
|
||||||
|
-o $@ --no-info ./zupdate
|
||||||
|
|
||||||
Makefile : $(VPATH)/configure $(VPATH)/Makefile.in
|
Makefile : $(VPATH)/configure $(VPATH)/Makefile.in
|
||||||
./config.status
|
./config.status
|
||||||
|
|
||||||
|
@ -124,6 +133,7 @@ install-bin : all
|
||||||
$(INSTALL_SCRIPT) ./zfgrep "$(DESTDIR)$(bindir)/zfgrep"
|
$(INSTALL_SCRIPT) ./zfgrep "$(DESTDIR)$(bindir)/zfgrep"
|
||||||
$(INSTALL_SCRIPT) ./zgrep "$(DESTDIR)$(bindir)/zgrep"
|
$(INSTALL_SCRIPT) ./zgrep "$(DESTDIR)$(bindir)/zgrep"
|
||||||
$(INSTALL_SCRIPT) ./ztest "$(DESTDIR)$(bindir)/ztest"
|
$(INSTALL_SCRIPT) ./ztest "$(DESTDIR)$(bindir)/ztest"
|
||||||
|
$(INSTALL_PROGRAM) ./zupdate "$(DESTDIR)$(bindir)/zupdate"
|
||||||
if [ ! -e "$(DESTDIR)$(sysconfdir)/$(pkgname)rc" ] ; then \
|
if [ ! -e "$(DESTDIR)$(sysconfdir)/$(pkgname)rc" ] ; 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)rc "$(DESTDIR)$(sysconfdir)/$(pkgname)rc" ; \
|
||||||
|
@ -141,6 +151,7 @@ install-man :
|
||||||
$(INSTALL_DATA) $(VPATH)/doc/zdiff.1 "$(DESTDIR)$(mandir)/man1/zdiff.1"
|
$(INSTALL_DATA) $(VPATH)/doc/zdiff.1 "$(DESTDIR)$(mandir)/man1/zdiff.1"
|
||||||
$(INSTALL_DATA) $(VPATH)/doc/zgrep.1 "$(DESTDIR)$(mandir)/man1/zgrep.1"
|
$(INSTALL_DATA) $(VPATH)/doc/zgrep.1 "$(DESTDIR)$(mandir)/man1/zgrep.1"
|
||||||
$(INSTALL_DATA) $(VPATH)/doc/ztest.1 "$(DESTDIR)$(mandir)/man1/ztest.1"
|
$(INSTALL_DATA) $(VPATH)/doc/ztest.1 "$(DESTDIR)$(mandir)/man1/ztest.1"
|
||||||
|
$(INSTALL_DATA) $(VPATH)/doc/zupdate.1 "$(DESTDIR)$(mandir)/man1/zupdate.1"
|
||||||
|
|
||||||
install-strip : all
|
install-strip : all
|
||||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
|
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
|
||||||
|
@ -156,6 +167,7 @@ uninstall-bin :
|
||||||
-rm -f "$(DESTDIR)$(bindir)/zfgrep"
|
-rm -f "$(DESTDIR)$(bindir)/zfgrep"
|
||||||
-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)$(sysconfdir)/$(pkgname)rc"
|
-rm -f "$(DESTDIR)$(sysconfdir)/$(pkgname)rc"
|
||||||
|
|
||||||
uninstall-info :
|
uninstall-info :
|
||||||
|
@ -168,6 +180,7 @@ uninstall-man :
|
||||||
-rm -f "$(DESTDIR)$(mandir)/man1/zdiff.1"
|
-rm -f "$(DESTDIR)$(mandir)/man1/zdiff.1"
|
||||||
-rm -f "$(DESTDIR)$(mandir)/man1/zgrep.1"
|
-rm -f "$(DESTDIR)$(mandir)/man1/zgrep.1"
|
||||||
-rm -f "$(DESTDIR)$(mandir)/man1/ztest.1"
|
-rm -f "$(DESTDIR)$(mandir)/man1/ztest.1"
|
||||||
|
-rm -f "$(DESTDIR)$(mandir)/man1/zupdate.1"
|
||||||
|
|
||||||
dist : doc
|
dist : doc
|
||||||
ln -sf $(VPATH) $(DISTNAME)
|
ln -sf $(VPATH) $(DISTNAME)
|
||||||
|
@ -195,7 +208,7 @@ dist : doc
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
-rm -f $(progname) $(progname)_profiled $(objs)
|
-rm -f $(progname) $(progname)_profiled $(objs)
|
||||||
-rm -f zcmp zcmp.o zdiff zdiff.o $(scripts)
|
-rm -f zcmp zcmp.o zdiff zdiff.o zupdate zupdate.o $(scripts)
|
||||||
|
|
||||||
distclean : clean
|
distclean : clean
|
||||||
-rm -f Makefile config.status *.tar *.tar.lz
|
-rm -f Makefile config.status *.tar *.tar.lz
|
||||||
|
|
14
NEWS
14
NEWS
|
@ -1,12 +1,4 @@
|
||||||
Changes in version 1.1:
|
Changes in version 1.2:
|
||||||
|
|
||||||
The new options "--bz2", "--gz", "--lz" and "--xz" have been added to
|
The new utility zupdate, which recompresses bzip2, gzip and xz files to
|
||||||
all utilities.
|
lzip format, has been added.
|
||||||
|
|
||||||
Zutils now provides the runtime configuration file "zutilsrc", which
|
|
||||||
allows the user change the compressor to be used for each format.
|
|
||||||
|
|
||||||
The checking of the exit status of compressors has been improved.
|
|
||||||
|
|
||||||
The use of "decompressed" and "uncompressed" in the documentation has
|
|
||||||
been revised.
|
|
||||||
|
|
|
@ -156,12 +156,12 @@ Arg_parser::Arg_parser( const int argc, const char * const argv[],
|
||||||
while( argind < argc )
|
while( argind < argc )
|
||||||
{
|
{
|
||||||
const unsigned char ch1 = argv[argind][0];
|
const unsigned char ch1 = argv[argind][0];
|
||||||
const unsigned char ch2 = ( ch1 ? argv[argind][1] : 0 );
|
const unsigned char ch2 = ch1 ? argv[argind][1] : 0;
|
||||||
|
|
||||||
if( ch1 == '-' && ch2 ) // we found an option
|
if( ch1 == '-' && ch2 ) // we found an option
|
||||||
{
|
{
|
||||||
const char * const opt = argv[argind];
|
const char * const opt = argv[argind];
|
||||||
const char * const arg = (argind + 1 < argc) ? argv[argind+1] : 0;
|
const char * const arg = ( argind + 1 < argc ) ? argv[argind+1] : 0;
|
||||||
if( ch2 == '-' )
|
if( ch2 == '-' )
|
||||||
{
|
{
|
||||||
if( !argv[argind][2] ) { ++argind; break; } // we found "--"
|
if( !argv[argind][2] ) { ++argind; break; } // we found "--"
|
||||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -6,7 +6,7 @@
|
||||||
# to copy, distribute and modify it.
|
# to copy, distribute and modify it.
|
||||||
|
|
||||||
pkgname=zutils
|
pkgname=zutils
|
||||||
pkgversion=1.1
|
pkgversion=1.2-pre2
|
||||||
progname=zutils
|
progname=zutils
|
||||||
srctrigger=doc/${pkgname}.texinfo
|
srctrigger=doc/${pkgname}.texinfo
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
||||||
.TH ZCAT "1" "August 2013" "Zcat (zutils) 1.1" "User Commands"
|
.TH ZCAT "1" "September 2013" "Zcat (zutils) 1.2-pre2" "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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
||||||
.TH ZCMP "1" "August 2013" "Zcmp (zutils) 1.1" "User Commands"
|
.TH ZCMP "1" "September 2013" "Zcmp (zutils) 1.2-pre2" "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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
||||||
.TH ZDIFF "1" "August 2013" "Zdiff (zutils) 1.1" "User Commands"
|
.TH ZDIFF "1" "September 2013" "Zdiff (zutils) 1.2-pre2" "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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
||||||
.TH ZGREP "1" "August 2013" "Zgrep (zutils) 1.1" "User Commands"
|
.TH ZGREP "1" "September 2013" "Zgrep (zutils) 1.2-pre2" "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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
||||||
.TH ZTEST "1" "August 2013" "Ztest (zutils) 1.1" "User Commands"
|
.TH ZTEST "1" "September 2013" "Ztest (zutils) 1.2-pre2" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
Ztest \- verify integrity of compressed files
|
Ztest \- verify integrity of compressed files
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
76
doc/zupdate.1
Normal file
76
doc/zupdate.1
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
||||||
|
.TH ZUPDATE "1" "September 2013" "Zupdate (zutils) 1.2-pre2" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
Zupdate \- recompress bzip2, gzip, xz files to lzip files
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B zupdate
|
||||||
|
[\fIoptions\fR] [\fIfiles\fR]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Zupdate recompresses files from bzip2, gzip, and xz formats to lzip format.
|
||||||
|
The originals are compared with the new files and then deleted.
|
||||||
|
Only regular files with standard file name extensions are recompressed,
|
||||||
|
other files are ignored.
|
||||||
|
Compressed files are decompressed and then recompressed on the fly; no
|
||||||
|
temporary files are created.
|
||||||
|
The lzip format is chosen as destination because it is by far the most
|
||||||
|
appropriate for long\-term data archiving.
|
||||||
|
.PP
|
||||||
|
If the lzip compressed version of a file already exists, the file is
|
||||||
|
skipped unless the '\-\-force' option is given. In this case, if the
|
||||||
|
comparison fails, an error is returned and the original file is not
|
||||||
|
deleted. The operation of zupdate is meant to be safe and not produce
|
||||||
|
any data loss. Therefore, existing lzip compressed files are never
|
||||||
|
overwritten nor deleted.
|
||||||
|
.PP
|
||||||
|
Exit status is 0 if all the compressed files were successfully
|
||||||
|
recompressed (if needed), compared and deleted. Non\-zero otherwise.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
|
display this help and exit
|
||||||
|
.TP
|
||||||
|
\fB\-V\fR, \fB\-\-version\fR
|
||||||
|
output version information and exit
|
||||||
|
.TP
|
||||||
|
\fB\-f\fR, \fB\-\-force\fR
|
||||||
|
do not skip a file even if the .lz exists
|
||||||
|
.TP
|
||||||
|
\fB\-l\fR, \fB\-\-lzip\-verbose\fR
|
||||||
|
pass a \fB\-v\fR option to the lzip compressor
|
||||||
|
.TP
|
||||||
|
\fB\-N\fR, \fB\-\-no\-rcfile\fR
|
||||||
|
don't read runtime configuration file
|
||||||
|
.TP
|
||||||
|
\fB\-q\fR, \fB\-\-quiet\fR
|
||||||
|
suppress all messages
|
||||||
|
.TP
|
||||||
|
\fB\-r\fR, \fB\-\-recursive\fR
|
||||||
|
operate recursively on directories
|
||||||
|
.TP
|
||||||
|
\fB\-v\fR, \fB\-\-verbose\fR
|
||||||
|
be verbose (a 2nd \fB\-v\fR gives more)
|
||||||
|
.TP
|
||||||
|
\fB\-0\fR .. \fB\-9\fR
|
||||||
|
set compression level [default 9]
|
||||||
|
.TP
|
||||||
|
\fB\-\-bz2=\fR<command>
|
||||||
|
set compressor and options for bzip2 format
|
||||||
|
.TP
|
||||||
|
\fB\-\-gz=\fR<command>
|
||||||
|
set compressor and options for gzip format
|
||||||
|
.TP
|
||||||
|
\fB\-\-lz=\fR<command>
|
||||||
|
set compressor and options for lzip format
|
||||||
|
.TP
|
||||||
|
\fB\-\-xz=\fR<command>
|
||||||
|
set compressor and options for xz format
|
||||||
|
.SH "REPORTING BUGS"
|
||||||
|
Report bugs to zutils\-bug@nongnu.org
|
||||||
|
.br
|
||||||
|
Zutils home page: http://www.nongnu.org/zutils/zutils.html
|
||||||
|
.SH COPYRIGHT
|
||||||
|
Copyright \(co 2013 Antonio Diaz Diaz.
|
||||||
|
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||||
|
.br
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
106
doc/zutils.info
106
doc/zutils.info
|
@ -12,7 +12,7 @@ File: zutils.info, Node: Top, Next: Introduction, Up: (dir)
|
||||||
Zutils Manual
|
Zutils Manual
|
||||||
*************
|
*************
|
||||||
|
|
||||||
This manual is for Zutils (version 1.1, 2 August 2013).
|
This manual is for Zutils (version 1.2-pre2, 4 September 2013).
|
||||||
|
|
||||||
* Menu:
|
* Menu:
|
||||||
|
|
||||||
|
@ -24,11 +24,12 @@ This manual is for Zutils (version 1.1, 2 August 2013).
|
||||||
* Zdiff:: Comparing compressed files line by line
|
* Zdiff:: Comparing compressed files line by line
|
||||||
* Zgrep:: Searching inside compressed files
|
* Zgrep:: Searching inside compressed files
|
||||||
* Ztest:: Testing integrity of compressed files
|
* Ztest:: Testing integrity of compressed files
|
||||||
|
* Zupdate:: Recompressing files to lzip format
|
||||||
* Problems:: Reporting bugs
|
* Problems:: Reporting bugs
|
||||||
* Concept index:: Index of concepts
|
* Concept index:: Index of concepts
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
Copyright (C) 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||||
|
|
||||||
This manual is free documentation: you have unlimited permission to
|
This manual is free documentation: you have unlimited permission to
|
||||||
copy, distribute and modify it.
|
copy, distribute and modify it.
|
||||||
|
@ -49,12 +50,13 @@ are created.
|
||||||
C++ programs. In particular the `--recursive' option is very efficient
|
C++ programs. In particular the `--recursive' option is very efficient
|
||||||
in those utilities supporting it.
|
in those utilities supporting it.
|
||||||
|
|
||||||
The provided utilities are zcat, zcmp, zdiff, zgrep and ztest.
|
The provided utilities are zcat, zcmp, zdiff, zgrep, ztest and zupdate.
|
||||||
The supported formats are bzip2, gzip, lzip and xz.
|
The supported formats are bzip2, gzip, lzip and xz.
|
||||||
The compressor to be used for each format is configurable at runtime.
|
The compressor to be used for each format 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 shell
|
||||||
scripts provided with GNU gzip. Ztest is unique to zutils.
|
scripts provided with GNU gzip. Ztest is unique to zutils. Zupdate is
|
||||||
|
similar to gzip's znew.
|
||||||
|
|
||||||
NOTE: Bzip2 and lzip provide well-defined values of exit status,
|
NOTE: Bzip2 and lzip provide well-defined values of exit status,
|
||||||
which makes them safe to use with zutils. Gzip and xz may return
|
which makes them safe to use with zutils. Gzip and xz may return
|
||||||
|
@ -545,7 +547,7 @@ matches were found, and 2 means trouble.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File: zutils.info, Node: Ztest, Next: Problems, Prev: Zgrep, Up: Top
|
File: zutils.info, Node: Ztest, Next: Zupdate, Prev: Zgrep, Up: Top
|
||||||
|
|
||||||
8 Ztest
|
8 Ztest
|
||||||
*******
|
*******
|
||||||
|
@ -588,10 +590,76 @@ environmental problems (file not found, invalid flags, I/O errors, etc),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File: zutils.info, Node: Problems, Next: Concept index, Prev: Ztest, Up: Top
|
File: zutils.info, Node: Zupdate, Next: Problems, Prev: Ztest, Up: Top
|
||||||
|
|
||||||
9 Reporting Bugs
|
9 Zupdate
|
||||||
****************
|
*********
|
||||||
|
|
||||||
|
Zupdate recompresses files from bzip2, gzip, and xz formats to lzip
|
||||||
|
format. The originals are compared with the new files and then deleted.
|
||||||
|
Only regular files with standard file name extensions are recompressed,
|
||||||
|
other files are ignored. Compressed files are decompressed and then
|
||||||
|
recompressed on the fly; no temporary files are created. The lzip format
|
||||||
|
is chosen as destination because it is by far the most appropriate for
|
||||||
|
long-term data archiving.
|
||||||
|
|
||||||
|
If the lzip compressed version of a file already exists, the file is
|
||||||
|
skipped unless the `--force' option is given. In this case, if the
|
||||||
|
comparison fails, an error is returned and the original file is not
|
||||||
|
deleted. The operation of zupdate is meant to be safe and not produce
|
||||||
|
any data loss. Therefore, existing lzip compressed files are never
|
||||||
|
overwritten nor deleted.
|
||||||
|
|
||||||
|
The names of the original files must have one of the following
|
||||||
|
extensions: `.bz2', `.tbz', `.tbz2', `.gz', `.tgz', `.xz', `.txz'. The
|
||||||
|
files produced have the extensions `.lz' or `.tar.lz'.
|
||||||
|
|
||||||
|
The format for running zupdate is:
|
||||||
|
|
||||||
|
zupdate [OPTIONS] [FILES]
|
||||||
|
|
||||||
|
Exit status is 0 if all the compressed files were successfully
|
||||||
|
recompressed (if needed), compared and deleted. Non-zero otherwise.
|
||||||
|
|
||||||
|
Zupdate supports the following options:
|
||||||
|
|
||||||
|
`-f'
|
||||||
|
`--force'
|
||||||
|
Do not skip a file for which a lzip compressed version already
|
||||||
|
exists. `--force' compares the content of the input file with the
|
||||||
|
content of the lzip file and deletes the input file if both
|
||||||
|
contents are identical.
|
||||||
|
|
||||||
|
`-l'
|
||||||
|
`--lzip-verbose'
|
||||||
|
Pass a `-v' option to the lzip compressor so that it shows the
|
||||||
|
compression ratio for each file processed. Using lzip 1.15 and
|
||||||
|
newer, a second `-l' shows the progress of compression. Use it
|
||||||
|
together with `-v' to see the name of the file.
|
||||||
|
|
||||||
|
`-q'
|
||||||
|
`--quiet'
|
||||||
|
Quiet operation. Suppress all messages.
|
||||||
|
|
||||||
|
`-r'
|
||||||
|
`--recursive'
|
||||||
|
Operate recursively on directories.
|
||||||
|
|
||||||
|
`-v'
|
||||||
|
`--verbose'
|
||||||
|
Verbose mode. Show the files being processed. A second `-v' also
|
||||||
|
shows the files being ignored.
|
||||||
|
|
||||||
|
`-0 .. -9'
|
||||||
|
Set the compression level of lzip. By default zupdate passes `-9'
|
||||||
|
to lzip.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
File: zutils.info, Node: Problems, Next: Concept index, Prev: Zupdate, Up: Top
|
||||||
|
|
||||||
|
10 Reporting bugs
|
||||||
|
*****************
|
||||||
|
|
||||||
There are probably bugs in zutils. There are certainly errors and
|
There are probably bugs in zutils. There are certainly errors and
|
||||||
omissions in this manual. If you report them, they will get fixed. If
|
omissions in this manual. If you report them, they will get fixed. If
|
||||||
|
@ -621,21 +689,23 @@ Concept index
|
||||||
* zdiff: Zdiff. (line 6)
|
* zdiff: Zdiff. (line 6)
|
||||||
* zgrep: Zgrep. (line 6)
|
* zgrep: Zgrep. (line 6)
|
||||||
* ztest: Ztest. (line 6)
|
* ztest: Ztest. (line 6)
|
||||||
|
* zupdate: Zupdate. (line 6)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Tag Table:
|
Tag Table:
|
||||||
Node: Top224
|
Node: Top224
|
||||||
Node: Introduction1095
|
Node: Introduction1156
|
||||||
Node: Common options3153
|
Node: Common options3258
|
||||||
Node: The zutilsrc file4402
|
Node: The zutilsrc file4507
|
||||||
Node: Zcat5328
|
Node: Zcat5433
|
||||||
Node: Zcmp7250
|
Node: Zcmp7355
|
||||||
Node: Zdiff9574
|
Node: Zdiff9679
|
||||||
Node: Zgrep12077
|
Node: Zgrep12182
|
||||||
Node: Ztest14914
|
Node: Ztest15019
|
||||||
Node: Problems16139
|
Node: Zupdate16243
|
||||||
Node: Concept index16668
|
Node: Problems18477
|
||||||
|
Node: Concept index19010
|
||||||
|
|
||||||
End Tag Table
|
End Tag Table
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
@finalout
|
@finalout
|
||||||
@c %**end of header
|
@c %**end of header
|
||||||
|
|
||||||
@set UPDATED 2 August 2013
|
@set UPDATED 4 September 2013
|
||||||
@set VERSION 1.1
|
@set VERSION 1.2-pre2
|
||||||
|
|
||||||
@dircategory Data Compression
|
@dircategory Data Compression
|
||||||
@direntry
|
@direntry
|
||||||
|
@ -43,13 +43,13 @@ This manual is for Zutils (version @value{VERSION}, @value{UPDATED}).
|
||||||
* Zdiff:: Comparing compressed files line by line
|
* Zdiff:: Comparing compressed files line by line
|
||||||
* Zgrep:: Searching inside compressed files
|
* Zgrep:: Searching inside compressed files
|
||||||
* Ztest:: Testing integrity of compressed files
|
* Ztest:: Testing integrity of compressed files
|
||||||
|
* Zupdate:: Recompressing files to lzip format
|
||||||
* Problems:: Reporting bugs
|
* Problems:: Reporting bugs
|
||||||
* Concept index:: Index of concepts
|
* Concept index:: Index of concepts
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@sp 1
|
@sp 1
|
||||||
Copyright @copyright{} 2008, 2009, 2010, 2011, 2012, 2013
|
Copyright @copyright{} 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||||
Antonio Diaz Diaz.
|
|
||||||
|
|
||||||
This manual is free documentation: you have unlimited permission
|
This manual is free documentation: you have unlimited permission
|
||||||
to copy, distribute and modify it.
|
to copy, distribute and modify it.
|
||||||
|
@ -70,12 +70,13 @@ programs. In particular the @samp{--recursive} option is very efficient
|
||||||
in those utilities supporting it.
|
in those utilities supporting it.
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
The provided utilities are zcat, zcmp, zdiff, zgrep and ztest.@*
|
The provided utilities are zcat, zcmp, zdiff, zgrep, ztest and zupdate.@*
|
||||||
The supported formats are bzip2, gzip, lzip and xz.@*
|
The supported formats are bzip2, gzip, lzip and xz.@*
|
||||||
The compressor to be used for each format is configurable at runtime.
|
The compressor to be used for each format 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 shell
|
||||||
scripts provided with GNU gzip. Ztest is unique to zutils.
|
scripts provided with GNU gzip. Ztest is unique to zutils. Zupdate is
|
||||||
|
similar to gzip's znew.
|
||||||
|
|
||||||
NOTE: Bzip2 and lzip provide well-defined values of exit status, which
|
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
|
makes them safe to use with zutils. Gzip and xz may return ambiguous
|
||||||
|
@ -638,14 +639,85 @@ Operate recursively on directories.
|
||||||
|
|
||||||
@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 increase the verbosity level.
|
Further -v's increase the verbosity level.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@node Zupdate
|
||||||
|
@chapter Zupdate
|
||||||
|
@cindex zupdate
|
||||||
|
|
||||||
|
Zupdate recompresses files from bzip2, gzip, and xz formats to lzip
|
||||||
|
format. The originals are compared with the new files and then deleted.
|
||||||
|
Only regular files with standard file name extensions are recompressed,
|
||||||
|
other files are ignored. Compressed files are decompressed and then
|
||||||
|
recompressed on the fly; no temporary files are created. The lzip format
|
||||||
|
is chosen as destination because it is by far the most appropriate for
|
||||||
|
long-term data archiving.
|
||||||
|
|
||||||
|
If the lzip compressed version of a file already exists, the file is
|
||||||
|
skipped unless the @samp{--force} option is given. In this case, if the
|
||||||
|
comparison fails, an error is returned and the original file is not
|
||||||
|
deleted. The operation of zupdate is meant to be safe and not produce
|
||||||
|
any data loss. Therefore, existing lzip compressed files are never
|
||||||
|
overwritten nor deleted.
|
||||||
|
|
||||||
|
The names of the original files must have one of the following
|
||||||
|
extensions: @samp{.bz2}, @samp{.tbz}, @samp{.tbz2}, @samp{.gz},
|
||||||
|
@samp{.tgz}, @samp{.xz}, @samp{.txz}. The files produced have the
|
||||||
|
extensions @samp{.lz} or @samp{.tar.lz}.
|
||||||
|
|
||||||
|
The format for running zupdate is:
|
||||||
|
|
||||||
|
@example
|
||||||
|
zupdate [@var{options}] [@var{files}]
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
Exit status is 0 if all the compressed files were successfully
|
||||||
|
recompressed (if needed), compared and deleted. Non-zero otherwise.
|
||||||
|
|
||||||
|
Zupdate supports the following options:
|
||||||
|
|
||||||
|
@table @samp
|
||||||
|
@item -f
|
||||||
|
@itemx --force
|
||||||
|
Do not skip a file for which a lzip compressed version already exists.
|
||||||
|
@samp{--force} compares the content of the input file with the content
|
||||||
|
of the lzip file and deletes the input file if both contents are
|
||||||
|
identical.
|
||||||
|
|
||||||
|
@item -l
|
||||||
|
@itemx --lzip-verbose
|
||||||
|
Pass a @samp{-v} option to the lzip compressor so that it shows the
|
||||||
|
compression ratio for each file processed. Using lzip 1.15 and newer, a
|
||||||
|
second @samp{-l} shows the progress of compression. Use it together with
|
||||||
|
@samp{-v} to see the name of the file.
|
||||||
|
|
||||||
|
@item -q
|
||||||
|
@itemx --quiet
|
||||||
|
Quiet operation. Suppress all messages.
|
||||||
|
|
||||||
|
@item -r
|
||||||
|
@itemx --recursive
|
||||||
|
Operate recursively on directories.
|
||||||
|
|
||||||
|
@item -v
|
||||||
|
@itemx --verbose
|
||||||
|
Verbose mode. Show the files being processed. A second @samp{-v} also
|
||||||
|
shows the files being ignored.
|
||||||
|
|
||||||
|
@item -0 .. -9
|
||||||
|
Set the compression level of lzip. By default zupdate passes @samp{-9}
|
||||||
|
to lzip.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
@node Problems
|
@node Problems
|
||||||
@chapter Reporting Bugs
|
@chapter Reporting bugs
|
||||||
@cindex bugs
|
@cindex bugs
|
||||||
@cindex getting help
|
@cindex getting help
|
||||||
|
|
||||||
|
|
4
main.cc
4
main.cc
|
@ -275,7 +275,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
for( ; argind < parser.arguments(); ++argind )
|
for( ; argind < parser.arguments(); ++argind )
|
||||||
{
|
{
|
||||||
const int code = parser.code( argind );
|
const int code = parser.code( argind );
|
||||||
const char * arg = parser.argument( argind ).c_str();
|
const char * const arg = parser.argument( argind ).c_str();
|
||||||
if( !code )
|
if( !code )
|
||||||
{
|
{
|
||||||
if( program_mode == m_zgrep && !grep_pattern_found )
|
if( program_mode == m_zgrep && !grep_pattern_found )
|
||||||
|
@ -399,7 +399,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
if( recursive )
|
if( recursive )
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if( !stat( input_filename.c_str(), &st ) && S_ISDIR( st.st_mode ) )
|
if( stat( input_filename.c_str(), &st ) == 0 && S_ISDIR( st.st_mode ) )
|
||||||
{
|
{
|
||||||
DIR * const dirp = opendir( input_filename.c_str() );
|
DIR * const dirp = opendir( input_filename.c_str() );
|
||||||
if( !dirp )
|
if( !dirp )
|
||||||
|
|
|
@ -16,6 +16,7 @@ ZGREP="${objdir}"/zgrep
|
||||||
ZEGREP="${objdir}"/zegrep
|
ZEGREP="${objdir}"/zegrep
|
||||||
ZFGREP="${objdir}"/zfgrep
|
ZFGREP="${objdir}"/zfgrep
|
||||||
ZTEST="${objdir}"/ztest
|
ZTEST="${objdir}"/ztest
|
||||||
|
ZUPDATE="${objdir}"/zupdate
|
||||||
compressors="bzip2 gzip lzip"
|
compressors="bzip2 gzip lzip"
|
||||||
extensions="bz2 gz lz"
|
extensions="bz2 gz lz"
|
||||||
compressor_needed() { echo "${compressors} are needed to run tests" ; exit 1 ; }
|
compressor_needed() { echo "${compressors} are needed to run tests" ; exit 1 ; }
|
||||||
|
@ -45,9 +46,9 @@ cat in.lz > lz_only.lz || framework_failure
|
||||||
cat in in in in in in > in6 || framework_failure
|
cat in in in in in in > in6 || framework_failure
|
||||||
fail=0
|
fail=0
|
||||||
|
|
||||||
printf "testing zutils-%s..." "$2"
|
printf "testing zutils-%s..." "$2"
|
||||||
|
|
||||||
printf "\ntesting zcat-%s..." "$2"
|
printf "\ntesting zcat-%s..." "$2"
|
||||||
|
|
||||||
for i in ${extensions}; do
|
for i in ${extensions}; do
|
||||||
"${ZCAT}" -N in.$i > copy || fail=1
|
"${ZCAT}" -N in.$i > copy || fail=1
|
||||||
|
@ -95,7 +96,7 @@ if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
|
||||||
|
|
||||||
printf "\ntesting zcmp-%s..." "$2"
|
printf "\ntesting zcmp-%s..." "$2"
|
||||||
|
|
||||||
for i in ${extensions}; do
|
for i in ${extensions}; do
|
||||||
"${ZCMP}" -N in.$i || fail=1
|
"${ZCMP}" -N in.$i || fail=1
|
||||||
|
@ -176,7 +177,7 @@ if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
|
||||||
|
|
||||||
printf "\ntesting zdiff-%s..." "$2"
|
printf "\ntesting zdiff-%s..." "$2"
|
||||||
|
|
||||||
for i in ${extensions}; do
|
for i in ${extensions}; do
|
||||||
"${ZDIFF}" -N in.$i > /dev/null || fail=1
|
"${ZDIFF}" -N in.$i > /dev/null || fail=1
|
||||||
|
@ -239,7 +240,7 @@ if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
|
||||||
|
|
||||||
printf "\ntesting zgrep-%s..." "$2"
|
printf "\ntesting zgrep-%s..." "$2"
|
||||||
|
|
||||||
for i in ${extensions}; do
|
for i in ${extensions}; do
|
||||||
"${ZGREP}" -N "GNU" in.$i > /dev/null || fail=1
|
"${ZGREP}" -N "GNU" in.$i > /dev/null || fail=1
|
||||||
|
@ -305,7 +306,7 @@ printf .
|
||||||
printf .
|
printf .
|
||||||
|
|
||||||
|
|
||||||
printf "\ntesting ztest-%s..." "$2"
|
printf "\ntesting ztest-%s..." "$2"
|
||||||
|
|
||||||
for i in ${extensions}; do
|
for i in ${extensions}; do
|
||||||
"${ZTEST}" -N --format=$i < in.$i || fail=1
|
"${ZTEST}" -N --format=$i < in.$i || fail=1
|
||||||
|
@ -335,10 +336,80 @@ if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
"${ZTEST}" -N --format=lz in.bz2 2> /dev/null
|
"${ZTEST}" -N --format=lz in.bz2 2> /dev/null
|
||||||
if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
"${ZTEST}" -N --lz='lzip --bad-option' in.lz 2> /dev/null
|
"${ZTEST}" -N --lz='lzip --bad-option' in.lz 2> /dev/null
|
||||||
if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
"${ZTEST}" -N --bad-option 2> /dev/null
|
"${ZTEST}" -N --bad-option 2> /dev/null
|
||||||
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
|
||||||
|
|
||||||
|
printf "\ntesting zupdate-%s..." "$2"
|
||||||
|
|
||||||
|
cat in.bz2 > x.bz2 || framework_failure
|
||||||
|
cat in.gz > x.gz || framework_failure
|
||||||
|
"${ZUPDATE}" -N --bz2=bad_command x.bz2 2> /dev/null
|
||||||
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
"${ZUPDATE}" -N --bz2='bzip2 --bad-option' x.bz2 > /dev/null 2> /dev/null
|
||||||
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
"${ZUPDATE}" -N --gz=bad_command x.gz 2> /dev/null
|
||||||
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
"${ZUPDATE}" -N --gz='gzip --bad-option' x.gz 2> /dev/null
|
||||||
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
"${ZUPDATE}" -N --lz=bad_command x.gz 2> /dev/null
|
||||||
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
"${ZUPDATE}" -N --lz='lzip --bad-option' x.gz 2> /dev/null
|
||||||
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
"${ZUPDATE}" -N --bad-option 2> /dev/null
|
||||||
|
if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
|
||||||
|
|
||||||
|
cat in.lz in.lz > x.lz || framework_failure
|
||||||
|
"${ZUPDATE}" -N -f x.bz2 x.gz 2> /dev/null
|
||||||
|
if [ $? = 1 ] && [ -e x.bz2 ] && [ -e x.gz ] && [ -e x.lz ] ; then printf .
|
||||||
|
else printf - ; fail=1
|
||||||
|
fi
|
||||||
|
rm -f x.lz || framework_failure
|
||||||
|
|
||||||
|
"${ZUPDATE}" -N x.bz2 2> /dev/null
|
||||||
|
if [ $? = 0 ] && [ ! -e x.bz2 ] && [ -e x.gz ] && [ -e x.lz ] ; then printf .
|
||||||
|
else printf - ; fail=1
|
||||||
|
fi
|
||||||
|
rm -f x.lz || framework_failure
|
||||||
|
"${ZUPDATE}" -N x.gz 2> /dev/null
|
||||||
|
if [ $? = 0 ] && [ ! -e x.bz2 ] && [ ! -e x.gz ] && [ -e x.lz ] ; then printf .
|
||||||
|
else printf - ; fail=1
|
||||||
|
fi
|
||||||
|
rm -f x.lz || framework_failure
|
||||||
|
|
||||||
|
cat in.bz2 > x.bz2 || framework_failure
|
||||||
|
cat in.gz > x.gz || framework_failure
|
||||||
|
"${ZUPDATE}" -N x.bz2 x.gz 2> /dev/null
|
||||||
|
if [ $? = 1 ] && [ ! -e x.bz2 ] && [ -e x.gz ] && [ -e x.lz ] ; then printf .
|
||||||
|
else printf - ; fail=1
|
||||||
|
fi
|
||||||
|
rm -f x.lz || framework_failure
|
||||||
|
|
||||||
|
cat in.bz2 > x.bz2 || framework_failure
|
||||||
|
cat in.gz > x.gz || framework_failure
|
||||||
|
"${ZUPDATE}" -N -f x.bz2 x.gz 2> /dev/null
|
||||||
|
if [ $? = 0 ] && [ ! -e x.bz2 ] && [ ! -e x.gz ] && [ -e x.lz ] ; then printf .
|
||||||
|
else printf - ; fail=1
|
||||||
|
fi
|
||||||
|
rm -f x.lz || framework_failure
|
||||||
|
|
||||||
|
cat in.bz2 > x.bz2 || framework_failure
|
||||||
|
cat in.gz > x.gz || framework_failure
|
||||||
|
"${ZUPDATE}" -N -f x.bz2 x.gz 2> /dev/null
|
||||||
|
if [ $? = 0 ] && [ ! -e x.bz2 ] && [ ! -e x.gz ] &&
|
||||||
|
[ ! -e x ] && [ -e x.lz ] ; then printf .
|
||||||
|
else printf - ; fail=1
|
||||||
|
fi
|
||||||
|
rm -f x.lz || framework_failure
|
||||||
|
|
||||||
|
cat in.bz2 > x.bz2 || framework_failure
|
||||||
|
"${ZUPDATE}" -N -6 -q x.bz2
|
||||||
|
if [ $? = 0 ] && [ ! -e x.bz2 ] && [ -e x.lz ] ; then printf .
|
||||||
|
else printf - ; fail=1
|
||||||
|
fi
|
||||||
|
rm -f x.lz || framework_failure
|
||||||
|
|
||||||
echo
|
echo
|
||||||
if [ ${fail} = 0 ] ; then
|
if [ ${fail} = 0 ] ; then
|
||||||
echo "tests completed successfully."
|
echo "tests completed successfully."
|
||||||
|
|
6
zcmp.cc
6
zcmp.cc
|
@ -246,12 +246,12 @@ int cmp( const long long max_size, const int infd[2],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer0[rd[0]] = ~buffer1[rd[0]]; // sentinels for the block compare
|
const int min_rd = std::min( rd[0], rd[1] );
|
||||||
buffer1[rd[1]] = ~buffer0[rd[1]];
|
buffer0[min_rd] = 0; // sentinels for the block compare
|
||||||
|
buffer1[min_rd] = 1;
|
||||||
|
|
||||||
int first_diff = block_compare( buffer0, buffer1, &line_number );
|
int first_diff = block_compare( buffer0, buffer1, &line_number );
|
||||||
byte_number += first_diff;
|
byte_number += first_diff;
|
||||||
const int min_rd = std::min( rd[0], rd[1] );
|
|
||||||
|
|
||||||
if( first_diff < min_rd )
|
if( first_diff < min_rd )
|
||||||
{
|
{
|
||||||
|
|
10
zdiff.cc
10
zdiff.cc
|
@ -389,6 +389,11 @@ int main( const int argc, const char * const argv[] )
|
||||||
set_signals();
|
set_signals();
|
||||||
if( !set_fifonames( filenames ) ) return 2;
|
if( !set_fifonames( filenames ) ) return 2;
|
||||||
|
|
||||||
|
Children children[2];
|
||||||
|
if( !set_data_feeder( fifonames[0], infd[0], children[0], format_types[0] ) ||
|
||||||
|
!set_data_feeder( fifonames[1], infd[1], children[1], format_types[1] ) )
|
||||||
|
return 2;
|
||||||
|
|
||||||
const pid_t diff_pid = fork();
|
const pid_t diff_pid = fork();
|
||||||
if( diff_pid == 0 ) // child (diff)
|
if( diff_pid == 0 ) // child (diff)
|
||||||
{
|
{
|
||||||
|
@ -407,11 +412,6 @@ int main( const int argc, const char * const argv[] )
|
||||||
if( diff_pid < 0 ) // parent
|
if( diff_pid < 0 ) // parent
|
||||||
{ show_fork_error( DIFF ); return 2; }
|
{ show_fork_error( DIFF ); return 2; }
|
||||||
|
|
||||||
Children children[2];
|
|
||||||
if( !set_data_feeder( fifonames[0], infd[0], children[0], format_types[0] ) ||
|
|
||||||
!set_data_feeder( fifonames[1], infd[1], children[1], format_types[1] ) )
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
int retval = wait_for_child( diff_pid, DIFF );
|
int retval = wait_for_child( diff_pid, DIFF );
|
||||||
|
|
||||||
for( int i = 0; i < 2; ++i )
|
for( int i = 0; i < 2; ++i )
|
||||||
|
|
38
ztest.cc
38
ztest.cc
|
@ -59,7 +59,20 @@ int ztest_stdin( const int infd, int format_index,
|
||||||
{ show_error( "Can't create pipe", errno ); return 1; }
|
{ show_error( "Can't create pipe", errno ); return 1; }
|
||||||
|
|
||||||
const pid_t pid = fork();
|
const pid_t pid = fork();
|
||||||
if( pid == 0 ) // child1 (compressor)
|
if( pid == 0 ) // child1 (compressor feeder)
|
||||||
|
{
|
||||||
|
if( close( fda[0] ) != 0 ||
|
||||||
|
!feed_data( infd, fda[1], magic_data, magic_size ) )
|
||||||
|
_exit( 1 );
|
||||||
|
if( close( fda[1] ) != 0 )
|
||||||
|
{ show_close_error( "data feeder" ); _exit( 1 ); }
|
||||||
|
_exit( 0 );
|
||||||
|
}
|
||||||
|
if( pid < 0 ) // parent
|
||||||
|
{ show_fork_error( "data feeder" ); return 1; }
|
||||||
|
|
||||||
|
const pid_t pid2 = fork();
|
||||||
|
if( pid2 == 0 ) // child2 (compressor)
|
||||||
{
|
{
|
||||||
if( dup2( fda[0], STDIN_FILENO ) >= 0 &&
|
if( dup2( fda[0], STDIN_FILENO ) >= 0 &&
|
||||||
close( fda[0] ) == 0 && close( fda[1] ) == 0 )
|
close( fda[0] ) == 0 && close( fda[1] ) == 0 )
|
||||||
|
@ -81,25 +94,13 @@ int ztest_stdin( const int infd, int format_index,
|
||||||
show_exec_error( compressor_name );
|
show_exec_error( compressor_name );
|
||||||
_exit( 1 );
|
_exit( 1 );
|
||||||
}
|
}
|
||||||
if( pid < 0 ) // parent
|
if( pid2 < 0 ) // parent
|
||||||
{ show_fork_error( compressor_name ); return 1; }
|
{ show_fork_error( compressor_name ); return 1; }
|
||||||
|
|
||||||
const pid_t pid2 = fork();
|
|
||||||
if( pid2 == 0 ) // child2 (compressor feeder)
|
|
||||||
{
|
|
||||||
if( close( fda[0] ) != 0 ||
|
|
||||||
!feed_data( infd, fda[1], magic_data, magic_size ) )
|
|
||||||
_exit( 1 );
|
|
||||||
if( close( fda[1] ) != 0 )
|
|
||||||
{ show_close_error( "data feeder" ); _exit( 1 ); }
|
|
||||||
_exit( 0 );
|
|
||||||
}
|
|
||||||
if( pid2 < 0 ) // parent
|
|
||||||
{ show_fork_error( "data feeder" ); return 1; }
|
|
||||||
|
|
||||||
close( fda[0] ); close( fda[1] );
|
close( fda[0] ); close( fda[1] );
|
||||||
int retval = wait_for_child( pid, compressor_name, 1 );
|
const bool isgzxz = ( format_index == fmt_gz || format_index == fmt_xz );
|
||||||
if( retval == 0 && wait_for_child( pid2, "data feeder" ) != 0 )
|
int retval = wait_for_child( pid2, compressor_name, 1, isgzxz );
|
||||||
|
if( retval == 0 && wait_for_child( pid, "data feeder" ) != 0 )
|
||||||
retval = 1;
|
retval = 1;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -141,5 +142,6 @@ int ztest_file( const int infd, int format_index,
|
||||||
if( pid < 0 ) // parent
|
if( pid < 0 ) // parent
|
||||||
{ show_fork_error( compressor_name ); return 1; }
|
{ show_fork_error( compressor_name ); return 1; }
|
||||||
|
|
||||||
return wait_for_child( pid, compressor_name, 1 );
|
const bool isgzxz = ( format_index == fmt_gz || format_index == fmt_xz );
|
||||||
|
return wait_for_child( pid, compressor_name, 1, isgzxz );
|
||||||
}
|
}
|
||||||
|
|
415
zupdate.cc
Normal file
415
zupdate.cc
Normal file
|
@ -0,0 +1,415 @@
|
||||||
|
/* Zupdate - recompress bzip2, gzip, xz files to lzip files
|
||||||
|
Copyright (C) 2013 Antonio Diaz Diaz.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <climits>
|
||||||
|
#include <csignal>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <utime.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#if defined(__MSVCRT__) || defined(__OS2__)
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "arg_parser.h"
|
||||||
|
#include "zutils.h"
|
||||||
|
#include "rc.h"
|
||||||
|
|
||||||
|
#if CHAR_BIT != 8
|
||||||
|
#error "Environments where CHAR_BIT != 8 are not supported."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
#ifdef O_BINARY
|
||||||
|
const int o_binary = O_BINARY;
|
||||||
|
#else
|
||||||
|
const int o_binary = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void show_zupdate_help()
|
||||||
|
{
|
||||||
|
std::printf( "Zupdate recompresses files from bzip2, gzip, and xz formats to lzip format.\n"
|
||||||
|
"The originals are compared with the new files and then deleted.\n"
|
||||||
|
"Only regular files with standard file name extensions are recompressed,\n"
|
||||||
|
"other files are ignored.\n"
|
||||||
|
"Compressed files are decompressed and then recompressed on the fly; no\n"
|
||||||
|
"temporary files are created.\n"
|
||||||
|
"The lzip format is chosen as destination because it is by far the most\n"
|
||||||
|
"appropriate for long-term data archiving.\n"
|
||||||
|
"\nIf the lzip compressed version of a file already exists, the file is\n"
|
||||||
|
"skipped unless the '--force' option is given. In this case, if the\n"
|
||||||
|
"comparison fails, an error is returned and the original file is not\n"
|
||||||
|
"deleted. The operation of zupdate is meant to be safe and not produce\n"
|
||||||
|
"any data loss. Therefore, existing lzip compressed files are never\n"
|
||||||
|
"overwritten nor deleted.\n"
|
||||||
|
"\nUsage: zupdate [options] [files]\n"
|
||||||
|
"\nExit status is 0 if all the compressed files were successfully\n"
|
||||||
|
"recompressed (if needed), compared and deleted. Non-zero otherwise.\n"
|
||||||
|
"\nOptions:\n"
|
||||||
|
" -h, --help display this help and exit\n"
|
||||||
|
" -V, --version output version information and exit\n"
|
||||||
|
" -f, --force do not skip a file even if the .lz exists\n"
|
||||||
|
" -l, --lzip-verbose pass a -v option to the lzip compressor\n"
|
||||||
|
" -N, --no-rcfile don't read runtime configuration file\n"
|
||||||
|
" -q, --quiet suppress all messages\n"
|
||||||
|
" -r, --recursive operate recursively on directories\n"
|
||||||
|
" -v, --verbose be verbose (a 2nd -v gives more)\n"
|
||||||
|
" -0 .. -9 set compression level [default 9]\n"
|
||||||
|
" --bz2=<command> set compressor and options for bzip2 format\n"
|
||||||
|
" --gz=<command> set compressor and options for gzip format\n"
|
||||||
|
" --lz=<command> set compressor and options for lzip format\n"
|
||||||
|
" --xz=<command> set compressor and options for xz format\n" );
|
||||||
|
show_help_addr();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cant_execute( const std::string & command, const int status )
|
||||||
|
{
|
||||||
|
if( verbosity >= 0 )
|
||||||
|
{
|
||||||
|
if( WIFEXITED( status ) )
|
||||||
|
std::fprintf( stderr, "%s: Error executing '%s'. Exit status = %d.\n",
|
||||||
|
util_name, command.c_str(), WEXITSTATUS( status ) );
|
||||||
|
else
|
||||||
|
std::fprintf( stderr, "%s: Can't execute '%s'.\n",
|
||||||
|
util_name, command.c_str() );
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set permissions, owner and times.
|
||||||
|
void set_permissions( const char * const rname, const struct stat & in_stats )
|
||||||
|
{
|
||||||
|
bool warning = false;
|
||||||
|
// fchown will in many cases return with EPERM, which can be safely ignored.
|
||||||
|
if( ( chown( rname, in_stats.st_uid, in_stats.st_gid ) != 0 &&
|
||||||
|
errno != EPERM ) ||
|
||||||
|
chmod( rname, in_stats.st_mode ) != 0 ) warning = true;
|
||||||
|
struct utimbuf t;
|
||||||
|
t.actime = in_stats.st_atime;
|
||||||
|
t.modtime = in_stats.st_mtime;
|
||||||
|
if( utime( rname, &t ) != 0 ) warning = true;
|
||||||
|
if( warning && verbosity >= 2 )
|
||||||
|
show_error( "Can't change output file attributes." );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct { const char * from; const char * to; int format_index; } const
|
||||||
|
known_extensions[] = {
|
||||||
|
{ ".bz2", "", fmt_bz2 },
|
||||||
|
{ ".tbz", ".tar", fmt_bz2 },
|
||||||
|
{ ".tbz2", ".tar", fmt_bz2 },
|
||||||
|
{ ".gz", "", fmt_gz },
|
||||||
|
{ ".tgz", ".tar", fmt_gz },
|
||||||
|
{ ".lz", "", fmt_lz },
|
||||||
|
{ ".tlz", ".tar", fmt_lz },
|
||||||
|
{ ".xz", "", fmt_xz },
|
||||||
|
{ ".txz", ".tar", fmt_xz },
|
||||||
|
{ 0, 0, -1 } };
|
||||||
|
|
||||||
|
|
||||||
|
// Returns 0 for success, -1 for file skipped, 1 for error.
|
||||||
|
int zupdate_file( const std::string & name, const char * const lzip_name,
|
||||||
|
const std::vector< std::string > & lzip_args2,
|
||||||
|
const bool force )
|
||||||
|
{
|
||||||
|
int format_index = -1;
|
||||||
|
std::string dname; // decompressed_name
|
||||||
|
|
||||||
|
for( int i = 0; known_extensions[i].from; ++i ) // search extension
|
||||||
|
{
|
||||||
|
const std::string from( known_extensions[i].from );
|
||||||
|
if( name.size() > from.size() &&
|
||||||
|
name.compare( name.size() - from.size(), from.size(), from ) == 0 )
|
||||||
|
{
|
||||||
|
dname.assign( name, 0, name.size() - from.size() );
|
||||||
|
dname += known_extensions[i].to;
|
||||||
|
format_index = known_extensions[i].format_index;
|
||||||
|
if( format_index == fmt_lz )
|
||||||
|
{
|
||||||
|
if( verbosity >= 2 )
|
||||||
|
std::fprintf( stderr, "%s: Input file '%s' already has '%s' suffix.\n",
|
||||||
|
util_name, name.c_str(), known_extensions[i].from );
|
||||||
|
return 0; // ignore this file
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char * const compressor_name = get_compressor_name( format_index );
|
||||||
|
if( !compressor_name || !compressor_name[0] )
|
||||||
|
{
|
||||||
|
if( verbosity >= 2 )
|
||||||
|
std::fprintf( stderr, "%s: Unknown extension in file name '%s' -- ignored.\n",
|
||||||
|
util_name, name.c_str() );
|
||||||
|
return 0; // ignore this file
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat in_stats;
|
||||||
|
if( stat( name.c_str(), &in_stats ) != 0 ) // check input file
|
||||||
|
{
|
||||||
|
if( verbosity >= 0 )
|
||||||
|
std::fprintf( stderr, "%s: Can't stat input file '%s': %s.\n",
|
||||||
|
util_name, name.c_str(), std::strerror( errno ) );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if( !S_ISREG( in_stats.st_mode ) )
|
||||||
|
{
|
||||||
|
if( verbosity >= 0 )
|
||||||
|
std::fprintf( stderr, "%s: Input file '%s' is not a regular file.\n",
|
||||||
|
util_name, name.c_str() );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
std::string rname( dname ); rname += ".lz"; // recompressed_name
|
||||||
|
const bool lz_exists = ( stat( rname.c_str(), &st ) == 0 );
|
||||||
|
if( lz_exists && !force )
|
||||||
|
{
|
||||||
|
if( verbosity >= 0 )
|
||||||
|
std::fprintf( stderr, "%s: Output file '%s' already exists, skipping.\n",
|
||||||
|
util_name, rname.c_str() );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !lz_exists ) // recompress
|
||||||
|
{
|
||||||
|
if( verbosity >= 1 )
|
||||||
|
std::fprintf( stderr, "Recompressing file '%s'.\n", name.c_str() );
|
||||||
|
int fda[2]; // pipe between decompressor and compressor
|
||||||
|
if( pipe( fda ) < 0 )
|
||||||
|
{ show_error( "Can't create pipe", errno ); return 1; }
|
||||||
|
|
||||||
|
const pid_t pid = fork();
|
||||||
|
if( pid == 0 ) // child1 (decompressor)
|
||||||
|
{
|
||||||
|
if( dup2( fda[1], STDOUT_FILENO ) >= 0 &&
|
||||||
|
close( fda[0] ) == 0 && close( fda[1] ) == 0 )
|
||||||
|
{
|
||||||
|
const std::vector< std::string > & compressor_args =
|
||||||
|
get_compressor_args( format_index );
|
||||||
|
const int size = compressor_args.size();
|
||||||
|
const char ** const argv = new const char *[size+5];
|
||||||
|
argv[0] = compressor_name;
|
||||||
|
for( int i = 0; i < size; ++i ) argv[i+1] = compressor_args[i].c_str();
|
||||||
|
argv[size+1] = "-cd";
|
||||||
|
argv[size+2] = "--";
|
||||||
|
argv[size+3] = name.c_str();
|
||||||
|
argv[size+4] = 0;
|
||||||
|
execvp( argv[0], (char **)argv );
|
||||||
|
}
|
||||||
|
show_exec_error( compressor_name );
|
||||||
|
_exit( 1 );
|
||||||
|
}
|
||||||
|
if( pid < 0 ) // parent
|
||||||
|
{ show_fork_error( compressor_name ); return 1; }
|
||||||
|
|
||||||
|
const pid_t pid2 = fork();
|
||||||
|
if( pid2 == 0 ) // child2 (lzip compressor)
|
||||||
|
{
|
||||||
|
if( dup2( fda[0], STDIN_FILENO ) >= 0 &&
|
||||||
|
close( fda[0] ) == 0 && close( fda[1] ) == 0 )
|
||||||
|
{
|
||||||
|
const std::vector< std::string > & lzip_args =
|
||||||
|
get_compressor_args( fmt_lz );
|
||||||
|
const int size = lzip_args.size();
|
||||||
|
const int size2 = lzip_args2.size();
|
||||||
|
const char ** const argv = new const char *[size+size2+5];
|
||||||
|
argv[0] = lzip_name;
|
||||||
|
argv[1] = "-9";
|
||||||
|
for( int i = 0; i < size; ++i ) argv[i+2] = lzip_args[i].c_str();
|
||||||
|
for( int i = 0; i < size2; ++i ) argv[i+size+2] = lzip_args2[i].c_str();
|
||||||
|
argv[size+size2+2] = "-o";
|
||||||
|
argv[size+size2+3] = dname.c_str();
|
||||||
|
argv[size+size2+4] = 0;
|
||||||
|
execvp( argv[0], (char **)argv );
|
||||||
|
}
|
||||||
|
show_exec_error( lzip_name );
|
||||||
|
_exit( 1 );
|
||||||
|
}
|
||||||
|
if( pid2 < 0 ) // parent
|
||||||
|
{ show_fork_error( lzip_name ); return 1; }
|
||||||
|
|
||||||
|
close( fda[0] ); close( fda[1] );
|
||||||
|
int retval = wait_for_child( pid, compressor_name );
|
||||||
|
int retval2 = wait_for_child( pid2, lzip_name );
|
||||||
|
if( retval || retval2 ) { std::remove( rname.c_str() ); return 1; }
|
||||||
|
set_permissions( rname.c_str(), in_stats );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if( lz_exists && verbosity >= 1 )
|
||||||
|
std::fprintf( stderr, "Comparing file '%s'.\n", name.c_str() );
|
||||||
|
std::string zcmp_command( invocation_name );
|
||||||
|
unsigned i = zcmp_command.size();
|
||||||
|
while( i > 0 && zcmp_command[i-1] != '/' ) --i;
|
||||||
|
zcmp_command.resize( i );
|
||||||
|
zcmp_command += "zcmp "; // ${bindir}zcmp
|
||||||
|
zcmp_command += name; zcmp_command += ' '; zcmp_command += rname;
|
||||||
|
int status = std::system( zcmp_command.c_str() );
|
||||||
|
if( status != 0 )
|
||||||
|
{ if( !lz_exists ) std::remove( rname.c_str() );
|
||||||
|
return cant_execute( zcmp_command, status ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
if( std::remove( name.c_str() ) != 0 && errno != ENOENT )
|
||||||
|
{
|
||||||
|
if( verbosity >= 0 )
|
||||||
|
std::fprintf( stderr, "%s: Can't delete input file '%s': %s.\n",
|
||||||
|
util_name, name.c_str(), std::strerror( errno ) );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
|
||||||
|
int main( const int argc, const char * const argv[] )
|
||||||
|
{
|
||||||
|
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt };
|
||||||
|
std::string input_filename;
|
||||||
|
std::list< std::string > filenames;
|
||||||
|
std::vector< std::string > lzip_args2; // args to lzip, maybe empty
|
||||||
|
bool force = false;
|
||||||
|
bool recursive = false;
|
||||||
|
invocation_name = argv[0];
|
||||||
|
util_name = "zupdate";
|
||||||
|
|
||||||
|
const Arg_parser::Option options[] =
|
||||||
|
{
|
||||||
|
{ '0', 0, Arg_parser::no },
|
||||||
|
{ '1', 0, Arg_parser::no },
|
||||||
|
{ '2', 0, Arg_parser::no },
|
||||||
|
{ '3', 0, Arg_parser::no },
|
||||||
|
{ '4', 0, Arg_parser::no },
|
||||||
|
{ '5', 0, Arg_parser::no },
|
||||||
|
{ '6', 0, Arg_parser::no },
|
||||||
|
{ '7', 0, Arg_parser::no },
|
||||||
|
{ '8', 0, Arg_parser::no },
|
||||||
|
{ '9', 0, Arg_parser::no },
|
||||||
|
{ 'f', "force", Arg_parser::no },
|
||||||
|
{ 'h', "help", Arg_parser::no },
|
||||||
|
{ 'l', "lzip-verbose", Arg_parser::no },
|
||||||
|
{ 'N', "no-rcfile", Arg_parser::no },
|
||||||
|
{ 'q', "quiet", Arg_parser::no },
|
||||||
|
{ 'r', "recursive", Arg_parser::no },
|
||||||
|
{ 'v', "verbose", Arg_parser::no },
|
||||||
|
{ 'V', "version", Arg_parser::no },
|
||||||
|
{ bz2_opt, "bz2", Arg_parser::yes },
|
||||||
|
{ gz_opt, "gz", Arg_parser::yes },
|
||||||
|
{ lz_opt, "lz", Arg_parser::yes },
|
||||||
|
{ xz_opt, "xz", Arg_parser::yes },
|
||||||
|
{ 0 , 0, Arg_parser::no } };
|
||||||
|
|
||||||
|
const Arg_parser parser( argc, argv, options );
|
||||||
|
if( parser.error().size() ) // bad option
|
||||||
|
{ show_error( parser.error().c_str(), 0, true ); return 1; }
|
||||||
|
|
||||||
|
maybe_process_config_file( parser );
|
||||||
|
|
||||||
|
int argind = 0;
|
||||||
|
for( ; argind < parser.arguments(); ++argind )
|
||||||
|
{
|
||||||
|
const int code = parser.code( argind );
|
||||||
|
if( !code ) break; // no more options
|
||||||
|
const char * const arg = parser.argument( argind ).c_str();
|
||||||
|
switch( code ) // common options
|
||||||
|
{
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
lzip_args2.push_back( "-" ); lzip_args2.back() += code; break;
|
||||||
|
case 'f': force = true; break;
|
||||||
|
case 'h': show_zupdate_help(); return 0;
|
||||||
|
case 'l': lzip_args2.push_back( "-v" ); break;
|
||||||
|
case 'N': continue;
|
||||||
|
case 'q': verbosity = -1; lzip_args2.push_back( "-q" ); break;
|
||||||
|
case 'r': recursive = true; break;
|
||||||
|
case 'v': if( verbosity < 4 ) ++verbosity; break;
|
||||||
|
case 'V': show_version( "Zupdate" ); return 0;
|
||||||
|
case bz2_opt: parse_compressor( arg, fmt_bz2, 1 ); continue;
|
||||||
|
case gz_opt: parse_compressor( arg, fmt_gz, 1 ); continue;
|
||||||
|
case lz_opt: parse_compressor( arg, fmt_lz, 1 ); continue;
|
||||||
|
case xz_opt: parse_compressor( arg, fmt_xz, 1 ); continue;
|
||||||
|
default : internal_error( "uncaught option" );
|
||||||
|
}
|
||||||
|
} // end process options
|
||||||
|
|
||||||
|
#if defined(__MSVCRT__) || defined(__OS2__)
|
||||||
|
setmode( STDIN_FILENO, O_BINARY );
|
||||||
|
setmode( STDOUT_FILENO, O_BINARY );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char * const lzip_name = get_compressor_name( fmt_lz );
|
||||||
|
if( !lzip_name || !lzip_name[0] )
|
||||||
|
{ show_error( "Missing name of compressor for lzip format." ); return 1; }
|
||||||
|
|
||||||
|
for( ; argind < parser.arguments(); ++argind )
|
||||||
|
filenames.push_back( parser.argument( argind ) );
|
||||||
|
|
||||||
|
int retval = 0;
|
||||||
|
while( !filenames.empty() )
|
||||||
|
{
|
||||||
|
input_filename = filenames.front();
|
||||||
|
filenames.pop_front();
|
||||||
|
if( !input_filename.size() || input_filename == "-" ) continue;
|
||||||
|
if( recursive )
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if( stat( input_filename.c_str(), &st ) == 0 && S_ISDIR( st.st_mode ) )
|
||||||
|
{
|
||||||
|
DIR * const dirp = opendir( input_filename.c_str() );
|
||||||
|
if( !dirp )
|
||||||
|
{
|
||||||
|
show_error2( "Can't open directory", input_filename.c_str() );
|
||||||
|
if( retval < 1 ) retval = 1; continue;
|
||||||
|
}
|
||||||
|
std::list< std::string > tmp_list;
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
const struct dirent * const entryp = readdir( dirp );
|
||||||
|
if( !entryp ) { closedir( dirp ); break; }
|
||||||
|
std::string tmp_name( entryp->d_name );
|
||||||
|
if( tmp_name != "." && tmp_name != ".." )
|
||||||
|
tmp_list.push_back( input_filename + "/" + tmp_name );
|
||||||
|
}
|
||||||
|
filenames.splice( filenames.begin(), tmp_list );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmp = zupdate_file( input_filename, lzip_name, lzip_args2, force );
|
||||||
|
if( tmp < 0 && retval < 1 ) retval = 1;
|
||||||
|
if( tmp > retval ) retval = tmp;
|
||||||
|
if( tmp > 0 ) break;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
|
@ -338,7 +338,7 @@ int test_format( const int infd, const uint8_t ** const magic_datap,
|
||||||
|
|
||||||
|
|
||||||
int wait_for_child( const pid_t pid, const char * const name,
|
int wait_for_child( const pid_t pid, const char * const name,
|
||||||
const int eretval )
|
const int eretval, const bool isgzxz )
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
while( waitpid( pid, &status, 0 ) == -1 )
|
while( waitpid( pid, &status, 0 ) == -1 )
|
||||||
|
@ -355,7 +355,7 @@ int wait_for_child( const pid_t pid, const char * const name,
|
||||||
if( WIFEXITED( status ) )
|
if( WIFEXITED( status ) )
|
||||||
{
|
{
|
||||||
const int tmp = WEXITSTATUS( status );
|
const int tmp = WEXITSTATUS( status );
|
||||||
if( eretval == 1 && tmp == 1 ) return 2; // for ztest
|
if( isgzxz && eretval == 1 && tmp == 1 ) return 2; // for ztest
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
return eretval;
|
return eretval;
|
||||||
|
|
2
zutils.h
2
zutils.h
|
@ -79,7 +79,7 @@ int test_format( const int infd, const uint8_t ** const magic_datap,
|
||||||
// Returns exit status of child process 'pid', or 'eretval' in case of error.
|
// Returns exit status of child process 'pid', or 'eretval' in case of error.
|
||||||
//
|
//
|
||||||
int wait_for_child( const pid_t pid, const char * const name,
|
int wait_for_child( const pid_t pid, const char * const name,
|
||||||
const int eretval = 2 );
|
const int eretval = 2, const bool isgzxz = false );
|
||||||
|
|
||||||
// Returns -1 if child not terminated, 'eretval' in case of error, or
|
// Returns -1 if child not terminated, 'eretval' in case of error, or
|
||||||
// exit status of child process 'pid'.
|
// exit status of child process 'pid'.
|
||||||
|
|
Loading…
Add table
Reference in a new issue