Skip to content

Latest commit

 

History

History
585 lines (470 loc) · 15.3 KB

zip.c

File metadata and controls

585 lines (470 loc) · 15.3 KB
 
Jul 7, 2001
Jul 7, 2001
1
2
3
4
5
6
7
8
/*
* ZIP support routines for PhysicsFS.
*
* Please see the file LICENSE in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
Jul 23, 2001
Jul 23, 2001
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
* !!! FIXME: overall design bugs.
*
* It'd be nice if we could remove the thread issues: I/O to individual
* files inside an archive are safe, but the searches over the central
* directory and the ZIP_openRead() call are race conditions. Basically,
* we need to hack something like openDir() into unzip.c, so that directory
* reads are separated by handles, and maybe add a openFileByName() call,
* or make unzOpenCurrentFile() take a handle, too.
*
* Make unz_file_info.version into two fields of unsigned char. That's what
* they are in the zipfile; heavens knows why unzip.c casts it...this causes
* a byte ordering headache for me in entry_is_symlink().
*
* Maybe add a seekToStartOfCurrentFile() in unzip.c if complete seek
* semantics are impossible.
*/
Jul 23, 2001
Jul 23, 2001
26
Jul 7, 2001
Jul 7, 2001
27
28
#include <stdio.h>
#include <stdlib.h>
Jul 15, 2001
Jul 15, 2001
29
30
#include <string.h>
#include <unistd.h>
Jul 23, 2001
Jul 23, 2001
31
#include <errno.h>
Jul 8, 2001
Jul 8, 2001
32
#include "physfs.h"
Jul 15, 2001
Jul 15, 2001
33
34
#include "unzip.h"
Jul 7, 2001
Jul 7, 2001
35
36
37
38
39
40
41
42
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
#if (!defined PHYSFS_SUPPORTS_ZIP)
#error PHYSFS_SUPPORTS_ZIP must be defined.
#endif
Jul 23, 2001
Jul 23, 2001
43
#define MAXZIPENTRYSIZE 256
Jul 15, 2001
Jul 15, 2001
44
45
46
47
48
typedef struct
{
unzFile handle;
uLong totalEntries;
Jul 23, 2001
Jul 23, 2001
49
char *archiveName;
Jul 15, 2001
Jul 15, 2001
50
51
52
53
} ZIPinfo;
typedef struct
{
Jul 23, 2001
Jul 23, 2001
54
unzFile handle;
Jul 15, 2001
Jul 15, 2001
55
56
57
} ZIPfileinfo;
Jul 8, 2001
Jul 8, 2001
58
extern const DirFunctions __PHYSFS_DirFunctions_ZIP;
Jul 8, 2001
Jul 8, 2001
59
static const FileFunctions __PHYSFS_FileFunctions_ZIP;
Jul 8, 2001
Jul 8, 2001
60
61
62
63
64
static int ZIP_read(FileHandle *handle, void *buffer,
unsigned int objSize, unsigned int objCount)
{
Jul 23, 2001
Jul 23, 2001
65
66
67
68
69
70
71
72
73
74
75
76
unzFile fh = ((ZIPfileinfo *) (handle->opaque))->handle;
int bytes = objSize * objCount;
int rc = unzReadCurrentFile(fh, buffer, bytes);
if (rc < bytes)
__PHYSFS_setError(ERR_PAST_EOF);
else if (rc == UNZ_ERRNO)
__PHYSFS_setError(ERR_IO_ERROR);
else if (rc < 0)
__PHYSFS_setError(ERR_COMPRESSION);
return(rc / objSize);
Jul 8, 2001
Jul 8, 2001
77
78
79
80
81
} /* ZIP_read */
static int ZIP_eof(FileHandle *handle)
{
Jul 23, 2001
Jul 23, 2001
82
return(unzeof(((ZIPfileinfo *) (handle->opaque))->handle));
Jul 8, 2001
Jul 8, 2001
83
84
85
86
87
} /* ZIP_eof */
static int ZIP_tell(FileHandle *handle)
{
Jul 23, 2001
Jul 23, 2001
88
return(unztell(((ZIPfileinfo *) (handle->opaque))->handle));
Jul 8, 2001
Jul 8, 2001
89
90
91
} /* ZIP_tell */
Jul 23, 2001
Jul 23, 2001
92
93
94
static int ZIP_fileLength(FileHandle *handle);
Jul 8, 2001
Jul 8, 2001
95
96
static int ZIP_seek(FileHandle *handle, int offset)
{
Jul 23, 2001
Jul 23, 2001
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* this blows. */
unzFile fh = ((ZIPfileinfo *) (handle->opaque))->handle;
char *buf;
int bufsize = 4096 * 2;
BAIL_IF_MACRO(unztell(fh) == offset, NULL, 1);
BAIL_IF_MACRO(ZIP_fileLength(handle) <= offset, ERR_PAST_EOF, 0);
/* reset to the start of the zipfile. */
unzCloseCurrentFile(fh);
BAIL_IF_MACRO(unzOpenCurrentFile(fh) != UNZ_OK, ERR_IO_ERROR, 0);
while ((buf == NULL) && (bufsize >= 512))
{
bufsize >>= 1; /* divides by two. */
buf = (char *) malloc(bufsize);
} /* while */
BAIL_IF_MACRO(buf == NULL, ERR_OUT_OF_MEMORY, 0);
while (offset > 0)
{
int chunk = (offset > bufsize) ? bufsize : offset;
int rc = unzReadCurrentFile(fh, buf, chunk);
BAIL_IF_MACRO(rc == 0, ERR_IO_ERROR, 0); /* shouldn't happen. */
BAIL_IF_MACRO(rc == UNZ_ERRNO, ERR_IO_ERROR, 0);
BAIL_IF_MACRO(rc < 0, ERR_COMPRESSION, 0);
offset -= rc;
} /* while */
free(buf);
return(offset == 0);
Jul 8, 2001
Jul 8, 2001
128
129
130
} /* ZIP_seek */
Jul 9, 2001
Jul 9, 2001
131
132
static int ZIP_fileLength(FileHandle *handle)
{
Jul 23, 2001
Jul 23, 2001
133
134
135
136
137
ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
unz_file_info info;
unzGetCurrentFileInfo(finfo->handle, &info, NULL, 0, NULL, 0, NULL, 0);
return(info.uncompressed_size);
Jul 9, 2001
Jul 9, 2001
138
139
140
} /* ZIP_fileLength */
Jul 8, 2001
Jul 8, 2001
141
142
static int ZIP_fileClose(FileHandle *handle)
{
Jul 23, 2001
Jul 23, 2001
143
144
145
146
147
ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
unzClose(finfo->handle);
free(finfo);
free(handle);
return(1);
Jul 8, 2001
Jul 8, 2001
148
149
150
151
152
} /* ZIP_fileClose */
static int ZIP_isArchive(const char *filename, int forWriting)
{
Jul 15, 2001
Jul 15, 2001
153
int retval = 0;
Jul 23, 2001
Jul 23, 2001
154
unzFile unz = unzOpen(filename);
Jul 15, 2001
Jul 15, 2001
155
156
157
158
159
160
161
162
163
164
unz_global_info global;
if (unz != NULL)
{
if (unzGetGlobalInfo(unz, &global) == UNZ_OK)
retval = 1;
unzClose(unz);
} /* if */
return(retval);
Jul 8, 2001
Jul 8, 2001
165
166
167
168
169
} /* ZIP_isArchive */
static DirHandle *ZIP_openArchive(const char *name, int forWriting)
{
Jul 15, 2001
Jul 15, 2001
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
unzFile unz = NULL;
DirHandle *retval = NULL;
unz_global_info global;
BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
errno = 0;
BAIL_IF_MACRO(access(name, R_OK) != 0, strerror(errno), NULL);
retval = malloc(sizeof (DirHandle));
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
unz = unzOpen(name);
if ((unz == NULL) || (unzGetGlobalInfo(unz, &global) != UNZ_OK))
{
if (unz)
unzClose(unz);
Jul 16, 2001
Jul 16, 2001
187
free(retval);
Jul 15, 2001
Jul 15, 2001
188
189
190
191
192
193
194
195
196
197
198
BAIL_IF_MACRO(1, ERR_UNSUPPORTED_ARCHIVE, NULL);
} /* if */
retval->opaque = malloc(sizeof (ZIPinfo));
if (retval->opaque == NULL)
{
free(retval);
unzClose(unz);
BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
} /* if */
Jul 23, 2001
Jul 23, 2001
199
200
201
202
203
204
205
206
207
((ZIPinfo *) (retval->opaque))->archiveName = malloc(strlen(name) + 1);
if (((ZIPinfo *) (retval->opaque))->archiveName == NULL)
{
free(retval->opaque);
free(retval);
unzClose(unz);
BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
} /* if */
Jul 15, 2001
Jul 15, 2001
208
((ZIPinfo *) (retval->opaque))->handle = unz;
Jul 16, 2001
Jul 16, 2001
209
((ZIPinfo *) (retval->opaque))->totalEntries = global.number_entry;
Jul 23, 2001
Jul 23, 2001
210
strcpy(((ZIPinfo *) (retval->opaque))->archiveName, name);
Jul 23, 2001
Jul 23, 2001
211
retval->funcs = &__PHYSFS_DirFunctions_ZIP;
Jul 15, 2001
Jul 15, 2001
212
213
return(retval);
Jul 8, 2001
Jul 8, 2001
214
215
216
} /* ZIP_openArchive */
Jul 23, 2001
Jul 23, 2001
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/* "uLong" is defined by zlib and/or unzip.h ... */
typedef union
{
unsigned char uchar4[4];
uLong ul;
} uchar4_uLong;
static int version_does_symlinks(uLong version)
{
int retval = 0;
unsigned char hosttype;
uchar4_uLong converter;
converter.ul = version;
hosttype = converter.uchar4[1]; /* !!! BYTE ORDERING ALERT! */
/*
* These are the platforms that can build an archive with symlinks,
* according to the Info-ZIP project.
*/
switch (hosttype)
{
case 3: /* Unix */
case 16: /* BeOS */
case 5: /* Atari */
retval = 1;
break;
} /* switch */
return(retval);
} /* version_does_symlinks */
static int entry_is_symlink(unz_file_info *info)
{
return (
(version_does_symlinks(info->version)) &&
(info->uncompressed_size > 0) &&
(info->external_fa & 0x0120000) /* symlink flag. */
);
} /* entry_is_symlink */
static char *ZIP_realpath(unzFile fh, unz_file_info *info)
{
char *retval = NULL;
int size;
if (entry_is_symlink(info))
{
BAIL_IF_MACRO(unzOpenCurrentFile(fh) != UNZ_OK, ERR_IO_ERROR, NULL);
size = info->uncompressed_size;
retval = (char *) malloc(size + 1);
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
if (unzReadCurrentFile(fh, retval, size) != size)
{
free(retval);
__PHYSFS_setError(ERR_IO_ERROR);
retval = NULL;
} /* if */
retval[size] = '\0';
unzCloseCurrentFile(fh);
} /* if */
return(retval);
} /* ZIP_realpath */
/* !!! This is seriously ugly. */
Jul 16, 2001
Jul 16, 2001
288
289
290
static LinkedStringList *ZIP_enumerateFiles(DirHandle *h,
const char *dirname,
int omitSymLinks)
Jul 8, 2001
Jul 8, 2001
291
{
Jul 15, 2001
Jul 15, 2001
292
293
294
ZIPinfo *zi = (ZIPinfo *) (h->opaque);
unzFile fh = zi->handle;
int i;
Jul 23, 2001
Jul 23, 2001
295
int dlen;
Jul 15, 2001
Jul 15, 2001
296
297
298
LinkedStringList *retval = NULL;
LinkedStringList *l = NULL;
LinkedStringList *prev = NULL;
Jul 23, 2001
Jul 23, 2001
299
char buf[MAXZIPENTRYSIZE];
Jul 15, 2001
Jul 15, 2001
300
char *d;
Jul 23, 2001
Jul 23, 2001
301
unz_file_info info;
Jul 15, 2001
Jul 15, 2001
302
303
304
/* jump to first file entry... */
BAIL_IF_MACRO(unzGoToFirstFile(fh) != UNZ_OK, ERR_IO_ERROR, NULL);
Jul 23, 2001
Jul 23, 2001
305
306
307
dlen = strlen(dirname);
d = malloc(dlen + 1);
BAIL_IF_MACRO(d == NULL, ERR_OUT_OF_MEMORY, NULL);
Jul 15, 2001
Jul 15, 2001
308
strcpy(d, dirname);
Jul 23, 2001
Jul 23, 2001
309
310
311
312
313
if ((dlen > 0) && (d[dlen - 1] == '/')) /* no trailing slash. */
{
dlen--;
d[dlen] = '\0';
} /* if */
Jul 15, 2001
Jul 15, 2001
314
Jul 23, 2001
Jul 23, 2001
315
for (i = 0; i < zi->totalEntries; i++, unzGoToNextFile(fh))
Jul 15, 2001
Jul 15, 2001
316
317
{
char *ptr;
Jul 23, 2001
Jul 23, 2001
318
319
320
321
322
323
324
325
326
327
328
char *add_file;
int this_dlen;
unzGetCurrentFileInfo(fh, &info, buf, sizeof (buf), NULL, 0, NULL, 0);
if ((omitSymLinks) && (entry_is_symlink(&info)))
continue;
buf[sizeof (buf) - 1] = '\0'; /* safety. */
this_dlen = strlen(buf);
if ((this_dlen > 0) && (buf[this_dlen - 1] == '/')) /* no trailing slash. */
Jul 15, 2001
Jul 15, 2001
329
{
Jul 23, 2001
Jul 23, 2001
330
331
332
333
334
335
336
337
338
this_dlen--;
buf[this_dlen] = '\0';
} /* if */
if (this_dlen <= dlen) /* not in this dir. */
continue;
if (*d == '\0')
add_file = buf;
Jul 15, 2001
Jul 15, 2001
339
340
else
{
Jul 23, 2001
Jul 23, 2001
341
342
343
344
345
346
347
348
if (buf[dlen] != '/') /* can't be in same directory? */
continue;
buf[dlen] = '\0';
if (strcmp(d, buf) != 0) /* not same directory? */
continue;
add_file = buf + dlen + 1;
Jul 15, 2001
Jul 15, 2001
349
350
} /* else */
Jul 23, 2001
Jul 23, 2001
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
/* handle subdirectories... */
ptr = strchr(add_file, '/');
if (ptr != NULL)
{
LinkedStringList *j;
*ptr = '\0';
for (j = retval; j != NULL; j = j->next)
{
if (strcmp(j->str, ptr) == 0)
break;
} /* for */
if (j != NULL)
continue;
} /* if */
Jul 15, 2001
Jul 15, 2001
367
l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
Jul 16, 2001
Jul 16, 2001
368
if (l == NULL)
Jul 15, 2001
Jul 15, 2001
369
370
break;
Jul 23, 2001
Jul 23, 2001
371
l->str = (char *) malloc(strlen(add_file) + 1);
Jul 15, 2001
Jul 15, 2001
372
373
374
375
376
377
if (l->str == NULL)
{
free(l);
break;
} /* if */
Jul 23, 2001
Jul 23, 2001
378
strcpy(l->str, add_file);
Jul 16, 2001
Jul 16, 2001
379
Jul 15, 2001
Jul 15, 2001
380
381
382
383
384
385
386
387
388
389
390
if (retval == NULL)
retval = l;
else
prev->next = l;
prev = l;
l->next = NULL;
} /* for */
free(d);
return(retval);
Jul 8, 2001
Jul 8, 2001
391
392
393
} /* ZIP_enumerateFiles */
Jul 23, 2001
Jul 23, 2001
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
/* !!! This is seriously ugly. */
static int ZIP_exists_symcheck(DirHandle *h, const char *name, int follow)
{
char buf[MAXZIPENTRYSIZE];
ZIPinfo *zi = (ZIPinfo *) (h->opaque);
unzFile fh = zi->handle;
int dlen;
char *d;
int i;
unz_file_info info;
BAIL_IF_MACRO(unzGoToFirstFile(fh) != UNZ_OK, ERR_IO_ERROR, 0);
dlen = strlen(name);
d = malloc(dlen + 1);
BAIL_IF_MACRO(d == NULL, ERR_OUT_OF_MEMORY, 0);
strcpy(d, name);
if ((dlen > 0) && (d[dlen - 1] == '/')) /* no trailing slash. */
{
dlen--;
d[dlen] = '\0';
} /* if */
for (i = 0; i < zi->totalEntries; i++, unzGoToNextFile(fh))
{
int this_dlen;
unzGetCurrentFileInfo(fh, &info, buf, sizeof (buf), NULL, 0, NULL, 0);
buf[sizeof (buf) - 1] = '\0'; /* safety. */
this_dlen = strlen(buf);
if ((this_dlen > 0) && (buf[this_dlen - 1] == '/')) /* no trailing slash. */
{
this_dlen--;
buf[this_dlen] = '\0';
} /* if */
if ( ((buf[dlen] == '/') || (buf[dlen] == '\0')) &&
(strncmp(d, buf, dlen) == 0) )
{
int retval = 1;
free(d);
if (follow) /* follow symlinks? */
{
char *real = ZIP_realpath(fh, &info);
if (real != NULL)
{
retval = ZIP_exists_symcheck(h, real, follow - 1);
free(real);
} /* if */
} /* if */
return(retval);
} /* if */
} /* for */
free(d);
return(0);
} /* ZIP_exists_symcheck */
static int ZIP_exists_nofollow(DirHandle *h, const char *name)
{
return(ZIP_exists_symcheck(h, name, 0));
} /* ZIP_exists_nofollow */
Jul 8, 2001
Jul 8, 2001
457
static int ZIP_exists(DirHandle *h, const char *name)
Jul 8, 2001
Jul 8, 2001
458
{
Jul 23, 2001
Jul 23, 2001
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
/* follow at most 20 links to prevent recursion... */
int retval = ZIP_exists_symcheck(h, name, 20);
unz_file_info info;
unzFile fh = ((ZIPinfo *) (h->opaque))->handle;
if (retval)
{
/* current zip entry will be the file in question. */
unzGetCurrentFileInfo(fh, &info, NULL, 0, NULL, 0, NULL, 0);
/* if it's a symlink, then we ran into a possible symlink loop. */
BAIL_IF_MACRO(entry_is_symlink(&info), ERR_TOO_MANY_SYMLINKS, 0);
} /* if */
return(retval);
Jul 8, 2001
Jul 8, 2001
474
475
476
} /* ZIP_exists */
Jul 8, 2001
Jul 8, 2001
477
static int ZIP_isDirectory(DirHandle *h, const char *name)
Jul 8, 2001
Jul 8, 2001
478
{
Jul 23, 2001
Jul 23, 2001
479
480
481
482
483
484
485
486
487
488
489
490
491
char buf[MAXZIPENTRYSIZE];
unzFile fh = ((ZIPinfo *) (h->opaque))->handle;
int retval = ZIP_exists(h, name);
int dlen = strlen(name);
if (retval)
{
/* current zip entry will be the file in question. */
unzGetCurrentFileInfo(fh, NULL, buf, sizeof (buf), NULL, 0, NULL, 0);
retval = (buf[dlen] == '/'); /* !!! yikes. */
} /* if */
return(retval);
Jul 8, 2001
Jul 8, 2001
492
493
494
} /* ZIP_isDirectory */
Jul 8, 2001
Jul 8, 2001
495
static int ZIP_isSymLink(DirHandle *h, const char *name)
Jul 8, 2001
Jul 8, 2001
496
{
Jul 23, 2001
Jul 23, 2001
497
498
499
500
501
502
503
504
505
506
507
508
unzFile fh = ((ZIPinfo *) (h->opaque))->handle;
int retval = ZIP_exists_nofollow(h, name);
unz_file_info info;
if (retval)
{
/* current zip entry will be the file in question. */
unzGetCurrentFileInfo(fh, &info, NULL, 0, NULL, 0, NULL, 0);
retval = entry_is_symlink(&info);
} /* if */
return(retval);
Jul 8, 2001
Jul 8, 2001
509
510
511
} /* ZIP_isSymLink */
Jul 8, 2001
Jul 8, 2001
512
static FileHandle *ZIP_openRead(DirHandle *h, const char *filename)
Jul 8, 2001
Jul 8, 2001
513
{
Jul 23, 2001
Jul 23, 2001
514
FileHandle *retval = NULL;
Jul 23, 2001
Jul 23, 2001
515
516
517
ZIPfileinfo *finfo = NULL;
char *name = ((ZIPinfo *) (h->opaque))->archiveName;
unzFile f;
Jul 23, 2001
Jul 23, 2001
518
519
520
BAIL_IF_MACRO(!ZIP_exists(h, filename), ERR_NO_SUCH_FILE, NULL);
Jul 23, 2001
Jul 23, 2001
521
522
523
524
525
526
527
528
529
530
531
532
f = unzOpen(name);
BAIL_IF_MACRO(f == NULL, ERR_IO_ERROR, NULL);
if ( (unzLocateFile(f, filename, 1) != UNZ_OK) ||
( (finfo = (ZIPfileinfo *) malloc(sizeof (ZIPfileinfo))) == NULL ) ||
(unzOpenCurrentFile(f) != UNZ_OK) )
{
unzClose(f);
BAIL_IF_MACRO(1, ERR_IO_ERROR, NULL);
} /* if */
finfo->handle = f;
Jul 23, 2001
Jul 23, 2001
533
retval->opaque = (void *) finfo;
Jul 23, 2001
Jul 23, 2001
534
retval->funcs = &__PHYSFS_FileFunctions_ZIP;
Jul 23, 2001
Jul 23, 2001
535
536
retval->dirHandle = h;
return(retval);
Jul 8, 2001
Jul 8, 2001
537
538
539
} /* ZIP_openRead */
Jul 8, 2001
Jul 8, 2001
540
static void ZIP_dirClose(DirHandle *h)
Jul 8, 2001
Jul 8, 2001
541
{
Jul 23, 2001
Jul 23, 2001
542
543
544
unzClose(((ZIPinfo *) (h->opaque))->handle);
free(h->opaque);
free(h);
Jul 8, 2001
Jul 8, 2001
545
546
} /* ZIP_dirClose */
Jul 7, 2001
Jul 7, 2001
547
Jul 8, 2001
Jul 8, 2001
548
static const FileFunctions __PHYSFS_FileFunctions_ZIP =
Jul 7, 2001
Jul 7, 2001
549
{
Jul 9, 2001
Jul 9, 2001
550
551
552
553
554
555
556
ZIP_read, /* read() method */
NULL, /* write() method */
ZIP_eof, /* eof() method */
ZIP_tell, /* tell() method */
ZIP_seek, /* seek() method */
ZIP_fileLength, /* fileLength() method */
ZIP_fileClose /* fileClose() method */
Jul 7, 2001
Jul 7, 2001
557
558
559
560
561
};
const DirFunctions __PHYSFS_DirFunctions_ZIP =
{
Jul 8, 2001
Jul 8, 2001
562
563
564
565
566
567
568
569
570
571
572
ZIP_isArchive, /* isArchive() method */
ZIP_openArchive, /* openArchive() method */
ZIP_enumerateFiles, /* enumerateFiles() method */
ZIP_exists, /* exists() method */
ZIP_isDirectory, /* isDirectory() method */
ZIP_isSymLink, /* isSymLink() method */
ZIP_openRead, /* openRead() method */
NULL, /* openWrite() method */
NULL, /* openAppend() method */
NULL, /* remove() method */
NULL, /* mkdir() method */
Jul 8, 2001
Jul 8, 2001
573
ZIP_dirClose /* dirClose() method */
Jul 7, 2001
Jul 7, 2001
574
575
};
Jul 8, 2001
Jul 8, 2001
576
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
Jul 7, 2001
Jul 7, 2001
577
578
{
"ZIP",
Jul 9, 2001
Jul 9, 2001
579
"PkZip/WinZip/Info-Zip compatible",
Jul 16, 2001
Jul 16, 2001
580
581
"Ryan C. Gordon (icculus@linuxgames.com)",
"http://www.icculus.org/~icculus/",
Jul 7, 2001
Jul 7, 2001
582
583
584
};
/* end of zip.c ... */