"Fossies" - the Fresh Open Source Software Archive

Member "muscle/zlib/zlib/gzlib.c" (28 Nov 2019, 17702 Bytes) of package /linux/privat/muscle7.52.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "gzlib.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 7.31_vs_7.40.

    1 /* gzlib.c -- zlib functions common to reading and writing gzip files
    2  * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
    3  * For conditions of distribution and use, see copyright notice in zlib.h
    4  */
    5 
    6 #if defined(__APPLE__) || defined(__linux__) || defined(__EMSCRIPTEN__)
    7 # include <unistd.h>  // just to avoid implicit-declaration warnings --jaf
    8 #endif
    9 
   10 #include "gzguts.h"
   11 
   12 #if defined(_WIN32) && !defined(__BORLANDC__)
   13 #  define LSEEK _lseeki64
   14 #else
   15 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
   16 #  define LSEEK lseek64
   17 #else
   18 #  define LSEEK lseek
   19 #endif
   20 #endif
   21 
   22 /* Local functions */
   23 local void gz_reset OF((gz_statep));
   24 local gzFile gz_open OF((const void *, int, const char *));
   25 
   26 #if defined UNDER_CE
   27 
   28 /* Map the Windows error number in ERROR to a locale-dependent error message
   29    string and return a pointer to it.  Typically, the values for ERROR come
   30    from GetLastError.
   31 
   32    The string pointed to shall not be modified by the application, but may be
   33    overwritten by a subsequent call to gz_strwinerror
   34 
   35    The gz_strwinerror function does not change the current setting of
   36    GetLastError. */
   37 char ZLIB_INTERNAL *gz_strwinerror (error)
   38      DWORD error;
   39 {
   40     static char buf[1024];
   41 
   42     wchar_t *msgbuf;
   43     DWORD lasterr = GetLastError();
   44     DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
   45         | FORMAT_MESSAGE_ALLOCATE_BUFFER,
   46         NULL,
   47         error,
   48         0, /* Default language */
   49         (LPVOID)&msgbuf,
   50         0,
   51         NULL);
   52     if (chars != 0) {
   53         /* If there is an \r\n appended, zap it.  */
   54         if (chars >= 2
   55             && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
   56             chars -= 2;
   57             msgbuf[chars] = 0;
   58         }
   59 
   60         if (chars > sizeof (buf) - 1) {
   61             chars = sizeof (buf) - 1;
   62             msgbuf[chars] = 0;
   63         }
   64 
   65         wcstombs(buf, msgbuf, chars + 1);
   66         LocalFree(msgbuf);
   67     }
   68     else {
   69         sprintf(buf, "unknown win32 error (%ld)", error);
   70     }
   71 
   72     SetLastError(lasterr);
   73     return buf;
   74 }
   75 
   76 #endif /* UNDER_CE */
   77 
   78 /* Reset gzip file state */
   79 local void gz_reset(state)
   80     gz_statep state;
   81 {
   82     state->x.have = 0;              /* no output data available */
   83     if (state->mode == GZ_READ) {   /* for reading ... */
   84         state->eof = 0;             /* not at end of file */
   85         state->past = 0;            /* have not read past end yet */
   86         state->how = LOOK;          /* look for gzip header */
   87     }
   88     state->seek = 0;                /* no seek request pending */
   89     gz_error(state, Z_OK, NULL);    /* clear error */
   90     state->x.pos = 0;               /* no uncompressed data yet */
   91     state->strm.avail_in = 0;       /* no input data yet */
   92 }
   93 
   94 /* Open a gzip file either by name or file descriptor. */
   95 local gzFile gz_open(path, fd, mode)
   96     const void *path;
   97     int fd;
   98     const char *mode;
   99 {
  100     gz_statep state;
  101     size_t len;
  102     int oflag;
  103 #ifdef O_CLOEXEC
  104     int cloexec = 0;
  105 #endif
  106 #ifdef O_EXCL
  107     int exclusive = 0;
  108 #endif
  109 #if __STDC_WANT_SECURE_LIB__
  110     int tempfd = -1;
  111 #endif
  112 
  113     /* check input */
  114     if (path == NULL)
  115         return NULL;
  116 
  117     /* allocate gzFile structure to return */
  118     state = (gz_statep)malloc(sizeof(gz_state));
  119     if (state == NULL)
  120         return NULL;
  121     state->size = 0;            /* no buffers allocated yet */
  122     state->want = GZBUFSIZE;    /* requested buffer size */
  123     state->msg = NULL;          /* no error message yet */
  124 
  125     /* interpret mode */
  126     state->mode = GZ_NONE;
  127     state->level = Z_DEFAULT_COMPRESSION;
  128     state->strategy = Z_DEFAULT_STRATEGY;
  129     state->direct = 0;
  130     while (*mode) {
  131         if (*mode >= '0' && *mode <= '9')
  132             state->level = *mode - '0';
  133         else
  134             switch (*mode) {
  135             case 'r':
  136                 state->mode = GZ_READ;
  137                 break;
  138 #ifndef NO_GZCOMPRESS
  139             case 'w':
  140                 state->mode = GZ_WRITE;
  141                 break;
  142             case 'a':
  143                 state->mode = GZ_APPEND;
  144                 break;
  145 #endif
  146             case '+':       /* can't read and write at the same time */
  147                 free(state);
  148                 return NULL;
  149             case 'b':       /* ignore -- will request binary anyway */
  150                 break;
  151 #ifdef O_CLOEXEC
  152             case 'e':
  153                 cloexec = 1;
  154                 break;
  155 #endif
  156 #ifdef O_EXCL
  157             case 'x':
  158                 exclusive = 1;
  159                 break;
  160 #endif
  161             case 'f':
  162                 state->strategy = Z_FILTERED;
  163                 break;
  164             case 'h':
  165                 state->strategy = Z_HUFFMAN_ONLY;
  166                 break;
  167             case 'R':
  168                 state->strategy = Z_RLE;
  169                 break;
  170             case 'F':
  171                 state->strategy = Z_FIXED;
  172                 break;
  173             case 'T':
  174                 state->direct = 1;
  175                 break;
  176             default:        /* could consider as an error, but just ignore */
  177                 ;
  178             }
  179         mode++;
  180     }
  181 
  182     /* must provide an "r", "w", or "a" */
  183     if (state->mode == GZ_NONE) {
  184         free(state);
  185         return NULL;
  186     }
  187 
  188     /* can't force transparent read */
  189     if (state->mode == GZ_READ) {
  190         if (state->direct) {
  191             free(state);
  192             return NULL;
  193         }
  194         state->direct = 1;      /* for empty file */
  195     }
  196 
  197     /* save the path name for error messages */
  198 #ifdef _WIN32
  199     if (fd == -2) {
  200 #  if __STDC_WANT_SECURE_LIB__
  201         (void) wcstombs_s(&len, NULL, 0, path, 0);
  202 #  else
  203         len = wcstombs(NULL, path, 0);
  204 #  endif
  205         if (len == (size_t)-1)
  206             len = 0;
  207     }
  208     else
  209 #endif
  210         len = strlen((const char *)path);
  211     state->path = (char *)malloc(len + 1);
  212     if (state->path == NULL) {
  213         free(state);
  214         return NULL;
  215     }
  216 #ifdef _WIN32
  217     if (fd == -2)
  218         if (len)
  219 #  if __STDC_WANT_SECURE_LIB__
  220         {
  221             size_t bytes;
  222             (void) wcstombs_s(&bytes, state->path, len + 1, path, len + 1);
  223         }
  224 #  else
  225             wcstombs(state->path, path, len + 1);
  226 #  endif
  227         else
  228             *(state->path) = 0;
  229     else
  230 #endif
  231 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  232 #  if __STDC_WANT_SECURE_LIB__
  233         _snprintf_s(state->path, len + 1, _TRUNCATE, "%s", (const char *)path);
  234 #  else
  235         snprintf(state->path, len + 1, "%s", (const char *)path);
  236 #  endif
  237 #else
  238         strcpy(state->path, path);
  239 #endif
  240 
  241     /* compute the flags for open() */
  242     oflag =
  243 #ifdef O_LARGEFILE
  244         O_LARGEFILE |
  245 #endif
  246 #ifdef O_BINARY
  247         O_BINARY |
  248 #endif
  249 #ifdef O_CLOEXEC
  250         (cloexec ? O_CLOEXEC : 0) |
  251 #endif
  252         (state->mode == GZ_READ ?
  253          O_RDONLY :
  254          (O_WRONLY | O_CREAT |
  255 #ifdef O_EXCL
  256           (exclusive ? O_EXCL : 0) |
  257 #endif
  258           (state->mode == GZ_WRITE ?
  259            O_TRUNC :
  260            O_APPEND)));
  261 
  262     /* open the file with the appropriate flags (or just use fd) */
  263     state->fd = fd > -1 ? fd : (
  264 #ifdef _WIN32
  265 #  if __STDC_WANT_SECURE_LIB__
  266         fd == -2 ? (_wsopen_s(&tempfd, path, oflag, (state->mode == GZ_WRITE || state->mode == GZ_APPEND) ? _SH_DENYWR : _SH_DENYNO, 0666) == 0 ? tempfd : -1) :
  267 #  else
  268         fd == -2 ? _wopen(path, oflag, 0666) :
  269 #  endif
  270 #endif
  271 #if __STDC_WANT_SECURE_LIB__
  272         (_sopen_s(&tempfd, (const char *)path, oflag, (state->mode == GZ_WRITE || state->mode == GZ_APPEND) ? _SH_DENYWR : _SH_DENYNO, 0666) == 0 ? tempfd : -1));
  273 #else
  274         open((const char *)path, oflag, 0666));
  275 #endif
  276     if (state->fd == -1) {
  277         free(state->path);
  278         free(state);
  279         return NULL;
  280     }
  281     if (state->mode == GZ_APPEND)
  282         state->mode = GZ_WRITE;         /* simplify later checks */
  283 
  284     /* save the current position for rewinding (only if reading) */
  285     if (state->mode == GZ_READ) {
  286         state->start = LSEEK(state->fd, 0, SEEK_CUR);
  287         if (state->start == -1) state->start = 0;
  288     }
  289 
  290     /* initialize stream */
  291     gz_reset(state);
  292 
  293     /* return stream */
  294     return (gzFile)state;
  295 }
  296 
  297 /* -- see zlib.h -- */
  298 gzFile ZEXPORT gzopen(path, mode)
  299     const char *path;
  300     const char *mode;
  301 {
  302     return gz_open(path, -1, mode);
  303 }
  304 
  305 /* -- see zlib.h -- */
  306 gzFile ZEXPORT gzopen64(path, mode)
  307     const char *path;
  308     const char *mode;
  309 {
  310     return gz_open(path, -1, mode);
  311 }
  312 
  313 /* -- see zlib.h -- */
  314 gzFile ZEXPORT gzdopen(fd, mode)
  315     int fd;
  316     const char *mode;
  317 {
  318     char *path;         /* identifier for error messages */
  319     gzFile gz;
  320 
  321     if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
  322         return NULL;
  323 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  324 #  if __STDC_WANT_SECURE_LIB__
  325     _snprintf_s(path, 7 + 3 * sizeof(int), _TRUNCATE, "<fd:%d>", fd); /* for debugging */
  326 #  else
  327     snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
  328 #  endif
  329 #else
  330     sprintf(path, "<fd:%d>", fd);   /* for debugging */
  331 #endif
  332     gz = gz_open(path, fd, mode);
  333     free(path);
  334     return gz;
  335 }
  336 
  337 /* -- see zlib.h -- */
  338 #ifdef _WIN32
  339 gzFile ZEXPORT gzopen_w(path, mode)
  340     const wchar_t *path;
  341     const char *mode;
  342 {
  343     return gz_open(path, -2, mode);
  344 }
  345 #endif
  346 
  347 /* -- see zlib.h -- */
  348 int ZEXPORT gzbuffer(file, size)
  349     gzFile file;
  350     unsigned size;
  351 {
  352     gz_statep state;
  353 
  354     /* get internal structure and check integrity */
  355     if (file == NULL)
  356         return -1;
  357     state = (gz_statep)file;
  358     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  359         return -1;
  360 
  361     /* make sure we haven't already allocated memory */
  362     if (state->size != 0)
  363         return -1;
  364 
  365     /* check and set requested size */
  366     if (size < 2)
  367         size = 2;               /* need two bytes to check magic header */
  368     state->want = size;
  369     return 0;
  370 }
  371 
  372 /* -- see zlib.h -- */
  373 int ZEXPORT gzrewind(file)
  374     gzFile file;
  375 {
  376     gz_statep state;
  377 
  378     /* get internal structure */
  379     if (file == NULL)
  380         return -1;
  381     state = (gz_statep)file;
  382 
  383     /* check that we're reading and that there's no error */
  384     if (state->mode != GZ_READ ||
  385             (state->err != Z_OK && state->err != Z_BUF_ERROR))
  386         return -1;
  387 
  388     /* back up and start over */
  389     if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
  390         return -1;
  391     gz_reset(state);
  392     return 0;
  393 }
  394 
  395 /* -- see zlib.h -- */
  396 z_off64_t ZEXPORT gzseek64(file, offset, whence)
  397     gzFile file;
  398     z_off64_t offset;
  399     int whence;
  400 {
  401     unsigned n;
  402     z_off64_t ret;
  403     gz_statep state;
  404 
  405     /* get internal structure and check integrity */
  406     if (file == NULL)
  407         return -1;
  408     state = (gz_statep)file;
  409     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  410         return -1;
  411 
  412     /* check that there's no error */
  413     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
  414         return -1;
  415 
  416     /* can only seek from start or relative to current position */
  417     if (whence != SEEK_SET && whence != SEEK_CUR)
  418         return -1;
  419 
  420     /* normalize offset to a SEEK_CUR specification */
  421     if (whence == SEEK_SET)
  422         offset -= state->x.pos;
  423     else if (state->seek)
  424         offset += state->skip;
  425     state->seek = 0;
  426 
  427     /* if within raw area while reading, just go there */
  428     if (state->mode == GZ_READ && state->how == COPY &&
  429             state->x.pos + offset >= 0) {
  430         ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
  431         if (ret == -1)
  432             return -1;
  433         state->x.have = 0;
  434         state->eof = 0;
  435         state->past = 0;
  436         state->seek = 0;
  437         gz_error(state, Z_OK, NULL);
  438         state->strm.avail_in = 0;
  439         state->x.pos += offset;
  440         return state->x.pos;
  441     }
  442 
  443     /* calculate skip amount, rewinding if needed for back seek when reading */
  444     if (offset < 0) {
  445         if (state->mode != GZ_READ)         /* writing -- can't go backwards */
  446             return -1;
  447         offset += state->x.pos;
  448         if (offset < 0)                     /* before start of file! */
  449             return -1;
  450         if (gzrewind(file) == -1)           /* rewind, then skip to offset */
  451             return -1;
  452     }
  453 
  454     /* if reading, skip what's in output buffer (one less gzgetc() check) */
  455     if (state->mode == GZ_READ) {
  456         n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
  457             (unsigned)offset : state->x.have;
  458         state->x.have -= n;
  459         state->x.next += n;
  460         state->x.pos += n;
  461         offset -= n;
  462     }
  463 
  464     /* request skip (if not zero) */
  465     if (offset) {
  466         state->seek = 1;
  467         state->skip = offset;
  468     }
  469     return state->x.pos + offset;
  470 }
  471 
  472 /* -- see zlib.h -- */
  473 z_off_t ZEXPORT gzseek(file, offset, whence)
  474     gzFile file;
  475     z_off_t offset;
  476     int whence;
  477 {
  478     z_off64_t ret;
  479 
  480     ret = gzseek64(file, (z_off64_t)offset, whence);
  481     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
  482 }
  483 
  484 /* -- see zlib.h -- */
  485 z_off64_t ZEXPORT gztell64(file)
  486     gzFile file;
  487 {
  488     gz_statep state;
  489 
  490     /* get internal structure and check integrity */
  491     if (file == NULL)
  492         return -1;
  493     state = (gz_statep)file;
  494     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  495         return -1;
  496 
  497     /* return position */
  498     return state->x.pos + (state->seek ? state->skip : 0);
  499 }
  500 
  501 /* -- see zlib.h -- */
  502 z_off_t ZEXPORT gztell(file)
  503     gzFile file;
  504 {
  505     z_off64_t ret;
  506 
  507     ret = gztell64(file);
  508     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
  509 }
  510 
  511 /* -- see zlib.h -- */
  512 z_off64_t ZEXPORT gzoffset64(file)
  513     gzFile file;
  514 {
  515     z_off64_t offset;
  516     gz_statep state;
  517 
  518     /* get internal structure and check integrity */
  519     if (file == NULL)
  520         return -1;
  521     state = (gz_statep)file;
  522     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  523         return -1;
  524 
  525     /* compute and return effective offset in file */
  526     offset = LSEEK(state->fd, 0, SEEK_CUR);
  527     if (offset == -1)
  528         return -1;
  529     if (state->mode == GZ_READ)             /* reading */
  530         offset -= state->strm.avail_in;     /* don't count buffered input */
  531     return offset;
  532 }
  533 
  534 /* -- see zlib.h -- */
  535 z_off_t ZEXPORT gzoffset(file)
  536     gzFile file;
  537 {
  538     z_off64_t ret;
  539 
  540     ret = gzoffset64(file);
  541     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
  542 }
  543 
  544 /* -- see zlib.h -- */
  545 int ZEXPORT gzeof(file)
  546     gzFile file;
  547 {
  548     gz_statep state;
  549 
  550     /* get internal structure and check integrity */
  551     if (file == NULL)
  552         return 0;
  553     state = (gz_statep)file;
  554     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  555         return 0;
  556 
  557     /* return end-of-file state */
  558     return state->mode == GZ_READ ? state->past : 0;
  559 }
  560 
  561 /* -- see zlib.h -- */
  562 const char * ZEXPORT gzerror(file, errnum)
  563     gzFile file;
  564     int *errnum;
  565 {
  566     gz_statep state;
  567 
  568     /* get internal structure and check integrity */
  569     if (file == NULL)
  570         return NULL;
  571     state = (gz_statep)file;
  572     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  573         return NULL;
  574 
  575     /* return error information */
  576     if (errnum != NULL)
  577         *errnum = state->err;
  578     return state->err == Z_MEM_ERROR ? "out of memory" :
  579                                        (state->msg == NULL ? "" : state->msg);
  580 }
  581 
  582 /* -- see zlib.h -- */
  583 void ZEXPORT gzclearerr(file)
  584     gzFile file;
  585 {
  586     gz_statep state;
  587 
  588     /* get internal structure and check integrity */
  589     if (file == NULL)
  590         return;
  591     state = (gz_statep)file;
  592     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  593         return;
  594 
  595     /* clear error and end-of-file */
  596     if (state->mode == GZ_READ) {
  597         state->eof = 0;
  598         state->past = 0;
  599     }
  600     gz_error(state, Z_OK, NULL);
  601 }
  602 
  603 /* Create an error message in allocated memory and set state->err and
  604    state->msg accordingly.  Free any previous error message already there.  Do
  605    not try to free or allocate space if the error is Z_MEM_ERROR (out of
  606    memory).  Simply save the error message as a static string.  If there is an
  607    allocation failure constructing the error message, then convert the error to
  608    out of memory. */
  609 void ZLIB_INTERNAL gz_error(state, err, msg)
  610     gz_statep state;
  611     int err;
  612     const char *msg;
  613 {
  614     /* free previously allocated message and clear */
  615     if (state->msg != NULL) {
  616         if (state->err != Z_MEM_ERROR)
  617             free(state->msg);
  618         state->msg = NULL;
  619     }
  620 
  621     /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
  622     if (err != Z_OK && err != Z_BUF_ERROR)
  623         state->x.have = 0;
  624 
  625     /* set error code, and if no message, then done */
  626     state->err = err;
  627     if (msg == NULL)
  628         return;
  629 
  630     /* for an out of memory error, return literal string when requested */
  631     if (err == Z_MEM_ERROR)
  632         return;
  633 
  634     /* construct error message with path */
  635     if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
  636             NULL) {
  637         state->err = Z_MEM_ERROR;
  638         return;
  639     }
  640 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  641 #  if __STDC_WANT_SECURE_LIB__
  642     _snprintf_s(state->msg, strlen(state->path) + strlen(msg) + 3, _TRUNCATE,
  643 #  else
  644     snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
  645 #  endif
  646              "%s%s%s", state->path, ": ", msg);
  647 #else
  648     strcpy(state->msg, state->path);
  649     strcat(state->msg, ": ");
  650     strcat(state->msg, msg);
  651 #endif
  652     return;
  653 }
  654 
  655 #ifndef INT_MAX
  656 /* portably return maximum value for an int (when limits.h presumed not
  657    available) -- we need to do this to cover cases where 2's complement not
  658    used, since C standard permits 1's complement and sign-bit representations,
  659    otherwise we could just use ((unsigned)-1) >> 1 */
  660 unsigned ZLIB_INTERNAL gz_intmax()
  661 {
  662     unsigned p, q;
  663 
  664     p = 1;
  665     do {
  666         q = p;
  667         p <<= 1;
  668         p++;
  669     } while (p > q);
  670     return q >> 1;
  671 }
  672 #endif