125839Speter/* zlib.c --- interface to the zlib compression library 225839Speter Ian Lance Taylor <ian@cygnus.com> 325839Speter 425839Speter This file is part of GNU CVS. 525839Speter 625839Speter GNU CVS is free software; you can redistribute it and/or modify it 725839Speter under the terms of the GNU General Public License as published by the 825839Speter Free Software Foundation; either version 2, or (at your option) any 925839Speter later version. 1025839Speter 1125839Speter This program is distributed in the hope that it will be useful, 1225839Speter but WITHOUT ANY WARRANTY; without even the implied warranty of 1325839Speter MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1425839Speter GNU General Public License for more details. */ 1525839Speter 1625839Speter/* The routines in this file are the interface between the CVS 1725839Speter client/server support and the zlib compression library. */ 1825839Speter 1925839Speter#include <assert.h> 2025839Speter#include "cvs.h" 2125839Speter#include "buffer.h" 2225839Speter 2325839Speter#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) 2425839Speter 2525839Speter#include "zlib.h" 2625839Speter 2725839Speter/* OS/2 doesn't have EIO. FIXME: this whole notion of turning 2825839Speter a different error into EIO strikes me as pretty dubious. */ 2925839Speter#if !defined (EIO) 3025839Speter#define EIO EBADPOS 3125839Speter#endif 3225839Speter 3325839Speter/* The compression interface is built upon the buffer data structure. 3425839Speter We provide a buffer type which compresses or decompresses the data 3525839Speter which passes through it. An input buffer decompresses the data 3625839Speter read from an underlying buffer, and an output buffer compresses the 3725839Speter data before writing it to an underlying buffer. */ 3825839Speter 3925839Speter/* This structure is the closure field of the buffer. */ 4025839Speter 4125839Speterstruct compress_buffer 4225839Speter{ 4325839Speter /* The underlying buffer. */ 4425839Speter struct buffer *buf; 4525839Speter /* The compression information. */ 4625839Speter z_stream zstr; 4725839Speter}; 4825839Speter 4925839Speterstatic void compress_error PROTO((int, int, z_stream *, const char *)); 5025839Speterstatic int compress_buffer_input PROTO((void *, char *, int, int, int *)); 5125839Speterstatic int compress_buffer_output PROTO((void *, const char *, int, int *)); 5225839Speterstatic int compress_buffer_flush PROTO((void *)); 5325839Speterstatic int compress_buffer_block PROTO((void *, int)); 54102840Speterstatic int compress_buffer_shutdown_input PROTO((struct buffer *)); 55102840Speterstatic int compress_buffer_shutdown_output PROTO((struct buffer *)); 5625839Speter 5725839Speter/* Report an error from one of the zlib functions. */ 5825839Speter 5925839Speterstatic void 6025839Spetercompress_error (status, zstatus, zstr, msg) 6125839Speter int status; 6225839Speter int zstatus; 6325839Speter z_stream *zstr; 6425839Speter const char *msg; 6525839Speter{ 6625839Speter int hold_errno; 6725839Speter const char *zmsg; 6825839Speter char buf[100]; 6925839Speter 7025839Speter hold_errno = errno; 7125839Speter 7225839Speter zmsg = zstr->msg; 7325839Speter if (zmsg == NULL) 7425839Speter { 7525839Speter sprintf (buf, "error %d", zstatus); 7625839Speter zmsg = buf; 7725839Speter } 7825839Speter 7925839Speter error (status, 8025839Speter zstatus == Z_ERRNO ? hold_errno : 0, 8125839Speter "%s: %s", msg, zmsg); 8225839Speter} 8325839Speter 8425839Speter/* Create a compression buffer. */ 8525839Speter 8625839Speterstruct buffer * 8725839Spetercompress_buffer_initialize (buf, input, level, memory) 8825839Speter struct buffer *buf; 8925839Speter int input; 9025839Speter int level; 9125839Speter void (*memory) PROTO((struct buffer *)); 9225839Speter{ 9325839Speter struct compress_buffer *n; 9425839Speter int zstatus; 9525839Speter 9625839Speter n = (struct compress_buffer *) xmalloc (sizeof *n); 9725839Speter memset (n, 0, sizeof *n); 9825839Speter 9925839Speter n->buf = buf; 10025839Speter 10125839Speter if (input) 10225839Speter zstatus = inflateInit (&n->zstr); 10325839Speter else 10425839Speter zstatus = deflateInit (&n->zstr, level); 10525839Speter if (zstatus != Z_OK) 10625839Speter compress_error (1, zstatus, &n->zstr, "compression initialization"); 10725839Speter 10825839Speter /* There may already be data buffered on BUF. For an output 10925839Speter buffer, this is OK, because these routines will just use the 11025839Speter buffer routines to append data to the (uncompressed) data 11125839Speter already on BUF. An input buffer expects to handle a single 11225839Speter buffer_data of buffered input to be uncompressed, so that is OK 11325839Speter provided there is only one buffer. At present that is all 11425839Speter there ever will be; if this changes, compress_buffer_input must 11525839Speter be modified to handle multiple input buffers. */ 11625839Speter assert (! input || buf->data == NULL || buf->data->next == NULL); 11725839Speter 11825839Speter return buf_initialize (input ? compress_buffer_input : NULL, 11925839Speter input ? NULL : compress_buffer_output, 12025839Speter input ? NULL : compress_buffer_flush, 12125839Speter compress_buffer_block, 12225839Speter (input 12325839Speter ? compress_buffer_shutdown_input 12425839Speter : compress_buffer_shutdown_output), 12525839Speter memory, 12625839Speter n); 12725839Speter} 12825839Speter 12925839Speter/* Input data from a compression buffer. */ 13025839Speter 13125839Speterstatic int 13225839Spetercompress_buffer_input (closure, data, need, size, got) 13325839Speter void *closure; 13425839Speter char *data; 13525839Speter int need; 13625839Speter int size; 13725839Speter int *got; 13825839Speter{ 13925839Speter struct compress_buffer *cb = (struct compress_buffer *) closure; 14025839Speter struct buffer_data *bd; 14125839Speter 14225839Speter if (cb->buf->input == NULL) 14325839Speter abort (); 14425839Speter 14525839Speter /* We use a single buffer_data structure to buffer up data which 14625839Speter the z_stream structure won't use yet. We can safely store this 14725839Speter on cb->buf->data, because we never call the buffer routines on 14825839Speter cb->buf; we only call the buffer input routine, since that 14925839Speter gives us the semantics we want. As noted in 15025839Speter compress_buffer_initialize, the buffer_data structure may 15125839Speter already exist, and hold data which was already read and 15225839Speter buffered before the decompression began. */ 15325839Speter bd = cb->buf->data; 15425839Speter if (bd == NULL) 15525839Speter { 156109655Speter bd = ((struct buffer_data *) xmalloc (sizeof (struct buffer_data))); 15725839Speter if (bd == NULL) 15825839Speter return -2; 159109655Speter bd->text = (char *) xmalloc (BUFFER_DATA_SIZE); 16025839Speter if (bd->text == NULL) 16125839Speter { 16225839Speter free (bd); 16325839Speter return -2; 16425839Speter } 16525839Speter bd->bufp = bd->text; 16625839Speter bd->size = 0; 16725839Speter cb->buf->data = bd; 16825839Speter } 16925839Speter 17025839Speter cb->zstr.avail_out = size; 17125839Speter cb->zstr.next_out = (Bytef *) data; 17225839Speter 17325839Speter while (1) 17425839Speter { 17525839Speter int zstatus, sofar, status, nread; 17625839Speter 17725839Speter /* First try to inflate any data we already have buffered up. 17825839Speter This is useful even if we don't have any buffered data, 17925839Speter because there may be data buffered inside the z_stream 18025839Speter structure. */ 18125839Speter 18225839Speter cb->zstr.avail_in = bd->size; 18325839Speter cb->zstr.next_in = (Bytef *) bd->bufp; 18425839Speter 18525839Speter do 18625839Speter { 18725839Speter zstatus = inflate (&cb->zstr, Z_NO_FLUSH); 18825839Speter if (zstatus == Z_STREAM_END) 18925839Speter break; 19025839Speter if (zstatus != Z_OK && zstatus != Z_BUF_ERROR) 19125839Speter { 19225839Speter compress_error (0, zstatus, &cb->zstr, "inflate"); 19325839Speter return EIO; 19425839Speter } 19525839Speter } while (cb->zstr.avail_in > 0 19625839Speter && cb->zstr.avail_out > 0); 19725839Speter 19825839Speter bd->size = cb->zstr.avail_in; 19925839Speter bd->bufp = (char *) cb->zstr.next_in; 20025839Speter 20125839Speter if (zstatus == Z_STREAM_END) 20225839Speter return -1; 20325839Speter 20425839Speter /* If we have obtained NEED bytes, then return, unless NEED is 20525839Speter zero and we haven't obtained anything at all. If NEED is 20625839Speter zero, we will keep reading from the underlying buffer until 20725839Speter we either can't read anything, or we have managed to 20825839Speter inflate at least one byte. */ 20925839Speter sofar = size - cb->zstr.avail_out; 21025839Speter if (sofar > 0 && sofar >= need) 21125839Speter break; 21225839Speter 21325839Speter /* All our buffered data should have been processed at this 21425839Speter point. */ 21525839Speter assert (bd->size == 0); 21625839Speter 21725839Speter /* This will work well in the server, because this call will 21825839Speter do an unblocked read and fetch all the available data. In 21925839Speter the client, this will read a single byte from the stdio 22025839Speter stream, which will cause us to call inflate once per byte. 22125839Speter It would be more efficient if we could make a call which 22225839Speter would fetch all the available bytes, and at least one byte. */ 22325839Speter 22425839Speter status = (*cb->buf->input) (cb->buf->closure, bd->text, 22525839Speter need > 0 ? 1 : 0, 22625839Speter BUFFER_DATA_SIZE, &nread); 22725839Speter if (status != 0) 22825839Speter return status; 22925839Speter 23025839Speter /* If we didn't read anything, then presumably the buffer is 23125839Speter in nonblocking mode, and we should just get out now with 23225839Speter whatever we've inflated. */ 23325839Speter if (nread == 0) 23425839Speter { 23525839Speter assert (need == 0); 23625839Speter break; 23725839Speter } 23825839Speter 23925839Speter bd->bufp = bd->text; 24025839Speter bd->size = nread; 24125839Speter } 24225839Speter 24325839Speter *got = size - cb->zstr.avail_out; 24425839Speter 24525839Speter return 0; 24625839Speter} 24725839Speter 24825839Speter/* Output data to a compression buffer. */ 24925839Speter 25025839Speterstatic int 25125839Spetercompress_buffer_output (closure, data, have, wrote) 25225839Speter void *closure; 25325839Speter const char *data; 25425839Speter int have; 25525839Speter int *wrote; 25625839Speter{ 25725839Speter struct compress_buffer *cb = (struct compress_buffer *) closure; 25825839Speter 25925839Speter cb->zstr.avail_in = have; 26025839Speter cb->zstr.next_in = (unsigned char *) data; 26125839Speter 26225839Speter while (cb->zstr.avail_in > 0) 26325839Speter { 26425839Speter char buffer[BUFFER_DATA_SIZE]; 26525839Speter int zstatus; 26625839Speter 26725839Speter cb->zstr.avail_out = BUFFER_DATA_SIZE; 26825839Speter cb->zstr.next_out = (unsigned char *) buffer; 26925839Speter 27025839Speter zstatus = deflate (&cb->zstr, Z_NO_FLUSH); 27125839Speter if (zstatus != Z_OK) 27225839Speter { 27325839Speter compress_error (0, zstatus, &cb->zstr, "deflate"); 27425839Speter return EIO; 27525839Speter } 27625839Speter 27725839Speter if (cb->zstr.avail_out != BUFFER_DATA_SIZE) 27825839Speter buf_output (cb->buf, buffer, 27925839Speter BUFFER_DATA_SIZE - cb->zstr.avail_out); 28025839Speter } 28125839Speter 28225839Speter *wrote = have; 28325839Speter 28425839Speter /* We will only be here because buf_send_output was called on the 28525839Speter compression buffer. That means that we should now call 28625839Speter buf_send_output on the underlying buffer. */ 28725839Speter return buf_send_output (cb->buf); 28825839Speter} 28925839Speter 29025839Speter/* Flush a compression buffer. */ 29125839Speter 29225839Speterstatic int 29325839Spetercompress_buffer_flush (closure) 29425839Speter void *closure; 29525839Speter{ 29625839Speter struct compress_buffer *cb = (struct compress_buffer *) closure; 29725839Speter 29825839Speter cb->zstr.avail_in = 0; 29925839Speter cb->zstr.next_in = NULL; 30025839Speter 30125839Speter while (1) 30225839Speter { 30325839Speter char buffer[BUFFER_DATA_SIZE]; 30425839Speter int zstatus; 30525839Speter 30625839Speter cb->zstr.avail_out = BUFFER_DATA_SIZE; 30725839Speter cb->zstr.next_out = (unsigned char *) buffer; 30825839Speter 30925839Speter zstatus = deflate (&cb->zstr, Z_SYNC_FLUSH); 31025839Speter 31125839Speter /* The deflate function will return Z_BUF_ERROR if it can't do 31225839Speter anything, which in this case means that all data has been 31325839Speter flushed. */ 31425839Speter if (zstatus == Z_BUF_ERROR) 31525839Speter break; 31625839Speter 31725839Speter if (zstatus != Z_OK) 31825839Speter { 31925839Speter compress_error (0, zstatus, &cb->zstr, "deflate flush"); 32025839Speter return EIO; 32125839Speter } 32225839Speter 32325839Speter if (cb->zstr.avail_out != BUFFER_DATA_SIZE) 32425839Speter buf_output (cb->buf, buffer, 32525839Speter BUFFER_DATA_SIZE - cb->zstr.avail_out); 32625839Speter 32725839Speter /* If the deflate function did not fill the output buffer, 32825839Speter then all data has been flushed. */ 32925839Speter if (cb->zstr.avail_out > 0) 33025839Speter break; 33125839Speter } 33225839Speter 33325839Speter /* Now flush the underlying buffer. Note that if the original 33425839Speter call to buf_flush passed 1 for the BLOCK argument, then the 33525839Speter buffer will already have been set into blocking mode, so we 33625839Speter should always pass 0 here. */ 33725839Speter return buf_flush (cb->buf, 0); 33825839Speter} 33925839Speter 34025839Speter/* The block routine for a compression buffer. */ 34125839Speter 34225839Speterstatic int 34325839Spetercompress_buffer_block (closure, block) 34425839Speter void *closure; 34525839Speter int block; 34625839Speter{ 34725839Speter struct compress_buffer *cb = (struct compress_buffer *) closure; 34825839Speter 34925839Speter if (block) 35025839Speter return set_block (cb->buf); 35125839Speter else 35225839Speter return set_nonblock (cb->buf); 35325839Speter} 35425839Speter 35525839Speter/* Shut down an input buffer. */ 35625839Speter 35725839Speterstatic int 358102840Spetercompress_buffer_shutdown_input (buf) 359102840Speter struct buffer *buf; 36025839Speter{ 361102840Speter struct compress_buffer *cb = (struct compress_buffer *) buf->closure; 36225839Speter int zstatus; 36325839Speter 364175261Sobrien /* Don't make any attempt to pick up trailing data since we are shutting 365175261Sobrien * down. If the client doesn't know we are shutting down, we might not 366175261Sobrien * see the EOF we are expecting. 367175261Sobrien */ 36825839Speter 36925839Speter zstatus = inflateEnd (&cb->zstr); 37025839Speter if (zstatus != Z_OK) 37125839Speter { 37225839Speter compress_error (0, zstatus, &cb->zstr, "inflateEnd"); 37325839Speter return EIO; 37425839Speter } 37525839Speter 37625839Speter return buf_shutdown (cb->buf); 37725839Speter} 37825839Speter 37925839Speter/* Shut down an output buffer. */ 38025839Speter 38125839Speterstatic int 382102840Spetercompress_buffer_shutdown_output (buf) 383102840Speter struct buffer *buf; 38425839Speter{ 385102840Speter struct compress_buffer *cb = (struct compress_buffer *) buf->closure; 38625839Speter int zstatus, status; 38725839Speter 38825839Speter do 38925839Speter { 39025839Speter char buffer[BUFFER_DATA_SIZE]; 39125839Speter 39225839Speter cb->zstr.avail_out = BUFFER_DATA_SIZE; 39325839Speter cb->zstr.next_out = (unsigned char *) buffer; 39425839Speter 39525839Speter zstatus = deflate (&cb->zstr, Z_FINISH); 39625839Speter if (zstatus != Z_OK && zstatus != Z_STREAM_END) 39725839Speter { 39825839Speter compress_error (0, zstatus, &cb->zstr, "deflate finish"); 39925839Speter return EIO; 40025839Speter } 40125839Speter 40225839Speter if (cb->zstr.avail_out != BUFFER_DATA_SIZE) 40325839Speter buf_output (cb->buf, buffer, 40425839Speter BUFFER_DATA_SIZE - cb->zstr.avail_out); 40525839Speter } while (zstatus != Z_STREAM_END); 40625839Speter 40725839Speter zstatus = deflateEnd (&cb->zstr); 40825839Speter if (zstatus != Z_OK) 40925839Speter { 41025839Speter compress_error (0, zstatus, &cb->zstr, "deflateEnd"); 41125839Speter return EIO; 41225839Speter } 41325839Speter 41425839Speter status = buf_flush (cb->buf, 1); 41525839Speter if (status != 0) 41625839Speter return status; 41725839Speter 41825839Speter return buf_shutdown (cb->buf); 41925839Speter} 42025839Speter 42132785Speter 42232785Speter 42332785Speter/* Here is our librarified gzip implementation. It is very minimal 42432785Speter but attempts to be RFC1952 compliant. */ 42532785Speter 426128266Speter/* GZIP ID byte values */ 427128266Speter#define GZIP_ID1 31 428128266Speter#define GZIP_ID2 139 429128266Speter 430128266Speter/* Compression methods */ 431128266Speter#define GZIP_CDEFLATE 8 432128266Speter 433128266Speter/* Flags */ 434128266Speter#define GZIP_FTEXT 1 435128266Speter#define GZIP_FHCRC 2 436128266Speter#define GZIP_FEXTRA 4 437128266Speter#define GZIP_FNAME 8 438128266Speter#define GZIP_FCOMMENT 16 439128266Speter 44032785Speter/* BUF should contain SIZE bytes of gzipped data (RFC1952/RFC1951). 44132785Speter We are to uncompress the data and write the result to the file 44254427Speter descriptor FD. If something goes wrong, give a nonfatal error message 44354427Speter mentioning FULLNAME as the name of the file for FD. Return 1 if 44454427Speter it is an error we can't recover from. */ 44532785Speter 44654427Speterint 44732785Spetergunzip_and_write (fd, fullname, buf, size) 44832785Speter int fd; 44932785Speter char *fullname; 45032785Speter unsigned char *buf; 45132785Speter size_t size; 45232785Speter{ 45332785Speter size_t pos; 45432785Speter z_stream zstr; 45532785Speter int zstatus; 45632785Speter unsigned char outbuf[32768]; 45732785Speter unsigned long crc; 45832785Speter 459128266Speter if (size < 10) 46054427Speter { 461128266Speter error (0, 0, "gzipped data too small - lacks complete header"); 462128266Speter return 1; 463128266Speter } 464128266Speter if (buf[0] != GZIP_ID1 || buf[1] != GZIP_ID2) 465128266Speter { 46654427Speter error (0, 0, "gzipped data does not start with gzip identification"); 46754427Speter return 1; 46854427Speter } 469128266Speter if (buf[2] != GZIP_CDEFLATE) 47054427Speter { 47154427Speter error (0, 0, "only the deflate compression method is supported"); 47254427Speter return 1; 47354427Speter } 47432785Speter 47532785Speter /* Skip over the fixed header, and then skip any of the variable-length 476128266Speter fields. As we skip each field, we keep pos <= size. The checks 477128266Speter on positions and lengths are really checks for malformed or 478128266Speter incomplete gzip data. */ 47932785Speter pos = 10; 480128266Speter if (buf[3] & GZIP_FEXTRA) 481128266Speter { 482128266Speter if (pos + 2 >= size) 483128266Speter { 484128266Speter error (0, 0, "%s lacks proper gzip XLEN field", fullname); 485128266Speter return 1; 486128266Speter } 48732785Speter pos += buf[pos] + (buf[pos + 1] << 8) + 2; 488128266Speter if (pos > size) 489128266Speter { 490128266Speter error (0, 0, "%s lacks proper gzip \"extra field\"", fullname); 491128266Speter return 1; 492128266Speter } 493128266Speter 494128266Speter } 495128266Speter if (buf[3] & GZIP_FNAME) 496128266Speter { 497128266Speter unsigned char *p = memchr(buf + pos, '\0', size - pos); 498128266Speter if (p == NULL) 499128266Speter { 500128266Speter error (0, 0, "%s has bad gzip filename field", fullname); 501128266Speter return 1; 502128266Speter } 503128266Speter pos = p - buf + 1; 504128266Speter } 505128266Speter if (buf[3] & GZIP_FCOMMENT) 506128266Speter { 507128266Speter unsigned char *p = memchr(buf + pos, '\0', size - pos); 508128266Speter if (p == NULL) 509128266Speter { 510128266Speter error (0, 0, "%s has bad gzip comment field", fullname); 511128266Speter return 1; 512128266Speter } 513128266Speter pos = p - buf + 1; 514128266Speter } 515128266Speter if (buf[3] & GZIP_FHCRC) 516128266Speter { 51732785Speter pos += 2; 518128266Speter if (pos > size) 519128266Speter { 520128266Speter error (0, 0, "%s has bad gzip CRC16 field", fullname); 521128266Speter return 1; 522128266Speter } 523128266Speter } 52432785Speter 525128266Speter /* There could be no data to decompress - check and short circuit. */ 526128266Speter if (pos >= size) 527128266Speter { 528128266Speter error (0, 0, "gzip data incomplete for %s (no data)", fullname); 529128266Speter return 1; 530128266Speter } 531128266Speter 53232785Speter memset (&zstr, 0, sizeof zstr); 53332785Speter /* Passing a negative argument tells zlib not to look for a zlib 53432785Speter (RFC1950) header. This is an undocumented feature; I suppose if 53532785Speter we wanted to be anal we could synthesize a header instead, 53632785Speter but why bother? */ 53732785Speter zstatus = inflateInit2 (&zstr, -15); 53832785Speter 53932785Speter if (zstatus != Z_OK) 54032785Speter compress_error (1, zstatus, &zstr, fullname); 54132785Speter 54232785Speter /* I don't see why we should have to include the 8 byte trailer in 54332785Speter avail_in. But I see that zlib/gzio.c does, and it seemed to fix 54432785Speter a fairly rare bug in which we'd get a Z_BUF_ERROR for no obvious 54532785Speter reason. */ 54632785Speter zstr.avail_in = size - pos; 54732785Speter zstr.next_in = buf + pos; 54832785Speter 54932785Speter crc = crc32 (0, NULL, 0); 55032785Speter 55132785Speter do 55232785Speter { 55332785Speter zstr.avail_out = sizeof (outbuf); 55432785Speter zstr.next_out = outbuf; 55532785Speter zstatus = inflate (&zstr, Z_NO_FLUSH); 55632785Speter if (zstatus != Z_STREAM_END && zstatus != Z_OK) 55754427Speter { 55854427Speter compress_error (0, zstatus, &zstr, fullname); 55954427Speter return 1; 56054427Speter } 56132785Speter if (write (fd, outbuf, sizeof (outbuf) - zstr.avail_out) < 0) 56254427Speter { 56354427Speter error (0, errno, "writing decompressed file %s", fullname); 56454427Speter return 1; 56554427Speter } 56632785Speter crc = crc32 (crc, outbuf, sizeof (outbuf) - zstr.avail_out); 56732785Speter } while (zstatus != Z_STREAM_END); 56832785Speter zstatus = inflateEnd (&zstr); 56932785Speter if (zstatus != Z_OK) 57032785Speter compress_error (0, zstatus, &zstr, fullname); 57132785Speter 572128266Speter /* Check that there is still 8 trailer bytes remaining (CRC32 573128266Speter and ISIZE). Check total decomp. data, plus header len (pos) 574128266Speter against input buffer total size. */ 575128266Speter pos += zstr.total_in; 576128266Speter if (size - pos != 8) 57754427Speter { 578128266Speter error (0, 0, "gzip data incomplete for %s (no trailer)", fullname); 579128266Speter return 1; 580128266Speter } 581128266Speter 582128266Speter if (crc != ((unsigned long)buf[pos] 583128266Speter + ((unsigned long)buf[pos + 1] << 8) 584128266Speter + ((unsigned long)buf[pos + 2] << 16) 585128266Speter + ((unsigned long)buf[pos + 3] << 24))) 586128266Speter { 58754427Speter error (0, 0, "CRC error uncompressing %s", fullname); 58854427Speter return 1; 58954427Speter } 59032785Speter 591128266Speter if (zstr.total_out != ((unsigned long)buf[pos + 4] 592128266Speter + ((unsigned long)buf[pos + 5] << 8) 593128266Speter + ((unsigned long)buf[pos + 6] << 16) 594128266Speter + ((unsigned long)buf[pos + 7] << 24))) 59554427Speter { 59654427Speter error (0, 0, "invalid length uncompressing %s", fullname); 59754427Speter return 1; 59854427Speter } 59954427Speter 60054427Speter return 0; 60132785Speter} 60232785Speter 60332785Speter/* Read all of FD and put the gzipped data (RFC1952/RFC1951) into *BUF, 604109655Speter replacing previous contents of *BUF. *BUF is xmalloc'd and *SIZE is 60532785Speter its allocated size. Put the actual number of bytes of data in 60654427Speter *LEN. If something goes wrong, give a nonfatal error mentioning 60754427Speter FULLNAME as the name of the file for FD, and return 1 if we can't 60854427Speter recover from it). LEVEL is the compression level (1-9). */ 60932785Speter 61054427Speterint 61132785Speterread_and_gzip (fd, fullname, buf, size, len, level) 61232785Speter int fd; 613128266Speter const char *fullname; 61432785Speter unsigned char **buf; 61532785Speter size_t *size; 61632785Speter size_t *len; 61732785Speter int level; 61832785Speter{ 61932785Speter z_stream zstr; 62032785Speter int zstatus; 62132785Speter unsigned char inbuf[8192]; 62232785Speter int nread; 62332785Speter unsigned long crc; 62432785Speter 62532785Speter if (*size < 1024) 62632785Speter { 62754427Speter unsigned char *newbuf; 62854427Speter 62932785Speter *size = 1024; 630109655Speter newbuf = xrealloc (*buf, *size); 63154427Speter if (newbuf == NULL) 63254427Speter { 63354427Speter error (0, 0, "out of memory"); 63454427Speter return 1; 63554427Speter } 63654427Speter *buf = newbuf; 63732785Speter } 638128266Speter (*buf)[0] = GZIP_ID1; 639128266Speter (*buf)[1] = GZIP_ID2; 640128266Speter (*buf)[2] = GZIP_CDEFLATE; 64132785Speter (*buf)[3] = 0; 64232785Speter (*buf)[4] = (*buf)[5] = (*buf)[6] = (*buf)[7] = 0; 64332785Speter /* Could set this based on level, but why bother? */ 64432785Speter (*buf)[8] = 0; 64532785Speter (*buf)[9] = 255; 64632785Speter 64732785Speter memset (&zstr, 0, sizeof zstr); 64832785Speter zstatus = deflateInit2 (&zstr, level, Z_DEFLATED, -15, 8, 64932785Speter Z_DEFAULT_STRATEGY); 65032785Speter crc = crc32 (0, NULL, 0); 65132785Speter if (zstatus != Z_OK) 65254427Speter { 65354427Speter compress_error (0, zstatus, &zstr, fullname); 65454427Speter return 1; 65554427Speter } 656128266Speter 657128266Speter /* Adjust for 10-byte output header (filled in above) */ 658128266Speter zstr.total_out = 10; 659128266Speter zstr.avail_out = *size - 10; 66032785Speter zstr.next_out = *buf + 10; 66132785Speter 66232785Speter while (1) 66332785Speter { 66432785Speter int finish = 0; 66532785Speter 66632785Speter nread = read (fd, inbuf, sizeof inbuf); 66732785Speter if (nread < 0) 66854427Speter { 66954427Speter error (0, errno, "cannot read %s", fullname); 67054427Speter return 1; 67154427Speter } 67232785Speter else if (nread == 0) 67332785Speter /* End of file. */ 67432785Speter finish = 1; 67532785Speter crc = crc32 (crc, inbuf, nread); 67632785Speter zstr.next_in = inbuf; 67732785Speter zstr.avail_in = nread; 67832785Speter 67932785Speter do 68032785Speter { 68132785Speter /* I don't see this documented anywhere, but deflate seems 68232785Speter to tend to dump core sometimes if we pass it Z_FINISH and 68332785Speter a small (e.g. 2147 byte) avail_out. So we insist on at 68432785Speter least 4096 bytes (that is what zlib/gzio.c uses). */ 68532785Speter 68632785Speter if (zstr.avail_out < 4096) 68732785Speter { 68854427Speter unsigned char *newbuf; 68954427Speter 690128266Speter assert(zstr.avail_out + zstr.total_out == *size); 691128266Speter assert(zstr.next_out == *buf + zstr.total_out); 69232785Speter *size *= 2; 693109655Speter newbuf = xrealloc (*buf, *size); 69454427Speter if (newbuf == NULL) 69554427Speter { 69654427Speter error (0, 0, "out of memory"); 69754427Speter return 1; 69854427Speter } 69954427Speter *buf = newbuf; 700128266Speter zstr.next_out = *buf + zstr.total_out; 701128266Speter zstr.avail_out = *size - zstr.total_out; 702128266Speter assert(zstr.avail_out + zstr.total_out == *size); 703128266Speter assert(zstr.next_out == *buf + zstr.total_out); 70432785Speter } 70532785Speter 70632785Speter zstatus = deflate (&zstr, finish ? Z_FINISH : 0); 70732785Speter if (zstatus == Z_STREAM_END) 70832785Speter goto done; 70932785Speter else if (zstatus != Z_OK) 71032785Speter compress_error (0, zstatus, &zstr, fullname); 71132785Speter } while (zstr.avail_out == 0); 71232785Speter } 71332785Speter done: 714128266Speter /* Need to add the CRC information (8 bytes) 715128266Speter to the end of the gzip'd output. 716128266Speter Ensure there is enough space in the output buffer 717128266Speter to do so. */ 718128266Speter if (zstr.avail_out < 8) 719128266Speter { 720128266Speter unsigned char *newbuf; 72132785Speter 722128266Speter assert(zstr.avail_out + zstr.total_out == *size); 723128266Speter assert(zstr.next_out == *buf + zstr.total_out); 724128266Speter *size += 8 - zstr.avail_out; 725128266Speter newbuf = realloc (*buf, *size); 726128266Speter if (newbuf == NULL) 727128266Speter { 728128266Speter error (0, 0, "out of memory"); 729128266Speter return 1; 730128266Speter } 731128266Speter *buf = newbuf; 732128266Speter zstr.next_out = *buf + zstr.total_out; 733128266Speter zstr.avail_out = *size - zstr.total_out; 734128266Speter assert(zstr.avail_out + zstr.total_out == *size); 735128266Speter assert(zstr.next_out == *buf + zstr.total_out); 736128266Speter } 737128266Speter *zstr.next_out++ = (unsigned char)(crc & 0xff); 738128266Speter *zstr.next_out++ = (unsigned char)((crc >> 8) & 0xff); 739128266Speter *zstr.next_out++ = (unsigned char)((crc >> 16) & 0xff); 740128266Speter *zstr.next_out++ = (unsigned char)((crc >> 24) & 0xff); 74132785Speter 742128266Speter *zstr.next_out++ = (unsigned char)(zstr.total_in & 0xff); 743128266Speter *zstr.next_out++ = (unsigned char)((zstr.total_in >> 8) & 0xff); 744128266Speter *zstr.next_out++ = (unsigned char)((zstr.total_in >> 16) & 0xff); 745128266Speter *zstr.next_out++ = (unsigned char)((zstr.total_in >> 24) & 0xff); 74632785Speter 747128266Speter zstr.total_out += 8; 748128266Speter zstr.avail_out -= 8; 749128266Speter assert(zstr.avail_out + zstr.total_out == *size); 750128266Speter assert(zstr.next_out == *buf + zstr.total_out); 751128266Speter 752128266Speter *len = zstr.total_out; 753128266Speter 75432785Speter zstatus = deflateEnd (&zstr); 75532785Speter if (zstatus != Z_OK) 75632785Speter compress_error (0, zstatus, &zstr, fullname); 75754427Speter 75854427Speter return 0; 75932785Speter} 76025839Speter#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ 761