"Fossies" - the Fresh Open Source Software Archive

Member "muscle/zlib/zlib/gzlib.c" (21 Nov 2020, 16644 Bytes) of package /linux/privat/muscle7.62.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 latest Fossies "Diffs" side-by-side code changes report: 7.61_vs_7.62.

    1 /* gzlib.c -- zlib functions common to reading and writing gzip files
    2  * Copyright (C) 2004-2017 Mark Adler
    3  * For conditions of distribution and use, see copyright notice in zlib.h
    4  */
    5 
    6 #include "gzguts.h"
    7 
    8 #ifndef _WIN32
    9 #  include <unistd.h>
   10 #endif
   11 
   12 #if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
   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     z_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 
  110     /* check input */
  111     if (path == NULL)
  112         return NULL;
  113 
  114     /* allocate gzFile structure to return */
  115     state = (gz_statep)malloc(sizeof(gz_state));
  116     if (state == NULL)
  117         return NULL;
  118     state->size = 0;            /* no buffers allocated yet */
  119     state->want = GZBUFSIZE;    /* requested buffer size */
  120     state->msg = NULL;          /* no error message yet */
  121 
  122     /* interpret mode */
  123     state->mode = GZ_NONE;
  124     state->level = Z_DEFAULT_COMPRESSION;
  125     state->strategy = Z_DEFAULT_STRATEGY;
  126     state->direct = 0;
  127     while (*mode) {
  128         if (*mode >= '0' && *mode <= '9')
  129             state->level = *mode - '0';
  130         else
  131             switch (*mode) {
  132             case 'r':
  133                 state->mode = GZ_READ;
  134                 break;
  135 #ifndef NO_GZCOMPRESS
  136             case 'w':
  137                 state->mode = GZ_WRITE;
  138                 break;
  139             case 'a':
  140                 state->mode = GZ_APPEND;
  141                 break;
  142 #endif
  143             case '+':       /* can't read and write at the same time */
  144                 free(state);
  145                 return NULL;
  146             case 'b':       /* ignore -- will request binary anyway */
  147                 break;
  148 #ifdef O_CLOEXEC
  149             case 'e':
  150                 cloexec = 1;
  151                 break;
  152 #endif
  153 #ifdef O_EXCL
  154             case 'x':
  155                 exclusive = 1;
  156                 break;
  157 #endif
  158             case 'f':
  159                 state->strategy = Z_FILTERED;
  160                 break;
  161             case 'h':
  162                 state->strategy = Z_HUFFMAN_ONLY;
  163                 break;
  164             case 'R':
  165                 state->strategy = Z_RLE;
  166                 break;
  167             case 'F':
  168                 state->strategy = Z_FIXED;
  169                 break;
  170             case 'T':
  171                 state->direct = 1;
  172                 break;
  173             default:        /* could consider as an error, but just ignore */
  174                 ;
  175             }
  176         mode++;
  177     }
  178 
  179     /* must provide an "r", "w", or "a" */
  180     if (state->mode == GZ_NONE) {
  181         free(state);
  182         return NULL;
  183     }
  184 
  185     /* can't force transparent read */
  186     if (state->mode == GZ_READ) {
  187         if (state->direct) {
  188             free(state);
  189             return NULL;
  190         }
  191         state->direct = 1;      /* for empty file */
  192     }
  193 
  194     /* save the path name for error messages */
  195 #ifdef WIDECHAR
  196     if (fd == -2) {
  197         len = wcstombs(NULL, path, 0);
  198         if (len == (z_size_t)-1)
  199             len = 0;
  200     }
  201     else
  202 #endif
  203         len = strlen((const char *)path);
  204     state->path = (char *)malloc(len + 1);
  205     if (state->path == NULL) {
  206         free(state);
  207         return NULL;
  208     }
  209 #ifdef WIDECHAR
  210     if (fd == -2)
  211         if (len)
  212             wcstombs(state->path, path, len + 1);
  213         else
  214             *(state->path) = 0;
  215     else
  216 #endif
  217 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  218         (void)snprintf(state->path, len + 1, "%s", (const char *)path);
  219 #else
  220         strcpy(state->path, path);
  221 #endif
  222 
  223     /* compute the flags for open() */
  224     oflag =
  225 #ifdef O_LARGEFILE
  226         O_LARGEFILE |
  227 #endif
  228 #ifdef O_BINARY
  229         O_BINARY |
  230 #endif
  231 #ifdef O_CLOEXEC
  232         (cloexec ? O_CLOEXEC : 0) |
  233 #endif
  234         (state->mode == GZ_READ ?
  235          O_RDONLY :
  236          (O_WRONLY | O_CREAT |
  237 #ifdef O_EXCL
  238           (exclusive ? O_EXCL : 0) |
  239 #endif
  240           (state->mode == GZ_WRITE ?
  241            O_TRUNC :
  242            O_APPEND)));
  243 
  244     /* open the file with the appropriate flags (or just use fd) */
  245     state->fd = fd > -1 ? fd : (
  246 #ifdef WIDECHAR
  247         fd == -2 ? _wopen(path, oflag, 0666) :
  248 #endif
  249         open((const char *)path, oflag, 0666));
  250     if (state->fd == -1) {
  251         free(state->path);
  252         free(state);
  253         return NULL;
  254     }
  255     if (state->mode == GZ_APPEND) {
  256         LSEEK(state->fd, 0, SEEK_END);  /* so gzoffset() is correct */
  257         state->mode = GZ_WRITE;         /* simplify later checks */
  258     }
  259 
  260     /* save the current position for rewinding (only if reading) */
  261     if (state->mode == GZ_READ) {
  262         state->start = LSEEK(state->fd, 0, SEEK_CUR);
  263         if (state->start == -1) state->start = 0;
  264     }
  265 
  266     /* initialize stream */
  267     gz_reset(state);
  268 
  269     /* return stream */
  270     return (gzFile)state;
  271 }
  272 
  273 /* -- see zlib.h -- */
  274 gzFile ZEXPORT gzopen(path, mode)
  275     const char *path;
  276     const char *mode;
  277 {
  278     return gz_open(path, -1, mode);
  279 }
  280 
  281 /* -- see zlib.h -- */
  282 gzFile ZEXPORT gzopen64(path, mode)
  283     const char *path;
  284     const char *mode;
  285 {
  286     return gz_open(path, -1, mode);
  287 }
  288 
  289 /* -- see zlib.h -- */
  290 gzFile ZEXPORT gzdopen(fd, mode)
  291     int fd;
  292     const char *mode;
  293 {
  294     char *path;         /* identifier for error messages */
  295     gzFile gz;
  296 
  297     if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
  298         return NULL;
  299 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  300     (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
  301 #else
  302     sprintf(path, "<fd:%d>", fd);   /* for debugging */
  303 #endif
  304     gz = gz_open(path, fd, mode);
  305     free(path);
  306     return gz;
  307 }
  308 
  309 /* -- see zlib.h -- */
  310 #ifdef WIDECHAR
  311 gzFile ZEXPORT gzopen_w(path, mode)
  312     const wchar_t *path;
  313     const char *mode;
  314 {
  315     return gz_open(path, -2, mode);
  316 }
  317 #endif
  318 
  319 /* -- see zlib.h -- */
  320 int ZEXPORT gzbuffer(file, size)
  321     gzFile file;
  322     unsigned size;
  323 {
  324     gz_statep state;
  325 
  326     /* get internal structure and check integrity */
  327     if (file == NULL)
  328         return -1;
  329     state = (gz_statep)file;
  330     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  331         return -1;
  332 
  333     /* make sure we haven't already allocated memory */
  334     if (state->size != 0)
  335         return -1;
  336 
  337     /* check and set requested size */
  338     if ((size << 1) < size)
  339         return -1;              /* need to be able to double it */
  340     if (size < 2)
  341         size = 2;               /* need two bytes to check magic header */
  342     state->want = size;
  343     return 0;
  344 }
  345 
  346 /* -- see zlib.h -- */
  347 int ZEXPORT gzrewind(file)
  348     gzFile file;
  349 {
  350     gz_statep state;
  351 
  352     /* get internal structure */
  353     if (file == NULL)
  354         return -1;
  355     state = (gz_statep)file;
  356 
  357     /* check that we're reading and that there's no error */
  358     if (state->mode != GZ_READ ||
  359             (state->err != Z_OK && state->err != Z_BUF_ERROR))
  360         return -1;
  361 
  362     /* back up and start over */
  363     if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
  364         return -1;
  365     gz_reset(state);
  366     return 0;
  367 }
  368 
  369 /* -- see zlib.h -- */
  370 z_off64_t ZEXPORT gzseek64(file, offset, whence)
  371     gzFile file;
  372     z_off64_t offset;
  373     int whence;
  374 {
  375     unsigned n;
  376     z_off64_t ret;
  377     gz_statep state;
  378 
  379     /* get internal structure and check integrity */
  380     if (file == NULL)
  381         return -1;
  382     state = (gz_statep)file;
  383     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  384         return -1;
  385 
  386     /* check that there's no error */
  387     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
  388         return -1;
  389 
  390     /* can only seek from start or relative to current position */
  391     if (whence != SEEK_SET && whence != SEEK_CUR)
  392         return -1;
  393 
  394     /* normalize offset to a SEEK_CUR specification */
  395     if (whence == SEEK_SET)
  396         offset -= state->x.pos;
  397     else if (state->seek)
  398         offset += state->skip;
  399     state->seek = 0;
  400 
  401     /* if within raw area while reading, just go there */
  402     if (state->mode == GZ_READ && state->how == COPY &&
  403             state->x.pos + offset >= 0) {
  404         ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
  405         if (ret == -1)
  406             return -1;
  407         state->x.have = 0;
  408         state->eof = 0;
  409         state->past = 0;
  410         state->seek = 0;
  411         gz_error(state, Z_OK, NULL);
  412         state->strm.avail_in = 0;
  413         state->x.pos += offset;
  414         return state->x.pos;
  415     }
  416 
  417     /* calculate skip amount, rewinding if needed for back seek when reading */
  418     if (offset < 0) {
  419         if (state->mode != GZ_READ)         /* writing -- can't go backwards */
  420             return -1;
  421         offset += state->x.pos;
  422         if (offset < 0)                     /* before start of file! */
  423             return -1;
  424         if (gzrewind(file) == -1)           /* rewind, then skip to offset */
  425             return -1;
  426     }
  427 
  428     /* if reading, skip what's in output buffer (one less gzgetc() check) */
  429     if (state->mode == GZ_READ) {
  430         n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
  431             (unsigned)offset : state->x.have;
  432         state->x.have -= n;
  433         state->x.next += n;
  434         state->x.pos += n;
  435         offset -= n;
  436     }
  437 
  438     /* request skip (if not zero) */
  439     if (offset) {
  440         state->seek = 1;
  441         state->skip = offset;
  442     }
  443     return state->x.pos + offset;
  444 }
  445 
  446 /* -- see zlib.h -- */
  447 z_off_t ZEXPORT gzseek(file, offset, whence)
  448     gzFile file;
  449     z_off_t offset;
  450     int whence;
  451 {
  452     z_off64_t ret;
  453 
  454     ret = gzseek64(file, (z_off64_t)offset, whence);
  455     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
  456 }
  457 
  458 /* -- see zlib.h -- */
  459 z_off64_t ZEXPORT gztell64(file)
  460     gzFile file;
  461 {
  462     gz_statep state;
  463 
  464     /* get internal structure and check integrity */
  465     if (file == NULL)
  466         return -1;
  467     state = (gz_statep)file;
  468     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  469         return -1;
  470 
  471     /* return position */
  472     return state->x.pos + (state->seek ? state->skip : 0);
  473 }
  474 
  475 /* -- see zlib.h -- */
  476 z_off_t ZEXPORT gztell(file)
  477     gzFile file;
  478 {
  479     z_off64_t ret;
  480 
  481     ret = gztell64(file);
  482     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
  483 }
  484 
  485 /* -- see zlib.h -- */
  486 z_off64_t ZEXPORT gzoffset64(file)
  487     gzFile file;
  488 {
  489     z_off64_t offset;
  490     gz_statep state;
  491 
  492     /* get internal structure and check integrity */
  493     if (file == NULL)
  494         return -1;
  495     state = (gz_statep)file;
  496     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  497         return -1;
  498 
  499     /* compute and return effective offset in file */
  500     offset = LSEEK(state->fd, 0, SEEK_CUR);
  501     if (offset == -1)
  502         return -1;
  503     if (state->mode == GZ_READ)             /* reading */
  504         offset -= state->strm.avail_in;     /* don't count buffered input */
  505     return offset;
  506 }
  507 
  508 /* -- see zlib.h -- */
  509 z_off_t ZEXPORT gzoffset(file)
  510     gzFile file;
  511 {
  512     z_off64_t ret;
  513 
  514     ret = gzoffset64(file);
  515     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
  516 }
  517 
  518 /* -- see zlib.h -- */
  519 int ZEXPORT gzeof(file)
  520     gzFile file;
  521 {
  522     gz_statep state;
  523 
  524     /* get internal structure and check integrity */
  525     if (file == NULL)
  526         return 0;
  527     state = (gz_statep)file;
  528     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  529         return 0;
  530 
  531     /* return end-of-file state */
  532     return state->mode == GZ_READ ? state->past : 0;
  533 }
  534 
  535 /* -- see zlib.h -- */
  536 const char * ZEXPORT gzerror(file, errnum)
  537     gzFile file;
  538     int *errnum;
  539 {
  540     gz_statep state;
  541 
  542     /* get internal structure and check integrity */
  543     if (file == NULL)
  544         return NULL;
  545     state = (gz_statep)file;
  546     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  547         return NULL;
  548 
  549     /* return error information */
  550     if (errnum != NULL)
  551         *errnum = state->err;
  552     return state->err == Z_MEM_ERROR ? "out of memory" :
  553                                        (state->msg == NULL ? "" : state->msg);
  554 }
  555 
  556 /* -- see zlib.h -- */
  557 void ZEXPORT gzclearerr(file)
  558     gzFile file;
  559 {
  560     gz_statep state;
  561 
  562     /* get internal structure and check integrity */
  563     if (file == NULL)
  564         return;
  565     state = (gz_statep)file;
  566     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
  567         return;
  568 
  569     /* clear error and end-of-file */
  570     if (state->mode == GZ_READ) {
  571         state->eof = 0;
  572         state->past = 0;
  573     }
  574     gz_error(state, Z_OK, NULL);
  575 }
  576 
  577 /* Create an error message in allocated memory and set state->err and
  578    state->msg accordingly.  Free any previous error message already there.  Do
  579    not try to free or allocate space if the error is Z_MEM_ERROR (out of
  580    memory).  Simply save the error message as a static string.  If there is an
  581    allocation failure constructing the error message, then convert the error to
  582    out of memory. */
  583 void ZLIB_INTERNAL gz_error(state, err, msg)
  584     gz_statep state;
  585     int err;
  586     const char *msg;
  587 {
  588     /* free previously allocated message and clear */
  589     if (state->msg != NULL) {
  590         if (state->err != Z_MEM_ERROR)
  591             free(state->msg);
  592         state->msg = NULL;
  593     }
  594 
  595     /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
  596     if (err != Z_OK && err != Z_BUF_ERROR)
  597         state->x.have = 0;
  598 
  599     /* set error code, and if no message, then done */
  600     state->err = err;
  601     if (msg == NULL)
  602         return;
  603 
  604     /* for an out of memory error, return literal string when requested */
  605     if (err == Z_MEM_ERROR)
  606         return;
  607 
  608     /* construct error message with path */
  609     if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
  610             NULL) {
  611         state->err = Z_MEM_ERROR;
  612         return;
  613     }
  614 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
  615     (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
  616                    "%s%s%s", state->path, ": ", msg);
  617 #else
  618     strcpy(state->msg, state->path);
  619     strcat(state->msg, ": ");
  620     strcat(state->msg, msg);
  621 #endif
  622 }
  623 
  624 #ifndef INT_MAX
  625 /* portably return maximum value for an int (when limits.h presumed not
  626    available) -- we need to do this to cover cases where 2's complement not
  627    used, since C standard permits 1's complement and sign-bit representations,
  628    otherwise we could just use ((unsigned)-1) >> 1 */
  629 unsigned ZLIB_INTERNAL gz_intmax()
  630 {
  631     unsigned p, q;
  632 
  633     p = 1;
  634     do {
  635         q = p;
  636         p <<= 1;
  637         p++;
  638     } while (p > q);
  639     return q >> 1;
  640 }
  641 #endif