Annotation of embedaddon/sudo/zlib/gzwrite.c, revision 1.1.1.1

1.1       misho       1: /* gzwrite.c -- zlib functions for writing gzip files
                      2:  * Copyright (C) 2004, 2005, 2010 Mark Adler
                      3:  * For conditions of distribution and use, see copyright notice in zlib.h
                      4:  */
                      5: 
                      6: #include "gzguts.h"
                      7: 
                      8: /* Local functions */
                      9: local int gz_init OF((gz_statep));
                     10: local int gz_comp OF((gz_statep, int));
                     11: local int gz_zero OF((gz_statep, z_off64_t));
                     12: 
                     13: /* Initialize state for writing a gzip file.  Mark initialization by setting
                     14:    state->size to non-zero.  Return -1 on failure or 0 on success. */
                     15: local int gz_init(state)
                     16:     gz_statep state;
                     17: {
                     18:     int ret;
                     19:     z_streamp strm = &(state->strm);
                     20: 
                     21:     /* allocate input and output buffers */
                     22:     state->in = malloc(state->want);
                     23:     state->out = malloc(state->want);
                     24:     if (state->in == NULL || state->out == NULL) {
                     25:         if (state->out != NULL)
                     26:             free(state->out);
                     27:         if (state->in != NULL)
                     28:             free(state->in);
                     29:         gz_error(state, Z_MEM_ERROR, "out of memory");
                     30:         return -1;
                     31:     }
                     32: 
                     33:     /* allocate deflate memory, set up for gzip compression */
                     34:     strm->zalloc = Z_NULL;
                     35:     strm->zfree = Z_NULL;
                     36:     strm->opaque = Z_NULL;
                     37:     ret = deflateInit2(strm, state->level, Z_DEFLATED,
                     38:                        15 + 16, 8, state->strategy);
                     39:     if (ret != Z_OK) {
                     40:         free(state->in);
                     41:         gz_error(state, Z_MEM_ERROR, "out of memory");
                     42:         return -1;
                     43:     }
                     44: 
                     45:     /* mark state as initialized */
                     46:     state->size = state->want;
                     47: 
                     48:     /* initialize write buffer */
                     49:     strm->avail_out = state->size;
                     50:     strm->next_out = state->out;
                     51:     state->next = strm->next_out;
                     52:     return 0;
                     53: }
                     54: 
                     55: /* Compress whatever is at avail_in and next_in and write to the output file.
                     56:    Return -1 if there is an error writing to the output file, otherwise 0.
                     57:    flush is assumed to be a valid deflate() flush value.  If flush is Z_FINISH,
                     58:    then the deflate() state is reset to start a new gzip stream. */
                     59: local int gz_comp(state, flush)
                     60:     gz_statep state;
                     61:     int flush;
                     62: {
                     63:     int ret, got;
                     64:     unsigned have;
                     65:     z_streamp strm = &(state->strm);
                     66: 
                     67:     /* allocate memory if this is the first time through */
                     68:     if (state->size == 0 && gz_init(state) == -1)
                     69:         return -1;
                     70: 
                     71:     /* run deflate() on provided input until it produces no more output */
                     72:     ret = Z_OK;
                     73:     do {
                     74:         /* write out current buffer contents if full, or if flushing, but if
                     75:            doing Z_FINISH then don't write until we get to Z_STREAM_END */
                     76:         if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
                     77:             (flush != Z_FINISH || ret == Z_STREAM_END))) {
                     78:             have = (unsigned)(strm->next_out - state->next);
                     79:             if (have && ((got = write(state->fd, state->next, have)) < 0 ||
                     80:                          (unsigned)got != have)) {
                     81:                 gz_error(state, Z_ERRNO, zstrerror());
                     82:                 return -1;
                     83:             }
                     84:             if (strm->avail_out == 0) {
                     85:                 strm->avail_out = state->size;
                     86:                 strm->next_out = state->out;
                     87:             }
                     88:             state->next = strm->next_out;
                     89:         }
                     90: 
                     91:         /* compress */
                     92:         have = strm->avail_out;
                     93:         ret = deflate(strm, flush);
                     94:         if (ret == Z_STREAM_ERROR) {
                     95:             gz_error(state, Z_STREAM_ERROR,
                     96:                       "internal error: deflate stream corrupt");
                     97:             return -1;
                     98:         }
                     99:         have -= strm->avail_out;
                    100:     } while (have);
                    101: 
                    102:     /* if that completed a deflate stream, allow another to start */
                    103:     if (flush == Z_FINISH)
                    104:         deflateReset(strm);
                    105: 
                    106:     /* all done, no errors */
                    107:     return 0;
                    108: }
                    109: 
                    110: /* Compress len zeros to output.  Return -1 on error, 0 on success. */
                    111: local int gz_zero(state, len)
                    112:     gz_statep state;
                    113:     z_off64_t len;
                    114: {
                    115:     int first;
                    116:     unsigned n;
                    117:     z_streamp strm = &(state->strm);
                    118: 
                    119:     /* consume whatever's left in the input buffer */
                    120:     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
                    121:         return -1;
                    122: 
                    123:     /* compress len zeros (len guaranteed > 0) */
                    124:     first = 1;
                    125:     while (len) {
                    126:         n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
                    127:             (unsigned)len : state->size;
                    128:         if (first) {
                    129:             memset(state->in, 0, n);
                    130:             first = 0;
                    131:         }
                    132:         strm->avail_in = n;
                    133:         strm->next_in = state->in;
                    134:         state->pos += n;
                    135:         if (gz_comp(state, Z_NO_FLUSH) == -1)
                    136:             return -1;
                    137:         len -= n;
                    138:     }
                    139:     return 0;
                    140: }
                    141: 
                    142: /* -- see zlib.h -- */
                    143: int ZEXPORT gzwrite(file, buf, len)
                    144:     gzFile file;
                    145:     voidpc buf;
                    146:     unsigned len;
                    147: {
                    148:     unsigned put = len;
                    149:     unsigned n;
                    150:     gz_statep state;
                    151:     z_streamp strm;
                    152: 
                    153:     /* get internal structure */
                    154:     if (file == NULL)
                    155:         return 0;
                    156:     state = (gz_statep)file;
                    157:     strm = &(state->strm);
                    158: 
                    159:     /* check that we're writing and that there's no error */
                    160:     if (state->mode != GZ_WRITE || state->err != Z_OK)
                    161:         return 0;
                    162: 
                    163:     /* since an int is returned, make sure len fits in one, otherwise return
                    164:        with an error (this avoids the flaw in the interface) */
                    165:     if ((int)len < 0) {
                    166:         gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
                    167:         return 0;
                    168:     }
                    169: 
                    170:     /* if len is zero, avoid unnecessary operations */
                    171:     if (len == 0)
                    172:         return 0;
                    173: 
                    174:     /* allocate memory if this is the first time through */
                    175:     if (state->size == 0 && gz_init(state) == -1)
                    176:         return 0;
                    177: 
                    178:     /* check for seek request */
                    179:     if (state->seek) {
                    180:         state->seek = 0;
                    181:         if (gz_zero(state, state->skip) == -1)
                    182:             return 0;
                    183:     }
                    184: 
                    185:     /* for small len, copy to input buffer, otherwise compress directly */
                    186:     if (len < state->size) {
                    187:         /* copy to input buffer, compress when full */
                    188:         do {
                    189:             if (strm->avail_in == 0)
                    190:                 strm->next_in = state->in;
                    191:             n = state->size - strm->avail_in;
                    192:             if (n > len)
                    193:                 n = len;
                    194:             memcpy(strm->next_in + strm->avail_in, buf, n);
                    195:             strm->avail_in += n;
                    196:             state->pos += n;
                    197:             buf = (char *)buf + n;
                    198:             len -= n;
                    199:             if (len && gz_comp(state, Z_NO_FLUSH) == -1)
                    200:                 return 0;
                    201:         } while (len);
                    202:     }
                    203:     else {
                    204:         /* consume whatever's left in the input buffer */
                    205:         if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
                    206:             return 0;
                    207: 
                    208:         /* directly compress user buffer to file */
                    209:         strm->avail_in = len;
                    210:         strm->next_in = (voidp)buf;
                    211:         state->pos += len;
                    212:         if (gz_comp(state, Z_NO_FLUSH) == -1)
                    213:             return 0;
                    214:     }
                    215: 
                    216:     /* input was all buffered or compressed (put will fit in int) */
                    217:     return (int)put;
                    218: }
                    219: 
                    220: /* -- see zlib.h -- */
                    221: int ZEXPORT gzputc(file, c)
                    222:     gzFile file;
                    223:     int c;
                    224: {
                    225:     unsigned char buf[1];
                    226:     gz_statep state;
                    227:     z_streamp strm;
                    228: 
                    229:     /* get internal structure */
                    230:     if (file == NULL)
                    231:         return -1;
                    232:     state = (gz_statep)file;
                    233:     strm = &(state->strm);
                    234: 
                    235:     /* check that we're writing and that there's no error */
                    236:     if (state->mode != GZ_WRITE || state->err != Z_OK)
                    237:         return -1;
                    238: 
                    239:     /* check for seek request */
                    240:     if (state->seek) {
                    241:         state->seek = 0;
                    242:         if (gz_zero(state, state->skip) == -1)
                    243:             return -1;
                    244:     }
                    245: 
                    246:     /* try writing to input buffer for speed (state->size == 0 if buffer not
                    247:        initialized) */
                    248:     if (strm->avail_in < state->size) {
                    249:         if (strm->avail_in == 0)
                    250:             strm->next_in = state->in;
                    251:         strm->next_in[strm->avail_in++] = c;
                    252:         state->pos++;
                    253:         return c;
                    254:     }
                    255: 
                    256:     /* no room in buffer or not initialized, use gz_write() */
                    257:     buf[0] = c;
                    258:     if (gzwrite(file, buf, 1) != 1)
                    259:         return -1;
                    260:     return c;
                    261: }
                    262: 
                    263: /* -- see zlib.h -- */
                    264: int ZEXPORT gzputs(file, str)
                    265:     gzFile file;
                    266:     const char *str;
                    267: {
                    268:     int ret;
                    269:     unsigned len;
                    270: 
                    271:     /* write string */
                    272:     len = (unsigned)strlen(str);
                    273:     ret = gzwrite(file, str, len);
                    274:     return ret == 0 && len != 0 ? -1 : ret;
                    275: }
                    276: 
                    277: #ifdef STDC
                    278: #include <stdarg.h>
                    279: 
                    280: /* -- see zlib.h -- */
                    281: int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
                    282: {
                    283:     int size, len;
                    284:     gz_statep state;
                    285:     z_streamp strm;
                    286:     va_list va;
                    287: 
                    288:     /* get internal structure */
                    289:     if (file == NULL)
                    290:         return -1;
                    291:     state = (gz_statep)file;
                    292:     strm = &(state->strm);
                    293: 
                    294:     /* check that we're writing and that there's no error */
                    295:     if (state->mode != GZ_WRITE || state->err != Z_OK)
                    296:         return 0;
                    297: 
                    298:     /* make sure we have some buffer space */
                    299:     if (state->size == 0 && gz_init(state) == -1)
                    300:         return 0;
                    301: 
                    302:     /* check for seek request */
                    303:     if (state->seek) {
                    304:         state->seek = 0;
                    305:         if (gz_zero(state, state->skip) == -1)
                    306:             return 0;
                    307:     }
                    308: 
                    309:     /* consume whatever's left in the input buffer */
                    310:     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
                    311:         return 0;
                    312: 
                    313:     /* do the printf() into the input buffer, put length in len */
                    314:     size = (int)(state->size);
                    315:     state->in[size - 1] = 0;
                    316:     va_start(va, format);
                    317: #ifdef NO_vsnprintf
                    318: #  ifdef HAS_vsprintf_void
                    319:     (void)vsprintf(state->in, format, va);
                    320:     va_end(va);
                    321:     for (len = 0; len < size; len++)
                    322:         if (state->in[len] == 0) break;
                    323: #  else
                    324:     len = vsprintf(state->in, format, va);
                    325:     va_end(va);
                    326: #  endif
                    327: #else
                    328: #  ifdef HAS_vsnprintf_void
                    329:     (void)vsnprintf(state->in, size, format, va);
                    330:     va_end(va);
                    331:     len = strlen(state->in);
                    332: #  else
                    333:     len = vsnprintf((char *)(state->in), size, format, va);
                    334:     va_end(va);
                    335: #  endif
                    336: #endif
                    337: 
                    338:     /* check that printf() results fit in buffer */
                    339:     if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
                    340:         return 0;
                    341: 
                    342:     /* update buffer and position, defer compression until needed */
                    343:     strm->avail_in = (unsigned)len;
                    344:     strm->next_in = state->in;
                    345:     state->pos += len;
                    346:     return len;
                    347: }
                    348: 
                    349: #else /* !STDC */
                    350: 
                    351: /* -- see zlib.h -- */
                    352: int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
                    353:                        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
                    354:     gzFile file;
                    355:     const char *format;
                    356:     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
                    357:         a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
                    358: {
                    359:     int size, len;
                    360:     gz_statep state;
                    361:     z_streamp strm;
                    362: 
                    363:     /* get internal structure */
                    364:     if (file == NULL)
                    365:         return -1;
                    366:     state = (gz_statep)file;
                    367:     strm = &(state->strm);
                    368: 
                    369:     /* check that we're writing and that there's no error */
                    370:     if (state->mode != GZ_WRITE || state->err != Z_OK)
                    371:         return 0;
                    372: 
                    373:     /* make sure we have some buffer space */
                    374:     if (state->size == 0 && gz_init(state) == -1)
                    375:         return 0;
                    376: 
                    377:     /* check for seek request */
                    378:     if (state->seek) {
                    379:         state->seek = 0;
                    380:         if (gz_zero(state, state->skip) == -1)
                    381:             return 0;
                    382:     }
                    383: 
                    384:     /* consume whatever's left in the input buffer */
                    385:     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
                    386:         return 0;
                    387: 
                    388:     /* do the printf() into the input buffer, put length in len */
                    389:     size = (int)(state->size);
                    390:     state->in[size - 1] = 0;
                    391: #ifdef NO_snprintf
                    392: #  ifdef HAS_sprintf_void
                    393:     sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
                    394:             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
                    395:     for (len = 0; len < size; len++)
                    396:         if (state->in[len] == 0) break;
                    397: #  else
                    398:     len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
                    399:                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
                    400: #  endif
                    401: #else
                    402: #  ifdef HAS_snprintf_void
                    403:     snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
                    404:              a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
                    405:     len = strlen(state->in);
                    406: #  else
                    407:     len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
                    408:                  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
                    409: #  endif
                    410: #endif
                    411: 
                    412:     /* check that printf() results fit in buffer */
                    413:     if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
                    414:         return 0;
                    415: 
                    416:     /* update buffer and position, defer compression until needed */
                    417:     strm->avail_in = (unsigned)len;
                    418:     strm->next_in = state->in;
                    419:     state->pos += len;
                    420:     return len;
                    421: }
                    422: 
                    423: #endif
                    424: 
                    425: /* -- see zlib.h -- */
                    426: int ZEXPORT gzflush(file, flush)
                    427:     gzFile file;
                    428:     int flush;
                    429: {
                    430:     gz_statep state;
                    431: 
                    432:     /* get internal structure */
                    433:     if (file == NULL)
                    434:         return -1;
                    435:     state = (gz_statep)file;
                    436: 
                    437:     /* check that we're writing and that there's no error */
                    438:     if (state->mode != GZ_WRITE || state->err != Z_OK)
                    439:         return Z_STREAM_ERROR;
                    440: 
                    441:     /* check flush parameter */
                    442:     if (flush < 0 || flush > Z_FINISH)
                    443:         return Z_STREAM_ERROR;
                    444: 
                    445:     /* check for seek request */
                    446:     if (state->seek) {
                    447:         state->seek = 0;
                    448:         if (gz_zero(state, state->skip) == -1)
                    449:             return -1;
                    450:     }
                    451: 
                    452:     /* compress remaining data with requested flush */
                    453:     gz_comp(state, flush);
                    454:     return state->err;
                    455: }
                    456: 
                    457: /* -- see zlib.h -- */
                    458: int ZEXPORT gzsetparams(file, level, strategy)
                    459:     gzFile file;
                    460:     int level;
                    461:     int strategy;
                    462: {
                    463:     gz_statep state;
                    464:     z_streamp strm;
                    465: 
                    466:     /* get internal structure */
                    467:     if (file == NULL)
                    468:         return Z_STREAM_ERROR;
                    469:     state = (gz_statep)file;
                    470:     strm = &(state->strm);
                    471: 
                    472:     /* check that we're writing and that there's no error */
                    473:     if (state->mode != GZ_WRITE || state->err != Z_OK)
                    474:         return Z_STREAM_ERROR;
                    475: 
                    476:     /* if no change is requested, then do nothing */
                    477:     if (level == state->level && strategy == state->strategy)
                    478:         return Z_OK;
                    479: 
                    480:     /* check for seek request */
                    481:     if (state->seek) {
                    482:         state->seek = 0;
                    483:         if (gz_zero(state, state->skip) == -1)
                    484:             return -1;
                    485:     }
                    486: 
                    487:     /* change compression parameters for subsequent input */
                    488:     if (state->size) {
                    489:         /* flush previous input with previous parameters before changing */
                    490:         if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
                    491:             return state->err;
                    492:         deflateParams(strm, level, strategy);
                    493:     }
                    494:     state->level = level;
                    495:     state->strategy = strategy;
                    496:     return Z_OK;
                    497: }
                    498: 
                    499: /* -- see zlib.h -- */
                    500: int ZEXPORT gzclose_w(file)
                    501:     gzFile file;
                    502: {
                    503:     int ret = 0;
                    504:     gz_statep state;
                    505: 
                    506:     /* get internal structure */
                    507:     if (file == NULL)
                    508:         return Z_STREAM_ERROR;
                    509:     state = (gz_statep)file;
                    510: 
                    511:     /* check that we're writing */
                    512:     if (state->mode != GZ_WRITE)
                    513:         return Z_STREAM_ERROR;
                    514: 
                    515:     /* check for seek request */
                    516:     if (state->seek) {
                    517:         state->seek = 0;
                    518:         ret += gz_zero(state, state->skip);
                    519:     }
                    520: 
                    521:     /* flush, free memory, and close file */
                    522:     ret += gz_comp(state, Z_FINISH);
                    523:     (void)deflateEnd(&(state->strm));
                    524:     free(state->out);
                    525:     free(state->in);
                    526:     gz_error(state, Z_OK, NULL);
                    527:     free(state->path);
                    528:     ret += close(state->fd);
                    529:     free(state);
                    530:     return ret ? Z_ERRNO : Z_OK;
                    531: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>