Updated gzip from 1.1 to 1.2.2

This commit is contained in:
Nate Williams 1993-06-19 00:22:46 +00:00
parent 7e0ed885d8
commit 35f29edac9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=26
39 changed files with 1460 additions and 292 deletions

View 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

View File

@ -2,10 +2,10 @@
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
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
@ -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 \
${.CURDIR}/zmore ${.CURDIR}/zdiff ${.CURDIR}/zcmp \
${.CURDIR}/zmore ${.CURDIR}/zdiff ${.CURDIR}/zgrep \
${DESTDIR}${BINDIR}
match.o: ${.CURDIR}/match.S

View 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.
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.

View 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
@ -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
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.
- 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.
@ -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 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:
@ -68,6 +74,9 @@ Bug reports should ideally include:
* 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
@ -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:
- 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.
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
(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.
@ -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
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
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.)

View 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
@ -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
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
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
@ -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
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
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
@ -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
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
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
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
@ -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
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
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
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
Burt Leland burt@molecular.com
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
@ -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
Don R. Maszle maze@bea.lbl.gov
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
M. Mesturino mesturino@cselt.stet.it
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
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
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
Yves Perrenoud pyves@nuga.alphanet.ch
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
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
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
@ -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
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
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
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
@ -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
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

View 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.
- 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>.

View 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.
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
@ -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.
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

View File

@ -60,7 +60,7 @@
#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
/* ===========================================================================
@ -84,7 +84,7 @@ local int bi_valid;
* 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

View File

@ -68,7 +68,7 @@
#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
/* ===========================================================================
@ -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
* 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 */
@ -216,18 +225,20 @@ typedef struct config {
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 */
/* 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
@ -237,6 +248,8 @@ local config configuration_table[10] = {
* 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 */
@ -277,6 +290,7 @@ void lm_init (pack_level, flags)
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
@ -558,10 +572,12 @@ local void fill_window()
(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 */
@ -592,22 +608,38 @@ ulg deflate()
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 */
Tracevv((stderr,"%c",window[strstart]));
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
@ -620,7 +652,7 @@ ulg deflate()
}
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
@ -637,6 +669,8 @@ ulg deflate()
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
@ -727,4 +761,3 @@ ulg deflate()
return FLUSH_BLOCK(1); /* eof */
}
#endif /* LAZY */

View File

@ -34,6 +34,11 @@ char *alloca ();
#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__)

View 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);
#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);

View 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.
# 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.
# On Ultrix, /bin/sh is too buggy, change the first line to: #!/bin/sh5
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]$$
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
@ -57,10 +73,10 @@ for i do
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
@ -72,25 +88,25 @@ for i do
fi
if test $decomp -eq 0; then
sed 1q $0 > $tmp
cat >> $tmp <<'EOF'
sed "s|^if tail|if $tail|" >> $tmp <<'EOF'
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
(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
(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
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
@ -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 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.

View 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)
.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,

View 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.
# 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.
# On Ultrix, /bin/sh is too buggy, change the first line to: #!/bin/sh5
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]$$
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
@ -58,10 +74,10 @@ for i do
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
@ -73,25 +89,25 @@ for i do
fi
if test $decomp -eq 0; then
sed 1q $0 > $tmp
cat >> $tmp <<'EOF'
sed "s|^if tail|if $tail|" >> $tmp <<'EOF'
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
(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
(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
gzip -cv9 "$i" >> $tmp || {
"BINDIR"/gzip -cv9 "$i" >> $tmp || {
/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 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.

View File

@ -5,7 +5,7 @@ gzip, gunzip, zcat \- compress or expand files
.SH SYNOPSIS
.ll +8
.B gzip
.RB [ " \-acdfhLrtvV19 " ]
.RB [ " \-acdfhlLnrtvV19 " ]
.RB [ \-S\ suffix ]
[
.I "name \&..."
@ -13,14 +13,14 @@ gzip, gunzip, zcat \- compress or expand files
.ll -8
.br
.B gunzip
.RB [ " \-acfhLrtvV " ]
.RB [ " \-acfhlLnrtvV " ]
.RB [ \-S\ suffix ]
[
.I "name \&..."
]
.br
.B zcat
.RB [ " \-hLV " ]
.RB [ " \-fhLV " ]
[
.I "name \&..."
]
@ -35,21 +35,33 @@ while keeping the same ownership modes, access and modification times.
.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
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
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.
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
@ -66,10 +78,17 @@ as shorthands for
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
.I gzip, zip, compress
.I gzip, zip, compress, compress -H
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
checks the uncompressed length. The
checks the uncompressed length. The standard
.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.
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
@ -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
.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,
@ -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
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,
@ -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 \-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
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.
@ -189,10 +255,15 @@ will descend into the directory and compress all the files it finds there
.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
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
@ -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
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.
@ -219,7 +291,8 @@ or
.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
@ -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
Usage: gzip [-cdfhLrtvV19] [-S suffix] [file ...]
Usage: gzip [-cdfhlLnrtvV19] [-S suffix] [file ...]
.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
.BR \-v \.)
.BR \-v
and
.BR \-l \.)
.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.
.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.

View 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.
* 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.
*
* 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
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
#include <stdio.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 */
#ifdef NO_TIME_H
# include <sys/time.h>
#else
# include <time.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_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 */
@ -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 no_name = 0; /* don't save or restore the original file name */
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) */
@ -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 */
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 */
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 */
@ -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 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 */
@ -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 */
/* {"list", 0, 0, 'l'}, list .gz file contents */
{"list", 0, 0, 'l'}, /* list .gz file contents */
{"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 */
@ -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 void shorten_name OF((char *name));
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));
@ -270,7 +300,7 @@ int (*work) OF((int infile, int outfile)) = zip; /* function to call */
/* ======================================================================== */
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",
@ -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 */
/* -l --list list .gz file contents */
" -l --list list .gz file contents",
" -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
" -S --suffix .gz use suffix .gz instead of .z",
" -S .suf --suffix .suf use suffix .suf instead of .z",
#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",
@ -435,7 +466,7 @@ int main (argc, argv)
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':
@ -451,8 +482,12 @@ int main (argc, argv)
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 'n':
no_name = 1; break;
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 (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':
@ -511,6 +541,11 @@ int main (argc, argv)
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) */
@ -527,7 +562,7 @@ int main (argc, argv)
/* 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) {
@ -536,6 +571,9 @@ int main (argc, argv)
} 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 */
}
@ -569,7 +607,7 @@ local void treat_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");
@ -604,6 +642,10 @@ local void treat_stdin()
do_exit(exit_code); /* error message already emitted */
}
}
if (list) {
do_list(ifd, method);
return;
}
/* Actually do the compression/decompression. Loop over zipped members.
*/
@ -620,14 +662,17 @@ local void treat_stdin()
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 {
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 */
if (to_stdout) {
if (to_stdout && !list) {
strcpy(ofname, "stdout");
} else if (make_ofname() != OK) {
@ -700,6 +745,11 @@ local void treat_file(iname)
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
@ -716,6 +766,9 @@ local void treat_file(iname)
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"));
@ -749,9 +802,9 @@ local void treat_file(iname)
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 {
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);
@ -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."
* 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.
@ -775,15 +829,13 @@ local void treat_file(iname)
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 (;;) {
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;
@ -799,7 +851,11 @@ local int create_outfile()
}
/* Check for name truncation on new file (1234567890123.gz) */
#ifdef NO_FSTAT
if (stat(ofname, &ostat) != 0) {
#else
if (fstat(ofd, &ostat) != 0) {
#endif
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;
} else {
}
close(ofd);
unlink(ofname);
#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
} /* 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.
* 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;
@ -877,19 +926,19 @@ local char *get_suffix(name)
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);
}
#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 {
@ -933,7 +982,8 @@ local int get_istat(iname, sbuf)
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) {
@ -941,10 +991,6 @@ local int get_istat(iname, sbuf)
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) {
@ -987,20 +1033,24 @@ local int get_istat(iname, sbuf)
/* ========================================================================
* 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);
/* strip a version number if any and get the gzip suffix if present: */
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: */
@ -1008,7 +1058,7 @@ local int make_ofname()
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 */
@ -1023,16 +1073,15 @@ local int make_ofname()
} 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
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.
@ -1066,9 +1115,17 @@ local int get_method(in)
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 */
@ -1079,8 +1136,15 @@ local int get_method(in)
if (memcmp(magic, GZIP_MAGIC, 2) == 0
|| memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
work = unzip;
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) {
@ -1132,13 +1196,14 @@ local int get_method(in)
/* 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. */
char *p = basename(ofname);
char *p = basename(ofname);
char *base = p;
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");
}
}
} /* 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) {
@ -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, 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 (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;
}
}
/* ========================================================================
* 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.
*/
@ -1231,6 +1403,62 @@ local int name_too_long(name, statb)
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
@ -1247,22 +1475,15 @@ local int name_too_long(name, statb)
*/
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: */
#ifdef NO_MULTIPLE_DOTS
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;
} /* !decompress && name_too_long */
}
/* Check that the input and output files are different (could be
* the same by name truncation or links).

View File

@ -16,7 +16,10 @@
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__)
@ -48,11 +51,13 @@ typedef unsigned long ulg;
#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
@ -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
* 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.
*/
@ -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 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 */
#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 LZH_MAGIC "\037\240" /* Magic header for SCO LZH Compress 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 */
@ -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 */
#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
@ -261,6 +269,9 @@ extern int check_zipfile OF((int in));
/* 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));
@ -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 copy OF((int in, int out));
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 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 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 */

View File

@ -97,10 +97,9 @@
*/
#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
#include <stdio.h>
#include <sys/types.h>
#include "tailor.h"

View File

@ -3,15 +3,13 @@
*/
#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"
#include <stdio.h>
static int msg_done = 0;
/* Compress in to out with lzw method. */

View File

@ -9,7 +9,7 @@
* 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 '_'.
@ -44,11 +44,11 @@
.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 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
@ -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
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:
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] */
@ -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]
*/
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 ? */
@ -125,7 +125,7 @@ do_scan:
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:
@ -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) */
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 ? */

View File

@ -4,13 +4,13 @@
* 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 REVDATE "1 Jun 93"
#define REVDATE "17 Jun 93"
/* 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 $ */

View File

@ -8,12 +8,16 @@
* 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(__OS2__) && !defined(OS2)
# define OS2
#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 NO_OFF_T
# else /* MSC */
# define HAVE_SYS_UTIME_H
# define NO_UTIME_H
@ -69,22 +74,34 @@
# 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 HAVE_SYS_UTIME_H
# define NO_UTIME_H
# 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
# 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
@ -138,7 +155,6 @@
# ifdef __GNUC__
# define DIRENT
# define HAVE_UNISTD_H
# define RETSIGTYPE int
# else /* SASC */
# define NO_STDIN_FSTAT
# define SYSDIR
@ -149,6 +165,7 @@
# 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
@ -199,7 +216,9 @@
# 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
@ -243,6 +262,19 @@
# 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

View File

@ -54,13 +54,12 @@
*/
#include <ctype.h>
#include <stdio.h>
#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
/* ===========================================================================

385
gnu/usr.bin/gzip/unlzh.c Normal file
View File

@ -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;
}

View File

@ -8,10 +8,9 @@
*/
#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
#include <stdio.h>
#include <sys/types.h>
#include "tailor.h"
@ -263,6 +262,7 @@ int unlzw(in, out)
read_error();
}
insize += rsize;
bytes_in += (ulg)rsize;
}
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) {
write_buf(out, outbuf, outpos);
write_buf(out, (char*)outbuf, outpos);
bytes_out += (ulg)outpos;
}
error("corrupt input. Use zcat to recover some data.");
}
@ -341,7 +342,10 @@ int unlzw(in, out)
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;
@ -360,10 +364,11 @@ int unlzw(in, out)
}
oldcode = incode; /* Remember previous code. */
}
bytes_in += rsize;
} 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;
}

View File

@ -5,11 +5,9 @@
*/
#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
#include <stdio.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 */
#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.
*/
@ -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 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
@ -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.
*/
#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. */

View File

@ -14,11 +14,9 @@
*/
#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
#include <stdio.h>
#include "tailor.h"
#include "gzip.h"
#include "crypt.h"

View File

@ -5,10 +5,9 @@
*/
#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
#include <stdio.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 */
/* ===========================================================================
* 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.
@ -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;
@ -86,6 +105,7 @@ int fill_inbuf()
} while (insize < INBUFSIZ);
if (insize == 0) {
if (eof_ok) return EOF;
read_error();
}
bytes_in += (ulg)insize;
@ -177,6 +197,26 @@ char *basename(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. */
@ -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;
FILE *file;
{
long ratio; /* 1000 times the compression ratio */
@ -341,10 +382,12 @@ void display_ratio(num, den)
ratio = num/(den/1000L);
}
if (ratio < 0) {
putc('-', stderr);
putc('-', file);
ratio = -ratio;
} else {
putc(' ', file);
}
fprintf(stderr, "%2ld.%ld%%", ratio / 10L, ratio % 10L);
fprintf(file, "%2ld.%1ld%%", ratio / 10L, ratio % 10L);
}

View File

@ -1,4 +1,5 @@
#!/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
@ -8,6 +9,7 @@
# 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} ;;

View File

@ -35,7 +35,7 @@ or
.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

View File

@ -5,6 +5,7 @@
# 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"
@ -23,17 +24,18 @@ for i do
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
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

View 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"
gzip(1), znew(1), zmore(1), zcmp(1), gzexe(1)
gzip(1), znew(1), zmore(1), zgrep(1), zdiff(1), gzexe(1)

72
gnu/usr.bin/gzip/zgrep Normal file
View File

@ -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

44
gnu/usr.bin/gzip/zgrep.1 Normal file
View File

@ -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)

View File

@ -5,11 +5,10 @@
*/
#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>
#include <stdio.h>
#include <sys/types.h>
#include "tailor.h"

View File

@ -1,22 +1,27 @@
#!/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
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
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
gzip -cd | eval ${PAGER-more}
gzip -cdfq | eval ${PAGER-more}
else
FIRST=1
for FILE
@ -33,7 +38,7 @@ else
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

View File

@ -6,9 +6,20 @@ zmore \- file perusal filter for crt viewing of compressed text
[ 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.
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,
@ -131,4 +142,4 @@ except that a header is printed before each file.
.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)

View File

@ -1,5 +1,6 @@
#!/bin/sh
PATH="/usr/local/bin:$PATH"; export PATH
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
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
@ -42,12 +55,12 @@ do
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 " -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
@ -76,9 +89,9 @@ for i do
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.
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
@ -112,25 +125,25 @@ for i do
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
rm -f "$n.gz"
rm -f "$n$ext"
elif test $check -eq 1; then
mv "$n.$$" "$n.Z" && rm -f "$n.gz"
mv "$n.$$" "$n.Z" && rm -f "$n$ext"
else
gzip -d "$n.gz" && compress "$n" && rm -f "$n.gz"
gzip -d "$n$ext" && compress "$n" && rm -f "$n$ext"
fi
echo "$n.Z smaller than $n.gz -- unchanged"
echo "$n.Z smaller than $n$ext -- unchanged"
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.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

View 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
.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"
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