2
* Author: Faidon Liambotis <paravoid@debian.org>
4
* This is a zlib-based gzip that is heavily based on NetBSD's gzip,
5
* developed by Matthew R. Green.
7
* This is suited for gzip regeneration and is part of pristine-tar.
8
* As such, it adds some extra options which are needed to successfully
9
* reproduce the gzips out there and removes features of the original
10
* implementation that were not relevant (e.g. decompression)
12
* Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green
13
* Copyright (c) 2007 Faidon Liambotis
14
* All rights reserved.
16
* Redistribution and use in source and binary forms, with or without
17
* modification, are permitted provided that the following conditions
19
* 1. Redistributions of source code must retain the above copyright
20
* notice, this list of conditions and the following disclaimer.
21
* 2. Redistributions in binary form must reproduce the above copyright
22
* notice, this list of conditions and the following disclaimer in the
23
* documentation and/or other materials provided with the distribution.
24
* 3. The name of the author may not be used to endorse or promote products
25
* derived from this software without specific prior written permission.
27
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
34
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41
* gzip.c -- GPL free gzip using zlib.
43
* RFC 1950 covers the zlib format
44
* RFC 1951 covers the deflate format
45
* RFC 1952 covers the gzip format
51
#include <sys/param.h>
71
#define PRIdOFF PRId64
74
/* what type of file are we dealing with */
81
#define GZ_SUFFIX ".gz"
83
#define BUFLEN (64 * 1024)
85
#define GZIP_MAGIC0 0x1F
86
#define GZIP_MAGIC1 0x8B
87
#define GZIP_OMAGIC1 0x9E
89
#define GZIP_TIMESTAMP (off_t)4
90
#define GZIP_ORIGNAME (off_t)10
93
#define EXTRA_FIELD 0x04
94
#define ORIG_NAME 0x08
97
#define GZIP_OS_UNIX 3 /* Unix */
98
#define GZIP_OS_NTFS 11 /* NTFS */
103
const char *normal; /* for unzip - must not be longer than zipped */
105
static suffixes_t suffixes[] = {
106
#define SUFFIX(Z, N) {Z, sizeof Z - 1, N}
107
SUFFIX(GZ_SUFFIX, ""), /* Overwritten by -S .xxx */
108
SUFFIX(GZ_SUFFIX, ""),
113
SUFFIX(".taz", ".tar"),
114
SUFFIX(".tgz", ".tar"),
115
SUFFIX(GZ_SUFFIX, ""), /* Overwritten by -S "" */
118
#define NUM_SUFFIXES (sizeof suffixes / sizeof suffixes[0])
120
static const char gzip_version[] = "zgz 20071002 based on NetBSD gzip 20060927";
122
static const char gzip_copyright[] = \
123
" Author: Faidon Liambotis <paravoid@debian.org>\n"
125
" Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green\n"
126
" Copyright (c) 2007 Faidon Liambotis\n"
127
" * All rights reserved.\n"
129
" * Redistribution and use in source and binary forms, with or without\n"
130
" * modification, are permitted provided that the following conditions\n"
132
" * 1. Redistributions of source code must retain the above copyright\n"
133
" * notice, this list of conditions and the following disclaimer.\n"
134
" * 2. Redistributions in binary form must reproduce the above copyright\n"
135
" * notice, this list of conditions and the following disclaimer in the\n"
136
" * documentation and/or other materials provided with the distribution.\n"
137
" * 3. The name of the author may not be used to endorse or promote products\n"
138
" * derived from this software without specific prior written permission.\n"
140
" * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n"
141
" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n"
142
" * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n"
143
" * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n"
144
" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n"
145
" * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
146
" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"
147
" * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n"
148
" * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"
149
" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"
152
static int cflag; /* stdout mode */
153
static int lflag; /* list mode */
154
static int numflag = 6; /* gzip -1..-9 value */
156
static int fflag; /* force mode */
157
static int nflag; /* don't save name (impiles -m) */
158
static int Nflag; /* restore name/timestamp */
159
static int mflag; /* undocumented: don't save timestamp */
160
static int qflag; /* quiet mode */
161
static int tflag; /* test */
162
static int vflag; /* verbose mode */
163
static int xflag = -1; /* don't set Extra Flags (i.e. compression level)
164
binary compatibility with an older, buggy version */
165
static int osflag = GZIP_OS_UNIX; /* Unix or otherwise */
166
static int ntfs_quirk = 0; /* whether NTFS quirk is activated */
167
static int exit_value = 0; /* exit value */
169
static char *infile; /* name of file coming in */
171
static void maybe_err(const char *fmt, ...)
172
__attribute__((__format__(__printf__, 1, 2)));
173
static void maybe_warn(const char *fmt, ...)
174
__attribute__((__format__(__printf__, 1, 2)));
175
static void maybe_warnx(const char *fmt, ...)
176
__attribute__((__format__(__printf__, 1, 2)));
178
static enum filetype file_gettype(u_char *);
180
static off_t gz_compress(int, int, off_t *, const char *, uint32_t);
181
static off_t file_compress(char *, char *, char *, size_t);
182
static void handle_pathname(char *, char *);
183
static void handle_file(char *, char *, struct stat *);
184
static void handle_stdout(char *);
185
static void print_ratio(off_t, off_t, FILE *);
186
static void print_list(int fd, off_t, const char *, time_t);
187
static void usage(void);
188
static void display_version(void);
189
static void display_license(void);
190
static const suffixes_t *check_suffix(char *, int);
192
static void print_verbage(const char *, const char *, off_t, off_t);
193
static void copymodes(int fd, const struct stat *, const char *file);
194
static int check_outfile(const char *outfile);
196
int main(int, char **p);
198
static const struct option longopts[] = {
199
{ "stdout", no_argument, 0, 'c' },
200
{ "to-stdout", no_argument, 0, 'c' },
201
{ "decompress", no_argument, 0, 'd' },
202
{ "uncompress", no_argument, 0, 'd' },
203
{ "force", no_argument, 0, 'f' },
204
{ "help", no_argument, 0, 'h' },
205
{ "list", no_argument, 0, 'l' },
206
{ "no-name", no_argument, 0, 'n' },
207
{ "name", no_argument, 0, 'N' },
208
{ "quiet", no_argument, 0, 'q' },
209
{ "recursive", no_argument, 0, 'r' },
210
{ "suffix", required_argument, 0, 'S' },
211
{ "test", no_argument, 0, 't' },
212
{ "verbose", no_argument, 0, 'v' },
213
{ "fast", no_argument, 0, '1' },
214
{ "best", no_argument, 0, '9' },
215
{ "ascii", no_argument, 0, 'a' },
217
{ "no-timestamp", no_argument, 0, 'm' },
218
{ "force-timestamp", no_argument, 0, 'M' },
219
{ "osflag", required_argument, 0, 's' },
220
{ "original-name", required_argument, 0, 'o' },
221
{ "quirk", required_argument, 0, 'k' },
223
{ "version", no_argument, 0, 'V' },
224
{ "license", no_argument, 0, 'L' },
225
{ NULL, no_argument, 0, 0 },
229
main(int argc, char **argv)
231
const char *progname = argv[0];
232
char origname[BUFLEN] = { 0 };
237
if (strcmp(progname, "gunzip") == 0 ||
238
strcmp(progname, "zcat") == 0 ||
239
strcmp(progname, "gzcat") == 0) {
240
fprintf(stderr, "%s: decompression is not supported on this version\n", progname);
244
if (argc > 1 && strcmp(argv[1], "--gnu") == 0) {
245
/* omit first argument, i.e. --gnu */
247
/* works because "--gnu" is bigger than "gzip" */
248
strcpy(argv[0], "gzip");
249
execv("/bin/gzip", argv);
252
fprintf(stderr, "Failed to spawn /bin/gzip\n");
254
} else if (argc > 1 && strcmp(argv[1], "--zlib") == 0) {
255
/* skip --zlib argument if existent */
260
#define OPT_LIST "123456789acdfhlLNnMmqrS:tVvo:k:s:"
262
while ((ch = getopt_long(argc, argv, OPT_LIST, longopts, NULL)) != -1) {
264
case '1': case '2': case '3':
265
case '4': case '5': case '6':
266
case '7': case '8': case '9':
285
/* no break, n implies m */
296
len = strlen(optarg);
298
suffixes[0].zipped = optarg;
299
suffixes[0].ziplen = len;
301
suffixes[NUM_SUFFIXES - 1].zipped = "";
302
suffixes[NUM_SUFFIXES - 1].ziplen = 0;
313
osflag = atoi(optarg);
317
fprintf(stderr, "%s: ignoring original-name because no-name was passed\n", progname);
318
strncpy(origname, optarg, BUFLEN);
321
if (strcmp(optarg, "buggy-bsd") == 0) {
322
/* certain archives made with older versions of
323
* BSD variants of gzip */
325
/* no name or timestamp information */
328
/* maximum compression but without indicating so */
331
} else if (strcmp(optarg, "ntfs") == 0) {
333
/* no name or timestamp information */
337
osflag = GZIP_OS_NTFS;
339
fprintf(stderr, "%s: unknown quirk!\n", progname);
344
fprintf(stderr, "%s: recursive is not supported on this version\n", progname);
348
fprintf(stderr, "%s: decompression is not supported on this version\n", progname);
352
fprintf(stderr, "%s: option --ascii ignored on this version\n", progname);
369
handle_stdout(origname);
372
handle_pathname(argv[0], origname);
375
if (qflag == 0 && lflag && argc > 1)
376
print_list(-1, 0, "(totals)", 0);
380
/* maybe print a warning */
382
maybe_warn(const char *fmt, ...)
395
/* ... without an errno. */
397
maybe_warnx(const char *fmt, ...)
410
/* maybe print an error */
412
maybe_err(const char *fmt, ...)
424
/* compress input to output. Return bytes read, -1 on error */
426
gz_compress(int in, int out, off_t *gsizep, const char *origname, uint32_t mtime)
429
char *outbufp, *inbufp;
430
off_t in_tot = 0, out_tot = 0;
435
outbufp = malloc(BUFLEN);
436
inbufp = malloc(BUFLEN);
437
if (outbufp == NULL || inbufp == NULL) {
438
maybe_err("malloc failed");
442
memset(&z, 0, sizeof z);
452
i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c%c%c%s",
453
GZIP_MAGIC0, GZIP_MAGIC1, Z_DEFLATED,
454
*origname ? ORIG_NAME : 0,
457
(mtime >> 16) & 0xff,
458
(mtime >> 24) & 0xff,
460
numflag == 1 ? 4 : numflag == 9 ? 2 : 0,
463
/* this need PATH_MAX > BUFLEN ... */
464
maybe_err("snprintf");
468
z.next_out = (unsigned char *)outbufp + i;
469
z.avail_out = BUFLEN - i;
471
error = deflateInit2(&z, numflag, Z_DEFLATED,
472
(-MAX_WBITS), 8, Z_DEFAULT_STRATEGY);
474
maybe_warnx("deflateInit2 failed");
479
crc = crc32(0L, Z_NULL, 0);
481
if (z.avail_out == 0) {
482
if (write(out, outbufp, BUFLEN) != BUFLEN) {
489
z.next_out = (unsigned char *)outbufp;
490
z.avail_out = BUFLEN;
493
if (z.avail_in == 0) {
494
in_size = read(in, inbufp, BUFLEN);
503
crc = crc32(crc, (const Bytef *)inbufp, (unsigned)in_size);
505
z.next_in = (unsigned char *)inbufp;
506
z.avail_in = in_size;
509
error = deflate(&z, Z_NO_FLUSH);
510
if (error != Z_OK && error != Z_STREAM_END) {
511
maybe_warnx("deflate failed");
522
error = deflate(&z, Z_FINISH);
523
if (error != Z_OK && error != Z_STREAM_END) {
524
maybe_warnx("deflate failed");
529
len = (char *)z.next_out - outbufp;
531
/* for a really strange reason, that
532
* particular byte is decremented */
536
w = write(out, outbufp, len);
537
if (w == -1 || (size_t)w != len) {
543
z.next_out = (unsigned char *)outbufp;
544
z.avail_out = BUFLEN;
546
if (error == Z_STREAM_END)
550
if (deflateEnd(&z) != Z_OK) {
551
maybe_warnx("deflateEnd failed");
557
/* write NTFS tail magic (?) */
558
i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c",
559
0x00, 0x00, 0xff, 0xff, 0x03, 0x00);
561
maybe_err("snprintf");
562
if (write(out, outbufp, i) != i) {
569
/* write CRC32 and input size (ISIZE) at the tail */
570
i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c",
572
(int)(crc >> 8) & 0xff,
573
(int)(crc >> 16) & 0xff,
574
(int)(crc >> 24) & 0xff,
576
(int)(in_tot >> 8) & 0xff,
577
(int)(in_tot >> 16) & 0xff,
578
(int)(in_tot >> 24) & 0xff);
580
maybe_err("snprintf");
581
if (write(out, outbufp, i) != i) {
599
* set the owner, mode, flags & utimes using the given file descriptor.
600
* file is only used in possible warning messages.
603
copymodes(int fd, const struct stat *sbp, const char *file)
608
* If we have no info on the input, give this file some
609
* default values and return..
612
mode_t mask = umask(022);
614
(void)fchmod(fd, DEFFILEMODE & ~mask);
620
/* if the chown fails, remove set-id bits as-per compress(1) */
621
if (fchown(fd, sb.st_uid, sb.st_gid) < 0) {
623
maybe_warn("couldn't fchown: %s", file);
624
sb.st_mode &= ~(S_ISUID|S_ISGID);
627
/* we only allow set-id and the 9 normal permission bits */
628
sb.st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
629
if (fchmod(fd, sb.st_mode) < 0)
630
maybe_warn("couldn't fchmod: %s", file);
634
/* what sort of file is this? */
636
file_gettype(u_char *buf)
639
if (buf[0] == GZIP_MAGIC0 &&
640
(buf[1] == GZIP_MAGIC1 || buf[1] == GZIP_OMAGIC1))
647
/* check the outfile is OK. */
649
check_outfile(const char *outfile)
654
if (lflag == 0 && stat(outfile, &sb) == 0) {
657
else if (isatty(STDIN_FILENO)) {
658
char ans[10] = { 'n', '\0' }; /* default */
660
fprintf(stderr, "%s already exists -- do you wish to "
661
"overwrite (y or n)? " , outfile);
662
(void)fgets(ans, sizeof(ans) - 1, stdin);
663
if (ans[0] != 'y' && ans[0] != 'Y') {
664
fprintf(stderr, "\tnot overwritting\n");
669
maybe_warnx("%s already exists -- skipping", outfile);
677
unlink_input(const char *file, const struct stat *sb)
681
if (stat(file, &nsb) != 0)
682
/* Must be gone alrady */
684
if (nsb.st_dev != sb->st_dev || nsb.st_ino != sb->st_ino)
685
/* Definitely a different file */
690
static const suffixes_t *
691
check_suffix(char *file, int xlate)
694
int len = strlen(file);
697
for (s = suffixes; s != suffixes + NUM_SUFFIXES; s++) {
698
/* if it doesn't fit in "a.suf", don't bother */
699
if (s->ziplen >= len)
701
sp = file + len - s->ziplen;
702
if (strcmp(s->zipped, sp) != 0)
705
strcpy(sp, s->normal);
712
* compress the given file: create a corresponding .gz file and remove the
716
file_compress(char *file, char *origname, char *outfile, size_t outsize)
721
struct stat isb, osb;
722
const suffixes_t *suff;
724
in = open(file, O_RDONLY);
726
maybe_warn("can't open %s", file);
731
if (fstat(in, &isb) == 0) {
732
if (isb.st_nlink > 1 && fflag == 0) {
733
maybe_warnx("%s has %d other link%s -- "
734
"skipping", file, isb.st_nlink - 1,
735
isb.st_nlink == 1 ? "" : "s");
741
if (fflag == 0 && (suff = check_suffix(file, 0))
742
&& suff->zipped[0] != 0) {
743
maybe_warnx("%s already has %s suffix -- unchanged",
749
/* Add (usually) .gz to filename */
750
if ((size_t)snprintf(outfile, outsize, "%s%s",
751
file, suffixes[0].zipped) >= outsize)
752
memcpy(outfile - suffixes[0].ziplen - 1,
753
suffixes[0].zipped, suffixes[0].ziplen + 1);
755
if (check_outfile(outfile) == 0) {
760
out = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0600);
762
maybe_warn("could not create output: %s", outfile);
770
insize = gz_compress(in, out, &size, origname, (uint32_t)isb.st_mtime);
775
* If there was an error, insize will be -1.
776
* If we compressed to stdout, just return the size.
777
* Otherwise stat the file and check it is the correct size.
778
* We only blow away the file if we can stat the output and it
779
* has the expected size.
782
return insize == -1 ? -1 : size;
784
if (fstat(out, &osb) != 0) {
785
maybe_warn("couldn't stat: %s", outfile);
789
if (osb.st_size != size) {
790
maybe_warnx("output file: %s wrong size (%" PRIdOFF
791
" != %" PRIdOFF "), deleting",
792
outfile, (long long)osb.st_size,
797
copymodes(out, &isb, outfile);
798
if (close(out) == -1)
799
maybe_warn("couldn't close output");
801
/* output is good, ok to delete input */
802
unlink_input(file, &isb);
806
if (close(out) == -1)
807
maybe_warn("couldn't close output");
809
maybe_warnx("leaving original %s", file);
815
handle_stdout(char *origname)
823
if (fflag == 0 && isatty(STDOUT_FILENO)) {
824
maybe_warnx("standard output is a terminal -- ignoring");
827
/* If stdin is a file use it's mtime, otherwise use current time */
828
ret = fstat(STDIN_FILENO, &sb);
831
maybe_warn("Can't stat stdin");
835
if (S_ISREG(sb.st_mode))
836
mtime = (uint32_t)sb.st_mtime;
838
systime = time(NULL);
843
mtime = (uint32_t)systime;
846
usize = gz_compress(STDIN_FILENO, STDOUT_FILENO, &gsize, origname, mtime);
847
if (vflag && !tflag && usize != -1 && gsize != -1)
848
print_verbage(NULL, NULL, usize, gsize);
851
/* do what is asked for, for the path name */
853
handle_pathname(char *path, char *origname)
858
/* check for stdout */
859
if (path[0] == '-' && path[1] == '\0') {
860
handle_stdout(origname);
864
if (stat(path, &sb) != 0) {
865
maybe_warn("can't stat: %s", opath);
869
if (S_ISDIR(sb.st_mode)) {
870
maybe_warnx("%s is a directory", path);
874
if (S_ISREG(sb.st_mode))
875
handle_file(path, strlen(origname) ? origname : basename(path), &sb);
877
maybe_warnx("%s is not a regular file", path);
880
/* compress/decompress a file */
882
handle_file(char *file, char *origname, struct stat *sbp)
885
char outfile[PATH_MAX];
888
gsize = file_compress(file, origname, outfile, sizeof(outfile));
891
usize = sbp->st_size;
894
print_verbage(file, (cflag) ? NULL : outfile, usize, gsize);
897
/* print a ratio - size reduction as a fraction of uncompressed size */
899
print_ratio(off_t in, off_t out, FILE *where)
901
int percent10; /* 10 * percent */
909
* Output is more than double size of input! print -99.9%
910
* Quite possibly we've failed to get the original size.
915
* We only need 12 bits of result from the final division,
916
* so reduce the values until a 32bit division will suffice.
918
while (in > 0x100000) {
923
percent10 = ((u_int)diff * 2000) / (u_int)in - 1000;
928
len = snprintf(buff, sizeof buff, "%2.2d.", percent10);
929
/* Move the '.' to before the last digit */
930
buff[len - 1] = buff[len - 2];
932
fprintf(where, "%5s%%", buff);
935
/* print compression statistics, and the new name (if there is one!) */
937
print_verbage(const char *file, const char *nfile, off_t usize, off_t gsize)
940
fprintf(stderr, "%s:%s ", file,
941
strlen(file) < 7 ? "\t\t" : "\t");
942
print_ratio(usize, gsize, stderr);
944
fprintf(stderr, " -- replaced with %s", nfile);
945
fprintf(stderr, "\n");
949
/* print a file's info ala --list */
951
compressed uncompressed ratio uncompressed_name
952
354841 1679360 78.8% /usr/pkgsrc/distfiles/libglade-2.0.1.tar
955
print_list(int fd, off_t out, const char *outfile, time_t ts)
957
static int first = 1;
958
static off_t in_tot, out_tot;
964
printf("method crc date time ");
966
printf(" compressed uncompressed "
967
"ratio uncompressed_name\n");
976
/* read the last 4 bytes - this is the uncompressed size */
977
rv = lseek(fd, (off_t)(-8), SEEK_END);
979
unsigned char buf[8];
982
rv = read(fd, (char *)buf, sizeof(buf));
984
maybe_warn("read of uncompressed size");
985
else if (rv != sizeof(buf))
986
maybe_warnx("read of uncompressed size");
989
usize = buf[4] | buf[5] << 8 |
990
buf[6] << 16 | buf[7] << 24;
992
crc = buf[0] | buf[1] << 8 |
993
buf[2] << 16 | buf[3] << 24;
998
if (vflag && fd == -1)
1001
char *date = ctime(&ts);
1003
/* skip the day, 1/100th second, and year */
1006
printf("%5s %08x %11s ", "defla"/*XXX*/, crc, date);
1011
printf("%12llu %12llu ", (unsigned long long)out, (unsigned long long)in);
1012
print_ratio(in, out, stdout);
1013
printf(" %s\n", outfile);
1016
/* display the usage of NetBSD gzip */
1021
fprintf(stderr, "%s\n", gzip_version);
1023
"usage: %s [--gnu | --zlib] [-" OPT_LIST "] [<file> [<file> ...]]\n"
1024
" --gnu use GNU gzip (/bin/gzip)\n"
1025
" --zlib use zlib's implementation (default)\n"
1026
" -1 --fast fastest (worst) compression\n"
1027
" -2 .. -8 set compression level\n"
1028
" -9 --best best (slowest) compression\n"
1029
" -c --stdout write to stdout, keep original files\n"
1031
" -f --force force overwriting & compress links\n"
1032
" -l --list list compressed file contents\n"
1033
" -N --name save or restore original file name and time stamp\n"
1034
" -n --no-name don't save original file name or time stamp\n"
1035
" -m --no-timestamp don't save original time stamp\n"
1036
" -M --force-timestemp save the timestamp even if -n was passed\n"
1037
" -S .suf use suffix .suf instead of .gz\n"
1039
" -t --test test compressed file\n"
1040
" -q --quiet output no warnings\n"
1041
" -V --version display program version\n"
1042
" -v --verbose print extra statistics\n"
1043
" -h --help display this help\n"
1044
" \nzlib-specific options:\n"
1046
" --original-name NAME use NAME as the original file name\n"
1047
" -k --quirk QUIRK enable a format quirk (buggy-bsd, ntfs)\n"
1048
" -s --osflag set the OS flag to something different than 03 (Unix)\n",
1053
/* display the license information of NetBSD gzip */
1055
display_license(void)
1058
fprintf(stderr, "%s\n", gzip_version);
1059
fprintf(stderr, "%s\n", gzip_copyright);
1063
/* display the version of NetBSD gzip */
1065
display_version(void)
1068
fprintf(stderr, "%s\n", gzip_version);