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