Annotation of embedaddon/sudo/zlib/gzwrite.c, revision 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>