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