Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6725 | siemargl | 1 | /* |
2 | Copyright (c) 1990-2009 Info-ZIP. All rights reserved. |
||
3 | |||
4 | See the accompanying file LICENSE, version 2009-Jan-02 or later |
||
5 | (the contents of which are also included in unzip.h) for terms of use. |
||
6 | If, for some reason, all these files are missing, the Info-ZIP license |
||
7 | also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html |
||
8 | */ |
||
9 | /* funzip.c -- by Mark Adler */ |
||
10 | |||
11 | #define VERSION "3.95 of 20 January 2009" |
||
12 | |||
13 | |||
14 | /* Copyright history: |
||
15 | - Starting with UnZip 5.41 of 16-April-2000, this source file |
||
16 | is covered by the Info-Zip LICENSE cited above. |
||
17 | - Prior versions of this source file, found in UnZip source packages |
||
18 | up to UnZip 5.40, were put in the public domain. |
||
19 | The original copyright note by Mark Adler was: |
||
20 | "You can do whatever you like with this source file, |
||
21 | though I would prefer that if you modify it and |
||
22 | redistribute it that you include comments to that effect |
||
23 | with your name and the date. Thank you." |
||
24 | |||
25 | History: |
||
26 | vers date who what |
||
27 | ---- --------- -------------- ------------------------------------ |
||
28 | 1.0 13 Aug 92 M. Adler really simple unzip filter. |
||
29 | 1.1 13 Aug 92 M. Adler cleaned up somewhat, give help if |
||
30 | stdin not redirected, warn if more |
||
31 | zip file entries after the first. |
||
32 | 1.2 15 Aug 92 M. Adler added check of lengths for stored |
||
33 | entries, added more help. |
||
34 | 1.3 16 Aug 92 M. Adler removed redundant #define's, added |
||
35 | decryption. |
||
36 | 1.4 27 Aug 92 G. Roelofs added exit(0). |
||
37 | 1.5 1 Sep 92 K. U. Rommel changed read/write modes for OS/2. |
||
38 | 1.6 6 Sep 92 G. Roelofs modified to use dummy crypt.c and |
||
39 | crypt.h instead of -DCRYPT. |
||
40 | 1.7 23 Sep 92 G. Roelofs changed to use DOS_OS2; included |
||
41 | crypt.c under MS-DOS. |
||
42 | 1.8 9 Oct 92 M. Adler improved inflation error msgs. |
||
43 | 1.9 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch; |
||
44 | renamed inflate_entry() to inflate(); |
||
45 | adapted to use new, in-place zdecode. |
||
46 | 2.0 22 Oct 92 M. Adler allow filename argument, prompt for |
||
47 | passwords and don't echo, still allow |
||
48 | command-line password entry, but as an |
||
49 | option. |
||
50 | 2.1 23 Oct 92 J-l. Gailly fixed crypt/store bug, |
||
51 | G. Roelofs removed crypt.c under MS-DOS, fixed |
||
52 | decryption check to compare single byte. |
||
53 | 2.2 28 Oct 92 G. Roelofs removed declaration of key. |
||
54 | 2.3 14 Dec 92 M. Adler replaced fseek (fails on stdin for SCO |
||
55 | Unix V.3.2.4). added quietflg for |
||
56 | inflate.c. |
||
57 | 3.0 11 May 93 M. Adler added gzip support |
||
58 | 3.1 9 Jul 93 K. U. Rommel fixed OS/2 pipe bug (PIPE_ERROR) |
||
59 | 3.2 4 Sep 93 G. Roelofs moved crc_32_tab[] to tables.h; used FOPx |
||
60 | from unzip.h; nuked OUTB macro and outbuf; |
||
61 | replaced flush(); inlined FlushOutput(); |
||
62 | renamed decrypt to encrypted |
||
63 | 3.3 29 Sep 93 G. Roelofs replaced ReadByte() with NEXTBYTE macro; |
||
64 | revised (restored?) flush(); added FUNZIP |
||
65 | 3.4 21 Oct 93 G. Roelofs renamed quietflg to qflag; changed outcnt, |
||
66 | H. Gessau second updcrc() arg and flush() arg to ulg; |
||
67 | added inflate_free(); added "g =" to null |
||
68 | getc(in) to avoid compiler warnings |
||
69 | 3.5 31 Oct 93 H. Gessau changed DOS_OS2 to DOS_NT_OS2 |
||
70 | 3.6 6 Dec 93 H. Gessau added "near" to mask_bits[] |
||
71 | 3.7 9 Dec 93 G. Roelofs added extent typecasts to fwrite() checks |
||
72 | 3.8 28 Jan 94 GRR/JlG initialized g variable in main() for gcc |
||
73 | 3.81 22 Feb 94 M. Hanning-Lee corrected usage message |
||
74 | 3.82 27 Feb 94 G. Roelofs added some typecasts to avoid warnings |
||
75 | 3.83 22 Jul 94 G. Roelofs changed fprintf to macro for DLLs |
||
76 | - 2 Aug 94 - public release with UnZip 5.11 |
||
77 | - 28 Aug 94 - public release with UnZip 5.12 |
||
78 | 3.84 1 Oct 94 K. U. Rommel changes for Metaware High C |
||
79 | 3.85 29 Oct 94 G. Roelofs changed fprintf macro to Info |
||
80 | 3.86 7 May 95 K. Davis RISCOS patches; |
||
81 | P. Kienitz Amiga patches |
||
82 | 3.87 12 Aug 95 G. Roelofs inflate_free(), DESTROYGLOBALS fixes |
||
83 | 3.88 4 Sep 95 C. Spieler reordered macro to work around MSC 5.1 bug |
||
84 | 3.89 22 Nov 95 PK/CS ifdef'd out updcrc() for ASM_CRC |
||
85 | 3.9 17 Dec 95 G. Roelofs modified for USE_ZLIB (new fillinbuf()) |
||
86 | - 30 Apr 96 - public release with UnZip 5.2 |
||
87 | 3.91 17 Aug 96 G. Roelofs main() -> return int (Peter Seebach) |
||
88 | 3.92 13 Apr 97 G. Roelofs minor cosmetic fixes to messages |
||
89 | - 22 Apr 97 - public release with UnZip 5.3 |
||
90 | - 31 May 97 - public release with UnZip 5.31 |
||
91 | 3.93 20 Sep 97 G. Roelofs minor cosmetic fixes to messages |
||
92 | - 3 Nov 97 - public release with UnZip 5.32 |
||
93 | - 28 Nov 98 - public release with UnZip 5.4 |
||
94 | - 16 Apr 00 - public release with UnZip 5.41 |
||
95 | - 14 Jan 01 - public release with UnZip 5.42 |
||
96 | 3.94 20 Feb 01 C. Spieler added support for Deflate64(tm) |
||
97 | 23 Mar 02 C. Spieler changed mask_bits[] type to "unsigned" |
||
98 | */ |
||
99 | |||
100 | |||
101 | /* |
||
102 | |||
103 | All funzip does is take a zipfile from stdin and decompress the |
||
104 | first entry to stdout. The entry has to be either deflated or |
||
105 | stored. If the entry is encrypted, then the decryption password |
||
106 | must be supplied on the command line as the first argument. |
||
107 | |||
108 | funzip needs to be linked with inflate.o and crypt.o compiled from |
||
109 | the unzip source. If decryption is desired, the full version of |
||
110 | crypt.c (and crypt.h) from zcrypt28.zip or later must be used. |
||
111 | |||
112 | */ |
||
113 | |||
114 | #ifndef FUNZIP |
||
115 | # define FUNZIP |
||
116 | #endif |
||
117 | #define UNZIP_INTERNAL |
||
118 | #include "unzip.h" |
||
119 | #include "crc32.h" |
||
120 | #include "crypt.h" |
||
121 | #include "ttyio.h" |
||
122 | |||
123 | #ifdef EBCDIC |
||
124 | # undef EBCDIC /* don't need ebcdic[] */ |
||
125 | #endif |
||
126 | |||
127 | #ifndef USE_ZLIB /* zlib's function is called inflate(), too */ |
||
128 | # define UZinflate inflate |
||
129 | #endif |
||
130 | |||
131 | /* PKZIP header definitions */ |
||
132 | #define ZIPMAG 0x4b50 /* two-byte zip lead-in */ |
||
133 | #define LOCREM 0x0403 /* remaining two bytes in zip signature */ |
||
134 | #define LOCSIG 0x04034b50L /* full signature */ |
||
135 | #define LOCFLG 4 /* offset of bit flag */ |
||
136 | #define CRPFLG 1 /* bit for encrypted entry */ |
||
137 | #define EXTFLG 8 /* bit for extended local header */ |
||
138 | #define LOCHOW 6 /* offset of compression method */ |
||
139 | #define LOCTIM 8 /* file mod time (for decryption) */ |
||
140 | #define LOCCRC 12 /* offset of crc */ |
||
141 | #define LOCSIZ 16 /* offset of compressed size */ |
||
142 | #define LOCLEN 20 /* offset of uncompressed length */ |
||
143 | #define LOCFIL 24 /* offset of file name field length */ |
||
144 | #define LOCEXT 26 /* offset of extra field length */ |
||
145 | #define LOCHDR 28 /* size of local header, including LOCREM */ |
||
146 | #define EXTHDR 16 /* size of extended local header, inc sig */ |
||
147 | |||
148 | /* GZIP header definitions */ |
||
149 | #define GZPMAG 0x8b1f /* two-byte gzip lead-in */ |
||
150 | #define GZPHOW 0 /* offset of method number */ |
||
151 | #define GZPFLG 1 /* offset of gzip flags */ |
||
152 | #define GZPMUL 2 /* bit for multiple-part gzip file */ |
||
153 | #define GZPISX 4 /* bit for extra field present */ |
||
154 | #define GZPISF 8 /* bit for filename present */ |
||
155 | #define GZPISC 16 /* bit for comment present */ |
||
156 | #define GZPISE 32 /* bit for encryption */ |
||
157 | #define GZPTIM 2 /* offset of Unix file modification time */ |
||
158 | #define GZPEXF 6 /* offset of extra flags */ |
||
159 | #define GZPCOS 7 /* offset of operating system compressed on */ |
||
160 | #define GZPHDR 8 /* length of minimal gzip header */ |
||
161 | |||
162 | #ifdef THEOS |
||
163 | /* Macros cause stack overflow in compiler */ |
||
164 | ush SH(uch* p) { return ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)); } |
||
165 | ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); } |
||
166 | #else /* !THEOS */ |
||
167 | /* Macros for getting two-byte and four-byte header values */ |
||
168 | #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) |
||
169 | #define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)) |
||
170 | #endif /* ?THEOS */ |
||
171 | |||
172 | /* Function prototypes */ |
||
173 | static void err OF((int, char *)); |
||
174 | #if (defined(USE_DEFLATE64) && defined(__16BIT__)) |
||
175 | static int partflush OF((uch *rawbuf, unsigned w)); |
||
176 | #endif |
||
177 | int main OF((int, char **)); |
||
178 | |||
179 | /* Globals */ |
||
180 | FILE *out; /* output file (*in moved to G struct) */ |
||
181 | ulg outsiz; /* total bytes written to out */ |
||
182 | int encrypted; /* flag to turn on decryption */ |
||
183 | |||
184 | /* Masks for inflate.c */ |
||
185 | ZCONST unsigned near mask_bits[17] = { |
||
186 | 0x0000, |
||
187 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, |
||
188 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff |
||
189 | }; |
||
190 | |||
191 | |||
192 | #ifdef USE_ZLIB |
||
193 | |||
194 | int fillinbuf(__G) |
||
195 | __GDEF |
||
196 | /* Fill input buffer for pull-model inflate() in zlib. Return the number of |
||
197 | * bytes in inbuf. */ |
||
198 | { |
||
199 | /* GRR: check return value from fread(): same as read()? check errno? */ |
||
200 | if ((G.incnt = fread((char *)G.inbuf, 1, INBUFSIZ, G.in)) <= 0) |
||
201 | return 0; |
||
202 | G.inptr = G.inbuf; |
||
203 | |||
204 | #if CRYPT |
||
205 | if (encrypted) { |
||
206 | uch *p; |
||
207 | int n; |
||
208 | |||
209 | for (n = G.incnt, p = G.inptr; n--; p++) |
||
210 | zdecode(*p); |
||
211 | } |
||
212 | #endif /* CRYPT */ |
||
213 | |||
214 | return G.incnt; |
||
215 | |||
216 | } |
||
217 | |||
218 | #endif /* USE_ZLIB */ |
||
219 | |||
220 | |||
221 | static void err(n, m) |
||
222 | int n; |
||
223 | char *m; |
||
224 | /* Exit on error with a message and a code */ |
||
225 | { |
||
226 | Info(slide, 1, ((char *)slide, "funzip error: %s\n", m)); |
||
227 | DESTROYGLOBALS(); |
||
228 | EXIT(n); |
||
229 | } |
||
230 | |||
231 | |||
232 | #if (defined(USE_DEFLATE64) && defined(__16BIT__)) |
||
233 | |||
234 | static int partflush(rawbuf, w) |
||
235 | uch *rawbuf; /* start of buffer area to flush */ |
||
236 | extent w; /* number of bytes to flush */ |
||
237 | { |
||
238 | G.crc32val = crc32(G.crc32val, rawbuf, (extent)w); |
||
239 | if (fwrite((char *)rawbuf,1,(extent)w,out) != (extent)w && !PIPE_ERROR) |
||
240 | err(9, "out of space on stdout"); |
||
241 | outsiz += w; |
||
242 | return 0; |
||
243 | } |
||
244 | |||
245 | |||
246 | int flush(w) /* used by inflate.c (FLUSH macro) */ |
||
247 | ulg w; /* number of bytes to flush */ |
||
248 | { |
||
249 | uch *rawbuf; |
||
250 | int ret; |
||
251 | |||
252 | /* On 16-bit systems (MSDOS, OS/2 1.x), the standard C library functions |
||
253 | * cannot handle writes of 64k blocks at once. For these systems, the |
||
254 | * blocks to flush are split into pieces of 32k or less. |
||
255 | */ |
||
256 | rawbuf = slide; |
||
257 | while (w > 0x8000L) { |
||
258 | ret = partflush(rawbuf, 0x8000); |
||
259 | if (ret != PK_OK) |
||
260 | return ret; |
||
261 | w -= 0x8000L; |
||
262 | rawbuf += (unsigned)0x8000; |
||
263 | } |
||
264 | return partflush(rawbuf, (extent)w); |
||
265 | } /* end function flush() */ |
||
266 | |||
267 | #else /* !(USE_DEFLATE64 && __16BIT__) */ |
||
268 | |||
269 | int flush(w) /* used by inflate.c (FLUSH macro) */ |
||
270 | ulg w; /* number of bytes to flush */ |
||
271 | { |
||
272 | G.crc32val = crc32(G.crc32val, slide, (extent)w); |
||
273 | if (fwrite((char *)slide,1,(extent)w,out) != (extent)w && !PIPE_ERROR) |
||
274 | err(9, "out of space on stdout"); |
||
275 | outsiz += w; |
||
276 | return 0; |
||
277 | } |
||
278 | |||
279 | #endif /* ?(USE_DEFLATE64 && __16BIT__) */ |
||
280 | |||
281 | |||
282 | int main(argc, argv) |
||
283 | int argc; |
||
284 | char **argv; |
||
285 | /* Given a zipfile on stdin, decompress the first entry to stdout. */ |
||
286 | { |
||
287 | ush n; |
||
288 | uch h[LOCHDR]; /* first local header (GZPHDR < LOCHDR) */ |
||
289 | int g = 0; /* true if gzip format */ |
||
290 | unsigned method = 0; /* initialized here to shut up gcc warning */ |
||
291 | #if CRYPT |
||
292 | char *s = " [-password]"; |
||
293 | char *p; /* password */ |
||
294 | #else /* !CRYPT */ |
||
295 | char *s = ""; |
||
296 | #endif /* ?CRYPT */ |
||
297 | CONSTRUCTGLOBALS(); |
||
298 | |||
299 | /* skip executable name */ |
||
300 | argc--; |
||
301 | argv++; |
||
302 | |||
303 | #if CRYPT |
||
304 | /* get the command line password, if any */ |
||
305 | p = (char *)NULL; |
||
306 | if (argc && **argv == '-') |
||
307 | { |
||
308 | argc--; |
||
309 | p = 1 + *argv++; |
||
310 | } |
||
311 | #endif /* CRYPT */ |
||
312 | |||
313 | #ifdef MALLOC_WORK |
||
314 | /* The following expression is a cooked-down simplyfication of the |
||
315 | calculation for the work area size of UnZip (see unzip.c). For |
||
316 | fUnZip, the work area does not need to match the granularity |
||
317 | of the complex unshrink structures, because it only supports |
||
318 | inflation. But, like in UnZip, the zcalloc() wrapper function |
||
319 | is needed for the allocation, to support the 64kByte buffer on |
||
320 | 16-bit systems. |
||
321 | */ |
||
322 | # define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch)) |
||
323 | # define UZ_NUMOF_CHUNKS (unsigned)( (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK ) |
||
324 | G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK); |
||
325 | # undef UZ_SLIDE_CHUNK |
||
326 | # undef UZ_NUMOF_CHUNKS |
||
327 | #endif |
||
328 | |||
329 | /* if no file argument and stdin not redirected, give the user help */ |
||
330 | if (argc == 0 && isatty(0)) |
||
331 | { |
||
332 | Info(slide, 1, ((char *)slide, "fUnZip (filter UnZip), version %s\n", |
||
333 | VERSION)); |
||
334 | Info(slide, 1, ((char *)slide, "usage: ... | funzip%s | ...\n", s)); |
||
335 | Info(slide, 1, ((char *)slide, " ... | funzip%s > outfile\n", s)); |
||
336 | Info(slide, 1, ((char *)slide, " funzip%s infile.zip > outfile\n",s)); |
||
337 | Info(slide, 1, ((char *)slide, " funzip%s infile.gz > outfile\n", s)); |
||
338 | Info(slide, 1, ((char *)slide, "Extracts to stdout the gzip file or first\ |
||
339 | zip entry of stdin or the given file.\n")); |
||
340 | DESTROYGLOBALS(); |
||
341 | EXIT(3); |
||
342 | } |
||
343 | |||
344 | /* prepare to be a binary filter */ |
||
345 | if (argc) |
||
346 | { |
||
347 | if ((G.in = fopen(*argv, FOPR)) == (FILE *)NULL) |
||
348 | err(2, "cannot find input file"); |
||
349 | } |
||
350 | else |
||
351 | { |
||
352 | #ifdef DOS_FLX_NLM_OS2_W32 |
||
353 | #if (defined(__HIGHC__) && !defined(FLEXOS)) |
||
354 | setmode(stdin, _BINARY); |
||
355 | #else |
||
356 | setmode(0, O_BINARY); /* some buggy C libraries require BOTH setmode() */ |
||
357 | #endif /* call AND the fdopen() in binary mode :-( */ |
||
358 | #endif /* DOS_FLX_NLM_OS2_W32 */ |
||
359 | |||
360 | #ifdef RISCOS |
||
361 | G.in = stdin; |
||
362 | #else |
||
363 | if ((G.in = fdopen(0, FOPR)) == (FILE *)NULL) |
||
364 | err(2, "cannot find stdin"); |
||
365 | #endif |
||
366 | } |
||
367 | |||
368 | #ifdef DOS_FLX_H68_NLM_OS2_W32 |
||
369 | #if (defined(__HIGHC__) && !defined(FLEXOS)) |
||
370 | setmode(stdout, _BINARY); |
||
371 | #else |
||
372 | setmode(1, O_BINARY); |
||
373 | #endif |
||
374 | #endif /* DOS_FLX_H68_NLM_OS2_W32 */ |
||
375 | |||
376 | #ifdef RISCOS |
||
377 | out = stdout; |
||
378 | #else |
||
379 | if ((out = fdopen(1, FOPW)) == (FILE *)NULL) |
||
380 | err(2, "cannot write to stdout"); |
||
381 | #endif |
||
382 | |||
383 | /* read local header, check validity, and skip name and extra fields */ |
||
384 | n = getc(G.in); n |= getc(G.in) << 8; |
||
385 | if (n == ZIPMAG) |
||
386 | { |
||
387 | if (fread((char *)h, 1, LOCHDR, G.in) != LOCHDR || SH(h) != LOCREM) |
||
388 | err(3, "invalid zipfile"); |
||
389 | switch (method = SH(h + LOCHOW)) { |
||
390 | case STORED: |
||
391 | case DEFLATED: |
||
392 | #ifdef USE_DEFLATE64 |
||
393 | case ENHDEFLATED: |
||
394 | #endif |
||
395 | break; |
||
396 | default: |
||
397 | err(3, "first entry not deflated or stored--cannot unpack"); |
||
398 | break; |
||
399 | } |
||
400 | for (n = SH(h + LOCFIL); n--; ) g = getc(G.in); |
||
401 | for (n = SH(h + LOCEXT); n--; ) g = getc(G.in); |
||
402 | g = 0; |
||
403 | encrypted = h[LOCFLG] & CRPFLG; |
||
404 | } |
||
405 | else if (n == GZPMAG) |
||
406 | { |
||
407 | if (fread((char *)h, 1, GZPHDR, G.in) != GZPHDR) |
||
408 | err(3, "invalid gzip file"); |
||
409 | if ((method = h[GZPHOW]) != DEFLATED && method != ENHDEFLATED) |
||
410 | err(3, "gzip file not deflated"); |
||
411 | if (h[GZPFLG] & GZPMUL) |
||
412 | err(3, "cannot handle multi-part gzip files"); |
||
413 | if (h[GZPFLG] & GZPISX) |
||
414 | { |
||
415 | n = getc(G.in); n |= getc(G.in) << 8; |
||
416 | while (n--) g = getc(G.in); |
||
417 | } |
||
418 | if (h[GZPFLG] & GZPISF) |
||
419 | while ((g = getc(G.in)) != 0 && g != EOF) ; |
||
420 | if (h[GZPFLG] & GZPISC) |
||
421 | while ((g = getc(G.in)) != 0 && g != EOF) ; |
||
422 | g = 1; |
||
423 | encrypted = h[GZPFLG] & GZPISE; |
||
424 | } |
||
425 | else |
||
426 | err(3, "input not a zip or gzip file"); |
||
427 | |||
428 | /* if entry encrypted, decrypt and validate encryption header */ |
||
429 | if (encrypted) |
||
430 | #if CRYPT |
||
431 | { |
||
432 | ush i, e; |
||
433 | |||
434 | if (p == (char *)NULL) { |
||
435 | if ((p = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL) |
||
436 | err(1, "out of memory"); |
||
437 | else if ((p = getp("Enter password: ", p, IZ_PWLEN+1)) == (char *)NULL) |
||
438 | err(1, "no tty to prompt for password"); |
||
439 | } |
||
440 | /* initialize crc_32_tab pointer for decryption */ |
||
441 | CRC_32_TAB = get_crc_table(); |
||
442 | /* prepare the decryption keys for extraction and check the password */ |
||
443 | init_keys(p); |
||
444 | for (i = 0; i < RAND_HEAD_LEN; i++) |
||
445 | e = NEXTBYTE; |
||
446 | if (e != (ush)(h[LOCFLG] & EXTFLG ? h[LOCTIM + 1] : h[LOCCRC + 3])) |
||
447 | err(3, "incorrect password for first entry"); |
||
448 | } |
||
449 | #else /* !CRYPT */ |
||
450 | err(3, "cannot decrypt entry (need to recompile with full crypt.c)"); |
||
451 | #endif /* ?CRYPT */ |
||
452 | |||
453 | /* prepare output buffer and crc */ |
||
454 | G.outptr = slide; |
||
455 | G.outcnt = 0L; |
||
456 | outsiz = 0L; |
||
457 | G.crc32val = CRCVAL_INITIAL; |
||
458 | |||
459 | /* decompress */ |
||
460 | if (g || h[LOCHOW]) |
||
461 | { /* deflated entry */ |
||
462 | int r; |
||
463 | |||
464 | #ifdef USE_ZLIB |
||
465 | /* need to allocate and prepare input buffer */ |
||
466 | if ((G.inbuf = (uch *)malloc(INBUFSIZ)) == (uch *)NULL) |
||
467 | err(1, "out of memory"); |
||
468 | #endif /* USE_ZLIB */ |
||
469 | if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) { |
||
470 | if (r == 3) |
||
471 | err(1, "out of memory"); |
||
472 | else |
||
473 | err(4, "invalid compressed data--format violated"); |
||
474 | } |
||
475 | inflate_free(__G); |
||
476 | } |
||
477 | else |
||
478 | { /* stored entry */ |
||
479 | register ulg n; |
||
480 | |||
481 | n = LG(h + LOCLEN); |
||
482 | #if CRYPT |
||
483 | if (n != LG(h + LOCSIZ) - (encrypted ? RAND_HEAD_LEN : 0)) { |
||
484 | #else |
||
485 | if (n != LG(h + LOCSIZ)) { |
||
486 | #endif |
||
487 | Info(slide, 1, ((char *)slide, "len %ld, siz %ld\n", n, LG(h + LOCSIZ))); |
||
488 | err(4, "invalid compressed data--length mismatch"); |
||
489 | } |
||
490 | while (n--) { |
||
491 | ush c = getc(G.in); |
||
492 | #if CRYPT |
||
493 | if (encrypted) |
||
494 | zdecode(c); |
||
495 | #endif |
||
496 | *G.outptr++ = (uch)c; |
||
497 | #if (defined(USE_DEFLATE64) && defined(__16BIT__)) |
||
498 | if (++G.outcnt == (WSIZE>>1)) /* do FlushOutput() */ |
||
499 | #else |
||
500 | if (++G.outcnt == WSIZE) /* do FlushOutput() */ |
||
501 | #endif |
||
502 | { |
||
503 | G.crc32val = crc32(G.crc32val, slide, (extent)G.outcnt); |
||
504 | if (fwrite((char *)slide, 1,(extent)G.outcnt,out) != (extent)G.outcnt |
||
505 | && !PIPE_ERROR) |
||
506 | err(9, "out of space on stdout"); |
||
507 | outsiz += G.outcnt; |
||
508 | G.outptr = slide; |
||
509 | G.outcnt = 0L; |
||
510 | } |
||
511 | } |
||
512 | } |
||
513 | if (G.outcnt) /* flush one last time; no need to reset G.outptr/outcnt */ |
||
514 | { |
||
515 | G.crc32val = crc32(G.crc32val, slide, (extent)G.outcnt); |
||
516 | if (fwrite((char *)slide, 1,(extent)G.outcnt,out) != (extent)G.outcnt |
||
517 | && !PIPE_ERROR) |
||
518 | err(9, "out of space on stdout"); |
||
519 | outsiz += G.outcnt; |
||
520 | } |
||
521 | fflush(out); |
||
522 | |||
523 | /* if extended header, get it */ |
||
524 | if (g) |
||
525 | { |
||
526 | if (fread((char *)h + LOCCRC, 1, 8, G.in) != 8) |
||
527 | err(3, "gzip file ended prematurely"); |
||
528 | } |
||
529 | else |
||
530 | if ((h[LOCFLG] & EXTFLG) && |
||
531 | fread((char *)h + LOCCRC - 4, 1, EXTHDR, G.in) != EXTHDR) |
||
532 | err(3, "zipfile ended prematurely"); |
||
533 | |||
534 | /* validate decompression */ |
||
535 | if (LG(h + LOCCRC) != G.crc32val) |
||
536 | err(4, "invalid compressed data--crc error"); |
||
537 | if (LG((g ? (h + LOCSIZ) : (h + LOCLEN))) != outsiz) |
||
538 | err(4, "invalid compressed data--length error"); |
||
539 | |||
540 | /* check if there are more entries */ |
||
541 | if (!g && fread((char *)h, 1, 4, G.in) == 4 && LG(h) == LOCSIG) |
||
542 | Info(slide, 1, ((char *)slide, |
||
543 | "funzip warning: zipfile has more than one entry--rest ignored\n")); |
||
544 | |||
545 | DESTROYGLOBALS(); |
||
546 | RETURN (0); |
||
547 | }>><>><>>=>><>><>><>><> |