The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/zlib/test/minigzip.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* minigzip.c -- simulate gzip using the zlib compression library
    2  * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly
    3  * For conditions of distribution and use, see copyright notice in zlib.h
    4  */
    5 
    6 /*
    7  * minigzip is a minimal implementation of the gzip utility. This is
    8  * only an example of using zlib and isn't meant to replace the
    9  * full-featured gzip. No attempt is made to deal with file systems
   10  * limiting names to 14 or 8+3 characters, etc... Error checking is
   11  * very limited. So use minigzip only for testing; use gzip for the
   12  * real thing. On MSDOS, use only on file names without extension
   13  * or in pipe mode.
   14  */
   15 
   16 /* @(#) $Id$ */
   17 
   18 #include "zlib.h"
   19 #include <stdio.h>
   20 
   21 #ifdef STDC
   22 #  include <string.h>
   23 #  include <stdlib.h>
   24 #endif
   25 
   26 #ifdef USE_MMAP
   27 #  include <sys/types.h>
   28 #  include <sys/mman.h>
   29 #  include <sys/stat.h>
   30 #endif
   31 
   32 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
   33 #  include <fcntl.h>
   34 #  include <io.h>
   35 #  ifdef UNDER_CE
   36 #    include <stdlib.h>
   37 #  endif
   38 #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
   39 #else
   40 #  define SET_BINARY_MODE(file)
   41 #endif
   42 
   43 #if defined(_MSC_VER) && _MSC_VER < 1900
   44 #  define snprintf _snprintf
   45 #endif
   46 
   47 #ifdef VMS
   48 #  define unlink delete
   49 #  define GZ_SUFFIX "-gz"
   50 #endif
   51 #ifdef RISCOS
   52 #  define unlink remove
   53 #  define GZ_SUFFIX "-gz"
   54 #  define fileno(file) file->__file
   55 #endif
   56 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
   57 #  include <unix.h> /* for fileno */
   58 #endif
   59 
   60 #if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
   61 #ifndef WIN32 /* unlink already in stdio.h for WIN32 */
   62   extern int unlink OF((const char *));
   63 #endif
   64 #endif
   65 
   66 #if defined(UNDER_CE)
   67 #  include <windows.h>
   68 #  define perror(s) pwinerror(s)
   69 
   70 /* Map the Windows error number in ERROR to a locale-dependent error
   71    message string and return a pointer to it.  Typically, the values
   72    for ERROR come from GetLastError.
   73 
   74    The string pointed to shall not be modified by the application,
   75    but may be overwritten by a subsequent call to strwinerror
   76 
   77    The strwinerror function does not change the current setting
   78    of GetLastError.  */
   79 
   80 static char *strwinerror (error)
   81      DWORD error;
   82 {
   83     static char buf[1024];
   84 
   85     wchar_t *msgbuf;
   86     DWORD lasterr = GetLastError();
   87     DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
   88         | FORMAT_MESSAGE_ALLOCATE_BUFFER,
   89         NULL,
   90         error,
   91         0, /* Default language */
   92         (LPVOID)&msgbuf,
   93         0,
   94         NULL);
   95     if (chars != 0) {
   96         /* If there is an \r\n appended, zap it.  */
   97         if (chars >= 2
   98             && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
   99             chars -= 2;
  100             msgbuf[chars] = 0;
  101         }
  102 
  103         if (chars > sizeof (buf) - 1) {
  104             chars = sizeof (buf) - 1;
  105             msgbuf[chars] = 0;
  106         }
  107 
  108         wcstombs(buf, msgbuf, chars + 1);
  109         LocalFree(msgbuf);
  110     }
  111     else {
  112         sprintf(buf, "unknown win32 error (%ld)", error);
  113     }
  114 
  115     SetLastError(lasterr);
  116     return buf;
  117 }
  118 
  119 static void pwinerror (s)
  120     const char *s;
  121 {
  122     if (s && *s)
  123         fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
  124     else
  125         fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
  126 }
  127 
  128 #endif /* UNDER_CE */
  129 
  130 #ifndef GZ_SUFFIX
  131 #  define GZ_SUFFIX ".gz"
  132 #endif
  133 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
  134 
  135 #define BUFLEN      16384
  136 #define MAX_NAME_LEN 1024
  137 
  138 #ifdef MAXSEG_64K
  139 #  define local static
  140    /* Needed for systems with limitation on stack size. */
  141 #else
  142 #  define local
  143 #endif
  144 
  145 #ifdef Z_SOLO
  146 /* for Z_SOLO, create simplified gz* functions using deflate and inflate */
  147 
  148 #if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
  149 #  include <unistd.h>       /* for unlink() */
  150 #endif
  151 
  152 void *myalloc OF((void *, unsigned, unsigned));
  153 void myfree OF((void *, void *));
  154 
  155 void *myalloc(q, n, m)
  156     void *q;
  157     unsigned n, m;
  158 {
  159     (void)q;
  160     return calloc(n, m);
  161 }
  162 
  163 void myfree(q, p)
  164     void *q, *p;
  165 {
  166     (void)q;
  167     free(p);
  168 }
  169 
  170 typedef struct gzFile_s {
  171     FILE *file;
  172     int write;
  173     int err;
  174     char *msg;
  175     z_stream strm;
  176 } *gzFile;
  177 
  178 gzFile gzopen OF((const char *, const char *));
  179 gzFile gzdopen OF((int, const char *));
  180 gzFile gz_open OF((const char *, int, const char *));
  181 
  182 gzFile gzopen(path, mode)
  183 const char *path;
  184 const char *mode;
  185 {
  186     return gz_open(path, -1, mode);
  187 }
  188 
  189 gzFile gzdopen(fd, mode)
  190 int fd;
  191 const char *mode;
  192 {
  193     return gz_open(NULL, fd, mode);
  194 }
  195 
  196 gzFile gz_open(path, fd, mode)
  197     const char *path;
  198     int fd;
  199     const char *mode;
  200 {
  201     gzFile gz;
  202     int ret;
  203 
  204     gz = malloc(sizeof(struct gzFile_s));
  205     if (gz == NULL)
  206         return NULL;
  207     gz->write = strchr(mode, 'w') != NULL;
  208     gz->strm.zalloc = myalloc;
  209     gz->strm.zfree = myfree;
  210     gz->strm.opaque = Z_NULL;
  211     if (gz->write)
  212         ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
  213     else {
  214         gz->strm.next_in = 0;
  215         gz->strm.avail_in = Z_NULL;
  216         ret = inflateInit2(&(gz->strm), 15 + 16);
  217     }
  218     if (ret != Z_OK) {
  219         free(gz);
  220         return NULL;
  221     }
  222     gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
  223                               fopen(path, gz->write ? "wb" : "rb");
  224     if (gz->file == NULL) {
  225         gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
  226         free(gz);
  227         return NULL;
  228     }
  229     gz->err = 0;
  230     gz->msg = "";
  231     return gz;
  232 }
  233 
  234 int gzwrite OF((gzFile, const void *, unsigned));
  235 
  236 int gzwrite(gz, buf, len)
  237     gzFile gz;
  238     const void *buf;
  239     unsigned len;
  240 {
  241     z_stream *strm;
  242     unsigned char out[BUFLEN];
  243 
  244     if (gz == NULL || !gz->write)
  245         return 0;
  246     strm = &(gz->strm);
  247     strm->next_in = (void *)buf;
  248     strm->avail_in = len;
  249     do {
  250         strm->next_out = out;
  251         strm->avail_out = BUFLEN;
  252         (void)deflate(strm, Z_NO_FLUSH);
  253         fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
  254     } while (strm->avail_out == 0);
  255     return len;
  256 }
  257 
  258 int gzread OF((gzFile, void *, unsigned));
  259 
  260 int gzread(gz, buf, len)
  261     gzFile gz;
  262     void *buf;
  263     unsigned len;
  264 {
  265     int ret;
  266     unsigned got;
  267     unsigned char in[1];
  268     z_stream *strm;
  269 
  270     if (gz == NULL || gz->write)
  271         return 0;
  272     if (gz->err)
  273         return 0;
  274     strm = &(gz->strm);
  275     strm->next_out = (void *)buf;
  276     strm->avail_out = len;
  277     do {
  278         got = fread(in, 1, 1, gz->file);
  279         if (got == 0)
  280             break;
  281         strm->next_in = in;
  282         strm->avail_in = 1;
  283         ret = inflate(strm, Z_NO_FLUSH);
  284         if (ret == Z_DATA_ERROR) {
  285             gz->err = Z_DATA_ERROR;
  286             gz->msg = strm->msg;
  287             return 0;
  288         }
  289         if (ret == Z_STREAM_END)
  290             inflateReset(strm);
  291     } while (strm->avail_out);
  292     return len - strm->avail_out;
  293 }
  294 
  295 int gzclose OF((gzFile));
  296 
  297 int gzclose(gz)
  298     gzFile gz;
  299 {
  300     z_stream *strm;
  301     unsigned char out[BUFLEN];
  302 
  303     if (gz == NULL)
  304         return Z_STREAM_ERROR;
  305     strm = &(gz->strm);
  306     if (gz->write) {
  307         strm->next_in = Z_NULL;
  308         strm->avail_in = 0;
  309         do {
  310             strm->next_out = out;
  311             strm->avail_out = BUFLEN;
  312             (void)deflate(strm, Z_FINISH);
  313             fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
  314         } while (strm->avail_out == 0);
  315         deflateEnd(strm);
  316     }
  317     else
  318         inflateEnd(strm);
  319     fclose(gz->file);
  320     free(gz);
  321     return Z_OK;
  322 }
  323 
  324 const char *gzerror OF((gzFile, int *));
  325 
  326 const char *gzerror(gz, err)
  327     gzFile gz;
  328     int *err;
  329 {
  330     *err = gz->err;
  331     return gz->msg;
  332 }
  333 
  334 #endif
  335 
  336 static char *prog;
  337 
  338 void error            OF((const char *msg));
  339 void gz_compress      OF((FILE   *in, gzFile out));
  340 #ifdef USE_MMAP
  341 int  gz_compress_mmap OF((FILE   *in, gzFile out));
  342 #endif
  343 void gz_uncompress    OF((gzFile in, FILE   *out));
  344 void file_compress    OF((char  *file, char *mode));
  345 void file_uncompress  OF((char  *file));
  346 int  main             OF((int argc, char *argv[]));
  347 
  348 /* ===========================================================================
  349  * Display error message and exit
  350  */
  351 void error(msg)
  352     const char *msg;
  353 {
  354     fprintf(stderr, "%s: %s\n", prog, msg);
  355     exit(1);
  356 }
  357 
  358 /* ===========================================================================
  359  * Compress input to output then close both files.
  360  */
  361 
  362 void gz_compress(in, out)
  363     FILE   *in;
  364     gzFile out;
  365 {
  366     local char buf[BUFLEN];
  367     int len;
  368     int err;
  369 
  370 #ifdef USE_MMAP
  371     /* Try first compressing with mmap. If mmap fails (minigzip used in a
  372      * pipe), use the normal fread loop.
  373      */
  374     if (gz_compress_mmap(in, out) == Z_OK) return;
  375 #endif
  376     for (;;) {
  377         len = (int)fread(buf, 1, sizeof(buf), in);
  378         if (ferror(in)) {
  379             perror("fread");
  380             exit(1);
  381         }
  382         if (len == 0) break;
  383 
  384         if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
  385     }
  386     fclose(in);
  387     if (gzclose(out) != Z_OK) error("failed gzclose");
  388 }
  389 
  390 #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
  391 
  392 /* Try compressing the input file at once using mmap. Return Z_OK if
  393  * if success, Z_ERRNO otherwise.
  394  */
  395 int gz_compress_mmap(in, out)
  396     FILE   *in;
  397     gzFile out;
  398 {
  399     int len;
  400     int err;
  401     int ifd = fileno(in);
  402     caddr_t buf;    /* mmap'ed buffer for the entire input file */
  403     off_t buf_len;  /* length of the input file */
  404     struct stat sb;
  405 
  406     /* Determine the size of the file, needed for mmap: */
  407     if (fstat(ifd, &sb) < 0) return Z_ERRNO;
  408     buf_len = sb.st_size;
  409     if (buf_len <= 0) return Z_ERRNO;
  410 
  411     /* Now do the actual mmap: */
  412     buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
  413     if (buf == (caddr_t)(-1)) return Z_ERRNO;
  414 
  415     /* Compress the whole file at once: */
  416     len = gzwrite(out, (char *)buf, (unsigned)buf_len);
  417 
  418     if (len != (int)buf_len) error(gzerror(out, &err));
  419 
  420     munmap(buf, buf_len);
  421     fclose(in);
  422     if (gzclose(out) != Z_OK) error("failed gzclose");
  423     return Z_OK;
  424 }
  425 #endif /* USE_MMAP */
  426 
  427 /* ===========================================================================
  428  * Uncompress input to output then close both files.
  429  */
  430 void gz_uncompress(in, out)
  431     gzFile in;
  432     FILE   *out;
  433 {
  434     local char buf[BUFLEN];
  435     int len;
  436     int err;
  437 
  438     for (;;) {
  439         len = gzread(in, buf, sizeof(buf));
  440         if (len < 0) error (gzerror(in, &err));
  441         if (len == 0) break;
  442 
  443         if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
  444             error("failed fwrite");
  445         }
  446     }
  447     if (fclose(out)) error("failed fclose");
  448 
  449     if (gzclose(in) != Z_OK) error("failed gzclose");
  450 }
  451 
  452 
  453 /* ===========================================================================
  454  * Compress the given file: create a corresponding .gz file and remove the
  455  * original.
  456  */
  457 void file_compress(file, mode)
  458     char  *file;
  459     char  *mode;
  460 {
  461     local char outfile[MAX_NAME_LEN];
  462     FILE  *in;
  463     gzFile out;
  464 
  465     if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
  466         fprintf(stderr, "%s: filename too long\n", prog);
  467         exit(1);
  468     }
  469 
  470 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  471     snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
  472 #else
  473     strcpy(outfile, file);
  474     strcat(outfile, GZ_SUFFIX);
  475 #endif
  476 
  477     in = fopen(file, "rb");
  478     if (in == NULL) {
  479         perror(file);
  480         exit(1);
  481     }
  482     out = gzopen(outfile, mode);
  483     if (out == NULL) {
  484         fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
  485         exit(1);
  486     }
  487     gz_compress(in, out);
  488 
  489     unlink(file);
  490 }
  491 
  492 
  493 /* ===========================================================================
  494  * Uncompress the given file and remove the original.
  495  */
  496 void file_uncompress(file)
  497     char  *file;
  498 {
  499     local char buf[MAX_NAME_LEN];
  500     char *infile, *outfile;
  501     FILE  *out;
  502     gzFile in;
  503     unsigned len = strlen(file);
  504 
  505     if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
  506         fprintf(stderr, "%s: filename too long\n", prog);
  507         exit(1);
  508     }
  509 
  510 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  511     snprintf(buf, sizeof(buf), "%s", file);
  512 #else
  513     strcpy(buf, file);
  514 #endif
  515 
  516     if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
  517         infile = file;
  518         outfile = buf;
  519         outfile[len-3] = '\0';
  520     } else {
  521         outfile = file;
  522         infile = buf;
  523 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  524         snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
  525 #else
  526         strcat(infile, GZ_SUFFIX);
  527 #endif
  528     }
  529     in = gzopen(infile, "rb");
  530     if (in == NULL) {
  531         fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
  532         exit(1);
  533     }
  534     out = fopen(outfile, "wb");
  535     if (out == NULL) {
  536         perror(file);
  537         exit(1);
  538     }
  539 
  540     gz_uncompress(in, out);
  541 
  542     unlink(infile);
  543 }
  544 
  545 
  546 /* ===========================================================================
  547  * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
  548  *   -c : write to standard output
  549  *   -d : decompress
  550  *   -f : compress with Z_FILTERED
  551  *   -h : compress with Z_HUFFMAN_ONLY
  552  *   -r : compress with Z_RLE
  553  *   -1 to -9 : compression level
  554  */
  555 
  556 int main(argc, argv)
  557     int argc;
  558     char *argv[];
  559 {
  560     int copyout = 0;
  561     int uncompr = 0;
  562     gzFile file;
  563     char *bname, outmode[20];
  564 
  565 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  566     snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
  567 #else
  568     strcpy(outmode, "wb6 ");
  569 #endif
  570 
  571     prog = argv[0];
  572     bname = strrchr(argv[0], '/');
  573     if (bname)
  574       bname++;
  575     else
  576       bname = argv[0];
  577     argc--, argv++;
  578 
  579     if (!strcmp(bname, "gunzip"))
  580       uncompr = 1;
  581     else if (!strcmp(bname, "zcat"))
  582       copyout = uncompr = 1;
  583 
  584     while (argc > 0) {
  585       if (strcmp(*argv, "-c") == 0)
  586         copyout = 1;
  587       else if (strcmp(*argv, "-d") == 0)
  588         uncompr = 1;
  589       else if (strcmp(*argv, "-f") == 0)
  590         outmode[3] = 'f';
  591       else if (strcmp(*argv, "-h") == 0)
  592         outmode[3] = 'h';
  593       else if (strcmp(*argv, "-r") == 0)
  594         outmode[3] = 'R';
  595       else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
  596                (*argv)[2] == 0)
  597         outmode[2] = (*argv)[1];
  598       else
  599         break;
  600       argc--, argv++;
  601     }
  602     if (outmode[3] == ' ')
  603         outmode[3] = 0;
  604     if (argc == 0) {
  605         SET_BINARY_MODE(stdin);
  606         SET_BINARY_MODE(stdout);
  607         if (uncompr) {
  608             file = gzdopen(fileno(stdin), "rb");
  609             if (file == NULL) error("can't gzdopen stdin");
  610             gz_uncompress(file, stdout);
  611         } else {
  612             file = gzdopen(fileno(stdout), outmode);
  613             if (file == NULL) error("can't gzdopen stdout");
  614             gz_compress(stdin, file);
  615         }
  616     } else {
  617         if (copyout) {
  618             SET_BINARY_MODE(stdout);
  619         }
  620         do {
  621             if (uncompr) {
  622                 if (copyout) {
  623                     file = gzopen(*argv, "rb");
  624                     if (file == NULL)
  625                         fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
  626                     else
  627                         gz_uncompress(file, stdout);
  628                 } else {
  629                     file_uncompress(*argv);
  630                 }
  631             } else {
  632                 if (copyout) {
  633                     FILE * in = fopen(*argv, "rb");
  634 
  635                     if (in == NULL) {
  636                         perror(*argv);
  637                     } else {
  638                         file = gzdopen(fileno(stdout), outmode);
  639                         if (file == NULL) error("can't gzdopen stdout");
  640 
  641                         gz_compress(in, file);
  642                     }
  643 
  644                 } else {
  645                     file_compress(*argv, outmode);
  646                 }
  647             }
  648         } while (argv++, --argc);
  649     }
  650     return 0;
  651 }

Cache object: 3d71410edd8d5c862712d3df21a69e7e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.