1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/zlib/src/gzlib.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,634 @@ 1.4 +/* gzlib.c -- zlib functions common to reading and writing gzip files 1.5 + * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler 1.6 + * For conditions of distribution and use, see copyright notice in zlib.h 1.7 + */ 1.8 + 1.9 +#include "gzguts.h" 1.10 + 1.11 +#if defined(_WIN32) && !defined(__BORLANDC__) 1.12 +# define LSEEK _lseeki64 1.13 +#else 1.14 +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 1.15 +# define LSEEK lseek64 1.16 +#else 1.17 +# define LSEEK lseek 1.18 +#endif 1.19 +#endif 1.20 + 1.21 +/* Local functions */ 1.22 +local void gz_reset OF((gz_statep)); 1.23 +local gzFile gz_open OF((const void *, int, const char *)); 1.24 + 1.25 +#if defined UNDER_CE 1.26 + 1.27 +/* Map the Windows error number in ERROR to a locale-dependent error message 1.28 + string and return a pointer to it. Typically, the values for ERROR come 1.29 + from GetLastError. 1.30 + 1.31 + The string pointed to shall not be modified by the application, but may be 1.32 + overwritten by a subsequent call to gz_strwinerror 1.33 + 1.34 + The gz_strwinerror function does not change the current setting of 1.35 + GetLastError. */ 1.36 +char ZLIB_INTERNAL *gz_strwinerror (error) 1.37 + DWORD error; 1.38 +{ 1.39 + static char buf[1024]; 1.40 + 1.41 + wchar_t *msgbuf; 1.42 + DWORD lasterr = GetLastError(); 1.43 + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 1.44 + | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1.45 + NULL, 1.46 + error, 1.47 + 0, /* Default language */ 1.48 + (LPVOID)&msgbuf, 1.49 + 0, 1.50 + NULL); 1.51 + if (chars != 0) { 1.52 + /* If there is an \r\n appended, zap it. */ 1.53 + if (chars >= 2 1.54 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { 1.55 + chars -= 2; 1.56 + msgbuf[chars] = 0; 1.57 + } 1.58 + 1.59 + if (chars > sizeof (buf) - 1) { 1.60 + chars = sizeof (buf) - 1; 1.61 + msgbuf[chars] = 0; 1.62 + } 1.63 + 1.64 + wcstombs(buf, msgbuf, chars + 1); 1.65 + LocalFree(msgbuf); 1.66 + } 1.67 + else { 1.68 + sprintf(buf, "unknown win32 error (%ld)", error); 1.69 + } 1.70 + 1.71 + SetLastError(lasterr); 1.72 + return buf; 1.73 +} 1.74 + 1.75 +#endif /* UNDER_CE */ 1.76 + 1.77 +/* Reset gzip file state */ 1.78 +local void gz_reset(state) 1.79 + gz_statep state; 1.80 +{ 1.81 + state->x.have = 0; /* no output data available */ 1.82 + if (state->mode == GZ_READ) { /* for reading ... */ 1.83 + state->eof = 0; /* not at end of file */ 1.84 + state->past = 0; /* have not read past end yet */ 1.85 + state->how = LOOK; /* look for gzip header */ 1.86 + } 1.87 + state->seek = 0; /* no seek request pending */ 1.88 + gz_error(state, Z_OK, NULL); /* clear error */ 1.89 + state->x.pos = 0; /* no uncompressed data yet */ 1.90 + state->strm.avail_in = 0; /* no input data yet */ 1.91 +} 1.92 + 1.93 +/* Open a gzip file either by name or file descriptor. */ 1.94 +local gzFile gz_open(path, fd, mode) 1.95 + const void *path; 1.96 + int fd; 1.97 + const char *mode; 1.98 +{ 1.99 + gz_statep state; 1.100 + size_t len; 1.101 + int oflag; 1.102 +#ifdef O_CLOEXEC 1.103 + int cloexec = 0; 1.104 +#endif 1.105 +#ifdef O_EXCL 1.106 + int exclusive = 0; 1.107 +#endif 1.108 + 1.109 + /* check input */ 1.110 + if (path == NULL) 1.111 + return NULL; 1.112 + 1.113 + /* allocate gzFile structure to return */ 1.114 + state = (gz_statep)malloc(sizeof(gz_state)); 1.115 + if (state == NULL) 1.116 + return NULL; 1.117 + state->size = 0; /* no buffers allocated yet */ 1.118 + state->want = GZBUFSIZE; /* requested buffer size */ 1.119 + state->msg = NULL; /* no error message yet */ 1.120 + 1.121 + /* interpret mode */ 1.122 + state->mode = GZ_NONE; 1.123 + state->level = Z_DEFAULT_COMPRESSION; 1.124 + state->strategy = Z_DEFAULT_STRATEGY; 1.125 + state->direct = 0; 1.126 + while (*mode) { 1.127 + if (*mode >= '0' && *mode <= '9') 1.128 + state->level = *mode - '0'; 1.129 + else 1.130 + switch (*mode) { 1.131 + case 'r': 1.132 + state->mode = GZ_READ; 1.133 + break; 1.134 +#ifndef NO_GZCOMPRESS 1.135 + case 'w': 1.136 + state->mode = GZ_WRITE; 1.137 + break; 1.138 + case 'a': 1.139 + state->mode = GZ_APPEND; 1.140 + break; 1.141 +#endif 1.142 + case '+': /* can't read and write at the same time */ 1.143 + free(state); 1.144 + return NULL; 1.145 + case 'b': /* ignore -- will request binary anyway */ 1.146 + break; 1.147 +#ifdef O_CLOEXEC 1.148 + case 'e': 1.149 + cloexec = 1; 1.150 + break; 1.151 +#endif 1.152 +#ifdef O_EXCL 1.153 + case 'x': 1.154 + exclusive = 1; 1.155 + break; 1.156 +#endif 1.157 + case 'f': 1.158 + state->strategy = Z_FILTERED; 1.159 + break; 1.160 + case 'h': 1.161 + state->strategy = Z_HUFFMAN_ONLY; 1.162 + break; 1.163 + case 'R': 1.164 + state->strategy = Z_RLE; 1.165 + break; 1.166 + case 'F': 1.167 + state->strategy = Z_FIXED; 1.168 + break; 1.169 + case 'T': 1.170 + state->direct = 1; 1.171 + break; 1.172 + default: /* could consider as an error, but just ignore */ 1.173 + ; 1.174 + } 1.175 + mode++; 1.176 + } 1.177 + 1.178 + /* must provide an "r", "w", or "a" */ 1.179 + if (state->mode == GZ_NONE) { 1.180 + free(state); 1.181 + return NULL; 1.182 + } 1.183 + 1.184 + /* can't force transparent read */ 1.185 + if (state->mode == GZ_READ) { 1.186 + if (state->direct) { 1.187 + free(state); 1.188 + return NULL; 1.189 + } 1.190 + state->direct = 1; /* for empty file */ 1.191 + } 1.192 + 1.193 + /* save the path name for error messages */ 1.194 +#ifdef _WIN32 1.195 + if (fd == -2) { 1.196 + len = wcstombs(NULL, path, 0); 1.197 + if (len == (size_t)-1) 1.198 + len = 0; 1.199 + } 1.200 + else 1.201 +#endif 1.202 + len = strlen((const char *)path); 1.203 + state->path = (char *)malloc(len + 1); 1.204 + if (state->path == NULL) { 1.205 + free(state); 1.206 + return NULL; 1.207 + } 1.208 +#ifdef _WIN32 1.209 + if (fd == -2) 1.210 + if (len) 1.211 + wcstombs(state->path, path, len + 1); 1.212 + else 1.213 + *(state->path) = 0; 1.214 + else 1.215 +#endif 1.216 +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 1.217 + snprintf(state->path, len + 1, "%s", (const char *)path); 1.218 +#else 1.219 + strcpy(state->path, path); 1.220 +#endif 1.221 + 1.222 + /* compute the flags for open() */ 1.223 + oflag = 1.224 +#ifdef O_LARGEFILE 1.225 + O_LARGEFILE | 1.226 +#endif 1.227 +#ifdef O_BINARY 1.228 + O_BINARY | 1.229 +#endif 1.230 +#ifdef O_CLOEXEC 1.231 + (cloexec ? O_CLOEXEC : 0) | 1.232 +#endif 1.233 + (state->mode == GZ_READ ? 1.234 + O_RDONLY : 1.235 + (O_WRONLY | O_CREAT | 1.236 +#ifdef O_EXCL 1.237 + (exclusive ? O_EXCL : 0) | 1.238 +#endif 1.239 + (state->mode == GZ_WRITE ? 1.240 + O_TRUNC : 1.241 + O_APPEND))); 1.242 + 1.243 + /* open the file with the appropriate flags (or just use fd) */ 1.244 + state->fd = fd > -1 ? fd : ( 1.245 +#ifdef _WIN32 1.246 + fd == -2 ? _wopen(path, oflag, 0666) : 1.247 +#endif 1.248 + open((const char *)path, oflag, 0666)); 1.249 + if (state->fd == -1) { 1.250 + free(state->path); 1.251 + free(state); 1.252 + return NULL; 1.253 + } 1.254 + if (state->mode == GZ_APPEND) 1.255 + state->mode = GZ_WRITE; /* simplify later checks */ 1.256 + 1.257 + /* save the current position for rewinding (only if reading) */ 1.258 + if (state->mode == GZ_READ) { 1.259 + state->start = LSEEK(state->fd, 0, SEEK_CUR); 1.260 + if (state->start == -1) state->start = 0; 1.261 + } 1.262 + 1.263 + /* initialize stream */ 1.264 + gz_reset(state); 1.265 + 1.266 + /* return stream */ 1.267 + return (gzFile)state; 1.268 +} 1.269 + 1.270 +/* -- see zlib.h -- */ 1.271 +gzFile ZEXPORT gzopen(path, mode) 1.272 + const char *path; 1.273 + const char *mode; 1.274 +{ 1.275 + return gz_open(path, -1, mode); 1.276 +} 1.277 + 1.278 +/* -- see zlib.h -- */ 1.279 +gzFile ZEXPORT gzopen64(path, mode) 1.280 + const char *path; 1.281 + const char *mode; 1.282 +{ 1.283 + return gz_open(path, -1, mode); 1.284 +} 1.285 + 1.286 +/* -- see zlib.h -- */ 1.287 +gzFile ZEXPORT gzdopen(fd, mode) 1.288 + int fd; 1.289 + const char *mode; 1.290 +{ 1.291 + char *path; /* identifier for error messages */ 1.292 + gzFile gz; 1.293 + 1.294 + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) 1.295 + return NULL; 1.296 +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 1.297 + snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */ 1.298 +#else 1.299 + sprintf(path, "<fd:%d>", fd); /* for debugging */ 1.300 +#endif 1.301 + gz = gz_open(path, fd, mode); 1.302 + free(path); 1.303 + return gz; 1.304 +} 1.305 + 1.306 +/* -- see zlib.h -- */ 1.307 +#ifdef _WIN32 1.308 +gzFile ZEXPORT gzopen_w(path, mode) 1.309 + const wchar_t *path; 1.310 + const char *mode; 1.311 +{ 1.312 + return gz_open(path, -2, mode); 1.313 +} 1.314 +#endif 1.315 + 1.316 +/* -- see zlib.h -- */ 1.317 +int ZEXPORT gzbuffer(file, size) 1.318 + gzFile file; 1.319 + unsigned size; 1.320 +{ 1.321 + gz_statep state; 1.322 + 1.323 + /* get internal structure and check integrity */ 1.324 + if (file == NULL) 1.325 + return -1; 1.326 + state = (gz_statep)file; 1.327 + if (state->mode != GZ_READ && state->mode != GZ_WRITE) 1.328 + return -1; 1.329 + 1.330 + /* make sure we haven't already allocated memory */ 1.331 + if (state->size != 0) 1.332 + return -1; 1.333 + 1.334 + /* check and set requested size */ 1.335 + if (size < 2) 1.336 + size = 2; /* need two bytes to check magic header */ 1.337 + state->want = size; 1.338 + return 0; 1.339 +} 1.340 + 1.341 +/* -- see zlib.h -- */ 1.342 +int ZEXPORT gzrewind(file) 1.343 + gzFile file; 1.344 +{ 1.345 + gz_statep state; 1.346 + 1.347 + /* get internal structure */ 1.348 + if (file == NULL) 1.349 + return -1; 1.350 + state = (gz_statep)file; 1.351 + 1.352 + /* check that we're reading and that there's no error */ 1.353 + if (state->mode != GZ_READ || 1.354 + (state->err != Z_OK && state->err != Z_BUF_ERROR)) 1.355 + return -1; 1.356 + 1.357 + /* back up and start over */ 1.358 + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) 1.359 + return -1; 1.360 + gz_reset(state); 1.361 + return 0; 1.362 +} 1.363 + 1.364 +/* -- see zlib.h -- */ 1.365 +z_off64_t ZEXPORT gzseek64(file, offset, whence) 1.366 + gzFile file; 1.367 + z_off64_t offset; 1.368 + int whence; 1.369 +{ 1.370 + unsigned n; 1.371 + z_off64_t ret; 1.372 + gz_statep state; 1.373 + 1.374 + /* get internal structure and check integrity */ 1.375 + if (file == NULL) 1.376 + return -1; 1.377 + state = (gz_statep)file; 1.378 + if (state->mode != GZ_READ && state->mode != GZ_WRITE) 1.379 + return -1; 1.380 + 1.381 + /* check that there's no error */ 1.382 + if (state->err != Z_OK && state->err != Z_BUF_ERROR) 1.383 + return -1; 1.384 + 1.385 + /* can only seek from start or relative to current position */ 1.386 + if (whence != SEEK_SET && whence != SEEK_CUR) 1.387 + return -1; 1.388 + 1.389 + /* normalize offset to a SEEK_CUR specification */ 1.390 + if (whence == SEEK_SET) 1.391 + offset -= state->x.pos; 1.392 + else if (state->seek) 1.393 + offset += state->skip; 1.394 + state->seek = 0; 1.395 + 1.396 + /* if within raw area while reading, just go there */ 1.397 + if (state->mode == GZ_READ && state->how == COPY && 1.398 + state->x.pos + offset >= 0) { 1.399 + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); 1.400 + if (ret == -1) 1.401 + return -1; 1.402 + state->x.have = 0; 1.403 + state->eof = 0; 1.404 + state->past = 0; 1.405 + state->seek = 0; 1.406 + gz_error(state, Z_OK, NULL); 1.407 + state->strm.avail_in = 0; 1.408 + state->x.pos += offset; 1.409 + return state->x.pos; 1.410 + } 1.411 + 1.412 + /* calculate skip amount, rewinding if needed for back seek when reading */ 1.413 + if (offset < 0) { 1.414 + if (state->mode != GZ_READ) /* writing -- can't go backwards */ 1.415 + return -1; 1.416 + offset += state->x.pos; 1.417 + if (offset < 0) /* before start of file! */ 1.418 + return -1; 1.419 + if (gzrewind(file) == -1) /* rewind, then skip to offset */ 1.420 + return -1; 1.421 + } 1.422 + 1.423 + /* if reading, skip what's in output buffer (one less gzgetc() check) */ 1.424 + if (state->mode == GZ_READ) { 1.425 + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? 1.426 + (unsigned)offset : state->x.have; 1.427 + state->x.have -= n; 1.428 + state->x.next += n; 1.429 + state->x.pos += n; 1.430 + offset -= n; 1.431 + } 1.432 + 1.433 + /* request skip (if not zero) */ 1.434 + if (offset) { 1.435 + state->seek = 1; 1.436 + state->skip = offset; 1.437 + } 1.438 + return state->x.pos + offset; 1.439 +} 1.440 + 1.441 +/* -- see zlib.h -- */ 1.442 +z_off_t ZEXPORT gzseek(file, offset, whence) 1.443 + gzFile file; 1.444 + z_off_t offset; 1.445 + int whence; 1.446 +{ 1.447 + z_off64_t ret; 1.448 + 1.449 + ret = gzseek64(file, (z_off64_t)offset, whence); 1.450 + return ret == (z_off_t)ret ? (z_off_t)ret : -1; 1.451 +} 1.452 + 1.453 +/* -- see zlib.h -- */ 1.454 +z_off64_t ZEXPORT gztell64(file) 1.455 + gzFile file; 1.456 +{ 1.457 + gz_statep state; 1.458 + 1.459 + /* get internal structure and check integrity */ 1.460 + if (file == NULL) 1.461 + return -1; 1.462 + state = (gz_statep)file; 1.463 + if (state->mode != GZ_READ && state->mode != GZ_WRITE) 1.464 + return -1; 1.465 + 1.466 + /* return position */ 1.467 + return state->x.pos + (state->seek ? state->skip : 0); 1.468 +} 1.469 + 1.470 +/* -- see zlib.h -- */ 1.471 +z_off_t ZEXPORT gztell(file) 1.472 + gzFile file; 1.473 +{ 1.474 + z_off64_t ret; 1.475 + 1.476 + ret = gztell64(file); 1.477 + return ret == (z_off_t)ret ? (z_off_t)ret : -1; 1.478 +} 1.479 + 1.480 +/* -- see zlib.h -- */ 1.481 +z_off64_t ZEXPORT gzoffset64(file) 1.482 + gzFile file; 1.483 +{ 1.484 + z_off64_t offset; 1.485 + gz_statep state; 1.486 + 1.487 + /* get internal structure and check integrity */ 1.488 + if (file == NULL) 1.489 + return -1; 1.490 + state = (gz_statep)file; 1.491 + if (state->mode != GZ_READ && state->mode != GZ_WRITE) 1.492 + return -1; 1.493 + 1.494 + /* compute and return effective offset in file */ 1.495 + offset = LSEEK(state->fd, 0, SEEK_CUR); 1.496 + if (offset == -1) 1.497 + return -1; 1.498 + if (state->mode == GZ_READ) /* reading */ 1.499 + offset -= state->strm.avail_in; /* don't count buffered input */ 1.500 + return offset; 1.501 +} 1.502 + 1.503 +/* -- see zlib.h -- */ 1.504 +z_off_t ZEXPORT gzoffset(file) 1.505 + gzFile file; 1.506 +{ 1.507 + z_off64_t ret; 1.508 + 1.509 + ret = gzoffset64(file); 1.510 + return ret == (z_off_t)ret ? (z_off_t)ret : -1; 1.511 +} 1.512 + 1.513 +/* -- see zlib.h -- */ 1.514 +int ZEXPORT gzeof(file) 1.515 + gzFile file; 1.516 +{ 1.517 + gz_statep state; 1.518 + 1.519 + /* get internal structure and check integrity */ 1.520 + if (file == NULL) 1.521 + return 0; 1.522 + state = (gz_statep)file; 1.523 + if (state->mode != GZ_READ && state->mode != GZ_WRITE) 1.524 + return 0; 1.525 + 1.526 + /* return end-of-file state */ 1.527 + return state->mode == GZ_READ ? state->past : 0; 1.528 +} 1.529 + 1.530 +/* -- see zlib.h -- */ 1.531 +const char * ZEXPORT gzerror(file, errnum) 1.532 + gzFile file; 1.533 + int *errnum; 1.534 +{ 1.535 + gz_statep state; 1.536 + 1.537 + /* get internal structure and check integrity */ 1.538 + if (file == NULL) 1.539 + return NULL; 1.540 + state = (gz_statep)file; 1.541 + if (state->mode != GZ_READ && state->mode != GZ_WRITE) 1.542 + return NULL; 1.543 + 1.544 + /* return error information */ 1.545 + if (errnum != NULL) 1.546 + *errnum = state->err; 1.547 + return state->err == Z_MEM_ERROR ? "out of memory" : 1.548 + (state->msg == NULL ? "" : state->msg); 1.549 +} 1.550 + 1.551 +/* -- see zlib.h -- */ 1.552 +void ZEXPORT gzclearerr(file) 1.553 + gzFile file; 1.554 +{ 1.555 + gz_statep state; 1.556 + 1.557 + /* get internal structure and check integrity */ 1.558 + if (file == NULL) 1.559 + return; 1.560 + state = (gz_statep)file; 1.561 + if (state->mode != GZ_READ && state->mode != GZ_WRITE) 1.562 + return; 1.563 + 1.564 + /* clear error and end-of-file */ 1.565 + if (state->mode == GZ_READ) { 1.566 + state->eof = 0; 1.567 + state->past = 0; 1.568 + } 1.569 + gz_error(state, Z_OK, NULL); 1.570 +} 1.571 + 1.572 +/* Create an error message in allocated memory and set state->err and 1.573 + state->msg accordingly. Free any previous error message already there. Do 1.574 + not try to free or allocate space if the error is Z_MEM_ERROR (out of 1.575 + memory). Simply save the error message as a static string. If there is an 1.576 + allocation failure constructing the error message, then convert the error to 1.577 + out of memory. */ 1.578 +void ZLIB_INTERNAL gz_error(state, err, msg) 1.579 + gz_statep state; 1.580 + int err; 1.581 + const char *msg; 1.582 +{ 1.583 + /* free previously allocated message and clear */ 1.584 + if (state->msg != NULL) { 1.585 + if (state->err != Z_MEM_ERROR) 1.586 + free(state->msg); 1.587 + state->msg = NULL; 1.588 + } 1.589 + 1.590 + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ 1.591 + if (err != Z_OK && err != Z_BUF_ERROR) 1.592 + state->x.have = 0; 1.593 + 1.594 + /* set error code, and if no message, then done */ 1.595 + state->err = err; 1.596 + if (msg == NULL) 1.597 + return; 1.598 + 1.599 + /* for an out of memory error, return literal string when requested */ 1.600 + if (err == Z_MEM_ERROR) 1.601 + return; 1.602 + 1.603 + /* construct error message with path */ 1.604 + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == 1.605 + NULL) { 1.606 + state->err = Z_MEM_ERROR; 1.607 + return; 1.608 + } 1.609 +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 1.610 + snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, 1.611 + "%s%s%s", state->path, ": ", msg); 1.612 +#else 1.613 + strcpy(state->msg, state->path); 1.614 + strcat(state->msg, ": "); 1.615 + strcat(state->msg, msg); 1.616 +#endif 1.617 + return; 1.618 +} 1.619 + 1.620 +#ifndef INT_MAX 1.621 +/* portably return maximum value for an int (when limits.h presumed not 1.622 + available) -- we need to do this to cover cases where 2's complement not 1.623 + used, since C standard permits 1's complement and sign-bit representations, 1.624 + otherwise we could just use ((unsigned)-1) >> 1 */ 1.625 +unsigned ZLIB_INTERNAL gz_intmax() 1.626 +{ 1.627 + unsigned p, q; 1.628 + 1.629 + p = 1; 1.630 + do { 1.631 + q = p; 1.632 + p <<= 1; 1.633 + p++; 1.634 + } while (p > q); 1.635 + return q >> 1; 1.636 +} 1.637 +#endif