]> git.lyx.org Git - features.git/commitdiff
Move two minizip functions from filetools.cpp to its own file minizip/zipunzip.cpp...
authorBo Peng <bpeng@lyx.org>
Mon, 3 Sep 2007 21:09:11 +0000 (21:09 +0000)
committerBo Peng <bpeng@lyx.org>
Mon, 3 Sep 2007 21:09:11 +0000 (21:09 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@20025 a592a061-630c-0410-9148-cb99ea01b6c8

development/scons/scons_manifest.py
src/Buffer.cpp
src/EmbeddedFiles.cpp
src/support/Makefile.am
src/support/filetools.cpp
src/support/filetools.h
src/support/minizip/zipunzip.cpp [new file with mode: 0644]

index 82f05920e2437da0e930d9a3a4d853c29e93b0f1..1dd4b41d2cdd03efca1c5f73d635711b7d57c45f 100644 (file)
@@ -431,6 +431,7 @@ src_support_minizip_files = Split('''
     ioapi.c
     iowin32.c
     zip.c
+    zipunzip.cpp
     unzip.c
 ''')
 
index 42a602b169a3edc5582742be6c4e7157cfb67dea..77faad5697b05b88dc6060a6ea35bfa6facf444c 100644 (file)
@@ -134,7 +134,6 @@ using support::subst;
 using support::tempName;
 using support::trim;
 using support::sum;
-using support::unzipToDir;
 
 namespace Alert = frontend::Alert;
 namespace os = support::os;
@@ -658,7 +657,7 @@ bool Buffer::readFile(FileName const & filename)
        if (format == "zip") {
                // decompress to a temp directory
                LYXERR(Debug::FILES) << filename << " is in zip format. Unzip to " << temppath() << endl;
-               unzipToDir(filename.toFilesystemEncoding(), temppath());
+               ::unzipToDir(filename.toFilesystemEncoding(), temppath());
                //
                FileName manifest(addName(temppath(), "manifest.txt"));
                FileName lyxfile(addName(temppath(), 
index 921838454283f2b0de26c93648618946adf6572f..180b88ed921db8766f6aa646ca0d7b6ff8a26272 100644 (file)
@@ -61,7 +61,6 @@ using support::onlyFilename;
 using support::makeRelPath;
 using support::changeExtension;
 using support::bformat;
-using support::zipFiles;
 using support::prefixIs;
 using support::sum;
 using support::makedir;
@@ -261,7 +260,7 @@ bool EmbeddedFiles::write(DocFileName const & filename)
                onlyFilename(changeExtension(
                        filename.toFilesystemEncoding(), ".zip"))));
 
-       zipFiles(zipfile, filenames);
+       ::zipFiles(zipfile.toFilesystemEncoding(), filenames);
        // copy file back
        try {
                fs::copy_file(zipfile.toFilesystemEncoding(), filename.toFilesystemEncoding(), false);
index 1692e9fa60bc9b23eb9de6573c938377249bf862..fdf1f7c8eab2d81b5e35f9ff4932b830d1b90988 100644 (file)
@@ -101,7 +101,8 @@ liblyxsupport_la_SOURCES = \
        minizip/unzip.c \
        minizip/unzip.h \
        minizip/zip.c \
-       minizip/zip.h
+       minizip/zip.h \
+       minizip/zipunzip.cpp
 
 ############################## Tests ##################################
 
index 727c0dffe6f2db1f0ce2f40c0e84cb709283e094..44c8b1e4f83892b0f5a966b9871c8471687c99f0 100644 (file)
 #include <fstream>
 #include <sstream>
 
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_DIRECT_H
-# include <direct.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef HAVE_IO_H
-# include <io.h>
-#endif
-#ifdef HAVE_SYS_UTIME_H
-# include <sys/utime.h>
-#endif
-#ifdef HAVE_UTIME_H
-# include <utime.h>
-#endif
-
-#include "zip.h"
-#include "unzip.h"
-
-#ifdef WIN32
-#define USEWIN32IOAPI
-#include "iowin32.h"
-#endif
-
-#define WRITEBUFFERSIZE (16384)
-#define MAXFILENAME (256)
-
-
-#ifndef CXX_GLOBAL_CSTD
-using std::fgetc;
-#endif
-
 using std::endl;
 using std::getline;
 using std::make_pair;
@@ -1285,392 +1247,5 @@ int compare_timestamps(FileName const & filename1, FileName const & filename2)
        return cmp;
 }
 
-// the following is adapted from zlib-1.2.3/contrib/minizip.c
-// and miniunz.c, except that
-// 1. mkdir, makedir is replaced by lyx' own version
-// 2. printf is replaced by lyxerr
-
-#ifdef WIN32
-uLong filetime(const char * f, tm_zip * tmzip, uLong * dt)
-{
-       int ret = 0;
-       {
-               FILETIME ftLocal;
-               HANDLE hFind;
-               WIN32_FIND_DATA  ff32;
-
-               hFind = FindFirstFile(f,&ff32);
-               if (hFind != INVALID_HANDLE_VALUE)
-               {
-                       FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
-                       FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
-                       FindClose(hFind);
-                       ret = 1;
-               }
-       }
-       return ret;
-}
-
-#else
-#ifdef unix
-uLong filetime(const char * f, tm_zip * tmzip, uLong * /*dt*/)
-{
-       int ret=0;
-       struct stat s;                                                            /* results of stat() */
-       struct tm* filedate;
-       time_t tm_t=0;
-
-       if (strcmp(f,"-")!=0) {
-               char name[MAXFILENAME+1];
-               int len = strlen(f);
-               if (len > MAXFILENAME)
-                       len = MAXFILENAME;
-
-               strncpy(name, f,MAXFILENAME-1);
-               /* strncpy doesnt append the trailing NULL, of the string is too long. */
-               name[ MAXFILENAME ] = '\0';
-
-               if (name[len - 1] == '/')
-                       name[len - 1] = '\0';
-               /* not all systems allow stat'ing a file with / appended */
-               if (stat(name,&s)==0) {
-                       tm_t = s.st_mtime;
-                       ret = 1;
-               }
-       }
-       filedate = localtime(&tm_t);
-
-       tmzip->tm_sec  = filedate->tm_sec;
-       tmzip->tm_min  = filedate->tm_min;
-       tmzip->tm_hour = filedate->tm_hour;
-       tmzip->tm_mday = filedate->tm_mday;
-       tmzip->tm_mon  = filedate->tm_mon ;
-       tmzip->tm_year = filedate->tm_year;
-
-       return ret;
-}
-
-#else
-
-uLong filetime(const char * f, tm_zip * tmzip, uLong * dt)
-{
-       return 0;
-}
-#endif
-#endif
-
-bool zipFiles(DocFileName const & zipfile, vector<pair<string, string> > const & files)
-{
-       int err = 0;
-       zipFile zf;
-       int errclose;
-       void * buf = NULL;
-
-       int size_buf = WRITEBUFFERSIZE;
-       buf = (void*)malloc(size_buf);
-       if (buf==NULL) {
-               lyxerr << "Error allocating memory" << endl;
-               return false;
-       }
-       string const zfile = zipfile.toFilesystemEncoding();
-       const char * fname = zfile.c_str();
-
-#ifdef USEWIN32IOAPI
-       zlib_filefunc_def ffunc;
-       fill_win32_filefunc(&ffunc);
-       // false: not append
-       zf = zipOpen2(fname, false, NULL, &ffunc);
-#else
-       zf = zipOpen(fname, false);
-#endif
-
-       if (zf == NULL) {
-               lyxerr << "error opening " << zipfile << endl;
-               return false;
-       }
-
-       for (vector<pair<string, string> >::const_iterator it = files.begin(); it != files.end(); ++it) {
-               FILE * fin;
-               int size_read;
-               zip_fileinfo zi;
-               const char * diskfilename = it->first.c_str();
-               const char * filenameinzip = it->second.c_str();
-               unsigned long crcFile=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 = zipOpenNewFileInZip3(zf, filenameinzip, &zi,
-                       NULL,0,NULL,0,NULL /* comment*/,
-                       Z_DEFLATED,
-                       Z_DEFAULT_COMPRESSION,            // compression level
-                       0,
-               /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
-                       -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                       NULL,                                             // password,
-                       crcFile);
-
-               if (err != ZIP_OK) {
-                       lyxerr << "error in opening " << filenameinzip << " in zipfile" << endl;
-                       return false;
-               }
-               fin = fopen(diskfilename, "rb");
-               if (fin==NULL) {
-                       lyxerr << "error in opening " << diskfilename << " for reading" << endl;
-                       return false;
-               }
-
-               do {
-                       err = ZIP_OK;
-                       size_read = (int)fread(buf, 1, size_buf, fin);
-                       if (size_read < size_buf)
-                               if (feof(fin)==0) {
-                                       lyxerr << "error in reading " << filenameinzip << endl;
-                                       return false;
-                               }
-
-                       if (size_read>0) {
-                               err = zipWriteInFileInZip (zf, buf, size_read);
-                               if (err<0) {
-                                       lyxerr << "error in writing " << filenameinzip << " in the zipfile" << endl;
-                                       return false;
-                               }
-                       }
-               } while ((err == ZIP_OK) && (size_read>0));
-
-               if (fin)
-                       fclose(fin);
-
-               err = zipCloseFileInZip(zf);
-               if (err != ZIP_OK) {
-                       lyxerr << "error in closing " << filenameinzip << "in the zipfile" << endl;
-                       return false;
-               }
-       }
-       errclose = zipClose(zf, NULL);
-       if (errclose != ZIP_OK) {
-               lyxerr << "error in closing " << zipfile << endl;
-               return false;
-       }
-       free(buf);
-       return true;
-}
-
-// adapted from miniunz.c
-
-/* change_file_date : change the date/time of a file
-       filename : the filename of the file where date/time must be modified
-       dosdate : the new date at the MSDos format (4 bytes)
-       tmu_date : the SAME new date at the tm_unz format */
-void change_file_date(const char * filename, uLong dosdate, tm_unz tmu_date)
-{
-#ifdef WIN32
-       HANDLE hFile;
-       FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
-
-       hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
-               0,NULL,OPEN_EXISTING,0,NULL);
-       GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
-       DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
-       LocalFileTimeToFileTime(&ftLocal,&ftm);
-       SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
-       CloseHandle(hFile);
-#else
-#ifdef unix
-       utimbuf ut;
-       tm newdate;
-
-       newdate.tm_sec = tmu_date.tm_sec;
-       newdate.tm_min=tmu_date.tm_min;
-       newdate.tm_hour=tmu_date.tm_hour;
-       newdate.tm_mday=tmu_date.tm_mday;
-       newdate.tm_mon=tmu_date.tm_mon;
-       if (tmu_date.tm_year > 1900)
-               newdate.tm_year=tmu_date.tm_year - 1900;
-       else
-               newdate.tm_year=tmu_date.tm_year ;
-       newdate.tm_isdst=-1;
-
-       ut.actime=ut.modtime=mktime(&newdate);
-       utime(filename,&ut);
-#endif
-#endif
-}
-
-
-int do_extract_currentfile(unzFile uf,
-       const int * popt_extract_without_path,
-       int * popt_overwrite,
-       const char * password,
-       const char * dirname)
-{
-       char filename_inzip[256];
-       char* filename_withoutpath;
-       char* p;
-       int err=UNZ_OK;
-       FILE *fout=NULL;
-       void* buf;
-       uInt size_buf;
-
-       unz_file_info file_info;
-       //uLong ratio=0;
-       err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
-
-       if (err!=UNZ_OK) {
-               lyxerr << "error " << err << " with zipfile in unzGetCurrentFileInfo" << endl;
-               return err;
-       }
-
-       size_buf = WRITEBUFFERSIZE;
-       buf = (void*)malloc(size_buf);
-       if (buf==NULL) {
-               lyxerr << "Error allocating memory" << endl;
-               return UNZ_INTERNALERROR;
-       }
-
-       p = filename_withoutpath = filename_inzip;
-       while ((*p) != '\0') {
-               if (((*p)=='/') || ((*p)=='\\'))
-                       filename_withoutpath = p+1;
-               p++;
-       }
-       // this is a directory
-       if ((*filename_withoutpath)=='\0') {
-               if ((*popt_extract_without_path)==0)
-                       makedir(filename_inzip);
-       }
-       // this is a filename
-       else {
-               char write_filename[1024];
-
-               strcpy(write_filename, dirname);
-               int len = strlen(write_filename);
-               if (write_filename[len-1] != '\\' &&
-                       write_filename[len-1] != '/')
-                       strcat(write_filename, "/");
-
-               if ((*popt_extract_without_path)==0)
-                       strcat(write_filename, filename_inzip);
-               else
-                       strcat(write_filename, filename_withoutpath);
-
-               err = unzOpenCurrentFilePassword(uf,password);
-               if (err!=UNZ_OK) {
-                       lyxerr << "error " << err << " with zipfile in unzOpenCurrentFilePassword" << endl;
-               } else {
-                       fout=fopen(write_filename, "wb");
-
-                       /* some zipfile don't contain directory alone before file */
-                       if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
-                               (filename_withoutpath!=(char*)filename_inzip)) {
-                               char c=*(filename_withoutpath-1);
-                               *(filename_withoutpath-1)='\0';
-                               makedir(write_filename);
-                               *(filename_withoutpath-1)=c;
-                               fout=fopen(write_filename,"wb");
-                       }
-
-                       if (fout==NULL) {
-                               lyxerr << "error opening " << write_filename << endl;
-                       }
-               }
-
-               if (fout!=NULL) {
-                       LYXERR(Debug::FILES) << " extracting: " << write_filename << endl;
-
-                       do {
-                               err = unzReadCurrentFile(uf,buf,size_buf);
-                               if (err<0) {
-                                       lyxerr << "error " << err << " with zipfile in unzReadCurrentFile" << endl;
-                                       break;
-                               }
-                               if (err>0)
-                                       if (fwrite(buf,err,1,fout)!=1) {
-                                               lyxerr << "error in writing extracted file" << endl;
-                                               err=UNZ_ERRNO;
-                                               break;
-                                       }
-                       } while (err>0);
-                       if (fout)
-                               fclose(fout);
-
-                       if (err==0)
-                               change_file_date(write_filename,file_info.dosDate,
-                                       file_info.tmu_date);
-               }
-
-               if (err==UNZ_OK) {
-                       err = unzCloseCurrentFile (uf);
-                       if (err!=UNZ_OK) {
-                               lyxerr << "error " << err << " with zipfile in unzCloseCurrentFile" << endl;
-                       }
-               }
-               else
-                       unzCloseCurrentFile(uf);          /* don't lose the error */
-       }
-
-       free(buf);
-       return err;
-}
-
-
-bool unzipToDir(string const & zipfile, string const & dirname)
-{
-       unzFile uf=NULL;
-#ifdef USEWIN32IOAPI
-       zlib_filefunc_def ffunc;
-#endif
-
-       const char * zipfilename = zipfile.c_str();
-
-#ifdef USEWIN32IOAPI
-       fill_win32_filefunc(&ffunc);
-       uf = unzOpen2(zipfilename, &ffunc);
-#else
-       uf = unzOpen(zipfilename);
-#endif
-
-       if (uf==NULL) {
-               lyxerr << "Cannot open " << zipfile << " or " << zipfile << ".zip" << endl;
-               return false;
-       }
-
-       uLong i;
-       unz_global_info gi;
-       int err;
-       //FILE* fout=NULL;
-       int opt_extract_without_path = 0;
-       int opt_overwrite = 1;
-       char * password = NULL;
-
-       err = unzGetGlobalInfo (uf, &gi);
-       if (err != UNZ_OK) {
-               lyxerr << "error " << err << " with zipfile in unzGetGlobalInfo " << endl;
-               return false;
-       }
-
-       for (i=0; i < gi.number_entry; i++) {
-               if (do_extract_currentfile(uf, &opt_extract_without_path,
-                       &opt_overwrite,
-                       password, dirname.c_str()) != UNZ_OK)
-                       break;
-
-               if ((i+1)<gi.number_entry) {
-                       err = unzGoToNextFile(uf);
-                       if (err != UNZ_OK) {
-                               lyxerr << "error " << err << " with zipfile in unzGoToNextFile" << endl;;
-                               break;
-                       }
-               }
-       }
-
-       unzCloseCurrentFile(uf);
-    return true;
-}
-
 } //namespace support
 } // namespace lyx
index 150202106937904ae85474a728e10e987cdb5ca3..25445a47bb491b5660f0ad24cbc0dddaf37541b8 100644 (file)
@@ -314,13 +314,17 @@ typedef std::pair<int, std::string> cmd_ret;
 
 cmd_ret const runCommand(std::string const & cmd);
 
+} // namespace support
+} // namespace lyx
+
+/// The following functions are implemented in minizip/zipunzip.cpp, and are not in
+/// the lyx::support namespace
+
 /// zip several files to a zipfile. In-zip filenames are also specified
-bool zipFiles(DocFileName const & zipfile, std::vector<std::pair<std::string, std::string> > const & files);
+bool zipFiles(std::string const & zipfile, std::vector<std::pair<std::string, std::string> > const & files);
 
 /// Unzip a zip file to a directory
 bool unzipToDir(std::string const & zipfile, std::string const & path);
 
-} // namespace support
-} // namespace lyx
 
 #endif
diff --git a/src/support/minizip/zipunzip.cpp b/src/support/minizip/zipunzip.cpp
new file mode 100644 (file)
index 0000000..964dcd6
--- /dev/null
@@ -0,0 +1,544 @@
+/* zipunzip.cpp -- IO for compress .zip files using zlib
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
+     WinZip, InfoZip tools and compatible.
+   Multi volume ZipFile (span) are not supported.
+   Encryption compatible with pkzip 2.04g only supported
+   Old compressions used by old PKZip 1.x are not supported
+
+  For uncompress .zip file, look at unzip.h
+
+
+   I WAIT FEEDBACK at mail info@winimage.com
+   Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
+
+   Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+
+*/
+
+/* for more info about .ZIP format, see
+      http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
+      http://www.info-zip.org/pub/infozip/doc/
+   PkWare has also a specification at :
+      ftp://ftp.pkware.com/probdesc.zip
+*/
+
+
+// The original minizip.c and miniunz.c distributed with minizip provide
+// two command line tools minizip and miniunz. This file combines these two 
+// files and modifies the interface to provide two functions zipFiles and 
+// unzipToDir. This file is covered by the original minizip license.
+// 
+
+#include <config.h>
+
+#include <string>
+#include <vector>
+#include <utility>
+using std::string;
+using std::vector;
+using std::pair;
+
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_IO_H
+# include <io.h>
+#endif
+#ifdef HAVE_SYS_UTIME_H
+# include <sys/utime.h>
+#endif
+#ifdef HAVE_UTIME_H
+# include <utime.h>
+#endif
+#include <fcntl.h>
+
+#include "zip.h"
+#include "unzip.h"
+
+#ifdef WIN32
+#define USEWIN32IOAPI
+#include "iowin32.h"
+#endif
+
+#define WRITEBUFFERSIZE (16384)
+#define MAXFILENAME (256)
+
+
+#ifndef CXX_GLOBAL_CSTD
+using std::fgetc;
+#endif
+
+#ifdef WIN32
+uLong filetime(const char * f, tm_zip * tmzip, uLong * dt)
+{
+       int ret = 0;
+       {
+               FILETIME ftLocal;
+               HANDLE hFind;
+               WIN32_FIND_DATA  ff32;
+
+               hFind = FindFirstFile(f,&ff32);
+               if (hFind != INVALID_HANDLE_VALUE)
+               {
+                       FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
+                       FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
+                       FindClose(hFind);
+                       ret = 1;
+               }
+       }
+       return ret;
+}
+
+#else
+#ifdef unix
+uLong filetime(const char * f, tm_zip * tmzip, uLong * /*dt*/)
+{
+       int ret=0;
+       struct stat s;                                                            /* results of stat() */
+       struct tm* filedate;
+       time_t tm_t=0;
+
+       if (strcmp(f,"-")!=0) {
+               char name[MAXFILENAME+1];
+               int len = strlen(f);
+               if (len > MAXFILENAME)
+                       len = MAXFILENAME;
+
+               strncpy(name, f,MAXFILENAME-1);
+               /* strncpy doesnt append the trailing NULL, of the string is too long. */
+               name[ MAXFILENAME ] = '\0';
+
+               if (name[len - 1] == '/')
+                       name[len - 1] = '\0';
+               /* not all systems allow stat'ing a file with / appended */
+               if (stat(name,&s)==0) {
+                       tm_t = s.st_mtime;
+                       ret = 1;
+               }
+       }
+       filedate = localtime(&tm_t);
+
+       tmzip->tm_sec  = filedate->tm_sec;
+       tmzip->tm_min  = filedate->tm_min;
+       tmzip->tm_hour = filedate->tm_hour;
+       tmzip->tm_mday = filedate->tm_mday;
+       tmzip->tm_mon  = filedate->tm_mon ;
+       tmzip->tm_year = filedate->tm_year;
+
+       return ret;
+}
+
+#else
+
+uLong filetime(const char * f, tm_zip * tmzip, uLong * dt)
+{
+       return 0;
+}
+#endif
+#endif
+
+bool zipFiles(string const & zipfile, vector<pair<string, string> > const & files)
+{
+       int err = 0;
+       zipFile zf;
+       int errclose;
+       void * buf = NULL;
+
+       int size_buf = WRITEBUFFERSIZE;
+       buf = (void*)malloc(size_buf);
+       if (buf==NULL) {
+               printf("Error allocating memory\n");
+               return false;
+       }
+       const char * fname = zipfile.c_str();
+
+#ifdef USEWIN32IOAPI
+       zlib_filefunc_def ffunc;
+       fill_win32_filefunc(&ffunc);
+       // false: not append
+       zf = zipOpen2(fname, false, NULL, &ffunc);
+#else
+       zf = zipOpen(fname, false);
+#endif
+
+       if (zf == NULL) {
+               return false;
+       }
+
+       for (vector<pair<string, string> >::const_iterator it = files.begin(); it != files.end(); ++it) {
+               FILE * fin;
+               int size_read;
+               zip_fileinfo zi;
+               const char * diskfilename = it->first.c_str();
+               const char * filenameinzip = it->second.c_str();
+               unsigned long crcFile=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 = zipOpenNewFileInZip3(zf, filenameinzip, &zi,
+                       NULL,0,NULL,0,NULL /* comment*/,
+                       Z_DEFLATED,
+                       Z_DEFAULT_COMPRESSION,            // compression level
+                       0,
+               /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
+                       -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                       NULL,                                             // password,
+                       crcFile);
+
+               if (err != ZIP_OK) {
+                       printf("error in opening %s in zipfile\n",filenameinzip);
+                       return false;
+               }
+               fin = fopen(diskfilename, "rb");
+               if (fin==NULL) {
+                       return false;
+               }
+
+               do {
+                       err = ZIP_OK;
+                       size_read = (int)fread(buf, 1, size_buf, fin);
+                       if (size_read < size_buf)
+                               if (feof(fin)==0) {
+                                       printf("error in reading %s\n",filenameinzip);
+                                       return false;
+                               }
+
+                       if (size_read>0) {
+                               err = zipWriteInFileInZip (zf, buf, size_read);
+                               if (err<0) {
+                                       printf("error in writing %s in the zipfile\n",
+                                                 filenameinzip);
+                                       return false;
+                               }
+                       }
+               } while ((err == ZIP_OK) && (size_read>0));
+
+               if (fin)
+                       fclose(fin);
+
+               err = zipCloseFileInZip(zf);
+               if (err != ZIP_OK) {
+                       printf("error in closing %s in the zipfile\n",
+                                    filenameinzip);
+                       return false;
+               }
+       }
+       errclose = zipClose(zf, NULL);
+       if (errclose != ZIP_OK) {
+               printf("error in closing zip file\n");
+               return false;
+       }
+       free(buf);
+       return true;
+}
+
+// adapted from miniunz.c
+
+
+int mymkdir(char const * pathname, unsigned long int mode)
+{
+#if HAVE_MKDIR
+# if MKDIR_TAKES_ONE_ARG
+       // MinGW32
+       return ::mkdir(pathname);
+# else
+       // POSIX
+       return ::mkdir(pathname, mode_t(mode));
+# endif
+#elif defined(_WIN32)
+       // plain Windows 32
+       return CreateDirectory(pathname, 0) != 0 ? 0 : -1;
+#elif HAVE__MKDIR
+       return ::_mkdir(pathname);
+#else
+#   error "Don't know how to create a directory on this system."
+#endif
+}
+
+
+int makedir(char * newdir)
+{
+       char *buffer;
+       char *p;
+       int     len = (int)strlen(newdir);
+       int mode = 0775;
+
+       if (len <= 0)
+               return 1;
+
+       buffer = (char*)malloc(len+1);
+       strcpy(buffer,newdir);
+
+       if (buffer[len-1] == '/')
+               buffer[len-1] = '\0';
+       if (mymkdir(buffer, mode) == 0) {
+               free(buffer);
+               return 0;
+       }
+
+       p = buffer + 1;
+       while (1) {
+               char hold;
+
+               while(*p && *p != '\\' && *p != '/')
+                       p++;
+               hold = *p;
+               *p = 0;
+               if (mymkdir(buffer, mode) != 0) {
+                       printf("couldn't create directory %s\n",buffer);
+                       free(buffer);
+                       return 1;
+               }
+               if (hold == 0)
+                       break;
+               *p++ = hold;
+       }
+       free(buffer);
+       return 0;
+}
+
+
+/* change_file_date : change the date/time of a file
+       filename : the filename of the file where date/time must be modified
+       dosdate : the new date at the MSDos format (4 bytes)
+       tmu_date : the SAME new date at the tm_unz format */
+void change_file_date(const char * filename, uLong dosdate, tm_unz tmu_date)
+{
+#ifdef WIN32
+       HANDLE hFile;
+       FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
+
+       hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
+               0,NULL,OPEN_EXISTING,0,NULL);
+       GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
+       DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
+       LocalFileTimeToFileTime(&ftLocal,&ftm);
+       SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
+       CloseHandle(hFile);
+#else
+#ifdef unix
+       utimbuf ut;
+       tm newdate;
+
+       newdate.tm_sec = tmu_date.tm_sec;
+       newdate.tm_min=tmu_date.tm_min;
+       newdate.tm_hour=tmu_date.tm_hour;
+       newdate.tm_mday=tmu_date.tm_mday;
+       newdate.tm_mon=tmu_date.tm_mon;
+       if (tmu_date.tm_year > 1900)
+               newdate.tm_year=tmu_date.tm_year - 1900;
+       else
+               newdate.tm_year=tmu_date.tm_year ;
+       newdate.tm_isdst=-1;
+
+       ut.actime=ut.modtime=mktime(&newdate);
+       utime(filename,&ut);
+#endif
+#endif
+}
+
+
+int do_extract_currentfile(unzFile uf,
+       const int * popt_extract_without_path,
+       int * popt_overwrite,
+       const char * password,
+       const char * dirname)
+{
+       char filename_inzip[256];
+       char* filename_withoutpath;
+       char* p;
+       int err=UNZ_OK;
+       FILE *fout=NULL;
+       void* buf;
+       uInt size_buf;
+
+       unz_file_info file_info;
+       //uLong ratio=0;
+       err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+       if (err!=UNZ_OK) {
+               printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+               return err;
+       }
+
+       size_buf = WRITEBUFFERSIZE;
+       buf = (void*)malloc(size_buf);
+       if (buf==NULL) {
+               printf("Error allocating memory\n");
+               return UNZ_INTERNALERROR;
+       }
+
+       p = filename_withoutpath = filename_inzip;
+       while ((*p) != '\0') {
+               if (((*p)=='/') || ((*p)=='\\'))
+                       filename_withoutpath = p+1;
+               p++;
+       }
+       // this is a directory
+       if ((*filename_withoutpath)=='\0') {
+               if ((*popt_extract_without_path)==0)
+                       makedir(filename_inzip);
+       }
+       // this is a filename
+       else {
+               char write_filename[1024];
+
+               strcpy(write_filename, dirname);
+               int len = strlen(write_filename);
+               if (write_filename[len-1] != '\\' &&
+                       write_filename[len-1] != '/')
+                       strcat(write_filename, "/");
+
+               if ((*popt_extract_without_path)==0)
+                       strcat(write_filename, filename_inzip);
+               else
+                       strcat(write_filename, filename_withoutpath);
+
+               err = unzOpenCurrentFilePassword(uf,password);
+               if (err!=UNZ_OK) {
+                       printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
+               } else {
+                       fout=fopen(write_filename, "wb");
+
+                       /* some zipfile don't contain directory alone before file */
+                       if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
+                               (filename_withoutpath!=(char*)filename_inzip)) {
+                               char c=*(filename_withoutpath-1);
+                               *(filename_withoutpath-1)='\0';
+                               makedir(write_filename);
+                               *(filename_withoutpath-1)=c;
+                               fout=fopen(write_filename,"wb");
+                       }
+
+                       if (fout==NULL) {
+                               printf("error opening %s\n",write_filename);
+                       }
+               }
+
+               if (fout!=NULL) {
+
+                       do {
+                               err = unzReadCurrentFile(uf,buf,size_buf);
+                               if (err<0) {
+                                       printf("error %d with zipfile in unzReadCurrentFile\n",err);
+                                       break;
+                               }
+                               if (err>0)
+                                       if (fwrite(buf,err,1,fout)!=1) {
+                                               printf("error in writing extracted file\n");
+                                               err=UNZ_ERRNO;
+                                               break;
+                                       }
+                       } while (err>0);
+                       if (fout)
+                               fclose(fout);
+
+                       if (err==0)
+                               change_file_date(write_filename,file_info.dosDate,
+                                       file_info.tmu_date);
+               }
+
+               if (err==UNZ_OK) {
+                       err = unzCloseCurrentFile (uf);
+                       if (err!=UNZ_OK) {
+                               printf("error %d with zipfile in unzCloseCurrentFile\n",err);
+                       }
+               }
+               else
+                       unzCloseCurrentFile(uf);          /* don't lose the error */
+       }
+
+       free(buf);
+       return err;
+}
+
+
+bool unzipToDir(string const & zipfile, string const & dirname)
+{
+       unzFile uf=NULL;
+#ifdef USEWIN32IOAPI
+       zlib_filefunc_def ffunc;
+#endif
+
+       const char * zipfilename = zipfile.c_str();
+
+#ifdef USEWIN32IOAPI
+       fill_win32_filefunc(&ffunc);
+       uf = unzOpen2(zipfilename, &ffunc);
+#else
+       uf = unzOpen(zipfilename);
+#endif
+
+       if (uf==NULL) {
+               return false;
+       }
+
+       uLong i;
+       unz_global_info gi;
+       int err;
+       //FILE* fout=NULL;
+       int opt_extract_without_path = 0;
+       int opt_overwrite = 1;
+       char * password = NULL;
+
+       err = unzGetGlobalInfo (uf, &gi);
+       if (err != UNZ_OK) {
+               printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+               return false;
+       }
+
+       for (i=0; i < gi.number_entry; i++) {
+               if (do_extract_currentfile(uf, &opt_extract_without_path,
+                       &opt_overwrite,
+                       password, dirname.c_str()) != UNZ_OK)
+                       break;
+
+               if ((i+1)<gi.number_entry) {
+                       err = unzGoToNextFile(uf);
+                       if (err != UNZ_OK) {
+                               printf("error %d with zipfile in unzGoToNextFile\n",err);
+                               break;
+                       }
+               }
+       }
+
+       unzCloseCurrentFile(uf);
+    return true;
+}
+