67c6c16b71ea35dd6cc918693f2f3ab95237b59d
[ppp.git] / modules / deflate.c
1 /*
2  * ppp_deflate.c - interface the zlib procedures for Deflate compression
3  * and decompression (as used by gzip) to the PPP code.
4  * This version is for use with STREAMS under SunOS 4.x, Solaris 2,
5  * SVR4, OSF/1 and AIX 4.x.
6  *
7  * Copyright (c) 1994 The Australian National University.
8  * All rights reserved.
9  *
10  * Permission to use, copy, modify, and distribute this software and its
11  * documentation is hereby granted, provided that the above copyright
12  * notice appears in all copies.  This software is provided without any
13  * warranty, express or implied. The Australian National University
14  * makes no representations about the suitability of this software for
15  * any purpose.
16  *
17  * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
18  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
19  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
20  * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
21  * OF SUCH DAMAGE.
22  *
23  * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
24  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
26  * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
27  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
28  * OR MODIFICATIONS.
29  *
30  * $Id: deflate.c,v 1.6 1997/11/27 06:05:17 paulus Exp $
31  */
32
33 #ifdef AIX4
34 #include <net/net_globals.h>
35 #endif
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/stream.h>
39 #include <net/ppp_defs.h>
40 #include "ppp_mod.h"
41
42 #define PACKETPTR       mblk_t *
43 #include <net/ppp-comp.h>
44
45 #ifdef __osf__
46 #include "zlib.h"
47 #else
48 #include "common/zlib.h"
49 #endif
50
51 #if DO_DEFLATE
52
53 #define DEFLATE_DEBUG   1
54
55 /*
56  * State for a Deflate (de)compressor.
57  */
58 struct deflate_state {
59     int         seqno;
60     int         w_size;
61     int         unit;
62     int         hdrlen;
63     int         mru;
64     int         debug;
65     z_stream    strm;
66     struct compstat stats;
67 };
68
69 #define DEFLATE_OVHD    2               /* Deflate overhead/packet */
70
71 static void     *z_alloc __P((void *, u_int items, u_int size));
72 static void     *z_alloc_init __P((void *, u_int items, u_int size));
73 static void     z_free __P((void *, void *ptr));
74 static void     *z_comp_alloc __P((u_char *options, int opt_len));
75 static void     *z_decomp_alloc __P((u_char *options, int opt_len));
76 static void     z_comp_free __P((void *state));
77 static void     z_decomp_free __P((void *state));
78 static int      z_comp_init __P((void *state, u_char *options, int opt_len,
79                                  int unit, int hdrlen, int debug));
80 static int      z_decomp_init __P((void *state, u_char *options, int opt_len,
81                                      int unit, int hdrlen, int mru, int debug));
82 static int      z_compress __P((void *state, mblk_t **mret,
83                                   mblk_t *mp, int slen, int maxolen));
84 static void     z_incomp __P((void *state, mblk_t *dmsg));
85 static int      z_decompress __P((void *state, mblk_t *cmp,
86                                     mblk_t **dmpp));
87 static void     z_comp_reset __P((void *state));
88 static void     z_decomp_reset __P((void *state));
89 static void     z_comp_stats __P((void *state, struct compstat *stats));
90
91 /*
92  * Procedures exported to if_ppp.c.
93  */
94 struct compressor ppp_deflate = {
95     CI_DEFLATE,                 /* compress_proto */
96     z_comp_alloc,               /* comp_alloc */
97     z_comp_free,                /* comp_free */
98     z_comp_init,                /* comp_init */
99     z_comp_reset,               /* comp_reset */
100     z_compress,                 /* compress */
101     z_comp_stats,               /* comp_stat */
102     z_decomp_alloc,             /* decomp_alloc */
103     z_decomp_free,              /* decomp_free */
104     z_decomp_init,              /* decomp_init */
105     z_decomp_reset,             /* decomp_reset */
106     z_decompress,               /* decompress */
107     z_incomp,                   /* incomp */
108     z_comp_stats,               /* decomp_stat */
109 };
110
111 #define DECOMP_CHUNK    512
112
113 /*
114  * Space allocation and freeing routines for use by zlib routines.
115  */
116 struct zchunk {
117     u_int       size;
118     u_int       guard;
119 };
120
121 #define GUARD_MAGIC     0x77a6011a
122
123 static void *
124 z_alloc_init(notused, items, size)
125     void *notused;
126     u_int items, size;
127 {
128     struct zchunk *z;
129
130     size = items * size + sizeof(struct zchunk);
131 #ifdef __osf__
132     z = (struct zchunk *) ALLOC_SLEEP(size);
133 #else
134     z = (struct zchunk *) ALLOC_NOSLEEP(size);
135 #endif
136     z->size = size;
137     z->guard = GUARD_MAGIC;
138     return (void *) (z + 1);
139 }
140
141 static void *
142 z_alloc(notused, items, size)
143     void *notused;
144     u_int items, size;
145 {
146     struct zchunk *z;
147
148     size = items * size + sizeof(struct zchunk);
149     z = (struct zchunk *) ALLOC_NOSLEEP(size);
150     z->size = size;
151     z->guard = GUARD_MAGIC;
152     return (void *) (z + 1);
153 }
154
155 static void
156 z_free(notused, ptr)
157     void *notused;
158     void *ptr;
159 {
160     struct zchunk *z = ((struct zchunk *) ptr) - 1;
161
162     if (z->guard != GUARD_MAGIC) {
163         printf("ppp: z_free of corrupted chunk at %x (%x, %x)\n",
164                z, z->size, z->guard);
165         return;
166     }
167     FREE(z, z->size);
168 }
169
170 /*
171  * Allocate space for a compressor.
172  */
173 static void *
174 z_comp_alloc(options, opt_len)
175     u_char *options;
176     int opt_len;
177 {
178     struct deflate_state *state;
179     int w_size;
180
181     if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE
182         || options[1] != CILEN_DEFLATE
183         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
184         || options[3] != DEFLATE_CHK_SEQUENCE)
185         return NULL;
186     w_size = DEFLATE_SIZE(options[2]);
187     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
188         return NULL;
189
190
191 #ifdef __osf__
192     state = (struct deflate_state *) ALLOC_SLEEP(sizeof(*state));
193 #else
194     state = (struct deflate_state *) ALLOC_NOSLEEP(sizeof(*state));
195 #endif
196
197     if (state == NULL)
198         return NULL;
199
200     state->strm.next_in = NULL;
201     state->strm.zalloc = (alloc_func) z_alloc_init;
202     state->strm.zfree = (free_func) z_free;
203     if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
204                      -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
205         FREE(state, sizeof(*state));
206         return NULL;
207     }
208
209     state->strm.zalloc = (alloc_func) z_alloc;
210     state->w_size = w_size;
211     bzero(&state->stats, sizeof(state->stats));
212     return (void *) state;
213 }
214
215 static void
216 z_comp_free(arg)
217     void *arg;
218 {
219     struct deflate_state *state = (struct deflate_state *) arg;
220
221     deflateEnd(&state->strm);
222     FREE(state, sizeof(*state));
223 }
224
225 static int
226 z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
227     void *arg;
228     u_char *options;
229     int opt_len, unit, hdrlen, debug;
230 {
231     struct deflate_state *state = (struct deflate_state *) arg;
232
233     if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE
234         || options[1] != CILEN_DEFLATE
235         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
236         || DEFLATE_SIZE(options[2]) != state->w_size
237         || options[3] != DEFLATE_CHK_SEQUENCE)
238         return 0;
239
240     state->seqno = 0;
241     state->unit = unit;
242     state->hdrlen = hdrlen;
243     state->debug = debug;
244
245     deflateReset(&state->strm);
246
247     return 1;
248 }
249
250 static void
251 z_comp_reset(arg)
252     void *arg;
253 {
254     struct deflate_state *state = (struct deflate_state *) arg;
255
256     state->seqno = 0;
257     deflateReset(&state->strm);
258 }
259
260 static int
261 z_compress(arg, mret, mp, orig_len, maxolen)
262     void *arg;
263     mblk_t **mret;              /* compressed packet (out) */
264     mblk_t *mp;         /* uncompressed packet (in) */
265     int orig_len, maxolen;
266 {
267     struct deflate_state *state = (struct deflate_state *) arg;
268     u_char *rptr, *wptr;
269     int proto, olen, wspace, r, flush;
270     mblk_t *m;
271
272     /*
273      * Check that the protocol is in the range we handle.
274      */
275     *mret = NULL;
276     rptr = mp->b_rptr;
277     if (rptr + PPP_HDRLEN > mp->b_wptr) {
278         if (!pullupmsg(mp, PPP_HDRLEN))
279             return 0;
280         rptr = mp->b_rptr;
281     }
282     proto = PPP_PROTOCOL(rptr);
283     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
284         return orig_len;
285
286     /* Allocate one mblk initially. */
287     if (maxolen > orig_len)
288         maxolen = orig_len;
289     wspace = maxolen < 4096? maxolen: 4096;
290     m = allocb(wspace, BPRI_MED);
291     if (m != NULL) {
292         *mret = m;
293         if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
294             m->b_rptr += state->hdrlen;
295             m->b_wptr = m->b_rptr;
296             wspace -= state->hdrlen;
297         }
298         wptr = m->b_wptr;
299
300         /*
301          * Copy over the PPP header and store the 2-byte sequence number.
302          */
303         wptr[0] = PPP_ADDRESS(rptr);
304         wptr[1] = PPP_CONTROL(rptr);
305         wptr[2] = PPP_COMP >> 8;
306         wptr[3] = PPP_COMP;
307         wptr += PPP_HDRLEN;
308         wptr[0] = state->seqno >> 8;
309         wptr[1] = state->seqno;
310         wptr += 2;
311         state->strm.next_out = wptr;
312         state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
313     } else {
314         state->strm.next_out = NULL;
315         state->strm.avail_out = 1000000;
316     }
317     ++state->seqno;
318
319     rptr += (proto > 0xff)? 2: 3;       /* skip 1st proto byte if 0 */
320     state->strm.next_in = rptr;
321     state->strm.avail_in = mp->b_wptr - rptr;
322     mp = mp->b_cont;
323     flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
324     olen = 0;
325     for (;;) {
326         r = deflate(&state->strm, flush);
327         if (r != Z_OK) {
328             printf("z_compress: deflate returned %d (%s)\n",
329                    r, (state->strm.msg? state->strm.msg: ""));
330             break;
331         }
332         if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
333             break;              /* all done */
334         if (state->strm.avail_in == 0 && mp != NULL) {
335             state->strm.next_in = mp->b_rptr;
336             state->strm.avail_in = mp->b_wptr - mp->b_rptr;
337             mp = mp->b_cont;
338             if (mp == NULL)
339                 flush = Z_PACKET_FLUSH;
340         }
341         if (state->strm.avail_out == 0) {
342             if (m != NULL) {
343                 m->b_wptr += wspace;
344                 olen += wspace;
345                 wspace = maxolen - olen;
346                 if (wspace < 32)
347                     wspace = 32;
348                 else if (wspace > 4096)
349                     wspace = 4096;
350                 m->b_cont = allocb(wspace, BPRI_MED);
351                 m = m->b_cont;
352                 if (m != NULL) {
353                     state->strm.next_out = m->b_wptr;
354                     state->strm.avail_out = wspace;
355                 }
356             }
357             if (m == NULL) {
358                 state->strm.next_out = NULL;
359                 state->strm.avail_out = 1000000;
360             }
361         }
362     }
363     m->b_wptr += wspace - state->strm.avail_out;
364     olen += wspace - state->strm.avail_out;
365
366     /*
367      * See if we managed to reduce the size of the packet.
368      */
369     if (olen < orig_len && m != NULL) {
370         state->stats.comp_bytes += olen;
371         state->stats.comp_packets++;
372     } else {
373         if (*mret != NULL) {
374             freemsg(*mret);
375             *mret = NULL;
376         }
377         state->stats.inc_bytes += orig_len;
378         state->stats.inc_packets++;
379         olen = orig_len;
380     }
381     state->stats.unc_bytes += orig_len;
382     state->stats.unc_packets++;
383
384     return olen;
385 }
386
387 static void
388 z_comp_stats(arg, stats)
389     void *arg;
390     struct compstat *stats;
391 {
392     struct deflate_state *state = (struct deflate_state *) arg;
393     u_int out;
394
395     *stats = state->stats;
396     stats->ratio = stats->unc_bytes;
397     out = stats->comp_bytes + stats->unc_bytes;
398     if (stats->ratio <= 0x7ffffff)
399         stats->ratio <<= 8;
400     else
401         out >>= 8;
402     if (out != 0)
403         stats->ratio /= out;
404 }
405
406 /*
407  * Allocate space for a decompressor.
408  */
409 static void *
410 z_decomp_alloc(options, opt_len)
411     u_char *options;
412     int opt_len;
413 {
414     struct deflate_state *state;
415     int w_size;
416
417     if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE
418         || options[1] != CILEN_DEFLATE
419         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
420         || options[3] != DEFLATE_CHK_SEQUENCE)
421         return NULL;
422     w_size = DEFLATE_SIZE(options[2]);
423     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
424         return NULL;
425
426 #ifdef __osf__
427     state = (struct deflate_state *) ALLOC_SLEEP(sizeof(*state));
428 #else
429     state = (struct deflate_state *) ALLOC_NOSLEEP(sizeof(*state));
430 #endif
431     if (state == NULL)
432         return NULL;
433
434     state->strm.next_out = NULL;
435     state->strm.zalloc = (alloc_func) z_alloc_init;
436     state->strm.zfree = (free_func) z_free;
437     if (inflateInit2(&state->strm, -w_size) != Z_OK) {
438         FREE(state, sizeof(*state));
439         return NULL;
440     }
441
442     state->strm.zalloc = (alloc_func) z_alloc;
443     state->w_size = w_size;
444     bzero(&state->stats, sizeof(state->stats));
445     return (void *) state;
446 }
447
448 static void
449 z_decomp_free(arg)
450     void *arg;
451 {
452     struct deflate_state *state = (struct deflate_state *) arg;
453
454     inflateEnd(&state->strm);
455     FREE(state, sizeof(*state));
456 }
457
458 static int
459 z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
460     void *arg;
461     u_char *options;
462     int opt_len, unit, hdrlen, mru, debug;
463 {
464     struct deflate_state *state = (struct deflate_state *) arg;
465
466     if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE
467         || options[1] != CILEN_DEFLATE
468         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
469         || DEFLATE_SIZE(options[2]) != state->w_size
470         || options[3] != DEFLATE_CHK_SEQUENCE)
471         return 0;
472
473     state->seqno = 0;
474     state->unit = unit;
475     state->hdrlen = hdrlen;
476     state->debug = debug;
477     state->mru = mru;
478
479     inflateReset(&state->strm);
480
481     return 1;
482 }
483
484 static void
485 z_decomp_reset(arg)
486     void *arg;
487 {
488     struct deflate_state *state = (struct deflate_state *) arg;
489
490     state->seqno = 0;
491     inflateReset(&state->strm);
492 }
493
494 /*
495  * Decompress a Deflate-compressed packet.
496  *
497  * Because of patent problems, we return DECOMP_ERROR for errors
498  * found by inspecting the input data and for system problems, but
499  * DECOMP_FATALERROR for any errors which could possibly be said to
500  * be being detected "after" decompression.  For DECOMP_ERROR,
501  * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
502  * infringing a patent of Motorola's if we do, so we take CCP down
503  * instead.
504  *
505  * Given that the frame has the correct sequence number and a good FCS,
506  * errors such as invalid codes in the input most likely indicate a
507  * bug, so we return DECOMP_FATALERROR for them in order to turn off
508  * compression, even though they are detected by inspecting the input.
509  */
510 static int
511 z_decompress(arg, mi, mop)
512     void *arg;
513     mblk_t *mi, **mop;
514 {
515     struct deflate_state *state = (struct deflate_state *) arg;
516     mblk_t *mo, *mo_head;
517     u_char *rptr, *wptr;
518     int rlen, olen, ospace;
519     int seq, i, flush, r, decode_proto;
520     u_char hdr[PPP_HDRLEN + DEFLATE_OVHD];
521
522     *mop = NULL;
523     rptr = mi->b_rptr;
524     for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) {
525         while (rptr >= mi->b_wptr) {
526             mi = mi->b_cont;
527             if (mi == NULL)
528                 return DECOMP_ERROR;
529             rptr = mi->b_rptr;
530         }
531         hdr[i] = *rptr++;
532     }
533
534     /* Check the sequence number. */
535     seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1];
536     if (seq != state->seqno) {
537 #if !DEFLATE_DEBUG
538         if (state->debug)
539 #endif
540             printf("z_decompress%d: bad seq # %d, expected %d\n",
541                    state->unit, seq, state->seqno);
542         return DECOMP_ERROR;
543     }
544     ++state->seqno;
545
546     /* Allocate an output message block. */
547     mo = allocb(DECOMP_CHUNK + state->hdrlen, BPRI_MED);
548     if (mo == NULL)
549         return DECOMP_ERROR;
550     mo_head = mo;
551     mo->b_cont = NULL;
552     mo->b_rptr += state->hdrlen;
553     mo->b_wptr = wptr = mo->b_rptr;
554     ospace = DECOMP_CHUNK;
555
556     /*
557      * Fill in the first part of the PPP header.  The protocol field
558      * comes from the decompressed data.
559      */
560     wptr[0] = PPP_ADDRESS(hdr);
561     wptr[1] = PPP_CONTROL(hdr);
562     wptr[2] = 0;
563
564     /*
565      * Set up to call inflate.  We set avail_out to 1 initially so we can
566      * look at the first byte of the output and decide whether we have
567      * a 1-byte or 2-byte protocol field.
568      */
569     state->strm.next_in = rptr;
570     state->strm.avail_in = mi->b_wptr - rptr;
571     mi = mi->b_cont;
572     flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
573     rlen = state->strm.avail_in + PPP_HDRLEN + DEFLATE_OVHD;
574     state->strm.next_out = wptr + 3;
575     state->strm.avail_out = 1;
576     decode_proto = 1;
577     olen = PPP_HDRLEN;
578
579     /*
580      * Call inflate, supplying more input or output as needed.
581      */
582     for (;;) {
583         r = inflate(&state->strm, flush);
584         if (r != Z_OK) {
585 #if !DEFLATE_DEBUG
586             if (state->debug)
587 #endif
588                 printf("z_decompress%d: inflate returned %d (%s)\n",
589                        state->unit, r, (state->strm.msg? state->strm.msg: ""));
590             freemsg(mo_head);
591             return DECOMP_FATALERROR;
592         }
593         if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
594             break;              /* all done */
595         if (state->strm.avail_in == 0 && mi != NULL) {
596             state->strm.next_in = mi->b_rptr;
597             state->strm.avail_in = mi->b_wptr - mi->b_rptr;
598             rlen += state->strm.avail_in;
599             mi = mi->b_cont;
600             if (mi == NULL)
601                 flush = Z_PACKET_FLUSH;
602         }
603         if (state->strm.avail_out == 0) {
604             if (decode_proto) {
605                 state->strm.avail_out = ospace - PPP_HDRLEN;
606                 if ((wptr[3] & 1) == 0) {
607                     /* 2-byte protocol field */
608                     wptr[2] = wptr[3];
609                     --state->strm.next_out;
610                     ++state->strm.avail_out;
611                     --olen;
612                 }
613                 decode_proto = 0;
614             } else {
615                 mo->b_wptr += ospace;
616                 olen += ospace;
617                 mo->b_cont = allocb(DECOMP_CHUNK, BPRI_MED);
618                 mo = mo->b_cont;
619                 if (mo == NULL) {
620                     freemsg(mo_head);
621                     return DECOMP_ERROR;
622                 }
623                 state->strm.next_out = mo->b_rptr;
624                 state->strm.avail_out = ospace = DECOMP_CHUNK;
625             }
626         }
627     }
628     if (decode_proto) {
629         freemsg(mo_head);
630         return DECOMP_ERROR;
631     }
632     mo->b_wptr += ospace - state->strm.avail_out;
633     olen += ospace - state->strm.avail_out;
634
635 #if DEFLATE_DEBUG
636     if (olen > state->mru + PPP_HDRLEN)
637         printf("ppp_deflate%d: exceeded mru (%d > %d)\n",
638                state->unit, olen, state->mru + PPP_HDRLEN);
639 #endif
640
641     state->stats.unc_bytes += olen;
642     state->stats.unc_packets++;
643     state->stats.comp_bytes += rlen;
644     state->stats.comp_packets++;
645
646     *mop = mo_head;
647     return DECOMP_OK;
648 }
649
650 /*
651  * Incompressible data has arrived - add it to the history.
652  */
653 static void
654 z_incomp(arg, mi)
655     void *arg;
656     mblk_t *mi;
657 {
658     struct deflate_state *state = (struct deflate_state *) arg;
659     u_char *rptr;
660     int rlen, proto, r;
661
662     /*
663      * Check that the protocol is one we handle.
664      */
665     rptr = mi->b_rptr;
666     if (rptr + PPP_HDRLEN > mi->b_wptr) {
667         if (!pullupmsg(mi, PPP_HDRLEN))
668             return;
669         rptr = mi->b_rptr;
670     }
671     proto = PPP_PROTOCOL(rptr);
672     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
673         return;
674
675     ++state->seqno;
676
677     /*
678      * Iterate through the message blocks, adding the characters in them
679      * to the decompressor's history.  For the first block, we start
680      * at the either the 1st or 2nd byte of the protocol field,
681      * depending on whether the protocol value is compressible.
682      */
683     rlen = mi->b_wptr - mi->b_rptr;
684     state->strm.next_in = rptr + 3;
685     state->strm.avail_in = rlen - 3;
686     if (proto > 0xff) {
687         --state->strm.next_in;
688         ++state->strm.avail_in;
689     }
690     for (;;) {
691         r = inflateIncomp(&state->strm);
692         if (r != Z_OK) {
693             /* gak! */
694 #if !DEFLATE_DEBUG
695             if (state->debug)
696 #endif
697                 printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
698                        state->unit, r, (state->strm.msg? state->strm.msg: ""));
699             return;
700         }
701         mi = mi->b_cont;
702         if (mi == NULL)
703             break;
704         state->strm.next_in = mi->b_rptr;
705         state->strm.avail_in = mi->b_wptr - mi->b_rptr;
706         rlen += state->strm.avail_in;
707     }
708
709     /*
710      * Update stats.
711      */
712     state->stats.inc_bytes += rlen;
713     state->stats.inc_packets++;
714     state->stats.unc_bytes += rlen;
715     state->stats.unc_packets++;
716 }
717
718 #endif /* DO_DEFLATE */