diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2001-03-28 05:38:24 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2001-03-28 05:38:24 +0000 |
commit | 58e42d5356bfbb8ed817a782901bf52d9b8f54bf (patch) | |
tree | a7293aaecbaf442947c1a5fbd089b45c6099ec4e /gunzip.c | |
parent | f58efb57d1c7134cfeaf73e84f210c2458826b80 (diff) | |
download | busybox-w32-58e42d5356bfbb8ed817a782901bf52d9b8f54bf.tar.gz busybox-w32-58e42d5356bfbb8ed817a782901bf52d9b8f54bf.tar.bz2 busybox-w32-58e42d5356bfbb8ed817a782901bf52d9b8f54bf.zip |
Major cleanup to better adhere to style guide and use standard busybox functions
Diffstat (limited to '')
-rw-r--r-- | gunzip.c | 1622 |
1 files changed, 724 insertions, 898 deletions
@@ -11,6 +11,9 @@ | |||
11 | * to support files as well as stdin/stdout, and to generally behave itself wrt | 11 | * to support files as well as stdin/stdout, and to generally behave itself wrt |
12 | * command line handling. | 12 | * command line handling. |
13 | * | 13 | * |
14 | * General cleanup to better adhere to the style guide and make use of standard | ||
15 | * busybox functions by Glenn McGrath <bug1@optushome.com.au> | ||
16 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | 17 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 18 | * it under the terms of the GNU General Public License as published by |
16 | * the Free Software Foundation; either version 2 of the License, or | 19 | * the Free Software Foundation; either version 2 of the License, or |
@@ -60,8 +63,9 @@ static char *license_msg[] = { | |||
60 | #include <getopt.h> | 63 | #include <getopt.h> |
61 | #include <ctype.h> | 64 | #include <ctype.h> |
62 | #include <sys/types.h> | 65 | #include <sys/types.h> |
66 | #include <sys/wait.h> | ||
63 | #include <signal.h> | 67 | #include <signal.h> |
64 | #include <errno.h> | 68 | //#include <errno.h> |
65 | #include <stdio.h> | 69 | #include <stdio.h> |
66 | #include <string.h> | 70 | #include <string.h> |
67 | #include <memory.h> | 71 | #include <memory.h> |
@@ -76,363 +80,85 @@ static char *license_msg[] = { | |||
76 | #define bb_need_name_too_long | 80 | #define bb_need_name_too_long |
77 | #include "messages.c" | 81 | #include "messages.c" |
78 | 82 | ||
79 | static const int RECORD_IO = 0; | 83 | FILE *in_file, *out_file; |
84 | |||
85 | static unsigned long *crc_table; | ||
86 | static unsigned long crc = 0xffffffffL; /* shift register contents */ | ||
80 | 87 | ||
81 | /* Return codes from gzip */ | 88 | /* Return codes from gzip */ |
82 | static const int OK = 0; | ||
83 | static const int ERROR = 1; | 89 | static const int ERROR = 1; |
84 | static const int WARNING = 2; | ||
85 | |||
86 | static const int DEFLATED = 8; | ||
87 | static const int INBUFSIZ = 0x2000; /* input buffer size */ | ||
88 | static const int INBUF_EXTRA = 64; /* required by unlzw() */ | ||
89 | static const int OUTBUFSIZ = 8192; /* output buffer size */ | ||
90 | static const int OUTBUF_EXTRA = 2048; /* required by unlzw() */ | ||
91 | static const int DIST_BUFSIZE = 0x2000; /* buffer for distances, see trees.c */ | ||
92 | |||
93 | #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ | ||
94 | 90 | ||
95 | /* gzip flag byte */ | 91 | /* |
96 | static const int EXTRA_FIELD = 0x04; /* bit 2 set: extra field present */ | 92 | * window size--must be a power of two, and |
97 | static const int ORIG_NAME = 0x08; /* bit 3 set: original file name present */ | 93 | * at least 32K for zip's deflate method |
98 | static const int COMMENT = 0x10; /* bit 4 set: file comment present */ | 94 | */ |
99 | static const int WSIZE = 0x8000; /* window size--must be a power of two, and */ | 95 | static const int WSIZE = 0x8000; |
100 | /* at least 32K for zip's deflate method */ | ||
101 | 96 | ||
102 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ | 97 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ |
103 | static const int BMAX = 16; /* maximum bit length of any code (16 for explode) */ | 98 | static const int BMAX = 16; /* maximum bit length of any code (16 for explode) */ |
104 | static const int N_MAX = 288; /* maximum number of codes in any set */ | 99 | static const int N_MAX = 288; /* maximum number of codes in any set */ |
105 | 100 | ||
106 | /* PKZIP header definitions */ | 101 | static unsigned char *window; |
107 | static const int LOCSIG = 0x04034b50L; /* four-byte lead-in (lsb first) */ | ||
108 | static const int LOCCRC = 14; /* offset of crc */ | ||
109 | static const int LOCLEN = 22; /* offset of uncompressed length */ | ||
110 | static const int EXTHDR = 16; /* size of extended local header, inc sig */ | ||
111 | |||
112 | static const int BITS = 16; | ||
113 | |||
114 | /* Diagnostic functions */ | ||
115 | #ifdef DEBUG | ||
116 | # define Assert(cond,msg) {if(!(cond)) error_msg(msg);} | ||
117 | # define Trace(x) fprintf x | ||
118 | # define Tracev(x) {if (verbose) fprintf x ;} | ||
119 | # define Tracevv(x) {if (verbose>1) fprintf x ;} | ||
120 | # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} | ||
121 | # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} | ||
122 | #else | ||
123 | # define Assert(cond,msg) | ||
124 | # define Trace(x) | ||
125 | # define Tracev(x) | ||
126 | # define Tracevv(x) | ||
127 | # define Tracec(c,x) | ||
128 | # define Tracecv(c,x) | ||
129 | #endif | ||
130 | 102 | ||
131 | #ifndef MAX_PATH_LEN /* max pathname length */ | ||
132 | # ifdef BUFSIZ | ||
133 | # define MAX_PATH_LEN BUFSIZ | ||
134 | # else | ||
135 | static const int MAX_PATH_LEN = 1024; | ||
136 | # endif | ||
137 | #endif | ||
138 | |||
139 | #define NEXTBYTE() (uch)get_byte() | ||
140 | #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}} | ||
141 | #define DUMPBITS(n) {b>>=(n);k-=(n);} | ||
142 | |||
143 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) | ||
144 | |||
145 | /* Macros for getting two-byte and four-byte header values */ | ||
146 | #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) | ||
147 | #define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)) | ||
148 | |||
149 | /* in gzip.c */ | ||
150 | void abort_gzip (void); | ||
151 | typedef void (*sig_type) (int); | ||
152 | |||
153 | typedef unsigned char uch; | ||
154 | typedef unsigned short ush; | ||
155 | typedef unsigned long ulg; | ||
156 | typedef int file_t; /* Do not use stdio */ | ||
157 | |||
158 | static uch *inbuf; | ||
159 | static uch *outbuf; | ||
160 | static ush *d_buf; | ||
161 | static uch *window; | ||
162 | static ush *tab_prefix0; | ||
163 | static ush *tab_prefix1; | ||
164 | |||
165 | /* local variables */ | ||
166 | static int test_mode = 0; /* check file integrity option */ | ||
167 | static int foreground; /* set if program run in foreground */ | ||
168 | static int method; /* compression method */ | ||
169 | static int exit_code; /* program exit code */ | ||
170 | static int last_member; /* set for .zip and .Z files */ | ||
171 | static int part_nb; /* number of parts in .gz file */ | ||
172 | static long ifile_size; /* input file size, -1 for devices (debug only) */ | ||
173 | static long bytes_in; /* number of input bytes */ | ||
174 | static long bytes_out; /* number of output bytes */ | 103 | static long bytes_out; /* number of output bytes */ |
175 | static int ifd; /* input file descriptor */ | 104 | static unsigned long outcnt; /* bytes in output buffer */ |
176 | static int ofd; /* output file descriptor */ | ||
177 | static unsigned insize; /* valid bytes in inbuf */ | ||
178 | static unsigned inptr; /* index of next byte to be processed in inbuf */ | ||
179 | static unsigned outcnt; /* bytes in output buffer */ | ||
180 | 105 | ||
181 | unsigned hufts; /* track memory usage */ | 106 | unsigned hufts; /* track memory usage */ |
182 | ulg bb; /* bit buffer */ | 107 | unsigned long bb; /* bit buffer */ |
183 | unsigned bk; /* bits in bit buffer */ | 108 | unsigned bk; /* bits in bit buffer */ |
184 | int crc_table_empty = 1; | ||
185 | 109 | ||
186 | struct huft { | 110 | typedef struct huft_s { |
187 | uch e; /* number of extra bits or operation */ | 111 | unsigned char e; /* number of extra bits or operation */ |
188 | uch b; /* number of bits in this code or subcode */ | 112 | unsigned char b; /* number of bits in this code or subcode */ |
189 | union { | 113 | union { |
190 | ush n; /* literal, length base, or distance base */ | 114 | unsigned short n; /* literal, length base, or distance base */ |
191 | struct huft *t; /* pointer to next level of table */ | 115 | struct huft_s *t; /* pointer to next level of table */ |
192 | } v; | 116 | } v; |
193 | }; | 117 | } huft_t; |
194 | 118 | ||
195 | /* Tables for deflate from PKZIP's appnote.txt. */ | 119 | unsigned short mask_bits[] = { |
196 | static unsigned border[] = { /* Order of the bit length code lengths */ | ||
197 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 | ||
198 | }; | ||
199 | static ush cplens[] = { /* Copy lengths for literal codes 257..285 */ | ||
200 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | ||
201 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 | ||
202 | }; | ||
203 | |||
204 | /* note: see note #13 above about the 258 in this list. */ | ||
205 | static ush cplext[] = { /* Extra bits for literal codes 257..285 */ | ||
206 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | ||
207 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 | ||
208 | }; /* 99==invalid */ | ||
209 | |||
210 | static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ | ||
211 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | ||
212 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | ||
213 | 8193, 12289, 16385, 24577 | ||
214 | }; | ||
215 | |||
216 | static ush cpdext[] = { /* Extra bits for distance codes */ | ||
217 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | ||
218 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | ||
219 | 12, 12, 13, 13 | ||
220 | }; | ||
221 | |||
222 | ush mask_bits[] = { | ||
223 | 0x0000, | 120 | 0x0000, |
224 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, | 121 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, |
225 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff | 122 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff |
226 | }; | 123 | }; |
227 | 124 | ||
228 | /* ======================================================================== | 125 | //static int error_number = 0; |
229 | * Error handlers. | ||
230 | */ | ||
231 | void read_error_msg() | ||
232 | { | ||
233 | fprintf(stderr, "\n"); | ||
234 | if (errno != 0) { | ||
235 | perror(""); | ||
236 | } else { | ||
237 | fprintf(stderr, "unexpected end of file\n"); | ||
238 | } | ||
239 | abort_gzip(); | ||
240 | } | ||
241 | |||
242 | /* =========================================================================== | ||
243 | * Fill the input buffer. This is called only when the buffer is empty. | ||
244 | */ | ||
245 | int fill_inbuf(eof_ok) | ||
246 | int eof_ok; /* set if EOF acceptable as a result */ | ||
247 | { | ||
248 | int len; | ||
249 | |||
250 | /* Read as much as possible */ | ||
251 | insize = 0; | ||
252 | errno = 0; | ||
253 | do { | ||
254 | len = read(ifd, (char *) inbuf + insize, INBUFSIZ - insize); | ||
255 | if (len == 0 || len == EOF) | ||
256 | break; | ||
257 | insize += len; | ||
258 | } while (insize < INBUFSIZ); | ||
259 | |||
260 | if (insize == 0) { | ||
261 | if (eof_ok) | ||
262 | return EOF; | ||
263 | read_error_msg(); | ||
264 | } | ||
265 | bytes_in += (ulg) insize; | ||
266 | inptr = 1; | ||
267 | return inbuf[0]; | ||
268 | } | ||
269 | |||
270 | |||
271 | /* ======================================================================== | ||
272 | * Check the magic number of the input file and update ofname if an | ||
273 | * original name was given and tostdout is not set. | ||
274 | * Return the compression method, -1 for error, -2 for warning. | ||
275 | * Set inptr to the offset of the next byte to be processed. | ||
276 | * Updates time_stamp if there is one and --no-time is not used. | ||
277 | * This function may be called repeatedly for an input file consisting | ||
278 | * of several contiguous gzip'ed members. | ||
279 | * IN assertions: there is at least one remaining compressed member. | ||
280 | * If the member is a zip file, it must be the only one. | ||
281 | */ | ||
282 | static int get_method(in) | ||
283 | int in; /* input file descriptor */ | ||
284 | { | ||
285 | uch flags; /* compression flags */ | ||
286 | char magic[2]; /* magic header */ | ||
287 | long header_bytes = 0; /* number of bytes in gzip header */ | ||
288 | |||
289 | magic[0] = (char) get_byte(); | ||
290 | magic[1] = (char) get_byte(); | ||
291 | method = -1; /* unknown yet */ | ||
292 | part_nb++; /* number of parts in gzip file */ | ||
293 | last_member = RECORD_IO; | ||
294 | /* assume multiple members in gzip file except for record oriented I/O */ | ||
295 | |||
296 | if (memcmp(magic, GZIP_MAGIC, 2) == 0) { | ||
297 | |||
298 | method = (int) get_byte(); | ||
299 | if (method != DEFLATED) { | ||
300 | error_msg("unknown method %d -- get newer version of gzip", method); | ||
301 | exit_code = ERROR; | ||
302 | return -1; | ||
303 | } | ||
304 | flags = (uch) get_byte(); | ||
305 | |||
306 | (ulg) get_byte(); /* Ignore time stamp */ | ||
307 | (ulg) get_byte(); | ||
308 | (ulg) get_byte(); | ||
309 | (ulg) get_byte(); | ||
310 | |||
311 | (void) get_byte(); /* Ignore extra flags for the moment */ | ||
312 | (void) get_byte(); /* Ignore OS type for the moment */ | ||
313 | |||
314 | if ((flags & EXTRA_FIELD) != 0) { | ||
315 | unsigned len = (unsigned) get_byte(); | ||
316 | len |= ((unsigned) get_byte()) << 8; | ||
317 | while (len--) | ||
318 | (void) get_byte(); | ||
319 | } | ||
320 | |||
321 | /* Discard original name if any */ | ||
322 | if ((flags & ORIG_NAME) != 0) { | ||
323 | while (get_byte() != 0); /* null */ | ||
324 | } | ||
325 | |||
326 | /* Discard file comment if any */ | ||
327 | if ((flags & COMMENT) != 0) { | ||
328 | while (get_byte() != 0) /* null */ | ||
329 | ; | ||
330 | } | ||
331 | if (part_nb == 1) { | ||
332 | header_bytes = inptr + 2 * sizeof(long); /* include crc and size */ | ||
333 | } | ||
334 | |||
335 | } | ||
336 | |||
337 | if (method >= 0) | ||
338 | return method; | ||
339 | |||
340 | if (part_nb == 1) { | ||
341 | fprintf(stderr, "\nnot in gzip format\n"); | ||
342 | exit_code = ERROR; | ||
343 | return -1; | ||
344 | } else { | ||
345 | fprintf(stderr, "\ndecompression OK, trailing garbage ignored\n"); | ||
346 | if (exit_code == OK) | ||
347 | exit_code = WARNING; | ||
348 | return -2; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /* ======================================================================== | 126 | /* ======================================================================== |
353 | * Signal and error handler. | 127 | * Signal and error handler. |
354 | */ | 128 | */ |
355 | void abort_gzip() | 129 | static void abort_gzip() |
356 | { | 130 | { |
357 | exit(ERROR); | 131 | error_msg("gzip aborted\n"); |
132 | // exit(ERROR); | ||
133 | return; | ||
358 | } | 134 | } |
359 | 135 | ||
360 | /* =========================================================================== | 136 | static void make_crc_table() |
361 | * Run a set of bytes through the crc shift register. If s is a NULL | ||
362 | * pointer, then initialize the crc shift register contents instead. | ||
363 | * Return the current crc in either case. | ||
364 | */ | ||
365 | ulg updcrc(s, n) | ||
366 | uch *s; /* pointer to bytes to pump through */ | ||
367 | unsigned n; /* number of bytes in s[] */ | ||
368 | { | 137 | { |
369 | static ulg crc = (ulg) 0xffffffffL; /* shift register contents */ | 138 | unsigned long table_entry; /* crc shift register */ |
370 | register ulg c; /* temporary variable */ | 139 | unsigned long poly = 0; /* polynomial exclusive-or pattern */ |
371 | static unsigned long crc_32_tab[256]; | 140 | int i; /* counter for all possible eight bit values */ |
372 | if (crc_table_empty) { | 141 | int k; /* byte being shifted into crc apparatus */ |
373 | unsigned long csr; /* crc shift register */ | 142 | |
374 | unsigned long e; /* polynomial exclusive-or pattern */ | 143 | /* terms of polynomial defining this crc (except x^32): */ |
375 | int i; /* counter for all possible eight bit values */ | 144 | static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; |
376 | int k; /* byte being shifted into crc apparatus */ | 145 | |
377 | 146 | crc_table = (unsigned long *) malloc(256 * sizeof(unsigned long)); | |
378 | /* terms of polynomial defining this crc (except x^32): */ | 147 | |
379 | static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; | 148 | /* Make exclusive-or pattern from polynomial (0xedb88320) */ |
380 | 149 | for (i = 0; i < sizeof(p)/sizeof(int); i++) | |
381 | /* Make exclusive-or pattern from polynomial (0xedb88320) */ | 150 | poly |= 1L << (31 - p[i]); |
382 | e = 0; | 151 | |
383 | for (i = 0; i < sizeof(p)/sizeof(int); i++) | 152 | /* Compute and print table of CRC's, five per line */ |
384 | e |= 1L << (31 - p[i]); | 153 | for (i = 0; i < 256; i++) { |
385 | 154 | table_entry = i; | |
386 | /* Compute and print table of CRC's, five per line */ | 155 | /* The idea to initialize the register with the byte instead of |
387 | crc_32_tab[0] = 0x00000000L; | 156 | * zero was stolen from Haruhiko Okumura's ar002 |
388 | for (i = 1; i < 256; i++) { | 157 | */ |
389 | csr = i; | 158 | for (k = 8; k; k--) { |
390 | /* The idea to initialize the register with the byte instead of | 159 | table_entry = table_entry & 1 ? (table_entry >> 1) ^ poly : table_entry >> 1; |
391 | * zero was stolen from Haruhiko Okumura's ar002 | ||
392 | */ | ||
393 | for (k = 8; k; k--) | ||
394 | csr = csr & 1 ? (csr >> 1) ^ e : csr >> 1; | ||
395 | crc_32_tab[i]=csr; | ||
396 | } | 160 | } |
397 | } | 161 | crc_table[i]=table_entry; |
398 | |||
399 | if (s == NULL) { | ||
400 | c = 0xffffffffL; | ||
401 | } else { | ||
402 | c = crc; | ||
403 | if (n) | ||
404 | do { | ||
405 | c = crc_32_tab[((int) c ^ (*s++)) & 0xff] ^ (c >> 8); | ||
406 | } while (--n); | ||
407 | } | ||
408 | crc = c; | ||
409 | return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ | ||
410 | } | ||
411 | |||
412 | void write_error_msg() | ||
413 | { | ||
414 | fprintf(stderr, "\n"); | ||
415 | perror(""); | ||
416 | abort_gzip(); | ||
417 | } | ||
418 | |||
419 | /* =========================================================================== | ||
420 | * Does the same as write(), but also handles partial pipe writes and checks | ||
421 | * for error return. | ||
422 | */ | ||
423 | void write_buf(fd, buf, cnt) | ||
424 | int fd; | ||
425 | void * buf; | ||
426 | unsigned cnt; | ||
427 | { | ||
428 | unsigned n; | ||
429 | |||
430 | while ((n = write(fd, buf, cnt)) != cnt) { | ||
431 | if (n == (unsigned) (-1)) { | ||
432 | write_error_msg(); | ||
433 | } | ||
434 | cnt -= n; | ||
435 | buf = (void *) ((char *) buf + n); | ||
436 | } | 162 | } |
437 | } | 163 | } |
438 | 164 | ||
@@ -442,74 +168,35 @@ unsigned cnt; | |||
442 | */ | 168 | */ |
443 | void flush_window() | 169 | void flush_window() |
444 | { | 170 | { |
171 | int n; | ||
172 | |||
445 | if (outcnt == 0) | 173 | if (outcnt == 0) |
446 | return; | 174 | return; |
447 | updcrc(window, outcnt); | ||
448 | |||
449 | if (!test_mode) | ||
450 | write_buf(ofd, (char *) window, outcnt); | ||
451 | bytes_out += (ulg) outcnt; | ||
452 | outcnt = 0; | ||
453 | } | ||
454 | |||
455 | int inflate_stored() | ||
456 | /* "decompress" an inflated type 0 (stored) block. */ | ||
457 | { | ||
458 | unsigned n; /* number of bytes in block */ | ||
459 | unsigned w; /* current window position */ | ||
460 | register ulg b; /* bit buffer */ | ||
461 | register unsigned k; /* number of bits in bit buffer */ | ||
462 | 175 | ||
463 | /* make local copies of globals */ | 176 | for (n = 0; n < outcnt; n++) { |
464 | b = bb; /* initialize bit buffer */ | 177 | crc = crc_table[((int) crc ^ (window[n])) & 0xff] ^ (crc >> 8); |
465 | k = bk; | ||
466 | w = outcnt; /* initialize window position */ | ||
467 | |||
468 | /* go to byte boundary */ | ||
469 | n = k & 7; | ||
470 | DUMPBITS(n); | ||
471 | |||
472 | /* get the length and its complement */ | ||
473 | NEEDBITS(16) | ||
474 | n = ((unsigned) b & 0xffff); | ||
475 | DUMPBITS(16) | ||
476 | NEEDBITS(16) | ||
477 | if (n != (unsigned) ((~b) & 0xffff)) | ||
478 | return 1; /* error in compressed data */ | ||
479 | DUMPBITS(16) | ||
480 | |||
481 | /* read and output the compressed data */ | ||
482 | while (n--) { | ||
483 | NEEDBITS(8) | ||
484 | window[w++] = (uch) b; | ||
485 | if (w == WSIZE) { | ||
486 | // flush_output(w); | ||
487 | outcnt=(w), | ||
488 | flush_window(); | ||
489 | w = 0; | ||
490 | } | ||
491 | DUMPBITS(8) | ||
492 | } | 178 | } |
493 | 179 | ||
494 | /* restore the globals from the locals */ | 180 | if (fwrite(window, 1, outcnt, out_file) != outcnt) { |
495 | outcnt = w; /* restore global window pointer */ | 181 | error_msg_and_die("Couldnt write"); |
496 | bb = b; /* restore global bit buffer */ | 182 | } |
497 | bk = k; | 183 | bytes_out += (unsigned long) outcnt; |
498 | return 0; | 184 | outcnt = 0; |
499 | } | 185 | } |
500 | 186 | ||
501 | int huft_free(t) | 187 | /* |
502 | struct huft *t; /* table to free */ | 188 | * Free the malloc'ed tables built by huft_build(), which makes a linked |
503 | 189 | * list of the tables it made, with the links in a dummy first entry of | |
504 | /* Free the malloc'ed tables built by huft_build(), which makes a linked | 190 | * each table. |
505 | list of the tables it made, with the links in a dummy first entry of | 191 | * t: table to free |
506 | each table. */ | 192 | */ |
193 | static int huft_free(huft_t *t) | ||
507 | { | 194 | { |
508 | register struct huft *p, *q; | 195 | huft_t *p, *q; |
509 | 196 | ||
510 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ | 197 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ |
511 | p = t; | 198 | p = t; |
512 | while (p != (struct huft *) NULL) { | 199 | while (p != (huft_t *) NULL) { |
513 | q = (--p)->v.t; | 200 | q = (--p)->v.t; |
514 | free((char *) p); | 201 | free((char *) p); |
515 | p = q; | 202 | p = q; |
@@ -517,21 +204,22 @@ struct huft *t; /* table to free */ | |||
517 | return 0; | 204 | return 0; |
518 | } | 205 | } |
519 | 206 | ||
520 | |||
521 | int huft_build(b, n, s, d, e, t, m) | ||
522 | unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ | ||
523 | unsigned n; /* number of codes (assumed <= N_MAX) */ | ||
524 | unsigned s; /* number of simple-valued codes (0..s-1) */ | ||
525 | ush *d; /* list of base values for non-simple codes */ | ||
526 | ush *e; /* list of extra bits for non-simple codes */ | ||
527 | struct huft **t; /* result: starting table */ | ||
528 | int *m; /* maximum lookup bits, returns actual */ | ||
529 | |||
530 | /* Given a list of code lengths and a maximum table size, make a set of | 207 | /* Given a list of code lengths and a maximum table size, make a set of |
531 | tables to decode that set of codes. Return zero on success, one if | 208 | * tables to decode that set of codes. Return zero on success, one if |
532 | the given code set is incomplete (the tables are still built in this | 209 | * the given code set is incomplete (the tables are still built in this |
533 | case), two if the input is invalid (all zero length codes or an | 210 | * case), two if the input is invalid (all zero length codes or an |
534 | oversubscribed set of lengths), and three if not enough memory. */ | 211 | * oversubscribed set of lengths), and three if not enough memory. |
212 | * | ||
213 | * b: code lengths in bits (all assumed <= BMAX) | ||
214 | * n: number of codes (assumed <= N_MAX) | ||
215 | * s: number of simple-valued codes (0..s-1) | ||
216 | * d: list of base values for non-simple codes | ||
217 | * e: list of extra bits for non-simple codes | ||
218 | * t: result: starting table | ||
219 | * m: maximum lookup bits, returns actual | ||
220 | */ | ||
221 | static int huft_build(unsigned int *b, const unsigned int n, const unsigned int s, | ||
222 | const unsigned short *d, const unsigned short *e, huft_t **t, int *m) | ||
535 | { | 223 | { |
536 | unsigned a; /* counter for codes of length k */ | 224 | unsigned a; /* counter for codes of length k */ |
537 | unsigned c[BMAX + 1]; /* bit length count table */ | 225 | unsigned c[BMAX + 1]; /* bit length count table */ |
@@ -543,9 +231,9 @@ int *m; /* maximum lookup bits, returns actual */ | |||
543 | register int k; /* number of bits in current code */ | 231 | register int k; /* number of bits in current code */ |
544 | int l; /* bits per table (returned in m) */ | 232 | int l; /* bits per table (returned in m) */ |
545 | register unsigned *p; /* pointer into c[], b[], or v[] */ | 233 | register unsigned *p; /* pointer into c[], b[], or v[] */ |
546 | register struct huft *q; /* points to current table */ | 234 | register huft_t *q; /* points to current table */ |
547 | struct huft r; /* table entry for structure assignment */ | 235 | huft_t r; /* table entry for structure assignment */ |
548 | struct huft *u[BMAX]; /* table stack */ | 236 | huft_t *u[BMAX]; /* table stack */ |
549 | unsigned v[N_MAX]; /* values in order of bit length */ | 237 | unsigned v[N_MAX]; /* values in order of bit length */ |
550 | register int w; /* bits before this table == (l * h) */ | 238 | register int w; /* bits before this table == (l * h) */ |
551 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ | 239 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ |
@@ -558,12 +246,11 @@ int *m; /* maximum lookup bits, returns actual */ | |||
558 | p = b; | 246 | p = b; |
559 | i = n; | 247 | i = n; |
560 | do { | 248 | do { |
561 | Tracecv(*p,(stderr, (n - i >= ' ' && n - i <= '~' ? "%c %d\n" : "0x%x %d\n"), n - i, *p)); | ||
562 | c[*p]++; /* assume all entries <= BMAX */ | 249 | c[*p]++; /* assume all entries <= BMAX */ |
563 | p++; /* Can't combine with above line (Solaris bug) */ | 250 | p++; /* Can't combine with above line (Solaris bug) */ |
564 | } while (--i); | 251 | } while (--i); |
565 | if (c[0] == n) { /* null input--all zero length codes */ | 252 | if (c[0] == n) { /* null input--all zero length codes */ |
566 | *t = (struct huft *) NULL; | 253 | *t = (huft_t *) NULL; |
567 | *m = 0; | 254 | *m = 0; |
568 | return 0; | 255 | return 0; |
569 | } | 256 | } |
@@ -613,8 +300,8 @@ int *m; /* maximum lookup bits, returns actual */ | |||
613 | p = v; /* grab values in bit order */ | 300 | p = v; /* grab values in bit order */ |
614 | h = -1; /* no tables yet--level -1 */ | 301 | h = -1; /* no tables yet--level -1 */ |
615 | w = -l; /* bits decoded == (l * h) */ | 302 | w = -l; /* bits decoded == (l * h) */ |
616 | u[0] = (struct huft *) NULL; /* just to keep compilers happy */ | 303 | u[0] = (huft_t *) NULL; /* just to keep compilers happy */ |
617 | q = (struct huft *) NULL; /* ditto */ | 304 | q = (huft_t *) NULL; /* ditto */ |
618 | z = 0; /* ditto */ | 305 | z = 0; /* ditto */ |
619 | 306 | ||
620 | /* go through the bit lengths (k already is bits in shortest code) */ | 307 | /* go through the bit lengths (k already is bits in shortest code) */ |
@@ -641,25 +328,22 @@ int *m; /* maximum lookup bits, returns actual */ | |||
641 | z = 1 << j; /* table entries for j-bit table */ | 328 | z = 1 << j; /* table entries for j-bit table */ |
642 | 329 | ||
643 | /* allocate and link in new table */ | 330 | /* allocate and link in new table */ |
644 | if ( | 331 | if ((q = (huft_t *) xmalloc((z + 1) * sizeof(huft_t))) == NULL) { |
645 | (q = | 332 | if (h) { |
646 | (struct huft *) malloc((z + 1) * | ||
647 | sizeof(struct huft))) == | ||
648 | (struct huft *) NULL) { | ||
649 | if (h) | ||
650 | huft_free(u[0]); | 333 | huft_free(u[0]); |
334 | } | ||
651 | return 3; /* not enough memory */ | 335 | return 3; /* not enough memory */ |
652 | } | 336 | } |
653 | hufts += z + 1; /* track memory usage */ | 337 | hufts += z + 1; /* track memory usage */ |
654 | *t = q + 1; /* link to list for huft_free() */ | 338 | *t = q + 1; /* link to list for huft_free() */ |
655 | *(t = &(q->v.t)) = (struct huft *) NULL; | 339 | *(t = &(q->v.t)) = NULL; |
656 | u[h] = ++q; /* table starts after link */ | 340 | u[h] = ++q; /* table starts after link */ |
657 | 341 | ||
658 | /* connect to last table, if there is one */ | 342 | /* connect to last table, if there is one */ |
659 | if (h) { | 343 | if (h) { |
660 | x[h] = i; /* save pattern for backing up */ | 344 | x[h] = i; /* save pattern for backing up */ |
661 | r.b = (uch) l; /* bits to dump before this table */ | 345 | r.b = (unsigned char) l; /* bits to dump before this table */ |
662 | r.e = (uch) (16 + j); /* bits in this table */ | 346 | r.e = (unsigned char) (16 + j); /* bits in this table */ |
663 | r.v.t = q; /* pointer to this table */ | 347 | r.v.t = q; /* pointer to this table */ |
664 | j = i >> (w - l); /* (get around Turbo C bug) */ | 348 | j = i >> (w - l); /* (get around Turbo C bug) */ |
665 | u[h - 1][j] = r; /* connect to last table */ | 349 | u[h - 1][j] = r; /* connect to last table */ |
@@ -667,15 +351,15 @@ int *m; /* maximum lookup bits, returns actual */ | |||
667 | } | 351 | } |
668 | 352 | ||
669 | /* set up table entry in r */ | 353 | /* set up table entry in r */ |
670 | r.b = (uch) (k - w); | 354 | r.b = (unsigned char) (k - w); |
671 | if (p >= v + n) | 355 | if (p >= v + n) |
672 | r.e = 99; /* out of values--invalid code */ | 356 | r.e = 99; /* out of values--invalid code */ |
673 | else if (*p < s) { | 357 | else if (*p < s) { |
674 | r.e = (uch) (*p < 256 ? 16 : 15); /* 256 is end-of-block code */ | 358 | r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is end-of-block code */ |
675 | r.v.n = (ush) (*p); /* simple code is just the value */ | 359 | r.v.n = (unsigned short) (*p); /* simple code is just the value */ |
676 | p++; /* one compiler does not like *p++ */ | 360 | p++; /* one compiler does not like *p++ */ |
677 | } else { | 361 | } else { |
678 | r.e = (uch) e[*p - s]; /* non-simple--look up in lists */ | 362 | r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */ |
679 | r.v.n = d[*p++ - s]; | 363 | r.v.n = d[*p++ - s]; |
680 | } | 364 | } |
681 | 365 | ||
@@ -700,20 +384,21 @@ int *m; /* maximum lookup bits, returns actual */ | |||
700 | return y != 0 && g != 1; | 384 | return y != 0 && g != 1; |
701 | } | 385 | } |
702 | 386 | ||
703 | 387 | /* | |
704 | int inflate_codes(tl, td, bl, bd) | 388 | * inflate (decompress) the codes in a deflated (compressed) block. |
705 | struct huft *tl, *td; /* literal/length and distance decoder tables */ | 389 | * Return an error code or zero if it all goes ok. |
706 | int bl, bd; /* number of bits decoded by tl[] and td[] */ | 390 | * |
707 | 391 | * tl, td: literal/length and distance decoder tables | |
708 | /* inflate (decompress) the codes in a deflated (compressed) block. | 392 | * bl, bd: number of bits decoded by tl[] and td[] |
709 | Return an error code or zero if it all goes ok. */ | 393 | */ |
394 | static int inflate_codes(huft_t *tl, huft_t *td, int bl, int bd) | ||
710 | { | 395 | { |
711 | register unsigned e; /* table entry flag/number of extra bits */ | 396 | register unsigned long e; /* table entry flag/number of extra bits */ |
712 | unsigned n, d; /* length and index for copy */ | 397 | unsigned long n, d; /* length and index for copy */ |
713 | unsigned w; /* current window position */ | 398 | unsigned long w; /* current window position */ |
714 | struct huft *t; /* pointer to table entry */ | 399 | huft_t *t; /* pointer to table entry */ |
715 | unsigned ml, md; /* masks for bl and bd bits */ | 400 | unsigned ml, md; /* masks for bl and bd bits */ |
716 | register ulg b; /* bit buffer */ | 401 | register unsigned long b; /* bit buffer */ |
717 | register unsigned k; /* number of bits in bit buffer */ | 402 | register unsigned k; /* number of bits in bit buffer */ |
718 | 403 | ||
719 | /* make local copies of globals */ | 404 | /* make local copies of globals */ |
@@ -725,20 +410,27 @@ int bl, bd; /* number of bits decoded by tl[] and td[] */ | |||
725 | ml = mask_bits[bl]; /* precompute masks for speed */ | 410 | ml = mask_bits[bl]; /* precompute masks for speed */ |
726 | md = mask_bits[bd]; | 411 | md = mask_bits[bd]; |
727 | for (;;) { /* do until end of block */ | 412 | for (;;) { /* do until end of block */ |
728 | NEEDBITS((unsigned) bl) | 413 | while (k < (unsigned) bl) { |
729 | if ((e = (t = tl + ((unsigned) b & ml))->e) > 16) | 414 | b |= ((unsigned long)fgetc(in_file)) << k; |
730 | do { | 415 | k += 8; |
731 | if (e == 99) | 416 | } |
732 | return 1; | 417 | if ((e = (t = tl + ((unsigned) b & ml))->e) > 16) |
733 | DUMPBITS(t->b) | 418 | do { |
734 | e -= 16; | 419 | if (e == 99) { |
735 | NEEDBITS(e) | 420 | return 1; |
736 | } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) | 421 | } |
737 | > 16); | 422 | b >>= t->b; |
738 | DUMPBITS(t->b) | 423 | k -= t->b; |
739 | if (e == 16) { /* then it's a literal */ | 424 | e -= 16; |
740 | window[w++] = (uch) t->v.n; | 425 | while (k < e) { |
741 | Tracevv((stderr, "%c", window[w - 1])); | 426 | b |= ((unsigned long)fgetc(in_file)) << k; |
427 | k += 8; | ||
428 | } | ||
429 | } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); | ||
430 | b >>= t->b; | ||
431 | k -= t->b; | ||
432 | if (e == 16) { /* then it's a literal */ | ||
433 | window[w++] = (unsigned char) t->v.n; | ||
742 | if (w == WSIZE) { | 434 | if (w == WSIZE) { |
743 | // flush_output(w); | 435 | // flush_output(w); |
744 | outcnt=(w), | 436 | outcnt=(w), |
@@ -748,41 +440,50 @@ int bl, bd; /* number of bits decoded by tl[] and td[] */ | |||
748 | } else { /* it's an EOB or a length */ | 440 | } else { /* it's an EOB or a length */ |
749 | 441 | ||
750 | /* exit if end of block */ | 442 | /* exit if end of block */ |
751 | if (e == 15) | 443 | if (e == 15) { |
752 | break; | 444 | break; |
445 | } | ||
753 | 446 | ||
754 | /* get length of block to copy */ | 447 | /* get length of block to copy */ |
755 | NEEDBITS(e) | 448 | while (k < e) { |
756 | n = t->v.n + ((unsigned) b & mask_bits[e]); | 449 | b |= ((unsigned long)fgetc(in_file)) << k; |
757 | DUMPBITS(e); | 450 | k += 8; |
451 | } | ||
452 | n = t->v.n + ((unsigned) b & mask_bits[e]); | ||
453 | b >>= e; | ||
454 | k -= e; | ||
758 | 455 | ||
759 | /* decode distance of block to copy */ | 456 | /* decode distance of block to copy */ |
760 | NEEDBITS((unsigned) bd) | 457 | while (k < (unsigned) bd) { |
761 | if ((e = (t = td + ((unsigned) b & md))->e) > 16) | 458 | b |= ((unsigned long)fgetc(in_file)) << k; |
459 | k += 8; | ||
460 | } | ||
461 | |||
462 | if ((e = (t = td + ((unsigned) b & md))->e) > 16) | ||
762 | do { | 463 | do { |
763 | if (e == 99) | 464 | if (e == 99) |
764 | return 1; | 465 | return 1; |
765 | DUMPBITS(t->b) | 466 | b >>= t->b; |
766 | e -= 16; | 467 | k -= t->b; |
767 | NEEDBITS(e) | 468 | e -= 16; |
768 | } | 469 | while (k < e) { |
769 | while ( | 470 | b |= ((unsigned long)fgetc(in_file)) << k; |
770 | (e = | 471 | k += 8; |
771 | (t = | 472 | } |
772 | t->v.t + ((unsigned) b & mask_bits[e]))->e) > | 473 | } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); |
773 | 16); | 474 | b >>= t->b; |
774 | DUMPBITS(t->b) | 475 | k -= t->b; |
775 | NEEDBITS(e) | 476 | while (k < e) { |
776 | d = w - t->v.n - ((unsigned) b & mask_bits[e]); | 477 | b |= ((unsigned long)fgetc(in_file)) << k; |
777 | DUMPBITS(e) | 478 | k += 8; |
778 | Tracevv((stderr, "\\[%d,%d]", w - d, n)); | 479 | } |
480 | d = w - t->v.n - ((unsigned) b & mask_bits[e]); | ||
481 | b >>= e; | ||
482 | k -= e; | ||
779 | 483 | ||
780 | /* do the copy */ | 484 | /* do the copy */ |
781 | do { | 485 | do { |
782 | n -= (e = | 486 | n -= (e = (e = WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > n ? n : e); |
783 | (e = | ||
784 | WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > | ||
785 | n ? n : e); | ||
786 | #if !defined(NOMEMCPY) && !defined(DEBUG) | 487 | #if !defined(NOMEMCPY) && !defined(DEBUG) |
787 | if (w - d >= e) { /* (this test assumes unsigned comparison) */ | 488 | if (w - d >= e) { /* (this test assumes unsigned comparison) */ |
788 | memcpy(window + w, window + d, e); | 489 | memcpy(window + w, window + d, e); |
@@ -792,12 +493,10 @@ int bl, bd; /* number of bits decoded by tl[] and td[] */ | |||
792 | #endif /* !NOMEMCPY */ | 493 | #endif /* !NOMEMCPY */ |
793 | do { | 494 | do { |
794 | window[w++] = window[d++]; | 495 | window[w++] = window[d++]; |
795 | Tracevv((stderr, "%c", window[w - 1])); | ||
796 | } while (--e); | 496 | } while (--e); |
797 | if (w == WSIZE) { | 497 | if (w == WSIZE) { |
798 | // flush_output(w); | 498 | outcnt=(w), |
799 | outcnt=(w), | 499 | flush_window(); |
800 | flush_window(); | ||
801 | w = 0; | 500 | w = 0; |
802 | } | 501 | } |
803 | } while (n); | 502 | } while (n); |
@@ -813,236 +512,365 @@ int bl, bd; /* number of bits decoded by tl[] and td[] */ | |||
813 | return 0; | 512 | return 0; |
814 | } | 513 | } |
815 | 514 | ||
816 | int inflate_fixed() | 515 | /* |
817 | /* decompress an inflated type 1 (fixed Huffman codes) block. We should | 516 | * decompress an inflated block |
818 | either replace this with a custom decoder, or at least precompute the | 517 | * e: last block flag |
819 | Huffman tables. */ | 518 | * |
820 | { | 519 | * GLOBAL VARIABLES: bb, kk, |
821 | int i; /* temporary variable */ | 520 | */ |
822 | struct huft *tl; /* literal/length code table */ | 521 | static int inflate_block(int *e) |
823 | struct huft *td; /* distance code table */ | ||
824 | int bl; /* lookup bits for tl */ | ||
825 | int bd; /* lookup bits for td */ | ||
826 | unsigned l[288]; /* length list for huft_build */ | ||
827 | |||
828 | /* set up literal table */ | ||
829 | for (i = 0; i < 144; i++) | ||
830 | l[i] = 8; | ||
831 | for (; i < 256; i++) | ||
832 | l[i] = 9; | ||
833 | for (; i < 280; i++) | ||
834 | l[i] = 7; | ||
835 | for (; i < 288; i++) /* make a complete, but wrong code set */ | ||
836 | l[i] = 8; | ||
837 | bl = 7; | ||
838 | if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) | ||
839 | return i; | ||
840 | |||
841 | /* set up distance table */ | ||
842 | for (i = 0; i < 30; i++) /* make an incomplete code set */ | ||
843 | l[i] = 5; | ||
844 | bd = 5; | ||
845 | if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) { | ||
846 | huft_free(tl); | ||
847 | return i; | ||
848 | } | ||
849 | |||
850 | /* decompress until an end-of-block code */ | ||
851 | if (inflate_codes(tl, td, bl, bd)) | ||
852 | return 1; | ||
853 | |||
854 | /* free the decoding tables, return */ | ||
855 | huft_free(tl); | ||
856 | huft_free(td); | ||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | int inflate_dynamic() | ||
861 | /* decompress an inflated type 2 (dynamic Huffman codes) block. */ | ||
862 | { | 522 | { |
863 | int dbits = 6; /* bits in base distance lookup table */ | 523 | unsigned t; /* block type */ |
864 | int lbits = 9; /* bits in base literal/length lookup table */ | 524 | register unsigned long b; /* bit buffer */ |
865 | |||
866 | int i; /* temporary variables */ | ||
867 | unsigned j; | ||
868 | unsigned l; /* last length */ | ||
869 | unsigned m; /* mask for bit lengths table */ | ||
870 | unsigned n; /* number of lengths to get */ | ||
871 | struct huft *tl; /* literal/length code table */ | ||
872 | struct huft *td; /* distance code table */ | ||
873 | int bl; /* lookup bits for tl */ | ||
874 | int bd; /* lookup bits for td */ | ||
875 | unsigned nb; /* number of bit length codes */ | ||
876 | unsigned nl; /* number of literal/length codes */ | ||
877 | unsigned nd; /* number of distance codes */ | ||
878 | |||
879 | #ifdef PKZIP_BUG_WORKAROUND | ||
880 | unsigned ll[288 + 32]; /* literal/length and distance code lengths */ | ||
881 | #else | ||
882 | unsigned ll[286 + 30]; /* literal/length and distance code lengths */ | ||
883 | #endif | ||
884 | register ulg b; /* bit buffer */ | ||
885 | register unsigned k; /* number of bits in bit buffer */ | 525 | register unsigned k; /* number of bits in bit buffer */ |
526 | static unsigned short cplens[] = { /* Copy lengths for literal codes 257..285 */ | ||
527 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | ||
528 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 | ||
529 | }; | ||
530 | /* note: see note #13 above about the 258 in this list. */ | ||
531 | static unsigned short cplext[] = { /* Extra bits for literal codes 257..285 */ | ||
532 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | ||
533 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 | ||
534 | }; /* 99==invalid */ | ||
535 | static unsigned short cpdist[] = { /* Copy offsets for distance codes 0..29 */ | ||
536 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | ||
537 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | ||
538 | 8193, 12289, 16385, 24577 | ||
539 | }; | ||
540 | static unsigned short cpdext[] = { /* Extra bits for distance codes */ | ||
541 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | ||
542 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | ||
543 | 12, 12, 13, 13 | ||
544 | }; | ||
886 | 545 | ||
887 | /* make local bit buffer */ | 546 | /* make local bit buffer */ |
888 | b = bb; | 547 | b = bb; |
889 | k = bk; | 548 | k = bk; |
890 | 549 | ||
891 | /* read in table lengths */ | 550 | /* read in last block bit */ |
892 | NEEDBITS(5) | 551 | while (k < 1) { |
893 | nl = 257 + ((unsigned) b & 0x1f); /* number of literal/length codes */ | 552 | b |= ((unsigned long)fgetc(in_file)) << k; |
894 | DUMPBITS(5) | 553 | k += 8; |
895 | NEEDBITS(5) | ||
896 | nd = 1 + ((unsigned) b & 0x1f); /* number of distance codes */ | ||
897 | DUMPBITS(5) | ||
898 | NEEDBITS(4) | ||
899 | nb = 4 + ((unsigned) b & 0xf); /* number of bit length codes */ | ||
900 | DUMPBITS(4) | ||
901 | #ifdef PKZIP_BUG_WORKAROUND | ||
902 | if (nl > 288 || nd > 32) | ||
903 | #else | ||
904 | if (nl > 286 || nd > 30) | ||
905 | #endif | ||
906 | return 1; /* bad lengths */ | ||
907 | |||
908 | /* read in bit-length-code lengths */ | ||
909 | for (j = 0; j < nb; j++) { | ||
910 | NEEDBITS(3) | ||
911 | ll[border[j]] = (unsigned) b & 7; | ||
912 | DUMPBITS(3) | ||
913 | } | 554 | } |
914 | for (; j < 19; j++) | 555 | *e = (int) b & 1; |
915 | ll[border[j]] = 0; | 556 | b >>= 1; |
916 | 557 | k -= 1; | |
917 | /* build decoding table for trees--single level, 7 bit lookup */ | 558 | |
918 | bl = 7; | 559 | /* read in block type */ |
919 | if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) { | 560 | while (k < 2) { |
920 | if (i == 1) | 561 | b |= ((unsigned long)fgetc(in_file)) << k; |
921 | huft_free(tl); | 562 | k += 8; |
922 | return i; /* incomplete code set */ | ||
923 | } | 563 | } |
924 | 564 | t = (unsigned) b & 3; | |
925 | /* read in literal and distance code lengths */ | 565 | b >>= 2; |
926 | n = nl + nd; | 566 | k -= 2; |
927 | m = mask_bits[bl]; | ||
928 | i = l = 0; | ||
929 | while ((unsigned) i < n) { | ||
930 | NEEDBITS((unsigned) bl) | ||
931 | j = (td = tl + ((unsigned) b & m))->b; | ||
932 | DUMPBITS(j) | ||
933 | j = td->v.n; | ||
934 | if (j < 16) /* length of code in bits (0..15) */ | ||
935 | ll[i++] = l = j; /* save last length in l */ | ||
936 | else if (j == 16) { /* repeat last length 3 to 6 times */ | ||
937 | NEEDBITS(2) | ||
938 | j = 3 + ((unsigned) b & 3); | ||
939 | DUMPBITS(2) | ||
940 | if ((unsigned) i + j > n) | ||
941 | return 1; | ||
942 | while (j--) | ||
943 | ll[i++] = l; | ||
944 | } else if (j == 17) { /* 3 to 10 zero length codes */ | ||
945 | NEEDBITS(3) | ||
946 | j = 3 + ((unsigned) b & 7); | ||
947 | DUMPBITS(3) | ||
948 | if ((unsigned) i + j > n) | ||
949 | return 1; | ||
950 | while (j--) | ||
951 | ll[i++] = 0; | ||
952 | l = 0; | ||
953 | } else { /* j == 18: 11 to 138 zero length codes */ | ||
954 | |||
955 | NEEDBITS(7) | ||
956 | j = 11 + ((unsigned) b & 0x7f); | ||
957 | DUMPBITS(7) | ||
958 | if ((unsigned) i + j > n) | ||
959 | return 1; | ||
960 | while (j--) | ||
961 | ll[i++] = 0; | ||
962 | l = 0; | ||
963 | } | ||
964 | } | ||
965 | |||
966 | /* free decoding table for trees */ | ||
967 | huft_free(tl); | ||
968 | 567 | ||
969 | /* restore the global bit buffer */ | 568 | /* restore the global bit buffer */ |
970 | bb = b; | 569 | bb = b; |
971 | bk = k; | 570 | bk = k; |
972 | 571 | ||
973 | /* build the decoding tables for literal/length and distance codes */ | 572 | /* inflate that block type */ |
974 | bl = lbits; | 573 | switch (t) { |
975 | if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { | 574 | case 0: /* Inflate stored */ |
976 | if (i == 1) { | 575 | { |
977 | fprintf(stderr, " incomplete literal tree\n"); | 576 | unsigned long n; /* number of bytes in block */ |
978 | huft_free(tl); | 577 | unsigned long w; /* current window position */ |
578 | register unsigned long b_stored; /* bit buffer */ | ||
579 | register unsigned long k_stored; /* number of bits in bit buffer */ | ||
580 | |||
581 | /* make local copies of globals */ | ||
582 | b_stored = bb; /* initialize bit buffer */ | ||
583 | k_stored = bk; | ||
584 | w = outcnt; /* initialize window position */ | ||
585 | |||
586 | /* go to byte boundary */ | ||
587 | n = k_stored & 7; | ||
588 | b_stored >>= n; | ||
589 | k_stored -= n; | ||
590 | |||
591 | /* get the length and its complement */ | ||
592 | while (k_stored < 16) { | ||
593 | b_stored |= ((unsigned long)fgetc(in_file)) << k_stored; | ||
594 | k_stored += 8; | ||
595 | } | ||
596 | n = ((unsigned) b_stored & 0xffff); | ||
597 | b_stored >>= 16; | ||
598 | k_stored -= 16; | ||
599 | while (k_stored < 16) { | ||
600 | b_stored |= ((unsigned long)fgetc(in_file)) << k_stored; | ||
601 | k_stored += 8; | ||
602 | } | ||
603 | if (n != (unsigned) ((~b_stored) & 0xffff)) { | ||
604 | return 1; /* error in compressed data */ | ||
605 | } | ||
606 | b_stored >>= 16; | ||
607 | k_stored -= 16; | ||
608 | |||
609 | /* read and output the compressed data */ | ||
610 | while (n--) { | ||
611 | while (k_stored < 8) { | ||
612 | b_stored |= ((unsigned long)fgetc(in_file)) << k_stored; | ||
613 | k_stored += 8; | ||
614 | } | ||
615 | window[w++] = (unsigned char) b_stored; | ||
616 | if (w == (unsigned long)WSIZE) { | ||
617 | outcnt=(w), | ||
618 | flush_window(); | ||
619 | w = 0; | ||
620 | } | ||
621 | b_stored >>= 8; | ||
622 | k_stored -= 8; | ||
623 | } | ||
624 | |||
625 | /* restore the globals from the locals */ | ||
626 | outcnt = w; /* restore global window pointer */ | ||
627 | bb = b_stored; /* restore global bit buffer */ | ||
628 | bk = k_stored; | ||
629 | return 0; | ||
979 | } | 630 | } |
980 | return i; /* incomplete code set */ | 631 | case 1: /* Inflate fixed |
981 | } | 632 | * decompress an inflated type 1 (fixed Huffman codes) block. We should |
982 | bd = dbits; | 633 | * either replace this with a custom decoder, or at least precompute the |
983 | if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { | 634 | * Huffman tables. |
984 | if (i == 1) { | 635 | */ |
985 | fprintf(stderr, " incomplete distance tree\n"); | 636 | { |
637 | int i; /* temporary variable */ | ||
638 | huft_t *tl; /* literal/length code table */ | ||
639 | huft_t *td; /* distance code table */ | ||
640 | int bl; /* lookup bits for tl */ | ||
641 | int bd; /* lookup bits for td */ | ||
642 | unsigned int l[288]; /* length list for huft_build */ | ||
643 | |||
644 | /* set up literal table */ | ||
645 | for (i = 0; i < 144; i++) { | ||
646 | l[i] = 8; | ||
647 | } | ||
648 | for (; i < 256; i++) { | ||
649 | l[i] = 9; | ||
650 | } | ||
651 | for (; i < 280; i++) { | ||
652 | l[i] = 7; | ||
653 | } | ||
654 | for (; i < 288; i++) { /* make a complete, but wrong code set */ | ||
655 | l[i] = 8; | ||
656 | } | ||
657 | bl = 7; | ||
658 | if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) { | ||
659 | return i; | ||
660 | } | ||
661 | |||
662 | /* set up distance table */ | ||
663 | for (i = 0; i < 30; i++) { /* make an incomplete code set */ | ||
664 | l[i] = 5; | ||
665 | } | ||
666 | bd = 5; | ||
667 | if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) { | ||
668 | huft_free(tl); | ||
669 | return i; | ||
670 | } | ||
671 | |||
672 | /* decompress until an end-of-block code */ | ||
673 | if (inflate_codes(tl, td, bl, bd)) | ||
674 | return 1; | ||
675 | |||
676 | /* free the decoding tables, return */ | ||
677 | huft_free(tl); | ||
986 | huft_free(td); | 678 | huft_free(td); |
679 | return 0; | ||
987 | } | 680 | } |
988 | huft_free(tl); | 681 | case 2: /* Inflate dynamic */ |
989 | return i; /* incomplete code set */ | 682 | { |
990 | } | 683 | /* Tables for deflate from PKZIP's appnote.txt. */ |
684 | static unsigned border[] = { /* Order of the bit length code lengths */ | ||
685 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 | ||
686 | }; | ||
687 | int dbits = 6; /* bits in base distance lookup table */ | ||
688 | int lbits = 9; /* bits in base literal/length lookup table */ | ||
689 | |||
690 | int i; /* temporary variables */ | ||
691 | unsigned j; | ||
692 | unsigned l; /* last length */ | ||
693 | unsigned m; /* mask for bit lengths table */ | ||
694 | unsigned n; /* number of lengths to get */ | ||
695 | huft_t *tl; /* literal/length code table */ | ||
696 | huft_t *td; /* distance code table */ | ||
697 | int bl; /* lookup bits for tl */ | ||
698 | int bd; /* lookup bits for td */ | ||
699 | unsigned nb; /* number of bit length codes */ | ||
700 | unsigned nl; /* number of literal/length codes */ | ||
701 | unsigned nd; /* number of distance codes */ | ||
702 | |||
703 | unsigned ll[286 + 30]; /* literal/length and distance code lengths */ | ||
704 | register unsigned long b_dynamic; /* bit buffer */ | ||
705 | register unsigned k_dynamic; /* number of bits in bit buffer */ | ||
706 | |||
707 | /* make local bit buffer */ | ||
708 | b_dynamic = bb; | ||
709 | k_dynamic = bk; | ||
710 | |||
711 | /* read in table lengths */ | ||
712 | while (k_dynamic < 5) { | ||
713 | b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; | ||
714 | k_dynamic += 8; | ||
715 | } | ||
716 | nl = 257 + ((unsigned) b_dynamic & 0x1f); /* number of literal/length codes */ | ||
717 | b_dynamic >>= 5; | ||
718 | k_dynamic -= 5; | ||
719 | while (k_dynamic < 5) { | ||
720 | b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; | ||
721 | k_dynamic += 8; | ||
722 | } | ||
723 | nd = 1 + ((unsigned) b_dynamic & 0x1f); /* number of distance codes */ | ||
724 | b_dynamic >>= 5; | ||
725 | k_dynamic -= 5; | ||
726 | while (k_dynamic < 4) { | ||
727 | b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; | ||
728 | k_dynamic += 8; | ||
729 | } | ||
730 | nb = 4 + ((unsigned) b_dynamic & 0xf); /* number of bit length codes */ | ||
731 | b_dynamic >>= 4; | ||
732 | k_dynamic -= 4; | ||
733 | if (nl > 286 || nd > 30) { | ||
734 | return 1; /* bad lengths */ | ||
735 | } | ||
991 | 736 | ||
992 | /* decompress until an end-of-block code */ | 737 | /* read in bit-length-code lengths */ |
993 | if (inflate_codes(tl, td, bl, bd)) | 738 | for (j = 0; j < nb; j++) { |
994 | return 1; | 739 | while (k_dynamic < 3) { |
740 | b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; | ||
741 | k_dynamic += 8; | ||
742 | } | ||
743 | ll[border[j]] = (unsigned) b_dynamic & 7; | ||
744 | b_dynamic >>= 3; | ||
745 | k_dynamic -= 3; | ||
746 | } | ||
747 | for (; j < 19; j++) { | ||
748 | ll[border[j]] = 0; | ||
749 | } | ||
995 | 750 | ||
996 | /* free the decoding tables, return */ | 751 | /* build decoding table for trees--single level, 7 bit lookup */ |
997 | huft_free(tl); | 752 | bl = 7; |
998 | huft_free(td); | 753 | if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) { |
999 | return 0; | 754 | if (i == 1) { |
1000 | } | 755 | huft_free(tl); |
756 | } | ||
757 | return i; /* incomplete code set */ | ||
758 | } | ||
1001 | 759 | ||
1002 | /* decompress an inflated block */ | 760 | /* read in literal and distance code lengths */ |
1003 | int inflate_block(e) | 761 | n = nl + nd; |
1004 | int *e; /* last block flag */ | 762 | m = mask_bits[bl]; |
1005 | { | 763 | i = l = 0; |
1006 | unsigned t; /* block type */ | 764 | while ((unsigned) i < n) { |
1007 | register ulg b; /* bit buffer */ | 765 | while (k_dynamic < (unsigned) bl) { |
1008 | register unsigned k; /* number of bits in bit buffer */ | 766 | b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; |
767 | k_dynamic += 8; | ||
768 | } | ||
769 | j = (td = tl + ((unsigned) b_dynamic & m))->b; | ||
770 | b_dynamic >>= j; | ||
771 | k_dynamic -= j; | ||
772 | j = td->v.n; | ||
773 | if (j < 16) { /* length of code in bits (0..15) */ | ||
774 | ll[i++] = l = j; /* save last length in l */ | ||
775 | } | ||
776 | else if (j == 16) { /* repeat last length 3 to 6 times */ | ||
777 | while (k_dynamic < 2) { | ||
778 | b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; | ||
779 | k_dynamic += 8; | ||
780 | } | ||
781 | j = 3 + ((unsigned) b_dynamic & 3); | ||
782 | b_dynamic >>= 2; | ||
783 | k_dynamic -= 2; | ||
784 | if ((unsigned) i + j > n) { | ||
785 | return 1; | ||
786 | } | ||
787 | while (j--) { | ||
788 | ll[i++] = l; | ||
789 | } | ||
790 | } else if (j == 17) { /* 3 to 10 zero length codes */ | ||
791 | while (k_dynamic < 3) { | ||
792 | b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; | ||
793 | k_dynamic += 8; | ||
794 | } | ||
795 | j = 3 + ((unsigned) b_dynamic & 7); | ||
796 | b_dynamic >>= 3; | ||
797 | k_dynamic -= 3; | ||
798 | if ((unsigned) i + j > n) { | ||
799 | return 1; | ||
800 | } | ||
801 | while (j--) { | ||
802 | ll[i++] = 0; | ||
803 | } | ||
804 | l = 0; | ||
805 | } else { /* j == 18: 11 to 138 zero length codes */ | ||
806 | while (k_dynamic < 7) { | ||
807 | b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; | ||
808 | k_dynamic += 8; | ||
809 | } | ||
810 | j = 11 + ((unsigned) b_dynamic & 0x7f); | ||
811 | b_dynamic >>= 7; | ||
812 | k_dynamic -= 7; | ||
813 | if ((unsigned) i + j > n) { | ||
814 | return 1; | ||
815 | } | ||
816 | while (j--) { | ||
817 | ll[i++] = 0; | ||
818 | } | ||
819 | l = 0; | ||
820 | } | ||
821 | } | ||
1009 | 822 | ||
1010 | /* make local bit buffer */ | 823 | /* free decoding table for trees */ |
1011 | b = bb; | 824 | huft_free(tl); |
1012 | k = bk; | ||
1013 | 825 | ||
1014 | /* read in last block bit */ | 826 | /* restore the global bit buffer */ |
1015 | NEEDBITS(1) | 827 | bb = b_dynamic; |
1016 | * e = (int) b & 1; | 828 | bk = k_dynamic; |
1017 | DUMPBITS(1) | ||
1018 | 829 | ||
1019 | /* read in block type */ | 830 | /* build the decoding tables for literal/length and distance codes */ |
1020 | NEEDBITS(2) | 831 | bl = lbits; |
1021 | t = (unsigned) b & 3; | 832 | if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { |
1022 | DUMPBITS(2) | 833 | if (i == 1) { |
834 | error_msg("Incomplete literal tree"); | ||
835 | huft_free(tl); | ||
836 | } | ||
837 | return i; /* incomplete code set */ | ||
838 | } | ||
839 | bd = dbits; | ||
840 | if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { | ||
841 | if (i == 1) { | ||
842 | error_msg("incomplete distance tree"); | ||
843 | huft_free(td); | ||
844 | } | ||
845 | huft_free(tl); | ||
846 | return i; /* incomplete code set */ | ||
847 | } | ||
1023 | 848 | ||
1024 | /* restore the global bit buffer */ | 849 | /* decompress until an end-of-block code */ |
1025 | bb = b; | 850 | if (inflate_codes(tl, td, bl, bd)) |
1026 | bk = k; | 851 | return 1; |
1027 | 852 | ||
1028 | /* inflate that block type */ | 853 | /* free the decoding tables, return */ |
1029 | if (t == 2) | 854 | huft_free(tl); |
1030 | return inflate_dynamic(); | 855 | huft_free(td); |
1031 | if (t == 0) | 856 | return 0; |
1032 | return inflate_stored(); | 857 | } |
1033 | if (t == 1) | 858 | default: |
1034 | return inflate_fixed(); | 859 | /* bad block type */ |
1035 | 860 | return 2; | |
1036 | /* bad block type */ | 861 | } |
1037 | return 2; | ||
1038 | } | 862 | } |
1039 | 863 | ||
1040 | int inflate() | 864 | /* |
1041 | /* decompress an inflated entry */ | 865 | * decompress an inflated entry |
866 | * | ||
867 | * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr | ||
868 | */ | ||
869 | static int inflate() | ||
1042 | { | 870 | { |
1043 | int e; /* last block flag */ | 871 | int e; /* last block flag */ |
1044 | int r; /* result code */ | 872 | int r; /* result code */ |
1045 | unsigned h; /* maximum struct huft's malloc'ed */ | 873 | unsigned h = 0; /* maximum struct huft's malloc'ed */ |
1046 | 874 | ||
1047 | /* initialize window, bit buffer */ | 875 | /* initialize window, bit buffer */ |
1048 | outcnt = 0; | 876 | outcnt = 0; |
@@ -1050,30 +878,20 @@ int inflate() | |||
1050 | bb = 0; | 878 | bb = 0; |
1051 | 879 | ||
1052 | /* decompress until the last block */ | 880 | /* decompress until the last block */ |
1053 | h = 0; | ||
1054 | do { | 881 | do { |
1055 | hufts = 0; | 882 | hufts = 0; |
1056 | if ((r = inflate_block(&e)) != 0) | 883 | if ((r = inflate_block(&e)) != 0) { |
1057 | return r; | 884 | return r; |
1058 | if (hufts > h) | 885 | } |
886 | if (hufts > h) { | ||
1059 | h = hufts; | 887 | h = hufts; |
888 | } | ||
1060 | } while (!e); | 889 | } while (!e); |
1061 | 890 | ||
1062 | /* Undo too much lookahead. The next read will be byte aligned so we | ||
1063 | * can discard unused bits in the last meaningful byte. | ||
1064 | */ | ||
1065 | while (bk >= 8) { | ||
1066 | bk -= 8; | ||
1067 | inptr--; | ||
1068 | } | ||
1069 | |||
1070 | /* flush out window */ | 891 | /* flush out window */ |
1071 | outcnt=(outcnt), | ||
1072 | flush_window(); | 892 | flush_window(); |
893 | |||
1073 | /* return success */ | 894 | /* return success */ |
1074 | #ifdef DEBUG | ||
1075 | fprintf(stderr, "<%u> ", h); | ||
1076 | #endif /* DEBUG */ | ||
1077 | return 0; | 895 | return 0; |
1078 | } | 896 | } |
1079 | 897 | ||
@@ -1083,33 +901,89 @@ int inflate() | |||
1083 | * IN assertions: the buffer inbuf contains already the beginning of | 901 | * IN assertions: the buffer inbuf contains already the beginning of |
1084 | * the compressed data, from offsets inptr to insize-1 included. | 902 | * the compressed data, from offsets inptr to insize-1 included. |
1085 | * The magic header has already been checked. The output buffer is cleared. | 903 | * The magic header has already been checked. The output buffer is cleared. |
904 | * in, out: input and output file descriptors | ||
1086 | */ | 905 | */ |
1087 | extern int unzip(in, out) | 906 | extern int unzip(FILE *l_in_file, FILE *l_out_file) |
1088 | int in, out; /* input and output file descriptors */ | ||
1089 | { | 907 | { |
1090 | int ext_header = 0; /* set if extended local header */ | 908 | const int extra_field = 0x04; /* bit 2 set: extra field present */ |
1091 | int pkzip = 0; /* set for a pkzip file */ | 909 | const int orig_name = 0x08; /* bit 3 set: original file name present */ |
1092 | ulg orig_crc = 0; /* original crc */ | 910 | const int comment = 0x10; /* bit 4 set: file comment present */ |
1093 | ulg orig_len = 0; /* original uncompressed length */ | 911 | unsigned char buf[8]; /* extended local header */ |
1094 | int n; | 912 | unsigned char flags; /* compression flags */ |
1095 | uch buf[EXTHDR]; /* extended local header */ | 913 | char magic[2]; /* magic header */ |
914 | int method; | ||
915 | typedef void (*sig_type) (int); | ||
916 | int exit_code=0; /* program exit code */ | ||
1096 | 917 | ||
1097 | ifd = in; | 918 | in_file = l_in_file; |
1098 | ofd = out; | 919 | out_file = l_out_file; |
1099 | method = get_method(ifd); | 920 | |
1100 | if (method < 0) { | 921 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) { |
1101 | exit(exit_code); /* error message already emitted */ | 922 | (void) signal(SIGINT, (sig_type) abort_gzip); |
923 | } | ||
924 | #ifdef SIGTERM | ||
925 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { | ||
926 | (void) signal(SIGTERM, (sig_type) abort_gzip); | ||
927 | } | ||
928 | #endif | ||
929 | #ifdef SIGHUP | ||
930 | if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { | ||
931 | (void) signal(SIGHUP, (sig_type) abort_gzip); | ||
1102 | } | 932 | } |
933 | #endif | ||
934 | |||
935 | /* Allocate all global buffers (for DYN_ALLOC option) */ | ||
936 | window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); | ||
937 | outcnt = 0; | ||
938 | bytes_out = 0L; | ||
939 | |||
940 | /* set the buffer size */ | ||
941 | setvbuf(in_file, NULL, _IOFBF, 0x8000); | ||
1103 | 942 | ||
1104 | updcrc(NULL, 0); /* initialize crc */ | 943 | magic[0] = fgetc(in_file); |
944 | magic[1] = fgetc(in_file); | ||
1105 | 945 | ||
1106 | if (pkzip && !ext_header) { /* crc and length at the end otherwise */ | 946 | /* Magic header for gzip files, 1F 8B = \037\213 */ |
1107 | orig_crc = LG(inbuf + LOCCRC); | 947 | if (memcmp(magic, "\037\213", 2) != 0) { |
1108 | orig_len = LG(inbuf + LOCLEN); | 948 | error_msg("Invalid gzip magic"); |
949 | return EXIT_FAILURE; | ||
1109 | } | 950 | } |
1110 | 951 | ||
952 | method = (int) fgetc(in_file); | ||
953 | if (method != 8) { | ||
954 | error_msg("unknown method %d -- get newer version of gzip", method); | ||
955 | exit_code = 1; | ||
956 | return -1; | ||
957 | } | ||
958 | |||
959 | flags = (unsigned char) fgetc(in_file); | ||
960 | |||
961 | /* Ignore time stamp(4), extra flags(1), OS type(1) */ | ||
962 | fseek(in_file, 6, SEEK_CUR); | ||
963 | |||
964 | if ((flags & extra_field) != 0) { | ||
965 | fseek(in_file, (size_t) fgetc(in_file) + ((size_t)fgetc(in_file) << 8), SEEK_CUR); | ||
966 | } | ||
967 | |||
968 | /* Discard original name if any */ | ||
969 | if ((flags & orig_name) != 0) { | ||
970 | while (fgetc(in_file) != 0); /* null */ | ||
971 | } | ||
972 | |||
973 | /* Discard file comment if any */ | ||
974 | if ((flags & comment) != 0) { | ||
975 | while (fgetc(in_file) != 0); /* null */ | ||
976 | } | ||
977 | |||
978 | if (method < 0) { | ||
979 | printf("it failed\n"); | ||
980 | return(exit_code); /* error message already emitted */ | ||
981 | } | ||
982 | |||
983 | make_crc_table(); | ||
984 | |||
1111 | /* Decompress */ | 985 | /* Decompress */ |
1112 | if (method == DEFLATED) { | 986 | if (method == 8) { |
1113 | 987 | ||
1114 | int res = inflate(); | 988 | int res = inflate(); |
1115 | 989 | ||
@@ -1123,241 +997,193 @@ int in, out; /* input and output file descriptors */ | |||
1123 | error_msg("internal error, invalid method"); | 997 | error_msg("internal error, invalid method"); |
1124 | } | 998 | } |
1125 | 999 | ||
1126 | /* Get the crc and original length */ | 1000 | /* Get the crc and original length |
1127 | if (!pkzip) { | 1001 | * crc32 (see algorithm.doc) |
1128 | /* crc32 (see algorithm.doc) | 1002 | * uncompressed input size modulo 2^32 |
1129 | * uncompressed input size modulo 2^32 | 1003 | */ |
1130 | */ | 1004 | fread(buf, 1, 8, in_file); |
1131 | for (n = 0; n < 8; n++) { | ||
1132 | buf[n] = (uch) get_byte(); /* may cause an error if EOF */ | ||
1133 | } | ||
1134 | orig_crc = LG(buf); | ||
1135 | orig_len = LG(buf + 4); | ||
1136 | |||
1137 | } else if (ext_header) { /* If extended header, check it */ | ||
1138 | /* signature - 4bytes: 0x50 0x4b 0x07 0x08 | ||
1139 | * CRC-32 value | ||
1140 | * compressed size 4-bytes | ||
1141 | * uncompressed size 4-bytes | ||
1142 | */ | ||
1143 | for (n = 0; n < EXTHDR; n++) { | ||
1144 | buf[n] = (uch) get_byte(); /* may cause an error if EOF */ | ||
1145 | } | ||
1146 | orig_crc = LG(buf + 4); | ||
1147 | orig_len = LG(buf + 12); | ||
1148 | } | ||
1149 | 1005 | ||
1150 | /* Validate decompression */ | 1006 | /* Validate decompression - crc */ |
1151 | if (orig_crc != updcrc(outbuf, 0)) { | 1007 | if (((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { |
1152 | error_msg("invalid compressed data--crc error"); | 1008 | error_msg("invalid compressed data--crc error"); |
1153 | } | 1009 | } |
1154 | if (orig_len != (ulg) bytes_out) { | 1010 | /* Validate decompression - size */ |
1011 | if (((buf[4] | (buf[5] << 8)) |((buf[6] | (buf[7] << 8)) << 16)) != (unsigned long) bytes_out) { | ||
1155 | error_msg("invalid compressed data--length error"); | 1012 | error_msg("invalid compressed data--length error"); |
1156 | } | 1013 | } |
1157 | 1014 | ||
1158 | /* Check if there are more entries in a pkzip file */ | 1015 | free(window); |
1159 | if (pkzip && inptr + 4 < insize && LG(inbuf + inptr) == LOCSIG) { | 1016 | free(crc_table); |
1160 | error_msg("has more than one entry--rest ignored"); | ||
1161 | if (exit_code == OK) | ||
1162 | exit_code = WARNING; | ||
1163 | } | ||
1164 | ext_header = pkzip = 0; /* for next file */ | ||
1165 | return OK; | ||
1166 | } | ||
1167 | 1017 | ||
1168 | 1018 | return 0; | |
1169 | /* =========================================================================== | ||
1170 | * Clear input and output buffers | ||
1171 | */ | ||
1172 | void clear_bufs(void) | ||
1173 | { | ||
1174 | outcnt = 0; | ||
1175 | insize = inptr = 0; | ||
1176 | bytes_in = bytes_out = 0L; | ||
1177 | } | 1019 | } |
1178 | 1020 | ||
1179 | /* =========================================================================== | 1021 | extern FILE *gz_open(FILE *compressed_file, int *pid) |
1180 | * Initialize gunzip buffers and signals | ||
1181 | */ | ||
1182 | extern int gunzip_init() | ||
1183 | { | 1022 | { |
1184 | foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; | 1023 | int unzip_pipe[2]; |
1185 | if (foreground) { | 1024 | |
1186 | (void) signal(SIGINT, (sig_type) abort_gzip); | 1025 | signal(SIGCHLD, abort_gzip); |
1026 | if (pipe(unzip_pipe)!=0) { | ||
1027 | error_msg("pipe error"); | ||
1028 | return NULL; | ||
1187 | } | 1029 | } |
1188 | #ifdef SIGTERM | 1030 | if ((*pid = fork()) == -1) { |
1189 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { | 1031 | error_msg("fork failured"); |
1190 | (void) signal(SIGTERM, (sig_type) abort_gzip); | 1032 | return NULL; |
1191 | } | 1033 | } |
1192 | #endif | 1034 | if (*pid==0) { |
1193 | #ifdef SIGHUP | 1035 | /* child process */ |
1194 | if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { | 1036 | close(unzip_pipe[0]); |
1195 | (void) signal(SIGHUP, (sig_type) abort_gzip); | 1037 | unzip(compressed_file, fdopen(unzip_pipe[1], "w")); |
1038 | // printf("finished unzipping\n"); | ||
1039 | fflush(NULL); | ||
1040 | // printf("fluched\n"); | ||
1041 | fclose(compressed_file); | ||
1042 | close(unzip_pipe[1]); | ||
1043 | exit(EXIT_SUCCESS); | ||
1196 | } | 1044 | } |
1197 | #endif | ||
1198 | |||
1199 | /* Allocate all global buffers (for DYN_ALLOC option) */ | ||
1200 | inbuf = xmalloc((size_t)((INBUFSIZ+INBUF_EXTRA+1L)*sizeof(uch))); | ||
1201 | outbuf = xmalloc((size_t)((OUTBUFSIZ+OUTBUF_EXTRA+1L)*sizeof(uch))); | ||
1202 | d_buf = xmalloc((size_t)((DIST_BUFSIZE+1L)*sizeof(ush))); | ||
1203 | window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(uch))); | ||
1204 | tab_prefix0 = xmalloc((size_t)(((1L<<(BITS-1))+1L)*sizeof(ush))); | ||
1205 | tab_prefix1 = xmalloc((size_t)(((1L<<(BITS-1))+1L)*sizeof(ush))); | ||
1206 | 1045 | ||
1207 | clear_bufs(); /* clear input and output buffers */ | 1046 | close(unzip_pipe[1]); |
1208 | part_nb = 0; | 1047 | return (fdopen(unzip_pipe[0], "r")); |
1209 | return(EXIT_SUCCESS); | ||
1210 | } | 1048 | } |
1211 | 1049 | ||
1212 | 1050 | extern void gz_close(int gunzip_pid) | |
1213 | /* ======================================================================== */ | ||
1214 | int gunzip_main(int argc, char **argv) | ||
1215 | { | 1051 | { |
1216 | int tostdout = 0; | 1052 | if (kill(gunzip_pid, SIGTERM) == -1) { |
1217 | int fromstdin = 0; | 1053 | error_msg_and_die("*** Couldnt kill old gunzip process *** aborting"); |
1218 | int result; | 1054 | } |
1219 | int inFileNum; | ||
1220 | int outFileNum; | ||
1221 | int delInputFile = 0; | ||
1222 | int force = 0; | ||
1223 | struct stat statBuf; | ||
1224 | char *delFileName; | ||
1225 | RESERVE_BB_BUFFER(ifname, MAX_PATH_LEN+1); /* input file name */ | ||
1226 | RESERVE_BB_BUFFER(ofname, MAX_PATH_LEN+1); /* output file name */ | ||
1227 | |||
1228 | method = DEFLATED; /* default compression method */ | ||
1229 | exit_code = OK; /* let's go out on a limb and assume everything will run fine (wink wink) */ | ||
1230 | 1055 | ||
1231 | if (strcmp(applet_name, "zcat") == 0) { | 1056 | if (waitpid(gunzip_pid, NULL, 0) == -1) { |
1232 | force = 1; | 1057 | printf("Couldnt wait ?"); |
1233 | tostdout = 1; | ||
1234 | } | 1058 | } |
1059 | free(window); | ||
1060 | free(crc_table); | ||
1061 | } | ||
1062 | |||
1063 | extern int gunzip_main(int argc, char **argv) | ||
1064 | { | ||
1065 | struct stat stat_buf; | ||
1066 | |||
1067 | char *if_name = NULL; | ||
1068 | char *of_name = NULL; | ||
1069 | char *delete_file_name = NULL; | ||
1070 | |||
1071 | const int gunzip_to_stdout = 1; | ||
1072 | const int gunzip_from_stdin = 2; | ||
1073 | const int gunzip_force = 4; | ||
1074 | const int gunzip_test = 8; | ||
1235 | 1075 | ||
1236 | /* Parse any options */ | 1076 | int flags = 0; |
1237 | while (--argc > 0 && **(++argv) == '-') { | 1077 | int opt = 0; |
1238 | if (*((*argv) + 1) == '\0') { | 1078 | int delete_old_file = FALSE; |
1239 | tostdout = 1; | 1079 | |
1080 | #ifdef BB_ZCAT | ||
1081 | /* if called as zcat */ | ||
1082 | if (strcmp(applet_name, "zcat") == 0) { | ||
1083 | if (argc != 2) { | ||
1084 | show_usage(); | ||
1085 | } | ||
1086 | flags |= gunzip_force; | ||
1087 | flags |= gunzip_to_stdout; | ||
1088 | } else | ||
1089 | #endif | ||
1090 | { | ||
1091 | /* workout flags as regular gunzip */ | ||
1092 | /* set default flags */ | ||
1093 | if (argc == 1) { | ||
1094 | flags |= (gunzip_from_stdin | gunzip_to_stdout); | ||
1240 | } | 1095 | } |
1241 | while (*(++(*argv))) { | 1096 | |
1242 | switch (**argv) { | 1097 | /* Parse any options */ |
1098 | while ((opt = getopt(argc, argv, "ctfh")) != -1) { | ||
1099 | switch (opt) { | ||
1243 | case 'c': | 1100 | case 'c': |
1244 | tostdout = 1; | 1101 | flags |= gunzip_to_stdout; |
1245 | break; | ||
1246 | case 't': | ||
1247 | test_mode = 1; | ||
1248 | break; | 1102 | break; |
1249 | case 'f': | 1103 | case 'f': |
1250 | force = 1; | 1104 | flags |= gunzip_force; |
1105 | break; | ||
1106 | case 't': | ||
1107 | flags |= gunzip_test; | ||
1251 | break; | 1108 | break; |
1109 | case 'h': | ||
1252 | default: | 1110 | default: |
1253 | show_usage(); | 1111 | show_usage(); /* exit's inside usage */ |
1254 | } | 1112 | } |
1255 | } | 1113 | } |
1256 | } | 1114 | } |
1257 | 1115 | ||
1258 | if (argc <= 0) { | 1116 | /* Set input filename and number */ |
1259 | tostdout = 1; | 1117 | if (flags & gunzip_from_stdin) { |
1260 | fromstdin = 1; | 1118 | in_file = stdin; |
1261 | } | 1119 | if ((flags & gunzip_force) == 0) { |
1262 | 1120 | error_msg_and_die("data not written to terminal. Use -f to force it."); | |
1263 | if (isatty(fileno(stdin)) && fromstdin==1 && force==0) | ||
1264 | error_msg_and_die( "data not read from terminal. Use -f to force it."); | ||
1265 | if (isatty(fileno(stdout)) && tostdout==1 && force==0) | ||
1266 | error_msg_and_die( "data not written to terminal. Use -f to force it."); | ||
1267 | |||
1268 | gunzip_init(); | ||
1269 | |||
1270 | if (fromstdin == 1) { | ||
1271 | strcpy(ofname, "stdin"); | ||
1272 | |||
1273 | inFileNum = fileno(stdin); | ||
1274 | ifile_size = -1L; /* convention for unknown size */ | ||
1275 | } else { | ||
1276 | /* Open up the input file */ | ||
1277 | if (argc <= 0) | ||
1278 | show_usage(); | ||
1279 | if (strlen(*argv) > MAX_PATH_LEN) { | ||
1280 | error_msg(name_too_long); | ||
1281 | exit(WARNING); | ||
1282 | } | 1121 | } |
1283 | strcpy(ifname, *argv); | 1122 | strcpy(if_name, "stdin"); |
1123 | } else { | ||
1124 | if_name = strdup(argv[optind]); | ||
1125 | /* Open input file */ | ||
1126 | in_file = xfopen(if_name, "r"); | ||
1284 | 1127 | ||
1285 | /* Open input fille */ | ||
1286 | inFileNum = open(ifname, O_RDONLY); | ||
1287 | if (inFileNum < 0) { | ||
1288 | perror(ifname); | ||
1289 | exit(WARNING); | ||
1290 | } | ||
1291 | /* Get the time stamp on the input file. */ | 1128 | /* Get the time stamp on the input file. */ |
1292 | result = stat(ifname, &statBuf); | 1129 | if (stat(if_name, &stat_buf) < 0) { |
1293 | if (result < 0) { | 1130 | error_msg_and_die("Couldnt stat file %s",if_name); |
1294 | perror(ifname); | ||
1295 | exit(WARNING); | ||
1296 | } | 1131 | } |
1297 | ifile_size = statBuf.st_size; | ||
1298 | } | 1132 | } |
1299 | 1133 | ||
1300 | if (tostdout == 1) { | 1134 | /* Set output filename and number */ |
1301 | /* And get to work */ | 1135 | if (flags & gunzip_to_stdout) { |
1302 | strcpy(ofname, "stdout"); | 1136 | out_file = stdout; |
1303 | outFileNum = fileno(stdout); | 1137 | /* whats the best way to do this with streams ? */ |
1304 | 1138 | if (isatty(fileno(out_file)) && ((flags & gunzip_force) == 0)) { | |
1305 | /* Actually do the compression/decompression. */ | 1139 | error_msg_and_die("data not written to terminal. Use -f to force it."); |
1306 | unzip(inFileNum, outFileNum); | 1140 | } |
1307 | 1141 | ||
1308 | } else if (test_mode) { | 1142 | strcpy(of_name, "stdout"); |
1309 | /* Actually do the compression/decompression. */ | 1143 | } else if (flags & gunzip_test) { |
1310 | unzip(inFileNum, 2); | 1144 | out_file = xfopen("/dev/null", "w"); /* why does test use filenum 2 ? */ |
1311 | } else { | 1145 | } else { |
1312 | char *pos; | 1146 | char *extension; |
1313 | 1147 | int length = strlen(if_name); | |
1314 | /* And get to work */ | 1148 | |
1315 | if (strlen(ifname) > MAX_PATH_LEN - 4) { | 1149 | delete_old_file = TRUE; |
1316 | error_msg(name_too_long); | 1150 | extension = strrchr(if_name, '.'); |
1317 | exit(WARNING); | 1151 | if (strcmp(extension, ".gz") == 0) { |
1318 | } | 1152 | length -= 3; |
1319 | strcpy(ofname, ifname); | 1153 | } else if (strcmp(extension, ".tgz") == 0) { |
1320 | pos = strstr(ofname, ".gz"); | 1154 | length -= 4; |
1321 | if (pos != NULL) { | ||
1322 | *pos = '\0'; | ||
1323 | delInputFile = 1; | ||
1324 | } else { | 1155 | } else { |
1325 | pos = strstr(ofname, ".tgz"); | 1156 | error_msg_and_die("Invalid extension"); |
1326 | if (pos != NULL) { | ||
1327 | *pos = '\0'; | ||
1328 | strcat(pos, ".tar"); | ||
1329 | delInputFile = 1; | ||
1330 | } | ||
1331 | } | 1157 | } |
1158 | of_name = (char *) xcalloc(sizeof(char), length + 1); | ||
1159 | strncpy(of_name, if_name, length); | ||
1160 | |||
1161 | /* Open output file */ | ||
1162 | out_file = xfopen(of_name, "w"); | ||
1332 | 1163 | ||
1333 | /* Open output fille */ | ||
1334 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) | ||
1335 | outFileNum = open(ofname, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW); | ||
1336 | #else | ||
1337 | outFileNum = open(ofname, O_RDWR | O_CREAT | O_EXCL); | ||
1338 | #endif | ||
1339 | if (outFileNum < 0) { | ||
1340 | perror(ofname); | ||
1341 | exit(WARNING); | ||
1342 | } | ||
1343 | /* Set permissions on the file */ | 1164 | /* Set permissions on the file */ |
1344 | fchmod(outFileNum, statBuf.st_mode); | 1165 | chmod(of_name, stat_buf.st_mode); |
1345 | 1166 | } | |
1346 | /* Actually do the compression/decompression. */ | 1167 | |
1347 | result = unzip(inFileNum, outFileNum); | 1168 | /* do the decompression, and cleanup */ |
1348 | 1169 | if (unzip(in_file, out_file) == 0) { | |
1349 | close(outFileNum); | 1170 | /* Success, remove .gz file */ |
1350 | close(inFileNum); | 1171 | delete_file_name = if_name; |
1351 | /* Delete the original file */ | 1172 | } else { |
1352 | if (result == OK) | 1173 | /* remove failed attempt */ |
1353 | delFileName = ifname; | 1174 | delete_file_name = of_name; |
1354 | else | 1175 | } |
1355 | delFileName = ofname; | 1176 | |
1356 | 1177 | fclose(out_file); | |
1357 | if (delInputFile == 1 && unlink(delFileName) < 0) { | 1178 | fclose(in_file); |
1358 | perror(delFileName); | 1179 | |
1359 | return EXIT_FAILURE; | 1180 | if (delete_old_file == TRUE) { |
1181 | if (unlink(delete_file_name) < 0) { | ||
1182 | error_msg_and_die("Couldnt remove %s", delete_file_name); | ||
1360 | } | 1183 | } |
1361 | } | 1184 | } |
1362 | return(exit_code); | 1185 | |
1186 | free(of_name); | ||
1187 | |||
1188 | return(EXIT_SUCCESS); | ||
1363 | } | 1189 | } |