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

Cache object: 107653dd0af8afcc41ce6a2d3a3de739


[ 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.