Annotation of coherent/g/usr/bin/gzip/unzip.c, revision 1.1.1.1

1.1       root        1: /* unzip.c -- decompress files in gzip or pkzip format.
                      2:  * Copyright (C) 1992-1993 Jean-loup Gailly
                      3:  * This is free software; you can redistribute it and/or modify it under the
                      4:  * terms of the GNU General Public License, see the file COPYING.
                      5:  *
                      6:  * The code in this file is derived from the file funzip.c written
                      7:  * and put in the public domain by Mark Adler.
                      8:  */
                      9: 
                     10: /*
                     11:    This version can extract files in gzip or pkzip format.
                     12:    For the latter, only the first entry is extracted, and it has to be
                     13:    either deflated or stored.
                     14:  */
                     15: 
                     16: #ifndef lint
                     17: static char rcsid[] = "$Id: unzip.c,v 0.10 1993/02/24 18:23:13 jloup Exp $";
                     18: #endif
                     19: 
                     20: #include "tailor.h"
                     21: #include "gzip.h"
                     22: #include "crypt.h"
                     23: 
                     24: #include <stdio.h>
                     25: 
                     26: /* PKZIP header definitions */
                     27: #define LOCSIG 0x04034b50L      /* four-byte lead-in (lsb first) */
                     28: #define LOCFLG 6                /* offset of bit flag */
                     29: #define  CRPFLG 1               /*  bit for encrypted entry */
                     30: #define  EXTFLG 8               /*  bit for extended local header */
                     31: #define LOCHOW 8                /* offset of compression method */
                     32: #define LOCTIM 10               /* file mod time (for decryption) */
                     33: #define LOCCRC 14               /* offset of crc */
                     34: #define LOCSIZ 18               /* offset of compressed size */
                     35: #define LOCLEN 22               /* offset of uncompressed length */
                     36: #define LOCFIL 26               /* offset of file name field length */
                     37: #define LOCEXT 28               /* offset of extra field length */
                     38: #define LOCHDR 30               /* size of local header, including sig */
                     39: #define EXTHDR 16               /* size of extended local header, inc sig */
                     40: 
                     41: 
                     42: /* Globals */
                     43: 
                     44: int decrypt;      /* flag to turn on decryption */
                     45: char *key;        /* not used--needed to link crypt.c */
                     46: int pkzip = 0;    /* set for a pkzip file */
                     47: int extended = 0; /* set if extended local header */
                     48: 
                     49: /* ===========================================================================
                     50:  * Check zip file and advance inptr to the start of the compressed data.
                     51:  * Get ofname from the local header if necessary.
                     52:  */
                     53: int check_zipfile(in)
                     54:     int in;   /* input file descriptors */
                     55: {
                     56:     uch *h = inbuf + inptr; /* first local header */
                     57: 
                     58:     ifd = in;
                     59: 
                     60:     /* Check validity of local header, and skip name and extra fields */
                     61:     inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT);
                     62: 
                     63:     if (inptr > insize || LG(h) != LOCSIG) {
                     64:        error("input not a zip file or empty");
                     65:     }
                     66:     method = h[LOCHOW];
                     67:     if (method != STORED && method != DEFLATED) {
                     68:        error("first entry not deflated or stored -- use unzip");
                     69:     }
                     70: 
                     71:     /* If entry encrypted, decrypt and validate encryption header */
                     72:     if ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
                     73:        fprintf(stderr, "encrypted file, not yet supported.\n");
                     74:        exit_code = ERROR;
                     75:        return -1;
                     76:     }
                     77: 
                     78:     /* Save flags for unzip() */
                     79:     extended = (h[LOCFLG] & EXTFLG) != 0;
                     80:     pkzip = 1;
                     81: 
                     82:     /* Get ofname and time stamp from local header (to be done) */
                     83:     return 0;
                     84: }
                     85: 
                     86: /* ===========================================================================
                     87:  * Unzip in to out.  This routine works on both gzip and pkzip files.
                     88:  *
                     89:  * IN assertions: the buffer inbuf contains already the beginning of
                     90:  *   the compressed data, from offsets inptr to insize-1 included.
                     91:  *   The magic header has already been checked. The output buffer is cleared.
                     92:  */
                     93: void unzip(in, out)
                     94:     int in, out;   /* input and output file descriptors */
                     95: {
                     96:     ulg orig_crc = 0;       /* original crc */
                     97:     ulg orig_len = 0;       /* original uncompressed length */
                     98:     int n;
                     99:     uch buf[EXTHDR];        /* extended local header */
                    100: 
                    101:     ifd = in;
                    102:     ofd = out;
                    103: 
                    104:     updcrc(NULL, 0);           /* initialize crc */
                    105: 
                    106:     if (pkzip && !extended) {  /* crc and length at the end otherwise */
                    107:        orig_crc = LG(inbuf + LOCCRC);
                    108:        orig_len = LG(inbuf + LOCLEN);
                    109:     }
                    110: 
                    111:     /* Decompress */
                    112:     if (method == DEFLATED)  {
                    113: 
                    114:        int res = inflate();
                    115: 
                    116:        if (res == 3) {
                    117:            error("out of memory");
                    118:        } else if (res != 0) {
                    119:            error("invalid compressed data--format violated");
                    120:        }
                    121: 
                    122:     } else if (pkzip && method == STORED) {
                    123: 
                    124:        register ulg n = LG(inbuf + LOCLEN);
                    125: 
                    126:        if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
                    127: 
                    128:            fprintf(stderr, "len %ld, siz %ld\n", n, LG(inbuf + LOCSIZ));
                    129:            error("invalid compressed data--length mismatch");
                    130:        }
                    131:        while (n--) {
                    132:            uch c = (uch)get_byte();
                    133: #ifdef CRYPT
                    134:            if (decrypt) zdecode(c);
                    135: #endif
                    136:            put_char(c);
                    137:        }
                    138:        flush_window();
                    139:     } else {
                    140:        error("internal error, invalid method");
                    141:     }
                    142: 
                    143:     /* Get the crc and original length */
                    144:     if (!pkzip) {
                    145:         /* crc32  (see algorithm.doc)
                    146:         * uncompressed input size modulo 2^32
                    147:          */
                    148:        for (n = 0; n < 8; n++) {
                    149:            buf[n] = (uch)get_byte(); /* may cause an error if EOF */
                    150:        }
                    151:        orig_crc = LG(buf);
                    152:        orig_len = LG(buf+4);
                    153: 
                    154:     } else if (extended) {  /* If extended header, check it */
                    155:        /* signature - 4bytes: 0x50 0x4b 0x07 0x08
                    156:         * CRC-32 value
                    157:          * compressed size 4-bytes
                    158:          * uncompressed size 4-bytes
                    159:         */
                    160:        for (n = 0; n < EXTHDR; n++) {
                    161:            buf[n] = (uch)get_byte(); /* may cause an error if EOF */
                    162:        }
                    163:        orig_crc = LG(buf+4);
                    164:        orig_len = LG(buf+12);
                    165:     }
                    166: 
                    167:     /* Validate decompression */
                    168:     if (orig_crc != updcrc(outbuf, 0)) {
                    169:        error("invalid compressed data--crc error");
                    170:     }
                    171:     if (orig_len != bytes_out) {
                    172:        error("invalid compressed data--length error");
                    173:     }
                    174: 
                    175:     /* Check if there are more entries in a pkzip file */
                    176:     if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
                    177:        if (to_stdout) {
                    178:            fprintf(stderr,
                    179:                  "warning: zip file has more than one entry--rest ignored\n");
                    180:        } else {
                    181:            /* Don't destroy the input zip file */
                    182:            error("zip file has more than one entry");
                    183:        }
                    184:     }
                    185:     extended = pkzip = 0; /* for next file */
                    186: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.