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