Updated gzip from 1.1 to 1.2.2
authorNate Willams <nate@FreeBSD.org>
Sat, 19 Jun 1993 00:22:46 +0000 (00:22 +0000)
committerNate Willams <nate@FreeBSD.org>
Sat, 19 Jun 1993 00:22:46 +0000 (00:22 +0000)
39 files changed:
gnu/usr.bin/gzip/ChangeLog
gnu/usr.bin/gzip/Makefile
gnu/usr.bin/gzip/NEWS
gnu/usr.bin/gzip/README
gnu/usr.bin/gzip/THANKS
gnu/usr.bin/gzip/TODO
gnu/usr.bin/gzip/algorithm.doc
gnu/usr.bin/gzip/bits.c
gnu/usr.bin/gzip/deflate.c
gnu/usr.bin/gzip/getopt.c
gnu/usr.bin/gzip/getopt.h
gnu/usr.bin/gzip/gzexe
gnu/usr.bin/gzip/gzexe.1
gnu/usr.bin/gzip/gzexe.in
gnu/usr.bin/gzip/gzip.1
gnu/usr.bin/gzip/gzip.c
gnu/usr.bin/gzip/gzip.h
gnu/usr.bin/gzip/inflate.c
gnu/usr.bin/gzip/lzw.c
gnu/usr.bin/gzip/match.S
gnu/usr.bin/gzip/revision.h
gnu/usr.bin/gzip/tailor.h
gnu/usr.bin/gzip/trees.c
gnu/usr.bin/gzip/unlzh.c [new file with mode: 0644]
gnu/usr.bin/gzip/unlzw.c
gnu/usr.bin/gzip/unpack.c
gnu/usr.bin/gzip/unzip.c
gnu/usr.bin/gzip/util.c
gnu/usr.bin/gzip/zdiff
gnu/usr.bin/gzip/zdiff.1
gnu/usr.bin/gzip/zforce
gnu/usr.bin/gzip/zforce.1
gnu/usr.bin/gzip/zgrep [new file with mode: 0644]
gnu/usr.bin/gzip/zgrep.1 [new file with mode: 0644]
gnu/usr.bin/gzip/zip.c
gnu/usr.bin/gzip/zmore
gnu/usr.bin/gzip/zmore.1
gnu/usr.bin/gzip/znew
gnu/usr.bin/gzip/znew.1

index 5238071..0506da5 100644 (file)
@@ -1,3 +1,79 @@
+Thu Jun 17 13:47:05 1993  Jean-loup Gailly  (jloup@chorus.fr)
+
+       * version 1.2.2
+       Fix a compilation error in gzip.c on Sun with cc (worked with gcc).
+
+
+Wed Jun 16 11:20:27 1993  Jean-loup Gailly  (jloup@chorus.fr)
+
+       * version 1.2.1
+        Let zmore act as more if the data is not gzipped.
+         By default, display output name only when name was actually truncated.
+        Use absolute path names in gzexe'd programs for better security.
+        In gzexe, use chmod 700 instead of 755 and don't gzexe tail,rm,etc...
+        Update vms/gzip.hlp.
+        Added a note about the fast options (-1 to -3) in algorithm.doc.
+        Improved man page for zgrep.
+        Minor fixes to gzip.texi.
+        Always set LC_ALL and LANG in configure (for tr on HPUX)
+
+Mon Jun 14 10:03:24 1993  Jean-loup Gailly  (jloup@chorus.fr)
+
+       * version 1.2
+        Added the --list option to display the file characteristics.
+         Added the --no-name option: do not save or restore original filename
+           Save the original name by default.
+         Allow gunzip --suffix "" to attempt decompression on any file
+           regardless of its extension if an original name is present.
+        Add support for the SCO compress -H format.
+         gzip --fast now compresses faster (speed close to that of compress)
+           with degraded compression ratio (but still better than compress).
+          Default level changed to -6 (acts exactly as previous level -5) to
+           be a better indication of its placement in the speed/ratio range.
+        Use smart name truncation: 123456789012.c -> 123456789.c.gz
+          instead of 12345678901.gz
+        With --force, let zcat pass non gzip'ed data unchanged (zcat == cat)
+        Added the zgrep shell script.
+        Made sub.c useful for 16 bit sound, 24 bit images, etc..
+        Supress warnings about suffix for gunzip -r, except with --verbose.
+        Moved the sample programs to a subdirectory sample.
+        On MSDOS, use .gz extension when possible (files without extension)
+        Added a "Special targets" section in INSTALL.
+        Use stty -g correctly in zmore.in.
+        Use cheaper test for gzipness in zforce.in.
+        Remove space before $ in match.S (no longer accepted by gas 2.x)
+        For the shell scripts, do not assume that gzip is in the path.
+        Fix syntax error and define lnk$library in vms/Makefile.mms
+        REGSIGTYPE is void on the Amiga.
+        Do not write empty line when decompressing stdin with --verbose.
+        Fix the 1.1.2 fix for VMS (bug in get_suffix)
+        Added warning in README about compiler bug on Solaris 2.1 for x86.
+        Added warning about 'rehash' in INSTALL.
+        Removed default value of read_buf in bits.c (supermax doesn't like).
+        In tailor.h, added support for Borland C and Zortech C on OS/2.
+        Added warning in gzexe about Ultrix buggy sh (use /bin/sh5 instead).
+        Added warning in zdiff about AIX buggy sh (use /bin/ksh instead).
+        In configure.in, do not try the asm code if DEFS contains NO_ASM
+
+Fri Jun  4 09:49:33 1993  Jean-loup Gailly  (jloup@chorus.fr)
+
+       * version 1.1.2
+        Fix serious bug for VMS (-gz not removed when decompressing).
+        Allow suffix other than .gz in znew.
+        Do not display compression ratio when decompressing stdin.
+        In zmore.in, work around brain damaged stty -g (Ultrix).
+        Display a correct compression ratio for .Z files.
+        Added .z to .gz renaming script in INTALL.
+        Allow setting CFLAGS in configure.
+        Add warning in README about bug in Concentrix cc compiler.
+        Avoid || in Makefile.in (at least one make doesn't support this).
+        Disable useless --ascii option for the Amiga.
+        Add a pointer to the Primos executable in README.
+        Added description of extra field in algorithm.doc.
+        Do not redefine NULL in alloca.c.
+        Added check for unsupported compression methods.
+        Avoid getopt redeclaration on OSF/1.
+
 Tue Jun  1 09:07:15 1993  Jean-loup Gailly  (jloup@chorus.fr)
 
        * version 1.1.1
 Tue Jun  1 09:07:15 1993  Jean-loup Gailly  (jloup@chorus.fr)
 
        * version 1.1.1
index 36200b8..4ac6acb 100644 (file)
@@ -2,10 +2,10 @@
 
 PROG=  gzip
 SRCS=  gzip.c zip.c deflate.c trees.c bits.c unzip.c inflate.c util.c \
 
 PROG=  gzip
 SRCS=  gzip.c zip.c deflate.c trees.c bits.c unzip.c inflate.c util.c \
-       crypt.c lzw.c unlzw.c unpack.c getopt.c match.S
+       crypt.c lzw.c unlzw.c unlzh.c unpack.c getopt.c match.S
 MAN1=  gzexe.0 gzip.0 zdiff.0 zforce.0 zmore.0 znew.0
 CFLAGS+=-DASMV -DHAVE_UNISTD_H=1 -DDIRENT=1
 MAN1=  gzexe.0 gzip.0 zdiff.0 zforce.0 zmore.0 znew.0
 CFLAGS+=-DASMV -DHAVE_UNISTD_H=1 -DDIRENT=1
-MLINKS=        zdiff.1 zcmp.1  gzip.1 gunzip.1  gzip.1 zcat.1  gzip.1 gzcat.1
+MLINKS= gzip.1 gunzip.1  gzip.1 zcat.1  gzip.1 gzcat.1
 LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/gunzip
 LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/gzcat
 LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/zcat
 LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/gunzip
 LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/gzcat
 LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/zcat
@@ -13,7 +13,7 @@ LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/zcat
 afterinstall:
        install -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
           ${.CURDIR}/zforce ${.CURDIR}/gzexe ${.CURDIR}/znew \
 afterinstall:
        install -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
           ${.CURDIR}/zforce ${.CURDIR}/gzexe ${.CURDIR}/znew \
-          ${.CURDIR}/zmore ${.CURDIR}/zdiff ${.CURDIR}/zcmp \
+          ${.CURDIR}/zmore ${.CURDIR}/zdiff ${.CURDIR}/zgrep \
           ${DESTDIR}${BINDIR}
 
 match.o: ${.CURDIR}/match.S
           ${DESTDIR}${BINDIR}
 
 match.o: ${.CURDIR}/match.S
index 097f7b1..b47e9a5 100644 (file)
@@ -1,6 +1,44 @@
-Current Version: 1.1.1
+Current Version: 1.2.2.
 See the file ChangeLog for the details of all changes.
 
 See the file ChangeLog for the details of all changes.
 
+Major changes from 1.2 to 1.2.1
+* Fix a compilation error on Sun with cc (worked with gcc).
+
+Major changes from 1.2 to 1.2.1
+* Let zmore act as more if the data is not gzipped.
+* made gzexe more secure (don't rely on PATH).
+* By default, display output name only when the name was actually truncated.
+
+Major changes from 1.1.2 to 1.2
+* Added the --list option to display the file characteristics.
+* Added the --no-name option: do not save or restore original filename
+  Save the original name by default.
+* Allow gunzip --suffix "" to attempt decompression on any file
+  regardless of its extension if an original name is present.
+* Add support for the SCO compress -H format.
+* gzip --fast now compresses faster (speed close to that of compress)
+  with degraded compression ratio (but still better than compress).
+  Default level changed to -6 (acts exactly as previous level -5) to
+  be a better indication of its placement in the speed/ratio range.
+* Use smart name truncation: 123456789012.c -> 123456789.c.gz
+   instead of 12345678901.gz
+* With --force, let zcat pass non gzip'ed data unchanged (zcat == cat)
+* Added the zgrep shell script.
+* Made sub.c useful for 16 bit sound, 24 bit images, etc..
+* Supress warnings about suffix for gunzip -r, except with --verbose.
+* On MSDOS, use .gz extension when possible (files without extension)
+* Moved the sample programs to a subdirectory sample.
+* Added a "Special targets" section in INSTALL.
+
+Major changes from 1.1.1 to 1.1.2.
+* Fix serious bug for VMS (-gz not removed when decompressing).
+* Allow suffix other than .gz in znew.
+* Do not display compression ratio when decompressing stdin.
+* In zmore.in, work around brain damaged stty -g (Ultrix).
+* Display a correct compression ratio for .Z files.
+* Added .z to .gz renaming script in INTALL.
+* Allow setting CFLAGS in configure.
+
 Major changes from 1.1 to 1.1.1.
 * Fix serious bug in vms.c (affects Vax/VMS only).
 * Added --ascii option.
 Major changes from 1.1 to 1.1.1.
 * Fix serious bug in vms.c (affects Vax/VMS only).
 * Added --ascii option.
index 152b7e5..3a7b283 100644 (file)
@@ -1,4 +1,4 @@
-This is the file README for the gzip distribution, version 1.1.1.
+This is the file README for the gzip distribution, version 1.2.2.
 
 gzip (GNU zip) is a compression utility designed to be a replacement
 for 'compress'. Its main advantages over compress are much better
 
 gzip (GNU zip) is a compression utility designed to be a replacement
 for 'compress'. Its main advantages over compress are much better
@@ -35,14 +35,17 @@ particular, please don't ask me once more for an /etc/magic entry.)
 WARNINGS about broken optimizers:
 
 - on the NeXT, "cc -finline-functions" is broken.  gzip produces
 WARNINGS about broken optimizers:
 
 - on the NeXT, "cc -finline-functions" is broken.  gzip produces
-  valid .z files but they are much too large because the string
+  valid .gz files but they are much too large because the string
   matching code misses most matches. Use "cc -O" instead.
 
 - on the Mips R4000, gcc -O (version 2.3.1) generates bad code, use cc
   or just gcc -g instead.
 
   matching code misses most matches. Use "cc -O" instead.
 
 - on the Mips R4000, gcc -O (version 2.3.1) generates bad code, use cc
   or just gcc -g instead.
 
-- gcc 2.3.3 on the SGI Indigo IRIX 4.0.5 also produces bad code. Use
-  instead: make CC='cc -O2' or gcc without -O.
+- gcc 2.3.3 and 2.4.3 on the SGI Indigo IRIX 4.0.5 also produce bad code.
+  Use instead: make CC='cc -O2' or gcc without -O.
+
+- On Solaris 2.1 for x86, the January 1993 "OEM" compiler release
+  generates bad code. This is fixed in the June 1993 "FCS" release.
 
 - on Sparc with SunOS 4.1.1 and the SC1.0 compiler, the optimizer
   works up to -O3 but -O4 does not work.
 
 - on Sparc with SunOS 4.1.1 and the SC1.0 compiler, the optimizer
   works up to -O3 but -O4 does not work.
@@ -53,6 +56,9 @@ WARNINGS about broken optimizers:
 
 - On dnix 5.3 2.2 cc version 2.37c is buggy. Version 2.38d works.
 
 
 - On dnix 5.3 2.2 cc version 2.37c is buggy. Version 2.38d works.
 
+- On an Alliant running Concentrix, cc (even without optimization) generates
+  incorrect code. You have to use gcc.
+
 For all machines, Use "make check" to check that gzip was compiled correctly.
 
 Please send all comments and bug reports by electronic mail to:
 For all machines, Use "make check" to check that gzip was compiled correctly.
 
 Please send all comments and bug reports by electronic mail to:
@@ -68,6 +74,9 @@ Bug reports should ideally include:
     * A description of the bug behavior
     * The input to gzip, that triggered the bug
 
     * A description of the bug behavior
     * The input to gzip, that triggered the bug
 
+If you send me patches for machines I don't have access to, please test them
+very carefully. gzip is used for backups, it must be extremely reliable.
+
 The package crypt++.el is highly recommended to manipulate gzip'ed
 file from emacs. It recognizes automatically encrypted and compressed
 files when they are first visited or written. It is available via
 The package crypt++.el is highly recommended to manipulate gzip'ed
 file from emacs. It recognizes automatically encrypted and compressed
 files when they are first visited or written. It is available via
@@ -93,13 +102,16 @@ provided under the name COPYING. The latest version of gzip are always
 available by ftp in prep.ai.mit.edu:/pub/gnu, or in any of the prep
 mirror sites:
 
 available by ftp in prep.ai.mit.edu:/pub/gnu, or in any of the prep
 mirror sites:
 
-- sources in gzip-*.tar (or .shar or .tar.z)
+- sources in gzip-*.tar (or .shar or .tar.gz)
 - Solaris 2 executables in sparc-sun-solaris2/gzip-binaries-*.tar
 - MSDOS lha self-extracting exe in gzip-msdos-*.exe. Once extracted,
   copy gzip.exe to gunzip.exe and zcat.exe, or use "gzip -d" to decompress.
 - Solaris 2 executables in sparc-sun-solaris2/gzip-binaries-*.tar
 - MSDOS lha self-extracting exe in gzip-msdos-*.exe. Once extracted,
   copy gzip.exe to gunzip.exe and zcat.exe, or use "gzip -d" to decompress.
+  gzip386.exe runs much faster but only on 386 and above; it needs go32.exe,
+  available in omnigate.clarkson.edu:/pub/msdos/djgpp/djdev110.zip
 
 A VMS executable is available in ftp.spc.edu:[.macro32.savesets]gzip-1-*.zip
 
 A VMS executable is available in ftp.spc.edu:[.macro32.savesets]gzip-1-*.zip
-(use [.macro32]unzip.exe to extract).
+(use [.macro32]unzip.exe to extract). A PRIMOS executable is available
+in ftp.lysator.liu.se:/pub/primos/run/gzip.run.
 
 Many thanks to those who provided me with bug reports and feedback.
 See the files THANKS and ChangeLog for more details.
 
 Many thanks to those who provided me with bug reports and feedback.
 See the files THANKS and ChangeLog for more details.
@@ -129,11 +141,11 @@ On Unix, gzip is mostly useful in combination with tar. GNU tar
 1.11.2 has a -z option to invoke gzip automatically.  "tar -z"
 compresses better than zip, since gzip can then take advantage of
 redundancy between distinct files. The drawback is that you must
 1.11.2 has a -z option to invoke gzip automatically.  "tar -z"
 compresses better than zip, since gzip can then take advantage of
 redundancy between distinct files. The drawback is that you must
-scan the whole tar.z file in order to extract a single file near
+scan the whole tar.gz file in order to extract a single file near
 the end; unzip can directly seek to the end of the zip file. There
 is no overhead when you extract the whole archive anyway.
 If a member of a .zip archive is damaged, other files can still
 the end; unzip can directly seek to the end of the zip file. There
 is no overhead when you extract the whole archive anyway.
 If a member of a .zip archive is damaged, other files can still
-be recovered. If a .tar.z file is damaged, files beyond the failure
+be recovered. If a .tar.gz file is damaged, files beyond the failure
 point cannot be recovered. (Future versions of gzip will have
 error recovery features.)
 
 point cannot be recovered. (Future versions of gzip will have
 error recovery features.)
 
index 5c9a47b..a5e79c1 100644 (file)
@@ -1,9 +1,10 @@
-gzip was written by Jean-loup Gailly <jloup@chorus.fr>, with
-portions written by Mark Adler (inflate.c) and Peter Jannesen
-(unlzw.c). The zip deflate format was defined by Phil Katz.
-Thanks to those who reported problems and suggested
-various improvements.  Here is a partial list of them:
+gzip was written by Jean-loup Gailly <jloup@chorus.fr>, with portions
+written by Mark Adler (inflate.c), Peter Jannesen (unlzw.c) and
+Haruhiko Okumura (unlzh.c). The zip deflate format was defined by Phil Katz.
+Thanks to those who reported problems and suggested various
+improvements.  Here is a partial list of them:
 
 
+Jay Adams               jka@ece.cmu.edu
 Mark Adler              madler@cco.caltech.edu
 Edwin Allum             edwin@csri.toronto.edu
 Joseph Arceneaux       jla@gnu.ai.mit.edu
 Mark Adler              madler@cco.caltech.edu
 Edwin Allum             edwin@csri.toronto.edu
 Joseph Arceneaux       jla@gnu.ai.mit.edu
@@ -29,11 +30,13 @@ Dave Brennan            brennan@hal.com
 Alan Brown              dogbowl@dogbox.acme.gen.nz
 Rodney Brown            rdb@mel.cocam.oz.au
 Bruce                   bde@runx.oz.au
 Alan Brown              dogbowl@dogbox.acme.gen.nz
 Rodney Brown            rdb@mel.cocam.oz.au
 Bruce                   bde@runx.oz.au
+Bill Bumgarner          bbum@stone.com
 Leila Burrell-Davis     leilabd@syma.sussex.ac.uk
 Roger Butenuth          butenuth@ira.uka.de
 Bud Carlson             bud@isle.pegasus.com
 Lim Fung Chai           fclim@i1sin.daq.semi.harris.com
 Wes Chalfant            wes@kofax.com
 Leila Burrell-Davis     leilabd@syma.sussex.ac.uk
 Roger Butenuth          butenuth@ira.uka.de
 Bud Carlson             bud@isle.pegasus.com
 Lim Fung Chai           fclim@i1sin.daq.semi.harris.com
 Wes Chalfant            wes@kofax.com
+Andrew A. Chernov       ache@astral.msk.su
 Paul Close              pdc@lunch.wpd.sgi.com
 Kevin Cosgrove          kevinc@tekig6.pen.tek.com
 Stephen J Cowley        s.j.cowley@amtp.cam.ac.uk
 Paul Close              pdc@lunch.wpd.sgi.com
 Kevin Cosgrove          kevinc@tekig6.pen.tek.com
 Stephen J Cowley        s.j.cowley@amtp.cam.ac.uk
@@ -42,9 +45,12 @@ James R. Crawford       qralston@cislabs.pitt.edu
 Lawrence Crowl          crowl@research.cs.orst.edu 
 Klaus Dahlenburg        kdburg@incoahe.hanse.de
 William E Davidsen      davidsen@ariel.crd.ge.com
 Lawrence Crowl          crowl@research.cs.orst.edu 
 Klaus Dahlenburg        kdburg@incoahe.hanse.de
 William E Davidsen      davidsen@ariel.crd.ge.com
+John M. DeDourek        dedourek@aixive2.cs.unb.ca
 Jeff Deifik             jdeifik@isi.edu
 Vince DeMarco           vince@whatnxt.cuc.ab.ca
 Michael De La Rue       p91152@cplab.physics.edinburgh.ac.uk
 Jeff Deifik             jdeifik@isi.edu
 Vince DeMarco           vince@whatnxt.cuc.ab.ca
 Michael De La Rue       p91152@cplab.physics.edinburgh.ac.uk
+John DeRoo              deroo@grout.adv.shr.dec.com
+Stefano Diomedi         sd@teculx.tecsiel.it
 Lawrence R. Dodd        dodd@roebling.poly.edu
 Matthew Donadio         donadio@mxd120.rh.psu.edu
 Andy Dougherty          andy@crystal.phys.lafayette.edu
 Lawrence R. Dodd        dodd@roebling.poly.edu
 Matthew Donadio         donadio@mxd120.rh.psu.edu
 Andy Dougherty          andy@crystal.phys.lafayette.edu
@@ -71,12 +77,15 @@ Bruno Haible            haible@ma2s2.mathematik.uni-karlsruhe.de
 Junio Hamano            junio@shadow.twinsun.com
 Harald Hanche-Olsen     hanche@ams.sunysb.edu
 Darrel R. Hankerson     hankedr@mail.auburn.edu
 Junio Hamano            junio@shadow.twinsun.com
 Harald Hanche-Olsen     hanche@ams.sunysb.edu
 Darrel R. Hankerson     hankedr@mail.auburn.edu
+Lars Hecking            st000002@hrz1.hrz.th-darmstadt.de
 Ruediger Helsch         ruediger@ramz.ing.tu-bs.de
 Mark C. Henderson       mch@sqwest.wimsey.bc.ca
 Karl Heuer              karl@kelp.boston.ma.us
 Ruediger Helsch         ruediger@ramz.ing.tu-bs.de
 Mark C. Henderson       mch@sqwest.wimsey.bc.ca
 Karl Heuer              karl@kelp.boston.ma.us
+Jarkko Hietaniemi       jhi@dol-guldur.hut.fi
 Thomas Hiller           hiller@fzi.de
 Eiji Hirai              hirai@cc.swarthmore.edu
 Kjetil Torgrim Homme    kjetilho@ifi.uio.no
 Thomas Hiller           hiller@fzi.de
 Eiji Hirai              hirai@cc.swarthmore.edu
 Kjetil Torgrim Homme    kjetilho@ifi.uio.no
+Jim Howard              jim_howard@mentorg.com
 Preston Hunt            gt5708a@prism.gatech.edu
 Shane C Hutchins        sch@nymph.msel.unh.edu
 Hutch                  hutchinson@wrair-emh1.army.mil
 Preston Hunt            gt5708a@prism.gatech.edu
 Shane C Hutchins        sch@nymph.msel.unh.edu
 Hutch                  hutchinson@wrair-emh1.army.mil
@@ -89,24 +98,31 @@ Denny de Jonge          witaddj@dutrex.tudelft.nl
 Arne H. Juul            arnej@lise.unit.no
 Dana Jacobsen           jacobsd@solar.cor2.epa.gov
 Peter Jannesen         peter@ncs.nl
 Arne H. Juul            arnej@lise.unit.no
 Dana Jacobsen           jacobsd@solar.cor2.epa.gov
 Peter Jannesen         peter@ncs.nl
+Tom Judson              judson@scf.usc.edu
+Henry G. Juengst        juengst@saph2.physik.uni-bonn.de
 Sarantos Kapidakis      sarantos%manteion@ics.forth.gr
 Amir J. Katz            amir@matis.ingr.com
 Steve Kelem             kelem@castor.xilinx.com
 Randy Kirchhof          rkk@posms.aus.tx.us
 Ned Kittlitz            kittlitz@seagoon.sw.stratus.com
 Sarantos Kapidakis      sarantos%manteion@ics.forth.gr
 Amir J. Katz            amir@matis.ingr.com
 Steve Kelem             kelem@castor.xilinx.com
 Randy Kirchhof          rkk@posms.aus.tx.us
 Ned Kittlitz            kittlitz@seagoon.sw.stratus.com
+Sakai Kiyotaka          ksakai@mtl.t.u-tokyo.ac.jp
+Philip C Kizer          pckizer@gonzo.tamu.edu
 Pete Klammer            pklammer@ouray.denver.colorado.edu
 Fritz Kleemann          kleemann@informatik.uni-wuerzburg.dbp.de
 Tom Kloos               tk@sequent.com
 Carsten Koch            carsten.koch@icem.de
 Winfried Koenig         win@in.rhein-main.de
 Steph Konigsdorfer      s.konigsdorfer@frmy.bull.fr
 Pete Klammer            pklammer@ouray.denver.colorado.edu
 Fritz Kleemann          kleemann@informatik.uni-wuerzburg.dbp.de
 Tom Kloos               tk@sequent.com
 Carsten Koch            carsten.koch@icem.de
 Winfried Koenig         win@in.rhein-main.de
 Steph Konigsdorfer      s.konigsdorfer@frmy.bull.fr
+Leif Kornstaedt         leif@rumtifsl.ruessel.sub.org
 Michael D. Lawler       mdlawler@bsu-cs.bsu.edu
 Kevin Layer             layer@franz.com
 Howard D. Leadmon       howardl@wb3ffv.ampr.org
 Alexander Lehmann       alex@hal.rhein-main.de
 Simon Leinen            simon@lia.di.epfl.ch
 Michael D. Lawler       mdlawler@bsu-cs.bsu.edu
 Kevin Layer             layer@franz.com
 Howard D. Leadmon       howardl@wb3ffv.ampr.org
 Alexander Lehmann       alex@hal.rhein-main.de
 Simon Leinen            simon@lia.di.epfl.ch
+Burt Leland             burt@molecular.com
 Hugues Leroy            hugues.leroy@irisa.fr 
 Charles Levert          charles@aramis.comm.polymtl.ca
 Hugues Leroy            hugues.leroy@irisa.fr 
 Charles Levert          charles@aramis.comm.polymtl.ca
+Richard Levitte         levitte@e.kth.se
 Torbj|rn Lindh          toobii@elixir.e.kth.se
 David R. Linn          drl@vuse.vanderbilt.edu
 Antonio Lioy            cat@athena.polito.it
 Torbj|rn Lindh          toobii@elixir.e.kth.se
 David R. Linn          drl@vuse.vanderbilt.edu
 Antonio Lioy            cat@athena.polito.it
@@ -114,25 +130,31 @@ Jamie Lokier            u90jl@ecs.oxford.ac.uk
 David J. MacKenzie     djm@eng.umd.edu
 John R MacMillan        john@chance.gts.org
 Ron Male                male@eso.mc.xerox.com
 David J. MacKenzie     djm@eng.umd.edu
 John R MacMillan        john@chance.gts.org
 Ron Male                male@eso.mc.xerox.com
+Don R. Maszle           maze@bea.lbl.gov
 Steeve McCauley         steeve@pooh.geophys.mcgill.ca
 Steeve McCauley         steeve@pooh.geophys.mcgill.ca
+Tom McConnell           tmcconne@sedona.intel.com
 Tod McQuillin           mcquill@ccit05.duq.edu
 Tye McQueen             tye@spillman.com
 Bernd Melchers          melchers@chemie.fu-berlin.de
 Jason Merrill           jason@jarthur.claremont.edu
 Dean S. Messing         deanm@medulla.labs.tek.com
 Tod McQuillin           mcquill@ccit05.duq.edu
 Tye McQueen             tye@spillman.com
 Bernd Melchers          melchers@chemie.fu-berlin.de
 Jason Merrill           jason@jarthur.claremont.edu
 Dean S. Messing         deanm@medulla.labs.tek.com
+M. Mesturino            mesturino@cselt.stet.it
 Luke Mewburn            zak@rmit.edu.au
 Jim Meyering           meyering@cs.utexas.edu 
 Luke Mewburn            zak@rmit.edu.au
 Jim Meyering           meyering@cs.utexas.edu 
-Frederic Miserey        miserey@laguna.ics.uci.edu
+Frederic Miserey        none.fred@applelink.apple.com
 Marcel J.E. Mol         marcel@duteca.et.tudelft.nl
 Marcel J.E. Mol         marcel@duteca.et.tudelft.nl
+Soren Juul Moller       sjm@dde.dk
 Chris Moore             moore@src.bae.co.uk
 Helmut Muelner          hmuelner@fiicmds04.tu-graz.ac.at
 Urban D Mueller         umueller@amiga.physik.unizh.ch
 Timothy Murphy          tim@maths.tcd.ie
 Greg Naber              greg@squally.halcyon.com
 Chris Moore             moore@src.bae.co.uk
 Helmut Muelner          hmuelner@fiicmds04.tu-graz.ac.at
 Urban D Mueller         umueller@amiga.physik.unizh.ch
 Timothy Murphy          tim@maths.tcd.ie
 Greg Naber              greg@squally.halcyon.com
+Jay Nayegandhi          jayng@bbiv02.enet.dec.com
 Karl L. Noell           noell@informatik.fh-wiesbaden.dbp.de
 Arthur David Olson      ado@elsie.nci.nih.gov
 Piet van Oostrum        piet@cs.ruu.nl
 Rafael R. Pappalardo    rafapa@obelix.cica.es 
 Karl L. Noell           noell@informatik.fh-wiesbaden.dbp.de
 Arthur David Olson      ado@elsie.nci.nih.gov
 Piet van Oostrum        piet@cs.ruu.nl
 Rafael R. Pappalardo    rafapa@obelix.cica.es 
+Yves Perrenoud          pyves@nuga.alphanet.ch
 Hal Peterson            hrp@pecan.cray.com
 Pascal Petit            petit@cadillac.ibp.fr
 Bruno Pillard          bp@chorus.fr
 Hal Peterson            hrp@pecan.cray.com
 Pascal Petit            petit@cadillac.ibp.fr
 Bruno Pillard          bp@chorus.fr
@@ -146,7 +168,11 @@ Andreas Raab            ar@nvmr.robin.de
 Eric S. Raymond         esr@snark.thyrsus.com
 Klaus Reimann           kr@cip.physik.uni-stuttgart.de
 Michael Rendell         michael@mercury.cs.mun.ca
 Eric S. Raymond         esr@snark.thyrsus.com
 Klaus Reimann           kr@cip.physik.uni-stuttgart.de
 Michael Rendell         michael@mercury.cs.mun.ca
+Hal Render              render@massive.uccs.edu
+Julian F. Reschke       julian@math.uni-muenster.de
+Phil Richards           Phil.Richards@prg.oxford.ac.uk
 Roland B Roberts        roberts@nsrl31.nsrl.rochester.edu
 Roland B Roberts        roberts@nsrl31.nsrl.rochester.edu
+Arnold Robbins          arnold@cc.gatech.edu
 Kevin Rodgers           kevin@rolling-stone.den.mmc.com
 Kai Uwe Rommel          rommel@informatik.tu-muenchen.de
 Paul Rubin              phr@america.telebit.com
 Kevin Rodgers           kevin@rolling-stone.den.mmc.com
 Kai Uwe Rommel          rommel@informatik.tu-muenchen.de
 Paul Rubin              phr@america.telebit.com
@@ -159,13 +185,16 @@ Niimi Satoshi           a01309@cfi.waseda.ac.jp
 Marc Schaefer           sysadm@alphanet.ch
 Andreas Schwab          schwab@lamothe.informatik.uni-dortmund.de
 Eric Schenk             schenk@cs.toronto.edu
 Marc Schaefer           sysadm@alphanet.ch
 Andreas Schwab          schwab@lamothe.informatik.uni-dortmund.de
 Eric Schenk             schenk@cs.toronto.edu
+Sunando Sen             sens@fasecon.econ.nyu.edu
 Rick Sladkey            jrs@world.std.com
 Daniel L Smith          dls@autodesk.com
 Fred Smith              fredex%fcshome@merk.merk.com
 Rick Sladkey            jrs@world.std.com
 Daniel L Smith          dls@autodesk.com
 Fred Smith              fredex%fcshome@merk.merk.com
+Stephen Soliday         soliday@ncat.edu
 Paul Southworth         pauls@css.itd.umich.edu
 Rob Spencer             robbie@winkle.bhpese.oz.au
 Richard Stallman       rms@gnu.ai.mit.edu
 Carsten Steger          carsten.steger@informatik.tu-muenchen.de
 Paul Southworth         pauls@css.itd.umich.edu
 Rob Spencer             robbie@winkle.bhpese.oz.au
 Richard Stallman       rms@gnu.ai.mit.edu
 Carsten Steger          carsten.steger@informatik.tu-muenchen.de
+David Sundstrom         sunds@anon.asic.sc.ti.com
 Ed Sznyter              ews@babel.babel.com
 Hideaki Tanabe          arctanx@iyeyasu.ynl.t.u-tokyo.ac.jp
 Andrew Telford          ajt@peregrin.resmel.bhp.com.au
 Ed Sznyter              ews@babel.babel.com
 Hideaki Tanabe          arctanx@iyeyasu.ynl.t.u-tokyo.ac.jp
 Andrew Telford          ajt@peregrin.resmel.bhp.com.au
@@ -188,6 +217,7 @@ Stephen J. Walick       steve@nshore.org
 Gray Watson            gray@antaire.com
 Scott Weikart           scott@igc.apc.org
 Ivo Welch               iwelch@agsm.ucla.edu
 Gray Watson            gray@antaire.com
 Scott Weikart           scott@igc.apc.org
 Ivo Welch               iwelch@agsm.ucla.edu
+Jochen Wiedmann         zrawi01@zmcipdec1.zdv.uni-tuebingen.de
 Gijsb. Wiesenekker      wiesenecker@sara.nl 
 Wietze van Winden       wietze@swi.psy.uva.nl
 Larry W. Virden         lwv26@cas.org 
 Gijsb. Wiesenekker      wiesenecker@sara.nl 
 Wietze van Winden       wietze@swi.psy.uva.nl
 Larry W. Virden         lwv26@cas.org 
index 1587c75..37b3c5c 100644 (file)
@@ -48,11 +48,6 @@ Some of the planned features include:
 - Use a larger window size to deal with some large redundant files that
   'compress' currently handles better than gzip.
 
 - Use a larger window size to deal with some large redundant files that
   'compress' currently handles better than gzip.
 
-- implement the following options:
-
-   -e    encrypt
-   -l    list .z file contents
+- Implement the -e (encrypt) option.
    
    
-- support .Z files in SCO 'compress -H' format.
-
 Send comments to Jean-loup Gailly <jloup@chorus.fr>.
 Send comments to Jean-loup Gailly <jloup@chorus.fr>.
index 9c4b0c2..24f7619 100644 (file)
@@ -48,6 +48,12 @@ match, thus speeding up the whole process. If compression ratio is more
 important than speed, zip attempts a complete second search even if
 the first match is already long enough.
 
 important than speed, zip attempts a complete second search even if
 the first match is already long enough.
 
+The lazy match evaluation is no performed for the fastest compression
+modes (speed options -1 to -3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
 
 2. gzip file format
 
 
 2. gzip file format
 
@@ -100,6 +106,23 @@ cleared indicating binary data. For systems which have different
 file formats for ascii text and binary data, the decompressor can
 use the flag to choose the appropriate format.
 
 file formats for ascii text and binary data, the decompressor can
 use the flag to choose the appropriate format.
 
+The extra field, if present, must consist of one or more subfields,
+each with the following format:
+
+  subfield id   : 2 bytes
+  subfield size : 2 bytes  (little-endian format)
+  subfield data
+
+The subfield id can consist of two letters with some mnemonic value.
+Please send any such id to jloup@chorus.fr. Ids with a zero second
+byte are reserved for future use. The following ids are defined:
+
+  Ap (0x41, 0x70) : Apollo file type information
+
+The subfield size is the size of the subfield data and does not
+include the id and the size itself. The field 'extra field length' is
+the total size of the extra field, including subfield ids and sizes.
+
 It must be possible to detect the end of the compressed data with any
 compression format, regardless of the actual size of the compressed
 data. If the compressed data cannot fit in one file (in particular for
 It must be possible to detect the end of the compressed data with any
 compression format, regardless of the actual size of the compressed
 data. If the compressed data cannot fit in one file (in particular for
index 65e78a6..610c7f0 100644 (file)
@@ -60,7 +60,7 @@
 #endif
 
 #ifndef lint
 #endif
 
 #ifndef lint
-static char rcsid[] = "$Id: bits.c,v 0.8 1993/02/04 13:21:06 jloup Exp $";
+static char rcsid[] = "$Id: bits.c,v 0.9 1993/06/11 10:16:58 jloup Exp $";
 #endif
 
 /* ===========================================================================
 #endif
 
 /* ===========================================================================
@@ -84,7 +84,7 @@ local int bi_valid;
  * are always zero.
  */
 
  * are always zero.
  */
 
-int (*read_buf) OF((char *buf, unsigned size)) = file_read;
+int (*read_buf) OF((char *buf, unsigned size));
 /* Current input function. Set to mem_read for in-memory compression */
 
 #ifdef DEBUG
 /* Current input function. Set to mem_read for in-memory compression */
 
 #ifdef DEBUG
index 0b3af93..eaad69a 100644 (file)
@@ -68,7 +68,7 @@
 #include "lzw.h" /* just for consistency checking */
 
 #ifndef lint
 #include "lzw.h" /* just for consistency checking */
 
 #ifndef lint
-static char rcsid[] = "$Id: deflate.c,v 0.13 1993/05/25 16:25:40 jloup Exp $";
+static char rcsid[] = "$Id: deflate.c,v 0.14 1993/06/12 20:11:10 jloup Exp $";
 #endif
 
 /* ===========================================================================
 #endif
 
 /* ===========================================================================
@@ -187,8 +187,17 @@ unsigned near max_chain_length;
 
 local unsigned int max_lazy_match;
 /* Attempt to find a better match only when the current match is strictly
 
 local unsigned int max_lazy_match;
 /* Attempt to find a better match only when the current match is strictly
- * smaller than this value.
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
  */
  */
+#define max_insert_length  max_lazy_match
+/* Insert new strings in the hash table only if the match length
+ * is not greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+local int compr_level;
+/* compression level (1..9) */
 
 int near good_match;
 /* Use a faster search when the previous match is longer than this */
 
 int near good_match;
 /* Use a faster search when the previous match is longer than this */
@@ -216,18 +225,20 @@ typedef struct config {
 local config configuration_table[10] = {
 /*      good lazy nice chain */
 /* 0 */ {0,    0,  0,    0},  /* store only */
 local config configuration_table[10] = {
 /*      good lazy nice chain */
 /* 0 */ {0,    0,  0,    0},  /* store only */
-/* 1 */ {4,    4, 16,   16},  /* maximum speed */
-/* 2 */ {6,    8, 16,   16},
-/* 3 */ {8,   16, 32,   32},
-/* 4 */ {8,   16, 64,   64},
-/* 5 */ {8,   16, 128, 128},
-/* 6 */ {8,   32, 128, 256},
-/* 7 */ {8,   64, 128, 512},
+/* 1 */ {4,    4,  8,    4},  /* maximum speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8},
+/* 3 */ {4,    6, 32,   32},
+
+/* 4 */ {4,    4, 16,   16},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32},
+/* 6 */ {8,   16, 128, 128},
+/* 7 */ {8,   32, 128, 256},
 /* 8 */ {32, 128, 258, 1024},
 /* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
 
 /* 8 */ {32, 128, 258, 1024},
 /* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
 
-/* Note: the current code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * but these restrictions can easily be removed at a small cost.
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
  */
 
 #define EQUAL 0
  */
 
 #define EQUAL 0
@@ -237,6 +248,8 @@ local config configuration_table[10] = {
  *  Prototypes for local functions.
  */
 local void fill_window   OF((void));
  *  Prototypes for local functions.
  */
 local void fill_window   OF((void));
+local ulg deflate_fast   OF((void));
+
       int  longest_match OF((IPos cur_match));
 #ifdef ASMV
       void match_init OF((void)); /* asm code initialization */
       int  longest_match OF((IPos cur_match));
 #ifdef ASMV
       void match_init OF((void)); /* asm code initialization */
@@ -277,6 +290,7 @@ void lm_init (pack_level, flags)
     register unsigned j;
 
     if (pack_level < 1 || pack_level > 9) error("bad pack level");
     register unsigned j;
 
     if (pack_level < 1 || pack_level > 9) error("bad pack level");
+    compr_level = pack_level;
 
     /* Initialize the hash table. */
 #if defined(MAXSEG_64K) && HASH_BITS == 15
 
     /* Initialize the hash table. */
 #if defined(MAXSEG_64K) && HASH_BITS == 15
@@ -558,10 +572,12 @@ local void fill_window()
                 (char*)NULL, (long)strstart - block_start, (eof))
 
 /* ===========================================================================
                 (char*)NULL, (long)strstart - block_start, (eof))
 
 /* ===========================================================================
- * Processes a new input file and return its compressed length.
+ * Processes a new input file and return its compressed length. This
+ * function does not perform lazy evaluationof matches and inserts
+ * new strings in the dictionary only for unmatched strings. It is used
+ * only for the fast compression options.
  */
  */
-#ifdef NO_LAZY
-ulg deflate()
+local ulg deflate_fast()
 {
     IPos hash_head; /* head of the hash chain */
     int flush;      /* set if current block must be flushed */
 {
     IPos hash_head; /* head of the hash chain */
     int flush;      /* set if current block must be flushed */
@@ -592,22 +608,38 @@ ulg deflate()
             flush = ct_tally(strstart-match_start, match_length - MIN_MATCH);
 
             lookahead -= match_length;
             flush = ct_tally(strstart-match_start, match_length - MIN_MATCH);
 
             lookahead -= match_length;
-            match_length--; /* string at strstart already in hash table */
-            do {
-                strstart++;
-                INSERT_STRING(strstart, hash_head);
-                /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-                 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
-                 * these bytes are garbage, but it does not matter since the
-                 * next lookahead bytes will always be emitted as literals.
-                 */
-            } while (--match_length != 0);
+
+           /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+            if (match_length <= max_insert_length) {
+                match_length--; /* string at strstart already in hash table */
+                do {
+                    strstart++;
+                    INSERT_STRING(strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
+                     * these bytes are garbage, but it does not matter since
+                     * the next lookahead bytes will be emitted as literals.
+                     */
+                } while (--match_length != 0);
+               strstart++; 
+            } else {
+               strstart += match_length;
+               match_length = 0;
+               ins_h = window[strstart];
+               UPDATE_HASH(ins_h, window[strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+            }
         } else {
             /* No match, output a literal byte */
         } else {
             /* No match, output a literal byte */
+            Tracevv((stderr,"%c",window[strstart]));
             flush = ct_tally (0, window[strstart]);
             lookahead--;
             flush = ct_tally (0, window[strstart]);
             lookahead--;
+           strstart++; 
         }
         }
-        strstart++; 
         if (flush) FLUSH_BLOCK(0), block_start = strstart;
 
         /* Make sure that we always have enough lookahead, except
         if (flush) FLUSH_BLOCK(0), block_start = strstart;
 
         /* Make sure that we always have enough lookahead, except
@@ -620,7 +652,7 @@ ulg deflate()
     }
     return FLUSH_BLOCK(1); /* eof */
 }
     }
     return FLUSH_BLOCK(1); /* eof */
 }
-#else /* LAZY */
+
 /* ===========================================================================
  * Same as above, but achieves better compression. We use a lazy
  * evaluation for matches: a match is finally adopted only if there is
 /* ===========================================================================
  * Same as above, but achieves better compression. We use a lazy
  * evaluation for matches: a match is finally adopted only if there is
@@ -637,6 +669,8 @@ ulg deflate()
     extern long isize;        /* byte length of input file, for debug only */
 #endif
 
     extern long isize;        /* byte length of input file, for debug only */
 #endif
 
+    if (compr_level <= 3) return deflate_fast(); /* optimized for speed */
+
     /* Process the input block. */
     while (lookahead != 0) {
         /* Insert the string window[strstart .. strstart+2] in the
     /* Process the input block. */
     while (lookahead != 0) {
         /* Insert the string window[strstart .. strstart+2] in the
@@ -727,4 +761,3 @@ ulg deflate()
 
     return FLUSH_BLOCK(1); /* eof */
 }
 
     return FLUSH_BLOCK(1); /* eof */
 }
-#endif /* LAZY */
index 3bf0277..9971e7b 100644 (file)
@@ -34,6 +34,11 @@ char *alloca ();
 #endif /* alloca.h */
 #endif /* not __GNUC__ */
 
 #endif /* alloca.h */
 #endif /* not __GNUC__ */
 
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#  define _NO_PROTO
+#endif
+
 #include <stdio.h>
 
 #if defined(USG) || defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
 #include <stdio.h>
 
 #if defined(USG) || defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
index 764f2f4..bd3b8e4 100644 (file)
@@ -99,8 +99,6 @@ enum _argtype
    differences in the consts, in stdlib.h.  To avoid compilation
    errors, only prototype getopt for the GNU C library.  */
 extern int getopt (int argc, char *const *argv, const char *shortopts);
    differences in the consts, in stdlib.h.  To avoid compilation
    errors, only prototype getopt for the GNU C library.  */
 extern int getopt (int argc, char *const *argv, const char *shortopts);
-#else /* not __GNU_LIBRARY__ */
-extern int getopt ();
 #endif /* not __GNU_LIBRARY__ */
 extern int getopt_long (int argc, char *const *argv, const char *shortopts,
                        const struct option *longopts, int *longind);
 #endif /* not __GNU_LIBRARY__ */
 extern int getopt_long (int argc, char *const *argv, const char *shortopts,
                        const struct option *longopts, int *longind);
index ba22eb1..3382bcf 100644 (file)
@@ -8,8 +8,9 @@
 # We also try to retain the original file permissions on the compressed file.
 # For safety reasons, gzexe will not create setuid or setgid shell scripts.
 
 # We also try to retain the original file permissions on the compressed file.
 # For safety reasons, gzexe will not create setuid or setgid shell scripts.
 
-# Warning: the first line of this file must be either : or #!/bin/sh
+# WARNING: the first line of this file must be either : or #!/bin/sh
 # The : is required for some old versions of csh.
 # The : is required for some old versions of csh.
+# On Ultrix, /bin/sh is too buggy, change the first line to: #!/bin/sh5
 
 x=`basename $0`
 if test $# = 0; then
 
 x=`basename $0`
 if test $# = 0; then
@@ -37,6 +38,21 @@ if test -z "`(${CPMOD-cpmod} zfoo1$$ zfoo2$$) 2>&1`"; then
 fi
 rm -f zfoo[12]$$
 
 fi
 rm -f zfoo[12]$$
 
+tail=""
+IFS="${IFS=    }"; saveifs="$IFS"; IFS="${IFS}:"
+for dir in $PATH; do
+  test -z "$dir" && dir=.
+  if test -f $dir/tail; then
+    tail="$dir/tail"
+    break
+  fi
+done
+IFS="$saveifs"
+if test -z "$tail"; then
+  echo cannot find tail
+  exit 1
+fi
+
 for i do
   if test ! -f "$i" ; then
     echo ${x}: $i not a file
 for i do
   if test ! -f "$i" ; then
     echo ${x}: $i not a file
@@ -57,10 +73,10 @@ for i do
     echo "${x}: $i has setgid permission, unchanged"
     continue
   fi
     echo "${x}: $i has setgid permission, unchanged"
     continue
   fi
-  if test "`basename $i`" = gzip; then
-    echo "${x}: cannot compress gzip itself"
-    continue
-  fi
+  case "`basename $i`" in
+  gzip | tail | chmod | ln | sleep | rm)
+       echo "${x}: $i would depend on itself"; continue ;;
+  esac
   if test -z "$cpmod"; then
     cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp
     if test -w $tmp 2>/dev/null; then
   if test -z "$cpmod"; then
     cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp
     if test -w $tmp 2>/dev/null; then
@@ -72,25 +88,25 @@ for i do
   fi
   if test $decomp -eq 0; then
     sed 1q $0 > $tmp
   fi
   if test $decomp -eq 0; then
     sed 1q $0 > $tmp
-    cat >> $tmp <<'EOF'
+    sed "s|^if tail|if $tail|" >> $tmp <<'EOF'
 skip=18
 skip=18
-if tail +$skip $0 | gzip -cd > /tmp/gztmp$$; then
-  chmod 755 /tmp/gztmp$$
-  prog="`basename $0`"
-  if ln /tmp/gztmp$$ "/tmp/$prog" 2>/dev/null; then
+if tail +$skip $0 | "/usr/local/bin"/gzip -cd > /tmp/gztmp$$; then
+  /bin/chmod 700 /tmp/gztmp$$
+  prog="`echo $0 | /bin/sed 's|^.*/||`"
+  if /bin/ln /tmp/gztmp$$ "/tmp/$prog" 2>/dev/null; then
     trap '/bin/rm -f /tmp/gztmp$$ "/tmp/$prog"; exit $res' 0
     trap '/bin/rm -f /tmp/gztmp$$ "/tmp/$prog"; exit $res' 0
-    (sleep 5; /bin/rm -f /tmp/gztmp$$ "/tmp/$prog") 2>/dev/null &
+    (/bin/sleep 5; /bin/rm -f /tmp/gztmp$$ "/tmp/$prog") 2>/dev/null &
     /tmp/"$prog" ${1+"$@"}; res=$?
   else
     trap '/bin/rm -f /tmp/gztmp$$; exit $res' 0
     /tmp/"$prog" ${1+"$@"}; res=$?
   else
     trap '/bin/rm -f /tmp/gztmp$$; exit $res' 0
-    (sleep 5; /bin/rm -f /tmp/gztmp$$) 2>/dev/null &
+    (/bin/sleep 5; /bin/rm -f /tmp/gztmp$$) 2>/dev/null &
     /tmp/gztmp$$ ${1+"$@"}; res=$?
   fi
 else
   echo Cannot decompress $0; exit 1
 fi; exit $res
 EOF
     /tmp/gztmp$$ ${1+"$@"}; res=$?
   fi
 else
   echo Cannot decompress $0; exit 1
 fi; exit $res
 EOF
-    gzip -cv9 "$i" >> $tmp || {
+    "/usr/local/bin"/gzip -cv9 "$i" >> $tmp || {
       /bin/rm -f $tmp
       echo ${x}: compression not possible for $i, file unchanged.
       res=1
       /bin/rm -f $tmp
       echo ${x}: compression not possible for $i, file unchanged.
       res=1
@@ -103,7 +119,7 @@ EOF
     if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
       eval `sed -e 1d -e 2q "$i"`
     fi
     if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
       eval `sed -e 1d -e 2q "$i"`
     fi
-    if tail +$skip "$i" | gzip -cd > $tmp; then
+    if tail +$skip "$i" | "/usr/local/bin"/gzip -cd > $tmp; then
       :
     else
       echo ${x}: $i probably not in gzexe format, file unchanged.
       :
     else
       echo ${x}: $i probably not in gzexe format, file unchanged.
index 68e4127..8b62cd6 100644 (file)
@@ -27,6 +27,13 @@ This utility is most useful on systems with very small disks.
 Decompress the given executables instead of compressing them.
 .SH "SEE ALSO"
 gzip(1), znew(1), zmore(1), zcmp(1), zforce(1)
 Decompress the given executables instead of compressing them.
 .SH "SEE ALSO"
 gzip(1), znew(1), zmore(1), zcmp(1), zforce(1)
+.SH CAVEATS
+The compressed executable is a shell script. This may create some
+security holes. In particular, the compressed executable relies
+on the PATH environment variable to find
+.I gzip
+and some other utilities
+.I (tail, chmod, ln, sleep).
 .SH "BUGS"
 .I gzexe 
 attempts to retain the original file attributes on the compressed executable,
 .SH "BUGS"
 .I gzexe 
 attempts to retain the original file attributes on the compressed executable,
index dcbab88..a28ec3d 100644 (file)
@@ -9,8 +9,9 @@
 # We also try to retain the original file permissions on the compressed file.
 # For safety reasons, gzexe will not create setuid or setgid shell scripts.
 
 # We also try to retain the original file permissions on the compressed file.
 # For safety reasons, gzexe will not create setuid or setgid shell scripts.
 
-# Warning: the first line of this file must be either : or #!/bin/sh
+# WARNING: the first line of this file must be either : or #!/bin/sh
 # The : is required for some old versions of csh.
 # The : is required for some old versions of csh.
+# On Ultrix, /bin/sh is too buggy, change the first line to: #!/bin/sh5
 
 x=`basename $0`
 if test $# = 0; then
 
 x=`basename $0`
 if test $# = 0; then
@@ -38,6 +39,21 @@ if test -z "`(${CPMOD-cpmod} zfoo1$$ zfoo2$$) 2>&1`"; then
 fi
 rm -f zfoo[12]$$
 
 fi
 rm -f zfoo[12]$$
 
+tail=""
+IFS="${IFS=    }"; saveifs="$IFS"; IFS="${IFS}:"
+for dir in $PATH; do
+  test -z "$dir" && dir=.
+  if test -f $dir/tail; then
+    tail="$dir/tail"
+    break
+  fi
+done
+IFS="$saveifs"
+if test -z "$tail"; then
+  echo cannot find tail
+  exit 1
+fi
+
 for i do
   if test ! -f "$i" ; then
     echo ${x}: $i not a file
 for i do
   if test ! -f "$i" ; then
     echo ${x}: $i not a file
@@ -58,10 +74,10 @@ for i do
     echo "${x}: $i has setgid permission, unchanged"
     continue
   fi
     echo "${x}: $i has setgid permission, unchanged"
     continue
   fi
-  if test "`basename $i`" = gzip; then
-    echo "${x}: cannot compress gzip itself"
-    continue
-  fi
+  case "`basename $i`" in
+  gzip | tail | chmod | ln | sleep | rm)
+       echo "${x}: $i would depend on itself"; continue ;;
+  esac
   if test -z "$cpmod"; then
     cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp
     if test -w $tmp 2>/dev/null; then
   if test -z "$cpmod"; then
     cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp
     if test -w $tmp 2>/dev/null; then
@@ -73,25 +89,25 @@ for i do
   fi
   if test $decomp -eq 0; then
     sed 1q $0 > $tmp
   fi
   if test $decomp -eq 0; then
     sed 1q $0 > $tmp
-    cat >> $tmp <<'EOF'
+    sed "s|^if tail|if $tail|" >> $tmp <<'EOF'
 skip=18
 skip=18
-if tail +$skip $0 | gzip -cd > /tmp/gztmp$$; then
-  chmod 755 /tmp/gztmp$$
-  prog="`basename $0`"
-  if ln /tmp/gztmp$$ "/tmp/$prog" 2>/dev/null; then
+if tail +$skip $0 | "BINDIR"/gzip -cd > /tmp/gztmp$$; then
+  /bin/chmod 700 /tmp/gztmp$$
+  prog="`echo $0 | /bin/sed 's|^.*/||`"
+  if /bin/ln /tmp/gztmp$$ "/tmp/$prog" 2>/dev/null; then
     trap '/bin/rm -f /tmp/gztmp$$ "/tmp/$prog"; exit $res' 0
     trap '/bin/rm -f /tmp/gztmp$$ "/tmp/$prog"; exit $res' 0
-    (sleep 5; /bin/rm -f /tmp/gztmp$$ "/tmp/$prog") 2>/dev/null &
+    (/bin/sleep 5; /bin/rm -f /tmp/gztmp$$ "/tmp/$prog") 2>/dev/null &
     /tmp/"$prog" ${1+"$@"}; res=$?
   else
     trap '/bin/rm -f /tmp/gztmp$$; exit $res' 0
     /tmp/"$prog" ${1+"$@"}; res=$?
   else
     trap '/bin/rm -f /tmp/gztmp$$; exit $res' 0
-    (sleep 5; /bin/rm -f /tmp/gztmp$$) 2>/dev/null &
+    (/bin/sleep 5; /bin/rm -f /tmp/gztmp$$) 2>/dev/null &
     /tmp/gztmp$$ ${1+"$@"}; res=$?
   fi
 else
   echo Cannot decompress $0; exit 1
 fi; exit $res
 EOF
     /tmp/gztmp$$ ${1+"$@"}; res=$?
   fi
 else
   echo Cannot decompress $0; exit 1
 fi; exit $res
 EOF
-    gzip -cv9 "$i" >> $tmp || {
+    "BINDIR"/gzip -cv9 "$i" >> $tmp || {
       /bin/rm -f $tmp
       echo ${x}: compression not possible for $i, file unchanged.
       res=1
       /bin/rm -f $tmp
       echo ${x}: compression not possible for $i, file unchanged.
       res=1
@@ -104,7 +120,7 @@ EOF
     if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
       eval `sed -e 1d -e 2q "$i"`
     fi
     if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
       eval `sed -e 1d -e 2q "$i"`
     fi
-    if tail +$skip "$i" | gzip -cd > $tmp; then
+    if tail +$skip "$i" | "BINDIR"/gzip -cd > $tmp; then
       :
     else
       echo ${x}: $i probably not in gzexe format, file unchanged.
       :
     else
       echo ${x}: $i probably not in gzexe format, file unchanged.
index a7d331f..06ec9d9 100644 (file)
@@ -5,7 +5,7 @@ gzip, gunzip, zcat \- compress or expand files
 .SH SYNOPSIS
 .ll +8
 .B gzip
 .SH SYNOPSIS
 .ll +8
 .B gzip
-.RB [ " \-acdfhLrtvV19 " ]
+.RB [ " \-acdfhlLnrtvV19 " ]
 .RB [ \-S\ suffix ]
 [
 .I "name \&..."
 .RB [ \-S\ suffix ]
 [
 .I "name \&..."
@@ -13,14 +13,14 @@ gzip, gunzip, zcat \- compress or expand files
 .ll -8
 .br
 .B gunzip
 .ll -8
 .br
 .B gunzip
-.RB [ " \-acfhLrtvV " ]
+.RB [ " \-acfhlLnrtvV " ]
 .RB [ \-S\ suffix ]
 [
 .I "name \&..."
 ]
 .br
 .B zcat
 .RB [ \-S\ suffix ]
 [
 .I "name \&..."
 ]
 .br
 .B zcat
-.RB [ " \-hLV " ]
+.RB [ " \-fhLV " ]
 [
 .I "name \&..."
 ]
 [
 .I "name \&..."
 ]
@@ -35,21 +35,33 @@ while keeping the same ownership modes, access and modification times.
 .B "\-gz"
 for VMS,
 .B "z"
 .B "\-gz"
 for VMS,
 .B "z"
-for MSDOS, OS/2 and Atari.)
+for MSDOS, OS/2 FAT and Atari.)
 If no files are specified, the standard input is compressed to the
 If no files are specified, the standard input is compressed to the
-standard output. If the new file name is too long,
-.I gzip
-truncates it and keeps the original file name in the compressed file.
+standard output.
 .I Gzip
 will only attempt to compress regular files.
 In particular, it will ignore symbolic links.
 .PP
 .I Gzip
 will only attempt to compress regular files.
 In particular, it will ignore symbolic links.
 .PP
+If the new file name is too long for its file system,
+.I gzip
+truncates it and keeps the original file name in the compressed file.
+.I Gzip
+attempts to truncate only the parts of the file name longer than 3 characters.
+(A part is delimited by dots.) If the name consists of small parts only,
+the longest parts are truncated. For example, if file names are limited
+to 14 characters, gzip.msdos.exe is compressed to gzi.msd.exe.gz.
+Names are not truncated on systems which do not have a limit on file name
+length.
+.PP
 Compressed files can be restored to their original form using
 .I gzip -d
 or
 .I gunzip
 or
 .I zcat.
 Compressed files can be restored to their original form using
 .I gzip -d
 or
 .I gunzip
 or
 .I zcat.
+If the original name saved in the compressed file is not suitable for its
+file system, a new name is constructed from the original one to make it
+legal.
 .PP
 .I gunzip
 takes a list of files on its command line and replaces each
 .PP
 .I gunzip
 takes a list of files on its command line and replaces each
@@ -66,10 +78,17 @@ as shorthands for
 and
 .B "\&.tar.Z"
 respectively.
 and
 .B "\&.tar.Z"
 respectively.
+When compressing,
+.I gzip
+uses the
+.B "\&.tgz"
+extension if necessary instead of truncating a file with a
+.B "\&.tar"
+extension.
 .PP
 .I gunzip
 can currently decompress files created by
 .PP
 .I gunzip
 can currently decompress files created by
-.I gzip, zip, compress
+.I gzip, zip, compress, compress -H
 or
 .I pack.
 The detection of the input format is automatic.  When using
 or
 .I pack.
 The detection of the input format is automatic.  When using
@@ -77,7 +96,7 @@ the first two formats,
 .I gunzip
 checks a 32 bit CRC. For
 .I pack, gunzip
 .I gunzip
 checks a 32 bit CRC. For
 .I pack, gunzip
-checks the uncompressed length. The
+checks the uncompressed length. The standard
 .I compress
 format was not designed to allow consistency checks. However
 .I gunzip
 .I compress
 format was not designed to allow consistency checks. However
 .I gunzip
@@ -88,6 +107,8 @@ correct simply because the standard
 does not complain. This generally means that the standard
 .I uncompress
 does not check its input, and happily generates garbage output.
 does not complain. This generally means that the standard
 .I uncompress
 does not check its input, and happily generates garbage output.
+The SCO compress -H format (lzh compression method) does not include a CRC
+but also allows some consistency checks.
 .PP
 Files created by
 .I zip
 .PP
 Files created by
 .I zip
@@ -150,7 +171,7 @@ Ascii text mode: convert end-of-lines using local conventions. This option
 is supported only on some non-Unix systems. For MSDOS, CR LF is converted
 to LF when compressing, and LF is converted to CR LF when decompressing.
 .TP
 is supported only on some non-Unix systems. For MSDOS, CR LF is converted
 to LF when compressing, and LF is converted to CR LF when decompressing.
 .TP
-.B \-c --stdout
+.B \-c --stdout --to-stdout
 Write output on standard output; keep original files unchanged.
 If there are several input files, the output consists of a sequence of
 independently compressed members. To obtain better compression,
 Write output on standard output; keep original files unchanged.
 If there are several input files, the output consists of a sequence of
 independently compressed members. To obtain better compression,
@@ -162,7 +183,15 @@ Decompress.
 .B \-f --force
 Force compression or decompression even if the file has multiple links
 or the corresponding file already exists, or if the compressed data
 .B \-f --force
 Force compression or decompression even if the file has multiple links
 or the corresponding file already exists, or if the compressed data
-is read from or written to a terminal. If
+is read from or written to a terminal. If the input data is not in
+a format recognized by
+.I gzip,
+and if the option --stdout is also given, copy the input data without change
+to the standard ouput: let
+.I zcat
+behave as
+.I cat.
+If
 .B \-f
 is not given,
 and when not running in the background,
 .B \-f
 is not given,
 and when not running in the background,
@@ -172,10 +201,47 @@ prompts to verify whether an existing file should be overwritten.
 .B \-h --help
 Display a help screen and quit.
 .TP
 .B \-h --help
 Display a help screen and quit.
 .TP
+.B \-l --list
+For each compressed file, list the following fields:
+
+    compressed size: size of the compressed file
+    uncompressed size: size of the uncompressed file
+    ratio: compression ratio (0.0% if unknown)
+    uncompressed_name: name of the uncompressed file
+
+The uncompressed size is given as -1 for files not in gzip format,
+such as compressed .Z files. To get the uncompressed size for such a file,
+you can use:
+
+    zcat file.Z | wc -c
+
+In combination with the --verbose option, the following fields are also
+displayed:
+
+    method: compression method
+    crc: the 32-bit CRC of the uncompressed data
+    date & time: time stamp for the uncompressed file
+
+The compression methods currently supported are deflate, compress, lzh
+(SCO compress -H) and pack.  The crc is given as ffffffff for a file
+not in gzip format.
+
+With --verbose, the size totals and compression ratio for all files
+is also displayed, unless some sizes are unknown. With --quiet,
+the title and totals lines are not displayed.
+.TP
 .B \-L --license
 Display the
 .I gzip
 .B \-L --license
 Display the
 .I gzip
-license.
+license and quit.
+.TP
+.B \-n --no-name
+When compressing, do not save the original file name by default. (The
+original name is always saved if the name had to be truncated.) When
+decompressing, do not restore the original file name if present: remove
+only the
+.I gzip
+suffix from the compressed file name.
 .TP
 .B \-q --quiet
 Suppress all warnings.
 .TP
 .B \-q --quiet
 Suppress all warnings.
@@ -189,10 +255,15 @@ will descend into the directory and compress all the files it finds there
 .I gunzip
 ).
 .TP
 .I gunzip
 ).
 .TP
-.B \-S .z   --suffix .z
-Use suffix .z instead of .gz. Any suffix can be given, but suffixes
+.B \-S .suf   --suffix .suf
+Use suffix .suf instead of .gz. Any suffix can be given, but suffixes
 other than .z and .gz should be avoided to avoid confusion when files
 other than .z and .gz should be avoided to avoid confusion when files
-are transferred to other systems.  Previous versions of gzip used
+are transferred to other.  A null suffix forces gunzip to  try
+decompression on all given files regardless of suffix, as in:
+
+    gunzip -S "" *       (*.* for MSDOS)
+
+Previous versions of gzip used
 the .z suffix. This was changed to avoid a conflict with
 .IR pack "(1)".
 .TP
 the .z suffix. This was changed to avoid a conflict with
 .IR pack "(1)".
 .TP
@@ -200,7 +271,8 @@ the .z suffix. This was changed to avoid a conflict with
 Test. Check the compressed file integrity.
 .TP
 .B \-v --verbose
 Test. Check the compressed file integrity.
 .TP
 .B \-v --verbose
-Verbose. Display the name and percentage reduction for each file compressed.
+Verbose. Display the name and percentage reduction for each file compressed
+or decompressed.
 .TP
 .B \-V --version
 Version. Display the version number and compilation options then quit.
 .TP
 .B \-V --version
 Version. Display the version number and compilation options then quit.
@@ -219,7 +291,8 @@ or
 .B \-\-best
 indicates the slowest compression method (optimal compression).
 The default compression level is
 .B \-\-best
 indicates the slowest compression method (optimal compression).
 The default compression level is
-.BR \-5.
+.BR \-6
+(that is, biased towards high compression at expense of speed).
 .SH "ADVANCED USAGE"
 Multiple compressed files can be concatenated. In this case,
 .I gunzip
 .SH "ADVANCED USAGE"
 Multiple compressed files can be concatenated. In this case,
 .I gunzip
@@ -268,7 +341,7 @@ pack(1), compact(1)
 Exit status is normally 0;
 if an error occurs, exit status is 1. If a warning occurs, exit status is 2.
 .PP
 Exit status is normally 0;
 if an error occurs, exit status is 1. If a warning occurs, exit status is 2.
 .PP
-Usage: gzip [-cdfhLrtvV19] [-S suffix] [file ...]
+Usage: gzip [-cdfhlLnrtvV19] [-S suffix] [file ...]
 .in +8
 Invalid options were specified on the command line.
 .in -8
 .in +8
 Invalid options were specified on the command line.
 .in -8
@@ -322,7 +395,9 @@ been corrupted.
 .in +8
 Percentage of the input saved by compression.
 (Relevant only for
 .in +8
 Percentage of the input saved by compression.
 (Relevant only for
-.BR \-v \.)
+.BR \-v
+and
+.BR \-l \.)
 .in -8
 -- not a regular file or directory: ignored
 .in +8
 .in -8
 -- not a regular file or directory: ignored
 .in +8
@@ -358,3 +433,7 @@ environment variable as in:
 In the above example, gzip is invoked implicitly by the -z option
 of GNU tar. Make sure that the same block size (-b option of
 tar) is used for reading and writing compressed data on tapes.
 In the above example, gzip is invoked implicitly by the -z option
 of GNU tar. Make sure that the same block size (-b option of
 tar) is used for reading and writing compressed data on tapes.
+.SH BUGS
+The --list option reports incorrect sizes if they exceed 2 gigabytes.
+The --list option reports sizes as -1 and crc as ffffffff if the
+compressed file is on a non seekable media.
index 2bc1c5f..37100cd 100644 (file)
@@ -31,19 +31,23 @@ static char  *license_msg[] = {
  * Outputs:
  *        file.gz:   compressed file with same mode, owner, and utimes
  *     or stdout with -c option or if stdin used as input.
  * Outputs:
  *        file.gz:   compressed file with same mode, owner, and utimes
  *     or stdout with -c option or if stdin used as input.
- * If the OS does not support file names with multiple dots (MSDOS, VMS) or
- * if the output file name had to be truncated, the original name is kept
+ * If the output file name had to be truncated, the original name is kept
  * in the compressed file.
  * On MSDOS, file.tmp -> file.tmz. On VMS, file.tmp -> file.tmp-gz.
  *
  * in the compressed file.
  * On MSDOS, file.tmp -> file.tmz. On VMS, file.tmp -> file.tmp-gz.
  *
+ * Using gz on MSDOS would create too many file name conflicts. For
+ * example, foo.txt -> foo.tgz (.tgz must be reserved as shorthand for
+ * tar.gz). Similarly, foo.dir and foo.doc would both be mapped to foo.dgz.
+ * I also considered 12345678.txt -> 12345txt.gz but this truncates the name
+ * too heavily. There is no ideal solution given the MSDOS 8+3 limitation. 
+ *
  * For the meaning of all compilation flags, see comments in Makefile.in.
  */
 
 #ifndef lint
  * For the meaning of all compilation flags, see comments in Makefile.in.
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: gzip.c,v 0.19 1993/06/01 14:21:46 jloup Exp $";
+static char rcsid[] = "$Id: gzip.c,v 0.22 1993/06/16 16:53:43 jloup Exp $";
 #endif
 
 #endif
 
-#include <stdio.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include <signal.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include <signal.h>
@@ -58,6 +62,12 @@ static char rcsid[] = "$Id: gzip.c,v 0.19 1993/06/01 14:21:46 jloup Exp $";
 
                /* configuration */
 
 
                /* configuration */
 
+#ifdef NO_TIME_H
+#  include <sys/time.h>
+#else
+#  include <time.h>
+#endif
+
 #ifndef NO_FCNTL_H
 #  include <fcntl.h>
 #endif
 #ifndef NO_FCNTL_H
 #  include <fcntl.h>
 #endif
@@ -157,8 +167,21 @@ typedef RETSIGTYPE (*sig_type) OF((int));
 #  define MAX_PATH_LEN   1024 /* max pathname length */
 #endif
 
 #  define MAX_PATH_LEN   1024 /* max pathname length */
 #endif
 
-#define MAX_HEADER_LEN   16
-/* max length of a compressed file header, fixed part only */
+#ifndef SEEK_END
+#  define SEEK_END 2
+#endif
+
+#ifdef NO_OFF_T
+  typedef long off_t;
+  off_t lseek OF((int fd, off_t offset, int whence));
+#endif
+
+/* Separator for file name parts (see shorten_name()) */
+#ifdef NO_MULTIPLE_DOTS
+#  define PART_SEP "-"
+#else
+#  define PART_SEP "."
+#endif
 
                /* global buffers */
 
 
                /* global buffers */
 
@@ -179,7 +202,9 @@ int ascii = 0;        /* convert end-of-lines to local OS conventions */
 int to_stdout = 0;    /* output to stdout (-c) */
 int decompress = 0;   /* decompress (-d) */
 int force = 0;        /* don't ask questions, compress links (-f) */
 int to_stdout = 0;    /* output to stdout (-c) */
 int decompress = 0;   /* decompress (-d) */
 int force = 0;        /* don't ask questions, compress links (-f) */
+int no_name = 0;      /* don't save or restore the original file name */
 int recursive = 0;    /* recurse through directories (-r) */
 int recursive = 0;    /* recurse through directories (-r) */
+int list = 0;         /* list the file contents (-l) */
 int verbose = 0;      /* be verbose (-v) */
 int quiet = 0;        /* be very quiet (-q) */
 int do_lzw = 0;       /* generate output compatible with old compress (-Z) */
 int verbose = 0;      /* be verbose (-v) */
 int quiet = 0;        /* be very quiet (-q) */
 int do_lzw = 0;       /* generate output compatible with old compress (-Z) */
@@ -188,12 +213,12 @@ int foreground;       /* set if program run in foreground */
 char *progname;       /* program name */
 int maxbits = BITS;   /* max bits per code for LZW */
 int method = DEFLATED;/* compression method */
 char *progname;       /* program name */
 int maxbits = BITS;   /* max bits per code for LZW */
 int method = DEFLATED;/* compression method */
-int level = 5;        /* compression level */
+int level = 6;        /* compression level */
 int exit_code = OK;   /* program exit code */
 int save_orig_name;   /* set if original name must be saved */
 int last_member;      /* set for .zip and .Z files */
 int part_nb;          /* number of parts in .gz file */
 int exit_code = OK;   /* program exit code */
 int save_orig_name;   /* set if original name must be saved */
 int last_member;      /* set for .zip and .Z files */
 int part_nb;          /* number of parts in .gz file */
-ulg time_stamp;       /* original time stamp (modification time) */
+long time_stamp;       /* original time stamp (modification time) */
 long ifile_size;      /* input file size, -1 for devices (debug only) */
 char *env;            /* contents of GZIP env variable */
 char **args = NULL;   /* argv pointer if GZIP env variable defined */
 long ifile_size;      /* input file size, -1 for devices (debug only) */
 char *env;            /* contents of GZIP env variable */
 char **args = NULL;   /* argv pointer if GZIP env variable defined */
@@ -202,6 +227,8 @@ int  z_len;           /* strlen(z_suffix) */
 
 long bytes_in;             /* number of input bytes */
 long bytes_out;            /* number of output bytes */
 
 long bytes_in;             /* number of input bytes */
 long bytes_out;            /* number of output bytes */
+long total_in = 0;         /* input bytes for all files */
+long total_out = 0;        /* output bytes for all files */
 char ifname[MAX_PATH_LEN]; /* input file name */
 char ofname[MAX_PATH_LEN]; /* output file name */
 int  remove_ofname = 0;           /* remove output file on error */
 char ifname[MAX_PATH_LEN]; /* input file name */
 char ofname[MAX_PATH_LEN]; /* output file name */
 int  remove_ofname = 0;           /* remove output file on error */
@@ -224,8 +251,9 @@ struct option longopts[] =
     {"force",      0, 0, 'f'}, /* force overwrite of output file */
     {"help",       0, 0, 'h'}, /* give help */
  /* {"pkzip",      0, 0, 'k'},    force output in pkzip format */
     {"force",      0, 0, 'f'}, /* force overwrite of output file */
     {"help",       0, 0, 'h'}, /* give help */
  /* {"pkzip",      0, 0, 'k'},    force output in pkzip format */
/* {"list",       0, 0, 'l'},    list .gz file contents */
   {"list",       0, 0, 'l'}, /* list .gz file contents */
     {"license",    0, 0, 'L'}, /* display software license */
     {"license",    0, 0, 'L'}, /* display software license */
+    {"no-name",    0, 0, 'n'}, /* don't save or restore the original name */
     {"quiet",      0, 0, 'q'}, /* quiet mode */
     {"silent",     0, 0, 'q'}, /* quiet mode */
     {"recurse",    0, 0, 'r'}, /* recurse through directories */
     {"quiet",      0, 0, 'q'}, /* quiet mode */
     {"silent",     0, 0, 'q'}, /* quiet mode */
     {"recurse",    0, 0, 'r'}, /* recurse through directories */
@@ -255,7 +283,9 @@ local int  get_istat    OF((char *iname, struct stat *sbuf));
 local int  make_ofname  OF((void));
 local int  same_file    OF((struct stat *stat1, struct stat *stat2));
 local int name_too_long OF((char *name, struct stat *statb));
 local int  make_ofname  OF((void));
 local int  same_file    OF((struct stat *stat1, struct stat *stat2));
 local int name_too_long OF((char *name, struct stat *statb));
+local void shorten_name  OF((char *name));
 local int  get_method   OF((int in));
 local int  get_method   OF((int in));
+local void do_list      OF((int ifd, int method));
 local int  check_ofname OF((void));
 local void reset_times  OF((char *name, struct stat *statb));
 local void copy_stat    OF((struct stat *ifstat));
 local int  check_ofname OF((void));
 local void reset_times  OF((char *name, struct stat *statb));
 local void copy_stat    OF((struct stat *ifstat));
@@ -270,7 +300,7 @@ int (*work) OF((int infile, int outfile)) = zip; /* function to call */
 /* ======================================================================== */
 local void usage()
 {
 /* ======================================================================== */
 local void usage()
 {
-    fprintf(stderr, "usage: %s [-%scdfhL%stvV19] [-S suffix] [file ...]\n",
+    fprintf(stderr, "usage: %s [-%scdfhlLn%stvV19] [-S suffix] [file ...]\n",
            progname,
 #if O_BINARY
            "a",
            progname,
 #if O_BINARY
            "a",
@@ -298,16 +328,17 @@ local void help()
  " -f --force       force overwrite of output file and compress links",
  " -h --help        give this help",
 /* -k --pkzip       force output in pkzip format */
  " -f --force       force overwrite of output file and compress links",
  " -h --help        give this help",
 /* -k --pkzip       force output in pkzip format */
-/* -l --list        list .gz file contents */
+ " -l --list        list .gz file contents",
  " -L --license     display software license",
  " -L --license     display software license",
+ " -n --no-name     do not save or restore the original name",
  " -q --quiet       suppress all warnings",
 #ifndef NO_DIR
  " -r --recurse     recurse through directories",
 #endif
 #ifdef MAX_EXT_CHARS
  " -q --quiet       suppress all warnings",
 #ifndef NO_DIR
  " -r --recurse     recurse through directories",
 #endif
 #ifdef MAX_EXT_CHARS
- " -S --suffix .gz  use suffix .gz instead of .z",
+ " -S .suf  --suffix .suf     use suffix .suf instead of .z",
 #else
 #else
- " -S --suffix .z   use suffix .z instead of .gz",
+ " -S .suf  --suffix .suf     use suffix .suf instead of .gz",
 #endif
  " -t --test        test compressed file integrity",
  " -v --verbose     verbose mode",
 #endif
  " -t --test        test compressed file integrity",
  " -v --verbose     verbose mode",
@@ -435,7 +466,7 @@ int main (argc, argv)
     strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix)-1);
     z_len = strlen(z_suffix);
 
     strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix)-1);
     z_len = strlen(z_suffix);
 
-    while ((optc = getopt_long (argc, argv, "ab:cdfhLqrS:tvVZ123456789",
+    while ((optc = getopt_long (argc, argv, "ab:cdfhlLnqrS:tvVZ123456789",
                                longopts, (int *)0)) != EOF) {
        switch (optc) {
         case 'a':
                                longopts, (int *)0)) != EOF) {
        switch (optc) {
         case 'a':
@@ -451,8 +482,12 @@ int main (argc, argv)
            force++; break;
        case 'h': case 'H': case '?':
            help(); do_exit(OK); break;
            force++; break;
        case 'h': case 'H': case '?':
            help(); do_exit(OK); break;
+       case 'l':
+           list = decompress = to_stdout = 1; break;
        case 'L':
            license(); do_exit(OK); break;
        case 'L':
            license(); do_exit(OK); break;
+       case 'n':
+           no_name = 1; break;
        case 'q':
            quiet = 1; verbose = 0; break;
        case 'r':
        case 'q':
            quiet = 1; verbose = 0; break;
        case 'r':
@@ -468,11 +503,6 @@ int main (argc, argv)
             if (*optarg == '.') optarg++;
 #endif
             z_len = strlen(optarg);
             if (*optarg == '.') optarg++;
 #endif
             z_len = strlen(optarg);
-            if (z_len == 0 || z_len > MAX_SUFFIX) {
-                fprintf(stderr, "%s: incorrect suffix '%s'\n",
-                        progname, optarg);
-                do_exit(ERROR);
-            }
             strcpy(z_suffix, optarg);
             break;
        case 't':
             strcpy(z_suffix, optarg);
             break;
        case 't':
@@ -511,6 +541,11 @@ int main (argc, argv)
                progname);
     }
 #endif
                progname);
     }
 #endif
+    if ((z_len == 0 && !decompress) || z_len > MAX_SUFFIX) {
+        fprintf(stderr, "%s: incorrect suffix '%s'\n",
+                progname, optarg);
+        do_exit(ERROR);
+    }
     if (do_lzw && !decompress) work = lzw;
 
     /* Allocate all global buffers (for DYN_ALLOC option) */
     if (do_lzw && !decompress) work = lzw;
 
     /* Allocate all global buffers (for DYN_ALLOC option) */
@@ -527,7 +562,7 @@ int main (argc, argv)
 
     /* And get to work */
     if (file_count != 0) {
 
     /* And get to work */
     if (file_count != 0) {
-       if (to_stdout && !test && (!decompress || !ascii)) {
+       if (to_stdout && !test && !list && (!decompress || !ascii)) {
            SET_BINARY_MODE(fileno(stdout));
        }
         while (optind < argc) {
            SET_BINARY_MODE(fileno(stdout));
        }
         while (optind < argc) {
@@ -536,6 +571,9 @@ int main (argc, argv)
     } else {  /* Standard input */
        treat_stdin();
     }
     } else {  /* Standard input */
        treat_stdin();
     }
+    if (list && !quiet) {
+       do_list(-1, -1); /* print totals */
+    }
     do_exit(exit_code);
     return exit_code; /* just to avoid lint warning */
 }
     do_exit(exit_code);
     return exit_code; /* just to avoid lint warning */
 }
@@ -569,7 +607,7 @@ local void treat_stdin()
     if (decompress || !ascii) {
        SET_BINARY_MODE(fileno(stdin));
     }
     if (decompress || !ascii) {
        SET_BINARY_MODE(fileno(stdin));
     }
-    if (!test && (!decompress || !ascii)) {
+    if (!test && !list && (!decompress || !ascii)) {
        SET_BINARY_MODE(fileno(stdout));
     }
     strcpy(ifname, "stdin");
        SET_BINARY_MODE(fileno(stdout));
     }
     strcpy(ifname, "stdin");
@@ -604,6 +642,10 @@ local void treat_stdin()
            do_exit(exit_code); /* error message already emitted */
        }
     }
            do_exit(exit_code); /* error message already emitted */
        }
     }
+    if (list) {
+        do_list(ifd, method);
+        return;
+    }
 
     /* Actually do the compression/decompression. Loop over zipped members.
      */
 
     /* Actually do the compression/decompression. Loop over zipped members.
      */
@@ -620,14 +662,17 @@ local void treat_stdin()
 
     if (verbose) {
        if (test) {
 
     if (verbose) {
        if (test) {
-           fprintf(stderr, " OK");
+           fprintf(stderr, " OK\n");
 
 
-       } else if (decompress) {
-           display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out);
+       } else if (!decompress) {
+           display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);
+           fprintf(stderr, "\n");
+#ifdef DISPLAY_STDIN_RATIO
        } else {
        } else {
-           display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in);
+           display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);
+           fprintf(stderr, "\n");
+#endif
        }
        }
-       fprintf(stderr, "\n");
     }
 }
 
     }
 }
 
@@ -671,7 +716,7 @@ local void treat_file(iname)
     time_stamp = istat.st_mtime;
 
     /* Generate output file name */
     time_stamp = istat.st_mtime;
 
     /* Generate output file name */
-    if (to_stdout) {
+    if (to_stdout && !list) {
        strcpy(ofname, "stdout");
 
     } else if (make_ofname() != OK) {
        strcpy(ofname, "stdout");
 
     } else if (make_ofname() != OK) {
@@ -700,6 +745,11 @@ local void treat_file(iname)
            return;               /* error message already emitted */
        }
     }
            return;               /* error message already emitted */
        }
     }
+    if (list) {
+        do_list(ifd, method);
+        close(ifd);
+        return;
+    }
 
     /* If compressing to a file, check if ofname is not ambiguous
      * because the operating system truncates names. Otherwise, generate
 
     /* If compressing to a file, check if ofname is not ambiguous
      * because the operating system truncates names. Otherwise, generate
@@ -716,6 +766,9 @@ local void treat_file(iname)
                    progname, ifname, ofname);
        }
     }
                    progname, ifname, ofname);
        }
     }
+    /* Keep the name even if not truncated except with --no-name: */
+    if (!save_orig_name) save_orig_name = !no_name;
+
     if (verbose) {
        fprintf(stderr, "%s:\t%s", ifname, (int)strlen(ifname) >= 15 ? 
                "" : ((int)strlen(ifname) >= 7 ? "\t" : "\t\t"));
     if (verbose) {
        fprintf(stderr, "%s:\t%s", ifname, (int)strlen(ifname) >= 15 ? 
                "" : ((int)strlen(ifname) >= 7 ? "\t" : "\t\t"));
@@ -749,9 +802,9 @@ local void treat_file(iname)
        if (test) {
            fprintf(stderr, " OK");
        } else if (decompress) {
        if (test) {
            fprintf(stderr, " OK");
        } else if (decompress) {
-           display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out);
+           display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);
        } else {
        } else {
-           display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in);
+           display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);
        }
        if (!test && !to_stdout) {
            fprintf(stderr, " -- replaced with %s", ofname);
        }
        if (!test && !to_stdout) {
            fprintf(stderr, " -- replaced with %s", ofname);
@@ -768,6 +821,7 @@ local void treat_file(iname)
  * Create the output file. Return OK or ERROR.
  * Try several times if necessary to avoid truncating the z_suffix. For
  * example, do not create a compressed file of name "1234567890123."
  * Create the output file. Return OK or ERROR.
  * Try several times if necessary to avoid truncating the z_suffix. For
  * example, do not create a compressed file of name "1234567890123."
+ * Sets save_orig_name to true if the file name has been truncated.
  * IN assertions: the input file has already been open (ifd is set) and
  *   ofname has already been updated if there was an original name.
  * OUT assertions: ifd and ofd are closed in case of error.
  * IN assertions: the input file has already been open (ifd is set) and
  *   ofname has already been updated if there was an original name.
  * OUT assertions: ifd and ofd are closed in case of error.
@@ -775,15 +829,13 @@ local void treat_file(iname)
 local int create_outfile()
 {
     struct stat        ostat; /* stat for ofname */
 local int create_outfile()
 {
     struct stat        ostat; /* stat for ofname */
-    int len;
     int flags = O_WRONLY | O_CREAT | O_EXCL | O_BINARY;
 
     if (ascii && decompress) {
        flags &= ~O_BINARY; /* force ascii text mode */
     }
     for (;;) {
     int flags = O_WRONLY | O_CREAT | O_EXCL | O_BINARY;
 
     if (ascii && decompress) {
        flags &= ~O_BINARY; /* force ascii text mode */
     }
     for (;;) {
-        len = strlen(ofname);
-        if (len == 0 || ofname[len] == PATH_SEP) break;
+       /* Make sure that ofname is not an existing file */
        if (check_ofname() != OK) {
            close(ifd);
            return ERROR;
        if (check_ofname() != OK) {
            close(ifd);
            return ERROR;
@@ -799,7 +851,11 @@ local int create_outfile()
        }
 
        /* Check for name truncation on new file (1234567890123.gz) */
        }
 
        /* Check for name truncation on new file (1234567890123.gz) */
+#ifdef NO_FSTAT
+       if (stat(ofname, &ostat) != 0) {
+#else
        if (fstat(ofd, &ostat) != 0) {
        if (fstat(ofd, &ostat) != 0) {
+#endif
            fprintf(stderr, "%s: ", progname);
            perror(ofname);
            close(ifd); close(ofd);
            fprintf(stderr, "%s: ", progname);
            perror(ofname);
            close(ifd); close(ofd);
@@ -814,25 +870,16 @@ local int create_outfile()
            WARN((stderr, "%s: %s: warning, name truncated\n",
                  progname, ofname));
            return OK;
            WARN((stderr, "%s: %s: warning, name truncated\n",
                  progname, ofname));
            return OK;
-       } else {
+       }
+       close(ofd);
+       unlink(ofname);
 #ifdef NO_MULTIPLE_DOTS
 #ifdef NO_MULTIPLE_DOTS
-           /* Should never happen, see check_ofname() */
-           fprintf(stderr, "%s: %s: name too long\n", progname, ofname);
-           do_exit(ERROR);
-#else
-           close(ofd);
-           unlink(ofname);
-           save_orig_name = 1;
-           strcpy(ofname+strlen(ofname)-z_len-1, z_suffix);
-            /* 123456789012.gz -> 12345678901.gz */
+       /* Should never happen, see check_ofname() */
+       fprintf(stderr, "%s: %s: name too long\n", progname, ofname);
+       do_exit(ERROR);
 #endif
 #endif
-       } /* decompress ? */
-    } /* while non null name */
-
-    close(ifd);
-    fprintf(stderr, "%s: %s: name too long\n", progname, ofname);
-    exit_code = ERROR;
-    return ERROR;
+       shorten_name(ofname);
+    }
 }
 
 /* ========================================================================
 }
 
 /* ========================================================================
@@ -861,6 +908,8 @@ local int do_stat(name, sbuf)
  * also accepted suffixes. For Unix, we do not want to accept any
  * .??z suffix as indicating a compressed file; some people use .xyz
  * to denote volume data.
  * also accepted suffixes. For Unix, we do not want to accept any
  * .??z suffix as indicating a compressed file; some people use .xyz
  * to denote volume data.
+ *   On systems allowing multiple versions of the same file (such as VMS),
+ * this function removes any version suffix in the given name.
  */
 local char *get_suffix(name)
     char *name;
  */
 local char *get_suffix(name)
     char *name;
@@ -877,19 +926,19 @@ local char *get_suffix(name)
 
     if (strequ(z_suffix, "z")) suf++; /* check long suffixes first */
 
 
     if (strequ(z_suffix, "z")) suf++; /* check long suffixes first */
 
+#ifdef SUFFIX_SEP
+    /* strip a version number from the file name */
+    {
+       char *v = strrchr(name, SUFFIX_SEP);
+       if (v != NULL) *v = '\0';
+    }
+#endif
     nlen = strlen(name);
     if (nlen <= MAX_SUFFIX+2) {
         strcpy(suffix, name);
     } else {
         strcpy(suffix, name+nlen-MAX_SUFFIX-2);
     }
     nlen = strlen(name);
     if (nlen <= MAX_SUFFIX+2) {
         strcpy(suffix, name);
     } else {
         strcpy(suffix, name+nlen-MAX_SUFFIX-2);
     }
-#ifdef SUFFIX_SEP
-    /* strip a version number from the file name */
-    {
-       char *v = strrchr(suffix, SUFFIX_SEP);
-       if (v != NULL) *v = '\0', nlen = v - name;
-    }
-#endif
     strlwr(suffix);
     slen = strlen(suffix);
     do {
     strlwr(suffix);
     slen = strlen(suffix);
     do {
@@ -933,7 +982,8 @@ local int get_istat(iname, sbuf)
        exit_code = ERROR;
        return ERROR;
     }
        exit_code = ERROR;
        return ERROR;
     }
-    /* file.ext doesn't exist, try adding a suffix.
+    /* file.ext doesn't exist, try adding a suffix (after removing any
+     * version number for VMS).
      */
     s = get_suffix(ifname);
     if (s != NULL) {
      */
     s = get_suffix(ifname);
     if (s != NULL) {
@@ -941,10 +991,6 @@ local int get_istat(iname, sbuf)
        exit_code = ERROR;
        return ERROR;
     }
        exit_code = ERROR;
        return ERROR;
     }
-#ifdef SUFFIX_SEP
-    /* strip a version number from the input file name */
-    if ((s = strrchr(ifname, SUFFIX_SEP)) != NULL) *s = '\0';
-#endif
 #ifdef NO_MULTIPLE_DOTS
     dot = strrchr(ifname, '.');
     if (dot == NULL) {
 #ifdef NO_MULTIPLE_DOTS
     dot = strrchr(ifname, '.');
     if (dot == NULL) {
@@ -987,20 +1033,24 @@ local int get_istat(iname, sbuf)
 
 /* ========================================================================
  * Generate ofname given ifname. Return OK, or WARNING if file must be skipped.
 
 /* ========================================================================
  * Generate ofname given ifname. Return OK, or WARNING if file must be skipped.
- * Initializes save_orig_name.
- * IN assertion: this function is not called if to_stdout is true.
+ * Sets save_orig_name to true if the file name has been truncated.
  */
 local int make_ofname()
 {
     char *suff;            /* ofname z suffix */
 
     strcpy(ofname, ifname);
  */
 local int make_ofname()
 {
     char *suff;            /* ofname z suffix */
 
     strcpy(ofname, ifname);
+    /* strip a version number if any and get the gzip suffix if present: */
     suff = get_suffix(ofname);
 
     if (decompress) {
        if (suff == NULL) {
     suff = get_suffix(ofname);
 
     if (decompress) {
        if (suff == NULL) {
-           WARN((stderr,"%s: %s: unknown suffix -- ignored\n",
-                 progname, ifname));
+            if (list) return OK;
+           /* Avoid annoying messages with -r */
+           if (verbose || (!recursive && !quiet)) {
+               WARN((stderr,"%s: %s: unknown suffix -- ignored\n",
+                     progname, ifname));
+           }
            return WARNING;
        }
        /* Make a special case for .tgz and .taz: */
            return WARNING;
        }
        /* Make a special case for .tgz and .taz: */
@@ -1008,7 +1058,7 @@ local int make_ofname()
        if (strequ(suff, ".tgz") || strequ(suff, ".taz")) {
            strcpy(suff, ".tar");
        } else {
        if (strequ(suff, ".tgz") || strequ(suff, ".taz")) {
            strcpy(suff, ".tar");
        } else {
-           *suff = '\0'; /* strip z suffix and optional version number */
+           *suff = '\0'; /* strip the z suffix */
        }
         /* ofname might be changed later if infile contains an original name */
 
        }
         /* ofname might be changed later if infile contains an original name */
 
@@ -1023,16 +1073,15 @@ local int make_ofname()
     } else {
         save_orig_name = 0;
 
     } else {
         save_orig_name = 0;
 
-#ifdef SUFFIX_SEP
-       /* strip a version number from the file name */
-       if ((suff = strrchr(ofname, SUFFIX_SEP)) != NULL) *suff = '\0';
-#endif
-
 #ifdef NO_MULTIPLE_DOTS
        suff = strrchr(ofname, '.');
        if (suff == NULL) {
             strcat(ofname, ".");
 #  ifdef MAX_EXT_CHARS
 #ifdef NO_MULTIPLE_DOTS
        suff = strrchr(ofname, '.');
        if (suff == NULL) {
             strcat(ofname, ".");
 #  ifdef MAX_EXT_CHARS
+           if (strequ(z_suffix, "z")) {
+               strcat(ofname, "gz"); /* enough room */
+               return OK;
+           }
         /* On the Atari and some versions of MSDOS, name_too_long()
          * does not work correctly because of a bug in stat(). So we
          * must truncate here.
         /* On the Atari and some versions of MSDOS, name_too_long()
          * does not work correctly because of a bug in stat(). So we
          * must truncate here.
@@ -1066,9 +1115,17 @@ local int get_method(in)
     uch flags;
     char magic[2]; /* magic header */
 
     uch flags;
     char magic[2]; /* magic header */
 
-    magic[0] = (char)get_byte();
-    magic[1] = (char)get_byte();
-
+    /* If --force and --stdout, zcat == cat, so do not complain about
+     * premature end of file: use try_byte instead of get_byte.
+     */
+    if (force && to_stdout) {
+       magic[0] = (char)try_byte();
+       magic[1] = (char)try_byte();
+       /* If try_byte returned EOF, magic[1] == 0xff */
+    } else {
+       magic[0] = (char)get_byte();
+       magic[1] = (char)get_byte();
+    }
     time_stamp = istat.st_mtime; /* may be modified later for some methods */
     method = -1;                 /* unknown yet */
     part_nb++;                   /* number of parts in gzip file */
     time_stamp = istat.st_mtime; /* may be modified later for some methods */
     method = -1;                 /* unknown yet */
     part_nb++;                   /* number of parts in gzip file */
@@ -1079,8 +1136,15 @@ local int get_method(in)
     if (memcmp(magic, GZIP_MAGIC, 2) == 0
         || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
 
     if (memcmp(magic, GZIP_MAGIC, 2) == 0
         || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
 
-       work = unzip;
        method = (int)get_byte();
        method = (int)get_byte();
+       if (method != DEFLATED) {
+           fprintf(stderr,
+                   "%s: %s: unknown method %d -- get newer version of gzip\n",
+                   progname, ifname, method);
+           exit_code = ERROR;
+           return -1;
+       }
+       work = unzip;
        flags  = (uch)get_byte();
 
        if ((flags & ENCRYPTED) != 0) {
        flags  = (uch)get_byte();
 
        if ((flags & ENCRYPTED) != 0) {
@@ -1132,13 +1196,14 @@ local int get_method(in)
 
        /* Get original file name if it was truncated */
        if ((flags & ORIG_NAME) != 0) {
 
        /* Get original file name if it was truncated */
        if ((flags & ORIG_NAME) != 0) {
-           if (to_stdout || part_nb > 1) {
+           if (no_name || (to_stdout && !list) || part_nb > 1) {
                /* Discard the old name */
                char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */
                while ((c=get_byte()) != 0) c++;
            } else {
                /* Copy the base name. Keep a directory prefix intact. */
                /* Discard the old name */
                char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */
                while ((c=get_byte()) != 0) c++;
            } else {
                /* Copy the base name. Keep a directory prefix intact. */
-               char *p = basename(ofname);
+                char *p = basename(ofname);
+                char *base = p;
                for (;;) {
                    *p = (char)get_char();
                    if (*p++ == '\0') break;
                for (;;) {
                    *p = (char)get_char();
                    if (*p++ == '\0') break;
@@ -1146,8 +1211,13 @@ local int get_method(in)
                        error("corrupted input -- file name too large");
                    }
                }
                        error("corrupted input -- file name too large");
                    }
                }
-           } /* to_stdout */
-       } /* orig_name */
+                /* If necessary, adapt the name to local OS conventions: */
+                if (!list) {
+                   MAKE_LEGAL_NAME(base);
+                  base++; /* avoid warning about unused variable */
+                }
+           } /* no_name || to_stdout */
+       } /* ORIG_NAME */
 
        /* Discard file comment if any */
        if ((flags & COMMENT) != 0) {
 
        /* Discard file comment if any */
        if ((flags & COMMENT) != 0) {
@@ -1171,23 +1241,125 @@ local int get_method(in)
     } else if (memcmp(magic, PACK_MAGIC, 2) == 0) {
        work = unpack;
        method = PACKED;
     } else if (memcmp(magic, PACK_MAGIC, 2) == 0) {
        work = unpack;
        method = PACKED;
+
     } else if (memcmp(magic, LZW_MAGIC, 2) == 0) {
        work = unlzw;
        method = COMPRESSED;
        last_member = 1;
     } else if (memcmp(magic, LZW_MAGIC, 2) == 0) {
        work = unlzw;
        method = COMPRESSED;
        last_member = 1;
+
+    } else if (memcmp(magic, LZH_MAGIC, 2) == 0) {
+       work = unlzh;
+       method = LZHED;
+       last_member = 1;
+
+    } else if (force && to_stdout) { /* pass input unchanged */
+       method = STORED;
+       work = copy;
+        inptr = 0;
+       last_member = 1;
     }
     if (method >= 0) return method;
     }
     if (method >= 0) return method;
+
     if (part_nb == 1) {
        fprintf(stderr, "\n%s: %s: not in gzip format\n", progname, ifname);
        exit_code = ERROR;
        return -1;
     } else {
     if (part_nb == 1) {
        fprintf(stderr, "\n%s: %s: not in gzip format\n", progname, ifname);
        exit_code = ERROR;
        return -1;
     } else {
-       WARN((stderr, "\n%s: %s: trailing garbage ignored\n",
+       WARN((stderr, "\n%s: %s: decompression OK, trailing garbage ignored\n",
              progname, ifname));
        return -2;
     }
 }
 
              progname, ifname));
        return -2;
     }
 }
 
+/* ========================================================================
+ * Display the characteristics of the compressed file.
+ * If the given method is < 0, display the accumulated totals.
+ * IN assertions: time_stamp, header_bytes and ifile_size are initialized.
+ */
+local void do_list(ifd, method)
+    int ifd;     /* input file descriptor */
+    int method;  /* compression method */
+{
+    ulg crc;  /* original crc */
+    static int first_time = 1;
+    static char* methods[MAX_METHODS] = {
+        "store",  /* 0 */
+        "compr",  /* 1 */
+        "pack ",  /* 2 */
+        "lzh  ",  /* 3 */
+        "", "", "", "", /* 4 to 7 reserved */
+        "defla"}; /* 8 */
+    char *date;
+
+    if (first_time && method >= 0) {
+       first_time = 0;
+       if (verbose)  {
+           printf("method  crc     date  time  ");
+       }
+       if (!quiet) {
+           printf("compressed  uncompr. ratio uncompressed_name\n");
+       }
+    } else if (method < 0) {
+       if (total_in <= 0 || total_out <= 0) return;
+       if (verbose) {
+           printf("                            %9lu %9lu ",
+                  total_in, total_out);
+       } else if (!quiet) {
+           printf("%9ld %9ld ", total_in, total_out);
+       }
+       display_ratio(total_out-(total_in-header_bytes), total_out, stdout);
+       /* header_bytes is not meaningful but used to ensure the same
+        * ratio if there is a single file.
+        */
+       printf(" (totals)\n");
+       return;
+    }
+    crc = ~0; /* unknown */
+    bytes_out = -1L;
+    bytes_in = ifile_size;
+
+#if RECORD_IO == 0
+    if (method == DEFLATED && !last_member) {
+        /* Get the crc and uncompressed size for gzip'ed (not zip'ed) files.
+         * If the lseek fails, we could use read() to get to the end, but
+         * --list is used to get quick results.
+         * Use "gunzip < foo.gz | wc -c" to get the uncompressed size if
+         * you are not concerned about speed.
+         */
+        bytes_in = (long)lseek(ifd, (off_t)(-8), SEEK_END);
+        if (bytes_in != -1L) {
+            uch buf[8];
+            bytes_in += 8L;
+            if (read(ifd, buf, sizeof(buf)) != sizeof(buf)) {
+                read_error();
+            }
+            crc       = LG(buf);
+           bytes_out = LG(buf+4);
+       }
+    }
+#endif /* RECORD_IO */
+    date = ctime(&time_stamp) + 4; /* skip the day of the week */
+    date[12] = '\0';               /* suppress the 1/100sec and the year */
+    if (verbose) {
+        printf("%5s %08lx %11s ", methods[method], crc, date);
+    }
+    printf("%9ld %9ld ", bytes_in, bytes_out);
+    if (bytes_in  == -1L) {
+       total_in = -1L;
+       bytes_in = bytes_out = header_bytes = 0;
+    } else if (total_in >= 0) {
+       total_in  += bytes_in;
+    }
+    if (bytes_out == -1L) {
+       total_out = -1L;
+       bytes_in = bytes_out = header_bytes = 0;
+    } else if (total_out >= 0) {
+       total_out += bytes_out;
+    }
+    display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out, stdout);
+    printf(" %s\n", ofname);
+}
+
 /* ========================================================================
  * Return true if the two stat structures correspond to the same file.
  */
 /* ========================================================================
  * Return true if the two stat structures correspond to the same file.
  */
@@ -1231,6 +1403,62 @@ local int name_too_long(name, statb)
     return res;
 }
 
     return res;
 }
 
+/* ========================================================================
+ * Shorten the given name by one character, or replace a .tar extension
+ * with .tgz. Truncate the last part of the name which is longer than
+ * MIN_PART characters: 1234.678.012.gz -> 123.678.012.gz. If the name
+ * has only parts shorter than MIN_PART truncate the longest part.
+ *
+ * IN assertion: This function is only called for the compressed file;
+ * the suffix of the given name is z_suffix.
+ */
+local void shorten_name(name)
+    char *name;
+{
+    int len;                 /* length of name without z_suffix */
+    char *trunc = NULL;      /* character to be truncated */
+    int plen;                /* current part length */
+    int min_part = MIN_PART; /* current minimum part length */
+    char *p;
+
+    p = get_suffix(name);
+    if (p == NULL) error("can't recover suffix\n");
+    *p = '\0';
+    len = strlen(name);
+    save_orig_name = 1;
+
+    /* compress 1234567890.tar to 1234567890.tgz */
+    if (len > 4 && strequ(p-4, ".tar")) {
+       strcpy(p-4, ".tgz");
+       return;
+    }
+    /* Try keeping short extensions intact:
+     * 1234.678.012.gz -> 123.678.012.gz
+     */
+    do {
+       p = strrchr(name, PATH_SEP);
+       p = p ? p+1 : name;
+       while (*p) {
+           plen = strcspn(p, PART_SEP);
+           p += plen;
+           if (plen > min_part) trunc = p-1;
+           if (*p) p++;
+       }
+    } while (trunc == NULL && --min_part != 0);
+
+    if (trunc != NULL) {
+       do {
+           trunc[0] = trunc[1];
+       } while (*trunc++);
+       trunc--;
+    } else {
+       trunc = strrchr(name, PART_SEP[0]);
+       if (trunc == NULL) error("internal error in shorten_name");
+       if (trunc[1] == '\0') trunc--; /* force truncation */
+    }
+    strcpy(trunc, z_suffix);
+}
+
 /* ========================================================================
  * If compressing to a file, check if ofname is not ambiguous
  * because the operating system truncates names. Otherwise, generate
 /* ========================================================================
  * If compressing to a file, check if ofname is not ambiguous
  * because the operating system truncates names. Otherwise, generate
@@ -1247,22 +1475,15 @@ local int name_too_long(name, statb)
  */
 local int check_ofname()
 {
  */
 local int check_ofname()
 {
-    int s = strlen(ofname);
     struct stat        ostat; /* stat for ofname */
 
     if (stat(ofname, &ostat) != 0) return 0;
 
     /* Check for name truncation on existing file: */
     struct stat        ostat; /* stat for ofname */
 
     if (stat(ofname, &ostat) != 0) return 0;
 
     /* Check for name truncation on existing file: */
-#ifdef NO_MULTIPLE_DOTS
     if (!decompress && name_too_long(ofname, &ostat)) {
     if (!decompress && name_too_long(ofname, &ostat)) {
-#else
-    if (!decompress && s > 8 && name_too_long(ofname, &ostat)) {
-#endif
-       save_orig_name = 1;
-       strcpy(ofname+s-z_len-1, z_suffix);  /* f.ext.gz -> f.ex.gz  */
-
+       shorten_name(ofname);
        if (stat(ofname, &ostat) != 0) return 0;
        if (stat(ofname, &ostat) != 0) return 0;
-    } /* !decompress && name_too_long */
+    }
 
     /* Check that the input and output files are different (could be
      * the same by name truncation or links).
 
     /* Check that the input and output files are different (could be
      * the same by name truncation or links).
index a4d6376..88b0710 100644 (file)
    typedef char *voidp;
 #endif
 
    typedef char *voidp;
 #endif
 
-/* I don't like nested includes, but the string functions are used too often */
+/* I don't like nested includes, but the string and io functions are used
+ * too often
+ */
+#include <stdio.h>
 #if !defined(NO_STRING_H) || defined(STDC_HEADERS)
 #  include <string.h>
 #  if !defined(STDC_HEADERS) && !defined(NO_MEMORY_H) && !defined(__GNUC__)
 #if !defined(NO_STRING_H) || defined(STDC_HEADERS)
 #  include <string.h>
 #  if !defined(STDC_HEADERS) && !defined(NO_MEMORY_H) && !defined(__GNUC__)
@@ -48,11 +51,13 @@ typedef unsigned long  ulg;
 #define WARNING 2
 
 /* Compression methods (see algorithm.doc) */
 #define WARNING 2
 
 /* Compression methods (see algorithm.doc) */
-#define STORED     0
-#define COMPRESSED 1
-#define PACKED     2
-/* methods 3 to 7 reserved */
-#define DEFLATED   8
+#define STORED      0
+#define COMPRESSED  1
+#define PACKED      2
+#define LZHED       3
+/* methods 4 to 7 reserved */
+#define DEFLATED    8
+#define MAX_METHODS 9
 extern int method;         /* compression method */
 
 /* To save memory for 16 bit systems, some arrays are overlaid between
 extern int method;         /* compression method */
 
 /* To save memory for 16 bit systems, some arrays are overlaid between
@@ -60,7 +65,8 @@ extern int method;         /* compression method */
  * deflate:  prev+head   window      d_buf  l_buf  outbuf
  * unlzw:    tab_prefix  tab_suffix  stack  inbuf  outbuf
  * inflate:              window             inbuf
  * deflate:  prev+head   window      d_buf  l_buf  outbuf
  * unlzw:    tab_prefix  tab_suffix  stack  inbuf  outbuf
  * inflate:              window             inbuf
- * unpack:               window             inbuf
+ * unpack:               window             inbuf  prefix_len
+ * unlzh:    left+right  window      c_table inbuf c_len
  * For compression, input is done in window[]. For decompression, output
  * is done in window except for unlzw.
  */
  * For compression, input is done in window[]. For decompression, output
  * is done in window except for unlzw.
  */
@@ -139,17 +145,18 @@ extern char ifname[];   /* input file name or "stdin" */
 extern char ofname[];   /* output file name or "stdout" */
 extern char *progname;  /* program name */
 
 extern char ofname[];   /* output file name or "stdout" */
 extern char *progname;  /* program name */
 
-extern ulg time_stamp;  /* original time stamp (modification time) */
+extern long time_stamp; /* original time stamp (modification time) */
 extern long ifile_size; /* input file size, -1 for devices (debug only) */
 
 typedef int file_t;     /* Do not use stdio */
 #define NO_FILE  (-1)   /* in memory compression */
 
 
 extern long ifile_size; /* input file size, -1 for devices (debug only) */
 
 typedef int file_t;     /* Do not use stdio */
 #define NO_FILE  (-1)   /* in memory compression */
 
 
+#define        PACK_MAGIC     "\037\036" /* Magic header for packed files */
 #define        GZIP_MAGIC     "\037\213" /* Magic header for gzip files, 1F 8B */
 #define        OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
 #define        GZIP_MAGIC     "\037\213" /* Magic header for gzip files, 1F 8B */
 #define        OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
+#define        LZH_MAGIC      "\037\240" /* Magic header for SCO LZH Compress files*/
 #define PKZIP_MAGIC    "\120\113\003\004" /* Magic header for pkzip files */
 #define PKZIP_MAGIC    "\120\113\003\004" /* Magic header for pkzip files */
-#define        PACK_MAGIC     "\037\036" /* Magic header for packed files */
 
 /* gzip flag byte */
 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
 
 /* gzip flag byte */
 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
@@ -192,7 +199,8 @@ extern int test;           /* check .z file integrity */
 extern int to_stdout;      /* output to stdout (-c) */
 extern int save_orig_name; /* set if original name must be saved */
 
 extern int to_stdout;      /* output to stdout (-c) */
 extern int save_orig_name; /* set if original name must be saved */
 
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf(0))
+#define try_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf(1))
 
 /* put_byte is used for the compressed output, put_ubyte for the
  * uncompressed output. However unlzw() uses window for its
 
 /* put_byte is used for the compressed output, put_ubyte for the
  * uncompressed output. However unlzw() uses window for its
@@ -261,6 +269,9 @@ extern int check_zipfile OF((int in));
        /* in unpack.c */
 extern int unpack     OF((int in, int out));
 
        /* in unpack.c */
 extern int unpack     OF((int in, int out));
 
+       /* in unlzh.c */
+extern int unlzh      OF((int in, int out));
+
        /* in gzip.c */
 RETSIGTYPE abort_gzip OF((void));
 
        /* in gzip.c */
 RETSIGTYPE abort_gzip OF((void));
 
@@ -282,20 +293,22 @@ void     copy_block OF((char *buf, unsigned len, int header));
 extern   int (*read_buf) OF((char *buf, unsigned size));
 
        /* in util.c: */
 extern   int (*read_buf) OF((char *buf, unsigned size));
 
        /* in util.c: */
+extern int copy           OF((int in, int out));
 extern ulg  updcrc        OF((uch *s, unsigned n));
 extern void clear_bufs    OF((void));
 extern ulg  updcrc        OF((uch *s, unsigned n));
 extern void clear_bufs    OF((void));
-extern int  fill_inbuf    OF((void));
+extern int  fill_inbuf    OF((int eof_ok));
 extern void flush_outbuf  OF((void));
 extern void flush_window  OF((void));
 extern void write_buf     OF((int fd, voidp buf, unsigned cnt));
 extern char *strlwr       OF((char *s));
 extern char *basename     OF((char *fname));
 extern void flush_outbuf  OF((void));
 extern void flush_window  OF((void));
 extern void write_buf     OF((int fd, voidp buf, unsigned cnt));
 extern char *strlwr       OF((char *s));
 extern char *basename     OF((char *fname));
+extern void make_simple_name OF((char *name));
 extern char *add_envopt   OF((int *argcp, char ***argvp, char *env));
 extern void error         OF((char *m));
 extern void warn          OF((char *a, char *b));
 extern void read_error    OF((void));
 extern void write_error   OF((void));
 extern char *add_envopt   OF((int *argcp, char ***argvp, char *env));
 extern void error         OF((char *m));
 extern void warn          OF((char *a, char *b));
 extern void read_error    OF((void));
 extern void write_error   OF((void));
-extern void display_ratio OF((long num, long den));
+extern void display_ratio OF((long num, long den, FILE *file));
 extern voidp xmalloc      OF((unsigned int size));
 
        /* in inflate.c */
 extern voidp xmalloc      OF((unsigned int size));
 
        /* in inflate.c */
index aa31f9e..dccd597 100644 (file)
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: inflate.c,v 0.13 1993/04/26 14:18:22 jloup Exp $";
+static char rcsid[] = "$Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp $";
 #endif
 
 #endif
 
-#include <stdio.h>
 #include <sys/types.h>
 
 #include "tailor.h"
 #include <sys/types.h>
 
 #include "tailor.h"
index cd09047..a360ca9 100644 (file)
@@ -3,15 +3,13 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: lzw.c,v 0.8 1993/04/25 08:09:58 jloup Exp $";
+static char rcsid[] = "$Id: lzw.c,v 0.9 1993/06/10 13:27:31 jloup Exp $";
 #endif
 
 #include "tailor.h"
 #include "gzip.h"
 #include "lzw.h"
 
 #endif
 
 #include "tailor.h"
 #include "gzip.h"
 #include "lzw.h"
 
-#include <stdio.h>
-
 static int msg_done = 0;
 
 /* Compress in to out with lzw method. */
 static int msg_done = 0;
 
 /* Compress in to out with lzw method. */
index cd3176b..4a3d681 100644 (file)
@@ -9,7 +9,7 @@
  * Kristoffer Eriksson <ske@pkmab.se>
  */
  
  * Kristoffer Eriksson <ske@pkmab.se>
  */
  
-/* $Id: match.S,v 0.13 1993/05/24 12:03:03 jloup Exp $ */
+/* $Id: match.S,v 0.14 1993/06/11 18:33:24 jloup Exp $ */
 
 /* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
  * external symbols with an underline character '_'.
 
 /* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
  * external symbols with an underline character '_'.
 
        .file   "match.S"
 
 
        .file   "match.S"
 
-#define MAX_MATCH      258
-#define MAX_MATCH2      128     /* MAX_MATCH/2-1 */
+#define MAX_MATCH      258
+#define MAX_MATCH2     $128 /* MAX_MATCH/2-1 */
 #define MIN_MATCH      3
 #define MIN_MATCH      3
-#define WSIZE          32768
-#define MAX_DIST       WSIZE - MAX_MATCH - MIN_MATCH - 1
+#define    WSIZE       $32768
+#define MAX_DIST       WSIZE - MAX_MATCH - MIN_MATCH - 1
 
        .globl  _match_init
        .globl  _longest_match
 
        .globl  _match_init
        .globl  _longest_match
@@ -87,11 +87,11 @@ _longest_match:     /* int longest_match(cur_match) */
         mov    _max_chain_length,%ebp /* chain_length = max_chain_length */
        mov     _strstart,%edi
        mov     %edi,%edx
         mov    _max_chain_length,%ebp /* chain_length = max_chain_length */
        mov     _strstart,%edi
        mov     %edi,%edx
-       sub     $ MAX_DIST,%edx        /* limit = strstart-MAX_DIST */
+       sub     MAX_DIST,%edx          /* limit = strstart-MAX_DIST */
        jae     limit_ok
        sub     %edx,%edx              /* limit = NIL */
 limit_ok:
        jae     limit_ok
        sub     %edx,%edx              /* limit = NIL */
 limit_ok:
-        add    $ _window+2,%edi       /* edi = offset(window+strstart+2) */
+        add    $2+_window,%edi        /* edi = offset(window+strstart+2) */
         mov    _prev_length,%ebx      /* best_len = prev_length */
         movw   -3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
         movw   -2(%edi),%cx           /* cx = scan[0..1] */
         mov    _prev_length,%ebx      /* best_len = prev_length */
         movw   -3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
         movw   -2(%edi),%cx           /* cx = scan[0..1] */
@@ -110,7 +110,7 @@ short_loop:
  * at this point, di == scan+2, si == cur_match,
  * ax = scan[best_len-1..best_len] and cx = scan[0..1]
  */
  * at this point, di == scan+2, si == cur_match,
  * ax = scan[best_len-1..best_len] and cx = scan[0..1]
  */
-        and     WSIZE-1, %esi
+        and     WSIZE-1, %esi
         movw    _prev(%esi,%esi),%si    /* cur_match = prev[cur_match] */
                                         /* top word of esi is still 0 */
         cmp     %edx,%esi              /* cur_match <= limit ? */
         movw    _prev(%esi,%esi),%si    /* cur_match = prev[cur_match] */
                                         /* top word of esi is still 0 */
         cmp     %edx,%esi              /* cur_match <= limit ? */
@@ -125,7 +125,7 @@ do_scan:
 
         lea     _window+2(%esi),%esi    /* si = match */
         mov     %edi,%eax               /* ax = scan+2 */
 
         lea     _window+2(%esi),%esi    /* si = match */
         mov     %edi,%eax               /* ax = scan+2 */
-        mov    $ MAX_MATCH2,%ecx       /* scan for at most MAX_MATCH bytes */
+        mov    MAX_MATCH2,%ecx         /* scan for at most MAX_MATCH bytes */
         rep;    cmpsw                   /* loop until mismatch */
         je      maxmatch                /* match of length MAX_MATCH? */
 mismatch:
         rep;    cmpsw                   /* loop until mismatch */
         je      maxmatch                /* match of length MAX_MATCH? */
 mismatch:
@@ -134,7 +134,7 @@ mismatch:
         xchg    %edi,%eax           /* edi = scan+2, eax = end of scan */
         sub     %edi,%eax           /* eax = len */
        sub     %eax,%esi           /* esi = cur_match + 2 + offset(window) */
         xchg    %edi,%eax           /* edi = scan+2, eax = end of scan */
         sub     %edi,%eax           /* eax = len */
        sub     %eax,%esi           /* esi = cur_match + 2 + offset(window) */
-       sub     $ _window+2,%esi    /* esi = cur_match */
+       sub     $2+_window,%esi     /* esi = cur_match */
         subb    $1,%cl              /* set carry if cl == 0 (cannot use DEC) */
         adc     $0,%eax             /* eax = carry ? len+1 : len */
         cmp     %ebx,%eax           /* len > best_len ? */
         subb    $1,%cl              /* set carry if cl == 0 (cannot use DEC) */
         adc     $0,%eax             /* eax = carry ? len+1 : len */
         cmp     %ebx,%eax           /* len > best_len ? */
index 5a4e1e6..4cb03a3 100644 (file)
@@ -4,13 +4,13 @@
  * terms of the GNU General Public License, see the file COPYING.
  */
 
  * terms of the GNU General Public License, see the file COPYING.
  */
 
-#define VERSION "1.1.1"
+#define VERSION "1.2.2"
 #define PATCHLEVEL 0
 #define PATCHLEVEL 0
-#define REVDATE "1 Jun 93"
+#define REVDATE "17 Jun 93"
 
 /* This version does not support compression into old compress format: */
 #ifdef LZW
 #  undef LZW
 #endif
 
 
 /* This version does not support compression into old compress format: */
 #ifdef LZW
 #  undef LZW
 #endif
 
-/* $Id: revision.h,v 0.20 1993/06/01 14:03:17 jloup Exp $ */
+/* $Id: revision.h,v 0.23 1993/06/16 15:03:51 jloup Exp $ */
index 915760a..960ff28 100644 (file)
@@ -8,12 +8,16 @@
  * The target dependent functions should be defined in tailor.c.
  */
 
  * The target dependent functions should be defined in tailor.c.
  */
 
-/* $Id: tailor.h,v 0.16 1993/06/01 12:46:03 jloup Exp $ */
+/* $Id: tailor.h,v 0.18 1993/06/14 19:32:20 jloup Exp $ */
 
 #if defined(__MSDOS__) && !defined(MSDOS)
 #  define MSDOS
 #endif
 
 
 #if defined(__MSDOS__) && !defined(MSDOS)
 #  define MSDOS
 #endif
 
+#if defined(__OS2__) && !defined(OS2)
+#  define OS2
+#endif
+
 #if defined(OS2) && defined(MSDOS) /* MS C under OS/2 */
 #  undef MSDOS
 #endif
 #if defined(OS2) && defined(MSDOS) /* MS C under OS/2 */
 #  undef MSDOS
 #endif
@@ -31,6 +35,7 @@
 #    define MAXSEG_64K
 #    ifdef __TURBOC__
 #      define NO_UTIME
 #    define MAXSEG_64K
 #    ifdef __TURBOC__
 #      define NO_UTIME
+#      define NO_OFF_T
 #    else /* MSC */
 #      define HAVE_SYS_UTIME_H
 #      define NO_UTIME_H
 #    else /* MSC */
 #      define HAVE_SYS_UTIME_H
 #      define NO_UTIME_H
 #  define NO_CHOWN
 #  define PROTO
 #  define STDC_HEADERS
 #  define NO_CHOWN
 #  define PROTO
 #  define STDC_HEADERS
-#  define HAVE_SYS_UTIME_H
-#  define NO_UTIME_H
 #  define casemap(c) tolow(c)
 #  include <io.h>
 #  define OS_CODE  0x06
 #  define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
 #  ifdef _MSC_VER
 #  define casemap(c) tolow(c)
 #  include <io.h>
 #  define OS_CODE  0x06
 #  define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
 #  ifdef _MSC_VER
+#    define HAVE_SYS_UTIME_H
+#    define NO_UTIME_H
 #    define MAXSEG_64K
 #    undef near
 #    define near _near
 #  endif
 #  ifdef __EMX__
 #    define MAXSEG_64K
 #    undef near
 #    define near _near
 #  endif
 #  ifdef __EMX__
+#    define HAVE_SYS_UTIME_H
+#    define NO_UTIME_H
 #    define DIRENT
 #    define EXPAND(argc,argv) \
        {_response(&argc, &argv); _wildcard(&argc, &argv);}
 #  endif
 #    define DIRENT
 #    define EXPAND(argc,argv) \
        {_response(&argc, &argv); _wildcard(&argc, &argv);}
 #  endif
+#  ifdef __BORLANDC__
+#    define DIRENT
+#  endif
+#  ifdef __ZTC__
+#    define NO_DIR
+#    define NO_UTIME_H
+#    include <dos.h>
+#    define EXPAND(argc,argv) \
+       {response_expand(&argc, &argv);}
+#  endif
 #endif
 
 #ifdef MSDOS
 #endif
 
 #ifdef MSDOS
 #  ifdef __GNUC__
 #    define DIRENT
 #    define HAVE_UNISTD_H
 #  ifdef __GNUC__
 #    define DIRENT
 #    define HAVE_UNISTD_H
-#    define RETSIGTYPE int
 #  else /* SASC */
 #    define NO_STDIN_FSTAT
 #    define SYSDIR
 #  else /* SASC */
 #    define NO_STDIN_FSTAT
 #    define SYSDIR
 #    define direct dirent
      extern void _expand_args(int *argc, char ***argv);
 #    define EXPAND(argc,argv) _expand_args(&argc,&argv);
 #    define direct dirent
      extern void _expand_args(int *argc, char ***argv);
 #    define EXPAND(argc,argv) _expand_args(&argc,&argv);
+#    undef  O_BINARY /* disable useless --ascii option */
 #  endif
 #endif
 
 #  endif
 #endif
 
 #  define put_char(c) put_byte((c) & 0x7F)
 #  define get_char(c) ascii2pascii(get_byte())
 #  define OS_CODE  0x0F    /* temporary, subject to change */
 #  define put_char(c) put_byte((c) & 0x7F)
 #  define get_char(c) ascii2pascii(get_byte())
 #  define OS_CODE  0x0F    /* temporary, subject to change */
-#  undef SIGTERM           /* We don't want a signal handler for SIGTERM */
+#  ifdef SIGTERM
+#    undef SIGTERM         /* We don't want a signal handler for SIGTERM */
+#  endif
 #endif
 
 #ifdef WIN32
 #endif
 
 #ifdef WIN32
 #  define MAX_SUFFIX  30
 #endif
 
 #  define MAX_SUFFIX  30
 #endif
 
+#ifndef MAKE_LEGAL_NAME
+#  ifdef NO_MULTIPLE_DOTS
+#    define MAKE_LEGAL_NAME(name)   make_simple_name(name)
+#  else
+#    define MAKE_LEGAL_NAME(name)
+#  endif
+#endif
+
+#ifndef MIN_PART
+#  define MIN_PART 3
+   /* keep at least MIN_PART chars between dots in a file name. */
+#endif
+
 #ifndef EXPAND
 #  define EXPAND(argc,argv)
 #endif
 #ifndef EXPAND
 #  define EXPAND(argc,argv)
 #endif
index 2cf380a..673dfde 100644 (file)
  */
 
 #include <ctype.h>
  */
 
 #include <ctype.h>
-#include <stdio.h>
 
 #include "tailor.h"
 #include "gzip.h"
 
 #ifndef lint
 
 #include "tailor.h"
 #include "gzip.h"
 
 #ifndef lint
-static char rcsid[] = "$Id: trees.c,v 0.11 1993/03/26 14:55:43 jloup Exp $";
+static char rcsid[] = "$Id: trees.c,v 0.12 1993/06/10 13:27:54 jloup Exp $";
 #endif
 
 /* ===========================================================================
 #endif
 
 /* ===========================================================================
diff --git a/gnu/usr.bin/gzip/unlzh.c b/gnu/usr.bin/gzip/unlzh.c
new file mode 100644 (file)
index 0000000..2c03d1f
--- /dev/null
@@ -0,0 +1,385 @@
+/* unlzh.c -- decompress files in SCO compress -H (LZH) format.
+ * The code in this file is directly derived from the public domain 'ar002'
+ * written by Haruhiko Okumura.
+ */
+
+#include <stdio.h>
+
+#include "tailor.h"
+#include "gzip.h"
+#include "lzw.h" /* just for consistency checking */
+
+/* decode.c */
+
+local unsigned  decode  OF((unsigned count, uch buffer[]));
+local void decode_start OF((void));
+
+/* huf.c */
+local void huf_decode_start OF((void));
+local unsigned decode_c     OF((void));
+local unsigned decode_p     OF((void));
+
+/* io.c */
+local void fillbuf      OF((int n));
+local unsigned getbits  OF((int n));
+local void init_getbits OF((void));
+
+#define DICBIT    13    /* 12(-lh4-) or 13(-lh5-) */
+#define DICSIZ ((unsigned) 1 << DICBIT)
+
+#ifndef CHAR_BIT
+#  define CHAR_BIT 8
+#endif
+
+#ifndef UCHAR_MAX
+#  define UCHAR_MAX 255
+#endif
+
+#define BITBUFSIZ (CHAR_BIT * 2 * sizeof(char))
+/* Do not use CHAR_BIT * sizeof(bitbuf), does not work on machines
+ * for which short is not on 16 bits (Cray).
+ */
+
+/* encode.c and decode.c */
+
+#define MAXMATCH 256    /* formerly F (not more than UCHAR_MAX + 1) */
+#define THRESHOLD  3    /* choose optimal value */
+
+/* huf.c */
+
+#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
+       /* alphabet = {0, 1, 2, ..., NC - 1} */
+#define CBIT 9  /* $\lfloor \log_2 NC \rfloor + 1$ */
+#define CODE_BIT  16  /* codeword length */
+
+#define NP (DICBIT + 1)
+#define NT (CODE_BIT + 3)
+#define PBIT 4  /* smallest integer such that (1U << PBIT) > NP */
+#define TBIT 5  /* smallest integer such that (1U << TBIT) > NT */
+#if NT > NP
+# define NPT NT
+#else
+# define NPT NP
+#endif
+
+/* local ush left[2 * NC - 1]; */
+/* local ush right[2 * NC - 1]; */
+#define left  prev
+#define right head
+#if NC > 1<<(BITS-2)
+    error cannot overlay left+right and prev
+#endif
+
+/* local uch c_len[NC]; */
+#define c_len outbuf
+#if NC > OUTBUFSIZ
+    error cannot overlay c_len and outbuf
+#endif
+
+local uch pt_len[NPT];
+local unsigned blocksize;
+local ush pt_table[256];
+
+/* local ush c_table[4096]; */
+#define c_table d_buf
+#if DIST_BUFSIZE < 4096
+    error cannot overlay c_table and d_buf
+#endif
+
+local ush       bitbuf;
+local unsigned  subbitbuf;
+local int       bitcount;
+
+local void fillbuf(n)  /* Shift bitbuf n bits left, read n bits */
+    int n;
+{
+    bitbuf <<= n;
+    while (n > bitcount) {
+       bitbuf |= subbitbuf << (n -= bitcount);
+       subbitbuf = (unsigned)try_byte();
+       if ((int)subbitbuf == EOF) subbitbuf = 0;
+       bitcount = CHAR_BIT;
+    }
+    bitbuf |= subbitbuf >> (bitcount -= n);
+}
+
+local unsigned getbits(n)
+    int n;
+{
+    unsigned x;
+
+    x = bitbuf >> (BITBUFSIZ - n);  fillbuf(n);
+    return x;
+}
+
+local void init_getbits()
+{
+    bitbuf = 0;  subbitbuf = 0;  bitcount = 0;
+    fillbuf(BITBUFSIZ);
+}
+
+/***********************************************************
+       maketbl.c -- make table for decoding
+***********************************************************/
+
+local void make_table(nchar, bitlen, tablebits, table)
+    int nchar;
+    uch bitlen[];
+    int tablebits;
+    ush table[];
+{
+    ush count[17], weight[17], start[18], *p;
+    unsigned i, k, len, ch, jutbits, avail, nextcode, mask;
+
+    for (i = 1; i <= 16; i++) count[i] = 0;
+    for (i = 0; i < nchar; i++) count[bitlen[i]]++;
+
+    start[1] = 0;
+    for (i = 1; i <= 16; i++)
+       start[i + 1] = start[i] + (count[i] << (16 - i));
+    if (start[17] != (ush)((unsigned) 1 << 16))
+       error("Bad table\n");
+
+    jutbits = 16 - tablebits;
+    for (i = 1; i <= tablebits; i++) {
+       start[i] >>= jutbits;
+       weight[i] = (unsigned) 1 << (tablebits - i);
+    }
+    while (i <= 16) {
+       weight[i] = (unsigned) 1 << (16 - i);
+       i++;
+    }
+
+    i = start[tablebits + 1] >> jutbits;
+    if (i != (ush)((unsigned) 1 << 16)) {
+       k = 1 << tablebits;
+       while (i != k) table[i++] = 0;
+    }
+
+    avail = nchar;
+    mask = (unsigned) 1 << (15 - tablebits);
+    for (ch = 0; ch < nchar; ch++) {
+       if ((len = bitlen[ch]) == 0) continue;
+       nextcode = start[len] + weight[len];
+       if (len <= tablebits) {
+           for (i = start[len]; i < nextcode; i++) table[i] = ch;
+       } else {
+           k = start[len];
+           p = &table[k >> jutbits];
+           i = len - tablebits;
+           while (i != 0) {
+               if (*p == 0) {
+                   right[avail] = left[avail] = 0;
+                   *p = avail++;
+               }
+               if (k & mask) p = &right[*p];
+               else          p = &left[*p];
+               k <<= 1;  i--;
+           }
+           *p = ch;
+       }
+       start[len] = nextcode;
+    }
+}
+
+/***********************************************************
+        huf.c -- static Huffman
+***********************************************************/
+
+local void read_pt_len(nn, nbit, i_special)
+    int nn;
+    int nbit;
+    int i_special;
+{
+    int i, c, n;
+    unsigned mask;
+
+    n = getbits(nbit);
+    if (n == 0) {
+       c = getbits(nbit);
+       for (i = 0; i < nn; i++) pt_len[i] = 0;
+       for (i = 0; i < 256; i++) pt_table[i] = c;
+    } else {
+       i = 0;
+       while (i < n) {
+           c = bitbuf >> (BITBUFSIZ - 3);
+           if (c == 7) {
+               mask = (unsigned) 1 << (BITBUFSIZ - 1 - 3);
+               while (mask & bitbuf) {  mask >>= 1;  c++;  }
+           }
+           fillbuf((c < 7) ? 3 : c - 3);
+           pt_len[i++] = c;
+           if (i == i_special) {
+               c = getbits(2);
+               while (--c >= 0) pt_len[i++] = 0;
+           }
+       }
+       while (i < nn) pt_len[i++] = 0;
+       make_table(nn, pt_len, 8, pt_table);
+    }
+}
+
+local void read_c_len()
+{
+    int i, c, n;
+    unsigned mask;
+
+    n = getbits(CBIT);
+    if (n == 0) {
+       c = getbits(CBIT);
+       for (i = 0; i < NC; i++) c_len[i] = 0;
+       for (i = 0; i < 4096; i++) c_table[i] = c;
+    } else {
+       i = 0;
+       while (i < n) {
+           c = pt_table[bitbuf >> (BITBUFSIZ - 8)];
+           if (c >= NT) {
+               mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
+               do {
+                   if (bitbuf & mask) c = right[c];
+                   else               c = left [c];
+                   mask >>= 1;
+               } while (c >= NT);
+           }
+           fillbuf((int) pt_len[c]);
+           if (c <= 2) {
+               if      (c == 0) c = 1;
+               else if (c == 1) c = getbits(4) + 3;
+               else             c = getbits(CBIT) + 20;
+               while (--c >= 0) c_len[i++] = 0;
+           } else c_len[i++] = c - 2;
+       }
+       while (i < NC) c_len[i++] = 0;
+       make_table(NC, c_len, 12, c_table);
+    }
+}
+
+local unsigned decode_c()
+{
+    unsigned j, mask;
+
+    if (blocksize == 0) {
+       blocksize = getbits(16);
+       if (blocksize == 0) {
+           return NC; /* end of file */
+       }
+       read_pt_len(NT, TBIT, 3);
+       read_c_len();
+       read_pt_len(NP, PBIT, -1);
+    }
+    blocksize--;
+    j = c_table[bitbuf >> (BITBUFSIZ - 12)];
+    if (j >= NC) {
+       mask = (unsigned) 1 << (BITBUFSIZ - 1 - 12);
+       do {
+           if (bitbuf & mask) j = right[j];
+           else               j = left [j];
+           mask >>= 1;
+       } while (j >= NC);
+    }
+    fillbuf((int) c_len[j]);
+    return j;
+}
+
+local unsigned decode_p()
+{
+    unsigned j, mask;
+
+    j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
+    if (j >= NP) {
+       mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
+       do {
+           if (bitbuf & mask) j = right[j];
+           else               j = left [j];
+           mask >>= 1;
+       } while (j >= NP);
+    }
+    fillbuf((int) pt_len[j]);
+    if (j != 0) j = ((unsigned) 1 << (j - 1)) + getbits((int) (j - 1));
+    return j;
+}
+
+local void huf_decode_start()
+{
+    init_getbits();  blocksize = 0;
+}
+
+/***********************************************************
+        decode.c
+***********************************************************/
+
+local int j;    /* remaining bytes to copy */
+local int done; /* set at end of input */
+
+local void decode_start()
+{
+    huf_decode_start();
+    j = 0;
+    done = 0;
+}
+
+/* Decode the input and return the number of decoded bytes put in buffer
+ */
+local unsigned decode(count, buffer)
+    unsigned count;
+    uch buffer[];
+    /* The calling function must keep the number of
+       bytes to be processed.  This function decodes
+       either 'count' bytes or 'DICSIZ' bytes, whichever
+       is smaller, into the array 'buffer[]' of size
+       'DICSIZ' or more.
+       Call decode_start() once for each new file
+       before calling this function.
+     */
+{
+    local unsigned i;
+    unsigned r, c;
+
+    r = 0;
+    while (--j >= 0) {
+       buffer[r] = buffer[i];
+       i = (i + 1) & (DICSIZ - 1);
+       if (++r == count) return r;
+    }
+    for ( ; ; ) {
+       c = decode_c();
+       if (c == NC) {
+           done = 1;
+           return r;
+       }
+       if (c <= UCHAR_MAX) {
+           buffer[r] = c;
+           if (++r == count) return r;
+       } else {
+           j = c - (UCHAR_MAX + 1 - THRESHOLD);
+           i = (r - decode_p() - 1) & (DICSIZ - 1);
+           while (--j >= 0) {
+               buffer[r] = buffer[i];
+               i = (i + 1) & (DICSIZ - 1);
+               if (++r == count) return r;
+           }
+       }
+    }
+}
+
+
+/* ===========================================================================
+ * Unlzh in to out. Return OK or ERROR.
+ */
+int unlzh(in, out)
+    int in;
+    int out;
+{
+    unsigned n;
+    ifd = in;
+    ofd = out;
+
+    decode_start();
+    while (!done) {
+       n = decode((unsigned) DICSIZ, window);
+       if (!test && n > 0) {
+           write_buf(out, (char*)window, n);
+       }
+    }
+    return OK;
+}
index 0687c1b..61c45fc 100644 (file)
@@ -8,10 +8,9 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: unlzw.c,v 0.13 1993/05/27 10:32:55 jloup Exp $";
+static char rcsid[] = "$Id: unlzw.c,v 0.15 1993/06/10 13:28:35 jloup Exp $";
 #endif
 
 #endif
 
-#include <stdio.h>
 #include <sys/types.h>
 
 #include "tailor.h"
 #include <sys/types.h>
 
 #include "tailor.h"
@@ -263,6 +262,7 @@ int unlzw(in, out)
                read_error();
            }
            insize += rsize;
                read_error();
            }
            insize += rsize;
+           bytes_in += (ulg)rsize;
        }
        inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : 
                  ((long)insize<<3)-(n_bits-1));
        }
        inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : 
                  ((long)insize<<3)-(n_bits-1));
@@ -313,7 +313,8 @@ int unlzw(in, out)
                            posbits, p[-1],p[0],p[1],p[2],p[3]);
 #endif
                    if (!test && outpos > 0) {
                            posbits, p[-1],p[0],p[1],p[2],p[3]);
 #endif
                    if (!test && outpos > 0) {
-                       write_buf(out, outbuf, outpos);
+                       write_buf(out, (char*)outbuf, outpos);
+                       bytes_out += (ulg)outpos;
                    }
                    error("corrupt input. Use zcat to recover some data.");
                }
                    }
                    error("corrupt input. Use zcat to recover some data.");
                }
@@ -341,7 +342,10 @@ int unlzw(in, out)
                            outpos += i;
                        }
                        if (outpos >= OUTBUFSIZ) {
                            outpos += i;
                        }
                        if (outpos >= OUTBUFSIZ) {
-                           if (!test) write_buf(out, outbuf, outpos);
+                           if (!test) {
+                               write_buf(out, (char*)outbuf, outpos);
+                               bytes_out += (ulg)outpos;
+                           }
                            outpos = 0;
                        }
                        stackp+= i;
                            outpos = 0;
                        }
                        stackp+= i;
@@ -360,10 +364,11 @@ int unlzw(in, out)
            } 
            oldcode = incode;   /* Remember previous code.      */
        }
            } 
            oldcode = incode;   /* Remember previous code.      */
        }
-       bytes_in += rsize;
-
     } while (rsize != 0);
     
     } while (rsize != 0);
     
-    if (!test && outpos > 0) write_buf(out, outbuf, outpos);
+    if (!test && outpos > 0) {
+       write_buf(out, (char*)outbuf, outpos);
+       bytes_out += (ulg)outpos;
+    }
     return OK;
 }
     return OK;
 }
index e6cf7ca..789cbc0 100644 (file)
@@ -5,11 +5,9 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: unpack.c,v 1.3 1993/05/28 17:56:07 jloup Exp $";
+static char rcsid[] = "$Id: unpack.c,v 1.4 1993/06/11 19:25:36 jloup Exp $";
 #endif
 
 #endif
 
-#include <stdio.h>
-
 #include "tailor.h"
 #include "gzip.h"
 #include "crypt.h"
 #include "tailor.h"
 #include "gzip.h"
 #include "crypt.h"
@@ -26,11 +24,7 @@ static char rcsid[] = "$Id: unpack.c,v 1.3 1993/05/28 17:56:07 jloup Exp $";
 #define LITERALS 256
 /* Number of literals, excluding the End of Block (EOB) code */
 
 #define LITERALS 256
 /* Number of literals, excluding the End of Block (EOB) code */
 
-#ifdef SMALL_MEM
-#  define MAX_PEEK 10
-#else
-#  define MAX_PEEK 12
-#endif
+#define MAX_PEEK 12
 /* Maximum number of 'peek' bits used to optimize traversal of the
  * Huffman tree.
  */
 /* Maximum number of 'peek' bits used to optimize traversal of the
  * Huffman tree.
  */
@@ -54,7 +48,8 @@ local int parents[MAX_BITLEN+1]; /* Number of parents for each bit length */
 
 local int peek_bits; /* Number of peek bits currently used */
 
 
 local int peek_bits; /* Number of peek bits currently used */
 
-local uch prefix_len[1 << MAX_PEEK];
+/* local uch prefix_len[1 << MAX_PEEK]; */
+#define prefix_len outbuf
 /* For each bit pattern b of peek_bits bits, prefix_len[b] is the length
  * of the Huffman code starting with a prefix of b (upper bits), or 0
  * if all codes of prefix b have more than peek_bits bits. It is not
 /* For each bit pattern b of peek_bits bits, prefix_len[b] is the length
  * of the Huffman code starting with a prefix of b (upper bits), or 0
  * if all codes of prefix b have more than peek_bits bits. It is not
@@ -62,6 +57,9 @@ local uch prefix_len[1 << MAX_PEEK];
  * codes encountered in the input stream are short codes (by construction).
  * So for most codes a single lookup will be necessary.
  */
  * codes encountered in the input stream are short codes (by construction).
  * So for most codes a single lookup will be necessary.
  */
+#if 1<<MAX_PEEK > OUTBUFSIZ
+    error cannot overlay prefix_len and outbuf
+#endif
 
 local ulg bitbuf;
 /* Bits are added on the low part of bitbuf and read from the high part. */
 
 local ulg bitbuf;
 /* Bits are added on the low part of bitbuf and read from the high part. */
index a78622a..48cdebe 100644 (file)
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: unzip.c,v 0.12 1993/05/28 17:56:23 jloup Exp $";
+static char rcsid[] = "$Id: unzip.c,v 0.13 1993/06/10 13:29:00 jloup Exp $";
 #endif
 
 #endif
 
-#include <stdio.h>
-
 #include "tailor.h"
 #include "gzip.h"
 #include "crypt.h"
 #include "tailor.h"
 #include "gzip.h"
 #include "crypt.h"
index dc3695e..52f1bdd 100644 (file)
@@ -5,10 +5,9 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: util.c,v 0.14 1993/05/27 10:31:52 jloup Exp $";
+static char rcsid[] = "$Id: util.c,v 0.15 1993/06/15 09:04:13 jloup Exp $";
 #endif
 
 #endif
 
-#include <stdio.h>
 #include <ctype.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <ctype.h>
 #include <errno.h>
 #include <sys/types.h>
@@ -33,6 +32,26 @@ static char rcsid[] = "$Id: util.c,v 0.14 1993/05/27 10:31:52 jloup Exp $";
 
 extern ulg crc_32_tab[];   /* crc table, defined below */
 
 
 extern ulg crc_32_tab[];   /* crc table, defined below */
 
+/* ===========================================================================
+ * Copy input to output unchanged: zcat == cat with --force.
+ * IN assertion: insize bytes have already been read in inbuf.
+ */
+int copy(in, out)
+    int in, out;   /* input and output file descriptors */
+{
+    errno = 0;
+    while (insize != 0 && (int)insize != EOF) {
+       write_buf(out, (char*)inbuf, insize);
+       bytes_out += insize;
+       insize = read(in, (char*)inbuf, INBUFSIZ);
+    }
+    if ((int)insize == EOF && errno != 0) {
+       read_error();
+    }
+    bytes_in = bytes_out;
+    return OK;
+}
+
 /* ===========================================================================
  * Run a set of bytes through the crc shift register.  If s is a NULL
  * pointer, then initialize the crc shift register contents instead.
 /* ===========================================================================
  * Run a set of bytes through the crc shift register.  If s is a NULL
  * pointer, then initialize the crc shift register contents instead.
@@ -69,10 +88,10 @@ void clear_bufs()
 }
 
 /* ===========================================================================
 }
 
 /* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
+ * Fill the input buffer. This is called only when the buffer is empty.
  */
  */
-int fill_inbuf()
+int fill_inbuf(eof_ok)
+    int eof_ok;          /* set if EOF acceptable as a result */
 {
     int len;
 
 {
     int len;
 
@@ -86,6 +105,7 @@ int fill_inbuf()
     } while (insize < INBUFSIZ);
 
     if (insize == 0) {
     } while (insize < INBUFSIZ);
 
     if (insize == 0) {
+       if (eof_ok) return EOF;
        read_error();
     }
     bytes_in += (ulg)insize;
        read_error();
     }
     bytes_in += (ulg)insize;
@@ -177,6 +197,26 @@ char *basename(fname)
     return fname;
 }
 
     return fname;
 }
 
+/* ========================================================================
+ * Make a file name legal for file systems not allowing file names with
+ * multiple dots or starting with a dot (such as MSDOS), by changing
+ * all dots except the last one into underlines.  A target dependent
+ * function can be used instead of this simple function by defining the macro
+ * MAKE_LEGAL_NAME in tailor.h and providing the function in a target
+ * dependent module.
+ */
+void make_simple_name(name)
+    char *name;
+{
+    char *p = strrchr(name, '.');
+    if (p == NULL) return;
+    if (p == name) p++;
+    do {
+        if (*--p == '.') *p = '_';
+    } while (p != name);
+}
+
+
 #if defined(NO_STRING_H) && !defined(STDC_HEADERS)
 
 /* Provide missing strspn and strcspn functions. */
 #if defined(NO_STRING_H) && !defined(STDC_HEADERS)
 
 /* Provide missing strspn and strcspn functions. */
@@ -325,11 +365,12 @@ void write_error()
 }
 
 /* ========================================================================
 }
 
 /* ========================================================================
- * Display compression ratio on stderr.
+ * Display compression ratio on the given stream on 6 characters.
  */
  */
-void display_ratio(num, den)
+void display_ratio(num, den, file)
     long num;
     long den;
     long num;
     long den;
+    FILE *file;
 {
     long ratio;  /* 1000 times the compression ratio */
 
 {
     long ratio;  /* 1000 times the compression ratio */
 
@@ -341,10 +382,12 @@ void display_ratio(num, den)
        ratio = num/(den/1000L);
     }
     if (ratio < 0) {
        ratio = num/(den/1000L);
     }
     if (ratio < 0) {
-       putc('-', stderr);
+       putc('-', file);
        ratio = -ratio;
        ratio = -ratio;
+    } else {
+       putc(' ', file);
     }
     }
-    fprintf(stderr, "%2ld.%ld%%", ratio / 10L, ratio % 10L);
+    fprintf(file, "%2ld.%1ld%%", ratio / 10L, ratio % 10L);
 }
 
 
 }
 
 
index c21e7ef..3de5cb4 100644 (file)
@@ -1,4 +1,5 @@
 #!/bin/sh
 #!/bin/sh
+# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh
 
 # Zcmp and zdiff are used to invoke the cmp or the  diff  pro-
 # gram  on compressed files.  All options specified are passed
 
 # Zcmp and zdiff are used to invoke the cmp or the  diff  pro-
 # gram  on compressed files.  All options specified are passed
@@ -8,6 +9,7 @@
 # necessary) and fed to cmp or diff.  The exit status from cmp
 # or diff is preserved.
 
 # necessary) and fed to cmp or diff.  The exit status from cmp
 # or diff is preserved.
 
+PATH="/usr/local/bin:$PATH"; export PATH
 prog=`echo $0 | sed 's|.*/||'`
 case "$prog" in
   *cmp) comp=${CMP-cmp}   ;;
 prog=`echo $0 | sed 's|.*/||'`
 case "$prog" in
   *cmp) comp=${CMP-cmp}   ;;
index 44f9137..ea3bf41 100644 (file)
@@ -35,7 +35,7 @@ or
 .I diff
 is preserved.
 .SH "SEE ALSO"
 .I diff
 is preserved.
 .SH "SEE ALSO"
-cmp(1), diff(1), zmore(1), znew(1), zforce(1), gzip(1), gzexe(1)
+cmp(1), diff(1), zmore(1), zgrep(1), znew(1), zforce(1), gzip(1), gzexe(1)
 .SH BUGS
 Messages from the
 .I cmp
 .SH BUGS
 Messages from the
 .I cmp
index 9fe85ad..17258a4 100644 (file)
@@ -5,6 +5,7 @@
 # This can be useful for files with names truncated after a file transfer.
 # 12345678901234 is renamed to 12345678901.gz
 
 # This can be useful for files with names truncated after a file transfer.
 # 12345678901234 is renamed to 12345678901.gz
 
+PATH="/usr/local/bin:$PATH"; export PATH
 x=`basename $0`
 if test $# = 0; then
   echo "force a '.gz' extension on all gzip files"
 x=`basename $0`
 if test $# = 0; then
   echo "force a '.gz' extension on all gzip files"
@@ -23,17 +24,18 @@ for i do
   test `expr "$i" : '.*[.-]gz$'` -eq 0 || continue
   test `expr "$i" : '.*[.]t[ag]z$'` -eq 0 || continue
 
   test `expr "$i" : '.*[.-]gz$'` -eq 0 || continue
   test `expr "$i" : '.*[.]t[ag]z$'` -eq 0 || continue
 
-  gzip -t "$i" 2>/dev/null || continue
+  if gzip -l < "$i" 2>/dev/null | grep '^defl' > /dev/null; then
 
 
-  if test `expr "$i" : '^............'` -eq 12; then
-    new=`expr "$i" : '\(.*\)...$`.gz
-  else
-    new="$i.gz"
+    if test `expr "$i" : '^............'` -eq 12; then
+      new=`expr "$i" : '\(.*\)...$`.gz
+    else
+      new="$i.gz"
+    fi
+    if mv "$i" "$new" 2>/dev/null; then
+      echo $i -- replaced with $new
+      continue
+    fi
+    res=1; echo ${x}: cannot rename $i to $new
   fi
   fi
-  if mv "$i" "$new" 2>/dev/null; then
-    echo $i -- replaced with $new
-    continue
-  fi
-  res=1; echo ${x}: cannot rename $i to $new
 done
 exit $res
 done
 exit $res
index e231815..37c6aba 100644 (file)
@@ -17,4 +17,4 @@ is truncated to make room for the .gz suffix. For example,
 12345678901234 is renamed to 12345678901.gz. A file name such as foo.tgz
 is left intact.
 .SH "SEE ALSO"
 12345678901234 is renamed to 12345678901.gz. A file name such as foo.tgz
 is left intact.
 .SH "SEE ALSO"
-gzip(1), znew(1), zmore(1), zcmp(1), gzexe(1)
+gzip(1), znew(1), zmore(1), zgrep(1), zdiff(1), gzexe(1)
diff --git a/gnu/usr.bin/gzip/zgrep b/gnu/usr.bin/gzip/zgrep
new file mode 100644 (file)
index 0000000..bcc10cc
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+# zgrep -- a wrapper around a grep program that decompresses files as needed
+# Adapted from a version sent by Charles Levert <charles@comm.polymtl.ca>
+
+PATH="/usr/local/bin:$PATH"; export PATH
+
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+       *egrep) grep=${EGREP-egrep}     ;;
+       *fgrep) grep=${FGREP-fgrep}     ;;
+       *)      grep=${GREP-grep}       ;;
+esac
+A=
+fileno=0
+pat=""
+while test $# -ne 0; do
+  case "$1" in
+  -e | -f) opt="$opt $1"; shift; pat="$1"
+           if test "$grep" = grep; then  # grep is buggy with -e on SVR4
+             grep=egrep
+           fi;;
+  -*)     opt="$opt $1";;
+   *)      if test -z "$pat"; then
+            pat="$1"
+          else
+             fileno=`expr $fileno + 1`
+             eval A$fileno=\$1
+             A="$A \"\$A$fileno\""
+             fi
+            ;;
+  esac
+  shift
+done
+
+if test -z "$pat"; then
+  echo "grep through gzip files"
+  echo "usage: $prog [grep_options] pattern [files]"
+  exit 1
+fi
+
+list=0
+silent=0
+op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
+case "$op" in
+  *l*) list=1
+esac
+case "$op" in
+  *h*) silent=1
+esac
+
+if test $fileno -eq 0; then
+  gzip -cdfq | $grep $opt "$pat"
+  exit $?
+fi
+eval set "$A" # files in $1, $2 ...
+
+res=0
+for i do
+  if test $list -eq 1; then
+    gzip -cdfq "$i" | $grep $opt "$pat" > /dev/null && echo $i
+    r=$?
+  elif test $# -eq 1 -o $silent -eq 1; then
+    gzip -cdfq "$i" | $grep $opt "$pat"
+    r=$?
+  else
+    gzip -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${i}:|"
+    r=$?
+  fi
+  test "$r" -ne 0 && res="$r"
+done
+exit $res
diff --git a/gnu/usr.bin/gzip/zgrep.1 b/gnu/usr.bin/gzip/zgrep.1
new file mode 100644 (file)
index 0000000..a52a88a
--- /dev/null
@@ -0,0 +1,44 @@
+.TH ZGREP 1
+.SH NAME
+zgrep \- search possibly compressed files for a regular expression
+.SH SYNOPSIS
+.B zgrep
+[ grep_options ]
+.BI  [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.SH DESCRIPTION
+.IR  Zgrep
+is used to invoke the
+.I grep
+on compress'ed or gzip'ed files. All options specified are passed directly to
+.I grep.
+If no file is specified, then the standard input is decompressed
+if necessary and fed to grep.
+Otherwise the given files are uncompressed if necessary and fed to
+.I grep.
+.PP
+If
+.I zgrep
+is invoked as
+.I zegrep
+or
+.I zfgrep
+then
+.I egrep
+or
+.I fgrep
+is used instead of
+.I grep.
+If the GREP environment variable is set,
+.I zgrep
+uses it as the
+.I grep
+program to be invoked. For example:
+
+    for sh:  GREP=fgrep  zgrep string files
+    for csh: (setenv GREP fgrep; zgrep string files)
+.SH AUTHOR
+Charles Levert (charles@comm.polymtl.ca)
+.SH "SEE ALSO"
+grep(1), egrep(1), fgrep(1), zdiff(1), zmore(1), znew(1), zforce(1),
+gzip(1), gzexe(1)
index 5bf172f..3928262 100644 (file)
@@ -5,11 +5,10 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: zip.c,v 0.16 1993/05/28 14:51:17 jloup Exp $";
+static char rcsid[] = "$Id: zip.c,v 0.17 1993/06/10 13:29:25 jloup Exp $";
 #endif
 
 #include <ctype.h>
 #endif
 
 #include <ctype.h>
-#include <stdio.h>
 #include <sys/types.h>
 
 #include "tailor.h"
 #include <sys/types.h>
 
 #include "tailor.h"
index 64f7b1b..6a089a2 100644 (file)
@@ -1,22 +1,27 @@
 #!/bin/sh
 
 #!/bin/sh
 
+PATH="/usr/local/bin:$PATH"; export PATH
 if test "`echo -n a`" = "-n a"; then
   # looks like a SysV system:
   n1=''; n2='\c'
 else
   n1='-n'; n2=''
 fi
 if test "`echo -n a`" = "-n a"; then
   # looks like a SysV system:
   n1=''; n2='\c'
 else
   n1='-n'; n2=''
 fi
+oldtty=`stty -g 2>/dev/null`
 if stty -cbreak 2>/dev/null; then
   cb='cbreak'; ncb='-cbreak'
 else
   # 'stty min 1' resets eof to ^a on both SunOS and SysV!
   cb='min 1 -icanon'; ncb='icanon eof ^d'
 fi
 if stty -cbreak 2>/dev/null; then
   cb='cbreak'; ncb='-cbreak'
 else
   # 'stty min 1' resets eof to ^a on both SunOS and SysV!
   cb='min 1 -icanon'; ncb='icanon eof ^d'
 fi
-oldtty=`stty -g`
-trap 'stty -g $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
+if test $? -eq 0 -a -n "$oldtty"; then
+   trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
+else
+   trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
+fi
 
 if test $# = 0; then
 
 if test $# = 0; then
-       gzip -cd | eval ${PAGER-more}
+       gzip -cdfq | eval ${PAGER-more}
 else
     FIRST=1
     for FILE
 else
     FIRST=1
     for FILE
@@ -33,7 +38,7 @@ else
        fi
        if test "$ANS" != 's'; then
                echo "------> $FILE <------"
        fi
        if test "$ANS" != 's'; then
                echo "------> $FILE <------"
-               gzip -cd "$FILE" | eval ${PAGER-more}
+               gzip -cdfq "$FILE" | eval ${PAGER-more}
        fi
        if test -t; then
                FIRST=0
        fi
        if test -t; then
                FIRST=0
index 08b49fb..f7f1843 100644 (file)
@@ -6,9 +6,20 @@ zmore \- file perusal filter for crt viewing of compressed text
 [ name ...  ]
 .SH DESCRIPTION
 .I  Zmore
 [ name ...  ]
 .SH DESCRIPTION
 .I  Zmore
-is a filter which allows examination of compressed text files
+is a filter which allows examination of compressed or plain text files
 one screenful at a time on a soft-copy terminal.
 one screenful at a time on a soft-copy terminal.
-It normally pauses after each screenful, printing --More--
+.I zmore
+works on files compressed with
+.I compress, pack
+or
+.I gzip,
+and also on uncompressed files.
+If a file does not exist,
+.I zmore
+looks for a file of the same name with the addition of a .gz, .z or .Z suffix.
+.PP
+.I Zmore
+normally pauses after each screenful, printing --More--
 at the bottom of the screen.
 If the user then types a carriage return, one more line is displayed.
 If the user hits a space,
 at the bottom of the screen.
 If the user then types a carriage return, one more line is displayed.
 If the user hits a space,
@@ -131,4 +142,4 @@ except that a header is printed before each file.
 .DT
 /etc/termcap           Terminal data base
 .SH "SEE ALSO"
 .DT
 /etc/termcap           Terminal data base
 .SH "SEE ALSO"
-more(1), gzip(1), zcmp(1), znew(1), zforce(1), gzexe(1)
+more(1), gzip(1), zdiff(1), zgrep(1), znew(1), zforce(1), gzexe(1)
index fcbc466..01be32c 100644 (file)
@@ -1,5 +1,6 @@
 #!/bin/sh
 
 #!/bin/sh
 
+PATH="/usr/local/bin:$PATH"; export PATH
 check=0
 pipe=0
 opt=
 check=0
 pipe=0
 opt=
@@ -25,7 +26,19 @@ if test -z "$cpmod" && ${TOUCH-touch} -r $tmp.1 $tmp.2 2>/dev/null; then
   cpmodarg="-r"
   warn="(does not preserve file modes)"
 fi
   cpmodarg="-r"
   warn="(does not preserve file modes)"
 fi
-rm -f $tmp.[12]
+
+# check if GZIP env. variable uses -S or --suffix
+gzip -q $tmp.1
+ext=`echo $tmp.1* | sed "s|$tmp.1||"`
+rm -f $tmp.[12]*
+if test -z "$ext"; then
+  echo znew: error determining gzip extension
+  exit 1
+fi
+if test "$ext" = ".Z"; then
+  echo znew: cannot use .Z as gzip extension.
+  exit 1
+fi
 
 A=
 fileno=0
 
 A=
 fileno=0
@@ -42,12 +55,12 @@ do
 done
 
 if test $fileno -eq 0; then
 done
 
 if test $fileno -eq 0; then
-  echo 'recompress .Z files into .gz (gzip) files'
-  echo usage: `echo $0 | sed 's,^.*/,,'` "[-tv9P]" file.Z...
+  echo "recompress .Z files into $ext (gzip) files"
+  echo usage: `echo $0 | sed 's,^.*/,,'` "[-tv9KP]" file.Z...
   echo "  -t tests the new files before deleting originals"
   echo "  -v be verbose"
   echo "  -9 use the slowest compression method (optimal compression)"
   echo "  -t tests the new files before deleting originals"
   echo "  -v be verbose"
   echo "  -9 use the slowest compression method (optimal compression)"
-  echo "  -K keep a .Z file when it is smaller than the .gz file"
+  echo "  -K keep a .Z file when it is smaller than the $ext file"
   echo "  -P use pipes for the conversion $warn"
   exit 1
 fi
   echo "  -P use pipes for the conversion $warn"
   exit 1
 fi
@@ -76,9 +89,9 @@ for i do
   fi
   test $keep -eq 1 && old=`wc -c < "$n.Z"`
   if test $pipe -eq 1; then
   fi
   test $keep -eq 1 && old=`wc -c < "$n.Z"`
   if test $pipe -eq 1; then
-    if gzip -d < "$n.Z" | gzip $opt > "$n.gz"; then
+    if gzip -d < "$n.Z" | gzip $opt > "$n$ext"; then
       # Copy file attributes from old file to new one, if possible.
       # Copy file attributes from old file to new one, if possible.
-      test -n "$cpmod" && $cpmod $cpmodarg "$n.Z" "$n.gz" 2> /dev/null
+      test -n "$cpmod" && $cpmod $cpmodarg "$n.Z" "$n$ext" 2> /dev/null
     else
       echo error while recompressing $n.Z
       res=1; continue
     else
       echo error while recompressing $n.Z
       res=1; continue
@@ -112,25 +125,25 @@ for i do
       res=1; continue
     fi
   fi
       res=1; continue
     fi
   fi
-  test $keep -eq 1 && new=`wc -c < "$n.gz"`
+  test $keep -eq 1 && new=`wc -c < "$n$ext"`
   if test $keep -eq 1 -a `expr \( $old + $block - 1 \) / $block` -lt \
                          `expr \( $new + $block - 1 \) / $block`; then
     if test $pipe -eq 1; then
   if test $keep -eq 1 -a `expr \( $old + $block - 1 \) / $block` -lt \
                          `expr \( $new + $block - 1 \) / $block`; then
     if test $pipe -eq 1; then
-      rm -f "$n.gz"
+      rm -f "$n$ext"
     elif test $check -eq 1; then
     elif test $check -eq 1; then
-      mv "$n.$$" "$n.Z" && rm -f "$n.gz"
+      mv "$n.$$" "$n.Z" && rm -f "$n$ext"
     else
     else
-      gzip -d "$n.gz" && compress "$n" && rm -f "$n.gz"
+      gzip -d "$n$ext" && compress "$n" && rm -f "$n$ext"
     fi
     fi
-    echo "$n.Z smaller than $n.gz -- unchanged"
+    echo "$n.Z smaller than $n$ext -- unchanged"
 
   elif test $check -eq 1; then
 
   elif test $check -eq 1; then
-    if gzip -t "$n.gz" ; then
+    if gzip -t "$n$ext" ; then
       rm -f "$n.$$" "$n.Z"
     else
       test $pipe -eq 0 && mv "$n.$$" "$n.Z"
       rm -f "$n.$$" "$n.Z"
     else
       test $pipe -eq 0 && mv "$n.$$" "$n.Z"
-      rm -f "$n.gz"
-      echo error while testing $n.gz, $n.Z unchanged
+      rm -f "$n$ext"
+      echo error while testing $n$ext, $n.Z unchanged
       res=1; continue
     fi
   elif test $pipe -eq 1; then
       res=1; continue
     fi
   elif test $pipe -eq 1; then
index 644873b..810c51d 100644 (file)
@@ -8,6 +8,7 @@ znew \-   recompress .Z files to .gz files
 .I  Znew
 recompresses files from .Z (compress) format to .gz (gzip) format.
 .SH OPTIONS
 .I  Znew
 recompresses files from .Z (compress) format to .gz (gzip) format.
 .SH OPTIONS
+.TP
 .B \-f
 Force recompression from .Z to .gz format even if a .gz file already exists.
 .TP
 .B \-f
 Force recompression from .Z to .gz format even if a .gz file already exists.
 .TP
@@ -26,7 +27,7 @@ Use pipes for the conversion to reduce disk space usage.
 .B \-K
 Keep a .Z file when it is smaller than the .gz file
 .SH "SEE ALSO"
 .B \-K
 Keep a .Z file when it is smaller than the .gz file
 .SH "SEE ALSO"
-gzip(1), zmore(1), zcmp(1), zforce(1), gzexe(1), compress(1)
+gzip(1), zmore(1), zdiff(1), zgrep(1), zforce(1), gzexe(1), compress(1)
 .SH BUGS
 .I Znew
 does not maintain the time stamp with the -P option if
 .SH BUGS
 .I Znew
 does not maintain the time stamp with the -P option if