archivers/zip.c
author Ryan C. Gordon <icculus@icculus.org>
Mon, 15 Jul 2002 13:20:34 +0000
changeset 342 cef50576cb0b
parent 340 24a11f8566f8
child 345 cbcb27547864
permissions -rw-r--r--
Fixed symlink detection.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
/*
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
 * ZIP support routines for PhysicsFS.
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
 *
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
 * Please see the file LICENSE in the source's root directory.
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
 *
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
     6
 *  This file written by Ryan C. Gordon, with some peeking at "unzip.c"
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
     7
 *   by Gilles Vollant.
17
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     8
 */
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     9
214
19846c18071b Initial autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 194
diff changeset
    10
#if HAVE_CONFIG_H
19846c18071b Initial autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 194
diff changeset
    11
#  include <config.h>
19846c18071b Initial autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 194
diff changeset
    12
#endif
19846c18071b Initial autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 194
diff changeset
    13
19846c18071b Initial autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 194
diff changeset
    14
#if (defined PHYSFS_SUPPORTS_ZIP)
19846c18071b Initial autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 194
diff changeset
    15
17
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    16
#include <stdio.h>
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    17
#include <stdlib.h>
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    18
#include <string.h>
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
    19
#include <assert.h>
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
    20
#include <time.h>
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    21
#include <errno.h>
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    22
22
49f6101707b4 More tweaks; GRP completely implemented. Everything builds clean.
Ryan C. Gordon <icculus@icculus.org>
parents: 21
diff changeset
    23
#include "physfs.h"
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    24
#include "zlib.h"
17
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    25
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    26
#define __PHYSICSFS_INTERNAL__
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    27
#include "physfs_internal.h"
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    28
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    29
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    30
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    31
 * A buffer of ZIP_READBUFSIZE is malloc() for each compressed file opened,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    32
 *  and is free()'d when you close the file; compressed data is read into
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    33
 *  this buffer, and then is decompressed into the buffer passed to
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    34
 *  PHYSFS_read().
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    35
 *
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    36
 * Uncompressed entries in a zipfile do not allocate this buffer; they just
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    37
 *  read data directly into the buffer passed to PHYSFS_read().
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    38
 *
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    39
 * Depending on your speed and memory requirements, you should tweak this
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    40
 *  value.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    41
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    42
#define ZIP_READBUFSIZE   (16 * 1024)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    43
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    44
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    45
 * One ZIPentry is kept for each file in an open ZIP archive.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    46
 */
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    47
typedef struct
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    48
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    49
    char *name;                         /* Name of file in archive   */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    50
    char *symlink;                      /* NULL or file we link to   */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    51
    int fixed_up;                       /* Have we updated offset?   */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    52
    PHYSFS_uint32 offset;               /* offset of data in file    */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    53
    PHYSFS_uint16 version;              /* version made by           */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    54
    PHYSFS_uint16 version_needed;       /* version needed to extract */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    55
    PHYSFS_uint16 flag;                 /* general purpose bit flag  */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    56
    PHYSFS_uint16 compression_method;   /* compression method        */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    57
    PHYSFS_uint32 crc;                  /* crc-32                    */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    58
    PHYSFS_uint32 compressed_size;      /* compressed size           */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    59
    PHYSFS_uint32 uncompressed_size;    /* uncompressed size         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    60
    PHYSFS_sint64 last_mod_time;        /* last file mod time        */
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
    61
} ZIPentry;
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
    62
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    63
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    64
 * One ZIPinfo is kept for each open ZIP archive.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    65
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    66
typedef struct
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    67
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    68
    char *archiveName;        /* path to ZIP in platform-dependent notation. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    69
    PHYSFS_uint16 entryCount; /* Number of files in ZIP.                     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    70
    ZIPentry *entries;        /* info on all files in ZIP.                   */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    71
} ZIPinfo;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    72
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    73
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    74
 * One ZIPfileinfo is kept for each open file in a ZIP archive.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    75
 */
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
    76
typedef struct
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
    77
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    78
    ZIPentry *entry;                      /* Info on file.              */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    79
    void *handle;                         /* physical file handle.      */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    80
    PHYSFS_uint32 compressed_position;    /* offset in compressed data. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    81
    PHYSFS_uint32 uncompressed_position;  /* tell() position.           */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    82
    PHYSFS_uint8 *buffer;                 /* decompression buffer.      */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    83
    z_stream stream;                      /* zlib stream state.         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    84
} ZIPfileinfo;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    85
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    86
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    87
/* Magic numbers... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    88
#define ZIP_LOCAL_FILE_SIG          0x04034b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    89
#define ZIP_CENTRAL_DIR_SIG         0x02014b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    90
#define ZIP_END_OF_CENTRAL_DIR_SIG  0x06054b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    91
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    92
/* compression methods... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    93
#define COMPMETH_NONE 0
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    94
/* ...and others... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    95
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    96
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
    97
#define UNIX_FILETYPE_MASK    0170000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
    98
#define UNIX_FILETYPE_SYMLINK 0120000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
    99
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   100
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   101
#define MAXZIPENTRYSIZE 256  /* !!! FIXME: get rid of this. */
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   102
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   103
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   104
/* Number of symlinks to follow before we assume it's a recursive link... */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   105
#define SYMLINK_RECURSE_COUNT 20
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   106
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   107
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   108
static PHYSFS_sint64 ZIP_read(FileHandle *handle, void *buffer,
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   109
                              PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   110
static int ZIP_eof(FileHandle *handle);
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   111
static PHYSFS_sint64 ZIP_tell(FileHandle *handle);
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   112
static int ZIP_seek(FileHandle *handle, PHYSFS_uint64 offset);
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   113
static PHYSFS_sint64 ZIP_fileLength(FileHandle *handle);
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   114
static int ZIP_fileClose(FileHandle *handle);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   115
static int ZIP_isArchive(const char *filename, int forWriting);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   116
static char *get_zip_realpath(void *in, ZIPentry *entry);
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   117
static DirHandle *ZIP_openArchive(const char *name, int forWriting);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   118
static LinkedStringList *ZIP_enumerateFiles(DirHandle *h,
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   119
                                            const char *dirname,
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   120
                                            int omitSymLinks);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   121
static int ZIP_exists(DirHandle *h, const char *name);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   122
static int ZIP_isDirectory(DirHandle *h, const char *name);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   123
static int ZIP_isSymLink(DirHandle *h, const char *name);
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
   124
static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *name);
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   125
static FileHandle *ZIP_openRead(DirHandle *h, const char *filename);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   126
static void ZIP_dirClose(DirHandle *h);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   127
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   128
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   129
static const FileFunctions __PHYSFS_FileFunctions_ZIP =
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   130
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   131
    ZIP_read,       /* read() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   132
    NULL,           /* write() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   133
    ZIP_eof,        /* eof() method        */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   134
    ZIP_tell,       /* tell() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   135
    ZIP_seek,       /* seek() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   136
    ZIP_fileLength, /* fileLength() method */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   137
    ZIP_fileClose   /* fileClose() method  */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   138
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   139
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   140
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   141
const DirFunctions __PHYSFS_DirFunctions_ZIP =
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   142
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   143
    ZIP_isArchive,          /* isArchive() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   144
    ZIP_openArchive,        /* openArchive() method    */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   145
    ZIP_enumerateFiles,     /* enumerateFiles() method */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   146
    ZIP_exists,             /* exists() method         */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   147
    ZIP_isDirectory,        /* isDirectory() method    */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   148
    ZIP_isSymLink,          /* isSymLink() method      */
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
   149
    ZIP_getLastModTime,     /* getLastModTime() method */
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   150
    ZIP_openRead,           /* openRead() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   151
    NULL,                   /* openWrite() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   152
    NULL,                   /* openAppend() method     */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   153
    NULL,                   /* remove() method         */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   154
    NULL,                   /* mkdir() method          */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   155
    ZIP_dirClose            /* dirClose() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   156
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   157
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   158
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   159
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   160
    "ZIP",
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   161
    "PkZip/WinZip/Info-Zip compatible",
95
215a06fc87eb Changed author credits to wrap email addresses in "<>" and not "()" chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 93
diff changeset
   162
    "Ryan C. Gordon <icculus@clutteredmind.org>",
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   163
    "http://www.icculus.org/physfs/",
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   164
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   165
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   166
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   167
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   168
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   169
 * Wrap all zlib calls in this, so the physfs error state is set appropriately.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   170
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   171
static int zlib_err(int rc)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   172
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   173
    const char *err = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   174
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   175
    switch (rc)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   176
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   177
        case Z_OK:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   178
        case Z_STREAM_END:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   179
            break;   /* not errors. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   180
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   181
        case Z_ERRNO:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   182
            err = strerror(errno);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   183
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   184
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   185
        case Z_NEED_DICT:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   186
            err = "zlib: need dictionary";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   187
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   188
        case Z_DATA_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   189
            err = "zlib: need dictionary";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   190
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   191
        case Z_MEM_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   192
            err = "zlib: memory error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   193
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   194
        case Z_BUF_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   195
            err = "zlib: buffer error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   196
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   197
        case Z_VERSION_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   198
            err = "zlib: version error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   199
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   200
        default:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   201
            err = "unknown zlib error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   202
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   203
    } /* switch */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   204
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   205
    if (err != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   206
        __PHYSFS_setError(err);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   207
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   208
    return(rc);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   209
} /* zlib_err */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   210
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   211
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   212
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   213
 * Read an unsigned 32-bit int and swap to native byte order.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   214
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   215
static int readui32(void *in, PHYSFS_uint32 *val)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   216
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   217
    PHYSFS_uint32 v;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   218
    BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   219
    *val = PHYSFS_swapULE32(v);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   220
    return(1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   221
} /* readui32 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   222
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   223
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   224
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   225
 * Read an unsigned 16-bit int and swap to native byte order.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   226
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   227
static int readui16(void *in, PHYSFS_uint16 *val)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   228
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   229
    PHYSFS_uint16 v;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   230
    BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   231
    *val = PHYSFS_swapULE16(v);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   232
    return(1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   233
} /* readui16 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   234
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   235
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   236
static PHYSFS_sint64 ZIP_read(FileHandle *handle, void *buf,
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   237
                              PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   238
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   239
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   240
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   241
    PHYSFS_sint64 retval = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   242
    PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   243
    PHYSFS_sint64 avail = entry->uncompressed_size -
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   244
                          finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   245
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   246
    BAIL_IF_MACRO(maxread == 0, NULL, 0);    /* quick rejection. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   247
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   248
    if (avail < maxread)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   249
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   250
        maxread = avail - (avail % objSize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   251
        objCount = maxread / objSize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   252
        BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0);  /* quick rejection. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   253
        __PHYSFS_setError(ERR_PAST_EOF);   /* this is always true here. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   254
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   255
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   256
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   257
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   258
        retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   259
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   260
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   261
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   262
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   263
        finfo->stream.next_out = buf;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   264
        finfo->stream.avail_out = objSize * objCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   265
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   266
        while (retval < maxread)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   267
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   268
            PHYSFS_uint32 before = finfo->stream.total_out;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   269
            int rc;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   270
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   271
            if (finfo->stream.avail_in == 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   272
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   273
                PHYSFS_sint64 br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   274
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   275
                br = entry->compressed_size - finfo->compressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   276
                if (br > 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   277
                {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   278
                    if (br > ZIP_READBUFSIZE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   279
                        br = ZIP_READBUFSIZE;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   280
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   281
                    br = __PHYSFS_platformRead(finfo->handle,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   282
                                               finfo->buffer,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   283
                                               1, br);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   284
                    if (br <= 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   285
                        break;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   286
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   287
                    finfo->compressed_position += br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   288
                    finfo->stream.next_in = finfo->buffer;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   289
                    finfo->stream.avail_in = br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   290
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   291
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   292
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   293
            rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   294
            retval += (finfo->stream.total_out - before);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   295
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   296
            if (rc != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   297
                break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   298
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   299
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   300
        retval /= objSize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   301
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   302
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   303
    if (retval > 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   304
        finfo->uncompressed_position += (retval * objSize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   305
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   306
    return(retval);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   307
} /* ZIP_read */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   308
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   309
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   310
static int ZIP_eof(FileHandle *handle)
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   311
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   312
    ZIPfileinfo *finfo = ((ZIPfileinfo *) (handle->opaque));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   313
    return(finfo->uncompressed_position >= finfo->entry->uncompressed_size);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   314
} /* ZIP_eof */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   315
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   316
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   317
static PHYSFS_sint64 ZIP_tell(FileHandle *handle)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   318
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   319
    return(((ZIPfileinfo *) (handle->opaque))->uncompressed_position);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   320
} /* ZIP_tell */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   321
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   322
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   323
static int ZIP_seek(FileHandle *handle, PHYSFS_uint64 offset)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   324
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   325
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   326
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   327
    void *in = finfo->handle;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   328
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   329
    BAIL_IF_MACRO(offset > entry->uncompressed_size, ERR_PAST_EOF, 0);
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   330
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   331
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   332
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   333
        PHYSFS_sint64 newpos = offset + entry->offset;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   334
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   335
        finfo->uncompressed_position = newpos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   336
    } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   337
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   338
    else
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   339
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   340
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   341
         * If seeking backwards, we need to redecode the file
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   342
         *  from the start and throw away the compressed bits until we hit
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   343
         *  the offset we need. If seeking forward, we still need to
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   344
         *  redecode, but we don't rewind first.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   345
         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   346
        if (offset < finfo->uncompressed_position)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   347
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   348
            /* we do a copy so state is sane if inflateInit2() fails. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   349
            z_stream str;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   350
            memset(&str, '\0', sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   351
            if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   352
                return(0);
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   353
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   354
            inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   355
            memcpy(&finfo->stream, &str, sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   356
            finfo->uncompressed_position = finfo->compressed_position = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   357
        } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   358
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   359
        while (finfo->uncompressed_position != offset)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   360
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   361
            PHYSFS_uint8 buf[512];
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   362
            PHYSFS_uint32 maxread = offset - finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   363
            if (maxread > sizeof (buf))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   364
                maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   365
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   366
            if (ZIP_read(handle, buf, maxread, 1) != 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   367
                return(0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   368
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   369
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   370
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   371
    return(1);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   372
} /* ZIP_seek */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   373
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   374
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   375
static PHYSFS_sint64 ZIP_fileLength(FileHandle *handle)
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   376
{
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   377
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   378
    return(finfo->entry->uncompressed_size);
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   379
} /* ZIP_fileLength */
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   380
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   381
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   382
static int ZIP_fileClose(FileHandle *handle)
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   383
{
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   384
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   385
    __PHYSFS_platformClose(finfo->handle);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   386
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   387
    if (finfo->entry->compression_method != COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   388
        inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   389
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   390
    if (finfo->buffer != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   391
        free(finfo->buffer);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   392
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   393
    free(finfo);
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   394
    return(1);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   395
} /* ZIP_fileClose */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   396
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   397
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   398
static PHYSFS_sint64 find_end_of_central_dir(void *in, PHYSFS_sint64 *len)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   399
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   400
    /* !!! FIXME: potential race condition! */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   401
    /* !!! FIXME: mutex this or switch to smaller stack-based buffer. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   402
    static PHYSFS_uint8 buf[0xFFFF + 20];
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   403
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   404
    PHYSFS_sint32 i;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   405
    PHYSFS_sint64 filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   406
    PHYSFS_sint64 filepos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   407
    PHYSFS_sint32 maxread;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   408
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   409
    filelen = __PHYSFS_platformFileLength(in);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   410
    BAIL_IF_MACRO(filelen == -1, NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   411
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   412
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   413
     * Jump to the end of the file and start reading backwards.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   414
     *  The last thing in the file is the zipfile comment, which is variable
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   415
     *  length, and the field that specifies its size is before it in the
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   416
     *  file (argh!)...this means that we need to scan backwards until we
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   417
     *  hit the end-of-central-dir signature. We can then sanity check that
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   418
     *  the comment was as big as it should be to make sure we're in the
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   419
     *  right place. The comment length field is 16 bits, so we can stop
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   420
     *  searching for that signature after 64k at most, and call it a
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   421
     *  corrupted zipfile.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   422
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   423
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   424
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   425
     * !!! FIXME: This was easier than reading backwards in chunks, but it's
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   426
     * !!! FIXME:  rather memory hungry.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   427
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   428
    if (sizeof (buf) < filelen)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   429
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   430
        filepos = filelen - sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   431
        maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   432
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   433
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   434
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   435
        filepos = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   436
        maxread = filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   437
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   438
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   439
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, filepos), NULL, -1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   440
    BAIL_IF_MACRO(__PHYSFS_platformRead(in, buf, maxread, 1) != 1, NULL, -1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   441
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   442
    for (i = maxread - 4; i > 0; i--)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   443
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   444
        if ((buf[i + 0] == 0x50) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   445
            (buf[i + 1] == 0x4B) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   446
            (buf[i + 2] == 0x05) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   447
            (buf[i + 3] == 0x06) )
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   448
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   449
            break;  /* that's the signature! */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   450
        } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   451
    } /* for */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   452
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   453
    BAIL_IF_MACRO(i < 0, ERR_NOT_AN_ARCHIVE, -1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   454
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   455
    if (len != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   456
        *len = filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   457
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   458
    return(filelen - (maxread - i));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   459
} /* find_end_of_central_dir */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   460
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   461
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   462
static int ZIP_isArchive(const char *filename, int forWriting)
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   463
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   464
    PHYSFS_uint32 sig;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   465
    int retval;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   466
    void *in;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   467
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   468
    in = __PHYSFS_platformOpenRead(filename);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   469
    BAIL_IF_MACRO(in == NULL, NULL, 0);
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   470
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   471
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   472
     * The first thing in a zip file might be the signature of the
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   473
     *  first local file record, so it makes for a quick determination.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   474
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   475
    BAIL_IF_MACRO(!readui32(in, &sig), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   476
    retval = (sig == ZIP_LOCAL_FILE_SIG);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   477
    if (!retval)
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   478
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   479
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   480
         * No sig...might be a ZIP with data at the start
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   481
         *  (a self-extracting executable, etc), so we'll have to do
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   482
         *  it the hard way...
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   483
         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   484
        retval = (find_end_of_central_dir(in, NULL) == -1);
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   485
    } /* if */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   486
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   487
    __PHYSFS_platformClose(in);
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   488
    return(retval);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   489
} /* ZIP_isArchive */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   490
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   491
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   492
static int zip_set_open_position(void *in, ZIPentry *entry)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   493
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   494
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   495
     * We fix up the offset to point to the actual data on the
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   496
     *  first open, since we don't want to seek across the whole file on
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   497
     *  archive open (can be SLOW on large, CD-stored files), but we
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   498
     *  need to check the local file header...not just for corruption,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   499
     *  but since it stores offset info the central directory does not.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   500
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   501
    if (!entry->fixed_up)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   502
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   503
        PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   504
        PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   505
        PHYSFS_uint16 fnamelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   506
        PHYSFS_uint16 extralen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   507
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   508
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, entry->offset), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   509
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   510
        BAIL_IF_MACRO(ui32 != ZIP_LOCAL_FILE_SIG, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   511
        BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   512
        BAIL_IF_MACRO(ui16 != entry->version_needed, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   513
        BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);  /* general bits. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   514
        BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   515
        BAIL_IF_MACRO(ui16 != entry->compression_method, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   516
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);  /* date/time */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   517
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   518
        BAIL_IF_MACRO(ui32 != entry->crc, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   519
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   520
        BAIL_IF_MACRO(ui32 != entry->compressed_size, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   521
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   522
        BAIL_IF_MACRO(ui32 != entry->uncompressed_size, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   523
        BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   524
        BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   525
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   526
        entry->offset += fnamelen + extralen + 30;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   527
        entry->fixed_up = 1;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   528
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   529
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   530
    return(__PHYSFS_platformSeek(in, entry->offset));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   531
} /* zip_set_open_position */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   532
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   533
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   534
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   535
static void freeEntries(ZIPinfo *info, int count)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   536
{
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   537
    int i;
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   538
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   539
    for (i = 0; i < count; i++)
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   540
    {
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   541
        free(info->entries[i].name);
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   542
        if (info->entries[i].symlink != NULL)
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   543
            free(info->entries[i].symlink);
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   544
    } /* for */
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   545
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   546
    free(info->entries);
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   547
} /* freeEntries */
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   548
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   549
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   550
/*
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   551
 * !!! FIXME: Really implement this.
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   552
 * !!! FIXME:  symlinks in zipfiles can be relative paths, including
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   553
 * !!! FIXME:  "." and ".." entries. These need to be parsed out.
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   554
 * !!! FIXME:  For now, though, we're just copying the relative path. Oh well.
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   555
 */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   556
static char *expand_symlink_path(char *path, ZIPentry *entry)
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   557
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   558
/*
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   559
    char *retval = (char *) malloc(strlen(path) + 1);
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   560
    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   561
    strcpy(retval, path);
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   562
    return(retval);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   563
*/
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   564
    return(path);  /* !!! FIXME */
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   565
} /* expand_symlink_path */
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   566
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   567
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   568
static char *get_zip_realpath(void *in, ZIPentry *entry)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   569
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   570
    char *path;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   571
    PHYSFS_uint32 size = entry->uncompressed_size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   572
    int rc = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   573
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   574
    BAIL_IF_MACRO(!zip_set_open_position(in, entry), NULL, NULL);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   575
    path = (char *) malloc(size + 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   576
    BAIL_IF_MACRO(path == NULL, ERR_OUT_OF_MEMORY, NULL);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   577
    
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   578
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   579
        rc = (__PHYSFS_platformRead(in, path, size, 1) == 1);
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   580
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   581
    else  /* symlink target path is compressed... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   582
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   583
        z_stream stream;
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   584
        PHYSFS_uint32 compsize = entry->compressed_size;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   585
        PHYSFS_uint8 *compressed = (PHYSFS_uint8 *) malloc(compsize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   586
        if (compressed != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   587
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   588
            if (__PHYSFS_platformRead(in, compressed, compsize, 1) == 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   589
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   590
                memset(&stream, '\0', sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   591
                stream.next_in = compressed;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   592
                stream.avail_in = compsize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   593
                stream.next_out = path;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   594
                stream.avail_out = size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   595
                if (zlib_err(inflateInit2(&stream, -MAX_WBITS)) == Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   596
                {
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   597
                    rc = zlib_err(inflate(&stream, Z_FINISH));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   598
                    inflateEnd(&stream);
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   599
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   600
                    /* both are acceptable outcomes... */
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   601
                    rc = ((rc == Z_OK) || (rc == Z_STREAM_END));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   602
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   603
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   604
            free(compressed);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   605
        } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   606
    } /* else */
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   607
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   608
    if (!rc)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   609
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   610
        free(path);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   611
        return(NULL);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   612
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   613
    path[entry->uncompressed_size] = '\0'; /* null-terminate it. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   614
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   615
    return(expand_symlink_path(path, entry)); /* retval is realloc()'d path. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   616
} /* get_zip_realpath */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   617
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   618
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   619
static int version_does_symlinks(PHYSFS_uint32 version)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   620
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   621
    int retval = 0;
163
fc2b8ee5b420 Approved zeph's comments, fixed a few of my screwups.
Ryan C. Gordon <icculus@icculus.org>
parents: 161
diff changeset
   622
    PHYSFS_uint8 hosttype = (PHYSFS_uint8) ((version >> 8) & 0xFF);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   623
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   624
    switch (hosttype)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   625
    {
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   626
            /*
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   627
             * These are the platforms that can NOT build an archive with
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   628
             *  symlinks, according to the Info-ZIP project.
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   629
             */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   630
        case 0:  /* FS_FAT_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   631
        case 1:  /* AMIGA_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   632
        case 2:  /* VMS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   633
        case 4:  /* VM_CSM_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   634
        case 6:  /* FS_HPFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   635
        case 11: /* FS_NTFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   636
        case 14: /* FS_VFAT_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   637
        case 13: /* ACORN_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   638
        case 15: /* MVS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   639
        case 18: /* THEOS_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   640
            break;  /* do nothing. */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   641
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   642
        default:  /* assume the rest to be unix-like. */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   643
            retval = 1;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   644
            break;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   645
    } /* switch */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   646
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   647
    return(retval);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   648
} /* version_does_symlinks */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   649
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   650
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   651
static int entry_is_symlink(ZIPentry *entry, PHYSFS_uint32 extern_attr)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   652
{
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   653
    PHYSFS_uint16 xattr = ((extern_attr >> 16) & 0xFFFF);
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   654
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   655
    return (
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   656
              (version_does_symlinks(entry->version)) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   657
              (entry->uncompressed_size > 0) &&
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   658
              ((xattr & UNIX_FILETYPE_MASK) == UNIX_FILETYPE_SYMLINK)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   659
           );
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   660
} /* entry_is_symlink */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   661
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   662
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   663
PHYSFS_sint64 dos_time_to_physfs_time(PHYSFS_uint32 dostime)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   664
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   665
    PHYSFS_uint32 dosdate = (PHYSFS_uint32) (dostime >> 16);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   666
    struct tm unixtime;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   667
    memset(&unixtime, '\0', sizeof (unixtime));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   668
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   669
    unixtime.tm_mday = (PHYSFS_uint32) (dosdate & 0x1F);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   670
    unixtime.tm_mon = (PHYSFS_uint32) ((((dosdate) & 0x1E0) / 0x20) - 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   671
    unixtime.tm_year = (PHYSFS_uint32) (((dosdate & 0x0FE00) / 0x0200) + 80);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   672
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   673
    unixtime.tm_hour = (PHYSFS_uint32) ((dostime & 0xF800) / 0x800);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   674
    unixtime.tm_min = (PHYSFS_uint32) ((dostime & 0x7E0) / 0x20);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   675
    unixtime.tm_sec = (PHYSFS_uint32) (2 * (dostime & 0x1F));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   676
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   677
    return((PHYSFS_sint64) mktime(&unixtime));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   678
} /* dos_time_to_physfs_time */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   679
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   680
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   681
static int load_zip_entry(void *in, ZIPentry *entry, PHYSFS_uint32 ofs_fixup)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   682
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   683
    PHYSFS_uint16 fnamelen, extralen, commentlen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   684
    PHYSFS_uint32 external_attr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   685
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   686
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   687
    PHYSFS_sint64 si64;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   688
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   689
    /* sanity check with central directory signature... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   690
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   691
    BAIL_IF_MACRO(ui32 != ZIP_CENTRAL_DIR_SIG, ERR_CORRUPTED, 0);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   692
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   693
    /* Get the pertinent parts of the record... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   694
    BAIL_IF_MACRO(!readui16(in, &entry->version), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   695
    BAIL_IF_MACRO(!readui16(in, &entry->version_needed), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   696
    BAIL_IF_MACRO(!readui16(in, &entry->flag), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   697
    BAIL_IF_MACRO(!readui16(in, &entry->compression_method), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   698
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   699
    entry->last_mod_time = dos_time_to_physfs_time(ui32);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   700
    BAIL_IF_MACRO(!readui32(in, &entry->crc), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   701
    BAIL_IF_MACRO(!readui32(in, &entry->compressed_size), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   702
    BAIL_IF_MACRO(!readui32(in, &entry->uncompressed_size), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   703
    BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   704
    BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   705
    BAIL_IF_MACRO(!readui16(in, &commentlen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   706
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);  /* disk number start */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   707
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);  /* internal file attribs */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   708
    BAIL_IF_MACRO(!readui32(in, &external_attr), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   709
    BAIL_IF_MACRO(!readui32(in, &entry->offset), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   710
    entry->offset += ofs_fixup;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   711
    entry->fixed_up = 0; /* we need to do a second fixup at openRead(). */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   712
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   713
    entry->name = (char *) malloc(fnamelen + 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   714
    BAIL_IF_MACRO(entry->name == NULL, ERR_OUT_OF_MEMORY, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   715
    if (__PHYSFS_platformRead(in, entry->name, fnamelen, 1) != 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   716
        goto load_zip_entry_puked;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   717
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   718
    entry->name[fnamelen] = '\0';  /* null-terminate the filename. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   719
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   720
    si64 = __PHYSFS_platformTell(in);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   721
    if (si64 == -1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   722
        goto load_zip_entry_puked;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   723
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   724
        /* If this is a symlink, resolve it. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   725
    if (!entry_is_symlink(entry, external_attr))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   726
        entry->symlink = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   727
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   728
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   729
        entry->symlink = get_zip_realpath(in, entry);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   730
        if (entry->symlink == NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   731
            goto load_zip_entry_puked;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   732
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   733
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   734
        /* seek to the start of the next entry in the central directory... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   735
    if (!__PHYSFS_platformSeek(in, si64 + extralen + commentlen))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   736
        goto load_zip_entry_puked;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   737
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   738
    return(1);  /* success. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   739
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   740
load_zip_entry_puked:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   741
    free(entry->name);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   742
    return(0);  /* failure. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   743
} /* load_zip_entry */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   744
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   745
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   746
static int load_zip_entries(void *in, DirHandle *dirh,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   747
                            PHYSFS_uint32 data_ofs, PHYSFS_uint32 central_ofs)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   748
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   749
    ZIPinfo *info = (ZIPinfo *) dirh->opaque;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   750
    PHYSFS_uint32 max = info->entryCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   751
    PHYSFS_uint32 i;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   752
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   753
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, central_ofs), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   754
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   755
    info->entries = (ZIPentry *) malloc(sizeof (ZIPentry) * max);
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   756
    BAIL_IF_MACRO(info->entries == NULL, ERR_OUT_OF_MEMORY, 0);
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   757
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   758
    for (i = 0; i < max; i++)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   759
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   760
        if (!load_zip_entry(in, &info->entries[i], data_ofs))
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   761
        {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   762
            freeEntries(info, i);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   763
            return(0);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   764
        } /* if */
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   765
    } /* for */
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   766
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   767
    return(1);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   768
} /* load_zip_entries */
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   769
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   770
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   771
static int parse_end_of_central_dir(void *in, DirHandle *dirh,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   772
                                    PHYSFS_uint32 *data_start,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   773
                                    PHYSFS_uint32 *central_dir_ofs)
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   774
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   775
    ZIPinfo *zipinfo = (ZIPinfo *) dirh->opaque;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   776
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   777
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   778
    PHYSFS_sint64 len;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   779
    PHYSFS_sint64 pos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   780
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   781
    /* find the end-of-central-dir record, and seek to it. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   782
    pos = find_end_of_central_dir(in, &len);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   783
    BAIL_IF_MACRO(pos == -1, NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   784
	BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, pos), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   785
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   786
    /* check signature again, just in case. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   787
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   788
    BAIL_IF_MACRO(ui32 != ZIP_END_OF_CENTRAL_DIR_SIG, ERR_NOT_AN_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   789
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   790
	/* number of this disk */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   791
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   792
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   793
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   794
	/* number of the disk with the start of the central directory */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   795
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   796
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   797
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   798
	/* total number of entries in the central dir on this disk */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   799
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   800
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   801
	/* total number of entries in the central dir */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   802
    BAIL_IF_MACRO(!readui16(in, &zipinfo->entryCount), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   803
    BAIL_IF_MACRO(ui16 != zipinfo->entryCount, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   804
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   805
	/* size of the central directory */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   806
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   807
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   808
	/* offset of central directory */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   809
    BAIL_IF_MACRO(!readui32(in, central_dir_ofs), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   810
    BAIL_IF_MACRO(pos < *central_dir_ofs + ui32, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   811
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   812
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   813
     * For self-extracting archives, etc, there's crapola in the file
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   814
     *  before the zipfile records; we calculate how much data there is
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   815
     *  prepended by determining how far the central directory offset is
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   816
     *  from where it is supposed to be (start of end-of-central-dir minus
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   817
     *  sizeof central dir)...the difference in bytes is how much arbitrary
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   818
     *  data is at the start of the physical file.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   819
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   820
	*data_start = pos - (*central_dir_ofs + ui32);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   821
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   822
    /* Now that we know the difference, fix up the central dir offset... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   823
    *central_dir_ofs += *data_start;
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   824
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   825
	/* zipfile comment length */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   826
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   827
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   828
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   829
     * Make sure that the comment length matches to the end of file...
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   830
     *  If it doesn't, we're either in the wrong part of the file, or the
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   831
     *  file is corrupted, but we give up either way.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   832
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   833
    BAIL_IF_MACRO((pos + 22 + ui16) != len, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   834
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   835
    return(1);  /* made it. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   836
} /* parse_end_of_central_dir */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   837
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   838
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   839
static DirHandle *allocate_zip_dirhandle(const char *name)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   840
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   841
    char *ptr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   842
    DirHandle *retval = malloc(sizeof (DirHandle));
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   843
    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   844
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   845
    memset(retval, '\0', sizeof (DirHandle));
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   846
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   847
    retval->opaque = malloc(sizeof (ZIPinfo));
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   848
    if (retval->opaque == NULL)
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   849
    {
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   850
        free(retval);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   851
        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   852
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   853
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   854
    memset(retval->opaque, '\0', sizeof (ZIPinfo));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   855
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   856
    ptr = (char *) malloc(strlen(name) + 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   857
    if (ptr == NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   858
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   859
        free(retval->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   860
        free(retval);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   861
        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   862
    } /* if */
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   863
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   864
    ((ZIPinfo *) (retval->opaque))->archiveName = ptr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   865
    strcpy(((ZIPinfo *) (retval->opaque))->archiveName, name);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   866
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   867
    retval->funcs = &__PHYSFS_DirFunctions_ZIP;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   868
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   869
    return(retval);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   870
} /* allocate_zip_dirhandle */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   871
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   872
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   873
static DirHandle *ZIP_openArchive(const char *name, int forWriting)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   874
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   875
    DirHandle *retval = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   876
    void *in = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   877
    PHYSFS_uint32 data_start;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   878
    PHYSFS_uint32 central_dir_ofs;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   879
    int success = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   880
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   881
    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   882
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   883
    if ((in = __PHYSFS_platformOpenRead(name)) == NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   884
        goto zip_openarchive_end;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   885
    
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   886
    if ((retval = allocate_zip_dirhandle(name)) == NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   887
        goto zip_openarchive_end;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   888
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   889
    if (!parse_end_of_central_dir(in, retval, &data_start, &central_dir_ofs))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   890
        goto zip_openarchive_end;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   891
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   892
    if (!load_zip_entries(in, retval, data_start, central_dir_ofs))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   893
        goto zip_openarchive_end;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   894
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   895
    success = 1;  /* ...and we're good to go.  :)  */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   896
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   897
zip_openarchive_end:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   898
    if (!success)  /* clean up for failures. */
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   899
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   900
        if (retval != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   901
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   902
            if (retval->opaque != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   903
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   904
                if (((ZIPinfo *) (retval->opaque))->archiveName != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   905
                    free(((ZIPinfo *) (retval->opaque))->archiveName);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   906
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   907
                free(retval->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   908
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   909
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   910
            free(retval);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   911
            retval = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   912
        } /* if */
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   913
    } /* if */
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   914
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   915
    if (in != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   916
        __PHYSFS_platformClose(in);  /* Close this even with success. */
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   917
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   918
    return(retval);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   919
} /* ZIP_openArchive */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   920
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   921
335
1d4720c018c3 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 254
diff changeset
   922
/* !!! FIXME: This is seriously ugly. */
41
ff60d39d0862 Architecture adjustment for enumerating files with regards to whether
Ryan C. Gordon <icculus@icculus.org>
parents: 39
diff changeset
   923
static LinkedStringList *ZIP_enumerateFiles(DirHandle *h,
ff60d39d0862 Architecture adjustment for enumerating files with regards to whether
Ryan C. Gordon <icculus@icculus.org>
parents: 39
diff changeset
   924
                                            const char *dirname,
ff60d39d0862 Architecture adjustment for enumerating files with regards to whether
Ryan C. Gordon <icculus@icculus.org>
parents: 39
diff changeset
   925
                                            int omitSymLinks)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   926
{
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   927
    ZIPinfo *zi = (ZIPinfo *) (h->opaque);
71
105bdb041c03 More win32 updates.
Ryan C. Gordon <icculus@icculus.org>
parents: 69
diff changeset
   928
    unsigned int i;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   929
    int dlen;
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   930
    LinkedStringList *retval = NULL;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   931
    LinkedStringList *l = NULL;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   932
    LinkedStringList *prev = NULL;
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   933
    char *d;
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   934
    ZIPentry *entry;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   935
    char buf[MAXZIPENTRYSIZE];
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   936
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   937
    dlen = strlen(dirname);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   938
    d = malloc(dlen + 1);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   939
    BAIL_IF_MACRO(d == NULL, ERR_OUT_OF_MEMORY, NULL);
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   940
    strcpy(d, dirname);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   941
    if ((dlen > 0) && (d[dlen - 1] == '/'))   /* remove trailing slash. */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   942
    {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   943
        dlen--;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   944
        d[dlen] = '\0';
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   945
    } /* if */
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   946
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   947
    for (i = 0, entry = zi->entries; i < zi->entryCount; i++, entry++)
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   948
    {
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   949
        char *ptr;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   950
        char *add_file;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   951
        int this_dlen;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   952
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   953
        if ((omitSymLinks) && (entry->symlink != NULL))
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   954
            continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   955
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   956
        this_dlen = strlen(entry->name);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   957
        if (this_dlen + 1 > MAXZIPENTRYSIZE)  /* !!! FIXME */
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   958
            continue;  /* ugh. */
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   959
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   960
        strcpy(buf, entry->name);
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   961
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   962
        if ((this_dlen > 0) && (buf[this_dlen - 1] == '/'))   /* no trailing slash. */
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   963
        {
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   964
            this_dlen--;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   965
            buf[this_dlen] = '\0';
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   966
        } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   967
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   968
        if (this_dlen <= dlen)  /* not in this dir. */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   969
            continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   970
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   971
        if (*d == '\0')
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   972
            add_file = buf;
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   973
        else
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   974
        {
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   975
            if (buf[dlen] != '/') /* can't be in same directory? */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   976
                continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   977
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   978
            buf[dlen] = '\0';
52
bbb26eacc532 Enough fixes to get the Build engine working with ZIP files instead of
Ryan C. Gordon <icculus@icculus.org>
parents: 50
diff changeset
   979
            if (__PHYSFS_platformStricmp(d, buf) != 0)   /* not same directory? */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   980
                continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   981
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   982
            add_file = buf + dlen + 1;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   983
        } /* else */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   984
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   985
        /* handle subdirectories... */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   986
        ptr = strchr(add_file, '/');
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   987
        if (ptr != NULL)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   988
        {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   989
            LinkedStringList *j;
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   990
            *ptr = '\0';
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   991
            for (j = retval; j != NULL; j = j->next)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   992
            {
52
bbb26eacc532 Enough fixes to get the Build engine working with ZIP files instead of
Ryan C. Gordon <icculus@icculus.org>
parents: 50
diff changeset
   993
                if (__PHYSFS_platformStricmp(j->str, ptr) == 0)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   994
                    break;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   995
            } /* for */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   996
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   997
            if (j != NULL)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   998
                continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   999
        } /* if */
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1000
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1001
        l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
39
bc29e1ee7ef6 Lots of bugfixes, enhancements, and corrections due to the work on
Ryan C. Gordon <icculus@icculus.org>
parents: 37
diff changeset
  1002
        if (l == NULL)
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1003
            break;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1004
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1005
        l->str = (char *) malloc(strlen(add_file) + 1);
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1006
        if (l->str == NULL)
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1007
        {
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1008
            free(l);
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1009
            break;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1010
        } /* if */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1011
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1012
        strcpy(l->str, add_file);
39
bc29e1ee7ef6 Lots of bugfixes, enhancements, and corrections due to the work on
Ryan C. Gordon <icculus@icculus.org>
parents: 37
diff changeset
  1013
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1014
        if (retval == NULL)
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1015
            retval = l;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1016
        else
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1017
            prev->next = l;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1018
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1019
        prev = l;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1020
        l->next = NULL;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1021
    } /* for */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1022
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1023
    free(d);
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1024
    return(retval);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1025
} /* ZIP_enumerateFiles */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1026
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1027
335
1d4720c018c3 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 254
diff changeset
  1028
/* !!! FIXME: This is seriously ugly. */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1029
static int ZIP_exists_symcheck(DirHandle *h, const char *name, int follow)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1030
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1031
    char buf[MAXZIPENTRYSIZE];
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1032
    ZIPinfo *zi = (ZIPinfo *) (h->opaque);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1033
    int dlen;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1034
    char *d;
71
105bdb041c03 More win32 updates.
Ryan C. Gordon <icculus@icculus.org>
parents: 69
diff changeset
  1035
    unsigned int i;
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1036
    ZIPentry *entry;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1037
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1038
    dlen = strlen(name);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1039
    d = malloc(dlen + 1);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1040
    BAIL_IF_MACRO(d == NULL, ERR_OUT_OF_MEMORY, -1);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1041
    strcpy(d, name);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1042
    if ((dlen > 0) && (d[dlen - 1] == '/'))   /* no trailing slash. */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1043
    {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1044
        dlen--;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1045
        d[dlen] = '\0';
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1046
    } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1047
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1048
    for (i = 0, entry = zi->entries; i < zi->entryCount; i++, entry++)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1049
    {
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1050
        int this_dlen = strlen(entry->name);
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1051
        if (this_dlen + 1 > MAXZIPENTRYSIZE)
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1052
            continue;  /* ugh. */
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1053
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1054
        strcpy(buf, entry->name);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1055
        if ((this_dlen > 0) && (buf[this_dlen - 1] == '/'))   /* no trailing slash. */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1056
        {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1057
            this_dlen--;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1058
            buf[this_dlen] = '\0';
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1059
        } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1060
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1061
        if ( ((buf[dlen] == '/') || (buf[dlen] == '\0')) &&
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1062
             (strncmp(d, buf, dlen) == 0) )
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1063
        {
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1064
            int retval = i;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1065
            free(d);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1066
            if (follow)  /* follow symlinks? */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1067
            {
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1068
                if (entry->symlink != NULL)
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1069
                    retval = ZIP_exists_symcheck(h, entry->symlink, follow-1);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1070
            } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1071
            return(retval);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1072
        } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1073
    } /* for */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1074
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1075
    free(d);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1076
    return(-1);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1077
} /* ZIP_exists_symcheck */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1078
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1079
21
b1ea58d70a56 Archive implementation (Build Groupfiles), other tweaks.
Ryan C. Gordon <icculus@icculus.org>
parents: 20
diff changeset
  1080
static int ZIP_exists(DirHandle *h, const char *name)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1081
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1082
    int pos = ZIP_exists_symcheck(h, name, SYMLINK_RECURSE_COUNT);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1083
    int is_sym;
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1084
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1085
    BAIL_IF_MACRO(pos == -1, ERR_NO_SUCH_FILE, 0);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1086
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1087
    /* if it's a symlink, then we ran into a possible symlink loop. */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1088
    is_sym = ( ((ZIPinfo *)(h->opaque))->entries[pos].symlink != NULL );
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1089
    BAIL_IF_MACRO(is_sym, ERR_TOO_MANY_SYMLINKS, 0);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1090
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1091
    return(1);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1092
} /* ZIP_exists */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1093
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1094
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1095
static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *name)
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1096
{
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1097
    ZIPinfo *zi = (ZIPinfo *) (h->opaque);
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1098
    int pos = ZIP_exists_symcheck(h, name, SYMLINK_RECURSE_COUNT);
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1099
    ZIPentry *entry;
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1100
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1101
    BAIL_IF_MACRO(pos == -1, ERR_NO_SUCH_FILE, 0);
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1102
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1103
    entry = &zi->entries[pos];
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1104
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1105
    /* if it's a symlink, then we ran into a possible symlink loop. */
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1106
    BAIL_IF_MACRO(entry->symlink != NULL, ERR_TOO_MANY_SYMLINKS, 0);
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1107
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1108
    return(entry->last_mod_time);
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1109
} /* ZIP_getLastModTime */
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1110
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1111
21
b1ea58d70a56 Archive implementation (Build Groupfiles), other tweaks.
Ryan C. Gordon <icculus@icculus.org>
parents: 20
diff changeset
  1112
static int ZIP_isDirectory(DirHandle *h, const char *name)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1113
{
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1114
    int dlen;
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1115
    int is_sym;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1116
    int pos = ZIP_exists_symcheck(h, name, SYMLINK_RECURSE_COUNT);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1117
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1118
    BAIL_IF_MACRO(pos == -1, ERR_NO_SUCH_FILE, 0);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1119
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1120
    /* if it's a symlink, then we ran into a possible symlink loop. */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1121
    is_sym = ( ((ZIPinfo *)(h->opaque))->entries[pos].symlink != NULL );
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1122
    BAIL_IF_MACRO(is_sym, ERR_TOO_MANY_SYMLINKS, 0);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1123
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1124
    dlen = strlen(name);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1125
335
1d4720c018c3 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 254
diff changeset
  1126
    /* !!! FIXME: yikes. Better way to check? */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1127
    return((((ZIPinfo *)(h->opaque))->entries[pos].name[dlen] == '/'));
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1128
} /* ZIP_isDirectory */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1129
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1130
21
b1ea58d70a56 Archive implementation (Build Groupfiles), other tweaks.
Ryan C. Gordon <icculus@icculus.org>
parents: 20
diff changeset
  1131
static int ZIP_isSymLink(DirHandle *h, const char *name)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1132
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1133
    int pos = ZIP_exists_symcheck(h, name, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1134
    BAIL_IF_MACRO(pos == -1, ERR_NO_SUCH_FILE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1135
    return( ((ZIPinfo *)(h->opaque))->entries[pos].symlink != NULL );
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1136
} /* ZIP_isSymLink */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1137
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1138
21
b1ea58d70a56 Archive implementation (Build Groupfiles), other tweaks.
Ryan C. Gordon <icculus@icculus.org>
parents: 20
diff changeset
  1139
static FileHandle *ZIP_openRead(DirHandle *h, const char *filename)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1140
{
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1141
    FileHandle *retval = NULL;
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1142
    ZIPinfo *zi = ((ZIPinfo *) (h->opaq