177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* gzlib.c -- zlib functions common to reading and writing gzip files
277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com * For conditions of distribution and use, see copyright notice in zlib.h
477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com */
577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#include "gzguts.h"
777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#if defined(_WIN32) && !defined(__BORLANDC__)
977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#  define LSEEK _lseeki64
1077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#else
1177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
1277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#  define LSEEK lseek64
1377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#else
1477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#  define LSEEK lseek
1577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
1677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
1777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
1877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* Local functions */
1977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comlocal void gz_reset OF((gz_statep));
2077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comlocal gzFile gz_open OF((const void *, int, const char *));
2177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
2277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#if defined UNDER_CE
2377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
2477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* Map the Windows error number in ERROR to a locale-dependent error message
2577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   string and return a pointer to it.  Typically, the values for ERROR come
2677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   from GetLastError.
2777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
2877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   The string pointed to shall not be modified by the application, but may be
2977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   overwritten by a subsequent call to gz_strwinerror
3077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
3177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   The gz_strwinerror function does not change the current setting of
3277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   GetLastError. */
3377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comchar ZLIB_INTERNAL *gz_strwinerror (error)
3477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com     DWORD error;
3577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
3677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    static char buf[1024];
3777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
3877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    wchar_t *msgbuf;
3977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    DWORD lasterr = GetLastError();
4077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
4177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
4277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        NULL,
4377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        error,
4477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        0, /* Default language */
4577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        (LPVOID)&msgbuf,
4677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        0,
4777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        NULL);
4877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (chars != 0) {
4977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        /* If there is an \r\n appended, zap it.  */
5077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (chars >= 2
5177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
5277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            chars -= 2;
5377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            msgbuf[chars] = 0;
5477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        }
5577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
5677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (chars > sizeof (buf) - 1) {
5777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            chars = sizeof (buf) - 1;
5877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            msgbuf[chars] = 0;
5977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        }
6077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
6177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        wcstombs(buf, msgbuf, chars + 1);
6277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        LocalFree(msgbuf);
6377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
6477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    else {
6577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        sprintf(buf, "unknown win32 error (%ld)", error);
6677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
6777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
6877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    SetLastError(lasterr);
6977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return buf;
7077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
7177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
7277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif /* UNDER_CE */
7377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
7477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* Reset gzip file state */
7577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comlocal void gz_reset(state)
7677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
7777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
7877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->x.have = 0;              /* no output data available */
7977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_READ) {   /* for reading ... */
8077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->eof = 0;             /* not at end of file */
8177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->past = 0;            /* have not read past end yet */
8277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->how = LOOK;          /* look for gzip header */
8377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
8477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->seek = 0;                /* no seek request pending */
8577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_error(state, Z_OK, NULL);    /* clear error */
8677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->x.pos = 0;               /* no uncompressed data yet */
8777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->strm.avail_in = 0;       /* no input data yet */
8877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
8977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
9077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* Open a gzip file either by name or file descriptor. */
9177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comlocal gzFile gz_open(path, fd, mode)
9277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const void *path;
9377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int fd;
9477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const char *mode;
9577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
9677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
9777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    size_t len;
9877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int oflag;
9977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef O_CLOEXEC
10077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int cloexec = 0;
10177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
10277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef O_EXCL
10377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int exclusive = 0;
10477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
10577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
10677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* check input */
10777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (path == NULL)
10877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return NULL;
10977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
11077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* allocate gzFile structure to return */
11177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)malloc(sizeof(gz_state));
11277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state == NULL)
11377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return NULL;
11477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->size = 0;            /* no buffers allocated yet */
11577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->want = GZBUFSIZE;    /* requested buffer size */
11677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->msg = NULL;          /* no error message yet */
11777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
11877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* interpret mode */
11977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->mode = GZ_NONE;
12077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->level = Z_DEFAULT_COMPRESSION;
12177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->strategy = Z_DEFAULT_STRATEGY;
12277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->direct = 0;
12377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    while (*mode) {
12477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (*mode >= '0' && *mode <= '9')
12577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            state->level = *mode - '0';
12677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        else
12777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            switch (*mode) {
12877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'r':
12977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                state->mode = GZ_READ;
13077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
13177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifndef NO_GZCOMPRESS
13277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'w':
13377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                state->mode = GZ_WRITE;
13477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
13577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'a':
13677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                state->mode = GZ_APPEND;
13777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
13877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
13977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case '+':       /* can't read and write at the same time */
14077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                free(state);
14177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                return NULL;
14277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'b':       /* ignore -- will request binary anyway */
14377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
14477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef O_CLOEXEC
14577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'e':
14677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                cloexec = 1;
14777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
14877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
14977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef O_EXCL
15077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'x':
15177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                exclusive = 1;
15277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
15377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
15477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'f':
15577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                state->strategy = Z_FILTERED;
15677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
15777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'h':
15877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                state->strategy = Z_HUFFMAN_ONLY;
15977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
16077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'R':
16177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                state->strategy = Z_RLE;
16277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
16377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'F':
16477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                state->strategy = Z_FIXED;
16577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
16677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            case 'T':
16777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                state->direct = 1;
16877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                break;
16977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            default:        /* could consider as an error, but just ignore */
17077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                ;
17177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            }
17277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        mode++;
17377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
17477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
17577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* must provide an "r", "w", or "a" */
17677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_NONE) {
17777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        free(state);
17877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return NULL;
17977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
18077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
18177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* can't force transparent read */
18277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_READ) {
18377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (state->direct) {
18477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            free(state);
18577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            return NULL;
18677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        }
18777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->direct = 1;      /* for empty file */
18877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
18977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
19077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* save the path name for error messages */
19177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef _WIN32
19277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (fd == -2) {
19377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        len = wcstombs(NULL, path, 0);
19477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (len == (size_t)-1)
19577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            len = 0;
19677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
19777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    else
19877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
19977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        len = strlen((const char *)path);
20077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->path = (char *)malloc(len + 1);
20177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->path == NULL) {
20277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        free(state);
20377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return NULL;
20477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
20577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef _WIN32
20677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (fd == -2)
20777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (len)
20877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            wcstombs(state->path, path, len + 1);
20977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        else
21077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            *(state->path) = 0;
21177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    else
21277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
21377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
21477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        snprintf(state->path, len + 1, "%s", (const char *)path);
21577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#else
21677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        strcpy(state->path, path);
21777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
21877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
21977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* compute the flags for open() */
22077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    oflag =
22177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef O_LARGEFILE
22277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        O_LARGEFILE |
22377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
22477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef O_BINARY
22577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        O_BINARY |
22677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
22777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef O_CLOEXEC
22877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        (cloexec ? O_CLOEXEC : 0) |
22977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
23077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        (state->mode == GZ_READ ?
23177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com         O_RDONLY :
23277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com         (O_WRONLY | O_CREAT |
23377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef O_EXCL
23477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com          (exclusive ? O_EXCL : 0) |
23577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
23677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com          (state->mode == GZ_WRITE ?
23777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com           O_TRUNC :
23877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com           O_APPEND)));
23977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
24077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* open the file with the appropriate flags (or just use fd) */
24177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->fd = fd > -1 ? fd : (
24277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef _WIN32
24377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        fd == -2 ? _wopen(path, oflag, 0666) :
24477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
24577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        open((const char *)path, oflag, 0666));
24677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->fd == -1) {
24777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        free(state->path);
24877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        free(state);
24977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return NULL;
25077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
25177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_APPEND)
25277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->mode = GZ_WRITE;         /* simplify later checks */
25377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
25477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* save the current position for rewinding (only if reading) */
25577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_READ) {
25677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->start = LSEEK(state->fd, 0, SEEK_CUR);
25777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (state->start == -1) state->start = 0;
25877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
25977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
26077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* initialize stream */
26177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_reset(state);
26277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
26377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* return stream */
26477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return (gzFile)state;
26577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
26677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
26777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
26877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comgzFile ZEXPORT gzopen(path, mode)
26977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const char *path;
27077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const char *mode;
27177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
27277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return gz_open(path, -1, mode);
27377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
27477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
27577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
27677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comgzFile ZEXPORT gzopen64(path, mode)
27777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const char *path;
27877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const char *mode;
27977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
28077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return gz_open(path, -1, mode);
28177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
28277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
28377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
28477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comgzFile ZEXPORT gzdopen(fd, mode)
28577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int fd;
28677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const char *mode;
28777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
28877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    char *path;         /* identifier for error messages */
28977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile gz;
29077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
29177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
29277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return NULL;
29377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
29477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
29577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#else
29677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    sprintf(path, "<fd:%d>", fd);   /* for debugging */
29777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
29877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz = gz_open(path, fd, mode);
29977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    free(path);
30077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return gz;
30177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
30277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
30377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
30477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifdef _WIN32
30577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comgzFile ZEXPORT gzopen_w(path, mode)
30677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const wchar_t *path;
30777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const char *mode;
30877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
30977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return gz_open(path, -2, mode);
31077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
31177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
31277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
31377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
31477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comint ZEXPORT gzbuffer(file, size)
31577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
31677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    unsigned size;
31777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
31877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
31977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
32077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* get internal structure and check integrity */
32177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (file == NULL)
32277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
32377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)file;
32477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
32577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
32677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
32777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* make sure we haven't already allocated memory */
32877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->size != 0)
32977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
33077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
33177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* check and set requested size */
33277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (size < 2)
33377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        size = 2;               /* need two bytes to check magic header */
33477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->want = size;
33577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return 0;
33677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
33777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
33877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
33977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comint ZEXPORT gzrewind(file)
34077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
34177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
34277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
34377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
34477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* get internal structure */
34577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (file == NULL)
34677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
34777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)file;
34877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
34977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* check that we're reading and that there's no error */
35077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode != GZ_READ ||
35177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            (state->err != Z_OK && state->err != Z_BUF_ERROR))
35277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
35377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
35477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* back up and start over */
35577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
35677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
35777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_reset(state);
35877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return 0;
35977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
36077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
36177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
36277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comz_off64_t ZEXPORT gzseek64(file, offset, whence)
36377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
36477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    z_off64_t offset;
36577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int whence;
36677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
36777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    unsigned n;
36877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    z_off64_t ret;
36977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
37077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
37177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* get internal structure and check integrity */
37277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (file == NULL)
37377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
37477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)file;
37577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
37677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
37777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
37877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* check that there's no error */
37977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
38077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
38177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
38277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* can only seek from start or relative to current position */
38377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (whence != SEEK_SET && whence != SEEK_CUR)
38477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
38577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
38677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* normalize offset to a SEEK_CUR specification */
38777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (whence == SEEK_SET)
38877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        offset -= state->x.pos;
38977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    else if (state->seek)
39077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        offset += state->skip;
39177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->seek = 0;
39277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
39377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* if within raw area while reading, just go there */
39477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_READ && state->how == COPY &&
39577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            state->x.pos + offset >= 0) {
39677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
39777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (ret == -1)
39877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            return -1;
39977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->x.have = 0;
40077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->eof = 0;
40177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->past = 0;
40277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->seek = 0;
40377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        gz_error(state, Z_OK, NULL);
40477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->strm.avail_in = 0;
40577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->x.pos += offset;
40677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return state->x.pos;
40777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
40877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
40977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* calculate skip amount, rewinding if needed for back seek when reading */
41077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (offset < 0) {
41177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (state->mode != GZ_READ)         /* writing -- can't go backwards */
41277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            return -1;
41377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        offset += state->x.pos;
41477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (offset < 0)                     /* before start of file! */
41577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            return -1;
41677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (gzrewind(file) == -1)           /* rewind, then skip to offset */
41777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            return -1;
41877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
41977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
42077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* if reading, skip what's in output buffer (one less gzgetc() check) */
42177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_READ) {
42277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
42377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            (unsigned)offset : state->x.have;
42477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->x.have -= n;
42577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->x.next += n;
42677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->x.pos += n;
42777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        offset -= n;
42877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
42977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
43077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* request skip (if not zero) */
43177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (offset) {
43277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->seek = 1;
43377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->skip = offset;
43477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
43577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return state->x.pos + offset;
43677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
43777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
43877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
43977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comz_off_t ZEXPORT gzseek(file, offset, whence)
44077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
44177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    z_off_t offset;
44277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int whence;
44377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
44477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    z_off64_t ret;
44577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
44677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    ret = gzseek64(file, (z_off64_t)offset, whence);
44777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
44877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
44977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
45077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
45177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comz_off64_t ZEXPORT gztell64(file)
45277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
45377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
45477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
45577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
45677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* get internal structure and check integrity */
45777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (file == NULL)
45877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
45977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)file;
46077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
46177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
46277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
46377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* return position */
46477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return state->x.pos + (state->seek ? state->skip : 0);
46577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
46677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
46777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
46877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comz_off_t ZEXPORT gztell(file)
46977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
47077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
47177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    z_off64_t ret;
47277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
47377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    ret = gztell64(file);
47477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
47577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
47677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
47777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
47877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comz_off64_t ZEXPORT gzoffset64(file)
47977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
48077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
48177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    z_off64_t offset;
48277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
48377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
48477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* get internal structure and check integrity */
48577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (file == NULL)
48677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
48777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)file;
48877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
48977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
49077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
49177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* compute and return effective offset in file */
49277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    offset = LSEEK(state->fd, 0, SEEK_CUR);
49377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (offset == -1)
49477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return -1;
49577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_READ)             /* reading */
49677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        offset -= state->strm.avail_in;     /* don't count buffered input */
49777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return offset;
49877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
49977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
50077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
50177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comz_off_t ZEXPORT gzoffset(file)
50277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
50377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
50477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    z_off64_t ret;
50577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
50677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    ret = gzoffset64(file);
50777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
50877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
50977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
51077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
51177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comint ZEXPORT gzeof(file)
51277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
51377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
51477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
51577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
51677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* get internal structure and check integrity */
51777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (file == NULL)
51877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return 0;
51977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)file;
52077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
52177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return 0;
52277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
52377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* return end-of-file state */
52477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return state->mode == GZ_READ ? state->past : 0;
52577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
52677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
52777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
52877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comconst char * ZEXPORT gzerror(file, errnum)
52977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
53077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int *errnum;
53177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
53277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
53377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
53477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* get internal structure and check integrity */
53577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (file == NULL)
53677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return NULL;
53777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)file;
53877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
53977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return NULL;
54077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
54177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* return error information */
54277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (errnum != NULL)
54377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        *errnum = state->err;
54477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return state->err == Z_MEM_ERROR ? "out of memory" :
54577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com                                       (state->msg == NULL ? "" : state->msg);
54677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
54777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
54877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* -- see zlib.h -- */
54977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comvoid ZEXPORT gzclearerr(file)
55077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gzFile file;
55177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
55277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
55377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
55477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* get internal structure and check integrity */
55577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (file == NULL)
55677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return;
55777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state = (gz_statep)file;
55877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
55977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return;
56077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
56177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* clear error and end-of-file */
56277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->mode == GZ_READ) {
56377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->eof = 0;
56477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->past = 0;
56577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
56677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_error(state, Z_OK, NULL);
56777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
56877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
56977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* Create an error message in allocated memory and set state->err and
57077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   state->msg accordingly.  Free any previous error message already there.  Do
57177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   not try to free or allocate space if the error is Z_MEM_ERROR (out of
57277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   memory).  Simply save the error message as a static string.  If there is an
57377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   allocation failure constructing the error message, then convert the error to
57477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   out of memory. */
57577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comvoid ZLIB_INTERNAL gz_error(state, err, msg)
57677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    gz_statep state;
57777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    int err;
57877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    const char *msg;
57977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
58077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* free previously allocated message and clear */
58177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (state->msg != NULL) {
58277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        if (state->err != Z_MEM_ERROR)
58377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            free(state->msg);
58477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->msg = NULL;
58577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
58677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
58777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
58877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (err != Z_OK && err != Z_BUF_ERROR)
58977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->x.have = 0;
59077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
59177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* set error code, and if no message, then done */
59277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    state->err = err;
59377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (msg == NULL)
59477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return;
59577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
59677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* for an out of memory error, return literal string when requested */
59777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if (err == Z_MEM_ERROR)
59877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return;
59977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
60077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    /* construct error message with path */
60177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
60277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com            NULL) {
60377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        state->err = Z_MEM_ERROR;
60477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        return;
60577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    }
60677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
60777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
60877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com             "%s%s%s", state->path, ": ", msg);
60977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#else
61077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    strcpy(state->msg, state->path);
61177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    strcat(state->msg, ": ");
61277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    strcat(state->msg, msg);
61377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
61477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return;
61577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
61677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
61777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#ifndef INT_MAX
61877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com/* portably return maximum value for an int (when limits.h presumed not
61977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   available) -- we need to do this to cover cases where 2's complement not
62077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   used, since C standard permits 1's complement and sign-bit representations,
62177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com   otherwise we could just use ((unsigned)-1) >> 1 */
62277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.comunsigned ZLIB_INTERNAL gz_intmax()
62377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com{
62477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    unsigned p, q;
62577a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com
62677a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    p = 1;
62777a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    do {
62877a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        q = p;
62977a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        p <<= 1;
63077a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com        p++;
63177a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    } while (p > q);
63277a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com    return q >> 1;
63377a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com}
63477a64bfdf752c594e09914f019f65e7f6aa633f5doko@ubuntu.com#endif
635