#ifdef RCSID
static char rcsid[] = "$Id: unzip.c,v 0.13 1993/06/10 13:29:00 jloup Exp $";
#endif
#include <config.h>
#include "tailor.h"
#include "gzip.h"
#include "crypt.h"
#define LOCSIG 0x04034b50L
#define LOCFLG 6
#define CRPFLG 1
#define EXTFLG 8
#define LOCHOW 8
#define LOCTIM 10
#define LOCCRC 14
#define LOCSIZ 18
#define LOCLEN 22
#define LOCFIL 26
#define LOCEXT 28
#define LOCHDR 30
#define EXTHDR 16
#define RAND_HEAD_LEN 12
int decrypt;
char *key;
int pkzip = 0;
int ext_header = 0;
int check_zipfile(in)
int in;
{
uch *h = inbuf + inptr;
ifd = in;
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 ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
fprintf(stderr, "\n%s: %s: encrypted file -- use unzip\n",
progname, ifname);
exit_code = ERROR;
return ERROR;
}
ext_header = (h[LOCFLG] & EXTFLG) != 0;
pkzip = 1;
return OK;
}
int unzip(in, out)
int in, out;
{
ulg orig_crc = 0;
ulg orig_len = 0;
int n;
uch buf[EXTHDR];
int err = OK;
ifd = in;
ofd = out;
updcrc(NULL, 0);
if (pkzip && !ext_header) {
orig_crc = LG(inbuf + LOCCRC);
orig_len = LG(inbuf + LOCLEN);
}
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();
put_ubyte(c);
}
flush_window();
} else {
error("internal error, invalid method");
}
if (!pkzip) {
for (n = 0; n < 8; n++) {
buf[n] = (uch)get_byte();
}
orig_crc = LG(buf);
orig_len = LG(buf+4);
} else if (ext_header) {
for (n = 0; n < EXTHDR; n++) {
buf[n] = (uch)get_byte();
}
orig_crc = LG(buf+4);
orig_len = LG(buf+12);
}
if (orig_crc != updcrc(outbuf, 0)) {
fprintf(stderr, "\n%s: %s: invalid compressed data--crc error\n",
progname, ifname);
err = ERROR;
}
if (orig_len != (ulg)(bytes_out & 0xffffffff)) {
fprintf(stderr, "\n%s: %s: invalid compressed data--length error\n",
progname, ifname);
err = ERROR;
}
if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
if (to_stdout) {
WARN((stderr,
"%s: %s has more than one entry--rest ignored\n",
progname, ifname));
} else {
fprintf(stderr,
"%s: %s has more than one entry -- unchanged\n",
progname, ifname);
err = ERROR;
}
}
ext_header = pkzip = 0;
if (err == OK) return OK;
exit_code = ERROR;
if (!test) abort_gzip();
return err;
}