aboutsummaryrefslogtreecommitdiffstats
path: root/inflate.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--inflate.c209
1 files changed, 59 insertions, 150 deletions
diff --git a/inflate.c b/inflate.c
index 571a1b3..3c30af0 100644
--- a/inflate.c
+++ b/inflate.c
@@ -1,174 +1,83 @@
-#include <errno.h>
+/* $Id: inflate.c,v 1.6 2002/01/31 15:26:19 ukai Exp $ */
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
#include <zlib.h>
-#define MYBUFSIZ (BUFSIZ * 0x10)
+#undef BUFSIZE
+#define BUFSIZE 4096
-/* cf. rfc1950.txt */
static char dummy_head[1 + 1] = {
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
- int err, nfiles, i, nin, inrest, eoin, nout, outrest, eoout, ninflates,
- raw;
- z_stream d_stream;
- char *me = argv[0];
- char *inbuf, *outbuf, **filev;
-
- if (!(inbuf = malloc(MYBUFSIZ))) {
- fprintf(stderr, "%s: inbuf = malloc(%lu): %s\n", me,
- (unsigned long)MYBUFSIZ, strerror(errno));
- exit(1);
- }
-
- if (!(outbuf = malloc(MYBUFSIZ))) {
- fprintf(stderr, "%s: outbuf = malloc(%lu): %s\n", me,
- (unsigned long)MYBUFSIZ, strerror(errno));
- exit(1);
- }
-
- d_stream.zalloc = NULL;
- d_stream.zfree = NULL;
- d_stream.opaque = NULL;
+ z_stream s;
+ FILE *f;
+ char inbuf[BUFSIZE], outbuf[BUFSIZE];
+ int status, flush, retry = 0, len = 0;
if (argc > 1) {
- nfiles = argc - 1;
- filev = &argv[1];
- }
- else {
- static char *myargv[] = { "-", NULL };
-
- nfiles = 1;
- filev = myargv;
+ f = fopen(argv[1], "rb");
+ if (!f) {
+ fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[1]);
+ exit(1);
+ }
}
-
- if ((err = inflateInit(&d_stream)) != Z_OK) {
- fprintf(stderr, "%s: inflateInit(&d_stream): %d\n", me, err);
+ else
+ f = stdin;
+
+ s.zalloc = Z_NULL;
+ s.zfree = Z_NULL;
+ s.opaque = Z_NULL;
+ status = inflateInit(&s);
+ if (status != Z_OK) {
+ fprintf(stderr, "%s: inflateInit() %s\n", argv[0], zError(status));
exit(1);
}
-
- for (raw = ninflates = i = inrest = outrest = 0, eoout = 1; i < nfiles;
- ++i) {
- FILE *in;
-
- if (strcmp(filev[i], "-")) {
- if (!(in = fopen(filev[i], "rb"))) {
- fprintf(stderr, "%s: fopen(\"%s\", \"rb\"): %s\n", me,
- filev[i], strerror(errno));
+ s.avail_in = 0;
+ s.next_out = (Bytef *) outbuf;
+ s.avail_out = sizeof(outbuf);
+ flush = Z_NO_FLUSH;
+ while (1) {
+ if (s.avail_in == 0) {
+ s.next_in = (Bytef *) inbuf;
+ len = s.avail_in = fread(inbuf, 1, sizeof(inbuf), f);
+ }
+ status = inflate(&s, flush);
+ if (status == Z_STREAM_END || status == Z_BUF_ERROR) {
+ if (sizeof(outbuf) - s.avail_out)
+ fwrite(outbuf, 1, sizeof(outbuf) - s.avail_out, stdout);
+ break;
+ }
+ if (status == Z_DATA_ERROR && ! retry++) {
+ status = inflateReset(&s);
+ if (status != Z_OK) {
+ fprintf(stderr, "%s: inflateReset() %s\n", argv[0],
+ zError(status));
exit(1);
}
+ s.next_in = (Bytef *) dummy_head;
+ s.avail_in = sizeof(dummy_head);
+ status = inflate(&s, flush);
+ s.next_in = (Bytef *) inbuf;
+ s.avail_in = len;
+ continue;
}
- else
- in = stdin;
-
- for (eoin = 0;;) {
- if ((nin =
- fread(&inbuf[inrest], 1, MYBUFSIZ - inrest,
- in)) < MYBUFSIZ - inrest) {
- if (ferror(in)) {
- fprintf(stderr, "%s: fread(&inbuf[%d], 1, %d, in): %s\n",
- me, inrest, MYBUFSIZ - inrest, strerror(errno));
- exit(1);
- }
-
- eoin = 1;
- }
-
- if (nin > 0) {
- retry:
- d_stream.next_in = inbuf;
- d_stream.avail_in = inrest + nin;
-
- for (eoout = 0;;) {
- d_stream.next_out = &outbuf[outrest];
- d_stream.avail_out = MYBUFSIZ - outrest;
-
- switch (err = inflate(&d_stream, Z_NO_FLUSH)) {
- case Z_OK:
- if (!
- ((nout =
- fwrite(outbuf, 1, MYBUFSIZ - d_stream.avail_out,
- stdout)) > 0)) {
- fprintf(stderr,
- "%s: fwrite(outbuf, 1, %d, stdout): %s\n",
- me, MYBUFSIZ - d_stream.avail_out,
- strerror(errno));
- exit(1);
- }
-
- memmove(outbuf, &outbuf[nout],
- MYBUFSIZ - d_stream.avail_out - nout);
- outrest = MYBUFSIZ - d_stream.avail_out - nout;
- ++ninflates;
- break;
- case Z_STREAM_END:
- case Z_BUF_ERROR:
- ninflates = 0;
- outrest = MYBUFSIZ - d_stream.avail_out;
- eoout = 1;
- goto next_fread;
- case Z_DATA_ERROR:
- if (!ninflates) {
- if ((err = inflateReset(&d_stream)) != Z_OK) {
- fprintf(stderr,
- "%s: inflateReset(&d_stream): %d\n",
- me, err);
- exit(1);
- }
-
- d_stream.next_in = dummy_head;
- d_stream.avail_in = sizeof(dummy_head);
-
- if ((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_OK) {
- raw = ninflates = 1;
- goto retry;
- }
- }
- default:
- fprintf(stderr,
- "%s: inflate(&d_stream, Z_NO_FLUSH): %d\n", me,
- err);
- exit(1);
- }
- }
- }
-
- next_fread:
- if (d_stream.avail_in) {
- memmove(inbuf, &inbuf[inrest + nin - d_stream.avail_in],
- d_stream.avail_in);
- inrest = d_stream.avail_in;
- }
- else
- inrest = 0;
-
- if (eoin)
- break;
+ if (status != Z_OK) {
+ fprintf(stderr, "%s: inflate() %s\n", argv[0], zError(status));
+ exit(1);
}
-
- if (in != stdin)
- fclose(in);
- }
-
- if (!eoout && !raw) {
- fprintf(stderr, "%s: short input\n", me);
- exit(1);
- }
-
- if (inrest)
- fprintf(stderr, "%s: trailing garbages are ignored\n", me);
-
- if (outrest && fwrite(outbuf, 1, outrest, stdout) < outrest) {
- fprintf(stderr, "%s: fwrite(outbuf, 1, %d, stdout): %s\n", me, outrest,
- strerror(errno));
- exit(1);
+ if (s.avail_out == 0) {
+ fwrite(outbuf, 1, sizeof(outbuf), stdout);
+ s.next_out = (Bytef *) outbuf;
+ s.avail_out = sizeof(outbuf);
+ }
+ retry = 1;
}
-
+ inflateEnd(&s);
+ fclose(f);
return 0;
}