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