1 /* $Id: inflate.c,v 1.7 2002/01/31 18:28:24 ukai Exp $ */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <zlib.h>
5 
6 #undef BUFSIZE
7 #define BUFSIZE 4096
8 
9 static char dummy_head[1 + 1] = {
10     0x8 + 0x7 * 0x10,
11     (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
12 };
13 
14 int
main(int argc,char ** argv)15 main(int argc, char **argv)
16 {
17     z_stream s;
18     FILE *f;
19     char inbuf[BUFSIZE], outbuf[BUFSIZE];
20     int status, flush, retry = 0, len = 0;
21 
22     if (argc > 1) {
23 	f = fopen(argv[1], "rb");
24 	if (!f) {
25 	    fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[1]);
26 	    exit(1);
27 	}
28     }
29     else
30 	f = stdin;
31 
32     s.zalloc = Z_NULL;
33     s.zfree = Z_NULL;
34     s.opaque = Z_NULL;
35     status = inflateInit(&s);
36     if (status != Z_OK) {
37 	fprintf(stderr, "%s: inflateInit() %s\n", argv[0], zError(status));
38 	exit(1);
39     }
40     s.avail_in = 0;
41     s.next_out = (Bytef *) outbuf;
42     s.avail_out = sizeof(outbuf);
43     flush = Z_NO_FLUSH;
44     while (1) {
45 	if (s.avail_in == 0) {
46 	    s.next_in = (Bytef *) inbuf;
47 	    len = s.avail_in = fread(inbuf, 1, sizeof(inbuf), f);
48 	}
49 	status = inflate(&s, flush);
50 	if (status == Z_STREAM_END || status == Z_BUF_ERROR) {
51 	    if (sizeof(outbuf) - s.avail_out)
52 		fwrite(outbuf, 1, sizeof(outbuf) - s.avail_out, stdout);
53 	    break;
54 	}
55 	if (status == Z_DATA_ERROR && !retry++) {
56 	    status = inflateReset(&s);
57 	    if (status != Z_OK) {
58 		fprintf(stderr, "%s: inflateReset() %s\n", argv[0],
59 			zError(status));
60 		exit(1);
61 	    }
62 	    s.next_in = (Bytef *) dummy_head;
63 	    s.avail_in = sizeof(dummy_head);
64 	    status = inflate(&s, flush);
65 	    s.next_in = (Bytef *) inbuf;
66 	    s.avail_in = len;
67 	    continue;
68 	}
69 	if (status != Z_OK) {
70 	    fprintf(stderr, "%s: inflate() %s\n", argv[0], zError(status));
71 	    exit(1);
72 	}
73 	if (s.avail_out == 0) {
74 	    fwrite(outbuf, 1, sizeof(outbuf), stdout);
75 	    s.next_out = (Bytef *) outbuf;
76 	    s.avail_out = sizeof(outbuf);
77 	}
78 	retry = 1;
79     }
80     inflateEnd(&s);
81     fclose(f);
82     return 0;
83 }
84