3 Version 1.1, February 14h, 2010
4 sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
6 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
8 Modifications of Unzip for Zip64
9 Copyright (C) 2007-2008 Even Rouault
11 Modifications for Zip64 support on both zip and unzip
12 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
16 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
17 #ifndef __USE_FILE_OFFSET64
18 #define __USE_FILE_OFFSET64
20 #ifndef __USE_LARGEFILE64
21 #define __USE_LARGEFILE64
23 #ifndef _LARGEFILE64_SOURCE
24 #define _LARGEFILE64_SOURCE
26 #ifndef _FILE_OFFSET_BIT
27 #define _FILE_OFFSET_BIT 64
31 #if defined(__APPLE__) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64)
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)
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)
57 # include <sys/types.h>
58 # include <sys/stat.h>
70 #define WRITEBUFFERSIZE (16384)
71 #define MAXFILENAME (256)
74 /* f: name of file to get info on, tmzip: return value: access,
75 modification and creation times, dt: dostime */
76 static int filetime(const char *f, tm_zip *tmzip, uLong *dt) {
81 WIN32_FIND_DATAA ff32;
83 hFind = FindFirstFileA(f,&ff32);
84 if (hFind != INVALID_HANDLE_VALUE)
86 FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
87 FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
95 #if defined(unix) || defined(__APPLE__)
96 /* f: name of file to get info on, tmzip: return value: access,
97 modification and creation times, dt: dostime */
98 static int filetime(const char *f, tm_zip *tmzip, uLong *dt) {
101 struct stat s; /* results of stat() */
105 if (strcmp(f,"-")!=0)
107 char name[MAXFILENAME+1];
108 size_t len = strlen(f);
109 if (len > MAXFILENAME)
112 strncpy(name, f,MAXFILENAME-1);
113 /* strncpy doesn't append the trailing NULL, of the string is too long. */
114 name[ MAXFILENAME ] = '\0';
116 if (name[len - 1] == '/')
117 name[len - 1] = '\0';
118 /* not all systems allow stat'ing a file with / appended */
119 if (stat(name,&s)==0)
125 filedate = localtime(&tm_t);
127 tmzip->tm_sec = filedate->tm_sec;
128 tmzip->tm_min = filedate->tm_min;
129 tmzip->tm_hour = filedate->tm_hour;
130 tmzip->tm_mday = filedate->tm_mday;
131 tmzip->tm_mon = filedate->tm_mon ;
132 tmzip->tm_year = filedate->tm_year;
137 /* f: name of file to get info on, tmzip: return value: access,
138 modification and creation times, dt: dostime */
139 static int filetime(const char *f, tm_zip *tmzip, uLong *dt) {
151 static int check_exist_file(const char* filename) {
154 ftestexist = FOPEN_FUNC(filename,"rb");
155 if (ftestexist==NULL)
162 static void do_banner(void) {
163 printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
164 printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
167 static void do_help(void) {
168 printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
169 " -o Overwrite existing file.zip\n" \
170 " -a Append to existing file.zip\n" \
172 " -1 Compress faster\n" \
173 " -9 Compress better\n\n" \
174 " -j exclude path. store only the file name.\n\n");
177 /* calculate the CRC32 of a file,
178 because to encrypt a file, we need known the CRC32 of the file before */
179 static int getFileCrc(const char* filenameinzip, void* buf, unsigned long size_buf, unsigned long* result_crc) {
180 unsigned long calculate_crc=0;
182 FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
184 unsigned long size_read = 0;
185 /* unsigned long total_read = 0; */
195 size_read = fread(buf,1,size_buf,fin);
196 if (size_read < size_buf)
199 printf("error in reading %s\n",filenameinzip);
204 calculate_crc = crc32_z(calculate_crc,buf,size_read);
205 /* total_read += size_read; */
207 } while ((err == ZIP_OK) && (size_read>0));
212 *result_crc=calculate_crc;
213 printf("file %s crc %lx\n", filenameinzip, calculate_crc);
217 static int isLargeFile(const char* filename) {
220 FILE* pFile = FOPEN_FUNC(filename, "rb");
224 FSEEKO_FUNC(pFile, 0, SEEK_END);
225 pos = (ZPOS64_T)FTELLO_FUNC(pFile);
227 printf("File : %s is %llu bytes\n", filename, pos);
229 if(pos >= 0xffffffff)
238 int main(int argc, char *argv[]) {
241 int opt_compress_level=Z_DEFAULT_COMPRESSION;
242 int opt_exclude_path=0;
243 int zipfilenamearg = 0;
244 char filename_try[MAXFILENAME+16];
249 const char* password=NULL;
264 const char *p=argv[i]+1;
269 if ((c=='o') || (c=='O'))
271 if ((c=='a') || (c=='A'))
273 if ((c>='0') && (c<='9'))
274 opt_compress_level = c-'0';
275 if ((c=='j') || (c=='J'))
276 opt_exclude_path = 1;
278 if (((c=='p') || (c=='P')) && (i+1<argc))
287 if (zipfilenamearg == 0)
295 size_buf = WRITEBUFFERSIZE;
296 buf = (void*)malloc(size_buf);
299 printf("Error allocating memory\n");
300 return ZIP_INTERNALERROR;
303 if (zipfilenamearg==0)
313 strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
314 /* strncpy doesn't append the trailing NULL, of the string is too long. */
315 filename_try[ MAXFILENAME ] = '\0';
317 len=(int)strlen(filename_try);
319 if (filename_try[i]=='.')
323 strcat(filename_try,".zip");
325 if (opt_overwrite==2)
327 /* if the file don't exist, we not append file */
328 if (check_exist_file(filename_try)==0)
332 if (opt_overwrite==0)
333 if (check_exist_file(filename_try)!=0)
340 printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
341 ret = scanf("%1s",answer);
347 if ((rep>='a') && (rep<='z'))
350 while ((rep!='Y') && (rep!='N') && (rep!='A'));
362 # ifdef USEWIN32IOAPI
363 zlib_filefunc64_def ffunc;
364 fill_win32_filefunc64A(&ffunc);
365 zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
367 zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
372 printf("error opening %s\n",filename_try);
376 printf("creating %s\n",filename_try);
378 for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
380 if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
381 ((argv[i][1]=='o') || (argv[i][1]=='O') ||
382 (argv[i][1]=='a') || (argv[i][1]=='A') ||
383 (argv[i][1]=='p') || (argv[i][1]=='P') ||
384 ((argv[i][1]>='0') && (argv[i][1]<='9'))) &&
385 (strlen(argv[i]) == 2)))
389 const char* filenameinzip = argv[i];
390 const char *savefilenameinzip;
392 unsigned long crcFile=0;
395 zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
396 zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
400 filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
403 err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
404 NULL,0,NULL,0,NULL / * comment * /,
405 (opt_compress_level != 0) ? Z_DEFLATED : 0,
408 if ((password != NULL) && (err==ZIP_OK))
409 err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
411 zip64 = isLargeFile(filenameinzip);
413 /* The path name saved, should not include a leading slash. */
414 /*if it did, windows/xp and dynazip couldn't read the zip file. */
415 savefilenameinzip = filenameinzip;
416 while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
421 /*should the zip file contain any path at all?*/
422 if( opt_exclude_path )
425 const char *lastslash = 0;
426 for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
428 if( *tmpptr == '\\' || *tmpptr == '/')
433 if( lastslash != NULL )
435 savefilenameinzip = lastslash+1; // base filename follows last slash.
440 err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
441 NULL,0,NULL,0,NULL /* comment*/,
442 (opt_compress_level != 0) ? Z_DEFLATED : 0,
443 opt_compress_level,0,
444 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
445 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
446 password,crcFile, zip64);
449 printf("error in opening %s in zipfile\n",filenameinzip);
452 fin = FOPEN_FUNC(filenameinzip,"rb");
456 printf("error in opening %s for reading\n",filenameinzip);
464 size_read = fread(buf,1,size_buf,fin);
465 if (size_read < size_buf)
468 printf("error in reading %s\n",filenameinzip);
474 err = zipWriteInFileInZip (zf,buf,(unsigned)size_read);
477 printf("error in writing %s in the zipfile\n",
482 } while ((err == ZIP_OK) && (size_read>0));
491 err = zipCloseFileInZip(zf);
493 printf("error in closing %s in the zipfile\n",
498 errclose = zipClose(zf,NULL);
499 if (errclose != ZIP_OK)
500 printf("error in closing %s\n",filename_try);