File indexing completed on 2025-05-11 08:24:11
0001
0002
0003
0004
0005
0006 #include "gzguts.h"
0007
0008
0009 local int gz_init OF((gz_statep));
0010 local int gz_comp OF((gz_statep, int));
0011 local int gz_zero OF((gz_statep, z_off64_t));
0012 local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
0013
0014
0015
0016
0017 local int gz_init(state)
0018 gz_statep state;
0019 {
0020 int ret;
0021 z_streamp strm = &(state->strm);
0022
0023
0024 state->in = (unsigned char *)malloc(state->want << 1);
0025 if (state->in == NULL) {
0026 gz_error(state, Z_MEM_ERROR, "out of memory");
0027 return -1;
0028 }
0029
0030
0031 if (!state->direct) {
0032
0033 state->out = (unsigned char *)malloc(state->want);
0034 if (state->out == NULL) {
0035 free(state->in);
0036 gz_error(state, Z_MEM_ERROR, "out of memory");
0037 return -1;
0038 }
0039
0040
0041 strm->zalloc = Z_NULL;
0042 strm->zfree = Z_NULL;
0043 strm->opaque = Z_NULL;
0044 ret = deflateInit2(strm, state->level, Z_DEFLATED,
0045 MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
0046 if (ret != Z_OK) {
0047 free(state->out);
0048 free(state->in);
0049 gz_error(state, Z_MEM_ERROR, "out of memory");
0050 return -1;
0051 }
0052 strm->next_in = NULL;
0053 }
0054
0055
0056 state->size = state->want;
0057
0058
0059 if (!state->direct) {
0060 strm->avail_out = state->size;
0061 strm->next_out = state->out;
0062 state->x.next = strm->next_out;
0063 }
0064 return 0;
0065 }
0066
0067
0068
0069
0070
0071
0072
0073 local int gz_comp(state, flush)
0074 gz_statep state;
0075 int flush;
0076 {
0077 int ret, writ;
0078 unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
0079 z_streamp strm = &(state->strm);
0080
0081
0082 if (state->size == 0 && gz_init(state) == -1)
0083 return -1;
0084
0085
0086 if (state->direct) {
0087 while (strm->avail_in) {
0088 put = strm->avail_in > max ? max : strm->avail_in;
0089 writ = write(state->fd, strm->next_in, put);
0090 if (writ < 0) {
0091 gz_error(state, Z_ERRNO, zstrerror());
0092 return -1;
0093 }
0094 strm->avail_in -= (unsigned)writ;
0095 strm->next_in += writ;
0096 }
0097 return 0;
0098 }
0099
0100
0101 if (state->reset) {
0102
0103 if (strm->avail_in == 0)
0104 return 0;
0105 deflateReset(strm);
0106 state->reset = 0;
0107 }
0108
0109
0110 ret = Z_OK;
0111 do {
0112
0113
0114 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
0115 (flush != Z_FINISH || ret == Z_STREAM_END))) {
0116 while (strm->next_out > state->x.next) {
0117 put = strm->next_out - state->x.next > (int)max ? max :
0118 (unsigned)(strm->next_out - state->x.next);
0119 writ = write(state->fd, state->x.next, put);
0120 if (writ < 0) {
0121 gz_error(state, Z_ERRNO, zstrerror());
0122 return -1;
0123 }
0124 state->x.next += writ;
0125 }
0126 if (strm->avail_out == 0) {
0127 strm->avail_out = state->size;
0128 strm->next_out = state->out;
0129 state->x.next = state->out;
0130 }
0131 }
0132
0133
0134 have = strm->avail_out;
0135 ret = deflate(strm, flush);
0136 if (ret == Z_STREAM_ERROR) {
0137 gz_error(state, Z_STREAM_ERROR,
0138 "internal error: deflate stream corrupt");
0139 return -1;
0140 }
0141 have -= strm->avail_out;
0142 } while (have);
0143
0144
0145 if (flush == Z_FINISH)
0146 state->reset = 1;
0147
0148
0149 return 0;
0150 }
0151
0152
0153
0154 local int gz_zero(state, len)
0155 gz_statep state;
0156 z_off64_t len;
0157 {
0158 int first;
0159 unsigned n;
0160 z_streamp strm = &(state->strm);
0161
0162
0163 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
0164 return -1;
0165
0166
0167 first = 1;
0168 while (len) {
0169 n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
0170 (unsigned)len : state->size;
0171 if (first) {
0172 memset(state->in, 0, n);
0173 first = 0;
0174 }
0175 strm->avail_in = n;
0176 strm->next_in = state->in;
0177 state->x.pos += n;
0178 if (gz_comp(state, Z_NO_FLUSH) == -1)
0179 return -1;
0180 len -= n;
0181 }
0182 return 0;
0183 }
0184
0185
0186
0187 local z_size_t gz_write(state, buf, len)
0188 gz_statep state;
0189 voidpc buf;
0190 z_size_t len;
0191 {
0192 z_size_t put = len;
0193
0194
0195 if (len == 0)
0196 return 0;
0197
0198
0199 if (state->size == 0 && gz_init(state) == -1)
0200 return 0;
0201
0202
0203 if (state->seek) {
0204 state->seek = 0;
0205 if (gz_zero(state, state->skip) == -1)
0206 return 0;
0207 }
0208
0209
0210 if (len < state->size) {
0211
0212 do {
0213 unsigned have, copy;
0214
0215 if (state->strm.avail_in == 0)
0216 state->strm.next_in = state->in;
0217 have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
0218 state->in);
0219 copy = state->size - have;
0220 if (copy > len)
0221 copy = (unsigned)len;
0222 memcpy(state->in + have, buf, copy);
0223 state->strm.avail_in += copy;
0224 state->x.pos += copy;
0225 buf = (const char *)buf + copy;
0226 len -= copy;
0227 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
0228 return 0;
0229 } while (len);
0230 }
0231 else {
0232
0233 if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
0234 return 0;
0235
0236
0237 state->strm.next_in = (z_const Bytef *)buf;
0238 do {
0239 unsigned n = (unsigned)-1;
0240 if (n > len)
0241 n = (unsigned)len;
0242 state->strm.avail_in = n;
0243 state->x.pos += n;
0244 if (gz_comp(state, Z_NO_FLUSH) == -1)
0245 return 0;
0246 len -= n;
0247 } while (len);
0248 }
0249
0250
0251 return put;
0252 }
0253
0254
0255 int ZEXPORT gzwrite(file, buf, len)
0256 gzFile file;
0257 voidpc buf;
0258 unsigned len;
0259 {
0260 gz_statep state;
0261
0262
0263 if (file == NULL)
0264 return 0;
0265 state = (gz_statep)file;
0266
0267
0268 if (state->mode != GZ_WRITE || state->err != Z_OK)
0269 return 0;
0270
0271
0272
0273 if ((int)len < 0) {
0274 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
0275 return 0;
0276 }
0277
0278
0279 return (int)gz_write(state, buf, len);
0280 }
0281
0282
0283 z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
0284 voidpc buf;
0285 z_size_t size;
0286 z_size_t nitems;
0287 gzFile file;
0288 {
0289 z_size_t len;
0290 gz_statep state;
0291
0292
0293 if (file == NULL)
0294 return 0;
0295 state = (gz_statep)file;
0296
0297
0298 if (state->mode != GZ_WRITE || state->err != Z_OK)
0299 return 0;
0300
0301
0302 len = nitems * size;
0303 if (size && len / size != nitems) {
0304 gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
0305 return 0;
0306 }
0307
0308
0309 return len ? gz_write(state, buf, len) / size : 0;
0310 }
0311
0312
0313 int ZEXPORT gzputc(file, c)
0314 gzFile file;
0315 int c;
0316 {
0317 unsigned have;
0318 unsigned char buf[1];
0319 gz_statep state;
0320 z_streamp strm;
0321
0322
0323 if (file == NULL)
0324 return -1;
0325 state = (gz_statep)file;
0326 strm = &(state->strm);
0327
0328
0329 if (state->mode != GZ_WRITE || state->err != Z_OK)
0330 return -1;
0331
0332
0333 if (state->seek) {
0334 state->seek = 0;
0335 if (gz_zero(state, state->skip) == -1)
0336 return -1;
0337 }
0338
0339
0340
0341 if (state->size) {
0342 if (strm->avail_in == 0)
0343 strm->next_in = state->in;
0344 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
0345 if (have < state->size) {
0346 state->in[have] = (unsigned char)c;
0347 strm->avail_in++;
0348 state->x.pos++;
0349 return c & 0xff;
0350 }
0351 }
0352
0353
0354 buf[0] = (unsigned char)c;
0355 if (gz_write(state, buf, 1) != 1)
0356 return -1;
0357 return c & 0xff;
0358 }
0359
0360
0361 int ZEXPORT gzputs(file, s)
0362 gzFile file;
0363 const char *s;
0364 {
0365 z_size_t len, put;
0366 gz_statep state;
0367
0368
0369 if (file == NULL)
0370 return -1;
0371 state = (gz_statep)file;
0372
0373
0374 if (state->mode != GZ_WRITE || state->err != Z_OK)
0375 return -1;
0376
0377
0378 len = strlen(s);
0379 if ((int)len < 0 || (unsigned)len != len) {
0380 gz_error(state, Z_STREAM_ERROR, "string length does not fit in int");
0381 return -1;
0382 }
0383 put = gz_write(state, s, len);
0384 return put < len ? -1 : (int)len;
0385 }
0386
0387 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
0388 #include <stdarg.h>
0389
0390
0391 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
0392 {
0393 int len;
0394 unsigned left;
0395 char *next;
0396 gz_statep state;
0397 z_streamp strm;
0398
0399
0400 if (file == NULL)
0401 return Z_STREAM_ERROR;
0402 state = (gz_statep)file;
0403 strm = &(state->strm);
0404
0405
0406 if (state->mode != GZ_WRITE || state->err != Z_OK)
0407 return Z_STREAM_ERROR;
0408
0409
0410 if (state->size == 0 && gz_init(state) == -1)
0411 return state->err;
0412
0413
0414 if (state->seek) {
0415 state->seek = 0;
0416 if (gz_zero(state, state->skip) == -1)
0417 return state->err;
0418 }
0419
0420
0421
0422
0423 if (strm->avail_in == 0)
0424 strm->next_in = state->in;
0425 next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
0426 next[state->size - 1] = 0;
0427 #ifdef NO_vsnprintf
0428 # ifdef HAS_vsprintf_void
0429 (void)vsprintf(next, format, va);
0430 for (len = 0; len < state->size; len++)
0431 if (next[len] == 0) break;
0432 # else
0433 len = vsprintf(next, format, va);
0434 # endif
0435 #else
0436 # ifdef HAS_vsnprintf_void
0437 (void)vsnprintf(next, state->size, format, va);
0438 len = strlen(next);
0439 # else
0440 len = vsnprintf(next, state->size, format, va);
0441 # endif
0442 #endif
0443
0444
0445 if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
0446 return 0;
0447
0448
0449 strm->avail_in += (unsigned)len;
0450 state->x.pos += len;
0451 if (strm->avail_in >= state->size) {
0452 left = strm->avail_in - state->size;
0453 strm->avail_in = state->size;
0454 if (gz_comp(state, Z_NO_FLUSH) == -1)
0455 return state->err;
0456 memmove(state->in, state->in + state->size, left);
0457 strm->next_in = state->in;
0458 strm->avail_in = left;
0459 }
0460 return len;
0461 }
0462
0463 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
0464 {
0465 va_list va;
0466 int ret;
0467
0468 va_start(va, format);
0469 ret = gzvprintf(file, format, va);
0470 va_end(va);
0471 return ret;
0472 }
0473
0474 #else
0475
0476
0477 int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
0478 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
0479 gzFile file;
0480 const char *format;
0481 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
0482 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
0483 {
0484 unsigned len, left;
0485 char *next;
0486 gz_statep state;
0487 z_streamp strm;
0488
0489
0490 if (file == NULL)
0491 return Z_STREAM_ERROR;
0492 state = (gz_statep)file;
0493 strm = &(state->strm);
0494
0495
0496 if (sizeof(int) != sizeof(void *))
0497 return Z_STREAM_ERROR;
0498
0499
0500 if (state->mode != GZ_WRITE || state->err != Z_OK)
0501 return Z_STREAM_ERROR;
0502
0503
0504 if (state->size == 0 && gz_init(state) == -1)
0505 return state->error;
0506
0507
0508 if (state->seek) {
0509 state->seek = 0;
0510 if (gz_zero(state, state->skip) == -1)
0511 return state->error;
0512 }
0513
0514
0515
0516
0517 if (strm->avail_in == 0)
0518 strm->next_in = state->in;
0519 next = (char *)(strm->next_in + strm->avail_in);
0520 next[state->size - 1] = 0;
0521 #ifdef NO_snprintf
0522 # ifdef HAS_sprintf_void
0523 sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
0524 a13, a14, a15, a16, a17, a18, a19, a20);
0525 for (len = 0; len < size; len++)
0526 if (next[len] == 0)
0527 break;
0528 # else
0529 len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
0530 a12, a13, a14, a15, a16, a17, a18, a19, a20);
0531 # endif
0532 #else
0533 # ifdef HAS_snprintf_void
0534 snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
0535 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
0536 len = strlen(next);
0537 # else
0538 len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
0539 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
0540 # endif
0541 #endif
0542
0543
0544 if (len == 0 || len >= state->size || next[state->size - 1] != 0)
0545 return 0;
0546
0547
0548 strm->avail_in += len;
0549 state->x.pos += len;
0550 if (strm->avail_in >= state->size) {
0551 left = strm->avail_in - state->size;
0552 strm->avail_in = state->size;
0553 if (gz_comp(state, Z_NO_FLUSH) == -1)
0554 return state->err;
0555 memmove(state->in, state->in + state->size, left);
0556 strm->next_in = state->in;
0557 strm->avail_in = left;
0558 }
0559 return (int)len;
0560 }
0561
0562 #endif
0563
0564
0565 int ZEXPORT gzflush(file, flush)
0566 gzFile file;
0567 int flush;
0568 {
0569 gz_statep state;
0570
0571
0572 if (file == NULL)
0573 return Z_STREAM_ERROR;
0574 state = (gz_statep)file;
0575
0576
0577 if (state->mode != GZ_WRITE || state->err != Z_OK)
0578 return Z_STREAM_ERROR;
0579
0580
0581 if (flush < 0 || flush > Z_FINISH)
0582 return Z_STREAM_ERROR;
0583
0584
0585 if (state->seek) {
0586 state->seek = 0;
0587 if (gz_zero(state, state->skip) == -1)
0588 return state->err;
0589 }
0590
0591
0592 (void)gz_comp(state, flush);
0593 return state->err;
0594 }
0595
0596
0597 int ZEXPORT gzsetparams(file, level, strategy)
0598 gzFile file;
0599 int level;
0600 int strategy;
0601 {
0602 gz_statep state;
0603 z_streamp strm;
0604
0605
0606 if (file == NULL)
0607 return Z_STREAM_ERROR;
0608 state = (gz_statep)file;
0609 strm = &(state->strm);
0610
0611
0612 if (state->mode != GZ_WRITE || state->err != Z_OK)
0613 return Z_STREAM_ERROR;
0614
0615
0616 if (level == state->level && strategy == state->strategy)
0617 return Z_OK;
0618
0619
0620 if (state->seek) {
0621 state->seek = 0;
0622 if (gz_zero(state, state->skip) == -1)
0623 return state->err;
0624 }
0625
0626
0627 if (state->size) {
0628
0629 if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
0630 return state->err;
0631 deflateParams(strm, level, strategy);
0632 }
0633 state->level = level;
0634 state->strategy = strategy;
0635 return Z_OK;
0636 }
0637
0638
0639 int ZEXPORT gzclose_w(file)
0640 gzFile file;
0641 {
0642 int ret = Z_OK;
0643 gz_statep state;
0644
0645
0646 if (file == NULL)
0647 return Z_STREAM_ERROR;
0648 state = (gz_statep)file;
0649
0650
0651 if (state->mode != GZ_WRITE)
0652 return Z_STREAM_ERROR;
0653
0654
0655 if (state->seek) {
0656 state->seek = 0;
0657 if (gz_zero(state, state->skip) == -1)
0658 ret = state->err;
0659 }
0660
0661
0662 if (gz_comp(state, Z_FINISH) == -1)
0663 ret = state->err;
0664 if (state->size) {
0665 if (!state->direct) {
0666 (void)deflateEnd(&(state->strm));
0667 free(state->out);
0668 }
0669 free(state->in);
0670 }
0671 gz_error(state, Z_OK, NULL);
0672 free(state->path);
0673 if (close(state->fd) == -1)
0674 ret = Z_ERRNO;
0675 free(state);
0676 return ret;
0677 }