Home | History | Annotate | Line # | Download | only in minizip
minizip.c revision 1.1
      1 /*	$NetBSD: minizip.c,v 1.1 2006/01/14 20:10:58 christos Exp $	*/
      2 
      3 /*
      4    minizip.c
      5    Version 1.01e, February 12th, 2005
      6 
      7    Copyright (C) 1998-2005 Gilles Vollant
      8 */
      9 
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 #include <time.h>
     14 #include <errno.h>
     15 #include <fcntl.h>
     16 
     17 #ifdef unix
     18 # include <unistd.h>
     19 # include <utime.h>
     20 # include <sys/types.h>
     21 # include <sys/stat.h>
     22 #else
     23 # include <direct.h>
     24 # include <io.h>
     25 #endif
     26 
     27 #include "zip.h"
     28 
     29 #ifdef WIN32
     30 #define USEWIN32IOAPI
     31 #include "iowin32.h"
     32 #endif
     33 
     34 
     35 
     36 #define WRITEBUFFERSIZE (16384)
     37 #define MAXFILENAME (256)
     38 
     39 #ifdef WIN32
     40 uLong filetime(f, tmzip, dt)
     41     char *f;                /* name of file to get info on */
     42     tm_zip *tmzip;             /* return value: access, modific. and creation times */
     43     uLong *dt;             /* dostime */
     44 {
     45   int ret = 0;
     46   {
     47       FILETIME ftLocal;
     48       HANDLE hFind;
     49       WIN32_FIND_DATA  ff32;
     50 
     51       hFind = FindFirstFile(f,&ff32);
     52       if (hFind != INVALID_HANDLE_VALUE)
     53       {
     54         FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
     55         FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
     56         FindClose(hFind);
     57         ret = 1;
     58       }
     59   }
     60   return ret;
     61 }
     62 #else
     63 #ifdef unix
     64 uLong filetime(f, tmzip, dt)
     65     char *f;               /* name of file to get info on */
     66     tm_zip *tmzip;         /* return value: access, modific. and creation times */
     67     uLong *dt;             /* dostime */
     68 {
     69   int ret=0;
     70   struct stat s;        /* results of stat() */
     71   struct tm* filedate;
     72   time_t tm_t=0;
     73 
     74   if (strcmp(f,"-")!=0)
     75   {
     76     char name[MAXFILENAME+1];
     77     int len = strlen(f);
     78     if (len > MAXFILENAME)
     79       len = MAXFILENAME;
     80 
     81     strncpy(name, f,MAXFILENAME-1);
     82     /* strncpy doesnt append the trailing NULL, of the string is too long. */
     83     name[ MAXFILENAME ] = '\0';
     84 
     85     if (name[len - 1] == '/')
     86       name[len - 1] = '\0';
     87     /* not all systems allow stat'ing a file with / appended */
     88     if (stat(name,&s)==0)
     89     {
     90       tm_t = s.st_mtime;
     91       ret = 1;
     92     }
     93   }
     94   filedate = localtime(&tm_t);
     95 
     96   tmzip->tm_sec  = filedate->tm_sec;
     97   tmzip->tm_min  = filedate->tm_min;
     98   tmzip->tm_hour = filedate->tm_hour;
     99   tmzip->tm_mday = filedate->tm_mday;
    100   tmzip->tm_mon  = filedate->tm_mon ;
    101   tmzip->tm_year = filedate->tm_year;
    102 
    103   return ret;
    104 }
    105 #else
    106 uLong filetime(f, tmzip, dt)
    107     char *f;                /* name of file to get info on */
    108     tm_zip *tmzip;             /* return value: access, modific. and creation times */
    109     uLong *dt;             /* dostime */
    110 {
    111     return 0;
    112 }
    113 #endif
    114 #endif
    115 
    116 
    117 
    118 
    119 int check_exist_file(filename)
    120     const char* filename;
    121 {
    122     FILE* ftestexist;
    123     int ret = 1;
    124     ftestexist = fopen(filename,"rb");
    125     if (ftestexist==NULL)
    126         ret = 0;
    127     else
    128         fclose(ftestexist);
    129     return ret;
    130 }
    131 
    132 void do_banner()
    133 {
    134     printf("MiniZip 1.01b, demo of zLib + Zip package written by Gilles Vollant\n");
    135     printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
    136 }
    137 
    138 void do_help()
    139 {
    140     printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] file.zip [files_to_add]\n\n" \
    141            "  -o  Overwrite existing file.zip\n" \
    142            "  -a  Append to existing file.zip\n" \
    143            "  -0  Store only\n" \
    144            "  -1  Compress faster\n" \
    145            "  -9  Compress better\n\n");
    146 }
    147 
    148 /* calculate the CRC32 of a file,
    149    because to encrypt a file, we need known the CRC32 of the file before */
    150 int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
    151 {
    152    unsigned long calculate_crc=0;
    153    int err=ZIP_OK;
    154    FILE * fin = fopen(filenameinzip,"rb");
    155    unsigned long size_read = 0;
    156    unsigned long total_read = 0;
    157    if (fin==NULL)
    158    {
    159        err = ZIP_ERRNO;
    160    }
    161 
    162     if (err == ZIP_OK)
    163         do
    164         {
    165             err = ZIP_OK;
    166             size_read = (int)fread(buf,1,size_buf,fin);
    167             if (size_read < size_buf)
    168                 if (feof(fin)==0)
    169             {
    170                 printf("error in reading %s\n",filenameinzip);
    171                 err = ZIP_ERRNO;
    172             }
    173 
    174             if (size_read>0)
    175                 calculate_crc = crc32(calculate_crc,buf,size_read);
    176             total_read += size_read;
    177 
    178         } while ((err == ZIP_OK) && (size_read>0));
    179 
    180     if (fin)
    181         fclose(fin);
    182 
    183     *result_crc=calculate_crc;
    184     printf("file %s crc %x\n",filenameinzip,calculate_crc);
    185     return err;
    186 }
    187 
    188 int main(argc,argv)
    189     int argc;
    190     char *argv[];
    191 {
    192     int i;
    193     int opt_overwrite=0;
    194     int opt_compress_level=Z_DEFAULT_COMPRESSION;
    195     int zipfilenamearg = 0;
    196     char filename_try[MAXFILENAME+16];
    197     int zipok;
    198     int err=0;
    199     int size_buf=0;
    200     void* buf=NULL;
    201     const char* password=NULL;
    202 
    203 
    204     do_banner();
    205     if (argc==1)
    206     {
    207         do_help();
    208         return 0;
    209     }
    210     else
    211     {
    212         for (i=1;i<argc;i++)
    213         {
    214             if ((*argv[i])=='-')
    215             {
    216                 const char *p=argv[i]+1;
    217 
    218                 while ((*p)!='\0')
    219                 {
    220                     char c=*(p++);;
    221                     if ((c=='o') || (c=='O'))
    222                         opt_overwrite = 1;
    223                     if ((c=='a') || (c=='A'))
    224                         opt_overwrite = 2;
    225                     if ((c>='0') && (c<='9'))
    226                         opt_compress_level = c-'0';
    227 
    228                     if (((c=='p') || (c=='P')) && (i+1<argc))
    229                     {
    230                         password=argv[i+1];
    231                         i++;
    232                     }
    233                 }
    234             }
    235             else
    236                 if (zipfilenamearg == 0)
    237                     zipfilenamearg = i ;
    238         }
    239     }
    240 
    241     size_buf = WRITEBUFFERSIZE;
    242     buf = (void*)malloc(size_buf);
    243     if (buf==NULL)
    244     {
    245         printf("Error allocating memory\n");
    246         return ZIP_INTERNALERROR;
    247     }
    248 
    249     if (zipfilenamearg==0)
    250         zipok=0;
    251     else
    252     {
    253         int i,len;
    254         int dot_found=0;
    255 
    256         zipok = 1 ;
    257         strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
    258         /* strncpy doesnt append the trailing NULL, of the string is too long. */
    259         filename_try[ MAXFILENAME ] = '\0';
    260 
    261         len=(int)strlen(filename_try);
    262         for (i=0;i<len;i++)
    263             if (filename_try[i]=='.')
    264                 dot_found=1;
    265 
    266         if (dot_found==0)
    267             strcat(filename_try,".zip");
    268 
    269         if (opt_overwrite==2)
    270         {
    271             /* if the file don't exist, we not append file */
    272             if (check_exist_file(filename_try)==0)
    273                 opt_overwrite=1;
    274         }
    275         else
    276         if (opt_overwrite==0)
    277             if (check_exist_file(filename_try)!=0)
    278             {
    279                 char rep=0;
    280                 do
    281                 {
    282                     char answer[128];
    283                     int ret;
    284                     printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
    285                     ret = scanf("%1s",answer);
    286                     if (ret != 1)
    287                     {
    288                        exit(EXIT_FAILURE);
    289                     }
    290                     rep = answer[0] ;
    291                     if ((rep>='a') && (rep<='z'))
    292                         rep -= 0x20;
    293                 }
    294                 while ((rep!='Y') && (rep!='N') && (rep!='A'));
    295                 if (rep=='N')
    296                     zipok = 0;
    297                 if (rep=='A')
    298                     opt_overwrite = 2;
    299             }
    300     }
    301 
    302     if (zipok==1)
    303     {
    304         zipFile zf;
    305         int errclose;
    306 #        ifdef USEWIN32IOAPI
    307         zlib_filefunc_def ffunc;
    308         fill_win32_filefunc(&ffunc);
    309         zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
    310 #        else
    311         zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0);
    312 #        endif
    313 
    314         if (zf == NULL)
    315         {
    316             printf("error opening %s\n",filename_try);
    317             err= ZIP_ERRNO;
    318         }
    319         else
    320             printf("creating %s\n",filename_try);
    321 
    322         for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
    323         {
    324             if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
    325                   ((argv[i][1]=='o') || (argv[i][1]=='O') ||
    326                    (argv[i][1]=='a') || (argv[i][1]=='A') ||
    327                    (argv[i][1]=='p') || (argv[i][1]=='P') ||
    328                    ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
    329                   (strlen(argv[i]) == 2)))
    330             {
    331                 FILE * fin;
    332                 int size_read;
    333                 const char* filenameinzip = argv[i];
    334                 zip_fileinfo zi;
    335                 unsigned long crcFile=0;
    336 
    337                 zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
    338                 zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
    339                 zi.dosDate = 0;
    340                 zi.internal_fa = 0;
    341                 zi.external_fa = 0;
    342                 filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
    343 
    344 /*
    345                 err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
    346                                  NULL,0,NULL,0,NULL / * comment * /,
    347                                  (opt_compress_level != 0) ? Z_DEFLATED : 0,
    348                                  opt_compress_level);
    349 */
    350                 if ((password != NULL) && (err==ZIP_OK))
    351                     err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
    352 
    353                 err = zipOpenNewFileInZip3(zf,filenameinzip,&zi,
    354                                  NULL,0,NULL,0,NULL /* comment*/,
    355                                  (opt_compress_level != 0) ? Z_DEFLATED : 0,
    356                                  opt_compress_level,0,
    357                                  /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
    358                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
    359                                  password,crcFile);
    360 
    361                 if (err != ZIP_OK)
    362                     printf("error in opening %s in zipfile\n",filenameinzip);
    363                 else
    364                 {
    365                     fin = fopen(filenameinzip,"rb");
    366                     if (fin==NULL)
    367                     {
    368                         err=ZIP_ERRNO;
    369                         printf("error in opening %s for reading\n",filenameinzip);
    370                     }
    371                 }
    372 
    373                 if (err == ZIP_OK)
    374                     do
    375                     {
    376                         err = ZIP_OK;
    377                         size_read = (int)fread(buf,1,size_buf,fin);
    378                         if (size_read < size_buf)
    379                             if (feof(fin)==0)
    380                         {
    381                             printf("error in reading %s\n",filenameinzip);
    382                             err = ZIP_ERRNO;
    383                         }
    384 
    385                         if (size_read>0)
    386                         {
    387                             err = zipWriteInFileInZip (zf,buf,size_read);
    388                             if (err<0)
    389                             {
    390                                 printf("error in writing %s in the zipfile\n",
    391                                                  filenameinzip);
    392                             }
    393 
    394                         }
    395                     } while ((err == ZIP_OK) && (size_read>0));
    396 
    397                 if (fin)
    398                     fclose(fin);
    399 
    400                 if (err<0)
    401                     err=ZIP_ERRNO;
    402                 else
    403                 {
    404                     err = zipCloseFileInZip(zf);
    405                     if (err!=ZIP_OK)
    406                         printf("error in closing %s in the zipfile\n",
    407                                     filenameinzip);
    408                 }
    409             }
    410         }
    411         errclose = zipClose(zf,NULL);
    412         if (errclose != ZIP_OK)
    413             printf("error in closing %s\n",filename_try);
    414     }
    415     else
    416     {
    417        do_help();
    418     }
    419 
    420     free(buf);
    421     return 0;
    422 }
    423