Index: gzip.c =================================================================== RCS file: /cvsroot/src/usr.bin/gzip/gzip.c,v retrieving revision 1.112 diff -p -u -u -r1.112 gzip.c --- gzip.c 23 Aug 2017 13:04:17 -0000 1.112 +++ gzip.c 5 Dec 2017 03:01:27 -0000 @@ -143,6 +143,7 @@ static suffixes_t suffixes[] = { SUFFIX("-gz", ""), SUFFIX("-z", ""), SUFFIX("_z", ""), + SUFFIX(".zz", ""), SUFFIX(".taz", ".tar"), SUFFIX(".tgz", ".tar"), #ifndef NO_BZIP2_SUPPORT @@ -177,6 +178,7 @@ static int qflag; /* quiet mode */ static int rflag; /* recursive mode */ static int tflag; /* test */ static int vflag; /* verbose mode */ +static int zflag; /* zlib mode */ static sig_atomic_t print_info = 0; #else #define qflag 0 @@ -278,6 +280,7 @@ static const struct option longopts[] = { "test", no_argument, 0, 't' }, { "verbose", no_argument, 0, 'v' }, { "version", no_argument, 0, 'V' }, + { "zlib", no_argument, 0, 'z' }, { "fast", no_argument, 0, '1' }, { "best", no_argument, 0, '9' }, #if 0 @@ -322,7 +325,7 @@ main(int argc, char **argv) #ifdef SMALL #define OPT_LIST "123456789cdhlV" #else -#define OPT_LIST "123456789cdfhklNnqrS:tVv" +#define OPT_LIST "123456789cdfhklNnqrS:tVvz" #endif while ((ch = getopt_long(argc, argv, OPT_LIST, longopts, NULL)) != -1) { @@ -386,6 +389,11 @@ main(int argc, char **argv) case 'v': vflag = 1; break; + case 'z': + zflag = 1; + suffixes[0].zipped = ".zz"; + suffixes[0].ziplen = strlen(suffixes[0].zipped); + break; #endif default: usage(); @@ -537,6 +545,16 @@ copy_done: nargv[i++] = *(ac++); nargv[i] = NULL; } + +static uLong gz_crc32(uLong, const Bytef *, uInt); +/* use crc32 or alder32 depending on the file type */ +static uLong +gz_crc32(uLong crc, const Bytef *buf, uInt len) +{ + if (zflag) + return adler32(crc, buf, len); + return crc32(crc, buf, len); +} #endif /* compress input to output. Return bytes read, -1 on error */ @@ -576,20 +594,35 @@ gz_compress(int in, int out, off_t *gsiz 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, - numflag == 1 ? 4 : numflag == 9 ? 2 : 0, - OS_CODE, origname); - if (i >= BUFLEN) - /* this need PATH_MAX > BUFLEN ... */ - maybe_err("snprintf"); - if (*origname) - i++; + if (zflag == 0) { + 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, + numflag == 1 ? 4 : numflag == 9 ? 2 : 0, + OS_CODE, origname); + if (i >= BUFLEN) + /* this need PATH_MAX > BUFLEN ... */ + maybe_err("snprintf"); + if (*origname) + i++; + } else { + outbufp[0] = 0x78; /* 32K, deflate */ + if (numflag == 1) + outbufp[1] = 0; + else if (numflag >= 9) + outbufp[1] = 3; + else if (numflag >= 5) + outbufp[1] = 1; + else + outbufp[1] = 2; + outbufp[1] <<= 6; + outbufp[1] += 31 - (((outbufp[0] << 8) + outbufp[1]) % 31); + i = 2; + } #endif z.next_out = (unsigned char *)outbufp + i; @@ -603,7 +636,7 @@ gz_compress(int in, int out, off_t *gsiz goto out; } - crc = crc32(0L, Z_NULL, 0); + crc = gz_crc32(0L, Z_NULL, 0); for (;;) { if (z.avail_out == 0) { if (write_retry(out, outbufp, BUFLEN) != BUFLEN) { @@ -628,7 +661,7 @@ gz_compress(int in, int out, off_t *gsiz break; infile_newdata(in_size); - crc = crc32(crc, (const Bytef *)inbufp, (unsigned)in_size); + crc = gz_crc32(crc, (const Bytef *)inbufp, (unsigned)in_size); in_tot += in_size; z.next_in = (unsigned char *)inbufp; z.avail_in = in_size; @@ -676,17 +709,28 @@ gz_compress(int in, int out, off_t *gsiz goto out; } - i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c", - (int)crc & 0xff, - (int)(crc >> 8) & 0xff, - (int)(crc >> 16) & 0xff, - (int)(crc >> 24) & 0xff, - (int)in_tot & 0xff, - (int)(in_tot >> 8) & 0xff, - (int)(in_tot >> 16) & 0xff, - (int)(in_tot >> 24) & 0xff); - if (i != 8) - maybe_err("snprintf"); + if (zflag == 0) { + i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c", + (int)crc & 0xff, + (int)(crc >> 8) & 0xff, + (int)(crc >> 16) & 0xff, + (int)(crc >> 24) & 0xff, + (int)in_tot & 0xff, + (int)(in_tot >> 8) & 0xff, + (int)(in_tot >> 16) & 0xff, + (int)(in_tot >> 24) & 0xff); + if (i != 8) + maybe_err("snprintf"); + } else { + i = snprintf(outbufp, BUFLEN, "%c%c%c%c", + (int)crc & 0xff, + (int)(crc >> 8) & 0xff, + (int)(crc >> 16) & 0xff, + (int)(crc >> 24) & 0xff); + if (i != 4) + maybe_err("snprintf"); + + } #if 0 if (in_tot > 0xffffffff) maybe_warn("input file size >= 4GB cannot be saved"); @@ -815,7 +859,7 @@ gz_uncompress(int in, int out, char *pre ADVANCE(); state++; out_sub_tot = 0; - crc = crc32(0L, Z_NULL, 0); + crc = gz_crc32(0L, Z_NULL, 0); break; case GZSTATE_MAGIC1: @@ -952,7 +996,7 @@ gz_uncompress(int in, int out, char *pre wr = BUFLEN - z.avail_out; if (wr != 0) { - crc = crc32(crc, (const Bytef *)outbufp, (unsigned)wr); + crc = gz_crc32(crc, (const Bytef *)outbufp, (unsigned)wr); if ( #ifndef SMALL /* don't write anything with -t */