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