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