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 */ 164ush SH(uch* p) { return ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)); } 165ulg 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 */ 173static void err OF((int, char *)); 174#if (defined(USE_DEFLATE64) && defined(__16BIT__)) 175static int partflush OF((uch *rawbuf, unsigned w)); 176#endif 177int main OF((int, char **)); 178 179/* Globals */ 180FILE *out; /* output file (*in moved to G struct) */ 181ulg outsiz; /* total bytes written to out */ 182int encrypted; /* flag to turn on decryption */ 183 184/* Masks for inflate.c */ 185ZCONST 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 194int 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 221static void err(n, m) 222int n; 223char *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 234static int partflush(rawbuf, w) 235uch *rawbuf; /* start of buffer area to flush */ 236extent 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 246int flush(w) /* used by inflate.c (FLUSH macro) */ 247ulg 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 269int flush(w) /* used by inflate.c (FLUSH macro) */ 270ulg 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 282int main(argc, argv) 283int argc; 284char **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} 548