-// 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
- struct utimbuf ut;
- struct 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;
-}