|
|
1.1 root 1: /*
1.1.1.2 root 2: Hatari - zip.c
3:
1.1.1.11 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
1.1.1.4 root 7: Zipped disk support, uses zlib
1.1 root 8: */
1.1.1.9 root 9: const char ZIP_fileid[] = "Hatari zip.c : " __DATE__ " " __TIME__;
1.1 root 10:
11: #include <stdio.h>
12: #include <stdlib.h>
13: #include <unistd.h>
14: #include <dirent.h>
1.1.1.5 root 15: #include <sys/types.h>
1.1.1.2 root 16: #include <zlib.h>
17:
1.1 root 18: #include "main.h"
1.1.1.2 root 19: #include "dim.h"
20: #include "file.h"
21: #include "floppy.h"
1.1.1.12! root 22: #include "floppy_ipf.h"
! 23: #include "floppy_stx.h"
1.1.1.3 root 24: #include "log.h"
1.1.1.2 root 25: #include "msa.h"
26: #include "st.h"
1.1.1.9 root 27: #include "str.h"
1.1 root 28: #include "unzip.h"
29: #include "zip.h"
30:
1.1.1.5 root 31: #ifdef QNX
32: #include <sys/dir.h>
33: #define dirent direct
34: #endif
35:
1.1 root 36: /* #define SAVE_TO_ZIP_IMAGES */
37:
38: #define ZIP_PATH_MAX 256
39:
1.1.1.12! root 40: #if HAVE_LIBZ
1.1.1.2 root 41:
1.1.1.5 root 42: /* Possible disk image extensions to scan for */
43: static const char * const pszDiskNameExts[] =
44: {
1.1.1.12! root 45: ".msa",
! 46: ".st",
! 47: ".dim",
! 48: ".ipf",
! 49: ".raw",
! 50: ".ctr",
! 51: ".stx",
! 52: NULL
1.1.1.5 root 53: };
54:
55:
1.1.1.2 root 56: /*-----------------------------------------------------------------------*/
1.1.1.6 root 57: /**
1.1.1.9 root 58: * Does filename end with a .ZIP extension? If so, return true.
1.1.1.6 root 59: */
1.1.1.7 root 60: bool ZIP_FileNameIsZIP(const char *pszFileName)
1.1.1.2 root 61: {
1.1.1.5 root 62: return File_DoesFileExtensionMatch(pszFileName,".zip");
1.1.1.2 root 63: }
1.1 root 64:
65:
1.1.1.2 root 66: /*-----------------------------------------------------------------------*/
1.1.1.6 root 67: /**
68: * Check if a file name contains a slash or backslash and return its position.
69: */
70: static int Zip_FileNameHasSlash(const char *fn)
1.1 root 71: {
1.1.1.5 root 72: int i=0;
73:
74: while (fn[i] != '\0')
75: {
76: if (fn[i] == '\\' || fn[i] == '/')
77: return i;
78: i++;
79: }
80: return -1;
1.1 root 81: }
82:
1.1.1.2 root 83:
1.1 root 84: /*-----------------------------------------------------------------------*/
1.1.1.6 root 85: /**
86: * Returns a list of files from a zip file. returns NULL on failure,
87: * returns a pointer to an array of strings if successful. Sets nfiles
88: * to the number of files.
89: */
90: zip_dir *ZIP_GetFiles(const char *pszFileName)
1.1 root 91: {
1.1.1.5 root 92: int nfiles;
93: unsigned int i;
94: unz_global_info gi;
95: int err;
96: unzFile uf;
97: char **filelist;
98: unz_file_info file_info;
99: char filename_inzip[ZIP_PATH_MAX];
100: zip_dir *zd;
101:
102: uf = unzOpen(pszFileName);
103: if (uf == NULL)
104: {
105: Log_Printf(LOG_ERROR, "ZIP_GetFiles: Cannot open %s\n", pszFileName);
106: return NULL;
107: }
1.1.1.3 root 108:
1.1.1.5 root 109: err = unzGetGlobalInfo(uf,&gi);
110: if (err != UNZ_OK)
111: {
112: Log_Printf(LOG_ERROR, "Error %d with zipfile in unzGetGlobalInfo \n",err);
113: return NULL;
114: }
115:
116: /* allocate a file list */
117: filelist = (char **)malloc(gi.number_entry*sizeof(char *));
118: if (!filelist)
119: {
120: perror("ZIP_GetFiles");
121: return NULL;
122: }
123:
124: nfiles = gi.number_entry; /* set the number of files */
125:
126: for (i = 0; i < gi.number_entry; i++)
127: {
128: err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, ZIP_PATH_MAX, NULL, 0, NULL, 0);
129: if (err != UNZ_OK)
130: {
131: free(filelist);
132: return NULL;
133: }
134:
135: filelist[i] = (char *)malloc(strlen(filename_inzip) + 1);
136: if (!filelist[i])
137: {
138: perror("ZIP_GetFiles");
139: free(filelist);
140: return NULL;
141: }
142:
143: strcpy(filelist[i], filename_inzip);
144: if ((i+1) < gi.number_entry)
145: {
146: err = unzGoToNextFile(uf);
147: if (err != UNZ_OK)
148: {
149: Log_Printf(LOG_ERROR, "ZIP_GetFiles: Error in ZIP-file\n");
150: /* deallocate memory */
151: for (; i > 0; i--)
152: free(filelist[i]);
153: free(filelist);
154: return NULL;
155: }
156: }
157: }
158:
159: unzClose(uf);
160:
161: zd = (zip_dir *)malloc(sizeof(zip_dir));
162: if (!zd)
163: {
164: perror("ZIP_GetFiles");
165: free(filelist);
166: return NULL;
167: }
168: zd->names = filelist;
169: zd->nfiles = nfiles;
170:
171: return zd;
1.1 root 172: }
173:
1.1.1.2 root 174:
175: /*-----------------------------------------------------------------------*/
1.1.1.6 root 176: /**
177: * Free the memory that has been allocated for a zip_dir.
178: */
1.1.1.2 root 179: void ZIP_FreeZipDir(zip_dir *f_zd)
180: {
1.1.1.5 root 181: while (f_zd->nfiles > 0)
182: {
183: f_zd->nfiles--;
184: free(f_zd->names[f_zd->nfiles]);
185: f_zd->names[f_zd->nfiles] = NULL;
186: }
187: free(f_zd->names);
188: f_zd->names = NULL;
189: free(f_zd);
1.1.1.2 root 190: }
191:
192:
1.1 root 193: /*-----------------------------------------------------------------------*/
1.1.1.6 root 194: /**
1.1.1.10 root 195: * Free the memory that has been allocated for fentries.
196: */
197: static void ZIP_FreeFentries(struct dirent **fentries, int entries)
198: {
199: while (entries > 0)
200: {
201: entries--;
202: free(fentries[entries]);
203: }
204: free(fentries);
205: }
206:
207:
208: /*-----------------------------------------------------------------------*/
209: /**
1.1.1.6 root 210: * Returns a list of files from the directory (dir) in a zip file list (zip)
211: * sets entries to the number of entries and returns a dirent structure, or
212: * NULL on failure. NOTE: only f_name is set in the dirent structures.
213: */
214: struct dirent **ZIP_GetFilesDir(const zip_dir *zip, const char *dir, int *entries)
1.1 root 215: {
1.1.1.5 root 216: int i,j;
217: zip_dir *files;
218: char *temp;
1.1.1.7 root 219: bool flag;
1.1.1.5 root 220: int slash;
221: struct dirent **fentries;
222:
223: files = (zip_dir *)malloc(sizeof(zip_dir));
224: if (!files)
225: {
226: perror("ZIP_GetFilesDir");
227: return NULL;
228: }
229:
230: files->names = (char **)malloc((zip->nfiles + 1) * sizeof(char *));
231: if (!files->names)
232: {
233: perror("ZIP_GetFilesDir");
234: free(files);
235: return NULL;
236: }
237:
238: /* add ".." directory */
239: files->nfiles = 1;
240: temp = (char *)malloc(4);
241: if (!temp)
1.1.1.10 root 242: {
243: ZIP_FreeZipDir(files);
1.1.1.5 root 244: return NULL;
1.1.1.10 root 245: }
1.1.1.5 root 246: temp[0] = temp[1] = '.';
247: temp[2] = '/';
248: temp[3] = '\0';
249: files->names[0] = temp;
250:
251: for (i = 0; i < zip->nfiles; i++)
252: {
253: if (strlen(zip->names[i]) > strlen(dir))
1.1 root 254: {
1.1.1.5 root 255: if (strncasecmp(zip->names[i], dir, strlen(dir)) == 0)
1.1 root 256: {
1.1.1.5 root 257: temp = zip->names[i];
258: temp = (char *)(temp + strlen(dir));
259: if (temp[0] != '\0')
260: {
261: if ((slash=Zip_FileNameHasSlash(temp)) > 0)
262: {
263: /* file is in a subdirectory, add this subdirectory if it doesn't exist in the list */
1.1.1.9 root 264: flag = false;
1.1.1.5 root 265: for (j = files->nfiles-1; j > 0; j--)
266: {
267: if (strncasecmp(temp, files->names[j], slash+1) == 0)
1.1.1.9 root 268: flag = true;
1.1.1.5 root 269: }
1.1.1.9 root 270: if (flag == false)
1.1.1.5 root 271: {
1.1.1.6 root 272: files->names[files->nfiles] = (char *)malloc(slash+2);
1.1.1.5 root 273: if (!files->names[files->nfiles])
274: {
275: perror("ZIP_GetFilesDir");
1.1.1.10 root 276: ZIP_FreeZipDir(files);
1.1.1.5 root 277: return NULL;
278: }
279: strncpy(files->names[files->nfiles], temp, slash+1);
280: ((char *)files->names[files->nfiles])[slash+1] = '\0';
281: files->nfiles++;
282: }
283: }
284: else
285: {
286: /* add a filename */
287: files->names[files->nfiles] = (char *)malloc(strlen(temp)+1);
288: if (!files->names[files->nfiles])
289: {
290: perror("ZIP_GetFilesDir");
1.1.1.10 root 291: ZIP_FreeZipDir(files);
1.1.1.5 root 292: return NULL;
293: }
294: strncpy(files->names[files->nfiles], temp, strlen(temp));
295: ((char *)files->names[files->nfiles])[strlen(temp)] = '\0';
296: files->nfiles++;
297: }
298: }
1.1 root 299: }
300: }
301: }
302:
1.1.1.5 root 303: /* copy to a dirent structure */
304: *entries = files->nfiles;
305: fentries = (struct dirent **)malloc(sizeof(struct dirent *)*files->nfiles);
306: if (!fentries)
307: {
308: perror("ZIP_GetFilesDir");
309: ZIP_FreeZipDir(files);
310: return NULL;
311: }
312: for (i = 0; i < files->nfiles; i++)
313: {
314: fentries[i] = (struct dirent *)malloc(sizeof(struct dirent));
315: if (!fentries[i])
316: {
317: perror("ZIP_GetFilesDir");
1.1.1.10 root 318: ZIP_FreeFentries(fentries, i+1);
1.1.1.12! root 319: ZIP_FreeZipDir(files);
1.1.1.5 root 320: return NULL;
321: }
322: strcpy(fentries[i]->d_name, files->names[i]);
323: }
1.1.1.3 root 324:
1.1.1.5 root 325: ZIP_FreeZipDir(files);
1.1.1.3 root 326:
1.1.1.5 root 327: return fentries;
1.1 root 328: }
329:
1.1.1.3 root 330:
1.1 root 331: /*-----------------------------------------------------------------------*/
1.1.1.6 root 332: /**
333: * Check an image file in the archive, return the uncompressed length
334: */
1.1.1.12! root 335: static long ZIP_CheckImageFile(unzFile uf, char *filename, int namelen, int *pImageType)
1.1 root 336: {
1.1.1.5 root 337: unz_file_info file_info;
338:
339: if (unzLocateFile(uf,filename, 0) != UNZ_OK)
340: {
1.1.1.6 root 341: Log_Printf(LOG_ERROR, "Error: File \"%s\" not found in the archive!\n", filename);
1.1.1.5 root 342: return -1;
343: }
344:
1.1.1.6 root 345: if (unzGetCurrentFileInfo(uf, &file_info, filename, namelen, NULL, 0, NULL, 0) != UNZ_OK)
1.1.1.5 root 346: {
1.1.1.6 root 347: Log_Printf(LOG_ERROR, "Error with zipfile in unzGetCurrentFileInfo\n");
1.1.1.5 root 348: return -1;
349: }
350:
1.1.1.12! root 351: /* check for .stx, .ipf, .msa, .dim or .st extension */
! 352: if (STX_FileNameIsSTX(filename, false))
! 353: {
! 354: *pImageType = FLOPPY_IMAGE_TYPE_STX;
! 355: return file_info.uncompressed_size;
! 356: }
! 357:
! 358: if (IPF_FileNameIsIPF(filename, false))
! 359: {
! 360: *pImageType = FLOPPY_IMAGE_TYPE_IPF;
! 361: return file_info.uncompressed_size;
! 362: }
! 363:
1.1.1.9 root 364: if (MSA_FileNameIsMSA(filename, false))
1.1.1.5 root 365: {
1.1.1.12! root 366: *pImageType = FLOPPY_IMAGE_TYPE_MSA;
1.1.1.5 root 367: return file_info.uncompressed_size;
368: }
369:
1.1.1.9 root 370: if (ST_FileNameIsST(filename, false))
1.1.1.5 root 371: {
1.1.1.12! root 372: *pImageType = FLOPPY_IMAGE_TYPE_ST;
1.1.1.5 root 373: return file_info.uncompressed_size;
374: }
375:
1.1.1.9 root 376: if (DIM_FileNameIsDIM(filename, false))
1.1.1.5 root 377: {
1.1.1.12! root 378: *pImageType = FLOPPY_IMAGE_TYPE_DIM;
1.1.1.5 root 379: return file_info.uncompressed_size;
380: }
381:
1.1.1.12! root 382: Log_Printf(LOG_ERROR, "Not an .ST, .MSA, .DIM, .IPF or .STX file.\n");
1.1.1.5 root 383: return 0;
384: }
385:
386: /*-----------------------------------------------------------------------*/
1.1.1.6 root 387: /**
388: * Return the first matching file in a zip, or NULL on failure.
389: * String buffer size is ZIP_PATH_MAX
390: */
391: static char *ZIP_FirstFile(const char *filename, const char * const ppsExts[])
1.1.1.5 root 392: {
393: zip_dir *files;
394: int i, j;
395: char *name;
396:
397: files = ZIP_GetFiles(filename);
398: if (files == NULL)
399: return NULL;
400:
401: name = malloc(ZIP_PATH_MAX);
402: if (!name)
403: {
404: perror("ZIP_FirstFile");
1.1.1.12! root 405: ZIP_FreeZipDir(files);
1.1.1.5 root 406: return NULL;
407: }
408:
409: /* Do we have to scan for a certain extension? */
410: if (ppsExts)
411: {
412: name[0] = '\0';
413: for(i = files->nfiles-1; i >= 0; i--)
414: {
415: for (j = 0; ppsExts[j] != NULL; j++)
416: {
417: if (File_DoesFileExtensionMatch(files->names[i], ppsExts[j]))
418: {
419: strncpy(name, files->names[i], ZIP_PATH_MAX);
420: break;
421: }
422: }
423: }
424: }
425: else
426: {
427: /* There was no extension given -> use the very first name */
428: strncpy(name, files->names[0], ZIP_PATH_MAX);
429: }
1.1 root 430:
1.1.1.5 root 431: /* free the files */
432: ZIP_FreeZipDir(files);
433:
434: if (name[0] == '\0')
1.1.1.12! root 435: {
! 436: free(name);
1.1.1.5 root 437: return NULL;
1.1.1.12! root 438: }
! 439:
1.1.1.5 root 440: return name;
1.1 root 441: }
442:
443:
444: /*-----------------------------------------------------------------------*/
1.1.1.6 root 445: /**
446: * Extract a file (filename) from a ZIP-file (uf), the number of
447: * bytes to uncompress is size. Returns a pointer to a buffer containing
448: * the uncompressed data, or NULL.
449: */
450: static void *ZIP_ExtractFile(unzFile uf, const char *filename, uLong size)
1.1 root 451: {
1.1.1.5 root 452: int err = UNZ_OK;
453: char filename_inzip[ZIP_PATH_MAX];
454: void* buf;
455: uInt size_buf;
456: unz_file_info file_info;
457:
458:
459: if (unzLocateFile(uf,filename, 0) != UNZ_OK)
460: {
461: Log_Printf(LOG_ERROR, "ZIP_ExtractFile: could not find file in archive\n");
462: return NULL;
463: }
464:
465: err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
466:
467: if (err != UNZ_OK)
468: {
469: Log_Printf(LOG_ERROR, "ZIP_ExtractFile: could not get file info\n");
470: return NULL;
471: }
472:
473: size_buf = size;
474: buf = malloc(size_buf);
475: if (!buf)
476: {
477: perror("ZIP_ExtractFile");
478: return NULL;
479: }
480:
481: err = unzOpenCurrentFile(uf);
482: if (err != UNZ_OK)
483: {
484: Log_Printf(LOG_ERROR, "ZIP_ExtractFile: could not open file\n");
1.1.1.10 root 485: free(buf);
1.1.1.5 root 486: return NULL;
487: }
488:
489: do
490: {
491: err = unzReadCurrentFile(uf,buf,size_buf);
492: if (err < 0)
493: {
494: Log_Printf(LOG_ERROR, "ZIP_ExtractFile: could not read file\n");
495: return NULL;
496: }
497: }
498: while (err > 0);
499:
500: return buf;
1.1 root 501: }
502:
1.1.1.5 root 503:
1.1 root 504: /*-----------------------------------------------------------------------*/
1.1.1.6 root 505: /**
506: * Load disk image from a .ZIP archive into memory, set the number
507: * of bytes loaded into pImageSize and return the data or NULL on error.
508: */
1.1.1.12! root 509: Uint8 *ZIP_ReadDisk(int Drive, const char *pszFileName, const char *pszZipPath, long *pImageSize, int *pImageType)
1.1 root 510: {
1.1.1.5 root 511: uLong ImageSize=0;
512: unzFile uf=NULL;
513: Uint8 *buf;
1.1.1.6 root 514: char *path;
1.1.1.5 root 515: Uint8 *pDiskBuffer = NULL;
516:
517: *pImageSize = 0;
1.1.1.12! root 518: *pImageType = FLOPPY_IMAGE_TYPE_NONE;
1.1.1.5 root 519:
520: uf = unzOpen(pszFileName);
521: if (uf == NULL)
522: {
523: Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
524: return NULL;
525: }
1.1 root 526:
1.1.1.5 root 527: if (pszZipPath == NULL || pszZipPath[0] == 0)
528: {
1.1.1.6 root 529: path = ZIP_FirstFile(pszFileName, pszDiskNameExts);
530: if (path == NULL)
1.1.1.5 root 531: {
532: Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
533: unzClose(uf);
534: return NULL;
535: }
1.1.1.6 root 536: }
537: else
538: {
539: path = malloc(ZIP_PATH_MAX);
540: if (path == NULL)
541: {
542: perror("ZIP_ReadDisk");
543: unzClose(uf);
544: return NULL;
545: }
546: strncpy(path, pszZipPath, ZIP_PATH_MAX);
547: path[ZIP_PATH_MAX-1] = '\0';
1.1.1.5 root 548: }
1.1.1.2 root 549:
1.1.1.12! root 550: ImageSize = ZIP_CheckImageFile(uf, path, ZIP_PATH_MAX, pImageType);
1.1.1.5 root 551: if (ImageSize <= 0)
552: {
553: unzClose(uf);
1.1.1.6 root 554: free(path);
1.1.1.5 root 555: return NULL;
556: }
557:
558: /* extract to buf */
1.1.1.6 root 559: buf = ZIP_ExtractFile(uf, path, ImageSize);
560:
1.1.1.5 root 561: unzCloseCurrentFile(uf);
562: unzClose(uf);
1.1.1.6 root 563: free(path);
564: path = NULL;
565:
1.1.1.5 root 566: if (buf == NULL)
567: {
568: return NULL; /* failed extraction, return error */
569: }
570:
1.1.1.12! root 571: switch(*pImageType) {
! 572: case FLOPPY_IMAGE_TYPE_IPF:
! 573: #ifndef HAVE_CAPSIMAGE
! 574: Log_AlertDlg(LOG_ERROR, "This version of Hatari was not built with IPF support, this disk image can't be handled.");
! 575: return NULL;
! 576: #else
! 577: /* return buffer */
! 578: pDiskBuffer = buf;
! 579: break;
! 580: #endif
! 581: case FLOPPY_IMAGE_TYPE_STX:
! 582: /* return buffer */
! 583: pDiskBuffer = buf;
! 584: break;
! 585: case FLOPPY_IMAGE_TYPE_MSA:
1.1.1.5 root 586: /* uncompress the MSA file */
1.1.1.6 root 587: pDiskBuffer = MSA_UnCompress(buf, (long *)&ImageSize);
588: free(buf);
589: buf = NULL;
590: break;
1.1.1.12! root 591: case FLOPPY_IMAGE_TYPE_DIM:
1.1.1.5 root 592: /* Skip DIM header */
593: ImageSize -= 32;
1.1.1.6 root 594: memmove(buf, buf+32, ImageSize);
1.1.1.12! root 595: /* return buffer */
! 596: pDiskBuffer = buf;
! 597: break;
! 598: case FLOPPY_IMAGE_TYPE_ST:
1.1.1.6 root 599: /* ST image => return buffer directly */
600: pDiskBuffer = buf;
601: break;
1.1.1.5 root 602: }
1.1.1.6 root 603:
604: if (pDiskBuffer)
605: {
1.1.1.5 root 606: *pImageSize = ImageSize;
1.1.1.6 root 607: }
1.1.1.5 root 608: return pDiskBuffer;
1.1 root 609: }
610:
611:
612: /*-----------------------------------------------------------------------*/
1.1.1.6 root 613: /**
614: * Load first file from a .ZIP archive into memory, and return the number
615: * of bytes loaded.
616: */
617: Uint8 *ZIP_ReadFirstFile(const char *pszFileName, long *pImageSize, const char * const ppszExts[])
1.1.1.5 root 618: {
619: unzFile uf=NULL;
620: Uint8 *pBuffer;
621: char *pszZipPath;
622: unz_file_info file_info;
623:
624: *pImageSize = 0;
625:
626: /* Open the ZIP file */
627: uf = unzOpen(pszFileName);
628: if (uf == NULL)
629: {
630: Log_Printf(LOG_ERROR, "Cannot open '%s'\n", pszFileName);
631: return NULL;
632: }
633:
634: /* Locate the first file in the ZIP archive */
635: pszZipPath = ZIP_FirstFile(pszFileName, ppszExts);
636: if (pszZipPath == NULL)
637: {
638: Log_Printf(LOG_ERROR, "Failed to locate first file in '%s'\n", pszFileName);
639: unzClose(uf);
640: return NULL;
641: }
642:
643: if (unzLocateFile(uf, pszZipPath, 0) != UNZ_OK)
644: {
1.1.1.6 root 645: Log_Printf(LOG_ERROR, "Error: Can not locate '%s' in the archive!\n", pszZipPath);
646: free(pszZipPath);
1.1.1.5 root 647: return NULL;
648: }
649:
650: /* Get file information (file size!) */
651: if (unzGetCurrentFileInfo(uf, &file_info, pszZipPath, ZIP_PATH_MAX, NULL, 0, NULL, 0) != UNZ_OK)
652: {
653: Log_Printf(LOG_ERROR, "Error with zipfile in unzGetCurrentFileInfo.\n");
1.1.1.6 root 654: free(pszZipPath);
1.1.1.5 root 655: return NULL;
656: }
657:
658: /* Extract to buffer */
659: pBuffer = ZIP_ExtractFile(uf, pszZipPath, file_info.uncompressed_size);
660:
661: /* And close the file */
662: unzCloseCurrentFile(uf);
663: unzClose(uf);
664:
665: free(pszZipPath);
666:
667: if (pBuffer)
668: *pImageSize = file_info.uncompressed_size;
669:
670: return pBuffer;
671: }
1.1.1.12! root 672:
! 673: #else
! 674:
! 675: bool ZIP_FileNameIsZIP(const char *pszFileName)
! 676: {
! 677: return false;
! 678: }
! 679: Uint8 *ZIP_ReadDisk(int Drive, const char *name, const char *path, long *size)
! 680: {
! 681: return NULL;
! 682: }
! 683: struct dirent **ZIP_GetFilesDir(const zip_dir *zip, const char *dir, int *entries)
! 684: {
! 685: return NULL;
! 686: }
! 687: zip_dir *ZIP_GetFiles(const char *pszFileName)
! 688: {
! 689: return NULL;
! 690: }
! 691: void ZIP_FreeZipDir(zip_dir *f_zd)
! 692: {
! 693: }
! 694:
! 695: #endif /* HAVE_LIBZ */
! 696:
! 697: /**
! 698: * Save .ZIP file from memory buffer. Returns true if all is OK.
! 699: *
! 700: * Not yet implemented.
! 701: */
! 702: bool ZIP_WriteDisk(int Drive, const char *pszFileName,unsigned char *pBuffer,int ImageSize)
! 703: {
! 704: return false;
! 705: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.