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