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