12569963fSbluhm /* minigzip.c -- simulate gzip using the zlib compression library
22569963fSbluhm * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly
32569963fSbluhm * For conditions of distribution and use, see copyright notice in zlib.h
42569963fSbluhm */
52569963fSbluhm
62569963fSbluhm /*
72569963fSbluhm * minigzip is a minimal implementation of the gzip utility. This is
82569963fSbluhm * only an example of using zlib and isn't meant to replace the
92569963fSbluhm * full-featured gzip. No attempt is made to deal with file systems
102569963fSbluhm * limiting names to 14 or 8+3 characters, etc... Error checking is
112569963fSbluhm * very limited. So use minigzip only for testing; use gzip for the
122569963fSbluhm * real thing. On MSDOS, use only on file names without extension
132569963fSbluhm * or in pipe mode.
142569963fSbluhm */
152569963fSbluhm
16*b0b511c0Stb /* @(#) $Id: minigzip.c,v 1.2 2023/11/18 22:40:14 tb Exp $ */
172569963fSbluhm
182569963fSbluhm #include "zlib.h"
192569963fSbluhm #include <stdio.h>
202569963fSbluhm
212569963fSbluhm #ifdef STDC
222569963fSbluhm # include <string.h>
232569963fSbluhm # include <stdlib.h>
242569963fSbluhm #endif
252569963fSbluhm
262569963fSbluhm #ifdef USE_MMAP
272569963fSbluhm # include <sys/types.h>
282569963fSbluhm # include <sys/mman.h>
292569963fSbluhm # include <sys/stat.h>
302569963fSbluhm #endif
312569963fSbluhm
322569963fSbluhm #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
332569963fSbluhm # include <fcntl.h>
342569963fSbluhm # include <io.h>
352569963fSbluhm # ifdef UNDER_CE
362569963fSbluhm # include <stdlib.h>
372569963fSbluhm # endif
382569963fSbluhm # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
392569963fSbluhm #else
402569963fSbluhm # define SET_BINARY_MODE(file)
412569963fSbluhm #endif
422569963fSbluhm
432569963fSbluhm #if defined(_MSC_VER) && _MSC_VER < 1900
442569963fSbluhm # define snprintf _snprintf
452569963fSbluhm #endif
462569963fSbluhm
472569963fSbluhm #ifdef VMS
482569963fSbluhm # define unlink delete
492569963fSbluhm # define GZ_SUFFIX "-gz"
502569963fSbluhm #endif
512569963fSbluhm #ifdef RISCOS
522569963fSbluhm # define unlink remove
532569963fSbluhm # define GZ_SUFFIX "-gz"
542569963fSbluhm # define fileno(file) file->__file
552569963fSbluhm #endif
562569963fSbluhm #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
572569963fSbluhm # include <unix.h> /* for fileno */
582569963fSbluhm #endif
592569963fSbluhm
602569963fSbluhm #if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
612569963fSbluhm #ifndef WIN32 /* unlink already in stdio.h for WIN32 */
62*b0b511c0Stb extern int unlink(const char *);
632569963fSbluhm #endif
642569963fSbluhm #endif
652569963fSbluhm
662569963fSbluhm #if defined(UNDER_CE)
672569963fSbluhm # include <windows.h>
682569963fSbluhm # define perror(s) pwinerror(s)
692569963fSbluhm
702569963fSbluhm /* Map the Windows error number in ERROR to a locale-dependent error
712569963fSbluhm message string and return a pointer to it. Typically, the values
722569963fSbluhm for ERROR come from GetLastError.
732569963fSbluhm
742569963fSbluhm The string pointed to shall not be modified by the application,
752569963fSbluhm but may be overwritten by a subsequent call to strwinerror
762569963fSbluhm
772569963fSbluhm The strwinerror function does not change the current setting
782569963fSbluhm of GetLastError. */
792569963fSbluhm
strwinerror(error)802569963fSbluhm static char *strwinerror (error)
812569963fSbluhm DWORD error;
822569963fSbluhm {
832569963fSbluhm static char buf[1024];
842569963fSbluhm
852569963fSbluhm wchar_t *msgbuf;
862569963fSbluhm DWORD lasterr = GetLastError();
872569963fSbluhm DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
882569963fSbluhm | FORMAT_MESSAGE_ALLOCATE_BUFFER,
892569963fSbluhm NULL,
902569963fSbluhm error,
912569963fSbluhm 0, /* Default language */
922569963fSbluhm (LPVOID)&msgbuf,
932569963fSbluhm 0,
942569963fSbluhm NULL);
952569963fSbluhm if (chars != 0) {
962569963fSbluhm /* If there is an \r\n appended, zap it. */
972569963fSbluhm if (chars >= 2
982569963fSbluhm && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
992569963fSbluhm chars -= 2;
1002569963fSbluhm msgbuf[chars] = 0;
1012569963fSbluhm }
1022569963fSbluhm
1032569963fSbluhm if (chars > sizeof (buf) - 1) {
1042569963fSbluhm chars = sizeof (buf) - 1;
1052569963fSbluhm msgbuf[chars] = 0;
1062569963fSbluhm }
1072569963fSbluhm
1082569963fSbluhm wcstombs(buf, msgbuf, chars + 1);
1092569963fSbluhm LocalFree(msgbuf);
1102569963fSbluhm }
1112569963fSbluhm else {
1122569963fSbluhm sprintf(buf, "unknown win32 error (%ld)", error);
1132569963fSbluhm }
1142569963fSbluhm
1152569963fSbluhm SetLastError(lasterr);
1162569963fSbluhm return buf;
1172569963fSbluhm }
1182569963fSbluhm
pwinerror(s)1192569963fSbluhm static void pwinerror (s)
1202569963fSbluhm const char *s;
1212569963fSbluhm {
1222569963fSbluhm if (s && *s)
1232569963fSbluhm fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
1242569963fSbluhm else
1252569963fSbluhm fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
1262569963fSbluhm }
1272569963fSbluhm
1282569963fSbluhm #endif /* UNDER_CE */
1292569963fSbluhm
1302569963fSbluhm #ifndef GZ_SUFFIX
1312569963fSbluhm # define GZ_SUFFIX ".gz"
1322569963fSbluhm #endif
1332569963fSbluhm #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
1342569963fSbluhm
1352569963fSbluhm #define BUFLEN 16384
1362569963fSbluhm #define MAX_NAME_LEN 1024
1372569963fSbluhm
1382569963fSbluhm #ifdef MAXSEG_64K
1392569963fSbluhm # define local static
1402569963fSbluhm /* Needed for systems with limitation on stack size. */
1412569963fSbluhm #else
1422569963fSbluhm # define local
1432569963fSbluhm #endif
1442569963fSbluhm
1452569963fSbluhm #ifdef Z_SOLO
1462569963fSbluhm /* for Z_SOLO, create simplified gz* functions using deflate and inflate */
1472569963fSbluhm
1482569963fSbluhm #if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
1492569963fSbluhm # include <unistd.h> /* for unlink() */
1502569963fSbluhm #endif
1512569963fSbluhm
myalloc(void * q,unsigned n,unsigned m)152*b0b511c0Stb static void *myalloc(void *q, unsigned n, unsigned m) {
1532569963fSbluhm (void)q;
1542569963fSbluhm return calloc(n, m);
1552569963fSbluhm }
1562569963fSbluhm
myfree(void * q,void * p)157*b0b511c0Stb static void myfree(void *q, void *p) {
1582569963fSbluhm (void)q;
1592569963fSbluhm free(p);
1602569963fSbluhm }
1612569963fSbluhm
1622569963fSbluhm typedef struct gzFile_s {
1632569963fSbluhm FILE *file;
1642569963fSbluhm int write;
1652569963fSbluhm int err;
1662569963fSbluhm char *msg;
1672569963fSbluhm z_stream strm;
1682569963fSbluhm } *gzFile;
1692569963fSbluhm
gz_open(const char * path,int fd,const char * mode)170*b0b511c0Stb static gzFile gz_open(const char *path, int fd, const char *mode) {
1712569963fSbluhm gzFile gz;
1722569963fSbluhm int ret;
1732569963fSbluhm
1742569963fSbluhm gz = malloc(sizeof(struct gzFile_s));
1752569963fSbluhm if (gz == NULL)
1762569963fSbluhm return NULL;
1772569963fSbluhm gz->write = strchr(mode, 'w') != NULL;
1782569963fSbluhm gz->strm.zalloc = myalloc;
1792569963fSbluhm gz->strm.zfree = myfree;
1802569963fSbluhm gz->strm.opaque = Z_NULL;
1812569963fSbluhm if (gz->write)
1822569963fSbluhm ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
1832569963fSbluhm else {
1842569963fSbluhm gz->strm.next_in = 0;
1852569963fSbluhm gz->strm.avail_in = Z_NULL;
1862569963fSbluhm ret = inflateInit2(&(gz->strm), 15 + 16);
1872569963fSbluhm }
1882569963fSbluhm if (ret != Z_OK) {
1892569963fSbluhm free(gz);
1902569963fSbluhm return NULL;
1912569963fSbluhm }
1922569963fSbluhm gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
1932569963fSbluhm fopen(path, gz->write ? "wb" : "rb");
1942569963fSbluhm if (gz->file == NULL) {
1952569963fSbluhm gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
1962569963fSbluhm free(gz);
1972569963fSbluhm return NULL;
1982569963fSbluhm }
1992569963fSbluhm gz->err = 0;
2002569963fSbluhm gz->msg = "";
2012569963fSbluhm return gz;
2022569963fSbluhm }
2032569963fSbluhm
gzopen(const char * path,const char * mode)204*b0b511c0Stb static gzFile gzopen(const char *path, const char *mode) {
205*b0b511c0Stb return gz_open(path, -1, mode);
206*b0b511c0Stb }
2072569963fSbluhm
gzdopen(int fd,const char * mode)208*b0b511c0Stb static gzFile gzdopen(int fd, const char *mode) {
209*b0b511c0Stb return gz_open(NULL, fd, mode);
210*b0b511c0Stb }
211*b0b511c0Stb
gzwrite(gzFile gz,const void * buf,unsigned len)212*b0b511c0Stb static int gzwrite(gzFile gz, const void *buf, unsigned len) {
2132569963fSbluhm z_stream *strm;
2142569963fSbluhm unsigned char out[BUFLEN];
2152569963fSbluhm
2162569963fSbluhm if (gz == NULL || !gz->write)
2172569963fSbluhm return 0;
2182569963fSbluhm strm = &(gz->strm);
2192569963fSbluhm strm->next_in = (void *)buf;
2202569963fSbluhm strm->avail_in = len;
2212569963fSbluhm do {
2222569963fSbluhm strm->next_out = out;
2232569963fSbluhm strm->avail_out = BUFLEN;
2242569963fSbluhm (void)deflate(strm, Z_NO_FLUSH);
2252569963fSbluhm fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
2262569963fSbluhm } while (strm->avail_out == 0);
2272569963fSbluhm return len;
2282569963fSbluhm }
2292569963fSbluhm
gzread(gzFile gz,void * buf,unsigned len)230*b0b511c0Stb static int gzread(gzFile gz, void *buf, unsigned len) {
2312569963fSbluhm int ret;
2322569963fSbluhm unsigned got;
2332569963fSbluhm unsigned char in[1];
2342569963fSbluhm z_stream *strm;
2352569963fSbluhm
2362569963fSbluhm if (gz == NULL || gz->write)
2372569963fSbluhm return 0;
2382569963fSbluhm if (gz->err)
2392569963fSbluhm return 0;
2402569963fSbluhm strm = &(gz->strm);
2412569963fSbluhm strm->next_out = (void *)buf;
2422569963fSbluhm strm->avail_out = len;
2432569963fSbluhm do {
2442569963fSbluhm got = fread(in, 1, 1, gz->file);
2452569963fSbluhm if (got == 0)
2462569963fSbluhm break;
2472569963fSbluhm strm->next_in = in;
2482569963fSbluhm strm->avail_in = 1;
2492569963fSbluhm ret = inflate(strm, Z_NO_FLUSH);
2502569963fSbluhm if (ret == Z_DATA_ERROR) {
2512569963fSbluhm gz->err = Z_DATA_ERROR;
2522569963fSbluhm gz->msg = strm->msg;
2532569963fSbluhm return 0;
2542569963fSbluhm }
2552569963fSbluhm if (ret == Z_STREAM_END)
2562569963fSbluhm inflateReset(strm);
2572569963fSbluhm } while (strm->avail_out);
2582569963fSbluhm return len - strm->avail_out;
2592569963fSbluhm }
2602569963fSbluhm
gzclose(gzFile gz)261*b0b511c0Stb static int gzclose(gzFile gz) {
2622569963fSbluhm z_stream *strm;
2632569963fSbluhm unsigned char out[BUFLEN];
2642569963fSbluhm
2652569963fSbluhm if (gz == NULL)
2662569963fSbluhm return Z_STREAM_ERROR;
2672569963fSbluhm strm = &(gz->strm);
2682569963fSbluhm if (gz->write) {
2692569963fSbluhm strm->next_in = Z_NULL;
2702569963fSbluhm strm->avail_in = 0;
2712569963fSbluhm do {
2722569963fSbluhm strm->next_out = out;
2732569963fSbluhm strm->avail_out = BUFLEN;
2742569963fSbluhm (void)deflate(strm, Z_FINISH);
2752569963fSbluhm fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
2762569963fSbluhm } while (strm->avail_out == 0);
2772569963fSbluhm deflateEnd(strm);
2782569963fSbluhm }
2792569963fSbluhm else
2802569963fSbluhm inflateEnd(strm);
2812569963fSbluhm fclose(gz->file);
2822569963fSbluhm free(gz);
2832569963fSbluhm return Z_OK;
2842569963fSbluhm }
2852569963fSbluhm
gzerror(gzFile gz,int * err)286*b0b511c0Stb static const char *gzerror(gzFile gz, int *err) {
2872569963fSbluhm *err = gz->err;
2882569963fSbluhm return gz->msg;
2892569963fSbluhm }
2902569963fSbluhm
2912569963fSbluhm #endif
2922569963fSbluhm
2932569963fSbluhm static char *prog;
2942569963fSbluhm
2952569963fSbluhm /* ===========================================================================
2962569963fSbluhm * Display error message and exit
2972569963fSbluhm */
error(const char * msg)298*b0b511c0Stb static void error(const char *msg) {
2992569963fSbluhm fprintf(stderr, "%s: %s\n", prog, msg);
3002569963fSbluhm exit(1);
3012569963fSbluhm }
3022569963fSbluhm
3032569963fSbluhm #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
3042569963fSbluhm
3052569963fSbluhm /* Try compressing the input file at once using mmap. Return Z_OK if
3062569963fSbluhm * if success, Z_ERRNO otherwise.
3072569963fSbluhm */
gz_compress_mmap(FILE * in,gzFile out)308*b0b511c0Stb static int gz_compress_mmap(FILE *in, gzFile out) {
3092569963fSbluhm int len;
3102569963fSbluhm int err;
3112569963fSbluhm int ifd = fileno(in);
3122569963fSbluhm caddr_t buf; /* mmap'ed buffer for the entire input file */
3132569963fSbluhm off_t buf_len; /* length of the input file */
3142569963fSbluhm struct stat sb;
3152569963fSbluhm
3162569963fSbluhm /* Determine the size of the file, needed for mmap: */
3172569963fSbluhm if (fstat(ifd, &sb) < 0) return Z_ERRNO;
3182569963fSbluhm buf_len = sb.st_size;
3192569963fSbluhm if (buf_len <= 0) return Z_ERRNO;
3202569963fSbluhm
3212569963fSbluhm /* Now do the actual mmap: */
3222569963fSbluhm buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
3232569963fSbluhm if (buf == (caddr_t)(-1)) return Z_ERRNO;
3242569963fSbluhm
3252569963fSbluhm /* Compress the whole file at once: */
3262569963fSbluhm len = gzwrite(out, (char *)buf, (unsigned)buf_len);
3272569963fSbluhm
3282569963fSbluhm if (len != (int)buf_len) error(gzerror(out, &err));
3292569963fSbluhm
3302569963fSbluhm munmap(buf, buf_len);
3312569963fSbluhm fclose(in);
3322569963fSbluhm if (gzclose(out) != Z_OK) error("failed gzclose");
3332569963fSbluhm return Z_OK;
3342569963fSbluhm }
3352569963fSbluhm #endif /* USE_MMAP */
3362569963fSbluhm
3372569963fSbluhm /* ===========================================================================
338*b0b511c0Stb * Compress input to output then close both files.
339*b0b511c0Stb */
340*b0b511c0Stb
gz_compress(FILE * in,gzFile out)341*b0b511c0Stb static void gz_compress(FILE *in, gzFile out) {
342*b0b511c0Stb local char buf[BUFLEN];
343*b0b511c0Stb int len;
344*b0b511c0Stb int err;
345*b0b511c0Stb
346*b0b511c0Stb #ifdef USE_MMAP
347*b0b511c0Stb /* Try first compressing with mmap. If mmap fails (minigzip used in a
348*b0b511c0Stb * pipe), use the normal fread loop.
349*b0b511c0Stb */
350*b0b511c0Stb if (gz_compress_mmap(in, out) == Z_OK) return;
351*b0b511c0Stb #endif
352*b0b511c0Stb for (;;) {
353*b0b511c0Stb len = (int)fread(buf, 1, sizeof(buf), in);
354*b0b511c0Stb if (ferror(in)) {
355*b0b511c0Stb perror("fread");
356*b0b511c0Stb exit(1);
357*b0b511c0Stb }
358*b0b511c0Stb if (len == 0) break;
359*b0b511c0Stb
360*b0b511c0Stb if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
361*b0b511c0Stb }
362*b0b511c0Stb fclose(in);
363*b0b511c0Stb if (gzclose(out) != Z_OK) error("failed gzclose");
364*b0b511c0Stb }
365*b0b511c0Stb
366*b0b511c0Stb /* ===========================================================================
3672569963fSbluhm * Uncompress input to output then close both files.
3682569963fSbluhm */
gz_uncompress(gzFile in,FILE * out)369*b0b511c0Stb static void gz_uncompress(gzFile in, FILE *out) {
3702569963fSbluhm local char buf[BUFLEN];
3712569963fSbluhm int len;
3722569963fSbluhm int err;
3732569963fSbluhm
3742569963fSbluhm for (;;) {
3752569963fSbluhm len = gzread(in, buf, sizeof(buf));
3762569963fSbluhm if (len < 0) error (gzerror(in, &err));
3772569963fSbluhm if (len == 0) break;
3782569963fSbluhm
3792569963fSbluhm if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
3802569963fSbluhm error("failed fwrite");
3812569963fSbluhm }
3822569963fSbluhm }
3832569963fSbluhm if (fclose(out)) error("failed fclose");
3842569963fSbluhm
3852569963fSbluhm if (gzclose(in) != Z_OK) error("failed gzclose");
3862569963fSbluhm }
3872569963fSbluhm
3882569963fSbluhm
3892569963fSbluhm /* ===========================================================================
3902569963fSbluhm * Compress the given file: create a corresponding .gz file and remove the
3912569963fSbluhm * original.
3922569963fSbluhm */
file_compress(char * file,char * mode)393*b0b511c0Stb static void file_compress(char *file, char *mode) {
3942569963fSbluhm local char outfile[MAX_NAME_LEN];
3952569963fSbluhm FILE *in;
3962569963fSbluhm gzFile out;
3972569963fSbluhm
3982569963fSbluhm if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
3992569963fSbluhm fprintf(stderr, "%s: filename too long\n", prog);
4002569963fSbluhm exit(1);
4012569963fSbluhm }
4022569963fSbluhm
4032569963fSbluhm #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
4042569963fSbluhm snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
4052569963fSbluhm #else
4062569963fSbluhm strcpy(outfile, file);
4072569963fSbluhm strcat(outfile, GZ_SUFFIX);
4082569963fSbluhm #endif
4092569963fSbluhm
4102569963fSbluhm in = fopen(file, "rb");
4112569963fSbluhm if (in == NULL) {
4122569963fSbluhm perror(file);
4132569963fSbluhm exit(1);
4142569963fSbluhm }
4152569963fSbluhm out = gzopen(outfile, mode);
4162569963fSbluhm if (out == NULL) {
4172569963fSbluhm fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
4182569963fSbluhm exit(1);
4192569963fSbluhm }
4202569963fSbluhm gz_compress(in, out);
4212569963fSbluhm
4222569963fSbluhm unlink(file);
4232569963fSbluhm }
4242569963fSbluhm
4252569963fSbluhm
4262569963fSbluhm /* ===========================================================================
4272569963fSbluhm * Uncompress the given file and remove the original.
4282569963fSbluhm */
file_uncompress(char * file)429*b0b511c0Stb static void file_uncompress(char *file) {
4302569963fSbluhm local char buf[MAX_NAME_LEN];
4312569963fSbluhm char *infile, *outfile;
4322569963fSbluhm FILE *out;
4332569963fSbluhm gzFile in;
434*b0b511c0Stb z_size_t len = strlen(file);
4352569963fSbluhm
4362569963fSbluhm if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
4372569963fSbluhm fprintf(stderr, "%s: filename too long\n", prog);
4382569963fSbluhm exit(1);
4392569963fSbluhm }
4402569963fSbluhm
4412569963fSbluhm #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
4422569963fSbluhm snprintf(buf, sizeof(buf), "%s", file);
4432569963fSbluhm #else
4442569963fSbluhm strcpy(buf, file);
4452569963fSbluhm #endif
4462569963fSbluhm
4472569963fSbluhm if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
4482569963fSbluhm infile = file;
4492569963fSbluhm outfile = buf;
4502569963fSbluhm outfile[len-3] = '\0';
4512569963fSbluhm } else {
4522569963fSbluhm outfile = file;
4532569963fSbluhm infile = buf;
4542569963fSbluhm #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
4552569963fSbluhm snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
4562569963fSbluhm #else
4572569963fSbluhm strcat(infile, GZ_SUFFIX);
4582569963fSbluhm #endif
4592569963fSbluhm }
4602569963fSbluhm in = gzopen(infile, "rb");
4612569963fSbluhm if (in == NULL) {
4622569963fSbluhm fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
4632569963fSbluhm exit(1);
4642569963fSbluhm }
4652569963fSbluhm out = fopen(outfile, "wb");
4662569963fSbluhm if (out == NULL) {
4672569963fSbluhm perror(file);
4682569963fSbluhm exit(1);
4692569963fSbluhm }
4702569963fSbluhm
4712569963fSbluhm gz_uncompress(in, out);
4722569963fSbluhm
4732569963fSbluhm unlink(infile);
4742569963fSbluhm }
4752569963fSbluhm
4762569963fSbluhm
4772569963fSbluhm /* ===========================================================================
4782569963fSbluhm * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
4792569963fSbluhm * -c : write to standard output
4802569963fSbluhm * -d : decompress
4812569963fSbluhm * -f : compress with Z_FILTERED
4822569963fSbluhm * -h : compress with Z_HUFFMAN_ONLY
4832569963fSbluhm * -r : compress with Z_RLE
4842569963fSbluhm * -1 to -9 : compression level
4852569963fSbluhm */
4862569963fSbluhm
main(int argc,char * argv[])487*b0b511c0Stb int main(int argc, char *argv[]) {
4882569963fSbluhm int copyout = 0;
4892569963fSbluhm int uncompr = 0;
4902569963fSbluhm gzFile file;
4912569963fSbluhm char *bname, outmode[20];
4922569963fSbluhm
4932569963fSbluhm #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
4942569963fSbluhm snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
4952569963fSbluhm #else
4962569963fSbluhm strcpy(outmode, "wb6 ");
4972569963fSbluhm #endif
4982569963fSbluhm
4992569963fSbluhm prog = argv[0];
5002569963fSbluhm bname = strrchr(argv[0], '/');
5012569963fSbluhm if (bname)
5022569963fSbluhm bname++;
5032569963fSbluhm else
5042569963fSbluhm bname = argv[0];
5052569963fSbluhm argc--, argv++;
5062569963fSbluhm
5072569963fSbluhm if (!strcmp(bname, "gunzip"))
5082569963fSbluhm uncompr = 1;
5092569963fSbluhm else if (!strcmp(bname, "zcat"))
5102569963fSbluhm copyout = uncompr = 1;
5112569963fSbluhm
5122569963fSbluhm while (argc > 0) {
5132569963fSbluhm if (strcmp(*argv, "-c") == 0)
5142569963fSbluhm copyout = 1;
5152569963fSbluhm else if (strcmp(*argv, "-d") == 0)
5162569963fSbluhm uncompr = 1;
5172569963fSbluhm else if (strcmp(*argv, "-f") == 0)
5182569963fSbluhm outmode[3] = 'f';
5192569963fSbluhm else if (strcmp(*argv, "-h") == 0)
5202569963fSbluhm outmode[3] = 'h';
5212569963fSbluhm else if (strcmp(*argv, "-r") == 0)
5222569963fSbluhm outmode[3] = 'R';
5232569963fSbluhm else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
5242569963fSbluhm (*argv)[2] == 0)
5252569963fSbluhm outmode[2] = (*argv)[1];
5262569963fSbluhm else
5272569963fSbluhm break;
5282569963fSbluhm argc--, argv++;
5292569963fSbluhm }
5302569963fSbluhm if (outmode[3] == ' ')
5312569963fSbluhm outmode[3] = 0;
5322569963fSbluhm if (argc == 0) {
5332569963fSbluhm SET_BINARY_MODE(stdin);
5342569963fSbluhm SET_BINARY_MODE(stdout);
5352569963fSbluhm if (uncompr) {
5362569963fSbluhm file = gzdopen(fileno(stdin), "rb");
5372569963fSbluhm if (file == NULL) error("can't gzdopen stdin");
5382569963fSbluhm gz_uncompress(file, stdout);
5392569963fSbluhm } else {
5402569963fSbluhm file = gzdopen(fileno(stdout), outmode);
5412569963fSbluhm if (file == NULL) error("can't gzdopen stdout");
5422569963fSbluhm gz_compress(stdin, file);
5432569963fSbluhm }
5442569963fSbluhm } else {
5452569963fSbluhm if (copyout) {
5462569963fSbluhm SET_BINARY_MODE(stdout);
5472569963fSbluhm }
5482569963fSbluhm do {
5492569963fSbluhm if (uncompr) {
5502569963fSbluhm if (copyout) {
5512569963fSbluhm file = gzopen(*argv, "rb");
5522569963fSbluhm if (file == NULL)
5532569963fSbluhm fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
5542569963fSbluhm else
5552569963fSbluhm gz_uncompress(file, stdout);
5562569963fSbluhm } else {
5572569963fSbluhm file_uncompress(*argv);
5582569963fSbluhm }
5592569963fSbluhm } else {
5602569963fSbluhm if (copyout) {
5612569963fSbluhm FILE * in = fopen(*argv, "rb");
5622569963fSbluhm
5632569963fSbluhm if (in == NULL) {
5642569963fSbluhm perror(*argv);
5652569963fSbluhm } else {
5662569963fSbluhm file = gzdopen(fileno(stdout), outmode);
5672569963fSbluhm if (file == NULL) error("can't gzdopen stdout");
5682569963fSbluhm
5692569963fSbluhm gz_compress(in, file);
5702569963fSbluhm }
5712569963fSbluhm
5722569963fSbluhm } else {
5732569963fSbluhm file_compress(*argv, outmode);
5742569963fSbluhm }
5752569963fSbluhm }
5762569963fSbluhm } while (argv++, --argc);
5772569963fSbluhm }
5782569963fSbluhm return 0;
5792569963fSbluhm }
580