cannam@128: /* cannam@128: minizip.c cannam@128: Version 1.1, February 14h, 2010 cannam@128: sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) cannam@128: cannam@128: Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) cannam@128: cannam@128: Modifications of Unzip for Zip64 cannam@128: Copyright (C) 2007-2008 Even Rouault cannam@128: cannam@128: Modifications for Zip64 support on both zip and unzip cannam@128: Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) cannam@128: */ cannam@128: cannam@128: cannam@128: #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) cannam@128: #ifndef __USE_FILE_OFFSET64 cannam@128: #define __USE_FILE_OFFSET64 cannam@128: #endif cannam@128: #ifndef __USE_LARGEFILE64 cannam@128: #define __USE_LARGEFILE64 cannam@128: #endif cannam@128: #ifndef _LARGEFILE64_SOURCE cannam@128: #define _LARGEFILE64_SOURCE cannam@128: #endif cannam@128: #ifndef _FILE_OFFSET_BIT cannam@128: #define _FILE_OFFSET_BIT 64 cannam@128: #endif cannam@128: #endif cannam@128: cannam@128: #ifdef __APPLE__ cannam@128: // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions cannam@128: #define FOPEN_FUNC(filename, mode) fopen(filename, mode) cannam@128: #define FTELLO_FUNC(stream) ftello(stream) cannam@128: #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) cannam@128: #else cannam@128: #define FOPEN_FUNC(filename, mode) fopen64(filename, mode) cannam@128: #define FTELLO_FUNC(stream) ftello64(stream) cannam@128: #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) cannam@128: #endif cannam@128: cannam@128: cannam@128: cannam@128: #include cannam@128: #include cannam@128: #include cannam@128: #include cannam@128: #include cannam@128: #include cannam@128: cannam@128: #ifdef _WIN32 cannam@128: # include cannam@128: # include cannam@128: #else cannam@128: # include cannam@128: # include cannam@128: # include cannam@128: # include cannam@128: #endif cannam@128: cannam@128: #include "zip.h" cannam@128: cannam@128: #ifdef _WIN32 cannam@128: #define USEWIN32IOAPI cannam@128: #include "iowin32.h" cannam@128: #endif cannam@128: cannam@128: cannam@128: cannam@128: #define WRITEBUFFERSIZE (16384) cannam@128: #define MAXFILENAME (256) cannam@128: cannam@128: #ifdef _WIN32 cannam@128: uLong filetime(f, tmzip, dt) cannam@128: char *f; /* name of file to get info on */ cannam@128: tm_zip *tmzip; /* return value: access, modific. and creation times */ cannam@128: uLong *dt; /* dostime */ cannam@128: { cannam@128: int ret = 0; cannam@128: { cannam@128: FILETIME ftLocal; cannam@128: HANDLE hFind; cannam@128: WIN32_FIND_DATAA ff32; cannam@128: cannam@128: hFind = FindFirstFileA(f,&ff32); cannam@128: if (hFind != INVALID_HANDLE_VALUE) cannam@128: { cannam@128: FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); cannam@128: FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); cannam@128: FindClose(hFind); cannam@128: ret = 1; cannam@128: } cannam@128: } cannam@128: return ret; cannam@128: } cannam@128: #else cannam@128: #ifdef unix || __APPLE__ cannam@128: uLong filetime(f, tmzip, dt) cannam@128: char *f; /* name of file to get info on */ cannam@128: tm_zip *tmzip; /* return value: access, modific. and creation times */ cannam@128: uLong *dt; /* dostime */ cannam@128: { cannam@128: int ret=0; cannam@128: struct stat s; /* results of stat() */ cannam@128: struct tm* filedate; cannam@128: time_t tm_t=0; cannam@128: cannam@128: if (strcmp(f,"-")!=0) cannam@128: { cannam@128: char name[MAXFILENAME+1]; cannam@128: int len = strlen(f); cannam@128: if (len > MAXFILENAME) cannam@128: len = MAXFILENAME; cannam@128: cannam@128: strncpy(name, f,MAXFILENAME-1); cannam@128: /* strncpy doesnt append the trailing NULL, of the string is too long. */ cannam@128: name[ MAXFILENAME ] = '\0'; cannam@128: cannam@128: if (name[len - 1] == '/') cannam@128: name[len - 1] = '\0'; cannam@128: /* not all systems allow stat'ing a file with / appended */ cannam@128: if (stat(name,&s)==0) cannam@128: { cannam@128: tm_t = s.st_mtime; cannam@128: ret = 1; cannam@128: } cannam@128: } cannam@128: filedate = localtime(&tm_t); cannam@128: cannam@128: tmzip->tm_sec = filedate->tm_sec; cannam@128: tmzip->tm_min = filedate->tm_min; cannam@128: tmzip->tm_hour = filedate->tm_hour; cannam@128: tmzip->tm_mday = filedate->tm_mday; cannam@128: tmzip->tm_mon = filedate->tm_mon ; cannam@128: tmzip->tm_year = filedate->tm_year; cannam@128: cannam@128: return ret; cannam@128: } cannam@128: #else cannam@128: uLong filetime(f, tmzip, dt) cannam@128: char *f; /* name of file to get info on */ cannam@128: tm_zip *tmzip; /* return value: access, modific. and creation times */ cannam@128: uLong *dt; /* dostime */ cannam@128: { cannam@128: return 0; cannam@128: } cannam@128: #endif cannam@128: #endif cannam@128: cannam@128: cannam@128: cannam@128: cannam@128: int check_exist_file(filename) cannam@128: const char* filename; cannam@128: { cannam@128: FILE* ftestexist; cannam@128: int ret = 1; cannam@128: ftestexist = FOPEN_FUNC(filename,"rb"); cannam@128: if (ftestexist==NULL) cannam@128: ret = 0; cannam@128: else cannam@128: fclose(ftestexist); cannam@128: return ret; cannam@128: } cannam@128: cannam@128: void do_banner() cannam@128: { cannam@128: printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n"); cannam@128: printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n"); cannam@128: } cannam@128: cannam@128: void do_help() cannam@128: { cannam@128: printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \ cannam@128: " -o Overwrite existing file.zip\n" \ cannam@128: " -a Append to existing file.zip\n" \ cannam@128: " -0 Store only\n" \ cannam@128: " -1 Compress faster\n" \ cannam@128: " -9 Compress better\n\n" \ cannam@128: " -j exclude path. store only the file name.\n\n"); cannam@128: } cannam@128: cannam@128: /* calculate the CRC32 of a file, cannam@128: because to encrypt a file, we need known the CRC32 of the file before */ cannam@128: int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc) cannam@128: { cannam@128: unsigned long calculate_crc=0; cannam@128: int err=ZIP_OK; cannam@128: FILE * fin = FOPEN_FUNC(filenameinzip,"rb"); cannam@128: cannam@128: unsigned long size_read = 0; cannam@128: unsigned long total_read = 0; cannam@128: if (fin==NULL) cannam@128: { cannam@128: err = ZIP_ERRNO; cannam@128: } cannam@128: cannam@128: if (err == ZIP_OK) cannam@128: do cannam@128: { cannam@128: err = ZIP_OK; cannam@128: size_read = (int)fread(buf,1,size_buf,fin); cannam@128: if (size_read < size_buf) cannam@128: if (feof(fin)==0) cannam@128: { cannam@128: printf("error in reading %s\n",filenameinzip); cannam@128: err = ZIP_ERRNO; cannam@128: } cannam@128: cannam@128: if (size_read>0) cannam@128: calculate_crc = crc32(calculate_crc,buf,size_read); cannam@128: total_read += size_read; cannam@128: cannam@128: } while ((err == ZIP_OK) && (size_read>0)); cannam@128: cannam@128: if (fin) cannam@128: fclose(fin); cannam@128: cannam@128: *result_crc=calculate_crc; cannam@128: printf("file %s crc %lx\n", filenameinzip, calculate_crc); cannam@128: return err; cannam@128: } cannam@128: cannam@128: int isLargeFile(const char* filename) cannam@128: { cannam@128: int largeFile = 0; cannam@128: ZPOS64_T pos = 0; cannam@128: FILE* pFile = FOPEN_FUNC(filename, "rb"); cannam@128: cannam@128: if(pFile != NULL) cannam@128: { cannam@128: int n = FSEEKO_FUNC(pFile, 0, SEEK_END); cannam@128: pos = FTELLO_FUNC(pFile); cannam@128: cannam@128: printf("File : %s is %lld bytes\n", filename, pos); cannam@128: cannam@128: if(pos >= 0xffffffff) cannam@128: largeFile = 1; cannam@128: cannam@128: fclose(pFile); cannam@128: } cannam@128: cannam@128: return largeFile; cannam@128: } cannam@128: cannam@128: int main(argc,argv) cannam@128: int argc; cannam@128: char *argv[]; cannam@128: { cannam@128: int i; cannam@128: int opt_overwrite=0; cannam@128: int opt_compress_level=Z_DEFAULT_COMPRESSION; cannam@128: int opt_exclude_path=0; cannam@128: int zipfilenamearg = 0; cannam@128: char filename_try[MAXFILENAME+16]; cannam@128: int zipok; cannam@128: int err=0; cannam@128: int size_buf=0; cannam@128: void* buf=NULL; cannam@128: const char* password=NULL; cannam@128: cannam@128: cannam@128: do_banner(); cannam@128: if (argc==1) cannam@128: { cannam@128: do_help(); cannam@128: return 0; cannam@128: } cannam@128: else cannam@128: { cannam@128: for (i=1;i='0') && (c<='9')) cannam@128: opt_compress_level = c-'0'; cannam@128: if ((c=='j') || (c=='J')) cannam@128: opt_exclude_path = 1; cannam@128: cannam@128: if (((c=='p') || (c=='P')) && (i+1='a') && (rep<='z')) cannam@128: rep -= 0x20; cannam@128: } cannam@128: while ((rep!='Y') && (rep!='N') && (rep!='A')); cannam@128: if (rep=='N') cannam@128: zipok = 0; cannam@128: if (rep=='A') cannam@128: opt_overwrite = 2; cannam@128: } cannam@128: } cannam@128: cannam@128: if (zipok==1) cannam@128: { cannam@128: zipFile zf; cannam@128: int errclose; cannam@128: # ifdef USEWIN32IOAPI cannam@128: zlib_filefunc64_def ffunc; cannam@128: fill_win32_filefunc64A(&ffunc); cannam@128: zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc); cannam@128: # else cannam@128: zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0); cannam@128: # endif cannam@128: cannam@128: if (zf == NULL) cannam@128: { cannam@128: printf("error opening %s\n",filename_try); cannam@128: err= ZIP_ERRNO; cannam@128: } cannam@128: else cannam@128: printf("creating %s\n",filename_try); cannam@128: cannam@128: for (i=zipfilenamearg+1;(i='0') || (argv[i][1]<='9'))) && cannam@128: (strlen(argv[i]) == 2))) cannam@128: { cannam@128: FILE * fin; cannam@128: int size_read; cannam@128: const char* filenameinzip = argv[i]; cannam@128: const char *savefilenameinzip; cannam@128: zip_fileinfo zi; cannam@128: unsigned long crcFile=0; cannam@128: int zip64 = 0; cannam@128: cannam@128: zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = cannam@128: zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; cannam@128: zi.dosDate = 0; cannam@128: zi.internal_fa = 0; cannam@128: zi.external_fa = 0; cannam@128: filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); cannam@128: cannam@128: /* cannam@128: err = zipOpenNewFileInZip(zf,filenameinzip,&zi, cannam@128: NULL,0,NULL,0,NULL / * comment * /, cannam@128: (opt_compress_level != 0) ? Z_DEFLATED : 0, cannam@128: opt_compress_level); cannam@128: */ cannam@128: if ((password != NULL) && (err==ZIP_OK)) cannam@128: err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); cannam@128: cannam@128: zip64 = isLargeFile(filenameinzip); cannam@128: cannam@128: /* The path name saved, should not include a leading slash. */ cannam@128: /*if it did, windows/xp and dynazip couldn't read the zip file. */ cannam@128: savefilenameinzip = filenameinzip; cannam@128: while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) cannam@128: { cannam@128: savefilenameinzip++; cannam@128: } cannam@128: cannam@128: /*should the zip file contain any path at all?*/ cannam@128: if( opt_exclude_path ) cannam@128: { cannam@128: const char *tmpptr; cannam@128: const char *lastslash = 0; cannam@128: for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) cannam@128: { cannam@128: if( *tmpptr == '\\' || *tmpptr == '/') cannam@128: { cannam@128: lastslash = tmpptr; cannam@128: } cannam@128: } cannam@128: if( lastslash != NULL ) cannam@128: { cannam@128: savefilenameinzip = lastslash+1; // base filename follows last slash. cannam@128: } cannam@128: } cannam@128: cannam@128: /**/ cannam@128: err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, cannam@128: NULL,0,NULL,0,NULL /* comment*/, cannam@128: (opt_compress_level != 0) ? Z_DEFLATED : 0, cannam@128: opt_compress_level,0, cannam@128: /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ cannam@128: -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, cannam@128: password,crcFile, zip64); cannam@128: cannam@128: if (err != ZIP_OK) cannam@128: printf("error in opening %s in zipfile\n",filenameinzip); cannam@128: else cannam@128: { cannam@128: fin = FOPEN_FUNC(filenameinzip,"rb"); cannam@128: if (fin==NULL) cannam@128: { cannam@128: err=ZIP_ERRNO; cannam@128: printf("error in opening %s for reading\n",filenameinzip); cannam@128: } cannam@128: } cannam@128: cannam@128: if (err == ZIP_OK) cannam@128: do cannam@128: { cannam@128: err = ZIP_OK; cannam@128: size_read = (int)fread(buf,1,size_buf,fin); cannam@128: if (size_read < size_buf) cannam@128: if (feof(fin)==0) cannam@128: { cannam@128: printf("error in reading %s\n",filenameinzip); cannam@128: err = ZIP_ERRNO; cannam@128: } cannam@128: cannam@128: if (size_read>0) cannam@128: { cannam@128: err = zipWriteInFileInZip (zf,buf,size_read); cannam@128: if (err<0) cannam@128: { cannam@128: printf("error in writing %s in the zipfile\n", cannam@128: filenameinzip); cannam@128: } cannam@128: cannam@128: } cannam@128: } while ((err == ZIP_OK) && (size_read>0)); cannam@128: cannam@128: if (fin) cannam@128: fclose(fin); cannam@128: cannam@128: if (err<0) cannam@128: err=ZIP_ERRNO; cannam@128: else cannam@128: { cannam@128: err = zipCloseFileInZip(zf); cannam@128: if (err!=ZIP_OK) cannam@128: printf("error in closing %s in the zipfile\n", cannam@128: filenameinzip); cannam@128: } cannam@128: } cannam@128: } cannam@128: errclose = zipClose(zf,NULL); cannam@128: if (errclose != ZIP_OK) cannam@128: printf("error in closing %s\n",filename_try); cannam@128: } cannam@128: else cannam@128: { cannam@128: do_help(); cannam@128: } cannam@128: cannam@128: free(buf); cannam@128: return 0; cannam@128: }