?? unzip.c
字號:
/* unzip.c -- decompress files in gzip or pkzip format. * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. * * The code in this file is derived from the file funzip.c written * and put in the public domain by Mark Adler. *//* This version can extract files in gzip or pkzip format. For the latter, only the first entry is extracted, and it has to be either deflated or stored. */#ifdef RCSIDstatic char rcsid[] = "$Id: unzip.c,v 0.13 1993/06/10 13:29:00 jloup Exp $";#endif#define RAND_HEAD_LEN 12#include "tailor.h"#include "gzip.h"#include "crypt.h"/* PKZIP header definitions */#define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */#define LOCFLG 6 /* offset of bit flag */#define CRPFLG 1 /* bit for encrypted entry */#define EXTFLG 8 /* bit for extended local header */#define LOCHOW 8 /* offset of compression method */#define LOCTIM 10 /* file mod time (for decryption) */#define LOCCRC 14 /* offset of crc */#define LOCSIZ 18 /* offset of compressed size */#define LOCLEN 22 /* offset of uncompressed length */#define LOCFIL 26 /* offset of file name field length */#define LOCEXT 28 /* offset of extra field length */#define LOCHDR 30 /* size of local header, including sig */#define EXTHDR 16 /* size of extended local header, inc sig *//* Globals */int decrypt; /* flag to turn on decryption */char *key; /* not used--needed to link crypt.c */int pkzip = 0; /* set for a pkzip file */int ext_header = 0; /* set if extended local header *//* =========================================================================== * Check zip file and advance inptr to the start of the compressed data. * Get ofname from the local header if necessary. */int check_zipfile(){ uch *h = inbuf + inptr; /* first local header */ /* Check validity of local header, and skip name and extra fields */ inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT); if (inptr > insize || LG(h) != LOCSIG) { fprintf(stderr, "\n%s: %s: not a valid zip file\n", progname, ifname); exit_code = ERROR; return ERROR; } method = h[LOCHOW]; if (method != STORED && method != DEFLATED) { fprintf(stderr, "\n%s: %s: first entry not deflated or stored -- use unzip\n", progname, ifname); exit_code = ERROR; return ERROR; } /* If entry encrypted, decrypt and validate encryption header */ if ((decrypt = h[LOCFLG] & CRPFLG) != 0) { fprintf(stderr, "\n%s: %s: encrypted file -- use unzip\n", progname, ifname); exit_code = ERROR; return ERROR; } /* Save flags for unzip() */ ext_header = (h[LOCFLG] & EXTFLG) != 0; pkzip = 1; /* Get ofname and time stamp from local header (to be done) */ return OK;}/* =========================================================================== * Unzip in to out. This routine works on both gzip and pkzip files. * * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets inptr to insize-1 included. * The magic header has already been checked. The output buffer is cleared. */int unzip(char *in, char *outprint) /* input and output file descriptors */{ ulg orig_crc = 0; /* original crc */ ulg orig_len = 0; /* original uncompressed length */ int n; uch buf[EXTHDR]; /* extended local header */ updcrc(NULL, 0); /* initialize crc */ if (pkzip && !ext_header) { /* crc and length at the end otherwise */ orig_crc = LG(inbuf + LOCCRC); orig_len = LG(inbuf + LOCLEN); } /* Decompress */ if (method == DEFLATED) { int res = inflate(); if (res == 3) { error("out of memory"); } else if (res != 0) { error("invalid compressed data--format violated"); } } else if (pkzip && method == STORED) { register ulg n = LG(inbuf + LOCLEN); if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) { fprintf(stderr, "len %ld, siz %ld\n", n, LG(inbuf + LOCSIZ)); error("invalid compressed data--length mismatch"); } while (n--) { uch c = (uch)get_byte();#ifdef CRYPT if (decrypt) zdecode(c);#endif put_ubyte(c); } flush_window(); } else { error("internal error, invalid method"); } /* Get the crc and original length */ if (!pkzip) { /* crc32 (see algorithm.doc) * uncompressed input size modulo 2^32 */ for (n = 0; n < 8; n++) { buf[n] = (uch)get_byte(); /* may cause an error if EOF */ } orig_crc = LG(buf); orig_len = LG(buf+4); } else if (ext_header) { /* If extended header, check it */ /* signature - 4bytes: 0x50 0x4b 0x07 0x08 * CRC-32 value * compressed size 4-bytes * uncompressed size 4-bytes */ for (n = 0; n < EXTHDR; n++) { buf[n] = (uch)get_byte(); /* may cause an error if EOF */ } orig_crc = LG(buf+4); orig_len = LG(buf+12); } /* Validate decompression */ if (orig_crc != updcrc(outbuf, 0)) { error("invalid compressed data--crc error"); } if (orig_len != (ulg)bytes_out) { error("invalid compressed data--length error"); } ext_header = pkzip = 0; return OK;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -