1 /*****************************************************************************
2 ** $Source: /cvsroot/bluemsx/blueMSX/Src/Utils/ziphelper.c,v $
3 **
4 ** $Revision: 1.6 $
5 **
6 ** $Date: 2008/03/30 21:38:43 $
7 **
8 ** More info: http://www.bluemsx.com
9 **
10 ** Copyright (C) 2003-2006 Daniel Vik
11 **
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License as published by
14 ** the Free Software Foundation; either version 2 of the License, or
15 ** (at your option) any later version.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 **
26 ******************************************************************************
27 */
28 #include "ziphelper.h"
29
30 #include "zip.h"
31 #include "unzip.h"
32 #include "ctype.h"
33 #include "ZipFromMem.h"
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/stat.h>
38 #include <errno.h>
39 #ifdef WIN32
40 #include <direct.h>
41 #endif
42
43 #if defined(MINGW)
44 #define MKDIR(x) mkdir(x)
45 #elif defined(WIN32)
46 #define MKDIR(x) _mkdir(x)
47 #else
48 #define MKDIR(x) mkdir(x,0777)
49 #endif
50
toLower(char * str)51 static void toLower(char* str) {
52 while (*str) {
53 *str = tolower(*str);
54 str++;
55 }
56 }
57
58 #if 1
59
60 #define MAX_FILES_IN_ZIP 64
61
62 typedef struct
63 {
64 char filename[32];
65 int size;
66 char* buffer;
67 } MemFile;
68
69 typedef struct
70 {
71 char zipName[32];
72 MemFile* memFiles[MAX_FILES_IN_ZIP];
73 int count;
74 } MemZipFile;
75
76 static MemZipFile** memZipFiles = NULL;
77 static int memZipFileCount = 0;
78
memZipFileDestroy(MemZipFile * memZipFile)79 void memZipFileDestroy(MemZipFile* memZipFile)
80 {
81 int i;
82
83 if (memZipFile == NULL)
84 {
85 return;
86 }
87
88 // Remove node
89 for (i = 0; i < memZipFileCount; i++)
90 {
91 if (memZipFiles[i] == memZipFile)
92 {
93 memZipFiles[i] = NULL;
94 }
95 }
96
97 // Delete file contents
98 for (i = 0; i < memZipFile->count; i++)
99 {
100 if (memZipFile->memFiles[i]->buffer != NULL)
101 {
102 free(memZipFile->memFiles[i]->buffer);
103 }
104 free(memZipFile->memFiles[i]);
105 }
106 free(memZipFile);
107 }
108
memZipFileSystemCreate(int maxFiles)109 void memZipFileSystemCreate(int maxFiles)
110 {
111 memZipFileCount = maxFiles;
112 memZipFiles = (MemZipFile**) calloc(memZipFileCount, sizeof(MemZipFile*));
113 }
114
memZipFileSystemDestroy()115 void memZipFileSystemDestroy()
116 {
117 int i;
118
119 if (memZipFileCount == 0)
120 {
121 return;
122 }
123
124 for (i = 0; i < memZipFileCount; i++)
125 {
126 memZipFileDestroy(memZipFiles[i]);
127 }
128 free(memZipFiles);
129
130 memZipFileCount = 0;
131 }
132
memZipFileFind(const char * zipName)133 MemZipFile* memZipFileFind(const char* zipName)
134 {
135 int i;
136 for (i = 0; i < memZipFileCount; i++)
137 {
138 if (memZipFiles[i] != NULL &&
139 strcmp(memZipFiles[i]->zipName, zipName) == 0)
140 {
141 return memZipFiles[i];
142 }
143 }
144 return NULL;
145 }
146
memZipFileCreate(const char * zipName)147 MemZipFile* memZipFileCreate(const char* zipName)
148 {
149 int i;
150
151 for (i = 0; i < memZipFileCount; i++)
152 {
153 if (memZipFiles[i] == NULL)
154 {
155 memZipFiles[i] = malloc(sizeof(MemZipFile));
156 strcpy(memZipFiles[i]->zipName, zipName);
157 memZipFiles[i]->count = 0;
158 return memZipFiles[i];
159 }
160 }
161 return NULL;
162 }
163
memFileFindInZip(MemZipFile * memZipFile,const char * filename)164 MemFile* memFileFindInZip(MemZipFile* memZipFile, const char* filename)
165 {
166 if (memZipFile != NULL)
167 {
168 int i;
169 for (i = 0; i < memZipFile->count; i++)
170 {
171 if (strcmp(memZipFile->memFiles[i]->filename, filename) == 0)
172 {
173 return memZipFile->memFiles[i];
174 }
175 }
176 }
177 return NULL;
178 }
179
memFileLoad(const char * zipName,const char * filename,int * size)180 void* memFileLoad(const char* zipName, const char* filename, int* size)
181 {
182 MemFile* memFile = memFileFindInZip(memZipFileFind(zipName), filename);
183 if (memFile != NULL && memFile->size > 0)
184 {
185 void* buffer = malloc(memFile->size);
186 memcpy(buffer, memFile->buffer, memFile->size);
187 *size = memFile->size;
188 return buffer;
189 }
190 *size = 0;
191 return NULL;
192 }
193
memFileSave(const char * zipName,const char * filename,int append,void * buffer,int size)194 int memFileSave(const char* zipName, const char* filename, int append, void* buffer, int size)
195 {
196 MemZipFile* memZipFile = memZipFileFind(zipName);
197 MemFile* memFile;
198
199 if (!append)
200 {
201 memZipFileDestroy(memZipFile);
202 memZipFile = NULL;
203 }
204
205 if (memZipFile == NULL)
206 {
207 memZipFile = memZipFileCreate(zipName);
208 }
209
210 if (memZipFile == NULL || memZipFile->count == MAX_FILES_IN_ZIP)
211 {
212 return 0;
213 }
214
215 memFile = malloc(sizeof(MemFile));
216 memFile->buffer = malloc(size);
217 memcpy(memFile->buffer, buffer, size);
218 memFile->size = size;
219 strcpy(memFile->filename, filename);
220
221 memZipFile->memFiles[memZipFile->count++] = memFile;
222
223 return 1;
224 }
225
226 #else
227 //////////////////////////////////////////
228 // Memory zip files
229
230 typedef struct {
231 char filename[32];
232 void* data;
233 int size;
234 unsigned long compSize;
235 } MemFile;
236
237 typedef struct {
238 char zipName[32];
239 MemFile memFile[32];
240 int count;
241 } MemZipFile;
242
memZipFileCreate(const char * zipName)243 MemZipFile* memZipFileCreate(const char* zipName)
244 {
245 MemZipFile* zipFile = (MemZipFile*)malloc(sizeof(MemZipFile));
246 if (zipFile == NULL) {
247 return NULL;
248 }
249 strcpy(zipFile->zipName, zipName);
250 zipFile->count = 0;
251
252 return zipFile;
253 }
254
memZipFileErase(MemZipFile * zipFile)255 void memZipFileErase(MemZipFile* zipFile)
256 {
257 int i;
258 for (i = 0; i < zipFile->count; i++) {
259 free(zipFile->memFile[i].data);
260 }
261 zipFile->count = 0;
262 }
263
memZipFileDestroy(MemZipFile * zipFile)264 void memZipFileDestroy(MemZipFile* zipFile)
265 {
266 memZipFileErase(zipFile);
267 free(zipFile);
268 }
269
memZipFileRead(MemZipFile * zipFile,const char * filename,int * size)270 void* memZipFileRead(MemZipFile* zipFile, const char* filename, int* size)
271 {
272 int i;
273 *size = 0;
274 for (i = 0; i < zipFile->count; i++) {
275 if (strcmp(filename, zipFile->memFile[i].filename) == 0) {
276 if (zipFile->memFile[i].size) {
277 unsigned long sz = zipFile->memFile[i].size;
278 void* buf = zipUncompress(zipFile->memFile[i].data, zipFile->memFile[i].compSize, &sz);
279 if (buf) {
280 *size = (int)sz;
281 return buf;
282 }
283 }
284 }
285 }
286 return NULL;
287 }
288
memZipFileWrite(MemZipFile * zipFile,const char * filename,void * buffer,int size)289 int memZipFileWrite(MemZipFile* zipFile, const char* filename, void* buffer, int size)
290 {
291 static const int MemFileCount = sizeof(zipFile->memFile) / sizeof(zipFile->memFile[0]);
292 unsigned long compSize;
293 void* compBuf;
294 MemFile* memFile = NULL;
295 int i;
296 for (i = 0; i < zipFile->count; i++) {
297 if (strcmp(filename, zipFile->memFile[i].filename) == 0) {
298 memFile = &zipFile->memFile[i];
299 free(memFile->data);
300 }
301 }
302 if (memFile == NULL && zipFile->count < MemFileCount) {
303 memFile = &zipFile->memFile[zipFile->count++];
304 }
305 if (memFile == NULL) {
306 return 0;
307 }
308
309 compBuf = zipCompress(buffer, size, &compSize);
310 memFile->data = malloc(compSize);
311 memcpy(memFile->data, compBuf, compSize);
312 memFile->size = memFile->data ? size : 0;
313 memFile->compSize = compSize;
314 strcpy(memFile->filename, filename);
315 free(compBuf);
316
317 return 1;
318 }
319
320 //////////////////////////////////////////
321 // Memory zip file system
322
323
324 typedef struct {
325 MemZipFile** zipFiles;
326 int count;
327 int maxFiles;
328 } MemZipFileSystem;
329
330 MemZipFileSystem memZipFileSystem;
331
memZipFileSystemCreate(int maxFiles)332 void memZipFileSystemCreate(int maxFiles)
333 {
334 memZipFileSystem.zipFiles = (MemZipFile**)malloc(maxFiles * sizeof(MemZipFile*));
335 memZipFileSystem.count = 0;
336 memZipFileSystem.maxFiles = maxFiles;
337 }
338
memZipFileSystemDestroy()339 void memZipFileSystemDestroy()
340 {
341 int i;
342
343 if (memZipFileSystem.zipFiles == NULL) {
344 return;
345 }
346
347 for (i = 0; i < memZipFileSystem.count; i++) {
348 memZipFileDestroy(memZipFileSystem.zipFiles[i]);
349 }
350
351 free(memZipFileSystem.zipFiles);
352 memZipFileSystem.zipFiles = NULL;
353 memZipFileSystem.count = 0;
354 }
355
memZipFileSystemOpen(const char * filename,int create)356 MemZipFile* memZipFileSystemOpen(const char* filename, int create)
357 {
358 int i;
359 for (i = 0; i < memZipFileSystem.count; i++) {
360 MemZipFile* zipFile = memZipFileSystem.zipFiles[i];
361 if (strcmp(filename, zipFile->zipName) == 0) {
362 return zipFile;
363 }
364 }
365 if (create) {
366 if (memZipFileSystem.count < memZipFileSystem.maxFiles) {
367 MemZipFile* zipFile = memZipFileCreate(filename);
368 if (zipFile != NULL) {
369 memZipFileSystem.zipFiles[memZipFileSystem.count++] = zipFile;
370 }
371 return zipFile;
372 }
373 }
374 return NULL;
375 }
376
377 ////////////////////////////////////////
378
memFileLoad(const char * zipName,const char * filename,int * size)379 void* memFileLoad(const char* zipName, const char* filename, int* size)
380 {
381 MemZipFile* zipFile;
382
383 *size = 0;
384
385 zipFile = memZipFileSystemOpen(zipName, 0);
386 if (zipFile == NULL) {
387 return NULL;
388 }
389
390 return memZipFileRead(zipFile, filename, size);
391 }
392
memFileSave(const char * zipName,const char * filename,int append,void * buffer,int size)393 int memFileSave(const char* zipName, const char* filename, int append, void* buffer, int size)
394 {
395 MemZipFile* zipFile = memZipFileSystemOpen(zipName, 1);
396 if (zipFile == NULL) {
397 return 0;
398 }
399
400 if (!append) {
401 memZipFileErase(zipFile);
402 }
403
404 return memZipFileWrite(zipFile, filename, buffer, size);
405 }
406
407 #endif
408
409 /******************************************************************************
410 *** Description
411 *** Load a file in a zip file into memory.
412 ***
413 *** Arguments
414 *** zipName - Name of zip file
415 *** fileName - Name of file insize zipfile to load
416 *** size - Output of size of file
417 ***
418 *** Return
419 *** Pointer to allocate memory buffer with file content or NULL on
420 *** failure.
421 ***
422 *******************************************************************************
423 */
_zipLoadFile(const char * zipName,const char * fileName,int * size,zlib_filefunc_def * filefunc)424 void* _zipLoadFile(const char* zipName, const char* fileName, int* size, zlib_filefunc_def* filefunc)
425 {
426 void* buf;
427 char name[256];
428 unzFile zip;
429 unz_file_info info;
430
431 *size = 0;
432
433 if (fileName[0] == '*') {
434 strcpy(name, zipName);
435 name[strlen(zipName) - 3] = fileName[strlen(fileName) - 3];
436 name[strlen(zipName) - 2] = fileName[strlen(fileName) - 2];
437 name[strlen(zipName) - 1] = fileName[strlen(fileName) - 1];
438 }
439 else {
440 strcpy(name, fileName);
441 }
442
443 zip = unzOpen2(zipName, filefunc);
444 if (!zip) {
445 return NULL;
446 }
447
448 #ifdef __APPLE__
449 // Most OS X installs are on a case-insensitive FS
450 if (unzLocateFile(zip, name, 2) == UNZ_END_OF_LIST_OF_FILE) {
451 #else
452 if (unzLocateFile(zip, name, 1) == UNZ_END_OF_LIST_OF_FILE) {
453 #endif
454 unzClose(zip);
455 return NULL;
456 }
457
458 if (unzOpenCurrentFile(zip) != UNZ_OK) {
459 return NULL;
460 }
461
462 unzGetCurrentFileInfo(zip,&info,NULL,0,NULL,0,NULL,0);
463
464 buf = malloc(info.uncompressed_size);
465 *size = info.uncompressed_size;
466
467 if (!buf) {
468 unzCloseCurrentFile(zip);
469 unzClose(zip);
470 return NULL;
471 }
472
473 unzReadCurrentFile(zip, buf, info.uncompressed_size);
474 unzCloseCurrentFile(zip);
475 unzClose(zip);
476
477 return buf;
478 }
479
480
481 /******************************************************************************
482 *** Description
483 *** Read cache to speed-up reading multiple files from one zip.
484 ***
485 ******************************************************************************/
486
487 static char *cacheData = NULL, cacheFile[512];
488 static zlib_filefunc_def cacheFilefunc;
489
490 void* zipLoadFile(const char* zipName, const char* fileName, int* size)
491 {
492 if (strncmp(zipName, "mem", 3) == 0) {
493 return memFileLoad(zipName, fileName, size);
494 }
495 if( cacheData != NULL && *cacheFile != '\0' && 0==strcmp(cacheFile, zipName) ) {
496 return _zipLoadFile(cacheData, fileName, size, &cacheFilefunc);
497 }else{
498 return _zipLoadFile(zipName, fileName, size, NULL);
499 }
500 }
501
502 void zipCacheReadOnlyZip(const char* zipName)
503 {
504 if (zipName != NULL && strncmp(zipName, "mem", 3) == 0) {
505 return;
506 }
507
508 *cacheFile = '\0';
509 if( cacheData != NULL ) {
510 free(cacheData);
511 cacheData = NULL;
512 free_fopen_memfunc(&cacheFilefunc);
513 }
514 if( zipName != NULL ) {
515 FILE *file;
516 file = fopen(zipName, "rb");
517 if( file != NULL ) {
518 unsigned int filesize;
519 fseek(file, 0, SEEK_END);
520 filesize = ftell(file);
521 fill_fopen_memfunc(&cacheFilefunc, filesize);
522 fseek(file, 0, SEEK_SET);
523 cacheData = malloc(filesize);
524 if( cacheData != NULL ) {
525 size_t size = fread(cacheData, 1, filesize, file);
526 if( size == filesize ) {
527 strcpy(cacheFile, zipName);
528 }
529 }
530 fclose(file);
531 }
532 }
533 }
534
535
536 /******************************************************************************
537 *** Description
538 *** Load a file in a zip file into memory.
539 ***
540 *** Arguments
541 *** zipName - Name of zip file
542 *** fileName - Name of file insize zipfile to save
543 *** buffer - Buffer to save
544 *** size - Size of buffer to save
545 ***
546 *******************************************************************************
547 */
548 int zipSaveFile(const char* zipName, const char* fileName, int append, void* buffer, int size)
549 {
550 zipFile zip;
551 zip_fileinfo zi;
552 int err;
553
554 if (strncmp(zipName, "mem", 3) == 0) {
555 return memFileSave(zipName, fileName, append, buffer, size);
556 }
557
558 zip = zipOpen(zipName, append ? 2 : 0);
559 if (zip == NULL) {
560 return 0;
561 }
562
563 memset(&zi, 0, sizeof(zi));
564
565 err = zipOpenNewFileInZip(zip, fileName, &zi,
566 NULL, 0, NULL, 0, NULL,
567 Z_DEFLATED, Z_DEFAULT_COMPRESSION);
568 if (err == ZIP_OK) {
569 err = zipWriteInFileInZip(zip, buffer, size);
570 }
571
572 zipClose(zip, NULL);
573
574 return err >= 0;
575 }
576
577 int zipHasFileType(char* zipName, char* ext) {
578 char tempName[256];
579 char extension[8];
580 unzFile zip;
581 unz_file_info info;
582 int found = 0;
583 int status;
584
585 zip = unzOpen(zipName);
586 if (!zip) {
587 return 0;
588 }
589
590 strcpy(extension, ext);
591 toLower(extension);
592
593 status = unzGoToFirstFile(zip);
594 unzGetCurrentFileInfo(zip,&info,tempName,256,NULL,0,NULL,0);
595
596 while (status == UNZ_OK) {
597 unzGetCurrentFileInfo(zip, &info, tempName, 256, NULL, 0, NULL, 0);
598
599 toLower(tempName);
600 if (strstr(tempName, extension) != NULL) {
601 found = 1;
602 break;
603 }
604
605 status = unzGoToNextFile(zip);
606 }
607
608 unzClose(zip);
609
610 return found;
611 }
612
613 /******************************************************************************
614 *** Description
615 *** Checks if a file exists in a zip file.
616 ***
617 *** Arguments
618 *** zipName - Name of zip file
619 *** fileName - Name of file insize zipfile to load
620 ***
621 *** Return
622 *** 1 = file exists, 0 = non existing zip or file in zip does not exists
623 *** failure.
624 ***
625 *******************************************************************************
626 */
627 int zipFileExists(const char* zipName, const char* fileName)
628 {
629 char name[256];
630 unzFile zip;
631
632 if (fileName[0] == '*') {
633 strcpy(name, zipName);
634 name[strlen(zipName) - 3] = fileName[strlen(fileName) - 3];
635 name[strlen(zipName) - 2] = fileName[strlen(fileName) - 2];
636 name[strlen(zipName) - 1] = fileName[strlen(fileName) - 1];
637 }
638 else {
639 strcpy(name, fileName);
640 }
641
642 zip = unzOpen(zipName);
643 if (!zip) {
644 return 0;
645 }
646
647 #ifdef __APPLE__
648 // Most OS X installs are on a case-insensitive FS
649 if (unzLocateFile(zip, name, 2) == UNZ_END_OF_LIST_OF_FILE) {
650 #else
651 if (unzLocateFile(zip, name, 1) == UNZ_END_OF_LIST_OF_FILE) {
652 #endif
653 unzClose(zip);
654 return 0;
655 }else{
656 unzClose(zip);
657 return 1;
658 }
659 }
660
661 /******************************************************************************
662 *** Description
663 *** Creates a list of file names inside a zip that matches a given
664 *** extension.
665 ***
666 *** Arguments
667 *** zipName - Name of zip file
668 *** ext - Extension to check
669 *** count - Output for number of matching files in zip file.
670 ***
671 *** Return
672 *** 1 if files with the given extension exists in the zip file,
673 *** 0 otherwise.
674 ***
675 *******************************************************************************
676 */
677 char* zipGetFileList(const char* zipName, const char* ext, int* count) {
678 char tempName[256];
679 char extension[8];
680 unzFile zip;
681 unz_file_info info;
682 char* fileArray = NULL;
683 int totalLen = 0;
684 int status;
685
686 *count = 0;
687
688 zip = unzOpen(zipName);
689 if (!zip) {
690 return 0;
691 }
692
693 strcpy(extension, ext);
694 toLower(extension);
695
696 status = unzGoToFirstFile(zip);
697 unzGetCurrentFileInfo(zip,&info,tempName,256,NULL,0,NULL,0);
698
699 while (status == UNZ_OK) {
700 char tmp[256];
701
702 unzGetCurrentFileInfo(zip, &info, tempName, 256, NULL, 0, NULL, 0);
703
704 strcpy(tmp, tempName);
705
706 toLower(tmp);
707 if (strstr(tmp, extension) != NULL) {
708 int entryLen = strlen(tempName) + 1;
709 fileArray = realloc(fileArray, totalLen + entryLen + 1);
710 strcpy(fileArray + totalLen, tempName);
711 totalLen += entryLen;
712 fileArray[totalLen] = '\0'; // double null termination at end
713
714 *count = *count + 1;
715 }
716
717 status = unzGoToNextFile(zip);
718 }
719
720 unzClose(zip);
721
722 return fileArray;
723 }
724
725 /******************************************************************************
726 *** Description
727 *** zipExtractCurrentfile - Extracts the current file from the zip
728 *** zipExtract - Extracts the whole zip file
729 ***
730 *** Arguments
731 *** uf - The zip file
732 *** overwrite - 1 = overwrite files, 0 = do not overwrite files
733 *** password - Optional password for the zip
734 ***
735 *** Return
736 *** 1 okay,
737 *** 0 failed.
738 ***
739 *******************************************************************************
740 */
741 #define WRITEBUFFERSIZE 8192
742
743 static int makedir(const char *newdir)
744 {
745 char *buffer;
746 char *p;
747 int len = (int)strlen(newdir);
748
749 if (len <= 0) return 0;
750
751 buffer = (char*)malloc(len+1);
752 strcpy(buffer,newdir);
753
754 if (buffer[len-1] == '/') {
755 buffer[len-1] = '\0';
756 }
757 if (MKDIR(buffer) == 0) {
758 free(buffer);
759 return 1;
760 }
761
762 p = buffer+1;
763 while (1) {
764 char hold;
765
766 while(*p && *p != '\\' && *p != '/') p++;
767 hold = *p;
768 *p = 0;
769 if ((MKDIR(buffer) == -1) && (errno == ENOENT))
770 {
771 printf("couldn't create directory %s\n",buffer);
772 free(buffer);
773 return 0;
774 }
775 if (hold == 0) break;
776 *p++ = hold;
777 }
778 free(buffer);
779 return 1;
780 }
781
782 int zipExtractCurrentfile(unzFile uf, int overwrite, const char* password)
783 {
784 char filename_inzip[256];
785 char* filename_withoutpath;
786 char* p;
787 int err=UNZ_OK;
788 FILE *fout=NULL;
789 void* buf;
790 uInt size_buf;
791
792 unz_file_info file_info;
793 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
794
795 if( err != UNZ_OK ) {
796 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
797 return 0;
798 }
799
800 size_buf = WRITEBUFFERSIZE;
801 buf = (void*)malloc(size_buf);
802
803 p = filename_withoutpath = filename_inzip;
804 while ((*p) != '\0') {
805 if (((*p)=='/') || ((*p)=='\\'))
806 filename_withoutpath = p+1;
807 p++;
808 }
809
810 if ((*filename_withoutpath)=='\0') {
811 MKDIR(filename_inzip);
812 }else{
813 const char* write_filename;
814 int skip=0;
815
816 write_filename = filename_inzip;
817
818 err = unzOpenCurrentFilePassword(uf,password);
819 if (err!=UNZ_OK) {
820 printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
821 }
822
823 if ((overwrite==0) && (err==UNZ_OK)) {
824 FILE* ftestexist = fopen(write_filename,"rb");
825 if (ftestexist!=NULL) {
826 fclose(ftestexist);
827 skip = 1;
828 }
829 }
830
831 if ((skip==0) && (err==UNZ_OK)) {
832 fout=fopen(write_filename,"wb");
833
834 /* some zipfile don't contain directory alone before file */
835 if( (fout==NULL) && (filename_withoutpath!=(char*)filename_inzip) ) {
836 char c=*(filename_withoutpath-1);
837 *(filename_withoutpath-1)='\0';
838 makedir(write_filename);
839 *(filename_withoutpath-1)=c;
840 fout=fopen(write_filename,"wb");
841 }
842
843 if( fout == NULL ) {
844 printf("error opening %s\n",write_filename);
845 }
846 }
847
848 if (fout!=NULL)
849 {
850 printf(" extracting: %s\n",write_filename);
851 do {
852 err = unzReadCurrentFile(uf,buf,size_buf);
853 if( err < 0 ) {
854 printf("error %d with zipfile in unzReadCurrentFile\n",err);
855 break;
856 }
857 if( err > 0 ) {
858 if (fwrite(buf,err,1,fout)!=1) {
859 printf("error in writing extracted file\n");
860 err=UNZ_ERRNO;
861 break;
862 }
863 }
864 }while( err > 0 );
865 if( fout ) fclose(fout);
866 }
867
868 if(err == UNZ_OK) {
869 err = unzCloseCurrentFile (uf);
870 if( err != UNZ_OK ) {
871 printf("error %d with zipfile in unzCloseCurrentFile\n",err);
872 }
873 }else{
874 unzCloseCurrentFile(uf); /* don't lose the error */
875 }
876 }
877
878 free(buf);
879 return 1;
880 }
881
882 int zipExtract(unzFile uf, int overwrite, const char* password,
883 ZIP_EXTRACT_CB progress_callback)
884 {
885 uLong i;
886 unz_global_info gi;
887 int err;
888
889 err = unzGetGlobalInfo(uf,&gi);
890 if (err!=UNZ_OK) {
891 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
892 return 0;
893 }
894
895 for (i = 0; i < gi.number_entry; i++)
896 {
897 if( progress_callback ) {
898 progress_callback(gi.number_entry, i);
899 }
900 if( !zipExtractCurrentfile(uf, overwrite, password) ) {
901 return 0;
902 }
903 if ((i+1) < gi.number_entry)
904 {
905 err = unzGoToNextFile(uf);
906 if (err!=UNZ_OK)
907 {
908 printf("error %d with zipfile in unzGoToNextFile\n",err);
909 return 0;
910 }
911 }
912 }
913
914 return 1;
915 }
916
917 void* zipCompress(void* buffer, int size, unsigned long* retSize)
918 {
919 void* retBuf;
920
921 *retSize = (size * 1001) / 1000 + 12;
922 retBuf = malloc(*retSize);
923
924 if (compress(retBuf, retSize, buffer, size) != Z_OK) {
925 free(retBuf);
926 retBuf = NULL;
927 }
928
929 return retBuf;
930 }
931
932 void* zipUncompress(void* buffer, int size, unsigned long* retSize)
933 {
934 void* retBuf = malloc(*retSize);
935
936 if (uncompress(retBuf, retSize, buffer, size) != Z_OK) {
937 free(retBuf);
938 retBuf = NULL;
939 }
940
941 return retBuf;
942 }
943