# This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # usr.bin/gzip # usr.bin/gzip/Makefile # usr.bin/gzip/gzexe # usr.bin/gzip/gzexe.1 # usr.bin/gzip/gzip.1 # usr.bin/gzip/gzip.c # usr.bin/gzip/unbzip2.c # usr.bin/gzip/zdiff # usr.bin/gzip/zdiff.1 # usr.bin/gzip/zforce # usr.bin/gzip/zforce.1 # usr.bin/gzip/zgrep # usr.bin/gzip/zgrep.1 # usr.bin/gzip/zmore # usr.bin/gzip/zmore.1 # usr.bin/gzip/znew # usr.bin/gzip/znew.1 # usr.bin/gzip/zuncompress.c # echo c - usr.bin/gzip mkdir -p usr.bin/gzip > /dev/null 2>&1 echo x - usr.bin/gzip/Makefile sed 's/^X//' >usr.bin/gzip/Makefile << 'END-of-usr.bin/gzip/Makefile' X# $NetBSD: Makefile,v 1.10 2006/05/12 02:01:15 mrg Exp $ X# $FreeBSD$ X XPROG= gzip XMAN= gzip.1 gzexe.1 zdiff.1 zforce.1 zgrep.1 zmore.1 znew.1 X XDPADD= ${LIBZ} ${LIBBZ2} XLDADD= -lz -lbz2 XWARNS?= 6 XWITH_GCC4= yes X XSCRIPTS= gzexe zdiff zforce zgrep zmore znew X XMLINKS+= gzip.1 gunzip.1 \ X gzip.1 gzcat.1 \ X gzip.1 zcat.1 \ X zdiff.1 zcmp.1 \ X zgrep.1 zegrep.1 \ X zgrep.1 zfgrep.1 X XLINKS+= ${BINDIR}/gzip ${BINDIR}/gunzip \ X ${BINDIR}/gzip ${BINDIR}/gzcat \ X ${BINDIR}/gzip ${BINDIR}/zcat \ X ${BINDIR}/zdiff ${BINDIR}/zcmp \ X ${BINDIR}/zgrep ${BINDIR}/zegrep \ X ${BINDIR}/zgrep ${BINDIR}/zfgrep X X.include END-of-usr.bin/gzip/Makefile echo x - usr.bin/gzip/gzexe sed 's/^X//' >usr.bin/gzip/gzexe << 'END-of-usr.bin/gzip/gzexe' X#!/bin/sh - X# X# $NetBSD: gzexe,v 1.3 2004/05/01 08:22:41 wiz Exp $ X# X# $OpenBSD: gzexe,v 1.3 2003/08/05 18:22:17 deraadt Exp $ X# X# Copyright (c) 2003 Otto Moerbeek X# X# Permission to use, copy, modify, and distribute this software for any X# purpose with or without fee is hereby granted, provided that the above X# copyright notice and this permission notice appear in all copies. X# X# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X# X# $FreeBSD$ X X# The number of lines plus one in the on-the-fly decompression script Xlines=19 X X# A simple string to recognize already compressed files Xmagic="# compressed by gzexe" X X# Write the decompression script to stdout Xheader () { X # first section needs variable expansion, second not X cat <<- EOF X #!/bin/sh - X $magic X lines=$lines X EOF X cat <<- 'EOF' X prog=`/usr/bin/basename "$0"` X tmp=`/usr/bin/mktemp -d /tmp/gzexeXXXXXXXXXX` || { X /bin/echo "$prog: cannot create tmp dir"; exit 1 X } X trap '/bin/rm -rf "$tmp"' 0 X if /usr/bin/tail +$lines "$0" | X /usr/bin/gzip -dc > "$tmp/$prog" 2> /dev/null; then X /bin/chmod u+x "$tmp/$prog" X "$tmp/$prog" ${1+"$@"} X ret=$? X else X /bin/echo "$prog: cannot decompress $0" X ret=1 X fi X exit $ret X EOF X} X X# Test if a file is compressed by checking the magic line Xcompressed () { X test "X`sed -n 2p "$1" 2> /dev/null`" = "X$magic" X} X X# Decompress a file Xdecompress () { X tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || { X echo "$prog: cannot create tmp file" X return 1 X } X if ! cp "$1" "$tmp"; then X echo "$prog: cannot copy $1 to $tmp" X rm -f "$tmp" X return 1 X fi X if ! tail +$lines "$tmp" | gzip -vdc > "$1"; then X echo "$prog: cannot decompress $1" X cp "$tmp" "$1" X rm -f "$tmp" X return 1 X fi X} X X# Perform some sanity checks on the file Xcheck () { X if test ! -e "$1"; then X echo "$prog: cannot compress non-existing file $1" X return 1 X fi X X if test ! -f "$1"; then X echo "$prog: cannot compress non-regular file $1" X return 1 X fi X X case `basename "$1"` in X sh | mktemp | rm | echo | tail | gzip | chmod) X echo "$prog: cannot compress $1, I depend on it" X return 1 X esac X X if test ! -x "$1"; then X echo "$prog: cannot compress $1, it is not executable" X return 1 X fi X X if test -u "$1" -o -g "$1"; then X echo "$prog: cannot compress $1, it has an s bit set" X return 1 X fi X} X X# Compress a file Xcompress () { X tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || { X echo "$prog: cannot create tmp file" X return 1 X } X if ! cp "$1" "$tmp"; then X echo "$prog: cannot copy $1 to $tmp" X rm -f "$tmp" X return 1 X fi X if ! cp "$1" "$1"~; then X echo "$prog: cannot create backup copy $1~" X rm -f "$1"~ "$tmp" X return 1 X fi X X # Use cp to overwrite the existing file preserving mode and owner X # if possible. If the file is not writable, this will produce an X # error. X X if header "$1" > "$tmp" && gzip -vc "$1" >> "$tmp"; then X if ! cp "$tmp" "$1"; then X echo "$prog: cannot copy $tmp to $1" X rm -f "$tmp" X return 1 X fi X else X echo "$prog: cannot compress $1" X rm -f "$1"~ "$tmp" X return 1 X fi X} X X# Is the -d flag specified? Xdflag= X X# Return value Xrc=0 X Xif test "X$1" = X-d; then X dflag=1 X shift Xfi X Xprog=`basename "$0"` XUSAGE="usage: $prog [-d] file ..." Xif test $# -eq 0; then X echo $USAGE X exit 1 Xfi X Xwhile test $# -ne 0; do X if test $dflag; then X if ! compressed "$1"; then X echo "$prog: $1 is not compressed" X rc=1; X elif ! decompress "$1"; then X rc=$? X fi X else X if compressed "$1"; then X echo "$prog: $1 is already compressed" X rc=1; X elif ! check "$1" || ! compress "$1"; then X rc=$? X fi X fi X shift Xdone Xexit $rc END-of-usr.bin/gzip/gzexe echo x - usr.bin/gzip/gzexe.1 sed 's/^X//' >usr.bin/gzip/gzexe.1 << 'END-of-usr.bin/gzip/gzexe.1' X.\" $NetBSD: gzexe.1,v 1.3 2003/12/28 12:49:41 wiz Exp $ X.\" $OpenBSD: gzexe.1,v 1.1 2003/07/31 07:32:47 otto Exp $ X.\" X.\" Copyright (c) 2003 Otto Moerbeek X.\" X.\" Permission to use, copy, modify, and distribute this software for any X.\" purpose with or without fee is hereby granted, provided that the above X.\" copyright notice and this permission notice appear in all copies. X.\" X.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X.\" X.\" $FreeBSD$ X.Dd October 3, 2006 X.Dt GZEXE 1 X.Os X.Sh NAME X.Nm gzexe X.Nd create auto-decompressing executables X.Sh SYNOPSIS X.Nm gzexe X.Op Fl d X.Ar X.Sh DESCRIPTION XThe X.Nm Xutility uses X.Xr gzip 1 Xto compress executables, producing executables that decompress on-the-fly Xwhen executed. XThis saves disk space, at the cost of slower execution times. XThe original executables are saved by copying each of them to a file with Xthe same name with a X.Sq ~ Xsuffix appended. XAfter verifying that the compressed executables work as expected, the backup Xfiles can be removed. X.Pp XThe options are as follows: X.Bl -tag -width Ds X.It Fl d XDecompress executables previously compressed by X.Nm . X.El X.Pp XThe X.Nm Xprogram refuses to compress non-regular or non-executable files, Xfiles with a setuid or setgid bit set, files that are already Xcompressed using X.Nm Xor programs it needs to perform on-the-fly decompression: X.Xr sh 1 , X.Xr mktemp 1 , X.Xr rm 1 , X.Xr echo 1 , X.Xr tail 1 , X.Xr gzip 1 , Xand X.Xr chmod 1 . X.Sh SEE ALSO X.Xr gzip 1 X.Sh CAVEATS XThe X.Nm Xutility replaces files by overwriting them with the generated Xcompressed executable. XTo be able to do this, it is required that the original files are writable. END-of-usr.bin/gzip/gzexe.1 echo x - usr.bin/gzip/gzip.1 sed 's/^X//' >usr.bin/gzip/gzip.1 << 'END-of-usr.bin/gzip/gzip.1' X.\" $NetBSD: gzip.1,v 1.18 2005/09/30 13:46:56 wiz Exp $ X.\" X.\" Copyright (c) 1997, 2003, 2004 Matthew R. Green X.\" All rights reserved. X.\" X.\" Redistribution and use in source and binary forms, with or without X.\" modification, are permitted provided that the following conditions X.\" are met: X.\" 1. Redistributions of source code must retain the above copyright X.\" notice, this list of conditions and the following disclaimer. X.\" 2. Redistributions in binary form must reproduce the above copyright X.\" notice, this list of conditions and the following disclaimer in the X.\" documentation and/or other materials provided with the distribution. X.\" 3. The name of the author may not be used to endorse or promote products X.\" derived from this software without specific prior written permission. X.\" X.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, X.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; X.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED X.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, X.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X.\" SUCH DAMAGE. X.\" X.\" $FreeBSD$ X.Dd October 3, 2006 X.Dt GZIP 1 X.Os X.Sh NAME X.Nm gzip X.Nd compression/decompression tool using Lempel-Ziv coding (LZ77) X.Sh SYNOPSIS X.Nm X.Op Fl cdfhlNnqrtVv X.Op Fl S Ar suffix X.Ar file X.Oo X.Ar file Oo ... X.Oc X.Oc X.Nm gunzip X.Op Fl cfhNqrtVv X.Op Fl S Ar suffix X.Ar file X.Oo X.Ar file Oo ... X.Oc X.Oc X.Nm zcat X.Op Fl fhV X.Ar file X.Oo X.Ar file Oo ... X.Oc X.Oc X.Sh DESCRIPTION XThe X.Nm Xprogram compresses and decompresses files using Lempel-Ziv coding X(LZ77). XIf no X.Ar files Xare specified, X.Nm Xwill compress from standard input, or decompress to standard output. XWhen in compression mode, each X.Ar file Xwill be replaced with another file with the suffix, set by the X.Fl S Ar suffix Xoption, added, if possible. XIn decompression mode, each X.Ar file Xwill be checked for existence, as will the file with the suffix Xadded. X.Pp XIf invoked as X.Nm gunzip Xthen the X.Fl d Xoption is enabled. XIf invoked as X.Nm zcat Xor X.Nm gzcat Xthen both the X.Fl c Xand X.Fl d Xoptions are enabled. X.Pp XThis version of X.Nm Xis also capable of decompressing files compressed using X.Xr compress 1 Xor X.Xr bzip2 1 . X.Sh OPTIONS XThe following options are available: X.Bl -tag -width XXrXXXrecursiveX X.It Fl 1 , -fast X.It Fl 2 , 3 , 4 , 5 , 6 , 7 , 8 X.It Fl 9 , -best XThese options change the compression level used, with the X.Fl 1 Xoption being the fastest, with less compression, and the X.Fl 9 Xoption being the slowest, with optimal compression. XThe default compression level is 6. X.It Fl c , -stdout , -to-stdout XThis option specifies that output will go to the standard output Xstream, leaving files intact. X.It Fl d , -decompress , -uncompress XThis option selects decompression rather than compression. X.It Fl f , -force XThis option turns on force mode. XThis allows files with multiple links, overwriting of pre-existing Xfiles, reading from or writing to a terminal, and when combined Xwith the X.Fl c Xoption, allowing non-compressed data to pass through unchanged. X.It Fl h , -help XThis option prints a usage summary and exits. X.It Fl l , -list XThis option displays information about the file's compressed and Xuncompressed size, ratio, uncompressed name. XWith the X.Fl v Xoption, it also displays the compression method, CRC, date and time Xembedded in the file. X.It Fl N , -name XThis option causes the stored filename in the input file to be used Xas the output file. X.It Fl n , -no-name XThis option stops the filename from being stored in the output Xfile. X.It Fl q , -quiet XWith this option, no warnings or errors are printed. X.It Fl r , -recursive XThis option is used to X.Nm Xthe files in a directory tree individually, using the X.Xr fts 3 Xlibrary. X.It Fl S Ar suffix , Fl -suffix Ar suffix XThis option changes the default suffix from .gz to X.Ar suffix . X.It Fl t , -test XThis option will test compressed files for integrity. X.It Fl V , -version XThis option prints the version of the X.Nm Xprogram. X.It Fl v , -verbose XThis option turns on verbose mode, which prints the compression Xratio for each file compressed. X.El X.Sh ENVIRONMENT XIf the environment variable X.Ev GZIP Xis set, it is parsed as a white-space separated list of options Xhandled before any options on the command line. XOptions on the command line will override anything in X.Ev GZIP . X.Sh SEE ALSO X.Xr bzip2 1 , X.Xr compress 1 , X.Xr fts 3 , X.Xr zlib 3 X.Sh HISTORY XThe X.Nm Xprogram was originally written by Jean-loup Gailly, licensed under Xthe GNU Public Licence. XMatthew R. Green wrote a simple front end for X.Nx 1.3 Xdistribution media, based on the freely re-distributable zlib library. XIt was enhanced to be mostly feature-compatible with the original XGNU X.Nm Xprogram for X.Nx 2.0 . X.Pp XThis implementation of X.Nm Xhas been first appeared in X.Fx 7.0 . X.Sh AUTHORS XThis implementation of X.Nm Xwas written by X.An Matthew R. Green Aq mrg@eterna.com.au . END-of-usr.bin/gzip/gzip.1 echo x - usr.bin/gzip/gzip.c sed 's/^X//' >usr.bin/gzip/gzip.c << 'END-of-usr.bin/gzip/gzip.c' X/* $NetBSD: gzip.c,v 1.85 2006/09/27 22:20:31 mrg Exp $ */ X X/*- X * Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. The name of the author may not be used to endorse or promote products X * derived from this software without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, X * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; X * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED X * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, X * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * $FreeBSD$ X */ X X#include X#ifndef lint X__COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green\n\ X All rights reserved.\n"); X__RCSID("$FreeBSD$"); X#endif /* not lint */ X X/* X * gzip.c -- GPL free gzip using zlib. X * X * RFC 1950 covers the zlib format X * RFC 1951 covers the deflate format X * RFC 1952 covers the gzip format X * X * TODO: X * - use mmap where possible X * - handle some signals better (remove outfile?) X * - make bzip2/compress -v/-t/-l support work as well as possible X */ X X#include X#include X#include X X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#ifndef PRIdOFF X#define PRIdOFF PRId64 X#endif X X/* what type of file are we dealing with */ Xenum filetype { X FT_GZIP, X#ifndef NO_BZIP2_SUPPORT X FT_BZIP2, X#endif X#ifndef NO_COMPRESS_SUPPORT X FT_Z, X#endif X FT_LAST, X FT_UNKNOWN X}; X X#ifndef NO_BZIP2_SUPPORT X#include X X#define BZ2_SUFFIX ".bz2" X#define BZIP2_MAGIC "\102\132\150" X#endif X X#ifndef NO_COMPRESS_SUPPORT X#define Z_SUFFIX ".Z" X#define Z_MAGIC "\037\235" X#endif X X#define GZ_SUFFIX ".gz" X X#define BUFLEN (64 * 1024) X X#define GZIP_MAGIC0 0x1F X#define GZIP_MAGIC1 0x8B X#define GZIP_OMAGIC1 0x9E X X#define GZIP_TIMESTAMP (off_t)4 X#define GZIP_ORIGNAME (off_t)10 X X#define HEAD_CRC 0x02 X#define EXTRA_FIELD 0x04 X#define ORIG_NAME 0x08 X#define COMMENT 0x10 X X#define OS_CODE 3 /* Unix */ X Xtypedef struct { X const char *zipped; X int ziplen; X const char *normal; /* for unzip - must not be longer than zipped */ X} suffixes_t; Xstatic suffixes_t suffixes[] = { X#define SUFFIX(Z, N) {Z, sizeof Z - 1, N} X SUFFIX(GZ_SUFFIX, ""), /* Overwritten by -S .xxx */ X#ifndef SMALL X SUFFIX(GZ_SUFFIX, ""), X SUFFIX(".z", ""), X SUFFIX("-gz", ""), X SUFFIX("-z", ""), X SUFFIX("_z", ""), X SUFFIX(".taz", ".tar"), X SUFFIX(".tgz", ".tar"), X#ifndef NO_BZIP2_SUPPORT X SUFFIX(BZ2_SUFFIX, ""), X#endif X#ifndef NO_COMPRESS_SUPPORT X SUFFIX(Z_SUFFIX, ""), X#endif X SUFFIX(GZ_SUFFIX, ""), /* Overwritten by -S "" */ X#endif /* SMALL */ X#undef SUFFIX X}; X#define NUM_SUFFIXES (sizeof suffixes / sizeof suffixes[0]) X Xstatic const char gzip_version[] = "NetBSD gzip 20060927"; X X#ifndef SMALL Xstatic const char gzip_copyright[] = " *\n"\ X" * Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green\n" X" * All rights reserved.\n" X" *\n" X" * Redistribution and use in source and binary forms, with or without\n" X" * modification, are permitted provided that the following conditions\n" X" * are met:\n" X" * 1. Redistributions of source code must retain the above copyright\n" X" * notice, this list of conditions and the following disclaimer.\n" X" * 2. Redistributions in binary form must reproduce the above copyright\n" X" * notice, this list of conditions and the following disclaimer in the\n" X" * documentation and/or other materials provided with the distribution.\n" X" * 3. The name of the author may not be used to endorse or promote products\n" X" * derived from this software without specific prior written permission.\n" X" *\n" X" * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n" X" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n" X" * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n" X" * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n" X" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n" X" * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" X" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n" X" * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n" X" * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n" X" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n" X" * SUCH DAMAGE.\n" X" *"; X#endif X Xstatic int cflag; /* stdout mode */ Xstatic int dflag; /* decompress mode */ Xstatic int lflag; /* list mode */ Xstatic int numflag = 6; /* gzip -1..-9 value */ X X#ifndef SMALL Xstatic int fflag; /* force mode */ Xstatic int nflag; /* don't save name/timestamp */ Xstatic int Nflag; /* don't restore name/timestamp */ Xstatic int qflag; /* quiet mode */ Xstatic int rflag; /* recursive mode */ Xstatic int tflag; /* test */ Xstatic int vflag; /* verbose mode */ X#else X#define qflag 0 X#define tflag 0 X#endif X Xstatic int exit_value = 0; /* exit value */ X Xstatic char *infile; /* name of file coming in */ X Xstatic void maybe_err(const char *fmt, ...) X __attribute__((__format__(__printf__, 1, 2))); X#ifndef NO_BZIP2_SUPPORT Xstatic void maybe_errx(const char *fmt, ...) X __attribute__((__format__(__printf__, 1, 2))); X#endif Xstatic void maybe_warn(const char *fmt, ...) X __attribute__((__format__(__printf__, 1, 2))); Xstatic void maybe_warnx(const char *fmt, ...) X __attribute__((__format__(__printf__, 1, 2))); Xstatic enum filetype file_gettype(u_char *); X#ifdef SMALL X#define gz_compress(if, of, sz, fn, tm) gz_compress(if, of, sz) X#endif Xstatic off_t gz_compress(int, int, off_t *, const char *, uint32_t); Xstatic off_t gz_uncompress(int, int, char *, size_t, off_t *, const char *); Xstatic off_t file_compress(char *, char *, size_t); Xstatic off_t file_uncompress(char *, char *, size_t); Xstatic void handle_pathname(char *); Xstatic void handle_file(char *, struct stat *); Xstatic void handle_stdin(void); Xstatic void handle_stdout(void); Xstatic void print_ratio(off_t, off_t, FILE *); Xstatic void print_list(int fd, off_t, const char *, time_t); Xstatic void usage(void); Xstatic void display_version(void); X#ifndef SMALL Xstatic void display_license(void); X#endif Xstatic const suffixes_t *check_suffix(char *, int); Xstatic ssize_t read_retry(int, void *, size_t); X X#ifdef SMALL X#define unlink_input(f, sb) unlink(f) X#else Xstatic off_t cat_fd(unsigned char *, size_t, off_t *, int fd); Xstatic void prepend_gzip(char *, int *, char ***); Xstatic void handle_dir(char *); Xstatic void print_verbage(const char *, const char *, off_t, off_t); Xstatic void print_test(const char *, int); Xstatic void copymodes(int fd, const struct stat *, const char *file); Xstatic int check_outfile(const char *outfile); X#endif X X#ifndef NO_BZIP2_SUPPORT Xstatic off_t unbzip2(int, int, char *, size_t, off_t *); X#endif X X#ifndef NO_COMPRESS_SUPPORT Xstatic FILE *zdopen(int); Xstatic off_t zuncompress(FILE *, FILE *, char *, size_t, off_t *); X#endif X Xint main(int, char **p); X X#ifdef SMALL X#define getopt_long(a,b,c,d,e) getopt(a,b,c) X#else Xstatic const struct option longopts[] = { X { "stdout", no_argument, 0, 'c' }, X { "to-stdout", no_argument, 0, 'c' }, X { "decompress", no_argument, 0, 'd' }, X { "uncompress", no_argument, 0, 'd' }, X { "force", no_argument, 0, 'f' }, X { "help", no_argument, 0, 'h' }, X { "list", no_argument, 0, 'l' }, X { "no-name", no_argument, 0, 'n' }, X { "name", no_argument, 0, 'N' }, X { "quiet", no_argument, 0, 'q' }, X { "recursive", no_argument, 0, 'r' }, X { "suffix", required_argument, 0, 'S' }, X { "test", no_argument, 0, 't' }, X { "verbose", no_argument, 0, 'v' }, X { "version", no_argument, 0, 'V' }, X { "fast", no_argument, 0, '1' }, X { "best", no_argument, 0, '9' }, X { "ascii", no_argument, 0, 'a' }, X { "license", no_argument, 0, 'L' }, X { NULL, no_argument, 0, 0 }, X}; X#endif X Xint Xmain(int argc, char **argv) X{ X const char *progname = getprogname(); X#ifndef SMALL X char *gzip; X int len; X#endif X int ch; X X /* XXX set up signals */ X X#ifndef SMALL X if ((gzip = getenv("GZIP")) != NULL) X prepend_gzip(gzip, &argc, &argv); X#endif X X /* X * XXX X * handle being called `gunzip', `zcat' and `gzcat' X */ X if (strcmp(progname, "gunzip") == 0) X dflag = 1; X else if (strcmp(progname, "zcat") == 0 || X strcmp(progname, "gzcat") == 0) X dflag = cflag = 1; X X#ifdef SMALL X#define OPT_LIST "123456789cdhltV" X#else X#define OPT_LIST "123456789acdfhlLNnqrS:tVv" X#endif X X while ((ch = getopt_long(argc, argv, OPT_LIST, longopts, NULL)) != -1) { X switch (ch) { X case '1': case '2': case '3': X case '4': case '5': case '6': X case '7': case '8': case '9': X numflag = ch - '0'; X break; X case 'c': X cflag = 1; X break; X case 'd': X dflag = 1; X break; X case 'l': X lflag = 1; X dflag = 1; X break; X case 'V': X display_version(); X /* NOTREACHED */ X#ifndef SMALL X case 'a': X fprintf(stderr, "%s: option --ascii ignored on this system\n", progname); X break; X case 'f': X fflag = 1; X break; X case 'L': X display_license(); X /* NOT REACHED */ X case 'N': X nflag = 0; X Nflag = 1; X break; X case 'n': X nflag = 1; X Nflag = 0; X break; X case 'q': X qflag = 1; X break; X case 'r': X rflag = 1; X break; X case 'S': X len = strlen(optarg); X if (len != 0) { X suffixes[0].zipped = optarg; X suffixes[0].ziplen = len; X } else { X suffixes[NUM_SUFFIXES - 1].zipped = ""; X suffixes[NUM_SUFFIXES - 1].ziplen = 0; X } X break; X case 't': X cflag = 1; X tflag = 1; X dflag = 1; X break; X case 'v': X vflag = 1; X break; X#endif X default: X usage(); X /* NOTREACHED */ X } X } X argv += optind; X argc -= optind; X X if (argc == 0) { X if (dflag) /* stdin mode */ X handle_stdin(); X else /* stdout mode */ X handle_stdout(); X } else { X do { X handle_pathname(argv[0]); X } while (*++argv); X } X#ifndef SMALL X if (qflag == 0 && lflag && argc > 1) X print_list(-1, 0, "(totals)", 0); X#endif X exit(exit_value); X} X X/* maybe print a warning */ Xvoid Xmaybe_warn(const char *fmt, ...) X{ X va_list ap; X X if (qflag == 0) { X va_start(ap, fmt); X vwarn(fmt, ap); X va_end(ap); X } X if (exit_value == 0) X exit_value = 1; X} X X/* ... without an errno. */ Xvoid Xmaybe_warnx(const char *fmt, ...) X{ X va_list ap; X X if (qflag == 0) { X va_start(ap, fmt); X vwarnx(fmt, ap); X va_end(ap); X } X if (exit_value == 0) X exit_value = 1; X} X X/* maybe print an error */ Xvoid Xmaybe_err(const char *fmt, ...) X{ X va_list ap; X X if (qflag == 0) { X va_start(ap, fmt); X vwarn(fmt, ap); X va_end(ap); X } X exit(2); X} X X#ifndef NO_BZIP2_SUPPORT X/* ... without an errno. */ Xvoid Xmaybe_errx(const char *fmt, ...) X{ X va_list ap; X X if (qflag == 0) { X va_start(ap, fmt); X vwarnx(fmt, ap); X va_end(ap); X } X exit(2); X} X#endif X X#ifndef SMALL X/* split up $GZIP and prepend it to the argument list */ Xstatic void Xprepend_gzip(char *gzip, int *argc, char ***argv) X{ X char *s, **nargv, **ac; X int nenvarg = 0, i; X X /* scan how many arguments there are */ X for (s = gzip;;) { X while (*s == ' ' || *s == '\t') X s++; X if (*s == 0) X goto count_done; X nenvarg++; X while (*s != ' ' && *s != '\t') X if (*s++ == 0) X goto count_done; X } Xcount_done: X /* punt early */ X if (nenvarg == 0) X return; X X *argc += nenvarg; X ac = *argv; X X nargv = (char **)malloc((*argc + 1) * sizeof(char *)); X if (nargv == NULL) X maybe_err("malloc"); X X /* stash this away */ X *argv = nargv; X X /* copy the program name first */ X i = 0; X nargv[i++] = *(ac++); X X /* take a copy of $GZIP and add it to the array */ X s = strdup(gzip); X if (s == NULL) X maybe_err("strdup"); X for (;;) { X /* Skip whitespaces. */ X while (*s == ' ' || *s == '\t') X s++; X if (*s == 0) X goto copy_done; X nargv[i++] = s; X /* Find the end of this argument. */ X while (*s != ' ' && *s != '\t') X if (*s++ == 0) X /* Argument followed by NUL. */ X goto copy_done; X /* Terminate by overwriting ' ' or '\t' with NUL. */ X *s++ = 0; X } Xcopy_done: X X /* copy the original arguments and a NULL */ X while (*ac) X nargv[i++] = *(ac++); X nargv[i] = NULL; X} X#endif X X/* compress input to output. Return bytes read, -1 on error */ Xstatic off_t Xgz_compress(int in, int out, off_t *gsizep, const char *origname, uint32_t mtime) X{ X z_stream z; X char *outbufp, *inbufp; X off_t in_tot = 0, out_tot = 0; X ssize_t in_size; X int i, error; X uLong crc; X#ifdef SMALL X static char header[] = { GZIP_MAGIC0, GZIP_MAGIC1, Z_DEFLATED, 0, X 0, 0, 0, 0, X 0, OS_CODE }; X#endif X X outbufp = malloc(BUFLEN); X inbufp = malloc(BUFLEN); X if (outbufp == NULL || inbufp == NULL) { X maybe_err("malloc failed"); X goto out; X } X X memset(&z, 0, sizeof z); X z.zalloc = Z_NULL; X z.zfree = Z_NULL; X z.opaque = 0; X X#ifdef SMALL X memcpy(outbufp, header, sizeof header); X i = sizeof header; X#else X if (nflag != 0) { X mtime = 0; X origname = ""; X } X X i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c%c%c%s", X GZIP_MAGIC0, GZIP_MAGIC1, Z_DEFLATED, X *origname ? ORIG_NAME : 0, X mtime & 0xff, X (mtime >> 8) & 0xff, X (mtime >> 16) & 0xff, X (mtime >> 24) & 0xff, X numflag == 1 ? 4 : numflag == 9 ? 2 : 0, X OS_CODE, origname); X if (i >= BUFLEN) X /* this need PATH_MAX > BUFLEN ... */ X maybe_err("snprintf"); X if (*origname) X i++; X#endif X X z.next_out = (unsigned char *)outbufp + i; X z.avail_out = BUFLEN - i; X X error = deflateInit2(&z, numflag, Z_DEFLATED, X (-MAX_WBITS), 8, Z_DEFAULT_STRATEGY); X if (error != Z_OK) { X maybe_warnx("deflateInit2 failed"); X in_tot = -1; X goto out; X } X X crc = crc32(0L, Z_NULL, 0); X for (;;) { X if (z.avail_out == 0) { X if (write(out, outbufp, BUFLEN) != BUFLEN) { X maybe_warn("write"); X in_tot = -1; X goto out; X } X X out_tot += BUFLEN; X z.next_out = (unsigned char *)outbufp; X z.avail_out = BUFLEN; X } X X if (z.avail_in == 0) { X in_size = read(in, inbufp, BUFLEN); X if (in_size < 0) { X maybe_warn("read"); X in_tot = -1; X goto out; X } X if (in_size == 0) X break; X X crc = crc32(crc, (const Bytef *)inbufp, (unsigned)in_size); X in_tot += in_size; X z.next_in = (unsigned char *)inbufp; X z.avail_in = in_size; X } X X error = deflate(&z, Z_NO_FLUSH); X if (error != Z_OK && error != Z_STREAM_END) { X maybe_warnx("deflate failed"); X in_tot = -1; X goto out; X } X } X X /* clean up */ X for (;;) { X size_t len; X ssize_t w; X X error = deflate(&z, Z_FINISH); X if (error != Z_OK && error != Z_STREAM_END) { X maybe_warnx("deflate failed"); X in_tot = -1; X goto out; X } X X len = (char *)z.next_out - outbufp; X X w = write(out, outbufp, len); X if (w == -1 || (size_t)w != len) { X maybe_warn("write"); X out_tot = -1; X goto out; X } X out_tot += len; X z.next_out = (unsigned char *)outbufp; X z.avail_out = BUFLEN; X X if (error == Z_STREAM_END) X break; X } X X if (deflateEnd(&z) != Z_OK) { X maybe_warnx("deflateEnd failed"); X in_tot = -1; X goto out; X } X X i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c", X (int)crc & 0xff, X (int)(crc >> 8) & 0xff, X (int)(crc >> 16) & 0xff, X (int)(crc >> 24) & 0xff, X (int)in_tot & 0xff, X (int)(in_tot >> 8) & 0xff, X (int)(in_tot >> 16) & 0xff, X (int)(in_tot >> 24) & 0xff); X if (i != 8) X maybe_err("snprintf"); X if (write(out, outbufp, i) != i) { X maybe_warn("write"); X in_tot = -1; X } else X out_tot += i; X Xout: X if (inbufp != NULL) X free(inbufp); X if (outbufp != NULL) X free(outbufp); X if (gsizep) X *gsizep = out_tot; X return in_tot; X} X X/* X * uncompress input to output then close the input. return the X * uncompressed size written, and put the compressed sized read X * into `*gsizep'. X */ Xstatic off_t Xgz_uncompress(int in, int out, char *pre, size_t prelen, off_t *gsizep, X const char *filename) X{ X z_stream z; X char *outbufp, *inbufp; X off_t out_tot = -1, in_tot = 0; X uint32_t out_sub_tot = 0; X enum { X GZSTATE_MAGIC0, X GZSTATE_MAGIC1, X GZSTATE_METHOD, X GZSTATE_FLAGS, X GZSTATE_SKIPPING, X GZSTATE_EXTRA, X GZSTATE_EXTRA2, X GZSTATE_EXTRA3, X GZSTATE_ORIGNAME, X GZSTATE_COMMENT, X GZSTATE_HEAD_CRC1, X GZSTATE_HEAD_CRC2, X GZSTATE_INIT, X GZSTATE_READ, X GZSTATE_CRC, X GZSTATE_LEN, X } state = GZSTATE_MAGIC0; X int flags = 0, skip_count = 0; X int error = Z_STREAM_ERROR, done_reading = 0; X uLong crc = 0; X ssize_t wr; X int needmore = 0; X X#define ADVANCE() { z.next_in++; z.avail_in--; } X X if ((outbufp = malloc(BUFLEN)) == NULL) { X maybe_err("malloc failed"); X goto out2; X } X if ((inbufp = malloc(BUFLEN)) == NULL) { X maybe_err("malloc failed"); X goto out1; X } X X memset(&z, 0, sizeof z); X z.avail_in = prelen; X z.next_in = (unsigned char *)pre; X z.avail_out = BUFLEN; X z.next_out = (unsigned char *)outbufp; X z.zalloc = NULL; X z.zfree = NULL; X z.opaque = 0; X X in_tot = prelen; X out_tot = 0; X X for (;;) { X if ((z.avail_in == 0 || needmore) && done_reading == 0) { X ssize_t in_size; X X if (z.avail_in > 0) { X memmove(inbufp, z.next_in, z.avail_in); X } X z.next_in = (unsigned char *)inbufp; X in_size = read(in, z.next_in + z.avail_in, X BUFLEN - z.avail_in); X X if (in_size == -1) { X maybe_warn("failed to read stdin"); X goto stop_and_fail; X } else if (in_size == 0) { X done_reading = 1; X } X X z.avail_in += in_size; X needmore = 0; X X in_tot += in_size; X } X if (z.avail_in == 0) { X if (done_reading && state != GZSTATE_MAGIC0) X maybe_warnx("%s: unexpected end of file", X filename); X goto stop; X } X switch (state) { X case GZSTATE_MAGIC0: X if (*z.next_in != GZIP_MAGIC0) { X maybe_warnx("input not gziped (MAGIC0)"); X goto stop_and_fail; X } X ADVANCE(); X state++; X out_sub_tot = 0; X crc = crc32(0L, Z_NULL, 0); X break; X X case GZSTATE_MAGIC1: X if (*z.next_in != GZIP_MAGIC1 && X *z.next_in != GZIP_OMAGIC1) { X maybe_warnx("input not gziped (MAGIC1)"); X goto stop_and_fail; X } X ADVANCE(); X state++; X break; X X case GZSTATE_METHOD: X if (*z.next_in != Z_DEFLATED) { X maybe_warnx("unknown compression method"); X goto stop_and_fail; X } X ADVANCE(); X state++; X break; X X case GZSTATE_FLAGS: X flags = *z.next_in; X ADVANCE(); X skip_count = 6; X state++; X break; X X case GZSTATE_SKIPPING: X if (skip_count > 0) { X skip_count--; X ADVANCE(); X } else X state++; X break; X X case GZSTATE_EXTRA: X if ((flags & EXTRA_FIELD) == 0) { X state = GZSTATE_ORIGNAME; X break; X } X skip_count = *z.next_in; X ADVANCE(); X state++; X break; X X case GZSTATE_EXTRA2: X skip_count |= ((*z.next_in) << 8); X ADVANCE(); X state++; X break; X X case GZSTATE_EXTRA3: X if (skip_count > 0) { X skip_count--; X ADVANCE(); X } else X state++; X break; X X case GZSTATE_ORIGNAME: X if ((flags & ORIG_NAME) == 0) { X state++; X break; X } X if (*z.next_in == 0) X state++; X ADVANCE(); X break; X X case GZSTATE_COMMENT: X if ((flags & COMMENT) == 0) { X state++; X break; X } X if (*z.next_in == 0) X state++; X ADVANCE(); X break; X X case GZSTATE_HEAD_CRC1: X if (flags & HEAD_CRC) X skip_count = 2; X else X skip_count = 0; X state++; X break; X X case GZSTATE_HEAD_CRC2: X if (skip_count > 0) { X skip_count--; X ADVANCE(); X } else X state++; X break; X X case GZSTATE_INIT: X if (inflateInit2(&z, -MAX_WBITS) != Z_OK) { X maybe_warnx("failed to inflateInit"); X goto stop_and_fail; X } X state++; X break; X X case GZSTATE_READ: X error = inflate(&z, Z_FINISH); X switch (error) { X /* Z_BUF_ERROR goes with Z_FINISH... */ X case Z_BUF_ERROR: X case Z_STREAM_END: X case Z_OK: X break; X X case Z_NEED_DICT: X maybe_warnx("Z_NEED_DICT error"); X goto stop_and_fail; X case Z_DATA_ERROR: X maybe_warnx("data stream error"); X goto stop_and_fail; X case Z_STREAM_ERROR: X maybe_warnx("internal stream error"); X goto stop_and_fail; X case Z_MEM_ERROR: X maybe_warnx("memory allocation error"); X goto stop_and_fail; X X default: X maybe_warn("unknown error from inflate(): %d", X error); X } X wr = BUFLEN - z.avail_out; X X if (wr != 0) { X crc = crc32(crc, (const Bytef *)outbufp, (unsigned)wr); X if ( X#ifndef SMALL X /* don't write anything with -t */ X tflag == 0 && X#endif X write(out, outbufp, wr) != wr) { X maybe_warn("error writing to output"); X goto stop_and_fail; X } X X out_tot += wr; X out_sub_tot += wr; X } X X if (error == Z_STREAM_END) { X inflateEnd(&z); X state++; X } X X z.next_out = (unsigned char *)outbufp; X z.avail_out = BUFLEN; X X break; X case GZSTATE_CRC: X { X uLong origcrc; X X if (z.avail_in < 4) { X if (!done_reading) { X needmore = 1; X continue; X } X maybe_warnx("truncated input"); X goto stop_and_fail; X } X origcrc = ((unsigned)z.next_in[0] & 0xff) | X ((unsigned)z.next_in[1] & 0xff) << 8 | X ((unsigned)z.next_in[2] & 0xff) << 16 | X ((unsigned)z.next_in[3] & 0xff) << 24; X if (origcrc != crc) { X maybe_warnx("invalid compressed" X " data--crc error"); X goto stop_and_fail; X } X } X X z.avail_in -= 4; X z.next_in += 4; X X if (!z.avail_in && done_reading) { X goto stop; X } X state++; X break; X case GZSTATE_LEN: X { X uLong origlen; X X if (z.avail_in < 4) { X if (!done_reading) { X needmore = 1; X continue; X } X maybe_warnx("truncated input"); X goto stop_and_fail; X } X origlen = ((unsigned)z.next_in[0] & 0xff) | X ((unsigned)z.next_in[1] & 0xff) << 8 | X ((unsigned)z.next_in[2] & 0xff) << 16 | X ((unsigned)z.next_in[3] & 0xff) << 24; X X if (origlen != out_sub_tot) { X maybe_warnx("invalid compressed" X " data--length error"); X goto stop_and_fail; X } X } X X z.avail_in -= 4; X z.next_in += 4; X X if (error < 0) { X maybe_warnx("decompression error"); X goto stop_and_fail; X } X state = GZSTATE_MAGIC0; X break; X } X continue; Xstop_and_fail: X out_tot = -1; Xstop: X break; X } X if (state > GZSTATE_INIT) X inflateEnd(&z); X X free(inbufp); Xout1: X free(outbufp); Xout2: X if (gsizep) X *gsizep = in_tot; X return (out_tot); X} X X#ifndef SMALL X/* X * set the owner, mode, flags & utimes using the given file descriptor. X * file is only used in possible warning messages. X */ Xstatic void Xcopymodes(int fd, const struct stat *sbp, const char *file) X{ X struct timeval times[2]; X struct stat sb; X X /* X * If we have no info on the input, give this file some X * default values and return.. X */ X if (sbp == NULL) { X mode_t mask = umask(022); X X (void)fchmod(fd, DEFFILEMODE & ~mask); X (void)umask(mask); X return; X } X sb = *sbp; X X /* if the chown fails, remove set-id bits as-per compress(1) */ X if (fchown(fd, sb.st_uid, sb.st_gid) < 0) { X if (errno != EPERM) X maybe_warn("couldn't fchown: %s", file); X sb.st_mode &= ~(S_ISUID|S_ISGID); X } X X /* we only allow set-id and the 9 normal permission bits */ X sb.st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO; X if (fchmod(fd, sb.st_mode) < 0) X maybe_warn("couldn't fchmod: %s", file); X X /* only try flags if they exist already */ X if (sb.st_flags != 0 && fchflags(fd, sb.st_flags) < 0) X maybe_warn("couldn't fchflags: %s", file); X X TIMESPEC_TO_TIMEVAL(×[0], &sb.st_atimespec); X TIMESPEC_TO_TIMEVAL(×[1], &sb.st_mtimespec); X if (futimes(fd, times) < 0) X maybe_warn("couldn't utimes: %s", file); X} X#endif X X/* what sort of file is this? */ Xstatic enum filetype Xfile_gettype(u_char *buf) X{ X X if (buf[0] == GZIP_MAGIC0 && X (buf[1] == GZIP_MAGIC1 || buf[1] == GZIP_OMAGIC1)) X return FT_GZIP; X else X#ifndef NO_BZIP2_SUPPORT X if (memcmp(buf, BZIP2_MAGIC, 3) == 0 && X buf[3] >= '0' && buf[3] <= '9') X return FT_BZIP2; X else X#endif X#ifndef NO_COMPRESS_SUPPORT X if (memcmp(buf, Z_MAGIC, 2) == 0) X return FT_Z; X else X#endif X return FT_UNKNOWN; X} X X#ifndef SMALL X/* check the outfile is OK. */ Xstatic int Xcheck_outfile(const char *outfile) X{ X struct stat sb; X int ok = 1; X X if (lflag == 0 && stat(outfile, &sb) == 0) { X if (fflag) X unlink(outfile); X else if (isatty(STDIN_FILENO)) { X char ans[10] = { 'n', '\0' }; /* default */ X X fprintf(stderr, "%s already exists -- do you wish to " X "overwrite (y or n)? " , outfile); X (void)fgets(ans, sizeof(ans) - 1, stdin); X if (ans[0] != 'y' && ans[0] != 'Y') { X fprintf(stderr, "\tnot overwritting\n"); X ok = 0; X } else X unlink(outfile); X } else { X maybe_warnx("%s already exists -- skipping", outfile); X ok = 0; X } X } X return ok; X} X Xstatic void Xunlink_input(const char *file, const struct stat *sb) X{ X struct stat nsb; X X if (stat(file, &nsb) != 0) X /* Must be gone alrady */ X return; X if (nsb.st_dev != sb->st_dev || nsb.st_ino != sb->st_ino) X /* Definitely a different file */ X return; X unlink(file); X} X#endif X Xstatic const suffixes_t * Xcheck_suffix(char *file, int xlate) X{ X const suffixes_t *s; X int len = strlen(file); X char *sp; X X for (s = suffixes; s != suffixes + NUM_SUFFIXES; s++) { X /* if it doesn't fit in "a.suf", don't bother */ X if (s->ziplen >= len) X continue; X sp = file + len - s->ziplen; X if (strcmp(s->zipped, sp) != 0) X continue; X if (xlate) X strcpy(sp, s->normal); X return s; X } X return NULL; X} X X/* X * compress the given file: create a corresponding .gz file and remove the X * original. X */ Xstatic off_t Xfile_compress(char *file, char *outfile, size_t outsize) X{ X int in; X int out; X off_t size, insize; X#ifndef SMALL X struct stat isb, osb; X const suffixes_t *suff; X#endif X X in = open(file, O_RDONLY); X if (in == -1) { X maybe_warn("can't open %s", file); X return -1; X } X X if (cflag == 0) { X#ifndef SMALL X if (fstat(in, &isb) == 0) { X if (isb.st_nlink > 1 && fflag == 0) { X maybe_warnx("%s has %d other link%s -- " X "skipping", file, isb.st_nlink - 1, X isb.st_nlink == 1 ? "" : "s"); X close(in); X return -1; X } X } X X if (fflag == 0 && (suff = check_suffix(file, 0)) X && suff->zipped[0] != 0) { X maybe_warnx("%s already has %s suffix -- unchanged", X file, suff->zipped); X close(in); X return -1; X } X#endif X X /* Add (usually) .gz to filename */ X if ((size_t)snprintf(outfile, outsize, "%s%s", X file, suffixes[0].zipped) >= outsize) X memcpy(outfile - suffixes[0].ziplen - 1, X suffixes[0].zipped, suffixes[0].ziplen + 1); X X#ifndef SMALL X if (check_outfile(outfile) == 0) { X close(in); X return -1; X } X#endif X } X X if (cflag == 0) { X out = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0600); X if (out == -1) { X maybe_warn("could not create output: %s", outfile); X fclose(stdin); X return -1; X } X } else X out = STDOUT_FILENO; X X insize = gz_compress(in, out, &size, basename(file), (uint32_t)isb.st_mtime); X X (void)close(in); X X /* X * If there was an error, insize will be -1. X * If we compressed to stdout, just return the size. X * Otherwise stat the file and check it is the correct size. X * We only blow away the file if we can stat the output and it X * has the expected size. X */ X if (cflag != 0) X return insize == -1 ? -1 : size; X X#ifndef SMALL X if (fstat(out, &osb) != 0) { X maybe_warn("couldn't stat: %s", outfile); X goto bad_outfile; X } X X if (osb.st_size != size) { X maybe_warnx("output file: %s wrong size (%" PRIdOFF X " != %" PRIdOFF "), deleting", X outfile, osb.st_size, size); X goto bad_outfile; X } X X copymodes(out, &isb, outfile); X#endif X if (close(out) == -1) X maybe_warn("couldn't close output"); X X /* output is good, ok to delete input */ X unlink_input(file, &isb); X return size; X X#ifndef SMALL X bad_outfile: X if (close(out) == -1) X maybe_warn("couldn't close output"); X X maybe_warnx("leaving original %s", file); X unlink(outfile); X return size; X#endif X} X X/* uncompress the given file and remove the original */ Xstatic off_t Xfile_uncompress(char *file, char *outfile, size_t outsize) X{ X struct stat isb, osb; X off_t size; X ssize_t rbytes; X unsigned char header1[4]; X enum filetype method; X int rv, fd, ofd, zfd = -1; X#ifndef SMALL X time_t timestamp = 0; X unsigned char name[PATH_MAX + 1]; X#endif X X /* gather the old name info */ X X fd = open(file, O_RDONLY); X if (fd < 0) { X maybe_warn("can't open %s", file); X goto lose; X } X X strlcpy(outfile, file, outsize); X if (check_suffix(outfile, 1) == NULL && !(cflag || lflag)) { X maybe_warnx("%s: unknown suffix -- ignored", file); X goto lose; X } X X rbytes = read(fd, header1, sizeof header1); X if (rbytes != sizeof header1) { X /* we don't want to fail here. */ X#ifndef SMALL X if (fflag) X goto lose; X#endif X if (rbytes == -1) X maybe_warn("can't read %s", file); X else X goto unexpected_EOF; X goto lose; X } X X method = file_gettype(header1); X X#ifndef SMALL X if (fflag == 0 && method == FT_UNKNOWN) { X maybe_warnx("%s: not in gzip format", file); X goto lose; X } X X#endif X X#ifndef SMALL X if (method == FT_GZIP && Nflag) { X unsigned char ts[4]; /* timestamp */ X X rv = pread(fd, ts, sizeof ts, GZIP_TIMESTAMP); X if (rv >= 0 && (size_t)rv < sizeof ts) X goto unexpected_EOF; X if (rv == -1) { X if (!fflag) X maybe_warn("can't read %s", file); X goto lose; X } X timestamp = ts[3] << 24 | ts[2] << 16 | ts[1] << 8 | ts[0]; X X if (header1[3] & ORIG_NAME) { X rbytes = pread(fd, name, sizeof name, GZIP_ORIGNAME); X if (rbytes < 0) { X maybe_warn("can't read %s", file); X goto lose; X } X if (name[0] != 0) { X /* preserve original directory name */ X char *dp = strrchr(file, '/'); X if (dp == NULL) X dp = file; X else X dp++; X snprintf(outfile, outsize, "%.*s%.*s", X (int) (dp - file), X file, (int) rbytes, name); X } X } X } X#endif X lseek(fd, 0, SEEK_SET); X X if (cflag == 0 || lflag) { X if (fstat(fd, &isb) != 0) X goto lose; X#ifndef SMALL X if (isb.st_nlink > 1 && lflag == 0 && fflag == 0) { X maybe_warnx("%s has %d other links -- skipping", X file, isb.st_nlink - 1); X goto lose; X } X if (nflag == 0 && timestamp) X isb.st_mtime = timestamp; X if (check_outfile(outfile) == 0) X goto lose; X#endif X } X X if (cflag == 0 && lflag == 0) { X zfd = open(outfile, O_WRONLY|O_CREAT|O_EXCL, 0600); X if (zfd == STDOUT_FILENO) { X /* We won't close STDOUT_FILENO later... */ X zfd = dup(zfd); X close(STDOUT_FILENO); X } X if (zfd == -1) { X maybe_warn("can't open %s", outfile); X goto lose; X } X } else X zfd = STDOUT_FILENO; X X#ifndef NO_BZIP2_SUPPORT X if (method == FT_BZIP2) { X X /* XXX */ X if (lflag) { X maybe_warnx("no -l with bzip2 files"); X goto lose; X } X X size = unbzip2(fd, zfd, NULL, 0, NULL); X } else X#endif X X#ifndef NO_COMPRESS_SUPPORT X if (method == FT_Z) { X FILE *in, *out; X X /* XXX */ X if (lflag) { X maybe_warnx("no -l with Lempel-Ziv files"); X goto lose; X } X X if ((in = zdopen(fd)) == NULL) { X maybe_warn("zdopen for read: %s", file); X goto lose; X } X X out = fdopen(dup(zfd), "w"); X if (out == NULL) { X maybe_warn("fdopen for write: %s", outfile); X fclose(in); X goto lose; X } X X size = zuncompress(in, out, NULL, 0, NULL); X /* need to fclose() if ferror() is true... */ X if (ferror(in) | fclose(in)) { X maybe_warn("failed infile fclose"); X unlink(outfile); X (void)fclose(out); X } X if (fclose(out) != 0) { X maybe_warn("failed outfile fclose"); X unlink(outfile); X goto lose; X } X } else X#endif X X#ifndef SMALL X if (method == FT_UNKNOWN) { X if (lflag) { X maybe_warnx("no -l for unknown filetypes"); X goto lose; X } X size = cat_fd(NULL, 0, NULL, fd); X } else X#endif X { X if (lflag) { X print_list(fd, isb.st_size, outfile, isb.st_mtime); X close(fd); X return -1; /* XXX */ X } X X size = gz_uncompress(fd, zfd, NULL, 0, NULL, file); X } X X if (close(fd) != 0) X maybe_warn("couldn't close input"); X if (zfd != STDOUT_FILENO && close(zfd) != 0) X maybe_warn("couldn't close output"); X X if (size == -1) { X if (cflag == 0) X unlink(outfile); X maybe_warnx("%s: uncompress failed", file); X return -1; X } X X /* if testing, or we uncompressed to stdout, this is all we need */ X#ifndef SMALL X if (tflag) X return size; X#endif X /* if we are uncompressing to stdin, don't remove the file. */ X if (cflag) X return size; X X /* X * if we create a file... X */ X /* X * if we can't stat the file don't remove the file. X */ X X ofd = open(outfile, O_RDWR, 0); X if (ofd == -1) { X maybe_warn("couldn't open (leaving original): %s", X outfile); X return -1; X } X if (fstat(ofd, &osb) != 0) { X maybe_warn("couldn't stat (leaving original): %s", X outfile); X close(ofd); X return -1; X } X if (osb.st_size != size) { X maybe_warnx("stat gave different size: %" PRIdOFF X " != %" PRIdOFF " (leaving original)", X size, osb.st_size); X close(ofd); X unlink(outfile); X return -1; X } X unlink_input(file, &isb); X#ifndef SMALL X copymodes(ofd, &isb, outfile); X#endif X close(ofd); X return size; X X unexpected_EOF: X maybe_warnx("%s: unexpected end of file", file); X lose: X if (fd != -1) X close(fd); X if (zfd != -1 && zfd != STDOUT_FILENO) X close(fd); X return -1; X} X X#ifndef SMALL Xstatic off_t Xcat_fd(unsigned char * prepend, size_t count, off_t *gsizep, int fd) X{ X char buf[BUFLEN]; X off_t in_tot; X ssize_t w; X X in_tot = count; X w = write(STDOUT_FILENO, prepend, count); X if (w == -1 || (size_t)w != count) { X maybe_warn("write to stdout"); X return -1; X } X for (;;) { X ssize_t rv; X X rv = read(fd, buf, sizeof buf); X if (rv == 0) X break; X if (rv < 0) { X maybe_warn("read from fd %d", fd); X break; X } X X if (write(STDOUT_FILENO, buf, rv) != rv) { X maybe_warn("write to stdout"); X break; X } X in_tot += rv; X } X X if (gsizep) X *gsizep = in_tot; X return (in_tot); X} X#endif X Xstatic void Xhandle_stdin(void) X{ X unsigned char header1[4]; X off_t usize, gsize; X enum filetype method; X ssize_t bytes_read; X#ifndef NO_COMPRESS_SUPPORT X FILE *in; X#endif X X#ifndef SMALL X if (fflag == 0 && lflag == 0 && isatty(STDIN_FILENO)) { X maybe_warnx("standard input is a terminal -- ignoring"); X return; X } X#endif X X if (lflag) { X struct stat isb; X X /* XXX could read the whole file, etc. */ X if (fstat(STDIN_FILENO, &isb) < 0) { X maybe_warn("fstat"); X return; X } X print_list(STDIN_FILENO, isb.st_size, "stdout", isb.st_mtime); X return; X } X X bytes_read = read_retry(STDIN_FILENO, header1, sizeof header1); X if (bytes_read == -1) { X maybe_warn("can't read stdin"); X return; X } else if (bytes_read != sizeof(header1)) { X maybe_warnx("(stdin): unexpected end of file"); X return; X } X X method = file_gettype(header1); X switch (method) { X default: X#ifndef SMALL X if (fflag == 0) { X maybe_warnx("unknown compression format"); X return; X } X usize = cat_fd(header1, sizeof header1, &gsize, STDIN_FILENO); X break; X#endif X case FT_GZIP: X usize = gz_uncompress(STDIN_FILENO, STDOUT_FILENO, X (char *)header1, sizeof header1, &gsize, "(stdin)"); X break; X#ifndef NO_BZIP2_SUPPORT X case FT_BZIP2: X usize = unbzip2(STDIN_FILENO, STDOUT_FILENO, X (char *)header1, sizeof header1, &gsize); X break; X#endif X#ifndef NO_COMPRESS_SUPPORT X case FT_Z: X if ((in = zdopen(STDIN_FILENO)) == NULL) { X maybe_warnx("zopen of stdin"); X return; X } X X usize = zuncompress(in, stdout, (char *)header1, sizeof header1, &gsize); X fclose(in); X break; X#endif X } X X#ifndef SMALL X if (vflag && !tflag && usize != -1 && gsize != -1) X print_verbage(NULL, NULL, usize, gsize); X if (vflag && tflag) X print_test("(stdin)", usize != -1); X#endif X X} X Xstatic void Xhandle_stdout(void) X{ X off_t gsize, usize; X struct stat sb; X time_t systime; X uint32_t mtime; X int ret; X X#ifndef SMALL X if (fflag == 0 && isatty(STDOUT_FILENO)) { X maybe_warnx("standard output is a terminal -- ignoring"); X return; X } X#endif X /* If stdin is a file use it's mtime, otherwise use current time */ X ret = fstat(STDIN_FILENO, &sb); X X#ifndef SMALL X if (ret < 0) { X maybe_warn("Can't stat stdin"); X return; X } X#endif X X if (S_ISREG(sb.st_mode)) X mtime = (uint32_t)sb.st_mtime; X else { X systime = time(NULL); X#ifndef SMALL X if (systime == -1) { X maybe_warn("time"); X return; X } X#endif X mtime = (uint32_t)systime; X } X X usize = gz_compress(STDIN_FILENO, STDOUT_FILENO, &gsize, "", mtime); X#ifndef SMALL X if (vflag && !tflag && usize != -1 && gsize != -1) X print_verbage(NULL, NULL, usize, gsize); X#endif X} X X/* do what is asked for, for the path name */ Xstatic void Xhandle_pathname(char *path) X{ X char *opath = path, *s = NULL; X ssize_t len; X int slen; X struct stat sb; X X /* check for stdout/stdin */ X if (path[0] == '-' && path[1] == '\0') { X if (dflag) X handle_stdin(); X else X handle_stdout(); X return; X } X Xretry: X if (stat(path, &sb) != 0) { X /* lets try .gz if we're decompressing */ X if (dflag && s == NULL && errno == ENOENT) { X len = strlen(path); X slen = suffixes[0].ziplen; X s = malloc(len + slen + 1); X if (s == NULL) X maybe_err("malloc"); X memcpy(s, path, len); X memcpy(s + len, suffixes[0].zipped, slen + 1); X path = s; X goto retry; X } X maybe_warn("can't stat: %s", opath); X goto out; X } X X if (S_ISDIR(sb.st_mode)) { X#ifndef SMALL X if (rflag) X handle_dir(path); X else X#endif X maybe_warnx("%s is a directory", path); X goto out; X } X X if (S_ISREG(sb.st_mode)) X handle_file(path, &sb); X else X maybe_warnx("%s is not a regular file", path); X Xout: X if (s) X free(s); X} X X/* compress/decompress a file */ Xstatic void Xhandle_file(char *file, struct stat *sbp) X{ X off_t usize, gsize; X char outfile[PATH_MAX]; X X infile = file; X if (dflag) { X usize = file_uncompress(file, outfile, sizeof(outfile)); X#ifndef SMALL X if (vflag && tflag) X print_test(file, usize != -1); X#endif X if (usize == -1) X return; X gsize = sbp->st_size; X } else { X gsize = file_compress(file, outfile, sizeof(outfile)); X if (gsize == -1) X return; X usize = sbp->st_size; X } X X X#ifndef SMALL X if (vflag && !tflag) X print_verbage(file, (cflag) ? NULL : outfile, usize, gsize); X#endif X} X X#ifndef SMALL X/* this is used with -r to recursively descend directories */ Xstatic void Xhandle_dir(char *dir) X{ X char *path_argv[2]; X FTS *fts; X FTSENT *entry; X X path_argv[0] = dir; X path_argv[1] = 0; X fts = fts_open(path_argv, FTS_PHYSICAL, NULL); X if (fts == NULL) { X warn("couldn't fts_open %s", dir); X return; X } X X while ((entry = fts_read(fts))) { X switch(entry->fts_info) { X case FTS_D: X case FTS_DP: X continue; X X case FTS_DNR: X case FTS_ERR: X case FTS_NS: X maybe_warn("%s", entry->fts_path); X continue; X case FTS_F: X handle_file(entry->fts_name, entry->fts_statp); X } X } X (void)fts_close(fts); X} X#endif X X/* print a ratio - size reduction as a fraction of uncompressed size */ Xstatic void Xprint_ratio(off_t in, off_t out, FILE *where) X{ X int percent10; /* 10 * percent */ X off_t diff; X char buff[8]; X int len; X X diff = in - out/2; X if (diff <= 0) X /* X * Output is more than double size of input! print -99.9% X * Quite possibly we've failed to get the original size. X */ X percent10 = -999; X else { X /* X * We only need 12 bits of result from the final division, X * so reduce the values until a 32bit division will suffice. X */ X while (in > 0x100000) { X diff >>= 1; X in >>= 1; X } X if (in != 0) X percent10 = ((u_int)diff * 2000) / (u_int)in - 1000; X else X percent10 = 0; X } X X len = snprintf(buff, sizeof buff, "%2.2d.", percent10); X /* Move the '.' to before the last digit */ X buff[len - 1] = buff[len - 2]; X buff[len - 2] = '.'; X fprintf(where, "%5s%%", buff); X} X X#ifndef SMALL X/* print compression statistics, and the new name (if there is one!) */ Xstatic void Xprint_verbage(const char *file, const char *nfile, off_t usize, off_t gsize) X{ X if (file) X fprintf(stderr, "%s:%s ", file, X strlen(file) < 7 ? "\t\t" : "\t"); X print_ratio(usize, gsize, stderr); X if (nfile) X fprintf(stderr, " -- replaced with %s", nfile); X fprintf(stderr, "\n"); X fflush(stderr); X} X X/* print test results */ Xstatic void Xprint_test(const char *file, int ok) X{ X X if (exit_value == 0 && ok == 0) X exit_value = 1; X fprintf(stderr, "%s:%s %s\n", file, X strlen(file) < 7 ? "\t\t" : "\t", ok ? "OK" : "NOT OK"); X fflush(stderr); X} X#endif X X/* print a file's info ala --list */ X/* eg: X compressed uncompressed ratio uncompressed_name X 354841 1679360 78.8% /usr/pkgsrc/distfiles/libglade-2.0.1.tar X*/ Xstatic void Xprint_list(int fd, off_t out, const char *outfile, time_t ts) X{ X static int first = 1; X#ifndef SMALL X static off_t in_tot, out_tot; X uint32_t crc = 0; X#endif X off_t in = 0, rv; X X if (first) { X#ifndef SMALL X if (vflag) X printf("method crc date time "); X#endif X if (qflag == 0) X printf(" compressed uncompressed " X "ratio uncompressed_name\n"); X } X first = 0; X X /* print totals? */ X#ifndef SMALL X if (fd == -1) { X in = in_tot; X out = out_tot; X } else X#endif X { X /* read the last 4 bytes - this is the uncompressed size */ X rv = lseek(fd, (off_t)(-8), SEEK_END); X if (rv != -1) { X unsigned char buf[8]; X uint32_t usize; X X rv = read(fd, (char *)buf, sizeof(buf)); X if (rv == -1) X maybe_warn("read of uncompressed size"); X else if (rv != sizeof(buf)) X maybe_warnx("read of uncompressed size"); X X else { X usize = buf[4] | buf[5] << 8 | X buf[6] << 16 | buf[7] << 24; X in = (off_t)usize; X#ifndef SMALL X crc = buf[0] | buf[1] << 8 | X buf[2] << 16 | buf[3] << 24; X#endif X } X } X } X X#ifndef SMALL X if (vflag && fd == -1) X printf(" "); X else if (vflag) { X char *date = ctime(&ts); X X /* skip the day, 1/100th second, and year */ X date += 4; X date[12] = 0; X printf("%5s %08x %11s ", "defla"/*XXX*/, crc, date); X } X in_tot += in; X out_tot += out; X#endif X printf("%12llu %12llu ", (unsigned long long)out, (unsigned long long)in); X print_ratio(in, out, stdout); X printf(" %s\n", outfile); X} X X/* display the usage of NetBSD gzip */ Xstatic void Xusage(void) X{ X X fprintf(stderr, "%s\n", gzip_version); X fprintf(stderr, X "usage: %s [-" OPT_LIST "] [ [ ...]]\n" X#ifndef SMALL X " -1 --fast fastest (worst) compression\n" X " -2 .. -8 set compression level\n" X " -9 --best best (slowest) compression\n" X " -c --stdout write to stdout, keep original files\n" X " --to-stdout\n" X " -d --decompress uncompress files\n" X " --uncompress\n" X " -f --force force overwriting & compress links\n" X " -h --help display this help\n" X " -l --list list compressed file contents\n" X " -N --name save or restore original file name and time stamp\n" X " -n --no-name don't save original file name or time stamp\n" X " -q --quiet output no warnings\n" X " -r --recursive recursively compress files in directories\n" X " -S .suf use suffix .suf instead of .gz\n" X " --suffix .suf\n" X " -t --test test compressed file\n" X " -V --version display program version\n" X " -v --verbose print extra statistics\n", X#else X , X#endif X getprogname()); X exit(0); X} X X#ifndef SMALL X/* display the license information of NetBSD gzip */ Xstatic void Xdisplay_license(void) X{ X X fprintf(stderr, "%s\n", gzip_version); X fprintf(stderr, "%s\n", gzip_copyright); X exit(0); X} X#endif X X/* display the version of NetBSD gzip */ Xstatic void Xdisplay_version(void) X{ X X fprintf(stderr, "%s\n", gzip_version); X exit(0); X} X X#ifndef NO_BZIP2_SUPPORT X#include "unbzip2.c" X#endif X#ifndef NO_COMPRESS_SUPPORT X#include "zuncompress.c" X#endif X Xstatic ssize_t Xread_retry(int fd, void *buf, size_t sz) X{ X char *cp = buf; X size_t left = MIN(sz, (size_t) SSIZE_MAX); X X while (left > 0) { X ssize_t ret; X X ret = read(fd, cp, left); X if (ret == -1) { X return ret; X } else if (ret == 0) { X break; /* EOF */ X } X cp += ret; X left -= ret; X } X X return sz - left; X} X END-of-usr.bin/gzip/gzip.c echo x - usr.bin/gzip/unbzip2.c sed 's/^X//' >usr.bin/gzip/unbzip2.c << 'END-of-usr.bin/gzip/unbzip2.c' X/* $NetBSD: unbzip2.c,v 1.10 2006/10/03 08:20:03 simonb Exp $ */ X X/*- X * Copyright (c) 2006 The NetBSD Foundation, Inc. X * All rights reserved. X * X * This code is derived from software contributed to The NetBSD Foundation X * by Simon Burge. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by the NetBSD X * Foundation, Inc. and its contributors. X * 4. Neither the name of The NetBSD Foundation nor the names of its X * contributors may be used to endorse or promote products derived X * from this software without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS X * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED X * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR X * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS X * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF X * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS X * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN X * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) X * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE X * POSSIBILITY OF SUCH DAMAGE. X * X * $FreeBSD$ X */ X X/* This file is #included by gzip.c */ X Xstatic off_t Xunbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) X{ X int ret, end_of_file; X off_t bytes_out = 0; X bz_stream bzs; X static char *inbuf, *outbuf; X X if (inbuf == NULL) X inbuf = malloc(BUFLEN); X if (outbuf == NULL) X outbuf = malloc(BUFLEN); X if (inbuf == NULL || outbuf == NULL) X maybe_err("malloc"); X X bzs.bzalloc = NULL; X bzs.bzfree = NULL; X bzs.opaque = NULL; X X end_of_file = 0; X ret = BZ2_bzDecompressInit(&bzs, 0, 0); X if (ret != BZ_OK) X maybe_errx("bzip2 init"); X X /* Prepend. */ X bzs.avail_in = prelen; X bzs.next_in = pre; X X if (bytes_in) X *bytes_in = prelen; X X while (ret >= BZ_OK && ret != BZ_STREAM_END) { X if (bzs.avail_in == 0 && !end_of_file) { X ssize_t n; X X n = read(in, inbuf, BUFLEN); X if (n < 0) X maybe_err("read"); X if (n == 0) X end_of_file = 1; X bzs.next_in = inbuf; X bzs.avail_in = n; X if (bytes_in) X *bytes_in += n; X } X X bzs.next_out = outbuf; X bzs.avail_out = BUFLEN; X ret = BZ2_bzDecompress(&bzs); X X switch (ret) { X case BZ_STREAM_END: X case BZ_OK: X if (ret == BZ_OK && end_of_file) X maybe_err("read"); X if (!tflag) { X ssize_t n; X X n = write(out, outbuf, BUFLEN - bzs.avail_out); X if (n < 0) X maybe_err("write"); X bytes_out += n; X } X break; X X case BZ_DATA_ERROR: X maybe_warnx("bzip2 data integrity error"); X break; X X case BZ_DATA_ERROR_MAGIC: X maybe_warnx("bzip2 magic number error"); X break; X X case BZ_MEM_ERROR: X maybe_warnx("bzip2 out of memory"); X break; X X } X } X X if (ret != BZ_STREAM_END || BZ2_bzDecompressEnd(&bzs) != BZ_OK) X return (-1); X X return (bytes_out); X} END-of-usr.bin/gzip/unbzip2.c echo x - usr.bin/gzip/zdiff sed 's/^X//' >usr.bin/gzip/zdiff << 'END-of-usr.bin/gzip/zdiff' X#!/bin/sh - X# X# $NetBSD: zdiff,v 1.3 2004/03/29 10:01:00 wiz Exp $ X# $OpenBSD: zdiff,v 1.2 2003/07/29 07:42:44 otto Exp $ X# X#- X# Copyright (c) 2003 Todd C. Miller X# X# Permission to use, copy, modify, and distribute this software for any X# purpose with or without fee is hereby granted, provided that the above X# copyright notice and this permission notice appear in all copies. X# X# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X# X# Sponsored in part by the Defense Advanced Research Projects X# Agency (DARPA) and Air Force Research Laboratory, Air Force X# Materiel Command, USAF, under agreement number F39502-99-1-0512. X# X# $FreeBSD$ X X# Set $prog based on $0 Xcase $0 in X *cmp) prog=cmp X ;; X *) prog=diff X ;; Xesac XUSAGE="usage: z$prog [options] file1 [file2]" X X# Pull out any command line flags so we can pass them to diff/cmp X# XXX - assumes there is no optarg Xflags= Xwhile test $# -ne 0; do X case "$1" in X --) X shift X break X ;; X -*) X flags="$flags $1" X shift X ;; X *) X break X ;; X esac Xdone X Xif [ $# -eq 1 ]; then X # One file given, compare compressed to uncompressed X files="$1" X case "$1" in X *[._-][Zz]) X files="${1%??}" X ;; X *[._-]gz) X files="${1%???}" X ;; X *.t[ag]z) X files="${1%??}"ar X ;; X *) echo "z$prog: unknown suffix" 1>&2 X exit 1 X esac X gzip -cdfq "$1" | $prog $flags - "$files" X status=$? Xelif [ $# -eq 2 ]; then X # Two files given, compare the two uncompressing as needed X case "$1" in X *[._-][Zz]|*[._-]gz|*.t[ag]z) X files=- X filt="gzip -cdfq $1" X ;; X *) X files="$1" X ;; X esac X case "$2" in X *[._-][Zz]|*[._-]gz|*.t[ag]z) X if [ "$files" = "-" ]; then X tmp=`mktemp -t z$prog.XXXXXXXXXX` || exit 1 X trap "rm -f $tmp" 0 1 2 3 13 15 X gzip -cdfq "$2" > $tmp X files="$files $tmp" X else X files="$files -" X filt="gzip -cdfq $2" X fi X ;; X *) X files="$files $2" X ;; X esac X if [ -n "$filt" ]; then X $filt | $prog $flags $files X else X $prog $flags $files X fi X status=$? Xelse X echo "$USAGE" 1>&2 X exit 1 Xfi X Xexit $status END-of-usr.bin/gzip/zdiff echo x - usr.bin/gzip/zdiff.1 sed 's/^X//' >usr.bin/gzip/zdiff.1 << 'END-of-usr.bin/gzip/zdiff.1' X.\" $NetBSD: zdiff.1,v 1.3 2003/12/28 12:48:03 wiz Exp $ X.\" $OpenBSD: zdiff.1,v 1.2 2003/07/13 17:39:14 millert Exp $ X.\" X.\" Copyright (c) 2003 Todd C. Miller X.\" X.\" Permission to use, copy, modify, and distribute this software for any X.\" purpose with or without fee is hereby granted, provided that the above X.\" copyright notice and this permission notice appear in all copies. X.\" X.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X.\" X.\" Sponsored in part by the Defense Advanced Research Projects X.\" Agency (DARPA) and Air Force Research Laboratory, Air Force X.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. X.\" X.\" $FreeBSD$ X.Dd October 3, 2006 X.Dt ZDIFF 1 X.Os X.Sh NAME X.Nm zcmp , X.Nm zdiff X.Nd compare compressed files X.Sh SYNOPSIS X.Nm zcmp X.Op Ar options X.Ar file X.Op Ar file2 X.Nm zdiff X.Op Ar options X.Ar file X.Op Ar file2 X.Sh DESCRIPTION X.Nm zcmp Xand X.Nm zdiff Xare filters that invoke X.Xr cmp 1 Xor X.Xr diff 1 Xrespectively to compare compressed files. XSuch files generally have a X.Dq Z Xor X.Dq gz Xextension (both the X.Xr compress 1 Xand X.Xr gzip 1 Xformats are supported). XAny X.Ar options Xthat are specified are passed to X.Xr cmp 1 Xor X.Xr diff 1 . X.Pp XIf only X.Ar file1 Xis specified, it is compared against a file with the same name, but Xwith the extension removed. XWhen both X.Ar file1 Xor X.Ar file2 Xare specified, either file may be compressed. X.Sh ENVIRONMENT X.Bl -tag -width "TMPDIR" X.It Ev TMPDIR XDirectory in which to place temporary files. XIf unset, X.Pa /tmp Xis used. X.El X.Sh FILES X.Bl -tag -width "/tmp/zdiff.XXXXXXXXXX" -compact X.It Pa /tmp/zcmp.XXXXXXXXXX XTemporary file for X.Nm zcmp . X.It Pa /tmp/zdiff.XXXXXXXXXX XTemporary file for X.Nm zdiff . X.El X.Sh SEE ALSO X.Xr cmp 1 , X.Xr compress 1 , X.Xr diff 1 X.Sh CAVEATS X.Nm zcmp Xand X.Nm zdiff Xrely solely on the file extension to determine what is, or is not, Xa compressed file. XConsequently, the following are not supported as arguments: X.Bl -dash X.It Xdirectories X.It Xdevice special files X.It Xfilenames indicating the standard input X.Pq Dq \- X.El END-of-usr.bin/gzip/zdiff.1 echo x - usr.bin/gzip/zforce sed 's/^X//' >usr.bin/gzip/zforce << 'END-of-usr.bin/gzip/zforce' X#!/bin/sh - X# X# $NetBSD: zforce,v 1.2 2003/12/28 12:43:43 wiz Exp $ X# $OpenBSD: zforce,v 1.2 2003/08/05 18:22:17 deraadt Exp $ X# X#- X# Copyright (c) 2003 Otto Moerbeek X# X# Permission to use, copy, modify, and distribute this software for any X# purpose with or without fee is hereby granted, provided that the above X# copyright notice and this permission notice appear in all copies. X# X# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X# X# $FreeBSD$ Xprog=`basename $0` XUSAGE="usage: $prog file ..." Xif test $# -eq 0; then X echo $USAGE X exit 1 Xfi X Xret=0 X Xwhile test $# -ne 0; do X case "$1" in X *[._-]gz) X shift X ;; X *.t[ag]z) X shift X ;; X *) X if file "$1" | X grep -q "gzip compressed data" 2> /dev/null X then X n="$1".gz X if mv "$1" "$n" 2> /dev/null; then X echo "$1" -- renamed to "$n" X else X ret=1 X echo $prog: cannot rename "$1" to "$n" X fi X fi X shift X ;; X esac Xdone Xexit $ret END-of-usr.bin/gzip/zforce echo x - usr.bin/gzip/zforce.1 sed 's/^X//' >usr.bin/gzip/zforce.1 << 'END-of-usr.bin/gzip/zforce.1' X.\" $NetBSD: zforce.1,v 1.2 2003/12/28 12:43:43 wiz Exp $ X.\" $OpenBSD: zforce.1,v 1.1 2003/07/29 11:50:09 otto Exp $ X.\" X.\" Copyright (c) 2003 Otto Moerbeek X.\" X.\" Permission to use, copy, modify, and distribute this software for any X.\" purpose with or without fee is hereby granted, provided that the above X.\" copyright notice and this permission notice appear in all copies. X.\" X.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X.\" X.\" $FreeBSD$ X.Dd October 3, 2006 X.Dt ZFORCE 1 X.Os X.Sh NAME X.Nm zforce X.Nd force gzip files to have a .gz suffix X.Sh SYNOPSIS X.Nm zforce X.Ar X.Sh DESCRIPTION XThe X.Nm Xutility renames X.Xr gzip 1 Xfiles to have a X.Sq .gz Xsuffix, so that X.Xr gzip 1 Xwill not compress them twice. XThis can be useful if file names were truncated during a file transfer. XFiles that have an existing X.Sq .gz , X.Sq -gz , X.Sq _gz , X.Sq .tgz Xor X.Sq .taz Xsuffix, or that have not been compressed by X.Xr gzip 1 , Xare ignored. X.Sh SEE ALSO X.Xr gzip 1 X.Sh CAVEATS X.Nm Xoverwrites existing files without warning. END-of-usr.bin/gzip/zforce.1 echo x - usr.bin/gzip/zgrep sed 's/^X//' >usr.bin/gzip/zgrep << 'END-of-usr.bin/gzip/zgrep' X#!/bin/sh X# X# $NetBSD: zgrep,v 1.5 2006/05/03 16:48:29 yamt Exp $ X# X# Copyright (c) 2003 Thomas Klausner. X# X# Redistribution and use in source and binary forms, with or without X# modification, are permitted provided that the following conditions X# are met: X# 1. Redistributions of source code must retain the above copyright X# notice, this list of conditions and the following disclaimer. X# 2. Redistributions in binary form must reproduce the above copyright X# notice, this list of conditions and the following disclaimer in the X# documentation and/or other materials provided with the distribution. X# 3. The name of the author may not be used to endorse or promote products X# derived from this software without specific prior written permission. X# X# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X# X# $FreeBSD$ X Xgrep=/usr/bin/grep Xzcat=/usr/bin/zcat X Xendofopts=0 Xpattern_found=0 Xgrep_args="" Xhyphen=0 X Xprg=$0 X X# handle being called 'zegrep' or 'zfgrep' Xcase ${prg} in X *zegrep) X grep_args="-E";; X *zfgrep) X grep_args="-F";; Xesac X X# skip all options and pass them on to grep taking care of options X# with arguments, and if -e was supplied X Xwhile [ $# -gt 0 -a ${endofopts} -eq 0 ] Xdo X case $1 in X # from GNU grep-2.5.1 -- keep in sync! X -[ABCDXdefm]) X if [ $# -lt 2 ] X then X echo "${prg}: missing argument for $1 flag" >&2 X exit 1 X fi X case $1 in X -e) X pattern="$2" X pattern_found=1 X shift 2 X break X ;; X *) X ;; X esac X grep_args="${grep_args} $1 $2" X shift 2 X ;; X --) X shift X endofopts=1 X ;; X -) X hyphen=1 X shift X ;; X -*) X grep_args="${grep_args} $1" X shift X ;; X *) X # pattern to grep for X endofopts=1 X ;; X esac Xdone X X# if no -e option was found, take next argument as grep-pattern Xif [ ${pattern_found} -lt 1 ] Xthen X if [ $# -ge 1 ]; then X pattern="$1" X shift X elif [ ${hyphen} -gt 0 ]; then X pattern="-" X else X echo "${prg}: missing pattern" >&2 X exit 1 X fi Xfi X X# call grep ... Xif [ $# -lt 1 ] Xthen X # ... on stdin X ${zcat} -fq - | ${grep} ${grep_args} -- "${pattern}" - Xelse X # ... on all files given on the command line X while [ $# -gt 0 ] X do X ${zcat} -fq -- "$1" | ${grep} -H --label="${1}" ${grep_args} -- "${pattern}" - X shift X done Xfi X Xexit 0 END-of-usr.bin/gzip/zgrep echo x - usr.bin/gzip/zgrep.1 sed 's/^X//' >usr.bin/gzip/zgrep.1 << 'END-of-usr.bin/gzip/zgrep.1' X.\" $NetBSD: zgrep.1,v 1.2 2005/09/11 23:30:20 wiz Exp $ X.\" X.\" Copyright (c) 2003 Thomas Klausner. X.\" X.\" Redistribution and use in source and binary forms, with or without X.\" modification, are permitted provided that the following conditions X.\" are met: X.\" 1. Redistributions of source code must retain the above copyright X.\" notice, this list of conditions and the following disclaimer. X.\" 2. Redistributions in binary form must reproduce the above copyright X.\" notice, this list of conditions and the following disclaimer in the X.\" documentation and/or other materials provided with the distribution. X.\" 3. The name of the author may not be used to endorse or promote products X.\" derived from this software without specific prior written permission. X.\" X.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X.\" X.\" $FreeBSD$ X.Dd October 3, 2006 X.Dt ZGREP 1 X.Os X.Sh NAME X.Nm zgrep , X.Nm zegrep , X.Nm zfgrep X.Nd print lines matching a pattern in gzip-compressed files X.Sh SYNOPSIS X.Nm X.Op Ar grep-flags X.Op Fl - X.Ar pattern X.Op Ar files ... X.Pp X.Nm zegrep X.Op Ar grep-flags X.Op Fl - X.Ar pattern X.Op Ar X.Pp X.Nm zfgrep X.Op Ar grep-flags X.Op Fl - X.Ar pattern X.Op Ar X.Sh DESCRIPTION X.Nm Xruns X.Xr grep 1 Xon X.Ar files Xor stdin, if no X.Ar files Xargument is given, after decompressing them with X.Xr zcat 1 . X.Pp XThe X.Ar grep-flags Xand X.Ar pattern Xarguments are passed on to X.Xr grep 1 . XIf an X.Fl e Xflag is found in the X.Ar grep-flags , X.Nm Xwill not look for a X.Ar pattern Xargument. X.Pp X.Nm zegrep Xcalls X.Xr egrep 1 , Xwhile X.Nm zfgrep Xcalls X.Xr fgrep 1 . X.Sh EXIT STATUS XIn case of missing arguments or missing pattern, X1 will be returned, otherwise 0. X.Sh SEE ALSO X.Xr egrep 1 , X.Xr fgrep 1 , X.Xr grep 1 , X.Xr gzip 1 , X.Xr zcat 1 X.Sh AUTHORS X.An Thomas Klausner X.Aq wiz@NetBSD.org END-of-usr.bin/gzip/zgrep.1 echo x - usr.bin/gzip/zmore sed 's/^X//' >usr.bin/gzip/zmore << 'END-of-usr.bin/gzip/zmore' X#!/bin/sh - X# X# $NetBSD: zmore,v 1.3 2004/03/29 09:59:42 wiz Exp $ X# $OpenBSD: zmore,v 1.4 2003/07/29 07:42:45 otto Exp $ X# X#- X# Copyright (c) 2003 Todd C. Miller X# X# Permission to use, copy, modify, and distribute this software for any X# purpose with or without fee is hereby granted, provided that the above X# copyright notice and this permission notice appear in all copies. X# X# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X# X# Sponsored in part by the Defense Advanced Research Projects X# Agency (DARPA) and Air Force Research Laboratory, Air Force X# Materiel Command, USAF, under agreement number F39502-99-1-0512. X# X# $FreeBSD$ X X# Pull out any command line flags so we can pass them to more/less Xflags= Xwhile test $# -ne 0; do X case "$1" in X --) X shift X break X ;; X -*) X flags="$flags $1" X shift X ;; X *) X break X ;; X esac Xdone X X# No files means read from stdin Xif [ $# -eq 0 ]; then X gzip -cdfq 2>&1 | ${PAGER-more} $flags X exit 0 Xfi X Xoterm=`stty -g 2>/dev/null` Xwhile test $# -ne 0; do X gzip -cdfq "$1" 2>&1 | ${PAGER-more} $flags X prev="$1" X shift X if tty -s && test -n "$oterm" -a $# -gt 0; then X #echo -n "--More--(Next file: $1)" X echo -n "$prev (END) - Next: $1 " X trap "stty $oterm 2>/dev/null" 0 1 2 3 13 15 X stty cbreak -echo 2>/dev/null X REPLY=`dd bs=1 count=1 2>/dev/null` X stty $oterm 2>/dev/null X trap - 0 1 2 3 13 15 X echo X case "$REPLY" in X s) X shift X ;; X e|q) X break X ;; X esac X fi Xdone Xexit 0 END-of-usr.bin/gzip/zmore echo x - usr.bin/gzip/zmore.1 sed 's/^X//' >usr.bin/gzip/zmore.1 << 'END-of-usr.bin/gzip/zmore.1' X.\" $NetBSD: zmore.1,v 1.3 2003/12/28 12:47:52 wiz Exp $ X.\" $OpenBSD: zmore.1,v 1.3 2003/06/23 21:00:48 deraadt Exp $ X.\" X.\" Copyright (c) 2003 Todd C. Miller X.\" X.\" Permission to use, copy, modify, and distribute this software for any X.\" purpose with or without fee is hereby granted, provided that the above X.\" copyright notice and this permission notice appear in all copies. X.\" X.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X.\" X.\" Sponsored in part by the Defense Advanced Research Projects X.\" Agency (DARPA) and Air Force Research Laboratory, Air Force X.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. X.\" X.\" $FreeBSD$ X.Dd October 3, 2006 X.Dt ZMORE 1 X.Os X.Sh NAME X.Nm zmore X.Nd view compressed files on a CRT X.Sh SYNOPSIS X.Nm zmore X.Op Ar flags X.Op Ar file ... X.Sh DESCRIPTION X.Nm Xis a filter that allows the viewing of files compressed with Lempel-Ziv Xencoding. XSuch files generally have a X.Dq Z Xor X.Dq gz Xextension (both the X.Xr compress 1 Xand X.Xr gzip 1 Xformats are supported). XAny X.Ar flags Xthat are specified are passed to the user's preferred X.Ev PAGER X(which is X.Pa /usr/bin/more Xby default). X.Pp XWhen multiple files are specified, X.Nm Xwill pause at the end of each file and present the following prompt to the user: X.Bd -literal -offset indent Xprev_file (END) - Next: next_file X.Ed X.Pp XWhere X.Sy prev_file Xis the file that was just displayed and X.Sy next_file Xis the next file to be displayed. XThe following keys are recognized at the prompt: X.Bl -tag -width "e or q" -offset indent X.It Ic e No or Ic q Xquit X.Nm zmore . X.It Ic s Xskip the next file (or exit if the next file is the last). X.El X.Pp XIf no files are specified, X.Nm Xwill read from the standard input. XIn this mode X.Nm Xwill assume X.Xr gzip 1 Xstyle compression since there is no suffix on which to make a decision. X.Sh ENVIRONMENT X.Bl -tag -width "PAGER" X.It Ev PAGER XProgram used to display files. XIf unset, X.Pa /usr/bin/more Xis used. X.El X.Sh SEE ALSO X.Xr compress 1 , X.Xr less 1 , X.Xr more 1 END-of-usr.bin/gzip/zmore.1 echo x - usr.bin/gzip/znew sed 's/^X//' >usr.bin/gzip/znew << 'END-of-usr.bin/gzip/znew' X#!/bin/ksh - X# X# $NetBSD: znew,v 1.2 2003/12/28 12:43:43 wiz Exp $ X# $OpenBSD: znew,v 1.2 2003/08/05 18:22:17 deraadt Exp $ X# X#- X# Copyright (c) 2003 Otto Moerbeek X# X# Permission to use, copy, modify, and distribute this software for any X# purpose with or without fee is hereby granted, provided that the above X# copyright notice and this permission notice appear in all copies. X# X# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X# X# $FreeBSD$ X X# Return 0 if the first arg file size is smaller than the second, 1 otherwise. Xsmaller () { X a=`du -k "$1" | awk '{ print $1 }'` X b=`du -k "$2" | awk '{ print $1 }'` X test $a -lt $b X} X X# Check gzip integrity if the -t flag is specified Xcheckfile () { X if test $tflag -eq 1; then X gzip -qt < "$1" X fi X} X X# Decompress a file and then gzip it Xprocess () { X prefix="${1%.Z}" X filez="$prefix".Z X filegz="$prefix".gz X X if test ! -e "$filez"; then X echo "$prog: $filez does not exist" X return 1 X fi X if test ! -f "$filez"; then X echo "$prog: $filez is not a regular file" X return 1 X fi X if test -e "$filegz" -a $fflag -eq 0; then X echo "$prog: $filegz already exists" X return 1 X fi X X tmp=`mktemp /tmp/znewXXXXXXXXXX` || { X echo "$prog: cannot create tmp file" X return 1 X } X trap 'rm -f "$tmp"; exit 1' HUP INT QUIT PIPE TERM X X # Do the actual work, producing a file "$tmp" X if uncompress -f -c < "$filez" | gzip -f $gzipflags -o "$tmp"; then X X if test $kflag -eq 1 && smaller "$filez" "$tmp"; then X echo -n "$prog: $filez is smaller than $filegz" X echo "; keeping it" X rm -f "$tmp" X return 0 X fi X if ! checkfile "$tmp"; then X echo "$prog: integrity check of $tmp failed" X rm -f "$tmp" X return 1; X fi X X # Try to keep the mode of the original file X if ! cp -fp "$filez" "$filegz"; then X echo "$prog: warning: could not keep mode of $filez" X fi X if ! cp "$tmp" "$filegz" 2> /dev/null; then X echo "$prog: warning: could not keep mode of $filez" X if ! cp -f "$tmp" "$filegz" 2> /dev/null; then X echo "$prog: could not copy $tmp to $filegz" X rm -f "$filegz" "$tmp" X return 1 X fi X fi X if ! touch -fr "$filez" "$filegz"; then X echo -n "$prog: warning: could not keep timestamp of " X echo "$filez" X fi X rm -f "$filez" "$tmp" X else X echo "$prog: failed to process $filez" X rm -f "$tmp" X return 1 X fi X} X Xprog=`basename "$0"` Xusage="usage: $prog [-ftv9K] file ..." X Xfflag=0 Xtflag=0 Xkflag=0 Xgzipflags= X X# -P flag is recognized to maintain compatibility, but ignored. Pipe mode is X# always used Xwhile getopts :ftv9PK i; do X case $i in X f) fflag=1;; X t) tflag=1;; X v) gzipflags="-v $gzipflags";; X 9) gzipflags="-9 $gzipflags";; X P) ;; X K) kflag=1;; X \?) echo "$usage"; exit 1;; X esac Xdone X Xshift OPTIND-1 X Xif test $# -eq 0; then X echo "$usage" X exit 1 Xfi X Xrc=0 X Xwhile test $# -ne 0; do X if ! process "$1"; then X rc=$? X fi X shift Xdone Xexit $rc END-of-usr.bin/gzip/znew echo x - usr.bin/gzip/znew.1 sed 's/^X//' >usr.bin/gzip/znew.1 << 'END-of-usr.bin/gzip/znew.1' X.\" $NetBSD: znew.1,v 1.2 2003/12/28 12:43:43 wiz Exp $ X.\" $OpenBSD: znew.1,v 1.1 2003/08/02 20:52:50 otto Exp $ X.\" X.\" Copyright (c) 2003 Otto Moerbeek X.\" X.\" Permission to use, copy, modify, and distribute this software for any X.\" purpose with or without fee is hereby granted, provided that the above X.\" copyright notice and this permission notice appear in all copies. X.\" X.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES X.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF X.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR X.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES X.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN X.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X.\" X.\" $FreeBSD$ X.Dd October 3, 2006 X.Dt ZNEW 1 X.Os X.Sh NAME X.Nm znew X.Nd convert compressed files to gzipped files X.Sh SYNOPSIS X.Nm X.Op Fl ftv9K X.Ar X.Sh DESCRIPTION XThe X.Nm Xutility uncompresses files compressed by X.Xr compress 1 Xand recompresses them with X.Xr gzip 1 . X.Pp XThe options are as follows: X.Bl -tag -width Ds X.It Fl f XOverwrite existing X.Sq .gz Xfiles. XUnless this option is specified, X.Nm Xrefuses to overwrite existing files. X.It Fl t XTest integrity of the gzipped file before deleting the original file. XIf the integrity check fails, the original X.Sq .Z Xfile is not removed. X.It Fl v XPrint a report specifying the achieved compression ratios. X.It Fl 9 XUse the -9 mode of X.Xr gzip 1 , Xachieving better compression at the cost of slower execution. X.It Fl K XKeep the original X.Sq .Z Xfile if it uses less disk blocks than the gzipped one. XA disk block is 1024 bytes. X.El X.Sh SEE ALSO X.Xr gzip 1 X.Sh CAVEATS XThe X.Nm Xutility tries to maintain the file mode of the original file. XIf the original file is not writable, it is not able to do that and X.Nm Xwill print a warning. END-of-usr.bin/gzip/znew.1 echo x - usr.bin/gzip/zuncompress.c sed 's/^X//' >usr.bin/gzip/zuncompress.c << 'END-of-usr.bin/gzip/zuncompress.c' X/* $NetBSD: zuncompress.c,v 1.6 2005/11/22 09:05:30 mrg Exp $ */ X X/*- X * Copyright (c) 1985, 1986, 1992, 1993 X * The Regents of the University of California. All rights reserved. X * X * This code is derived from software contributed to Berkeley by X * Diomidis Spinellis and James A. Woods, derived from original X * work by Spencer Thomas and Joseph Orost. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. Neither the name of the University nor the names of its contributors X * may be used to endorse or promote products derived from this software X * without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * from: NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp X * $FreeBSD$ X */ X X/* This file is #included by gzip.c */ X Xstatic int zread(void *, char *, int); X X#define tab_prefixof(i) (zs->zs_codetab[i]) X#define tab_suffixof(i) ((char_type *)(zs->zs_htab))[i] X#define de_stack ((char_type *)&tab_suffixof(1 << BITS)) X X#define BITS 16 /* Default bits. */ X#define HSIZE 69001 /* 95% occupancy */ /* XXX may not need HSIZE */ X#define BIT_MASK 0x1f /* Defines for third byte of header. */ X#define BLOCK_MASK 0x80 X#define CHECK_GAP 10000 /* Ratio check interval. */ X#define BUFSIZE (64 * 1024) X X/* X * Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is X * a fourth header byte (for expansion). X */ X#define INIT_BITS 9 /* Initial number of bits/code. */ X X/* X * the next two codes should not be changed lightly, as they must not X * lie within the contiguous general code space. X */ X#define FIRST 257 /* First free entry. */ X#define CLEAR 256 /* Table clear output code. */ X X X#define MAXCODE(n_bits) ((1 << (n_bits)) - 1) X Xtypedef long code_int; Xtypedef long count_int; Xtypedef u_char char_type; X Xstatic char_type magic_header[] = X {'\037', '\235'}; /* 1F 9D */ X Xstatic char_type rmask[9] = X {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; X X/* XXX zuncompress global */ Xoff_t total_compressed_bytes; Xsize_t compressed_prelen; Xchar *compressed_pre; X Xstruct s_zstate { X FILE *zs_fp; /* File stream for I/O */ X char zs_mode; /* r or w */ X enum { X S_START, S_MIDDLE, S_EOF X } zs_state; /* State of computation */ X int zs_n_bits; /* Number of bits/code. */ X int zs_maxbits; /* User settable max # bits/code. */ X code_int zs_maxcode; /* Maximum code, given n_bits. */ X code_int zs_maxmaxcode; /* Should NEVER generate this code. */ X count_int zs_htab [HSIZE]; X u_short zs_codetab [HSIZE]; X code_int zs_hsize; /* For dynamic table sizing. */ X code_int zs_free_ent; /* First unused entry. */ X /* X * Block compression parameters -- after all codes are used up, X * and compression rate changes, start over. X */ X int zs_block_compress; X int zs_clear_flg; X long zs_ratio; X count_int zs_checkpoint; X int zs_offset; X long zs_in_count; /* Length of input. */ X long zs_bytes_out; /* Length of compressed output. */ X long zs_out_count; /* # of codes output (for debugging). */ X char_type zs_buf[BITS]; X union { X struct { X long zs_fcode; X code_int zs_ent; X code_int zs_hsize_reg; X int zs_hshift; X } w; /* Write paramenters */ X struct { X char_type *zs_stackp; X int zs_finchar; X code_int zs_code, zs_oldcode, zs_incode; X int zs_roffset, zs_size; X char_type zs_gbuf[BITS]; X } r; /* Read parameters */ X } u; X}; X Xstatic code_int getcode(struct s_zstate *zs); X Xstatic off_t Xzuncompress(FILE *in, FILE *out, char *pre, size_t prelen, X off_t *compressed_bytes) X{ X off_t bin, bout = 0; X char *buf; X X buf = malloc(BUFSIZE); X if (buf == NULL) X return -1; X X /* XXX */ X compressed_prelen = prelen; X if (prelen != 0) X compressed_pre = pre; X else X compressed_pre = NULL; X X while ((bin = fread(buf, 1, sizeof(buf), in)) != 0) { X if (tflag == 0 && fwrite(buf, 1, bin, out) != bin) { X free(buf); X return -1; X } X bout += bin; X } X X if (compressed_bytes) X *compressed_bytes = total_compressed_bytes; X X free(buf); X return bout; X} X Xstatic int Xzclose(void *zs) X{ X free(zs); X /* We leave the caller to close the fd passed to zdopen() */ X return 0; X} X XFILE * Xzdopen(int fd) X{ X struct s_zstate *zs; X X if ((zs = calloc(1, sizeof(struct s_zstate))) == NULL) X return (NULL); X X zs->zs_state = S_START; X X /* XXX we can get rid of some of these */ X zs->zs_hsize = HSIZE; /* For dynamic table sizing. */ X zs->zs_free_ent = 0; /* First unused entry. */ X zs->zs_block_compress = BLOCK_MASK; X zs->zs_clear_flg = 0; /* XXX we calloc()'d this structure why = 0? */ X zs->zs_ratio = 0; X zs->zs_checkpoint = CHECK_GAP; X zs->zs_in_count = 1; /* Length of input. */ X zs->zs_out_count = 0; /* # of codes output (for debugging). */ X zs->u.r.zs_roffset = 0; X zs->u.r.zs_size = 0; X X /* X * Layering compress on top of stdio in order to provide buffering, X * and ensure that reads and write work with the data specified. X */ X if ((zs->zs_fp = fdopen(fd, "r")) == NULL) { X free(zs); X return NULL; X } X X return funopen(zs, zread, NULL, NULL, zclose); X} X X/* X * Decompress read. This routine adapts to the codes in the file building X * the "string" table on-the-fly; requiring no table to be stored in the X * compressed file. The tables used herein are shared with those of the X * compress() routine. See the definitions above. X */ Xstatic int Xzread(void *cookie, char *rbp, int num) X{ X u_int count, i; X struct s_zstate *zs; X u_char *bp, header[3]; X X if (num == 0) X return (0); X X zs = cookie; X count = num; X bp = (u_char *)rbp; X switch (zs->zs_state) { X case S_START: X zs->zs_state = S_MIDDLE; X break; X case S_MIDDLE: X goto middle; X case S_EOF: X goto eof; X } X X /* Check the magic number */ X for (i = 0; i < 3 && compressed_prelen; i++, compressed_prelen--) X header[i] = *compressed_pre++; X X if (fread(header + i, 1, sizeof(header) - i, zs->zs_fp) != X sizeof(header) - i || X memcmp(header, magic_header, sizeof(magic_header)) != 0) { X errno = EFTYPE; X return (-1); X } X total_compressed_bytes = 0; X zs->zs_maxbits = header[2]; /* Set -b from file. */ X zs->zs_block_compress = zs->zs_maxbits & BLOCK_MASK; X zs->zs_maxbits &= BIT_MASK; X zs->zs_maxmaxcode = 1L << zs->zs_maxbits; X if (zs->zs_maxbits > BITS) { X errno = EFTYPE; X return (-1); X } X /* As above, initialize the first 256 entries in the table. */ X zs->zs_maxcode = MAXCODE(zs->zs_n_bits = INIT_BITS); X for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0; zs->u.r.zs_code--) { X tab_prefixof(zs->u.r.zs_code) = 0; X tab_suffixof(zs->u.r.zs_code) = (char_type) zs->u.r.zs_code; X } X zs->zs_free_ent = zs->zs_block_compress ? FIRST : 256; X X zs->u.r.zs_finchar = zs->u.r.zs_oldcode = getcode(zs); X if (zs->u.r.zs_oldcode == -1) /* EOF already? */ X return (0); /* Get out of here */ X X /* First code must be 8 bits = char. */ X *bp++ = (u_char)zs->u.r.zs_finchar; X count--; X zs->u.r.zs_stackp = de_stack; X X while ((zs->u.r.zs_code = getcode(zs)) > -1) { X X if ((zs->u.r.zs_code == CLEAR) && zs->zs_block_compress) { X for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0; X zs->u.r.zs_code--) X tab_prefixof(zs->u.r.zs_code) = 0; X zs->zs_clear_flg = 1; X zs->zs_free_ent = FIRST - 1; X if ((zs->u.r.zs_code = getcode(zs)) == -1) /* O, untimely death! */ X break; X } X zs->u.r.zs_incode = zs->u.r.zs_code; X X /* Special case for KwKwK string. */ X if (zs->u.r.zs_code >= zs->zs_free_ent) { X *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar; X zs->u.r.zs_code = zs->u.r.zs_oldcode; X } X X /* Generate output characters in reverse order. */ X while (zs->u.r.zs_code >= 256) { X *zs->u.r.zs_stackp++ = tab_suffixof(zs->u.r.zs_code); X zs->u.r.zs_code = tab_prefixof(zs->u.r.zs_code); X } X *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar = tab_suffixof(zs->u.r.zs_code); X X /* And put them out in forward order. */ Xmiddle: do { X if (count-- == 0) X return (num); X *bp++ = *--zs->u.r.zs_stackp; X } while (zs->u.r.zs_stackp > de_stack); X X /* Generate the new entry. */ X if ((zs->u.r.zs_code = zs->zs_free_ent) < zs->zs_maxmaxcode) { X tab_prefixof(zs->u.r.zs_code) = (u_short) zs->u.r.zs_oldcode; X tab_suffixof(zs->u.r.zs_code) = zs->u.r.zs_finchar; X zs->zs_free_ent = zs->u.r.zs_code + 1; X } X X /* Remember previous code. */ X zs->u.r.zs_oldcode = zs->u.r.zs_incode; X } X zs->zs_state = S_EOF; Xeof: return (num - count); X} X X/*- X * Read one code from the standard input. If EOF, return -1. X * Inputs: X * stdin X * Outputs: X * code or -1 is returned. X */ Xstatic code_int Xgetcode(struct s_zstate *zs) X{ X code_int gcode; X int r_off, bits, i; X char_type *bp; X X bp = zs->u.r.zs_gbuf; X if (zs->zs_clear_flg > 0 || zs->u.r.zs_roffset >= zs->u.r.zs_size || X zs->zs_free_ent > zs->zs_maxcode) { X /* X * If the next entry will be too big for the current gcode X * size, then we must increase the size. This implies reading X * a new buffer full, too. X */ X if (zs->zs_free_ent > zs->zs_maxcode) { X zs->zs_n_bits++; X if (zs->zs_n_bits == zs->zs_maxbits) /* Won't get any bigger now. */ X zs->zs_maxcode = zs->zs_maxmaxcode; X else X zs->zs_maxcode = MAXCODE(zs->zs_n_bits); X } X if (zs->zs_clear_flg > 0) { X zs->zs_maxcode = MAXCODE(zs->zs_n_bits = INIT_BITS); X zs->zs_clear_flg = 0; X } X /* XXX */ X for (i = 0; i < zs->zs_n_bits && compressed_prelen; i++, compressed_prelen--) X zs->u.r.zs_gbuf[i] = *compressed_pre++; X zs->u.r.zs_size = fread(zs->u.r.zs_gbuf + i, 1, zs->zs_n_bits - i, zs->zs_fp); X zs->u.r.zs_size += i; X if (zs->u.r.zs_size <= 0) /* End of file. */ X return (-1); X zs->u.r.zs_roffset = 0; X X total_compressed_bytes += zs->u.r.zs_size; X X /* Round size down to integral number of codes. */ X zs->u.r.zs_size = (zs->u.r.zs_size << 3) - (zs->zs_n_bits - 1); X } X r_off = zs->u.r.zs_roffset; X bits = zs->zs_n_bits; X X /* Get to the first byte. */ X bp += (r_off >> 3); X r_off &= 7; X X /* Get first part (low order bits). */ X gcode = (*bp++ >> r_off); X bits -= (8 - r_off); X r_off = 8 - r_off; /* Now, roffset into gcode word. */ X X /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ X if (bits >= 8) { X gcode |= *bp++ << r_off; X r_off += 8; X bits -= 8; X } X X /* High order bits. */ X gcode |= (*bp & rmask[bits]) << r_off; X zs->u.r.zs_roffset += zs->zs_n_bits; X X return (gcode); X} END-of-usr.bin/gzip/zuncompress.c exit