00001
00024 #include <cstdlib>
00025 #include <cstring>
00026 #include "funzipuno.hpp"
00027
00028 using namespace std;
00029
00030
00031 ulg outsiz;
00032 int encrypted;
00033 int qflag = 1;
00034
00035
00036 #define TAMCE 16384
00037 unsigned char colen[TAMCE];
00038
00039
00040 #define TAMCS 32768
00041 unsigned char colsal[TAMCS];
00042
00043
00049 ulg updcrc(uch *s, ulg n)
00050 {
00051 register ulg c;
00052
00053 static ulg crc = 0xffffffffL;
00054
00055 if (s == (uch *)NULL) {
00056 c = 0xffffffffL;
00057 } else {
00058 c = crc;
00059 while (n--) {
00060 c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
00061 }
00062 }
00063 crc = c;
00064 return c ^ 0xffffffffL;
00065 }
00066
00070 void err(int n, char *m)
00071 {
00072 fprintf(stderr, "funzip error: %s\n", m);
00073 exit(n);
00074 }
00075
00076
00080 void unzipUno(FILE *in, char *nombre, FILE *out)
00081 {
00082
00083 uch h[LOCHDR];
00084
00085 int n = getc(in);
00086 n |= getc(in) << 8;
00087 h[0] = getc(in);
00088 h[1] = getc(in);
00089 while (n == ZIPMAG && SH(h) == LOCREM) {
00090 char noma[PATH_MAX];
00091 int cn;
00092
00093 if (fread((char *)(h+2), 1, LOCHDR - 2, in) != LOCHDR - 2) {
00094 err(3, "invalid zip file");
00095 }
00096
00097 if (SH(h + LOCHOW) != Z_STORED && SH(h + LOCHOW) != Z_DEFLATED) {
00098 err(3, "first entry not deflated or stored--can't funzip");
00099 }
00100
00101
00102 cn = 0;
00103 for (n = SH(h + LOCFIL); n--; ) {
00104 int g = getc(in);
00105
00106 if (cn < PATH_MAX - 1) {
00107 noma[cn] = g;
00108 cn++;
00109 }
00110 }
00111 noma[cn] = '\0';
00112
00113 for (n = SH(h + LOCEXT); n--; ) {
00114 getc(in);
00115
00116 }
00117 encrypted = h[LOCFLG] & CRPFLG;
00118
00119
00120
00121 if (encrypted) {
00122 err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
00123 }
00124
00125
00126
00127 outsiz = 0L;
00128 updcrc(NULL, 0L);
00129 z_stream stream;
00130 int tl ;
00131
00132
00133
00134 if (h[LOCHOW]) {
00135
00136 stream.zalloc = (alloc_func)0;
00137 stream.zfree = (free_func)0;
00138 stream.opaque = (voidpf)0;
00139 int ri = inflateInit2(&stream, -MAX_WBITS);
00140 if (ri != Z_OK) {
00141 fprintf(stderr, "No pudo inicializar stream, err=%i\n",
00142 ri);
00143 exit(1);
00144 }
00145
00146 ri = Z_STREAM_END + 1;
00147
00148 int flush = 0;
00149 do {
00150 if ((tl = fread((char *)colen, 1, TAMCE, in)) < 0)
00151 err(4, "vacío");
00152
00153 stream.next_in = colen;
00154 stream.avail_in = tl;
00155 do {
00156 stream.next_out = (Bytef*)colsal;
00157 stream.avail_out = TAMCS;
00158 flush = feof(in) ? Z_FINISH : Z_NO_FLUSH;
00159 ri = inflate(&stream, flush);
00160 if (ri == Z_STREAM_ERROR) {
00161 err(4, "problema descomprimiendo");
00162 }
00163 unsigned long w =
00164 TAMCS - stream.avail_out;
00165 updcrc(colsal, w);
00166 if (strcmp(noma, nombre) == 0) {
00167 if (fwrite((char *)colsal,
00168 1, w, out) != w ||
00169 ferror(out)) {
00170 err(9, "problema al escribir");
00171 }
00172 }
00173 outsiz += w;
00174 } while (stream.avail_out == 0);
00175 } while (flush != Z_FINISH && ri != Z_STREAM_END) ;
00176 inflateEnd(&stream);
00177 } else {
00178
00179
00180 tl = 0;
00181 stream.avail_in = 0;
00182 register ulg n;
00183 n = LG(h + LOCLEN);
00184 if (n != LG(h + LOCSIZ)) {
00185 fprintf(stderr, "len %ld, siz %ld\n", n, LG(h + LOCSIZ));
00186 err(4, "invalid compressed data--length mismatch");
00187 }
00188 unsigned long nsal = 0;
00189 while (n--) {
00190 ush c = getc(in);
00191 colsal[nsal++] = (uch)c;
00192 if (nsal == TAMCS)
00193 {
00194 updcrc(colsal, nsal);
00195 if (strcmp(noma, nombre) == 0)
00196 {
00197 if (fwrite((char *)colsal, 1,
00198 nsal, out) != nsal) {
00199 err(9, "out of space on stdout");
00200 }
00201 }
00202 outsiz += nsal;
00203 nsal = 0;
00204 }
00205 }
00206 if (nsal)
00207 {
00208 updcrc(colsal, nsal);
00209 if (strcmp(noma, nombre) == 0)
00210 {
00211 if (fwrite((char *)colsal, 1, nsal, out) != nsal) {
00212 err(9, "out of space on stdout");
00213 }
00214 }
00215 outsiz += nsal;
00216 }
00217 }
00218 if (strcmp(noma, nombre) == 0) {
00219 fflush(out);
00220 }
00221
00222 if ((h[LOCFLG] & EXTFLG)) {
00223
00224 unsigned int i;
00225 for (i = 0; i < EXTHDR && i < stream.avail_in; i++) {
00226 h[LOCCRC - 4 + i] =
00227 colen[tl - stream.avail_in + i];
00228 }
00229 stream.avail_in -= i;
00230 if (i < EXTHDR) {
00231
00232 if (fread((char *)h + LOCCRC - 4 + i, 1,
00233 EXTHDR - i, in) != EXTHDR - i) {
00234 err(3, "zip file ended prematurely");
00235 }
00236 stream.avail_in = 0;
00237
00238 }
00239
00240
00241
00242
00243 }
00244
00245
00246 unsigned long int crcu = updcrc(colsal, 0L);
00247 if (LG(h + LOCCRC) != crcu) {
00248 fprintf(stderr, "invalid compressed data--crc error en %s, dio %li, se esperaba %li\n", noma, crcu, LG(h + LOCCRC));
00249 }
00250 if (LG(h + LOCLEN) != outsiz) {
00251 fprintf(stderr, "invalid compressed data--length error en %s, dio %li, se esperaba %li\n", noma, outsiz, LG(h + LOCLEN));
00252 }
00253
00254
00255 if (stream.avail_in > 0) {
00256
00257 long pa=ftell(in);
00258
00259 fseek(in, pa - stream.avail_in, SEEK_SET);
00260
00261 }
00262 if (!feof(in)) {
00263 n = getc(in);
00264 n |= getc(in) << 8;
00265 h[0] = getc(in);
00266 h[1] = getc(in);
00267 } else {
00268 n = 0;
00269 }
00270 }
00271 if (n != 0 && SH(h) != 513) {
00272
00273 err(3, "input not a zip or gzip file");
00274 }
00275 }
00276