/* minigzip.c -- simulate gzip using the zlib compression library * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* * minigzip is a minimal implementation of the gzip utility. This is * only an example of using zlib and isn't meant to replace the * full-featured gzip. No attempt is made to deal with file systems * limiting names to 14 or 8+3 characters, etc... Error checking is * very limited. So use minigzip only for testing; use gzip for the * real thing. On MSDOS, use only on file names without extension * or in pipe mode. */ /* @(#) $Id$ */ #include "zlib.h" #include #ifdef STDC # include # include #endif #ifndef GZ_SUFFIX # define GZ_SUFFIX ".gz" #endif #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) #define BUFLEN 16384 #define MAX_NAME_LEN 1024 #ifdef MAXSEG_64K # define local static /* Needed for systems with limitation on stack size. */ #else # define local #endif static char *prog; void error OF((const char *msg)); void gz_compress OF((FILE *in, gzFile out)); void gz_uncompress OF((gzFile in, FILE *out)); void file_compress OF((char *file, char *mode)); void file_uncompress OF((char *file)); int main OF((int argc, char *argv[])); /* =========================================================================== * Compress input to output then close both files. */ void gz_compress(in, out) FILE *in; gzFile out; { local char buf[BUFLEN]; int len; int ret = 0; for (;;) { len = (int)fread(buf, 1, sizeof(buf), in); if (len == 0) break; ret = gzwrite(out, buf, (unsigned)len); if (ret != len) printf("wrong gzwrite:%d,ret:%d\n", len, ret); } fclose(in); gzclose(out); } /* =========================================================================== * Compress the given file: create a corresponding .gz file and remove the * original. */ void file_compress(file, mode) char *file; char *mode; { local char outfile[MAX_NAME_LEN]; FILE *in; gzFile out; if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { fprintf(stderr, "%s: filename too long\n", prog); exit(1); } #if !defined(NO_snprintf) && !defined(NO_vsnprintf) snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); #else strcpy(outfile, file); strcat(outfile, GZ_SUFFIX); #endif in = fopen(file, "rb"); if (in == NULL) { perror(file); exit(1); } out = gzopen(outfile, mode); if (out == NULL) { fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); exit(1); } gz_compress(in, out); unlink(file); } /* =========================================================================== * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] * -c : write to standard output * -d : decompress * -f : compress with Z_FILTERED * -h : compress with Z_HUFFMAN_ONLY * -r : compress with Z_RLE * -1 to -9 : compression level */ int main(argc, argv) int argc; char *argv[]; { int copyout = 0; int uncompr = 0; gzFile file; char *bname, outmode[20]; #if !defined(NO_snprintf) && !defined(NO_vsnprintf) snprintf(outmode, sizeof(outmode), "%s", "wb6 "); #else strcpy(outmode, "wb6 "); #endif prog = argv[0]; bname = strrchr(argv[0], '/'); if (bname) bname++; else bname = argv[0]; argc--, argv++; if (!strcmp(bname, "gunzip")) uncompr = 1; else if (!strcmp(bname, "zcat")) copyout = uncompr = 1; while (argc > 0) { if (strcmp(*argv, "-c") == 0) copyout = 1; else if (strcmp(*argv, "-d") == 0) uncompr = 1; else if (strcmp(*argv, "-f") == 0) outmode[3] = 'f'; else if (strcmp(*argv, "-h") == 0) outmode[3] = 'h'; else if (strcmp(*argv, "-r") == 0) outmode[3] = 'R'; else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && (*argv)[2] == 0) outmode[2] = (*argv)[1]; else break; argc--, argv++; } if (outmode[3] == ' ') outmode[3] = 0; { do { { if (copyout) { FILE * in = fopen(*argv, "rb"); if (in == NULL) { perror(*argv); } else { file = gzdopen(fileno(stdout), outmode); if (file == NULL) printf("can't gzdopen stdout"); gz_compress(in, file); } } else { printf("outmode:%s\n",outmode); file_compress(*argv, outmode); } } } while (argv++, --argc); } return 0; }