Rizin
unix-like reverse engineering framework and cli tools
minizip.c
Go to the documentation of this file.
1 /*
2  minizip.c
3  Version 1.1, February 14h, 2010
4  sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
5 
6  Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
7 
8  Modifications of Unzip for Zip64
9  Copyright (C) 2007-2008 Even Rouault
10 
11  Modifications for Zip64 support on both zip and unzip
12  Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
13 */
14 
15 
16 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
17  #ifndef __USE_FILE_OFFSET64
18  #define __USE_FILE_OFFSET64
19  #endif
20  #ifndef __USE_LARGEFILE64
21  #define __USE_LARGEFILE64
22  #endif
23  #ifndef _LARGEFILE64_SOURCE
24  #define _LARGEFILE64_SOURCE
25  #endif
26  #ifndef _FILE_OFFSET_BIT
27  #define _FILE_OFFSET_BIT 64
28  #endif
29 #endif
30 
31 #ifdef __APPLE__
32 // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
33 #define FOPEN_FUNC(filename, mode) fopen(filename, mode)
34 #define FTELLO_FUNC(stream) ftello(stream)
35 #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
36 #else
37 #define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
38 #define FTELLO_FUNC(stream) ftello64(stream)
39 #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
40 #endif
41 
42 
43 
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <time.h>
48 #include <errno.h>
49 #include <fcntl.h>
50 
51 #ifdef _WIN32
52 # include <direct.h>
53 # include <io.h>
54 #else
55 # include <unistd.h>
56 # include <utime.h>
57 # include <sys/types.h>
58 # include <sys/stat.h>
59 #endif
60 
61 #include "zip.h"
62 
63 #ifdef _WIN32
64  #define USEWIN32IOAPI
65  #include "iowin32.h"
66 #endif
67 
68 
69 
70 #define WRITEBUFFERSIZE (16384)
71 #define MAXFILENAME (256)
72 
73 #ifdef _WIN32
74 static int filetime(f, tmzip, dt)
75  const char *f; /* name of file to get info on */
76  tm_zip *tmzip; /* return value: access, modific. and creation times */
77  uLong *dt; /* dostime */
78 {
79  int ret = 0;
80  {
81  FILETIME ftLocal;
82  HANDLE hFind;
83  WIN32_FIND_DATAA ff32;
84 
85  hFind = FindFirstFileA(f,&ff32);
86  if (hFind != INVALID_HANDLE_VALUE)
87  {
88  FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
89  FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
90  FindClose(hFind);
91  ret = 1;
92  }
93  }
94  return ret;
95 }
96 #else
97 #if defined(unix) || defined(__APPLE__)
98 static int filetime(f, tmzip, dt)
99  const char *f; /* name of file to get info on */
100  tm_zip *tmzip; /* return value: access, modific. and creation times */
101  uLong *dt; /* dostime */
102 {
103  (void)dt;
104  int ret=0;
105  struct stat s; /* results of stat() */
106  struct tm* filedate;
107  time_t tm_t=0;
108 
109  if (strcmp(f,"-")!=0)
110  {
111  char name[MAXFILENAME+1];
112  size_t len = strlen(f);
113  if (len > MAXFILENAME)
114  len = MAXFILENAME;
115 
116  strncpy(name, f,MAXFILENAME-1);
117  /* strncpy doesnt append the trailing NULL, of the string is too long. */
118  name[ MAXFILENAME ] = '\0';
119 
120  if (name[len - 1] == '/')
121  name[len - 1] = '\0';
122  /* not all systems allow stat'ing a file with / appended */
123  if (stat(name,&s)==0)
124  {
125  tm_t = s.st_mtime;
126  ret = 1;
127  }
128  }
129  filedate = localtime(&tm_t);
130 
131  tmzip->tm_sec = filedate->tm_sec;
132  tmzip->tm_min = filedate->tm_min;
133  tmzip->tm_hour = filedate->tm_hour;
134  tmzip->tm_mday = filedate->tm_mday;
135  tmzip->tm_mon = filedate->tm_mon ;
136  tmzip->tm_year = filedate->tm_year;
137 
138  return ret;
139 }
140 #else
141 uLong filetime(f, tmzip, dt)
142  const char *f; /* name of file to get info on */
143  tm_zip *tmzip; /* return value: access, modific. and creation times */
144  uLong *dt; /* dostime */
145 {
146  return 0;
147 }
148 #endif
149 #endif
150 
151 
152 
153 
155  const char* filename;
156 {
157  FILE* ftestexist;
158  int ret = 1;
159  ftestexist = FOPEN_FUNC(filename,"rb");
160  if (ftestexist==NULL)
161  ret = 0;
162  else
163  fclose(ftestexist);
164  return ret;
165 }
166 
167 static void do_banner()
168 {
169  printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
170  printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
171 }
172 
173 static void do_help()
174 {
175  printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
176  " -o Overwrite existing file.zip\n" \
177  " -a Append to existing file.zip\n" \
178  " -0 Store only\n" \
179  " -1 Compress faster\n" \
180  " -9 Compress better\n\n" \
181  " -j exclude path. store only the file name.\n\n");
182 }
183 
184 /* calculate the CRC32 of a file,
185  because to encrypt a file, we need known the CRC32 of the file before */
186 static int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
187 {
188  unsigned long calculate_crc=0;
189  int err=ZIP_OK;
190  FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
191 
192  unsigned long size_read = 0;
193  unsigned long total_read = 0;
194  if (fin==NULL)
195  {
196  err = ZIP_ERRNO;
197  }
198 
199  if (err == ZIP_OK)
200  do
201  {
202  err = ZIP_OK;
203  size_read = fread(buf,1,size_buf,fin);
204  if (size_read < size_buf)
205  if (feof(fin)==0)
206  {
207  printf("error in reading %s\n",filenameinzip);
208  err = ZIP_ERRNO;
209  }
210 
211  if (size_read>0)
212  calculate_crc = crc32_z(calculate_crc,buf,size_read);
213  total_read += size_read;
214 
215  } while ((err == ZIP_OK) && (size_read>0));
216 
217  if (fin)
218  fclose(fin);
219 
220  *result_crc=calculate_crc;
221  printf("file %s crc %lx\n", filenameinzip, calculate_crc);
222  return err;
223 }
224 
225 static int isLargeFile(const char* filename)
226 {
227  int largeFile = 0;
228  ZPOS64_T pos = 0;
229  FILE* pFile = FOPEN_FUNC(filename, "rb");
230 
231  if(pFile != NULL)
232  {
233  FSEEKO_FUNC(pFile, 0, SEEK_END);
234  pos = (ZPOS64_T)FTELLO_FUNC(pFile);
235 
236  printf("File : %s is %lld bytes\n", filename, pos);
237 
238  if(pos >= 0xffffffff)
239  largeFile = 1;
240 
241  fclose(pFile);
242  }
243 
244  return largeFile;
245 }
246 
247 int main(argc,argv)
248  int argc;
249  char *argv[];
250 {
251  int i;
252  int opt_overwrite=0;
253  int opt_compress_level=Z_DEFAULT_COMPRESSION;
254  int opt_exclude_path=0;
255  int zipfilenamearg = 0;
256  char filename_try[MAXFILENAME+16];
257  int zipok;
258  int err=0;
259  size_t size_buf=0;
260  void* buf=NULL;
261  const char* password=NULL;
262 
263 
264  do_banner();
265  if (argc==1)
266  {
267  do_help();
268  return 0;
269  }
270  else
271  {
272  for (i=1;i<argc;i++)
273  {
274  if ((*argv[i])=='-')
275  {
276  const char *p=argv[i]+1;
277 
278  while ((*p)!='\0')
279  {
280  char c=*(p++);;
281  if ((c=='o') || (c=='O'))
282  opt_overwrite = 1;
283  if ((c=='a') || (c=='A'))
284  opt_overwrite = 2;
285  if ((c>='0') && (c<='9'))
286  opt_compress_level = c-'0';
287  if ((c=='j') || (c=='J'))
288  opt_exclude_path = 1;
289 
290  if (((c=='p') || (c=='P')) && (i+1<argc))
291  {
292  password=argv[i+1];
293  i++;
294  }
295  }
296  }
297  else
298  {
299  if (zipfilenamearg == 0)
300  {
301  zipfilenamearg = i ;
302  }
303  }
304  }
305  }
306 
307  size_buf = WRITEBUFFERSIZE;
308  buf = (void*)malloc(size_buf);
309  if (buf==NULL)
310  {
311  printf("Error allocating memory\n");
312  return ZIP_INTERNALERROR;
313  }
314 
315  if (zipfilenamearg==0)
316  {
317  zipok=0;
318  }
319  else
320  {
321  int i,len;
322  int dot_found=0;
323 
324  zipok = 1 ;
325  strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
326  /* strncpy doesnt append the trailing NULL, of the string is too long. */
327  filename_try[ MAXFILENAME ] = '\0';
328 
329  len=(int)strlen(filename_try);
330  for (i=0;i<len;i++)
331  if (filename_try[i]=='.')
332  dot_found=1;
333 
334  if (dot_found==0)
335  strcat(filename_try,".zip");
336 
337  if (opt_overwrite==2)
338  {
339  /* if the file don't exist, we not append file */
340  if (check_exist_file(filename_try)==0)
341  opt_overwrite=1;
342  }
343  else
344  if (opt_overwrite==0)
345  if (check_exist_file(filename_try)!=0)
346  {
347  char rep=0;
348  do
349  {
350  char answer[128];
351  int ret;
352  printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
353  ret = scanf("%1s",answer);
354  if (ret != 1)
355  {
356  exit(EXIT_FAILURE);
357  }
358  rep = answer[0] ;
359  if ((rep>='a') && (rep<='z'))
360  rep -= 0x20;
361  }
362  while ((rep!='Y') && (rep!='N') && (rep!='A'));
363  if (rep=='N')
364  zipok = 0;
365  if (rep=='A')
366  opt_overwrite = 2;
367  }
368  }
369 
370  if (zipok==1)
371  {
372  zipFile zf;
373  int errclose;
374 # ifdef USEWIN32IOAPI
375  zlib_filefunc64_def ffunc;
376  fill_win32_filefunc64A(&ffunc);
377  zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
378 # else
379  zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
380 # endif
381 
382  if (zf == NULL)
383  {
384  printf("error opening %s\n",filename_try);
385  err= ZIP_ERRNO;
386  }
387  else
388  printf("creating %s\n",filename_try);
389 
390  for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
391  {
392  if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
393  ((argv[i][1]=='o') || (argv[i][1]=='O') ||
394  (argv[i][1]=='a') || (argv[i][1]=='A') ||
395  (argv[i][1]=='p') || (argv[i][1]=='P') ||
396  ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
397  (strlen(argv[i]) == 2)))
398  {
399  FILE * fin;
400  size_t size_read;
401  const char* filenameinzip = argv[i];
402  const char *savefilenameinzip;
403  zip_fileinfo zi;
404  unsigned long crcFile=0;
405  int zip64 = 0;
406 
408  zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
409  zi.dosDate = 0;
410  zi.internal_fa = 0;
411  zi.external_fa = 0;
412  filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
413 
414 /*
415  err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
416  NULL,0,NULL,0,NULL / * comment * /,
417  (opt_compress_level != 0) ? Z_DEFLATED : 0,
418  opt_compress_level);
419 */
420  if ((password != NULL) && (err==ZIP_OK))
421  err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
422 
423  zip64 = isLargeFile(filenameinzip);
424 
425  /* The path name saved, should not include a leading slash. */
426  /*if it did, windows/xp and dynazip couldn't read the zip file. */
427  savefilenameinzip = filenameinzip;
428  while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
429  {
430  savefilenameinzip++;
431  }
432 
433  /*should the zip file contain any path at all?*/
434  if( opt_exclude_path )
435  {
436  const char *tmpptr;
437  const char *lastslash = 0;
438  for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
439  {
440  if( *tmpptr == '\\' || *tmpptr == '/')
441  {
442  lastslash = tmpptr;
443  }
444  }
445  if( lastslash != NULL )
446  {
447  savefilenameinzip = lastslash+1; // base filename follows last slash.
448  }
449  }
450 
451 
452  err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
453  NULL,0,NULL,0,NULL /* comment*/,
454  (opt_compress_level != 0) ? Z_DEFLATED : 0,
455  opt_compress_level,0,
456  /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
458  password,crcFile, zip64);
459 
460  if (err != ZIP_OK)
461  printf("error in opening %s in zipfile\n",filenameinzip);
462  else
463  {
464  fin = FOPEN_FUNC(filenameinzip,"rb");
465  if (fin==NULL)
466  {
467  err=ZIP_ERRNO;
468  printf("error in opening %s for reading\n",filenameinzip);
469  }
470  }
471 
472  if (err == ZIP_OK)
473  do
474  {
475  err = ZIP_OK;
476  size_read = fread(buf,1,size_buf,fin);
477  if (size_read < size_buf)
478  if (feof(fin)==0)
479  {
480  printf("error in reading %s\n",filenameinzip);
481  err = ZIP_ERRNO;
482  }
483 
484  if (size_read>0)
485  {
486  err = zipWriteInFileInZip (zf,buf,(unsigned)size_read);
487  if (err<0)
488  {
489  printf("error in writing %s in the zipfile\n",
490  filenameinzip);
491  }
492 
493  }
494  } while ((err == ZIP_OK) && (size_read>0));
495 
496  if (fin)
497  fclose(fin);
498 
499  if (err<0)
500  err=ZIP_ERRNO;
501  else
502  {
503  err = zipCloseFileInZip(zf);
504  if (err!=ZIP_OK)
505  printf("error in closing %s in the zipfile\n",
506  filenameinzip);
507  }
508  }
509  }
510  errclose = zipClose(zf,NULL);
511  if (errclose != ZIP_OK)
512  printf("error in closing %s\n",filename_try);
513  }
514  else
515  {
516  do_help();
517  }
518 
519  free(buf);
520  return 0;
521 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
static bool err
Definition: armass.c:435
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
#define MAX_WBITS
Definition: flirt.c:105
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
const char * filename
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
unsigned long long int ZPOS64_T
Definition: ioapi.h:99
#define INVALID_HANDLE_VALUE
Definition: iowin32.c:21
void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def)
Definition: iowin32.c:439
void * p
Definition: libc.cpp:67
void * malloc(size_t size)
Definition: malloc.c:123
static stat
Definition: sflib.h:131
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
static void do_banner()
Definition: minizip.c:167
#define MAXFILENAME
Definition: minizip.c:71
#define FSEEKO_FUNC(stream, offset, origin)
Definition: minizip.c:39
static int isLargeFile(const char *filename)
Definition: minizip.c:225
static int check_exist_file(char *filename) const
Definition: minizip.c:154
#define FOPEN_FUNC(filename, mode)
Definition: minizip.c:37
static int getFileCrc(const char *filenameinzip, void *buf, unsigned long size_buf, unsigned long *result_crc)
Definition: minizip.c:186
static void do_help()
Definition: minizip.c:173
#define WRITEBUFFERSIZE
Definition: minizip.c:70
#define FTELLO_FUNC(stream)
Definition: minizip.c:38
uLong filetime(char *f, tm_zip *tmzip, uLong *dt) const
Definition: minizip.c:141
int main(int argc, argv)
Definition: minizip.c:247
string FILE
Definition: benchmark.py:21
static RzSocket * s
Definition: rtr.c:28
static int
Definition: sfsocketcall.h:114
int time_t
Definition: sftypes.h:66
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
Definition: z80asm.h:102
Definition: sftypes.h:80
Definition: zip.h:90
int tm_hour
Definition: zip.h:93
int tm_min
Definition: zip.h:92
int tm_sec
Definition: zip.h:91
int tm_mon
Definition: zip.h:95
int tm_year
Definition: zip.h:96
int tm_mday
Definition: zip.h:94
uLong dosDate
Definition: zip.h:102
uLong internal_fa
Definition: zip.h:105
uLong external_fa
Definition: zip.h:106
tm_zip tmz_date
Definition: zip.h:101
int pos
Definition: main.c:11
DWORD * HANDLE
unsigned long uLong
Definition: zconf.h:394
int ZEXPORT zipClose(zipFile file, const char *global_comment)
Definition: zip.c:1882
zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc *globalcomment, zlib_filefunc64_def *pzlib_filefunc_def)
Definition: zip.c:932
int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, unsigned int len)
Definition: zip.c:1402
#define SEEK_END
Definition: zip.c:84
int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char *password, uLong crcForCrypting, int zip64)
Definition: zip.c:1296
int ZEXPORT zipCloseFileInZip(zipFile file)
Definition: zip.c:1750
zipFile ZEXPORT zipOpen64(const void *pathname, int append)
Definition: zip.c:953
#define DEF_MEM_LEVEL
Definition: zip.h:83
#define ZIP_OK
Definition: zip.h:72
#define ZIP_INTERNALERROR
Definition: zip.h:77
#define ZIP_ERRNO
Definition: zip.h:74
voidp zipFile
Definition: zip.h:69
unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, z_size_t len)
Definition: crc32.c:739
#define Z_DEFLATED
Definition: zlib.h:209
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:200
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:193