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

--- 41 unchanged lines hidden (view full) ---

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

--- 41 unchanged lines hidden (view full) ---

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;

--- 5 unchanged lines hidden (view full) ---

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;

--- 5 unchanged lines hidden (view full) ---

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

--- 38 unchanged lines hidden (view full) ---

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

--- 38 unchanged lines hidden (view full) ---

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}

--- 11 unchanged lines hidden (view full) ---

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}

--- 11 unchanged lines hidden (view full) ---

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{

--- 12 unchanged lines hidden (view full) ---

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{

--- 12 unchanged lines hidden (view full) ---

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

--- 43 unchanged lines hidden (view full) ---

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

--- 43 unchanged lines hidden (view full) ---

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;

--- 20 unchanged lines hidden (view full) ---

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;

--- 20 unchanged lines hidden (view full) ---

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

--- 5 unchanged lines hidden (view full) ---

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

--- 5 unchanged lines hidden (view full) ---

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;

--- 33 unchanged lines hidden ---
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;

--- 33 unchanged lines hidden ---