File indexing completed on 2025-05-11 08:24:11
0001
0002
0003
0004
0005
0006 #include "gzguts.h"
0007
0008 #if defined(_WIN32) && !defined(__BORLANDC__)
0009 # define LSEEK _lseeki64
0010 #else
0011 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
0012 # define LSEEK lseek64
0013 #else
0014 # define LSEEK lseek
0015 #endif
0016 #endif
0017
0018
0019 local void gz_reset OF((gz_statep));
0020 local gzFile gz_open OF((const void *, int, const char *));
0021
0022 #if defined UNDER_CE
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 char ZLIB_INTERNAL *gz_strwinerror(error)
0034 DWORD error;
0035 {
0036 static char buf[1024];
0037
0038 wchar_t *msgbuf;
0039 DWORD lasterr = GetLastError();
0040 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
0041 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
0042 NULL,
0043 error,
0044 0,
0045 (LPVOID)&msgbuf,
0046 0,
0047 NULL);
0048 if (chars != 0) {
0049
0050 if (chars >= 2
0051 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
0052 chars -= 2;
0053 msgbuf[chars] = 0;
0054 }
0055
0056 if (chars > sizeof (buf) - 1) {
0057 chars = sizeof (buf) - 1;
0058 msgbuf[chars] = 0;
0059 }
0060
0061 wcstombs(buf, msgbuf, chars + 1);
0062 LocalFree(msgbuf);
0063 }
0064 else {
0065 sprintf(buf, "unknown win32 error (%ld)", error);
0066 }
0067
0068 SetLastError(lasterr);
0069 return buf;
0070 }
0071
0072 #endif
0073
0074
0075 local void gz_reset(state)
0076 gz_statep state;
0077 {
0078 state->x.have = 0;
0079 if (state->mode == GZ_READ) {
0080 state->eof = 0;
0081 state->past = 0;
0082 state->how = LOOK;
0083 }
0084 else
0085 state->reset = 0;
0086 state->seek = 0;
0087 gz_error(state, Z_OK, NULL);
0088 state->x.pos = 0;
0089 state->strm.avail_in = 0;
0090 }
0091
0092
0093 local gzFile gz_open(path, fd, mode)
0094 const void *path;
0095 int fd;
0096 const char *mode;
0097 {
0098 gz_statep state;
0099 z_size_t len;
0100 int oflag;
0101 #ifdef O_CLOEXEC
0102 int cloexec = 0;
0103 #endif
0104 #ifdef O_EXCL
0105 int exclusive = 0;
0106 #endif
0107
0108
0109 if (path == NULL)
0110 return NULL;
0111
0112
0113 state = (gz_statep)malloc(sizeof(gz_state));
0114 if (state == NULL)
0115 return NULL;
0116 state->size = 0;
0117 state->want = GZBUFSIZE;
0118 state->msg = NULL;
0119
0120
0121 state->mode = GZ_NONE;
0122 state->level = Z_DEFAULT_COMPRESSION;
0123 state->strategy = Z_DEFAULT_STRATEGY;
0124 state->direct = 0;
0125 while (*mode) {
0126 if (*mode >= '0' && *mode <= '9')
0127 state->level = *mode - '0';
0128 else
0129 switch (*mode) {
0130 case 'r':
0131 state->mode = GZ_READ;
0132 break;
0133 #ifndef NO_GZCOMPRESS
0134 case 'w':
0135 state->mode = GZ_WRITE;
0136 break;
0137 case 'a':
0138 state->mode = GZ_APPEND;
0139 break;
0140 #endif
0141 case '+':
0142 free(state);
0143 return NULL;
0144 case 'b':
0145 break;
0146 #ifdef O_CLOEXEC
0147 case 'e':
0148 cloexec = 1;
0149 break;
0150 #endif
0151 #ifdef O_EXCL
0152 case 'x':
0153 exclusive = 1;
0154 break;
0155 #endif
0156 case 'f':
0157 state->strategy = Z_FILTERED;
0158 break;
0159 case 'h':
0160 state->strategy = Z_HUFFMAN_ONLY;
0161 break;
0162 case 'R':
0163 state->strategy = Z_RLE;
0164 break;
0165 case 'F':
0166 state->strategy = Z_FIXED;
0167 break;
0168 case 'T':
0169 state->direct = 1;
0170 break;
0171 default:
0172 ;
0173 }
0174 mode++;
0175 }
0176
0177
0178 if (state->mode == GZ_NONE) {
0179 free(state);
0180 return NULL;
0181 }
0182
0183
0184 if (state->mode == GZ_READ) {
0185 if (state->direct) {
0186 free(state);
0187 return NULL;
0188 }
0189 state->direct = 1;
0190 }
0191
0192
0193 #ifdef WIDECHAR
0194 if (fd == -2) {
0195 len = wcstombs(NULL, path, 0);
0196 if (len == (z_size_t)-1)
0197 len = 0;
0198 }
0199 else
0200 #endif
0201 len = strlen((const char *)path);
0202 state->path = (char *)malloc(len + 1);
0203 if (state->path == NULL) {
0204 free(state);
0205 return NULL;
0206 }
0207 #ifdef WIDECHAR
0208 if (fd == -2)
0209 if (len)
0210 wcstombs(state->path, path, len + 1);
0211 else
0212 *(state->path) = 0;
0213 else
0214 #endif
0215 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
0216 (void)snprintf(state->path, len + 1, "%s", (const char *)path);
0217 #else
0218 strcpy(state->path, path);
0219 #endif
0220
0221
0222 oflag =
0223 #ifdef O_LARGEFILE
0224 O_LARGEFILE |
0225 #endif
0226 #ifdef O_BINARY
0227 O_BINARY |
0228 #endif
0229 #ifdef O_CLOEXEC
0230 (cloexec ? O_CLOEXEC : 0) |
0231 #endif
0232 (state->mode == GZ_READ ?
0233 O_RDONLY :
0234 (O_WRONLY | O_CREAT |
0235 #ifdef O_EXCL
0236 (exclusive ? O_EXCL : 0) |
0237 #endif
0238 (state->mode == GZ_WRITE ?
0239 O_TRUNC :
0240 O_APPEND)));
0241
0242
0243 state->fd = fd > -1 ? fd : (
0244 #ifdef WIDECHAR
0245 fd == -2 ? _wopen(path, oflag, 0666) :
0246 #endif
0247 open((const char *)path, oflag, 0666));
0248 if (state->fd == -1) {
0249 free(state->path);
0250 free(state);
0251 return NULL;
0252 }
0253 if (state->mode == GZ_APPEND) {
0254 LSEEK(state->fd, 0, SEEK_END);
0255 state->mode = GZ_WRITE;
0256 }
0257
0258
0259 if (state->mode == GZ_READ) {
0260 state->start = LSEEK(state->fd, 0, SEEK_CUR);
0261 if (state->start == -1) state->start = 0;
0262 }
0263
0264
0265 gz_reset(state);
0266
0267
0268 return (gzFile)state;
0269 }
0270
0271
0272 gzFile ZEXPORT gzopen(path, mode)
0273 const char *path;
0274 const char *mode;
0275 {
0276 return gz_open(path, -1, mode);
0277 }
0278
0279
0280 gzFile ZEXPORT gzopen64(path, mode)
0281 const char *path;
0282 const char *mode;
0283 {
0284 return gz_open(path, -1, mode);
0285 }
0286
0287
0288 gzFile ZEXPORT gzdopen(fd, mode)
0289 int fd;
0290 const char *mode;
0291 {
0292 char *path;
0293 gzFile gz;
0294
0295 if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
0296 return NULL;
0297 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
0298 (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
0299 #else
0300 sprintf(path, "<fd:%d>", fd);
0301 #endif
0302 gz = gz_open(path, fd, mode);
0303 free(path);
0304 return gz;
0305 }
0306
0307
0308 #ifdef WIDECHAR
0309 gzFile ZEXPORT gzopen_w(path, mode)
0310 const wchar_t *path;
0311 const char *mode;
0312 {
0313 return gz_open(path, -2, mode);
0314 }
0315 #endif
0316
0317
0318 int ZEXPORT gzbuffer(file, size)
0319 gzFile file;
0320 unsigned size;
0321 {
0322 gz_statep state;
0323
0324
0325 if (file == NULL)
0326 return -1;
0327 state = (gz_statep)file;
0328 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
0329 return -1;
0330
0331
0332 if (state->size != 0)
0333 return -1;
0334
0335
0336 if ((size << 1) < size)
0337 return -1;
0338 if (size < 2)
0339 size = 2;
0340 state->want = size;
0341 return 0;
0342 }
0343
0344
0345 int ZEXPORT gzrewind(file)
0346 gzFile file;
0347 {
0348 gz_statep state;
0349
0350
0351 if (file == NULL)
0352 return -1;
0353 state = (gz_statep)file;
0354
0355
0356 if (state->mode != GZ_READ ||
0357 (state->err != Z_OK && state->err != Z_BUF_ERROR))
0358 return -1;
0359
0360
0361 if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
0362 return -1;
0363 gz_reset(state);
0364 return 0;
0365 }
0366
0367
0368 z_off64_t ZEXPORT gzseek64(file, offset, whence)
0369 gzFile file;
0370 z_off64_t offset;
0371 int whence;
0372 {
0373 unsigned n;
0374 z_off64_t ret;
0375 gz_statep state;
0376
0377
0378 if (file == NULL)
0379 return -1;
0380 state = (gz_statep)file;
0381 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
0382 return -1;
0383
0384
0385 if (state->err != Z_OK && state->err != Z_BUF_ERROR)
0386 return -1;
0387
0388
0389 if (whence != SEEK_SET && whence != SEEK_CUR)
0390 return -1;
0391
0392
0393 if (whence == SEEK_SET)
0394 offset -= state->x.pos;
0395 else if (state->seek)
0396 offset += state->skip;
0397 state->seek = 0;
0398
0399
0400 if (state->mode == GZ_READ && state->how == COPY &&
0401 state->x.pos + offset >= 0) {
0402 ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR);
0403 if (ret == -1)
0404 return -1;
0405 state->x.have = 0;
0406 state->eof = 0;
0407 state->past = 0;
0408 state->seek = 0;
0409 gz_error(state, Z_OK, NULL);
0410 state->strm.avail_in = 0;
0411 state->x.pos += offset;
0412 return state->x.pos;
0413 }
0414
0415
0416 if (offset < 0) {
0417 if (state->mode != GZ_READ)
0418 return -1;
0419 offset += state->x.pos;
0420 if (offset < 0)
0421 return -1;
0422 if (gzrewind(file) == -1)
0423 return -1;
0424 }
0425
0426
0427 if (state->mode == GZ_READ) {
0428 n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
0429 (unsigned)offset : state->x.have;
0430 state->x.have -= n;
0431 state->x.next += n;
0432 state->x.pos += n;
0433 offset -= n;
0434 }
0435
0436
0437 if (offset) {
0438 state->seek = 1;
0439 state->skip = offset;
0440 }
0441 return state->x.pos + offset;
0442 }
0443
0444
0445 z_off_t ZEXPORT gzseek(file, offset, whence)
0446 gzFile file;
0447 z_off_t offset;
0448 int whence;
0449 {
0450 z_off64_t ret;
0451
0452 ret = gzseek64(file, (z_off64_t)offset, whence);
0453 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
0454 }
0455
0456
0457 z_off64_t ZEXPORT gztell64(file)
0458 gzFile file;
0459 {
0460 gz_statep state;
0461
0462
0463 if (file == NULL)
0464 return -1;
0465 state = (gz_statep)file;
0466 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
0467 return -1;
0468
0469
0470 return state->x.pos + (state->seek ? state->skip : 0);
0471 }
0472
0473
0474 z_off_t ZEXPORT gztell(file)
0475 gzFile file;
0476 {
0477 z_off64_t ret;
0478
0479 ret = gztell64(file);
0480 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
0481 }
0482
0483
0484 z_off64_t ZEXPORT gzoffset64(file)
0485 gzFile file;
0486 {
0487 z_off64_t offset;
0488 gz_statep state;
0489
0490
0491 if (file == NULL)
0492 return -1;
0493 state = (gz_statep)file;
0494 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
0495 return -1;
0496
0497
0498 offset = LSEEK(state->fd, 0, SEEK_CUR);
0499 if (offset == -1)
0500 return -1;
0501 if (state->mode == GZ_READ)
0502 offset -= state->strm.avail_in;
0503 return offset;
0504 }
0505
0506
0507 z_off_t ZEXPORT gzoffset(file)
0508 gzFile file;
0509 {
0510 z_off64_t ret;
0511
0512 ret = gzoffset64(file);
0513 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
0514 }
0515
0516
0517 int ZEXPORT gzeof(file)
0518 gzFile file;
0519 {
0520 gz_statep state;
0521
0522
0523 if (file == NULL)
0524 return 0;
0525 state = (gz_statep)file;
0526 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
0527 return 0;
0528
0529
0530 return state->mode == GZ_READ ? state->past : 0;
0531 }
0532
0533
0534 const char * ZEXPORT gzerror(file, errnum)
0535 gzFile file;
0536 int *errnum;
0537 {
0538 gz_statep state;
0539
0540
0541 if (file == NULL)
0542 return NULL;
0543 state = (gz_statep)file;
0544 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
0545 return NULL;
0546
0547
0548 if (errnum != NULL)
0549 *errnum = state->err;
0550 return state->err == Z_MEM_ERROR ? "out of memory" :
0551 (state->msg == NULL ? "" : state->msg);
0552 }
0553
0554
0555 void ZEXPORT gzclearerr(file)
0556 gzFile file;
0557 {
0558 gz_statep state;
0559
0560
0561 if (file == NULL)
0562 return;
0563 state = (gz_statep)file;
0564 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
0565 return;
0566
0567
0568 if (state->mode == GZ_READ) {
0569 state->eof = 0;
0570 state->past = 0;
0571 }
0572 gz_error(state, Z_OK, NULL);
0573 }
0574
0575
0576
0577
0578
0579
0580
0581 void ZLIB_INTERNAL gz_error(state, err, msg)
0582 gz_statep state;
0583 int err;
0584 const char *msg;
0585 {
0586
0587 if (state->msg != NULL) {
0588 if (state->err != Z_MEM_ERROR)
0589 free(state->msg);
0590 state->msg = NULL;
0591 }
0592
0593
0594 if (err != Z_OK && err != Z_BUF_ERROR)
0595 state->x.have = 0;
0596
0597
0598 state->err = err;
0599 if (msg == NULL)
0600 return;
0601
0602
0603 if (err == Z_MEM_ERROR)
0604 return;
0605
0606
0607 if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
0608 NULL) {
0609 state->err = Z_MEM_ERROR;
0610 return;
0611 }
0612 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
0613 (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
0614 "%s%s%s", state->path, ": ", msg);
0615 #else
0616 strcpy(state->msg, state->path);
0617 strcat(state->msg, ": ");
0618 strcat(state->msg, msg);
0619 #endif
0620 }
0621
0622 #ifndef INT_MAX
0623
0624
0625
0626
0627 unsigned ZLIB_INTERNAL gz_intmax()
0628 {
0629 unsigned p, q;
0630
0631 p = 1;
0632 do {
0633 q = p;
0634 p <<= 1;
0635 p++;
0636 } while (p > q);
0637 return q >> 1;
0638 }
0639 #endif