Deleted Added
sdiff udiff text old ( 206924 ) new ( 237410 )
full compact
1/* gzlib.c -- zlib functions common to reading and writing gzip files
2 * Copyright (C) 2004, 2010 Mark Adler
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 $ */
7
8#include "gzguts.h"
9#include "zutil.h"
10
11#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
12# define LSEEK lseek64
13#else
14# define LSEEK lseek
15#endif
16
17/* Local functions */
18local void gz_reset OF((gz_statep));
19local gzFile gz_open OF((const char *, 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{
77 if (state->mode == GZ_READ) { /* for reading ... */
78 state->have = 0; /* no output data available */
79 state->eof = 0; /* not at end of file */
80 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 */
85 state->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)
91 const char *path;
92 int fd;
93 const char *mode;
94{
95 gz_statep state;
96
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;
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;
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;
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
153 /* save the path name for error messages */
154 state->path = malloc(strlen(path) + 1);
155 if (state->path == NULL) {
156 free(state);
157 return NULL;
158 }
159 strcpy(state->path, path);
160
161 /* open the file with the appropriate mode (or just use fd) */
162 state->fd = fd != -1 ? fd :
163 open(path,
164#ifdef O_LARGEFILE
165 O_LARGEFILE |
166#endif
167#ifdef O_BINARY
168 O_BINARY |
169#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);
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 -- */
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 */
249 if (size == 0)
250 return -1;
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 */
267 if (state->mode != GZ_READ || state->err != Z_OK)
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 */
295 if (state->err != Z_OK)
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)
304 offset -= state->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 &&
311 state->pos + offset >= state->raw) {
312 ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
313 if (ret == -1)
314 return -1;
315 state->have = 0;
316 state->eof = 0;
317 state->seek = 0;
318 gz_error(state, Z_OK, NULL);
319 state->strm.avail_in = 0;
320 state->pos += offset;
321 return state->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;
328 offset += state->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) {
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;
342 offset -= n;
343 }
344
345 /* request skip (if not zero) */
346 if (offset) {
347 state->seek = 1;
348 state->skip = offset;
349 }
350 return state->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 */
379 return state->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 */
439 return state->mode == GZ_READ ?
440 (state->eof && state->strm.avail_in == 0 && state->have == 0) : 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 */
477 if (state->mode == GZ_READ)
478 state->eof = 0;
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
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 ---