]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/cvs/src/zlib.c
This commit was generated by cvs2svn to compensate for changes in r173932,
[FreeBSD/FreeBSD.git] / contrib / cvs / 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 <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
41 struct compress_buffer
42 {
43     /* The underlying buffer.  */
44     struct buffer *buf;
45     /* The compression information.  */
46     z_stream zstr;
47 };
48
49 static void compress_error PROTO((int, int, z_stream *, const char *));
50 static int compress_buffer_input PROTO((void *, char *, int, int, int *));
51 static int compress_buffer_output PROTO((void *, const char *, int, int *));
52 static int compress_buffer_flush PROTO((void *));
53 static int compress_buffer_block PROTO((void *, int));
54 static int compress_buffer_shutdown_input PROTO((struct buffer *));
55 static int compress_buffer_shutdown_output PROTO((struct buffer *));
56
57 /* Report an error from one of the zlib functions.  */
58
59 static void
60 compress_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
86 struct buffer *
87 compress_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
131 static int
132 compress_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
250 static int
251 compress_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
292 static int
293 compress_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
342 static int
343 compress_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
357 static int
358 compress_buffer_shutdown_input (buf)
359      struct buffer *buf;
360 {
361     struct compress_buffer *cb = (struct compress_buffer *) buf->closure;
362     int zstatus;
363
364     /* Pick up any trailing data, such as the checksum.  */
365     while (1)
366     {
367         int status, nread;
368         char buf[100];
369
370         status = compress_buffer_input (cb, buf, 0, sizeof buf, &nread);
371         if (status == -1)
372             break;
373         if (status != 0)
374             return status;
375     }
376
377     zstatus = inflateEnd (&cb->zstr);
378     if (zstatus != Z_OK)
379     {
380         compress_error (0, zstatus, &cb->zstr, "inflateEnd");
381         return EIO;
382     }
383
384     return buf_shutdown (cb->buf);
385 }
386
387 /* Shut down an output buffer.  */
388
389 static int
390 compress_buffer_shutdown_output (buf)
391      struct buffer *buf;
392 {
393     struct compress_buffer *cb = (struct compress_buffer *) buf->closure;
394     int zstatus, status;
395
396     do
397     {
398         char buffer[BUFFER_DATA_SIZE];
399
400         cb->zstr.avail_out = BUFFER_DATA_SIZE;
401         cb->zstr.next_out = (unsigned char *) buffer;
402
403         zstatus = deflate (&cb->zstr, Z_FINISH);
404         if (zstatus != Z_OK && zstatus != Z_STREAM_END)
405         {
406             compress_error (0, zstatus, &cb->zstr, "deflate finish");
407             return EIO;
408         }
409
410         if (cb->zstr.avail_out != BUFFER_DATA_SIZE)
411             buf_output (cb->buf, buffer,
412                         BUFFER_DATA_SIZE - cb->zstr.avail_out);
413     } while (zstatus != Z_STREAM_END);
414
415     zstatus = deflateEnd (&cb->zstr);
416     if (zstatus != Z_OK)
417     {
418         compress_error (0, zstatus, &cb->zstr, "deflateEnd");
419         return EIO;
420     }
421
422     status = buf_flush (cb->buf, 1);
423     if (status != 0)
424         return status;
425
426     return buf_shutdown (cb->buf);
427 }
428
429
430
431 /* Here is our librarified gzip implementation.  It is very minimal
432    but attempts to be RFC1952 compliant.  */
433
434 /* GZIP ID byte values */
435 #define GZIP_ID1        31
436 #define GZIP_ID2        139
437
438 /* Compression methods */
439 #define GZIP_CDEFLATE   8
440
441 /* Flags */
442 #define GZIP_FTEXT      1
443 #define GZIP_FHCRC      2
444 #define GZIP_FEXTRA     4
445 #define GZIP_FNAME      8
446 #define GZIP_FCOMMENT   16
447
448 /* BUF should contain SIZE bytes of gzipped data (RFC1952/RFC1951).
449    We are to uncompress the data and write the result to the file
450    descriptor FD.  If something goes wrong, give a nonfatal error message
451    mentioning FULLNAME as the name of the file for FD.  Return 1 if
452    it is an error we can't recover from.  */
453
454 int
455 gunzip_and_write (fd, fullname, buf, size)
456     int fd;
457     char *fullname;
458     unsigned char *buf;
459     size_t size;
460 {
461     size_t pos;
462     z_stream zstr;
463     int zstatus;
464     unsigned char outbuf[32768];
465     unsigned long crc;
466
467     if (size < 10)
468     {
469         error (0, 0, "gzipped data too small - lacks complete header");
470         return 1;
471     }
472     if (buf[0] != GZIP_ID1 || buf[1] != GZIP_ID2)
473     {
474         error (0, 0, "gzipped data does not start with gzip identification");
475         return 1;
476     }
477     if (buf[2] != GZIP_CDEFLATE)
478     {
479         error (0, 0, "only the deflate compression method is supported");
480         return 1;
481     }
482
483     /* Skip over the fixed header, and then skip any of the variable-length
484        fields.  As we skip each field, we keep pos <= size. The checks
485        on positions and lengths are really checks for malformed or 
486        incomplete gzip data.  */
487     pos = 10;
488     if (buf[3] & GZIP_FEXTRA)
489     {
490         if (pos + 2 >= size) 
491         {
492             error (0, 0, "%s lacks proper gzip XLEN field", fullname);
493             return 1;
494         }
495         pos += buf[pos] + (buf[pos + 1] << 8) + 2;
496         if (pos > size) 
497         {
498             error (0, 0, "%s lacks proper gzip \"extra field\"", fullname);
499             return 1;
500         }
501
502     }
503     if (buf[3] & GZIP_FNAME)
504     {
505         unsigned char *p = memchr(buf + pos, '\0', size - pos);
506         if (p == NULL)
507         {
508             error (0, 0, "%s has bad gzip filename field", fullname);
509             return 1;
510         }
511         pos = p - buf + 1;
512     }
513     if (buf[3] & GZIP_FCOMMENT)
514     {
515         unsigned char *p = memchr(buf + pos, '\0', size - pos);
516         if (p == NULL)
517         {
518             error (0, 0, "%s has bad gzip comment field", fullname);
519             return 1;
520         }
521         pos = p - buf + 1;
522     }
523     if (buf[3] & GZIP_FHCRC)
524     {
525         pos += 2;
526         if (pos > size) 
527         {
528             error (0, 0, "%s has bad gzip CRC16 field", fullname);
529             return 1;
530         }
531     }
532
533     /* There could be no data to decompress - check and short circuit.  */
534     if (pos >= size)
535     {
536         error (0, 0, "gzip data incomplete for %s (no data)", fullname);
537         return 1;
538     }
539
540     memset (&zstr, 0, sizeof zstr);
541     /* Passing a negative argument tells zlib not to look for a zlib
542        (RFC1950) header.  This is an undocumented feature; I suppose if
543        we wanted to be anal we could synthesize a header instead,
544        but why bother?  */
545     zstatus = inflateInit2 (&zstr, -15);
546
547     if (zstatus != Z_OK)
548         compress_error (1, zstatus, &zstr, fullname);
549
550     /* I don't see why we should have to include the 8 byte trailer in
551        avail_in.  But I see that zlib/gzio.c does, and it seemed to fix
552        a fairly rare bug in which we'd get a Z_BUF_ERROR for no obvious
553        reason.  */
554     zstr.avail_in = size - pos;
555     zstr.next_in = buf + pos;
556
557     crc = crc32 (0, NULL, 0);
558
559     do
560     {
561         zstr.avail_out = sizeof (outbuf);
562         zstr.next_out = outbuf;
563         zstatus = inflate (&zstr, Z_NO_FLUSH);
564         if (zstatus != Z_STREAM_END && zstatus != Z_OK)
565         {
566             compress_error (0, zstatus, &zstr, fullname);
567             return 1;
568         }
569         if (write (fd, outbuf, sizeof (outbuf) - zstr.avail_out) < 0)
570         {
571             error (0, errno, "writing decompressed file %s", fullname);
572             return 1;
573         }
574         crc = crc32 (crc, outbuf, sizeof (outbuf) - zstr.avail_out);
575     } while (zstatus != Z_STREAM_END);
576     zstatus = inflateEnd (&zstr);
577     if (zstatus != Z_OK)
578         compress_error (0, zstatus, &zstr, fullname);
579
580     /* Check that there is still 8 trailer bytes remaining (CRC32
581        and ISIZE).  Check total decomp. data, plus header len (pos)
582        against input buffer total size.  */
583     pos += zstr.total_in;
584     if (size - pos != 8)
585     {
586         error (0, 0, "gzip data incomplete for %s (no trailer)", fullname);
587         return 1;
588     }
589
590     if (crc != ((unsigned long)buf[pos]
591                 + ((unsigned long)buf[pos + 1] << 8)
592                 + ((unsigned long)buf[pos + 2] << 16)
593                 + ((unsigned long)buf[pos + 3] << 24)))
594     {
595         error (0, 0, "CRC error uncompressing %s", fullname);
596         return 1;
597     }
598
599     if (zstr.total_out != ((unsigned long)buf[pos + 4]
600                            + ((unsigned long)buf[pos + 5] << 8)
601                            + ((unsigned long)buf[pos + 6] << 16)
602                            + ((unsigned long)buf[pos + 7] << 24)))
603     {
604         error (0, 0, "invalid length uncompressing %s", fullname);
605         return 1;
606     }
607
608     return 0;
609 }
610
611 /* Read all of FD and put the gzipped data (RFC1952/RFC1951) into *BUF,
612    replacing previous contents of *BUF.  *BUF is xmalloc'd and *SIZE is
613    its allocated size.  Put the actual number of bytes of data in
614    *LEN.  If something goes wrong, give a nonfatal error mentioning
615    FULLNAME as the name of the file for FD, and return 1 if we can't
616    recover from it).  LEVEL is the compression level (1-9).  */
617
618 int
619 read_and_gzip (fd, fullname, buf, size, len, level)
620     int fd;
621     const char *fullname;
622     unsigned char **buf;
623     size_t *size;
624     size_t *len;
625     int level;
626 {
627     z_stream zstr;
628     int zstatus;
629     unsigned char inbuf[8192];
630     int nread;
631     unsigned long crc;
632
633     if (*size < 1024)
634     {
635         unsigned char *newbuf;
636
637         *size = 1024;
638         newbuf = xrealloc (*buf, *size);
639         if (newbuf == NULL)
640         {
641             error (0, 0, "out of memory");
642             return 1;
643         }
644         *buf = newbuf;
645     }
646     (*buf)[0] = GZIP_ID1;
647     (*buf)[1] = GZIP_ID2;
648     (*buf)[2] = GZIP_CDEFLATE;
649     (*buf)[3] = 0;
650     (*buf)[4] = (*buf)[5] = (*buf)[6] = (*buf)[7] = 0;
651     /* Could set this based on level, but why bother?  */
652     (*buf)[8] = 0;
653     (*buf)[9] = 255;
654
655     memset (&zstr, 0, sizeof zstr);
656     zstatus = deflateInit2 (&zstr, level, Z_DEFLATED, -15, 8,
657                             Z_DEFAULT_STRATEGY);
658     crc = crc32 (0, NULL, 0);
659     if (zstatus != Z_OK)
660     {
661         compress_error (0, zstatus, &zstr, fullname);
662         return 1;
663     }
664     
665     /* Adjust for 10-byte output header (filled in above) */
666     zstr.total_out = 10;
667     zstr.avail_out = *size - 10;
668     zstr.next_out = *buf + 10;
669
670     while (1)
671     {
672         int finish = 0;
673
674         nread = read (fd, inbuf, sizeof inbuf);
675         if (nread < 0)
676         {
677             error (0, errno, "cannot read %s", fullname);
678             return 1;
679         }
680         else if (nread == 0)
681             /* End of file.  */
682             finish = 1;
683         crc = crc32 (crc, inbuf, nread);
684         zstr.next_in = inbuf;
685         zstr.avail_in = nread;
686
687         do
688         {
689             /* I don't see this documented anywhere, but deflate seems
690                to tend to dump core sometimes if we pass it Z_FINISH and
691                a small (e.g. 2147 byte) avail_out.  So we insist on at
692                least 4096 bytes (that is what zlib/gzio.c uses).  */
693
694             if (zstr.avail_out < 4096)
695             {
696                 unsigned char *newbuf;
697
698                 assert(zstr.avail_out + zstr.total_out == *size);
699                 assert(zstr.next_out == *buf + zstr.total_out);
700                 *size *= 2;
701                 newbuf = xrealloc (*buf, *size);
702                 if (newbuf == NULL)
703                 {
704                     error (0, 0, "out of memory");
705                     return 1;
706                 }
707                 *buf = newbuf;
708                 zstr.next_out = *buf + zstr.total_out;
709                 zstr.avail_out = *size - zstr.total_out;
710                 assert(zstr.avail_out + zstr.total_out == *size);
711                 assert(zstr.next_out == *buf + zstr.total_out);
712             }
713
714             zstatus = deflate (&zstr, finish ? Z_FINISH : 0);
715             if (zstatus == Z_STREAM_END)
716                 goto done;
717             else if (zstatus != Z_OK)
718                 compress_error (0, zstatus, &zstr, fullname);
719         } while (zstr.avail_out == 0);
720     }
721  done:
722     /* Need to add the CRC information (8 bytes)
723        to the end of the gzip'd output.
724        Ensure there is enough space in the output buffer
725        to do so.  */
726     if (zstr.avail_out < 8)
727     {
728         unsigned char *newbuf;
729
730         assert(zstr.avail_out + zstr.total_out == *size);
731         assert(zstr.next_out == *buf + zstr.total_out);
732         *size += 8 - zstr.avail_out;
733         newbuf = realloc (*buf, *size);
734         if (newbuf == NULL)
735         {
736             error (0, 0, "out of memory");
737             return 1;
738         }
739         *buf = newbuf;
740         zstr.next_out = *buf + zstr.total_out;
741         zstr.avail_out = *size - zstr.total_out;
742         assert(zstr.avail_out + zstr.total_out == *size);
743         assert(zstr.next_out == *buf + zstr.total_out);
744     } 
745     *zstr.next_out++ = (unsigned char)(crc & 0xff);
746     *zstr.next_out++ = (unsigned char)((crc >> 8) & 0xff);
747     *zstr.next_out++ = (unsigned char)((crc >> 16) & 0xff);
748     *zstr.next_out++ = (unsigned char)((crc >> 24) & 0xff);
749
750     *zstr.next_out++ = (unsigned char)(zstr.total_in & 0xff);
751     *zstr.next_out++ = (unsigned char)((zstr.total_in >> 8) & 0xff);
752     *zstr.next_out++ = (unsigned char)((zstr.total_in >> 16) & 0xff);
753     *zstr.next_out++ = (unsigned char)((zstr.total_in >> 24) & 0xff);
754
755     zstr.total_out += 8;
756     zstr.avail_out -= 8;
757     assert(zstr.avail_out + zstr.total_out == *size);
758     assert(zstr.next_out == *buf + zstr.total_out);
759
760     *len = zstr.total_out;
761
762     zstatus = deflateEnd (&zstr);
763     if (zstatus != Z_OK)
764         compress_error (0, zstatus, &zstr, fullname);
765
766     return 0;
767 }
768 #endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */