funzipuno.cpp

Ir a la documentación de este archivo.
00001 // vim: set expandtab tabstop=8 shiftwidth=8 foldmethod=marker:
00024 #include <cstdlib>
00025 #include <cstring>
00026 #include "funzipuno.hpp"
00027 
00028 using namespace std;
00029 
00030 /* Globals */
00031 ulg outsiz;                     /* total bytes written to out */
00032 int encrypted;                  /* flag to turn on decryption */
00033 int qflag = 1;                  /* turn off messages in inflate.c */
00034 
00035 // Colchon de entrada
00036 #define TAMCE 16384
00037 unsigned char colen[TAMCE];
00038 
00039 // Colchon de salida
00040 #define TAMCS 32768
00041 unsigned char colsal[TAMCS];
00042 
00043 
00049 ulg updcrc(uch *s, ulg n)
00050 {
00051         register ulg c;       /* temporary variable */
00052 
00053         static ulg crc = 0xffffffffL; /* shift register contents */
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;       /* (instead of ~c for 64-bit machines) */
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         //fprintf(stderr, "OJO unzipUno(%p, %s, %p)\n", in, nombre, out);
00083         uch h[LOCHDR];
00084         /* read local header, check validity, and skip name and extra fields */
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                 //              printf("\n ------ \n OJO ZIPMAG n=%i, ftell=%li\n", n, ftell(in));
00093                 if (fread((char *)(h+2), 1, LOCHDR - 2, in) != LOCHDR - 2) {
00094                         err(3, "invalid zip file");
00095                 }
00096                 //              printf("OJO h=%s\n", h);
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                 //              printf("OJO lochow=%i\n", SH(h+LOCHOW));
00101                 //              printf("OJO locfil=%i\n", SH(h+LOCFIL));
00102                 cn = 0;
00103                 for (n = SH(h + LOCFIL); n--; ) {
00104                         int g = getc(in);
00105                         //                      printf("%c", (char)g);
00106                         if (cn < PATH_MAX - 1) {
00107                                 noma[cn] = g;
00108                                 cn++;
00109                         }
00110                 }
00111                 noma[cn] = '\0';
00112                 //              printf("\nOJO locext=%i\n", SH(h+LOCEXT));
00113                 for (n = SH(h + LOCEXT); n--; ) {
00114                         getc(in);
00115                         //                      printf("%c", (char)g);
00116                 }
00117                 encrypted = h[LOCFLG] & CRPFLG;
00118                 //              printf("OJO encrypted=%i\n", encrypted);
00119 
00120                 /* if entry encrypted, decrypt and validate encryption header */
00121                 if (encrypted) {
00122                         err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
00123                 }
00124 
00125 
00126                 /* prepare output buffer and crc */
00127                 outsiz = 0L;
00128                 updcrc(NULL, 0L);
00129                 z_stream stream;
00130                 int tl ;
00131 
00132 
00133                 /* decompress */
00134                 if (h[LOCHOW]) {                             /* deflated entry */
00135                         //                      printf("OJO deflated\n");
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                         //int w = 0;
00148                         int flush = 0;
00149                         do {
00150                                 if ((tl = fread((char *)colen, 1, TAMCE, in)) < 0)
00151                                         err(4, "vacío");
00152                                 //                              printf("OJO tl=%i\n", tl);
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 {                             /* stored entry */
00178 
00179                         //                      printf("OJO stored\n");
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)    /* do FlushOutput() */
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)   /* flush one last time; no need to reset outptr/outcnt */
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                         //                      printf("OJO EXTFLG stream.avail_in=%i\n", stream.avail_in);
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                                 //                              fprintf(stderr," OJO toco leer mas exthdr\n");
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                                 // no devolverse
00238                         }
00239 
00240                         /*                      if (fread((char *)h + LOCCRC - 4, 1, EXTHDR, in) != EXTHDR) {
00241                                                         err(3, "zip file ended prematurely");
00242                                                 } */
00243                 }
00244 
00245                 /* validate decompression */
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                 /* check if there are more entries */
00255                 if (stream.avail_in > 0) {
00256                         //                      fprintf(stderr, "OJO stream.avail_in = %i \n", stream.avail_in);
00257                         long pa=ftell(in);
00258                         //                      fprintf(stderr, "OJO ftell = %li \n", pa);
00259                         fseek(in, pa - stream.avail_in, SEEK_SET);
00260                         //                      fprintf(stderr, "OJO ftell = %li \n", ftell(in));
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                 //              printf("OJO n=%i\n", n);
00273                 err(3, "input not a zip or gzip file");
00274         }
00275 }
00276 

Generado el Wed Jan 6 06:58:22 2010 para Mt77 por  doxygen 1.5.4