1c3423655Schristos /* gzwrite.c -- zlib functions for writing gzip files 23b1253e8Schristos * Copyright (C) 2004-2019 Mark Adler 3c3423655Schristos * For conditions of distribution and use, see copyright notice in zlib.h 4c3423655Schristos */ 5c3423655Schristos 6c3423655Schristos #include "gzguts.h" 7c3423655Schristos 8c3423655Schristos /* Initialize state for writing a gzip file. Mark initialization by setting 9c3423655Schristos state->size to non-zero. Return -1 on a memory allocation failure, or 0 on 10c3423655Schristos success. */ 11*96c32821Schristos local int gz_init(gz_statep state) { 12c3423655Schristos int ret; 13c3423655Schristos z_streamp strm = &(state->strm); 14c3423655Schristos 15c3423655Schristos /* allocate input buffer (double size for gzprintf) */ 16c3423655Schristos state->in = (unsigned char *)malloc(state->want << 1); 17c3423655Schristos if (state->in == NULL) { 18c3423655Schristos gz_error(state, Z_MEM_ERROR, "out of memory"); 19c3423655Schristos return -1; 20c3423655Schristos } 21c3423655Schristos 22c3423655Schristos /* only need output buffer and deflate state if compressing */ 23c3423655Schristos if (!state->direct) { 24c3423655Schristos /* allocate output buffer */ 25c3423655Schristos state->out = (unsigned char *)malloc(state->want); 26c3423655Schristos if (state->out == NULL) { 27c3423655Schristos free(state->in); 28c3423655Schristos gz_error(state, Z_MEM_ERROR, "out of memory"); 29c3423655Schristos return -1; 30c3423655Schristos } 31c3423655Schristos 32c3423655Schristos /* allocate deflate memory, set up for gzip compression */ 33c3423655Schristos strm->zalloc = Z_NULL; 34c3423655Schristos strm->zfree = Z_NULL; 35c3423655Schristos strm->opaque = Z_NULL; 36c3423655Schristos ret = deflateInit2(strm, state->level, Z_DEFLATED, 37c3423655Schristos MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); 38c3423655Schristos if (ret != Z_OK) { 39c3423655Schristos free(state->out); 40c3423655Schristos free(state->in); 41c3423655Schristos gz_error(state, Z_MEM_ERROR, "out of memory"); 42c3423655Schristos return -1; 43c3423655Schristos } 44c3423655Schristos strm->next_in = NULL; 45c3423655Schristos } 46c3423655Schristos 47c3423655Schristos /* mark state as initialized */ 48c3423655Schristos state->size = state->want; 49c3423655Schristos 50c3423655Schristos /* initialize write buffer if compressing */ 51c3423655Schristos if (!state->direct) { 52c3423655Schristos strm->avail_out = state->size; 53c3423655Schristos strm->next_out = state->out; 54c3423655Schristos state->x.next = strm->next_out; 55c3423655Schristos } 56c3423655Schristos return 0; 57c3423655Schristos } 58c3423655Schristos 59c3423655Schristos /* Compress whatever is at avail_in and next_in and write to the output file. 60c3423655Schristos Return -1 if there is an error writing to the output file or if gz_init() 61c3423655Schristos fails to allocate memory, otherwise 0. flush is assumed to be a valid 62c3423655Schristos deflate() flush value. If flush is Z_FINISH, then the deflate() state is 63c3423655Schristos reset to start a new gzip stream. If gz->direct is true, then simply write 64c3423655Schristos to the output file without compressing, and ignore flush. */ 65*96c32821Schristos local int gz_comp(gz_statep state, int flush) { 666db8c6e9Schristos int ret; 676db8c6e9Schristos ssize_t writ; 686db8c6e9Schristos size_t put; 696db8c6e9Schristos unsigned have, max = ((unsigned)-1 >> 2) + 1; 70c3423655Schristos z_streamp strm = &(state->strm); 71c3423655Schristos 72c3423655Schristos /* allocate memory if this is the first time through */ 73c3423655Schristos if (state->size == 0 && gz_init(state) == -1) 74c3423655Schristos return -1; 75c3423655Schristos 76c3423655Schristos /* write directly if requested */ 77c3423655Schristos if (state->direct) { 78c3423655Schristos while (strm->avail_in) { 79c3423655Schristos put = strm->avail_in > max ? max : strm->avail_in; 80c3423655Schristos writ = write(state->fd, strm->next_in, put); 81c3423655Schristos if (writ < 0) { 82c3423655Schristos gz_error(state, Z_ERRNO, zstrerror()); 83c3423655Schristos return -1; 84c3423655Schristos } 85c3423655Schristos strm->avail_in -= (unsigned)writ; 86c3423655Schristos strm->next_in += writ; 87c3423655Schristos } 88c3423655Schristos return 0; 89c3423655Schristos } 90c3423655Schristos 913b1253e8Schristos /* check for a pending reset */ 923b1253e8Schristos if (state->reset) { 933b1253e8Schristos /* don't start a new gzip member unless there is data to write */ 943b1253e8Schristos if (strm->avail_in == 0) 953b1253e8Schristos return 0; 963b1253e8Schristos deflateReset(strm); 973b1253e8Schristos state->reset = 0; 983b1253e8Schristos } 993b1253e8Schristos 100c3423655Schristos /* run deflate() on provided input until it produces no more output */ 101c3423655Schristos ret = Z_OK; 102c3423655Schristos do { 103c3423655Schristos /* write out current buffer contents if full, or if flushing, but if 104c3423655Schristos doing Z_FINISH then don't write until we get to Z_STREAM_END */ 105c3423655Schristos if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && 106c3423655Schristos (flush != Z_FINISH || ret == Z_STREAM_END))) { 107c3423655Schristos while (strm->next_out > state->x.next) { 108c3423655Schristos put = strm->next_out - state->x.next > (int)max ? max : 109c3423655Schristos (unsigned)(strm->next_out - state->x.next); 110c3423655Schristos writ = write(state->fd, state->x.next, put); 111c3423655Schristos if (writ < 0) { 112c3423655Schristos gz_error(state, Z_ERRNO, zstrerror()); 113c3423655Schristos return -1; 114c3423655Schristos } 115c3423655Schristos state->x.next += writ; 116c3423655Schristos } 117c3423655Schristos if (strm->avail_out == 0) { 118c3423655Schristos strm->avail_out = state->size; 119c3423655Schristos strm->next_out = state->out; 120c3423655Schristos state->x.next = state->out; 121c3423655Schristos } 122c3423655Schristos } 123c3423655Schristos 124c3423655Schristos /* compress */ 125c3423655Schristos have = strm->avail_out; 126c3423655Schristos ret = deflate(strm, flush); 127c3423655Schristos if (ret == Z_STREAM_ERROR) { 128c3423655Schristos gz_error(state, Z_STREAM_ERROR, 129c3423655Schristos "internal error: deflate stream corrupt"); 130c3423655Schristos return -1; 131c3423655Schristos } 132c3423655Schristos have -= strm->avail_out; 133c3423655Schristos } while (have); 134c3423655Schristos 135c3423655Schristos /* if that completed a deflate stream, allow another to start */ 136c3423655Schristos if (flush == Z_FINISH) 1373b1253e8Schristos state->reset = 1; 138c3423655Schristos 139c3423655Schristos /* all done, no errors */ 140c3423655Schristos return 0; 141c3423655Schristos } 142c3423655Schristos 143c3423655Schristos /* Compress len zeros to output. Return -1 on a write error or memory 144c3423655Schristos allocation failure by gz_comp(), or 0 on success. */ 145*96c32821Schristos local int gz_zero(gz_statep state, z_off64_t len) { 146c3423655Schristos int first; 147c3423655Schristos unsigned n; 148c3423655Schristos z_streamp strm = &(state->strm); 149c3423655Schristos 150c3423655Schristos /* consume whatever's left in the input buffer */ 151c3423655Schristos if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 152c3423655Schristos return -1; 153c3423655Schristos 154c3423655Schristos /* compress len zeros (len guaranteed > 0) */ 155c3423655Schristos first = 1; 156c3423655Schristos while (len) { 157c3423655Schristos n = GT_OFF(state->size) || (z_off64_t)state->size > len ? 158c3423655Schristos (unsigned)len : state->size; 159c3423655Schristos if (first) { 160c3423655Schristos memset(state->in, 0, n); 161c3423655Schristos first = 0; 162c3423655Schristos } 163c3423655Schristos strm->avail_in = n; 164c3423655Schristos strm->next_in = state->in; 165c3423655Schristos state->x.pos += n; 166c3423655Schristos if (gz_comp(state, Z_NO_FLUSH) == -1) 167c3423655Schristos return -1; 168c3423655Schristos len -= n; 169c3423655Schristos } 170c3423655Schristos return 0; 171c3423655Schristos } 172c3423655Schristos 173c3423655Schristos /* Write len bytes from buf to file. Return the number of bytes written. If 174c3423655Schristos the returned value is less than len, then there was an error. */ 175*96c32821Schristos local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { 176c3423655Schristos z_size_t put = len; 177c3423655Schristos 178c3423655Schristos /* if len is zero, avoid unnecessary operations */ 179c3423655Schristos if (len == 0) 180c3423655Schristos return 0; 181c3423655Schristos 182c3423655Schristos /* allocate memory if this is the first time through */ 183c3423655Schristos if (state->size == 0 && gz_init(state) == -1) 184c3423655Schristos return 0; 185c3423655Schristos 186c3423655Schristos /* check for seek request */ 187c3423655Schristos if (state->seek) { 188c3423655Schristos state->seek = 0; 189c3423655Schristos if (gz_zero(state, state->skip) == -1) 190c3423655Schristos return 0; 191c3423655Schristos } 192c3423655Schristos 193c3423655Schristos /* for small len, copy to input buffer, otherwise compress directly */ 194c3423655Schristos if (len < state->size) { 195c3423655Schristos /* copy to input buffer, compress when full */ 196c3423655Schristos do { 197c3423655Schristos unsigned have, copy; 198c3423655Schristos 199c3423655Schristos if (state->strm.avail_in == 0) 200c3423655Schristos state->strm.next_in = state->in; 201c3423655Schristos have = (unsigned)((state->strm.next_in + state->strm.avail_in) - 202c3423655Schristos state->in); 203c3423655Schristos copy = state->size - have; 204c3423655Schristos if (copy > len) 2053b1253e8Schristos copy = (unsigned)len; 206c3423655Schristos memcpy(state->in + have, buf, copy); 207c3423655Schristos state->strm.avail_in += copy; 208c3423655Schristos state->x.pos += copy; 209c3423655Schristos buf = (const char *)buf + copy; 210c3423655Schristos len -= copy; 211c3423655Schristos if (len && gz_comp(state, Z_NO_FLUSH) == -1) 212c3423655Schristos return 0; 213c3423655Schristos } while (len); 214c3423655Schristos } 215c3423655Schristos else { 216c3423655Schristos /* consume whatever's left in the input buffer */ 217c3423655Schristos if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 218c3423655Schristos return 0; 219c3423655Schristos 220c3423655Schristos /* directly compress user buffer to file */ 2216db8c6e9Schristos state->strm.next_in = __UNCONST(buf); 222c3423655Schristos do { 223c3423655Schristos unsigned n = (unsigned)-1; 224c3423655Schristos if (n > len) 2253b1253e8Schristos n = (unsigned)len; 226c3423655Schristos state->strm.avail_in = n; 227c3423655Schristos state->x.pos += n; 228c3423655Schristos if (gz_comp(state, Z_NO_FLUSH) == -1) 229c3423655Schristos return 0; 230c3423655Schristos len -= n; 231c3423655Schristos } while (len); 232c3423655Schristos } 233c3423655Schristos 234c3423655Schristos /* input was all buffered or compressed */ 235c3423655Schristos return put; 236c3423655Schristos } 237c3423655Schristos 238c3423655Schristos /* -- see zlib.h -- */ 239*96c32821Schristos int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { 240c3423655Schristos gz_statep state; 241c3423655Schristos 242c3423655Schristos /* get internal structure */ 243c3423655Schristos if (file == NULL) 244c3423655Schristos return 0; 245c3423655Schristos state = (gz_statep)file; 246c3423655Schristos 247c3423655Schristos /* check that we're writing and that there's no error */ 248c3423655Schristos if (state->mode != GZ_WRITE || state->err != Z_OK) 249c3423655Schristos return 0; 250c3423655Schristos 251c3423655Schristos /* since an int is returned, make sure len fits in one, otherwise return 252c3423655Schristos with an error (this avoids a flaw in the interface) */ 253c3423655Schristos if ((int)len < 0) { 254c3423655Schristos gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); 255c3423655Schristos return 0; 256c3423655Schristos } 257c3423655Schristos 258c3423655Schristos /* write len bytes from buf (the return value will fit in an int) */ 259c3423655Schristos return (int)gz_write(state, buf, len); 260c3423655Schristos } 261c3423655Schristos 262c3423655Schristos /* -- see zlib.h -- */ 263*96c32821Schristos z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, 264*96c32821Schristos gzFile file) { 265c3423655Schristos z_size_t len; 266c3423655Schristos gz_statep state; 267c3423655Schristos 268c3423655Schristos /* get internal structure */ 269c3423655Schristos if (file == NULL) 270c3423655Schristos return 0; 271c3423655Schristos state = (gz_statep)file; 272c3423655Schristos 273c3423655Schristos /* check that we're writing and that there's no error */ 274c3423655Schristos if (state->mode != GZ_WRITE || state->err != Z_OK) 275c3423655Schristos return 0; 276c3423655Schristos 277c3423655Schristos /* compute bytes to read -- error on overflow */ 278c3423655Schristos len = nitems * size; 279c3423655Schristos if (size && len / size != nitems) { 280c3423655Schristos gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); 281c3423655Schristos return 0; 282c3423655Schristos } 283c3423655Schristos 284c3423655Schristos /* write len bytes to buf, return the number of full items written */ 285c3423655Schristos return len ? gz_write(state, buf, len) / size : 0; 286c3423655Schristos } 287c3423655Schristos 288c3423655Schristos /* -- see zlib.h -- */ 289*96c32821Schristos int ZEXPORT gzputc(gzFile file, int c) { 290c3423655Schristos unsigned have; 291c3423655Schristos unsigned char buf[1]; 292c3423655Schristos gz_statep state; 293c3423655Schristos z_streamp strm; 294c3423655Schristos 295c3423655Schristos /* get internal structure */ 296c3423655Schristos if (file == NULL) 297c3423655Schristos return -1; 298c3423655Schristos state = (gz_statep)file; 299c3423655Schristos strm = &(state->strm); 300c3423655Schristos 301c3423655Schristos /* check that we're writing and that there's no error */ 302c3423655Schristos if (state->mode != GZ_WRITE || state->err != Z_OK) 303c3423655Schristos return -1; 304c3423655Schristos 305c3423655Schristos /* check for seek request */ 306c3423655Schristos if (state->seek) { 307c3423655Schristos state->seek = 0; 308c3423655Schristos if (gz_zero(state, state->skip) == -1) 309c3423655Schristos return -1; 310c3423655Schristos } 311c3423655Schristos 312c3423655Schristos /* try writing to input buffer for speed (state->size == 0 if buffer not 313c3423655Schristos initialized) */ 314c3423655Schristos if (state->size) { 315c3423655Schristos if (strm->avail_in == 0) 316c3423655Schristos strm->next_in = state->in; 317c3423655Schristos have = (unsigned)((strm->next_in + strm->avail_in) - state->in); 318c3423655Schristos if (have < state->size) { 319c3423655Schristos state->in[have] = (unsigned char)c; 320c3423655Schristos strm->avail_in++; 321c3423655Schristos state->x.pos++; 322c3423655Schristos return c & 0xff; 323c3423655Schristos } 324c3423655Schristos } 325c3423655Schristos 326c3423655Schristos /* no room in buffer or not initialized, use gz_write() */ 327c3423655Schristos buf[0] = (unsigned char)c; 328c3423655Schristos if (gz_write(state, buf, 1) != 1) 329c3423655Schristos return -1; 330c3423655Schristos return c & 0xff; 331c3423655Schristos } 332c3423655Schristos 333c3423655Schristos /* -- see zlib.h -- */ 334*96c32821Schristos int ZEXPORT gzputs(gzFile file, const char *s) { 3353b1253e8Schristos z_size_t len, put; 336c3423655Schristos gz_statep state; 337c3423655Schristos 338c3423655Schristos /* get internal structure */ 339c3423655Schristos if (file == NULL) 340c3423655Schristos return -1; 341c3423655Schristos state = (gz_statep)file; 342c3423655Schristos 343c3423655Schristos /* check that we're writing and that there's no error */ 344c3423655Schristos if (state->mode != GZ_WRITE || state->err != Z_OK) 345c3423655Schristos return -1; 346c3423655Schristos 347c3423655Schristos /* write string */ 3483b1253e8Schristos len = strlen(s); 3493b1253e8Schristos if ((int)len < 0 || (unsigned)len != len) { 3503b1253e8Schristos gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); 3513b1253e8Schristos return -1; 3523b1253e8Schristos } 3533b1253e8Schristos put = gz_write(state, s, len); 3543b1253e8Schristos return put < len ? -1 : (int)len; 355c3423655Schristos } 356c3423655Schristos 357c3423655Schristos #if defined(STDC) || defined(Z_HAVE_STDARG_H) 358c3423655Schristos #include <stdarg.h> 359c3423655Schristos 360c3423655Schristos /* -- see zlib.h -- */ 361*96c32821Schristos int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { 362c3423655Schristos int len; 363c3423655Schristos unsigned left; 364c3423655Schristos char *next; 365c3423655Schristos gz_statep state; 366c3423655Schristos z_streamp strm; 367c3423655Schristos 368c3423655Schristos /* get internal structure */ 369c3423655Schristos if (file == NULL) 370c3423655Schristos return Z_STREAM_ERROR; 371c3423655Schristos state = (gz_statep)file; 372c3423655Schristos strm = &(state->strm); 373c3423655Schristos 374c3423655Schristos /* check that we're writing and that there's no error */ 375c3423655Schristos if (state->mode != GZ_WRITE || state->err != Z_OK) 376c3423655Schristos return Z_STREAM_ERROR; 377c3423655Schristos 378c3423655Schristos /* make sure we have some buffer space */ 379c3423655Schristos if (state->size == 0 && gz_init(state) == -1) 380c3423655Schristos return state->err; 381c3423655Schristos 382c3423655Schristos /* check for seek request */ 383c3423655Schristos if (state->seek) { 384c3423655Schristos state->seek = 0; 385c3423655Schristos if (gz_zero(state, state->skip) == -1) 386c3423655Schristos return state->err; 387c3423655Schristos } 388c3423655Schristos 389c3423655Schristos /* do the printf() into the input buffer, put length in len -- the input 390c3423655Schristos buffer is double-sized just for this function, so there is guaranteed to 391c3423655Schristos be state->size bytes available after the current contents */ 392c3423655Schristos if (strm->avail_in == 0) 393c3423655Schristos strm->next_in = state->in; 394c3423655Schristos next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); 395c3423655Schristos next[state->size - 1] = 0; 396c3423655Schristos #ifdef NO_vsnprintf 397c3423655Schristos # ifdef HAS_vsprintf_void 398c3423655Schristos (void)vsprintf(next, format, va); 399c3423655Schristos for (len = 0; len < state->size; len++) 400c3423655Schristos if (next[len] == 0) break; 401c3423655Schristos # else 402c3423655Schristos len = vsprintf(next, format, va); 403c3423655Schristos # endif 404c3423655Schristos #else 405c3423655Schristos # ifdef HAS_vsnprintf_void 406c3423655Schristos (void)vsnprintf(next, state->size, format, va); 407c3423655Schristos len = strlen(next); 408c3423655Schristos # else 409c3423655Schristos len = vsnprintf(next, state->size, format, va); 410c3423655Schristos # endif 411c3423655Schristos #endif 412c3423655Schristos 413c3423655Schristos /* check that printf() results fit in buffer */ 414c3423655Schristos if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) 415c3423655Schristos return 0; 416c3423655Schristos 417c3423655Schristos /* update buffer and position, compress first half if past that */ 418c3423655Schristos strm->avail_in += (unsigned)len; 419c3423655Schristos state->x.pos += len; 420c3423655Schristos if (strm->avail_in >= state->size) { 421c3423655Schristos left = strm->avail_in - state->size; 422c3423655Schristos strm->avail_in = state->size; 423c3423655Schristos if (gz_comp(state, Z_NO_FLUSH) == -1) 424c3423655Schristos return state->err; 4253b1253e8Schristos memmove(state->in, state->in + state->size, left); 426c3423655Schristos strm->next_in = state->in; 427c3423655Schristos strm->avail_in = left; 428c3423655Schristos } 429c3423655Schristos return len; 430c3423655Schristos } 431c3423655Schristos 432*96c32821Schristos int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { 433c3423655Schristos va_list va; 434c3423655Schristos int ret; 435c3423655Schristos 436c3423655Schristos va_start(va, format); 437c3423655Schristos ret = gzvprintf(file, format, va); 438c3423655Schristos va_end(va); 439c3423655Schristos return ret; 440c3423655Schristos } 441c3423655Schristos 442c3423655Schristos #else /* !STDC && !Z_HAVE_STDARG_H */ 443c3423655Schristos 444c3423655Schristos /* -- see zlib.h -- */ 445*96c32821Schristos int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, 446*96c32821Schristos int a4, int a5, int a6, int a7, int a8, int a9, int a10, 447*96c32821Schristos int a11, int a12, int a13, int a14, int a15, int a16, 448*96c32821Schristos int a17, int a18, int a19, int a20) { 449c3423655Schristos unsigned len, left; 450c3423655Schristos char *next; 451c3423655Schristos gz_statep state; 452c3423655Schristos z_streamp strm; 453c3423655Schristos 454c3423655Schristos /* get internal structure */ 455c3423655Schristos if (file == NULL) 456c3423655Schristos return Z_STREAM_ERROR; 457c3423655Schristos state = (gz_statep)file; 458c3423655Schristos strm = &(state->strm); 459c3423655Schristos 460c3423655Schristos /* check that can really pass pointer in ints */ 461c3423655Schristos if (sizeof(int) != sizeof(void *)) 462c3423655Schristos return Z_STREAM_ERROR; 463c3423655Schristos 464c3423655Schristos /* check that we're writing and that there's no error */ 465c3423655Schristos if (state->mode != GZ_WRITE || state->err != Z_OK) 466c3423655Schristos return Z_STREAM_ERROR; 467c3423655Schristos 468c3423655Schristos /* make sure we have some buffer space */ 469c3423655Schristos if (state->size == 0 && gz_init(state) == -1) 470c3423655Schristos return state->error; 471c3423655Schristos 472c3423655Schristos /* check for seek request */ 473c3423655Schristos if (state->seek) { 474c3423655Schristos state->seek = 0; 475c3423655Schristos if (gz_zero(state, state->skip) == -1) 476c3423655Schristos return state->error; 477c3423655Schristos } 478c3423655Schristos 479c3423655Schristos /* do the printf() into the input buffer, put length in len -- the input 480c3423655Schristos buffer is double-sized just for this function, so there is guaranteed to 481c3423655Schristos be state->size bytes available after the current contents */ 482c3423655Schristos if (strm->avail_in == 0) 483c3423655Schristos strm->next_in = state->in; 484c3423655Schristos next = (char *)(strm->next_in + strm->avail_in); 485c3423655Schristos next[state->size - 1] = 0; 486c3423655Schristos #ifdef NO_snprintf 487c3423655Schristos # ifdef HAS_sprintf_void 488c3423655Schristos sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, 489c3423655Schristos a13, a14, a15, a16, a17, a18, a19, a20); 490c3423655Schristos for (len = 0; len < size; len++) 491c3423655Schristos if (next[len] == 0) 492c3423655Schristos break; 493c3423655Schristos # else 494c3423655Schristos len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, 495c3423655Schristos a12, a13, a14, a15, a16, a17, a18, a19, a20); 496c3423655Schristos # endif 497c3423655Schristos #else 498c3423655Schristos # ifdef HAS_snprintf_void 499c3423655Schristos snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, 500c3423655Schristos a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 501c3423655Schristos len = strlen(next); 502c3423655Schristos # else 503c3423655Schristos len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, 504c3423655Schristos a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 505c3423655Schristos # endif 506c3423655Schristos #endif 507c3423655Schristos 508c3423655Schristos /* check that printf() results fit in buffer */ 509c3423655Schristos if (len == 0 || len >= state->size || next[state->size - 1] != 0) 510c3423655Schristos return 0; 511c3423655Schristos 512c3423655Schristos /* update buffer and position, compress first half if past that */ 513c3423655Schristos strm->avail_in += len; 514c3423655Schristos state->x.pos += len; 515c3423655Schristos if (strm->avail_in >= state->size) { 516c3423655Schristos left = strm->avail_in - state->size; 517c3423655Schristos strm->avail_in = state->size; 518c3423655Schristos if (gz_comp(state, Z_NO_FLUSH) == -1) 519c3423655Schristos return state->err; 5203b1253e8Schristos memmove(state->in, state->in + state->size, left); 521c3423655Schristos strm->next_in = state->in; 522c3423655Schristos strm->avail_in = left; 523c3423655Schristos } 524c3423655Schristos return (int)len; 525c3423655Schristos } 526c3423655Schristos 527c3423655Schristos #endif 528c3423655Schristos 529c3423655Schristos /* -- see zlib.h -- */ 530*96c32821Schristos int ZEXPORT gzflush(gzFile file, int flush) { 531c3423655Schristos gz_statep state; 532c3423655Schristos 533c3423655Schristos /* get internal structure */ 534c3423655Schristos if (file == NULL) 535c3423655Schristos return Z_STREAM_ERROR; 536c3423655Schristos state = (gz_statep)file; 537c3423655Schristos 538c3423655Schristos /* check that we're writing and that there's no error */ 539c3423655Schristos if (state->mode != GZ_WRITE || state->err != Z_OK) 540c3423655Schristos return Z_STREAM_ERROR; 541c3423655Schristos 542c3423655Schristos /* check flush parameter */ 543c3423655Schristos if (flush < 0 || flush > Z_FINISH) 544c3423655Schristos return Z_STREAM_ERROR; 545c3423655Schristos 546c3423655Schristos /* check for seek request */ 547c3423655Schristos if (state->seek) { 548c3423655Schristos state->seek = 0; 549c3423655Schristos if (gz_zero(state, state->skip) == -1) 550c3423655Schristos return state->err; 551c3423655Schristos } 552c3423655Schristos 553c3423655Schristos /* compress remaining data with requested flush */ 554c3423655Schristos (void)gz_comp(state, flush); 555c3423655Schristos return state->err; 556c3423655Schristos } 557c3423655Schristos 558c3423655Schristos /* -- see zlib.h -- */ 559*96c32821Schristos int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { 560c3423655Schristos gz_statep state; 561c3423655Schristos z_streamp strm; 562c3423655Schristos 563c3423655Schristos /* get internal structure */ 564c3423655Schristos if (file == NULL) 565c3423655Schristos return Z_STREAM_ERROR; 566c3423655Schristos state = (gz_statep)file; 567c3423655Schristos strm = &(state->strm); 568c3423655Schristos 569c3423655Schristos /* check that we're writing and that there's no error */ 570*96c32821Schristos if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) 571c3423655Schristos return Z_STREAM_ERROR; 572c3423655Schristos 573c3423655Schristos /* if no change is requested, then do nothing */ 574c3423655Schristos if (level == state->level && strategy == state->strategy) 575c3423655Schristos return Z_OK; 576c3423655Schristos 577c3423655Schristos /* check for seek request */ 578c3423655Schristos if (state->seek) { 579c3423655Schristos state->seek = 0; 580c3423655Schristos if (gz_zero(state, state->skip) == -1) 581c3423655Schristos return state->err; 582c3423655Schristos } 583c3423655Schristos 584c3423655Schristos /* change compression parameters for subsequent input */ 585c3423655Schristos if (state->size) { 586c3423655Schristos /* flush previous input with previous parameters before changing */ 587c3423655Schristos if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) 588c3423655Schristos return state->err; 589c3423655Schristos deflateParams(strm, level, strategy); 590c3423655Schristos } 591c3423655Schristos state->level = level; 592c3423655Schristos state->strategy = strategy; 593c3423655Schristos return Z_OK; 594c3423655Schristos } 595c3423655Schristos 596c3423655Schristos /* -- see zlib.h -- */ 597*96c32821Schristos int ZEXPORT gzclose_w(gzFile file) { 598c3423655Schristos int ret = Z_OK; 599c3423655Schristos gz_statep state; 600c3423655Schristos 601c3423655Schristos /* get internal structure */ 602c3423655Schristos if (file == NULL) 603c3423655Schristos return Z_STREAM_ERROR; 604c3423655Schristos state = (gz_statep)file; 605c3423655Schristos 606c3423655Schristos /* check that we're writing */ 607c3423655Schristos if (state->mode != GZ_WRITE) 608c3423655Schristos return Z_STREAM_ERROR; 609c3423655Schristos 610c3423655Schristos /* check for seek request */ 611c3423655Schristos if (state->seek) { 612c3423655Schristos state->seek = 0; 613c3423655Schristos if (gz_zero(state, state->skip) == -1) 614c3423655Schristos ret = state->err; 615c3423655Schristos } 616c3423655Schristos 617c3423655Schristos /* flush, free memory, and close file */ 618c3423655Schristos if (gz_comp(state, Z_FINISH) == -1) 619c3423655Schristos ret = state->err; 620c3423655Schristos if (state->size) { 621c3423655Schristos if (!state->direct) { 622c3423655Schristos (void)deflateEnd(&(state->strm)); 623c3423655Schristos free(state->out); 624c3423655Schristos } 625c3423655Schristos free(state->in); 626c3423655Schristos } 627c3423655Schristos gz_error(state, Z_OK, NULL); 628c3423655Schristos free(state->path); 629c3423655Schristos if (close(state->fd) == -1) 630c3423655Schristos ret = Z_ERRNO; 631c3423655Schristos free(state); 632c3423655Schristos return ret; 633c3423655Schristos } 634