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