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