diff --git a/contrib/minizip/CMakeLists.txt b/contrib/minizip/CMakeLists.txt index 80ccf9906..00c697bfa 100644 --- a/contrib/minizip/CMakeLists.txt +++ b/contrib/minizip/CMakeLists.txt @@ -81,6 +81,11 @@ check_function_exists(fseeko HAVE_FSEEKO) # check_include_file(unistd.h HAVE_UNISTD_H) +# +# Check for dirent.h +# +check_include_file(dirent.h HAVE_DIRENT_H) + # # Check to see if we have large file support # @@ -145,6 +150,7 @@ if(MINIZIP_BUILD_SHARED) PRIVATE $<$:_CRT_SECURE_NO_WARNINGS> $<$:HAVE_HIDDEN> $<$:HAVE_UNISTD_H=1> + $<$:HAVE_DIRENT_H=1> PUBLIC $<$:_LARGEFILE64_SOURCE=1> $<$:HAVE_BZIP2=1> $<$:USE_FILE32API=1>) @@ -189,6 +195,7 @@ if(MINIZIP_BUILD_STATIC) PRIVATE $<$:_CRT_SECURE_NO_WARNINGS> $<$:HAVE_HIDDEN> $<$:HAVE_UNISTD_H=1> + $<$:HAVE_DIRENT_H=1> PUBLIC $<$:_LARGEFILE64_SOURCE=1> $<$:HAVE_BZIP2=1> $<$:USE_FILE32API=1>) diff --git a/contrib/minizip/configure.ac b/contrib/minizip/configure.ac index b739fa0c7..028d52ea8 100644 --- a/contrib/minizip/configure.ac +++ b/contrib/minizip/configure.ac @@ -28,5 +28,7 @@ AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) AC_SUBST([HAVE_UNISTD_H], [0]) AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], []) +AC_SUBST([HAVE_DIRENT_H], [0]) +AC_CHECK_HEADER([dirent.h], [HAVE_DIRENT_H=1], []) AC_CONFIG_FILES([Makefile minizip.pc]) AC_OUTPUT diff --git a/contrib/minizip/minizip.c b/contrib/minizip/minizip.c index f68bea1da..35d14c1e8 100644 --- a/contrib/minizip/minizip.c +++ b/contrib/minizip/minizip.c @@ -43,6 +43,9 @@ #ifndef _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_WARNINGS #endif +#ifdef HAVE_DIRENT_H +# include +#endif #include #include #include @@ -167,7 +170,8 @@ static void do_banner(void) { } static void do_help(void) { - printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \ + printf("Usage : minizip [-r] [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \ + " -r Scan directories recursively\n" \ " -o Overwrite existing file.zip\n" \ " -a Append to existing file.zip\n" \ " -0 Store only\n" \ @@ -237,8 +241,151 @@ static int isLargeFile(const char* filename) { return largeFile; } +void addFileToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) { + FILE * fin = NULL; + size_t size_read; + const char *savefilenameinzip; + zip_fileinfo zi; + unsigned long crcFile=0; + int zip64 = 0; + int err=0; + unsigned long size_buf=WRITEBUFFERSIZE; + unsigned char buf[WRITEBUFFERSIZE]; + zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = + zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; + zi.dosDate = 0; + zi.internal_fa = 0; + zi.external_fa = 0; + filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); + +/* + err = zipOpenNewFileInZip(zf,filenameinzip,&zi, + NULL,0,NULL,0,NULL / * comment * /, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level); +*/ + if ((password != NULL) && (err==ZIP_OK)) + err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); + + zip64 = isLargeFile(filenameinzip); + + /* The path name saved, should not include a leading slash. */ + /*if it did, windows/xp and dynazip couldn't read the zip file. */ + savefilenameinzip = filenameinzip; + while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) + { + savefilenameinzip++; + } + + /*should the zip file contain any path at all?*/ + if( opt_exclude_path ) + { + const char *tmpptr; + const char *lastslash = 0; + for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) + { + if( *tmpptr == '\\' || *tmpptr == '/') + { + lastslash = tmpptr; + } + } + if( lastslash != NULL ) + { + savefilenameinzip = lastslash+1; /* base filename follows last slash. */ + } + } + + /**/ + err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, + NULL,0,NULL,0,NULL /* comment*/, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level,0, + /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + password,crcFile, zip64); + + if (err != ZIP_OK) + printf("error in opening %s in zipfile\n",filenameinzip); + else + { + fin = FOPEN_FUNC(filenameinzip,"rb"); + if (fin==NULL) + { + err=ZIP_ERRNO; + printf("error in opening %s for reading\n",filenameinzip); + } + } + + if (err == ZIP_OK) + do + { + err = ZIP_OK; + size_read = fread(buf,1,size_buf,fin); + if (size_read < size_buf) + if (feof(fin)==0) + { + printf("error in reading %s\n",filenameinzip); + err = ZIP_ERRNO; + } + + if (size_read>0) + { + err = zipWriteInFileInZip (zf,buf,(unsigned)size_read); + if (err<0) + { + printf("error in writing %s in the zipfile\n", + filenameinzip); + } + + } + } while ((err == ZIP_OK) && (size_read>0)); + + if (fin) + fclose(fin); + + if (err<0) + err=ZIP_ERRNO; + else + { + err = zipCloseFileInZip(zf); + if (err!=ZIP_OK) + printf("error in closing %s in the zipfile\n", + filenameinzip); + } +} + + +void addPathToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) { +#ifdef HAVE_DIRENT_H +# if defined(_MSC_VER) +# define snprintf _snprintf +# endif + char newname[MAXFILENAME+1+MAXFILENAME+1]; + struct dirent *dp; + + DIR *dir = opendir(filenameinzip); + if (dir == NULL) { + addFileToZip(zf,filenameinzip,password,opt_exclude_path,opt_compress_level); + return; + } + while ((dp = readdir(dir))) + { + if(strcmp(dp->d_name,".")==0) continue; + if(strcmp(dp->d_name,"..")==0) continue; + snprintf(newname, sizeof(newname), "%.*s/%.*s", MAXFILENAME, filenameinzip, MAXFILENAME, dp->d_name); + addPathToZip(zf,newname,password,opt_exclude_path,opt_compress_level); + } + + closedir(dir); +#else + printf("-r option not supported"); +#endif +} + + int main(int argc, char *argv[]) { int i; + int opt_recursive=0; int opt_overwrite=0; int opt_compress_level=Z_DEFAULT_COMPRESSION; int opt_exclude_path=0; @@ -276,6 +423,8 @@ int main(int argc, char *argv[]) { opt_compress_level = c-'0'; if ((c=='j') || (c=='J')) opt_exclude_path = 1; + if ((c=='r') || (c=='R')) + opt_recursive = 1; if (((c=='p') || (c=='P')) && (i+1='0') && (argv[i][1]<='9'))) && (strlen(argv[i]) == 2))) { - FILE * fin = NULL; - size_t size_read; - const char* filenameinzip = argv[i]; - const char *savefilenameinzip; - zip_fileinfo zi; - unsigned long crcFile=0; - int zip64 = 0; - - zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = - zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; - zi.dosDate = 0; - zi.internal_fa = 0; - zi.external_fa = 0; - filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); - -/* - err = zipOpenNewFileInZip(zf,filenameinzip,&zi, - NULL,0,NULL,0,NULL / * comment * /, - (opt_compress_level != 0) ? Z_DEFLATED : 0, - opt_compress_level); -*/ - if ((password != NULL) && (err==ZIP_OK)) - err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); - - zip64 = isLargeFile(filenameinzip); - - /* The path name saved, should not include a leading slash. */ - /*if it did, windows/xp and dynazip couldn't read the zip file. */ - savefilenameinzip = filenameinzip; - while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) - { - savefilenameinzip++; - } - - /*should the zip file contain any path at all?*/ - if( opt_exclude_path ) - { - const char *tmpptr; - const char *lastslash = 0; - for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) - { - if( *tmpptr == '\\' || *tmpptr == '/') - { - lastslash = tmpptr; - } - } - if( lastslash != NULL ) - { - savefilenameinzip = lastslash+1; /* base filename follows last slash. */ - } - } - - /**/ - err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, - NULL,0,NULL,0,NULL /* comment*/, - (opt_compress_level != 0) ? Z_DEFLATED : 0, - opt_compress_level,0, - /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - password,crcFile, zip64); - - if (err != ZIP_OK) - printf("error in opening %s in zipfile\n",filenameinzip); - else - { - fin = FOPEN_FUNC(filenameinzip,"rb"); - if (fin==NULL) - { - err=ZIP_ERRNO; - printf("error in opening %s for reading\n",filenameinzip); - } - } - - if (err == ZIP_OK) - do - { - err = ZIP_OK; - size_read = fread(buf,1,size_buf,fin); - if (size_read < size_buf) - if (feof(fin)==0) - { - printf("error in reading %s\n",filenameinzip); - err = ZIP_ERRNO; - } - - if (size_read>0) - { - err = zipWriteInFileInZip (zf,buf,(unsigned)size_read); - if (err<0) - { - printf("error in writing %s in the zipfile\n", - filenameinzip); - } - - } - } while ((err == ZIP_OK) && (size_read>0)); - - if (fin) - fclose(fin); - - if (err<0) - err=ZIP_ERRNO; - else - { - err = zipCloseFileInZip(zf); - if (err!=ZIP_OK) - printf("error in closing %s in the zipfile\n", - filenameinzip); + if(opt_recursive) { + addPathToZip(zf,argv[i],password,opt_exclude_path,opt_compress_level); + } else { + addFileToZip(zf,argv[i],password,opt_exclude_path,opt_compress_level); } } }