1/* zlib.c --- interface to the zlib compression library 2 Ian Lance Taylor <ian@cygnus.com> 3 4 This file is part of GNU CVS. 5 6 GNU CVS is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by the 8 Free Software Foundation; either version 2, or (at your option) any 9 later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. */ 15 16/* The routines in this file are the interface between the CVS 17 client/server support and the zlib compression library. */ 18 19#include <assert.h> 20#include "cvs.h" 21#include "buffer.h" 22 23#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) 24 25#include "zlib.h" 26 27/* OS/2 doesn't have EIO. FIXME: this whole notion of turning 28 a different error into EIO strikes me as pretty dubious. */ 29#if !defined (EIO) 30#define EIO EBADPOS 31#endif 32 33/* The compression interface is built upon the buffer data structure. 34 We provide a buffer type which compresses or decompresses the data 35 which passes through it. An input buffer decompresses the data 36 read from an underlying buffer, and an output buffer compresses the 37 data before writing it to an underlying buffer. */ 38 39/* This structure is the closure field of the buffer. */ 40 41struct compress_buffer 42{ 43 /* The underlying buffer. */ 44 struct buffer *buf; 45 /* The compression information. */ 46 z_stream zstr; 47}; 48 49static void compress_error PROTO((int, int, z_stream *, const char *)); 50static int compress_buffer_input PROTO((void *, char *, int, int, int *)); 51static int compress_buffer_output PROTO((void *, const char *, int, int *)); 52static int compress_buffer_flush PROTO((void *)); 53static int compress_buffer_block PROTO((void *, int)); 54static int compress_buffer_shutdown_input PROTO((struct buffer *)); 55static int compress_buffer_shutdown_output PROTO((struct buffer *)); 56 57/* Report an error from one of the zlib functions. */ 58 59static void 60compress_error (status, zstatus, zstr, msg) 61 int status; 62 int zstatus; 63 z_stream *zstr; 64 const char *msg; 65{ 66 int hold_errno; 67 const char *zmsg; 68 char buf[100]; 69 70 hold_errno = errno; 71 72 zmsg = zstr->msg; 73 if (zmsg == NULL) 74 { 75 sprintf (buf, "error %d", zstatus); 76 zmsg = buf; 77 } 78 79 error (status, 80 zstatus == Z_ERRNO ? hold_errno : 0, 81 "%s: %s", msg, zmsg); 82} 83 84/* Create a compression buffer. */ 85 86struct buffer * 87compress_buffer_initialize (buf, input, level, memory) 88 struct buffer *buf; 89 int input; 90 int level; 91 void (*memory) PROTO((struct buffer *)); 92{ 93 struct compress_buffer *n; 94 int zstatus; 95 96 n = (struct compress_buffer *) xmalloc (sizeof *n); 97 memset (n, 0, sizeof *n); 98 99 n->buf = buf; 100 101 if (input) 102 zstatus = inflateInit (&n->zstr); 103 else 104 zstatus = deflateInit (&n->zstr, level); 105 if (zstatus != Z_OK) 106 compress_error (1, zstatus, &n->zstr, "compression initialization"); 107 108 /* There may already be data buffered on BUF. For an output 109 buffer, this is OK, because these routines will just use the 110 buffer routines to append data to the (uncompressed) data 111 already on BUF. An input buffer expects to handle a single 112 buffer_data of buffered input to be uncompressed, so that is OK 113 provided there is only one buffer. At present that is all 114 there ever will be; if this changes, compress_buffer_input must 115 be modified to handle multiple input buffers. */ 116 assert (! input || buf->data == NULL || buf->data->next == NULL); 117 118 return buf_initialize (input ? compress_buffer_input : NULL, 119 input ? NULL : compress_buffer_output, 120 input ? NULL : compress_buffer_flush, 121 compress_buffer_block, 122 (input 123 ? compress_buffer_shutdown_input 124 : compress_buffer_shutdown_output), 125 memory, 126 n); 127} 128 129/* Input data from a compression buffer. */ 130 131static int 132compress_buffer_input (closure, data, need, size, got) 133 void *closure; 134 char *data; 135 int need; 136 int size; 137 int *got; 138{ 139 struct compress_buffer *cb = (struct compress_buffer *) closure; 140 struct buffer_data *bd; 141 142 if (cb->buf->input == NULL) 143 abort (); 144 145 /* We use a single buffer_data structure to buffer up data which 146 the z_stream structure won't use yet. We can safely store this 147 on cb->buf->data, because we never call the buffer routines on 148 cb->buf; we only call the buffer input routine, since that 149 gives us the semantics we want. As noted in 150 compress_buffer_initialize, the buffer_data structure may 151 already exist, and hold data which was already read and 152 buffered before the decompression began. */ 153 bd = cb->buf->data; 154 if (bd == NULL) 155 { 156 bd = ((struct buffer_data *) xmalloc (sizeof (struct buffer_data))); 157 if (bd == NULL) 158 return -2; 159 bd->text = (char *) xmalloc (BUFFER_DATA_SIZE); 160 if (bd->text == NULL) 161 { 162 free (bd); 163 return -2; 164 } 165 bd->bufp = bd->text; 166 bd->size = 0; 167 cb->buf->data = bd; 168 } 169 170 cb->zstr.avail_out = size; 171 cb->zstr.next_out = (Bytef *) data; 172 173 while (1) 174 { 175 int zstatus, sofar, status, nread; 176 177 /* First try to inflate any data we already have buffered up. 178 This is useful even if we don't have any buffered data, 179 because there may be data buffered inside the z_stream 180 structure. */ 181 182 cb->zstr.avail_in = bd->size; 183 cb->zstr.next_in = (Bytef *) bd->bufp; 184 185 do 186 { 187 zstatus = inflate (&cb->zstr, Z_NO_FLUSH); 188 if (zstatus == Z_STREAM_END) 189 break; 190 if (zstatus != Z_OK && zstatus != Z_BUF_ERROR) 191 { 192 compress_error (0, zstatus, &cb->zstr, "inflate"); 193 return EIO; 194 } 195 } while (cb->zstr.avail_in > 0 196 && cb->zstr.avail_out > 0); 197 198 bd->size = cb->zstr.avail_in; 199 bd->bufp = (char *) cb->zstr.next_in; 200 201 if (zstatus == Z_STREAM_END) 202 return -1; 203 204 /* If we have obtained NEED bytes, then return, unless NEED is 205 zero and we haven't obtained anything at all. If NEED is 206 zero, we will keep reading from the underlying buffer until 207 we either can't read anything, or we have managed to 208 inflate at least one byte. */ 209 sofar = size - cb->zstr.avail_out; 210 if (sofar > 0 && sofar >= need) 211 break; 212 213 /* All our buffered data should have been processed at this 214 point. */ 215 assert (bd->size == 0); 216 217 /* This will work well in the server, because this call will 218 do an unblocked read and fetch all the available data. In 219 the client, this will read a single byte from the stdio 220 stream, which will cause us to call inflate once per byte. 221 It would be more efficient if we could make a call which 222 would fetch all the available bytes, and at least one byte. */ 223 224 status = (*cb->buf->input) (cb->buf->closure, bd->text, 225 need > 0 ? 1 : 0, 226 BUFFER_DATA_SIZE, &nread); 227 if (status != 0) 228 return status; 229 230 /* If we didn't read anything, then presumably the buffer is 231 in nonblocking mode, and we should just get out now with 232 whatever we've inflated. */ 233 if (nread == 0) 234 { 235 assert (need == 0); 236 break; 237 } 238 239 bd->bufp = bd->text; 240 bd->size = nread; 241 } 242 243 *got = size - cb->zstr.avail_out; 244 245 return 0; 246} 247 248/* Output data to a compression buffer. */ 249 250static int 251compress_buffer_output (closure, data, have, wrote) 252 void *closure; 253 const char *data; 254 int have; 255 int *wrote; 256{ 257 struct compress_buffer *cb = (struct compress_buffer *) closure; 258 259 cb->zstr.avail_in = have; 260 cb->zstr.next_in = (unsigned char *) data; 261 262 while (cb->zstr.avail_in > 0) 263 { 264 char buffer[BUFFER_DATA_SIZE]; 265 int zstatus; 266 267 cb->zstr.avail_out = BUFFER_DATA_SIZE; 268 cb->zstr.next_out = (unsigned char *) buffer; 269 270 zstatus = deflate (&cb->zstr, Z_NO_FLUSH); 271 if (zstatus != Z_OK) 272 { 273 compress_error (0, zstatus, &cb->zstr, "deflate"); 274 return EIO; 275 } 276 277 if (cb->zstr.avail_out != BUFFER_DATA_SIZE) 278 buf_output (cb->buf, buffer, 279 BUFFER_DATA_SIZE - cb->zstr.avail_out); 280 } 281 282 *wrote = have; 283 284 /* We will only be here because buf_send_output was called on the 285 compression buffer. That means that we should now call 286 buf_send_output on the underlying buffer. */ 287 return buf_send_output (cb->buf); 288} 289 290/* Flush a compression buffer. */ 291 292static int 293compress_buffer_flush (closure) 294 void *closure; 295{ 296 struct compress_buffer *cb = (struct compress_buffer *) closure; 297 298 cb->zstr.avail_in = 0; 299 cb->zstr.next_in = NULL; 300 301 while (1) 302 { 303 char buffer[BUFFER_DATA_SIZE]; 304 int zstatus; 305 306 cb->zstr.avail_out = BUFFER_DATA_SIZE; 307 cb->zstr.next_out = (unsigned char *) buffer; 308 309 zstatus = deflate (&cb->zstr, Z_SYNC_FLUSH); 310 311 /* The deflate function will return Z_BUF_ERROR if it can't do 312 anything, which in this case means that all data has been 313 flushed. */ 314 if (zstatus == Z_BUF_ERROR) 315 break; 316 317 if (zstatus != Z_OK) 318 { 319 compress_error (0, zstatus, &cb->zstr, "deflate flush"); 320 return EIO; 321 } 322 323 if (cb->zstr.avail_out != BUFFER_DATA_SIZE) 324 buf_output (cb->buf, buffer, 325 BUFFER_DATA_SIZE - cb->zstr.avail_out); 326 327 /* If the deflate function did not fill the output buffer, 328 then all data has been flushed. */ 329 if (cb->zstr.avail_out > 0) 330 break; 331 } 332 333 /* Now flush the underlying buffer. Note that if the original 334 call to buf_flush passed 1 for the BLOCK argument, then the 335 buffer will already have been set into blocking mode, so we 336 should always pass 0 here. */ 337 return buf_flush (cb->buf, 0); 338} 339 340/* The block routine for a compression buffer. */ 341 342static int 343compress_buffer_block (closure, block) 344 void *closure; 345 int block; 346{ 347 struct compress_buffer *cb = (struct compress_buffer *) closure; 348 349 if (block) 350 return set_block (cb->buf); 351 else 352 return set_nonblock (cb->buf); 353} 354 355/* Shut down an input buffer. */ 356 357static int 358compress_buffer_shutdown_input (buf) 359 struct buffer *buf; 360{ 361 struct compress_buffer *cb = (struct compress_buffer *) buf->closure; 362 int zstatus; 363 364 /* Don't make any attempt to pick up trailing data since we are shutting 365 * down. If the client doesn't know we are shutting down, we might not 366 * see the EOF we are expecting. 367 */ 368 369 zstatus = inflateEnd (&cb->zstr); 370 if (zstatus != Z_OK) 371 { 372 compress_error (0, zstatus, &cb->zstr, "inflateEnd"); 373 return EIO; 374 } 375 376 return buf_shutdown (cb->buf); 377} 378 379/* Shut down an output buffer. */ 380 381static int 382compress_buffer_shutdown_output (buf) 383 struct buffer *buf; 384{ 385 struct compress_buffer *cb = (struct compress_buffer *) buf->closure; 386 int zstatus, status; 387 388 do 389 { 390 char buffer[BUFFER_DATA_SIZE]; 391 392 cb->zstr.avail_out = BUFFER_DATA_SIZE; 393 cb->zstr.next_out = (unsigned char *) buffer; 394 395 zstatus = deflate (&cb->zstr, Z_FINISH); 396 if (zstatus != Z_OK && zstatus != Z_STREAM_END) 397 { 398 compress_error (0, zstatus, &cb->zstr, "deflate finish"); 399 return EIO; 400 } 401 402 if (cb->zstr.avail_out != BUFFER_DATA_SIZE) 403 buf_output (cb->buf, buffer, 404 BUFFER_DATA_SIZE - cb->zstr.avail_out); 405 } while (zstatus != Z_STREAM_END); 406 407 zstatus = deflateEnd (&cb->zstr); 408 if (zstatus != Z_OK) 409 { 410 compress_error (0, zstatus, &cb->zstr, "deflateEnd"); 411 return EIO; 412 } 413 414 status = buf_flush (cb->buf, 1); 415 if (status != 0) 416 return status; 417 418 return buf_shutdown (cb->buf); 419} 420 421 422 423/* Here is our librarified gzip implementation. It is very minimal 424 but attempts to be RFC1952 compliant. */ 425 426/* GZIP ID byte values */ 427#define GZIP_ID1 31 428#define GZIP_ID2 139 429 430/* Compression methods */ 431#define GZIP_CDEFLATE 8 432 433/* Flags */ 434#define GZIP_FTEXT 1 435#define GZIP_FHCRC 2 436#define GZIP_FEXTRA 4 437#define GZIP_FNAME 8 438#define GZIP_FCOMMENT 16 439 440/* BUF should contain SIZE bytes of gzipped data (RFC1952/RFC1951). 441 We are to uncompress the data and write the result to the file 442 descriptor FD. If something goes wrong, give a nonfatal error message 443 mentioning FULLNAME as the name of the file for FD. Return 1 if 444 it is an error we can't recover from. */ 445 446int 447gunzip_and_write (fd, fullname, buf, size) 448 int fd; 449 char *fullname; 450 unsigned char *buf; 451 size_t size; 452{ 453 size_t pos; 454 z_stream zstr; 455 int zstatus; 456 unsigned char outbuf[32768]; 457 unsigned long crc; 458 459 if (size < 10) 460 { 461 error (0, 0, "gzipped data too small - lacks complete header"); 462 return 1; 463 } 464 if (buf[0] != GZIP_ID1 || buf[1] != GZIP_ID2) 465 { 466 error (0, 0, "gzipped data does not start with gzip identification"); 467 return 1; 468 } 469 if (buf[2] != GZIP_CDEFLATE) 470 { 471 error (0, 0, "only the deflate compression method is supported"); 472 return 1; 473 } 474 475 /* Skip over the fixed header, and then skip any of the variable-length 476 fields. As we skip each field, we keep pos <= size. The checks 477 on positions and lengths are really checks for malformed or 478 incomplete gzip data. */ 479 pos = 10; 480 if (buf[3] & GZIP_FEXTRA) 481 { 482 if (pos + 2 >= size) 483 { 484 error (0, 0, "%s lacks proper gzip XLEN field", fullname); 485 return 1; 486 } 487 pos += buf[pos] + (buf[pos + 1] << 8) + 2; 488 if (pos > size) 489 { 490 error (0, 0, "%s lacks proper gzip \"extra field\"", fullname); 491 return 1; 492 } 493 494 } 495 if (buf[3] & GZIP_FNAME) 496 { 497 unsigned char *p = memchr(buf + pos, '\0', size - pos); 498 if (p == NULL) 499 { 500 error (0, 0, "%s has bad gzip filename field", fullname); 501 return 1; 502 } 503 pos = p - buf + 1; 504 } 505 if (buf[3] & GZIP_FCOMMENT) 506 { 507 unsigned char *p = memchr(buf + pos, '\0', size - pos); 508 if (p == NULL) 509 { 510 error (0, 0, "%s has bad gzip comment field", fullname); 511 return 1; 512 } 513 pos = p - buf + 1; 514 } 515 if (buf[3] & GZIP_FHCRC) 516 { 517 pos += 2; 518 if (pos > size) 519 { 520 error (0, 0, "%s has bad gzip CRC16 field", fullname); 521 return 1; 522 } 523 } 524 525 /* There could be no data to decompress - check and short circuit. */ 526 if (pos >= size) 527 { 528 error (0, 0, "gzip data incomplete for %s (no data)", fullname); 529 return 1; 530 } 531 532 memset (&zstr, 0, sizeof zstr); 533 /* Passing a negative argument tells zlib not to look for a zlib 534 (RFC1950) header. This is an undocumented feature; I suppose if 535 we wanted to be anal we could synthesize a header instead, 536 but why bother? */ 537 zstatus = inflateInit2 (&zstr, -15); 538 539 if (zstatus != Z_OK) 540 compress_error (1, zstatus, &zstr, fullname); 541 542 /* I don't see why we should have to include the 8 byte trailer in 543 avail_in. But I see that zlib/gzio.c does, and it seemed to fix 544 a fairly rare bug in which we'd get a Z_BUF_ERROR for no obvious 545 reason. */ 546 zstr.avail_in = size - pos; 547 zstr.next_in = buf + pos; 548 549 crc = crc32 (0, NULL, 0); 550 551 do 552 { 553 zstr.avail_out = sizeof (outbuf); 554 zstr.next_out = outbuf; 555 zstatus = inflate (&zstr, Z_NO_FLUSH); 556 if (zstatus != Z_STREAM_END && zstatus != Z_OK) 557 { 558 compress_error (0, zstatus, &zstr, fullname); 559 return 1; 560 } 561 if (write (fd, outbuf, sizeof (outbuf) - zstr.avail_out) < 0) 562 { 563 error (0, errno, "writing decompressed file %s", fullname); 564 return 1; 565 } 566 crc = crc32 (crc, outbuf, sizeof (outbuf) - zstr.avail_out); 567 } while (zstatus != Z_STREAM_END); 568 zstatus = inflateEnd (&zstr); 569 if (zstatus != Z_OK) 570 compress_error (0, zstatus, &zstr, fullname); 571 572 /* Check that there is still 8 trailer bytes remaining (CRC32 573 and ISIZE). Check total decomp. data, plus header len (pos) 574 against input buffer total size. */ 575 pos += zstr.total_in; 576 if (size - pos != 8) 577 { 578 error (0, 0, "gzip data incomplete for %s (no trailer)", fullname); 579 return 1; 580 } 581 582 if (crc != ((unsigned long)buf[pos] 583 + ((unsigned long)buf[pos + 1] << 8) 584 + ((unsigned long)buf[pos + 2] << 16) 585 + ((unsigned long)buf[pos + 3] << 24))) 586 { 587 error (0, 0, "CRC error uncompressing %s", fullname); 588 return 1; 589 } 590 591 if (zstr.total_out != ((unsigned long)buf[pos + 4] 592 + ((unsigned long)buf[pos + 5] << 8) 593 + ((unsigned long)buf[pos + 6] << 16) 594 + ((unsigned long)buf[pos + 7] << 24))) 595 { 596 error (0, 0, "invalid length uncompressing %s", fullname); 597 return 1; 598 } 599 600 return 0; 601} 602 603/* Read all of FD and put the gzipped data (RFC1952/RFC1951) into *BUF, 604 replacing previous contents of *BUF. *BUF is xmalloc'd and *SIZE is 605 its allocated size. Put the actual number of bytes of data in 606 *LEN. If something goes wrong, give a nonfatal error mentioning 607 FULLNAME as the name of the file for FD, and return 1 if we can't 608 recover from it). LEVEL is the compression level (1-9). */ 609 610int 611read_and_gzip (fd, fullname, buf, size, len, level) 612 int fd; 613 const char *fullname; 614 unsigned char **buf; 615 size_t *size; 616 size_t *len; 617 int level; 618{ 619 z_stream zstr; 620 int zstatus; 621 unsigned char inbuf[8192]; 622 int nread; 623 unsigned long crc; 624 625 if (*size < 1024) 626 { 627 unsigned char *newbuf; 628 629 *size = 1024; 630 newbuf = xrealloc (*buf, *size); 631 if (newbuf == NULL) 632 { 633 error (0, 0, "out of memory"); 634 return 1; 635 } 636 *buf = newbuf; 637 } 638 (*buf)[0] = GZIP_ID1; 639 (*buf)[1] = GZIP_ID2; 640 (*buf)[2] = GZIP_CDEFLATE; 641 (*buf)[3] = 0; 642 (*buf)[4] = (*buf)[5] = (*buf)[6] = (*buf)[7] = 0; 643 /* Could set this based on level, but why bother? */ 644 (*buf)[8] = 0; 645 (*buf)[9] = 255; 646 647 memset (&zstr, 0, sizeof zstr); 648 zstatus = deflateInit2 (&zstr, level, Z_DEFLATED, -15, 8, 649 Z_DEFAULT_STRATEGY); 650 crc = crc32 (0, NULL, 0); 651 if (zstatus != Z_OK) 652 { 653 compress_error (0, zstatus, &zstr, fullname); 654 return 1; 655 } 656 657 /* Adjust for 10-byte output header (filled in above) */ 658 zstr.total_out = 10; 659 zstr.avail_out = *size - 10; 660 zstr.next_out = *buf + 10; 661 662 while (1) 663 { 664 int finish = 0; 665 666 nread = read (fd, inbuf, sizeof inbuf); 667 if (nread < 0) 668 { 669 error (0, errno, "cannot read %s", fullname); 670 return 1; 671 } 672 else if (nread == 0) 673 /* End of file. */ 674 finish = 1; 675 crc = crc32 (crc, inbuf, nread); 676 zstr.next_in = inbuf; 677 zstr.avail_in = nread; 678 679 do 680 { 681 /* I don't see this documented anywhere, but deflate seems 682 to tend to dump core sometimes if we pass it Z_FINISH and 683 a small (e.g. 2147 byte) avail_out. So we insist on at 684 least 4096 bytes (that is what zlib/gzio.c uses). */ 685 686 if (zstr.avail_out < 4096) 687 { 688 unsigned char *newbuf; 689 690 assert(zstr.avail_out + zstr.total_out == *size); 691 assert(zstr.next_out == *buf + zstr.total_out); 692 *size *= 2; 693 newbuf = xrealloc (*buf, *size); 694 if (newbuf == NULL) 695 { 696 error (0, 0, "out of memory"); 697 return 1; 698 } 699 *buf = newbuf; 700 zstr.next_out = *buf + zstr.total_out; 701 zstr.avail_out = *size - zstr.total_out; 702 assert(zstr.avail_out + zstr.total_out == *size); 703 assert(zstr.next_out == *buf + zstr.total_out); 704 } 705 706 zstatus = deflate (&zstr, finish ? Z_FINISH : 0); 707 if (zstatus == Z_STREAM_END) 708 goto done; 709 else if (zstatus != Z_OK) 710 compress_error (0, zstatus, &zstr, fullname); 711 } while (zstr.avail_out == 0); 712 } 713 done: 714 /* Need to add the CRC information (8 bytes) 715 to the end of the gzip'd output. 716 Ensure there is enough space in the output buffer 717 to do so. */ 718 if (zstr.avail_out < 8) 719 { 720 unsigned char *newbuf; 721 722 assert(zstr.avail_out + zstr.total_out == *size); 723 assert(zstr.next_out == *buf + zstr.total_out); 724 *size += 8 - zstr.avail_out; 725 newbuf = realloc (*buf, *size); 726 if (newbuf == NULL) 727 { 728 error (0, 0, "out of memory"); 729 return 1; 730 } 731 *buf = newbuf; 732 zstr.next_out = *buf + zstr.total_out; 733 zstr.avail_out = *size - zstr.total_out; 734 assert(zstr.avail_out + zstr.total_out == *size); 735 assert(zstr.next_out == *buf + zstr.total_out); 736 } 737 *zstr.next_out++ = (unsigned char)(crc & 0xff); 738 *zstr.next_out++ = (unsigned char)((crc >> 8) & 0xff); 739 *zstr.next_out++ = (unsigned char)((crc >> 16) & 0xff); 740 *zstr.next_out++ = (unsigned char)((crc >> 24) & 0xff); 741 742 *zstr.next_out++ = (unsigned char)(zstr.total_in & 0xff); 743 *zstr.next_out++ = (unsigned char)((zstr.total_in >> 8) & 0xff); 744 *zstr.next_out++ = (unsigned char)((zstr.total_in >> 16) & 0xff); 745 *zstr.next_out++ = (unsigned char)((zstr.total_in >> 24) & 0xff); 746 747 zstr.total_out += 8; 748 zstr.avail_out -= 8; 749 assert(zstr.avail_out + zstr.total_out == *size); 750 assert(zstr.next_out == *buf + zstr.total_out); 751 752 *len = zstr.total_out; 753 754 zstatus = deflateEnd (&zstr); 755 if (zstatus != Z_OK) 756 compress_error (0, zstatus, &zstr, fullname); 757 758 return 0; 759} 760#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ 761