Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/gzip Redo suffix handling so that gunzip xxx.tgx => ...
details: https://anonhg.NetBSD.org/src/rev/98228d05c2cb
branches: trunk
changeset: 569701:98228d05c2cb
user: dsl <dsl%NetBSD.org@localhost>
date: Mon Aug 30 14:36:51 2004 +0000
description:
Redo suffix handling so that gunzip xxx.tgx => xxx.tar
Rework logic of gz_{un}compress to make it much less likely to leak fds
(at least 2 non-error paths leaked them!)
Make -S ".xyz" and -S "" both do something sensible.
Make in-situ compression work - only lose the file on error.
Pass an open fd to zopen (renamed zdopen) to avoid fd leakage (was badly borked)
Write header into first 64k output block to writes are aligned.
(more efficient and might avoid some problem with code that doesn't
like receiving partial buffers)
Check file size on compression - double checks against fs full.
Remove some pointless casts, and otherwise simplify some logic.
diffstat:
usr.bin/gzip/gzip.c | 673 ++++++++++++++++++++++----------------------
usr.bin/gzip/zuncompress.c | 28 +-
2 files changed, 353 insertions(+), 348 deletions(-)
diffs (truncated from 1180 to 300 lines):
diff -r 245bee322013 -r 98228d05c2cb usr.bin/gzip/gzip.c
--- a/usr.bin/gzip/gzip.c Mon Aug 30 12:54:39 2004 +0000
+++ b/usr.bin/gzip/gzip.c Mon Aug 30 14:36:51 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gzip.c,v 1.62 2004/07/16 22:44:01 he Exp $ */
+/* $NetBSD: gzip.c,v 1.63 2004/08/30 14:36:51 dsl Exp $ */
/*
* Copyright (c) 1997, 1998, 2003, 2004 Matthew R. Green
@@ -32,14 +32,13 @@
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004 Matthew R. Green\n\
All rights reserved.\n");
-__RCSID("$NetBSD: gzip.c,v 1.62 2004/07/16 22:44:01 he Exp $");
+__RCSID("$NetBSD: gzip.c,v 1.63 2004/08/30 14:36:51 dsl Exp $");
#endif /* not lint */
/*
* gzip.c -- GPL free gzip using zlib.
*
* TODO:
- * - handle .taz/.tgz files?
* - use mmap where possible
* - handle some signals better (remove outfile?)
* - make bzip2/compress -v/-t/-l support work as well as possible
@@ -49,6 +48,7 @@
#include <sys/stat.h>
#include <sys/time.h>
+#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
@@ -62,6 +62,10 @@
#include <stdarg.h>
#include <getopt.h>
+#ifndef PRIdOFF
+#define PRIdOFF PRId64
+#endif
+
/* what type of file are we dealing with */
enum filetype {
FT_GZIP,
@@ -105,20 +109,36 @@
#define OS_CODE 3 /* Unix */
+typedef struct {
+ char zipped[8];
+ int ziplen;
+ char normal[8];
+ int norlen;
+} suffixes_t;
+static suffixes_t suffixes[] = {
+#define SUFFIX(Z, N) {Z, sizeof Z - 1, N, sizeof N - 0}
+ SUFFIX(GZ_SUFFIX, ""), /* Overwritten by -S .xxx */
#ifndef SMALL
-static char const *suffixes[] = {
- GZ_SUFFIX, ".z", ".taz", ".tgz", "-gz", "-z", "_z",
+ SUFFIX(GZ_SUFFIX, ""),
+ SUFFIX(".z", ""),
+ SUFFIX("-gz", ""),
+ SUFFIX("-z", ""),
+ SUFFIX("_z", ""),
+ SUFFIX(".taz", ".tar"),
+ SUFFIX(".tgz", ".tar"),
#ifndef NO_BZIP2_SUPPORT
- BZ2_SUFFIX,
+ SUFFIX(BZ2_SUFFIX, ""),
#endif
#ifndef NO_COMPRESS_SUPPORT
- Z_SUFFIX,
+ SUFFIX(Z_SUFFIX, ""),
#endif
- NULL
+ SUFFIX(GZ_SUFFIX, ""), /* Overwritten by -S "" */
+#endif /* SMALL */
+#undef SUFFIX
};
-#endif /* SMALL */
+#define NUM_SUFFIXES (sizeof suffixes / sizeof suffixes[0])
-static const char gzip_version[] = "NetBSD gzip 20040711";
+static const char gzip_version[] = "NetBSD gzip 20040830";
static int cflag; /* stdout mode */
static int dflag; /* decompress mode */
@@ -132,7 +152,6 @@
static int qflag; /* quiet mode */
static int rflag; /* recursive mode */
static int tflag; /* test */
-static char *Sflag;
static int vflag; /* verbose mode */
#else
#define qflag 0
@@ -140,16 +159,21 @@
static int exit_value = 0; /* exit value */
-static const char *suffix;
-#define suffix_len (strlen(suffix) + 1) /* len + nul */
static char *infile; /* name of file coming in */
-static void maybe_err(const char *fmt, ...);
-static void maybe_errx(const char *fmt, ...);
-static void maybe_warn(const char *fmt, ...);
-static void maybe_warnx(const char *fmt, ...);
+static void maybe_err(const char *fmt, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
+static void maybe_errx(const char *fmt, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
+static void maybe_warn(const char *fmt, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
+static void maybe_warnx(const char *fmt, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
static enum filetype file_gettype(u_char *);
-static off_t gz_compress(FILE *, int, off_t *, const char *, time_t);
+#ifdef SMALL
+#define gz_compress(if, of, sz, fn, tm) gz_compress(if, of, sz)
+#endif
+static off_t gz_compress(int, int, off_t *, const char *, uint32_t);
static off_t gz_uncompress(int, int, char *, size_t, off_t *, const char *);
static off_t file_compress(char *, char *, size_t);
static off_t file_uncompress(char *, char *, size_t);
@@ -162,15 +186,17 @@
static void print_list(int fd, off_t, const char *, time_t);
static void usage(void);
static void display_version(void);
+static const suffixes_t *check_suffix(char *, int);
-#ifndef SMALL
+#ifdef SMALL
+#define unlink_input(f, sb) unlink(f)
+#else
static void prepend_gzip(char *, int *, char ***);
static void handle_dir(char *, struct stat *);
-static void print_verbage(char *, char *, off_t, off_t);
+static void print_verbage(const char *, const char *, off_t, off_t);
static void print_test(const char *, int);
static void copymodes(const char *, struct stat *);
static int check_outfile(const char *outfile, struct stat *sb);
-static const char *check_suffix(char *);
#endif
#ifndef NO_BZIP2_SUPPORT
@@ -178,7 +204,7 @@
#endif
#ifndef NO_COMPRESS_SUPPORT
-static FILE *zopen(const char *, FILE *);
+static FILE *zdopen(int);
static off_t zuncompress(FILE *, FILE *, char *, size_t, off_t *);
#endif
@@ -223,13 +249,12 @@
const char *progname = getprogname();
#ifndef SMALL
char *gzip;
+ int len;
#endif
int ch;
/* XXX set up signals */
- suffix = GZ_SUFFIX;
-
#ifndef SMALL
if ((gzip = getenv("GZIP")) != NULL)
prepend_gzip(gzip, &argc, &argv);
@@ -251,7 +276,7 @@
#define OPT_LIST "cdfhHlnNqrS:tvV123456789"
#endif
- while ((ch = getopt_long(argc, argv, OPT_LIST, longopts, NULL)) != -1)
+ while ((ch = getopt_long(argc, argv, OPT_LIST, longopts, NULL)) != -1) {
switch (ch) {
case 'c':
cflag = 1;
@@ -290,7 +315,17 @@
rflag = 1;
break;
case 'S':
- Sflag = optarg;
+ len = strlen(optarg);
+ if (len >= sizeof suffixes[0].zipped)
+ /* 7 bytes of suffix is enough for anyone... */
+ usage();
+ if (len != 0) {
+ memcpy(suffixes[0].zipped, optarg, len + 1);
+ suffixes[0].ziplen = len;
+ } else {
+ suffixes[NUM_SUFFIXES - 1].zipped[0] = 0;
+ suffixes[NUM_SUFFIXES - 1].ziplen = 0;
+ }
break;
case 't':
cflag = 1;
@@ -305,6 +340,7 @@
usage();
/* NOTREACHED */
}
+ }
argv += optind;
argc -= optind;
@@ -442,53 +478,61 @@
}
#endif
-/* compress input to output then close both files */
+/* compress input to output. Return bytes read, -1 on error */
static off_t
-gz_compress(FILE *in, int out, off_t *gsizep, const char *origname, time_t mtime)
+gz_compress(int in, int out, off_t *gsizep, const char *origname, uint32_t mtime)
{
z_stream z;
char *outbufp, *inbufp;
off_t in_tot = 0, out_tot = 0;
ssize_t in_size;
- char *str;
int i, error;
uLong crc;
+#ifdef SMALL
+ static char header[] = { GZIP_MAGIC0, GZIP_MAGIC1, Z_DEFLATED, 0,
+ 0, 0, 0, 0,
+ 0, OS_CODE };
+#endif
- if ((outbufp = malloc(BUFLEN)) == NULL) {
+ outbufp = malloc(BUFLEN);
+ inbufp = malloc(BUFLEN);
+ if (outbufp == NULL || inbufp == NULL) {
maybe_err("malloc failed");
- goto out2;
- }
- if ((inbufp = malloc(BUFLEN)) == NULL) {
- maybe_err("malloc failed");
- goto out1;
+ goto out;
}
- i = asprintf(&str, "%c%c%c%c%c%c%c%c%c%c%s",
- GZIP_MAGIC0, GZIP_MAGIC1,
- Z_DEFLATED, origname ? ORIG_NAME : 0,
- (int)mtime & 0xff,
- (int)(mtime >> 8) & 0xff,
- (int)(mtime >> 16) & 0xff,
- (int)(mtime >> 24) & 0xff,
- 0, OS_CODE, origname ? origname : "");
- if (i == -1)
- maybe_err("asprintf");
- if (origname)
- i++;
- if (write(out, str, i) != i) {
- maybe_warn("write");
- in_tot = -1;
- goto out;
- }
- free(str);
-
memset(&z, 0, sizeof z);
- z.next_out = outbufp;
- z.avail_out = BUFLEN;
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = 0;
+#ifdef SMALL
+ memcpy(outbufp, header, sizeof header);
+ i = sizeof header;
+#else
+ if (nflag != 0) {
+ mtime = 0;
+ origname = "";
+ }
+
+ i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c%c%c%s",
+ GZIP_MAGIC0, GZIP_MAGIC1, Z_DEFLATED,
+ *origname ? ORIG_NAME : 0,
+ mtime & 0xff,
+ (mtime >> 8) & 0xff,
+ (mtime >> 16) & 0xff,
+ (mtime >> 24) & 0xff,
+ 0, OS_CODE, origname);
+ if (i >= BUFLEN)
+ /* this need PATH_MAX > BUFLEN ... */
+ maybe_err("snprintf");
+ if (*origname)
+ i++;
+#endif
+
+ z.next_out = outbufp + i;
+ z.avail_out = BUFLEN - i;
+
error = deflateInit2(&z, numflag, Z_DEFLATED,
-MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
if (error != Z_OK) {
@@ -512,9 +556,9 @@
}
Home |
Main Index |
Thread Index |
Old Index