00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifdef RCSID
00032 static char rcsid[] = "$Id: unzip.c,v 1.4 2006/11/20 08:40:34 eggert Exp $";
00033 #endif
00034
00035 #include <config.h>
00036 #include "tailor.h"
00037 #include "gzip.h"
00038 #include "crypt.h"
00039
00040
00041 #define LOCSIG 0x04034b50L
00042 #define LOCFLG 6
00043 #define CRPFLG 1
00044 #define EXTFLG 8
00045 #define LOCHOW 8
00046 #define LOCTIM 10
00047 #define LOCCRC 14
00048 #define LOCSIZ 18
00049 #define LOCLEN 22
00050 #define LOCFIL 26
00051 #define LOCEXT 28
00052 #define LOCHDR 30
00053 #define EXTHDR 16
00054 #define RAND_HEAD_LEN 12
00055
00056
00057
00058
00059 int decrypt;
00060 char *key;
00061 int pkzip = 0;
00062 int ext_header = 0;
00063
00064
00065
00066
00067
00068 int check_zipfile(in)
00069 int in;
00070 {
00071 uch *h = inbuf + inptr;
00072
00073 ifd = in;
00074
00075
00076 inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT);
00077
00078 if (inptr > insize || LG(h) != LOCSIG) {
00079 fprintf(stderr, "\n%s: %s: not a valid zip file\n",
00080 program_name, ifname);
00081 exit_code = ERROR;
00082 return ERROR;
00083 }
00084 method = h[LOCHOW];
00085 if (method != STORED && method != DEFLATED) {
00086 fprintf(stderr,
00087 "\n%s: %s: first entry not deflated or stored -- use unzip\n",
00088 program_name, ifname);
00089 exit_code = ERROR;
00090 return ERROR;
00091 }
00092
00093
00094 if ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
00095 fprintf(stderr, "\n%s: %s: encrypted file -- use unzip\n",
00096 program_name, ifname);
00097 exit_code = ERROR;
00098 return ERROR;
00099 }
00100
00101
00102 ext_header = (h[LOCFLG] & EXTFLG) != 0;
00103 pkzip = 1;
00104
00105
00106 return OK;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 int unzip(in, out)
00117 int in, out;
00118 {
00119 ulg orig_crc = 0;
00120 ulg orig_len = 0;
00121 int n;
00122 uch buf[EXTHDR];
00123 int err = OK;
00124
00125 ifd = in;
00126 ofd = out;
00127
00128 updcrc(NULL, 0);
00129
00130 if (pkzip && !ext_header) {
00131 orig_crc = LG(inbuf + LOCCRC);
00132 orig_len = LG(inbuf + LOCLEN);
00133 }
00134
00135
00136 if (method == DEFLATED) {
00137
00138 int res = inflate();
00139
00140 if (res == 3) {
00141 xalloc_die ();
00142 } else if (res != 0) {
00143 gzip_error ("invalid compressed data--format violated");
00144 }
00145
00146 } else if (pkzip && method == STORED) {
00147
00148 register ulg n = LG(inbuf + LOCLEN);
00149
00150 if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
00151
00152 fprintf(stderr, "len %ld, siz %ld\n", n, LG(inbuf + LOCSIZ));
00153 gzip_error ("invalid compressed data--length mismatch");
00154 }
00155 while (n--) {
00156 uch c = (uch)get_byte();
00157 put_ubyte(c);
00158 }
00159 flush_window();
00160 } else {
00161 gzip_error ("internal error, invalid method");
00162 }
00163
00164
00165 if (!pkzip) {
00166
00167
00168
00169 for (n = 0; n < 8; n++) {
00170 buf[n] = (uch)get_byte();
00171 }
00172 orig_crc = LG(buf);
00173 orig_len = LG(buf+4);
00174
00175 } else if (ext_header) {
00176
00177
00178
00179
00180
00181 for (n = 0; n < EXTHDR; n++) {
00182 buf[n] = (uch)get_byte();
00183 }
00184 orig_crc = LG(buf+4);
00185 orig_len = LG(buf+12);
00186 }
00187
00188
00189 if (orig_crc != updcrc(outbuf, 0)) {
00190 fprintf(stderr, "\n%s: %s: invalid compressed data--crc error\n",
00191 program_name, ifname);
00192 err = ERROR;
00193 }
00194 if (orig_len != (ulg)(bytes_out & 0xffffffff)) {
00195 fprintf(stderr, "\n%s: %s: invalid compressed data--length error\n",
00196 program_name, ifname);
00197 err = ERROR;
00198 }
00199
00200
00201 if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
00202 if (to_stdout) {
00203 WARN((stderr,
00204 "%s: %s has more than one entry--rest ignored\n",
00205 program_name, ifname));
00206 } else {
00207
00208 fprintf(stderr,
00209 "%s: %s has more than one entry -- unchanged\n",
00210 program_name, ifname);
00211 err = ERROR;
00212 }
00213 }
00214 ext_header = pkzip = 0;
00215 if (err == OK) return OK;
00216 exit_code = ERROR;
00217 if (!test) abort_gzip();
00218 return err;
00219 }