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 --- |