archivers/zip.c
author Ryan C. Gordon <icculus@icculus.org>
Sat, 13 Jul 2002 10:17:13 +0000
changeset 337 28500f02eb87
parent 335 1d4720c018c3
child 340 24a11f8566f8
permissions -rw-r--r--
ZIP archiver rewrite.
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
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    97
#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
    98
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    99
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   100
/* 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
   101
#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
   102
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   103
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   104
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
   105
                              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
   106
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
   107
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
   108
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
   109
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
   110
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
   111
static int ZIP_isArchive(const char *filename, int forWriting);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   112
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
   113
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
   114
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
   115
                                            const char *dirname,
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   116
                                            int omitSymLinks);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   117
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
   118
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
   119
static int ZIP_isSymLink(DirHandle *h, const char *name);
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
   120
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
   121
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
   122
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
   123
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   124
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   125
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
   126
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   127
    ZIP_read,       /* read() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   128
    NULL,           /* write() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   129
    ZIP_eof,        /* eof() method        */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   130
    ZIP_tell,       /* tell() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   131
    ZIP_seek,       /* seek() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   132
    ZIP_fileLength, /* fileLength() method */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   133
    ZIP_fileClose   /* fileClose() method  */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   134
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   135
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   136
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   137
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
   138
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   139
    ZIP_isArchive,          /* isArchive() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   140
    ZIP_openArchive,        /* openArchive() method    */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   141
    ZIP_enumerateFiles,     /* enumerateFiles() method */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   142
    ZIP_exists,             /* exists() method         */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   143
    ZIP_isDirectory,        /* isDirectory() method    */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   144
    ZIP_isSymLink,          /* isSymLink() method      */
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
   145
    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
   146
    ZIP_openRead,           /* openRead() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   147
    NULL,                   /* openWrite() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   148
    NULL,                   /* openAppend() method     */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   149
    NULL,                   /* remove() method         */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   150
    NULL,                   /* mkdir() method          */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   151
    ZIP_dirClose            /* dirClose() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   152
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   153
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   154
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
   155
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   156
    "ZIP",
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   157
    "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
   158
    "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
   159
    "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
   160
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   161
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
   162
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   163
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   164
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   165
 * 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
   166
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   167
static int zlib_err(int rc)
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
    const char *err = NULL;
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
    switch (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
        case Z_OK:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   174
        case Z_STREAM_END:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   175
            break;   /* not errors. */
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_ERRNO:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   178
            err = strerror(errno);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   179
            break;
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_NEED_DICT:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   182
            err = "zlib: need dictionary";
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
        case Z_DATA_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   185
            err = "zlib: need dictionary";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   186
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   187
        case Z_MEM_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   188
            err = "zlib: memory error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   189
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   190
        case Z_BUF_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   191
            err = "zlib: buffer error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   192
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   193
        case Z_VERSION_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   194
            err = "zlib: version error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   195
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   196
        default:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   197
            err = "unknown zlib error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   198
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   199
    } /* switch */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   200
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   201
    if (err != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   202
        __PHYSFS_setError(err);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   203
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   204
    return(rc);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   205
} /* zlib_err */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   206
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
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   209
 * 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
   210
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   211
static int readui32(void *in, PHYSFS_uint32 *val)
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
    PHYSFS_uint32 v;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   214
    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
   215
    *val = PHYSFS_swapULE32(v);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   216
    return(1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   217
} /* readui32 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   218
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   219
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   220
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   221
 * 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
   222
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   223
static int readui16(void *in, PHYSFS_uint16 *val)
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
    PHYSFS_uint16 v;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   226
    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
   227
    *val = PHYSFS_swapULE16(v);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   228
    return(1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   229
} /* readui16 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   230
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   231
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   232
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
   233
                              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
   234
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   235
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   236
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   237
    PHYSFS_sint64 retval = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   238
    PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   239
    PHYSFS_sint64 avail = entry->uncompressed_size -
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   240
                          finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   241
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   242
    BAIL_IF_MACRO(maxread == 0, NULL, 0);    /* quick rejection. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   243
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   244
    if (avail < maxread)
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
        maxread = avail - (avail % objSize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   247
        objCount = maxread / objSize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   248
        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
   249
        __PHYSFS_setError(ERR_PAST_EOF);   /* this is always true here. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   250
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   251
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   252
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   253
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   254
        retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   255
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   256
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   257
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   258
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   259
        finfo->stream.next_out = buf;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   260
        finfo->stream.avail_out = objSize * objCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   261
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   262
        while (retval < maxread)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   263
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   264
            PHYSFS_uint32 before = finfo->stream.total_out;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   265
            int rc;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   266
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   267
            if (finfo->stream.avail_in == 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   268
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   269
                PHYSFS_sint64 br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   270
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   271
                br = entry->compressed_size - finfo->compressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   272
                if (br > 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   273
                {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   274
                    if (br > ZIP_READBUFSIZE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   275
                        br = ZIP_READBUFSIZE;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   276
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   277
                    br = __PHYSFS_platformRead(finfo->handle,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   278
                                               finfo->buffer,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   279
                                               1, br);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   280
                    if (br <= 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   281
                        break;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   282
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   283
                    finfo->compressed_position += br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   284
                    finfo->stream.next_in = finfo->buffer;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   285
                    finfo->stream.avail_in = br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   286
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   287
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   288
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   289
            rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   290
            retval += (finfo->stream.total_out - before);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   291
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   292
            if (rc != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   293
                break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   294
        } /* while */
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
        retval /= objSize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   297
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   298
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   299
    if (retval > 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   300
        finfo->uncompressed_position += (retval * objSize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   301
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   302
    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
   303
} /* ZIP_read */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   304
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   305
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   306
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
   307
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   308
    ZIPfileinfo *finfo = ((ZIPfileinfo *) (handle->opaque));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   309
    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
   310
} /* ZIP_eof */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   311
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   312
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   313
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
   314
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   315
    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
   316
} /* ZIP_tell */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   317
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   318
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   319
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
   320
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   321
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   322
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   323
    void *in = finfo->handle;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   324
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   325
    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
   326
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   327
    if (entry->compression_method == COMPMETH_NONE)
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
        PHYSFS_sint64 newpos = offset + entry->offset;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   330
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   331
        finfo->uncompressed_position = newpos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   332
    } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   333
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   334
    else
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   335
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   336
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   337
         * If seeking backwards, we need to redecode the file
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   338
         *  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
   339
         *  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
   340
         *  redecode, but we don't rewind first.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   341
         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   342
        if (offset < finfo->uncompressed_position)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   343
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   344
            /* 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
   345
            z_stream str;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   346
            memset(&str, '\0', sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   347
            if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   348
                return(0);
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   349
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   350
            inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   351
            memcpy(&finfo->stream, &str, sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   352
            finfo->uncompressed_position = finfo->compressed_position = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   353
        } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   354
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   355
        while (finfo->uncompressed_position != offset)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   356
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   357
            PHYSFS_uint8 buf[512];
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   358
            PHYSFS_uint32 maxread = offset - finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   359
            if (maxread > sizeof (buf))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   360
                maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   361
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   362
            if (ZIP_read(handle, buf, maxread, 1) != 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   363
                return(0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   364
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   365
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   366
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   367
    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
   368
} /* ZIP_seek */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   369
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   370
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   371
static PHYSFS_sint64 ZIP_fileLength(FileHandle *handle)
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   372
{
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   373
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   374
    return(finfo->entry->uncompressed_size);
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   375
} /* ZIP_fileLength */
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   376
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   377
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   378
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
   379
{
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   380
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   381
    __PHYSFS_platformClose(finfo->handle);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   382
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   383
    if (finfo->entry->compression_method != COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   384
        inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   385
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   386
    if (finfo->buffer != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   387
        free(finfo->buffer);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   388
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   389
    free(finfo);
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   390
    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
   391
} /* ZIP_fileClose */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   392
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   393
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   394
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
   395
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   396
    /* !!! FIXME: potential race condition! */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   397
    /* !!! FIXME: mutex this or switch to smaller stack-based buffer. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   398
    static PHYSFS_uint8 buf[0xFFFF + 20];
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
    PHYSFS_sint32 i;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   401
    PHYSFS_sint64 filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   402
    PHYSFS_sint64 filepos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   403
    PHYSFS_sint32 maxread;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   404
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   405
    filelen = __PHYSFS_platformFileLength(in);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   406
    BAIL_IF_MACRO(filelen == -1, NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   407
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
     * 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
   410
     *  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
   411
     *  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
   412
     *  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
   413
     *  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
   414
     *  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
   415
     *  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
   416
     *  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
   417
     *  corrupted zipfile.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   418
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   419
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   420
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   421
     * !!! 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
   422
     * !!! FIXME:  rather memory hungry.
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
    if (sizeof (buf) < filelen)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   425
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   426
        filepos = filelen - sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   427
        maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   428
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   429
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   430
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   431
        filepos = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   432
        maxread = filelen;
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
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, filepos), NULL, -1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   436
    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
   437
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   438
    for (i = maxread - 4; i > 0; i--)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   439
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   440
        if ((buf[i + 0] == 0x50) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   441
            (buf[i + 1] == 0x4B) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   442
            (buf[i + 2] == 0x05) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   443
            (buf[i + 3] == 0x06) )
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   444
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   445
            break;  /* that's the signature! */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   446
        } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   447
    } /* for */
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
    BAIL_IF_MACRO(i < 0, ERR_NOT_AN_ARCHIVE, -1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   450
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   451
    if (len != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   452
        *len = filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   453
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   454
    return(filelen - (maxread - i));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   455
} /* find_end_of_central_dir */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   456
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   457
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   458
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
   459
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   460
    PHYSFS_uint32 sig;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   461
    int retval;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   462
    void *in;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   463
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   464
    in = __PHYSFS_platformOpenRead(filename);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   465
    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
   466
337
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
     * 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
   469
     *  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
   470
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   471
    BAIL_IF_MACRO(!readui32(in, &sig), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   472
    retval = (sig == ZIP_LOCAL_FILE_SIG);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   473
    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
   474
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   475
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   476
         * 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
   477
         *  (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
   478
         *  it the hard way...
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
        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
   481
    } /* if */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   482
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   483
    __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
   484
    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
   485
} /* ZIP_isArchive */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   486
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   487
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   488
static int zip_set_open_position(void *in, ZIPentry *entry)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   489
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   490
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   491
     * 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
   492
     *  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
   493
     *  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
   494
     *  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
   495
     *  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
   496
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   497
    if (!entry->fixed_up)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   498
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   499
        PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   500
        PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   501
        PHYSFS_uint16 fnamelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   502
        PHYSFS_uint16 extralen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   503
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   504
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, entry->offset), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   505
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   506
        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
   507
        BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   508
        BAIL_IF_MACRO(ui16 != entry->version_needed, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   509
        BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);  /* general bits. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   510
        BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   511
        BAIL_IF_MACRO(ui16 != entry->compression_method, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   512
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);  /* date/time */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   513
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   514
        BAIL_IF_MACRO(ui32 != entry->crc, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   515
        BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   516
        BAIL_IF_MACRO(ui32 != entry->compressed_size, ERR_CORRUPTED, 0);
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->uncompressed_size, ERR_CORRUPTED, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   519
        BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   520
        BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   521
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   522
        entry->offset += fnamelen + extralen + 30;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   523
        entry->fixed_up = 1;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   524
    } /* if */
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
    return(__PHYSFS_platformSeek(in, entry->offset));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   527
} /* zip_set_open_position */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   528
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
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   531
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
   532
{
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
   533
    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
   534
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   535
    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
   536
    {
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
        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
   538
        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
   539
            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
   540
    } /* 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
   541
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
    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
   543
} /* 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
   544
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   545
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   546
/*
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   547
 * !!! FIXME: Really implement this.
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   548
 * !!! 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
   549
 * !!! 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
   550
 * !!! 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
   551
 */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   552
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
   553
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   554
/*
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   555
    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
   556
    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
   557
    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
   558
    return(retval);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   559
*/
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   560
    return(path);  /* !!! FIXME */
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   561
} /* 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
   562
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   563
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   564
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
   565
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   566
    char *path;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   567
    PHYSFS_uint32 size = entry->uncompressed_size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   568
    int rc = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   569
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   570
    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
   571
    path = (char *) malloc(size + 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   572
    BAIL_IF_MACRO(path == NULL, ERR_OUT_OF_MEMORY, NULL);
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
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   575
        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
   576
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   577
    else  /* symlink target path is compressed... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   578
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   579
        z_stream stream;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   580
        PHYSFS_uint32 compsize = entry->uncompressed_size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   581
        PHYSFS_uint8 *compressed = (PHYSFS_uint8 *) malloc(compsize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   582
        if (compressed != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   583
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   584
            if (__PHYSFS_platformRead(in, compressed, compsize, 1) == 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   585
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   586
                memset(&stream, '\0', sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   587
                stream.next_in = compressed;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   588
                stream.avail_in = compsize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   589
                stream.next_out = path;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   590
                stream.avail_out = size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   591
                if (zlib_err(inflateInit2(&stream, -MAX_WBITS)) == Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   592
                {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   593
                    rc = (zlib_err(inflate(&stream, Z_FINISH)) == Z_OK);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   594
                    inflateEnd(&stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   595
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   596
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   597
            free(compressed);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   598
        } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   599
    } /* else */
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   600
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   601
    if (!rc)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   602
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   603
        free(path);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   604
        return(NULL);
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
    path[entry->uncompressed_size] = '\0'; /* null-terminate it. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   607
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   608
    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
   609
} /* 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
   610
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   611
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   612
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
   613
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   614
    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
   615
    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
   616
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
     * These are the platforms that can build an archive with symlinks,
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   619
     *  according to the Info-ZIP project.
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
    switch (hosttype)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   622
    {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   623
        case 3:   /* Unix  */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   624
        case 16:  /* BeOS  */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   625
        case 5:   /* Atari */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   626
            retval = 1;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   627
            break;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   628
    } /* switch */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   629
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   630
    return(retval);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   631
} /* version_does_symlinks */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   632
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   633
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   634
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
   635
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   636
    return (
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   637
              (version_does_symlinks(entry->version)) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   638
              (entry->uncompressed_size > 0) &&
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   639
              (extern_attr & 0x00120000)  /* symlink flag. */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   640
           );
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   641
} /* entry_is_symlink */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   642
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   643
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   644
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
   645
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   646
    PHYSFS_uint32 dosdate = (PHYSFS_uint32) (dostime >> 16);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   647
    struct tm unixtime;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   648
    memset(&unixtime, '\0', sizeof (unixtime));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   649
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   650
    unixtime.tm_mday = (PHYSFS_uint32) (dosdate & 0x1F);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   651
    unixtime.tm_mon = (PHYSFS_uint32) ((((dosdate) & 0x1E0) / 0x20) - 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   652
    unixtime.tm_year = (PHYSFS_uint32) (((dosdate & 0x0FE00) / 0x0200) + 80);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   653
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   654
    unixtime.tm_hour = (PHYSFS_uint32) ((dostime & 0xF800) / 0x800);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   655
    unixtime.tm_min = (PHYSFS_uint32) ((dostime & 0x7E0) / 0x20);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   656
    unixtime.tm_sec = (PHYSFS_uint32) (2 * (dostime & 0x1F));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   657
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   658
    return((PHYSFS_sint64) mktime(&unixtime));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   659
} /* dos_time_to_physfs_time */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   660
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   661
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   662
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
   663
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   664
    PHYSFS_uint16 fnamelen, extralen, commentlen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   665
    PHYSFS_uint32 external_attr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   666
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   667
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   668
    PHYSFS_sint64 si64;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   669
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   670
    /* sanity check with central directory signature... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   671
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   672
    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
   673
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   674
    /* Get the pertinent parts of the record... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   675
    BAIL_IF_MACRO(!readui16(in, &entry->version), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   676
    BAIL_IF_MACRO(!readui16(in, &entry->version_needed), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   677
    BAIL_IF_MACRO(!readui16(in, &entry->flag), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   678
    BAIL_IF_MACRO(!readui16(in, &entry->compression_method), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   679
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   680
    entry->last_mod_time = dos_time_to_physfs_time(ui32);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   681
    BAIL_IF_MACRO(!readui32(in, &entry->crc), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   682
    BAIL_IF_MACRO(!readui32(in, &entry->compressed_size), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   683
    BAIL_IF_MACRO(!readui32(in, &entry->uncompressed_size), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   684
    BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   685
    BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   686
    BAIL_IF_MACRO(!readui16(in, &commentlen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   687
    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
   688
    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
   689
    BAIL_IF_MACRO(!readui32(in, &external_attr), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   690
    BAIL_IF_MACRO(!readui32(in, &entry->offset), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   691
    entry->offset += ofs_fixup;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   692
    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
   693
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   694
    entry->name = (char *) malloc(fnamelen + 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   695
    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
   696
    if (__PHYSFS_platformRead(in, entry->name, fnamelen, 1) != 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   697
        goto load_zip_entry_puked;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   698
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   699
    entry->name[fnamelen] = '\0';  /* null-terminate the filename. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   700
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   701
    si64 = __PHYSFS_platformTell(in);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   702
    if (si64 == -1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   703
        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
   704
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   705
        /* If this is a symlink, resolve it. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   706
    if (!entry_is_symlink(entry, external_attr))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   707
        entry->symlink = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   708
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   709
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   710
        entry->symlink = get_zip_realpath(in, entry);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   711
        if (entry->symlink == NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   712
            goto load_zip_entry_puked;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   713
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   714
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   715
        /* 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
   716
    if (!__PHYSFS_platformSeek(in, si64 + extralen + commentlen))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   717
        goto load_zip_entry_puked;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   718
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   719
    return(1);  /* success. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   720
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   721
load_zip_entry_puked:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   722
    free(entry->name);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   723
    return(0);  /* failure. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   724
} /* load_zip_entry */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   725
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   726
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   727
static int load_zip_entries(void *in, DirHandle *dirh,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   728
                            PHYSFS_uint32 data_ofs, PHYSFS_uint32 central_ofs)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   729
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   730
    ZIPinfo *info = (ZIPinfo *) dirh->opaque;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   731
    PHYSFS_uint32 max = info->entryCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   732
    PHYSFS_uint32 i;
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
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, central_ofs), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   735
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
   736
    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
   737
    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
   738
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   739
    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
   740
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   741
        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
   742
        {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   743
            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
   744
            return(0);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   745
        } /* 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
   746
    } /* 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
   747
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   748
    return(1);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   749
} /* 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
   750
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   751
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   752
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
   753
                                    PHYSFS_uint32 *data_start,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   754
                                    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
   755
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   756
    ZIPinfo *zipinfo = (ZIPinfo *) dirh->opaque;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   757
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   758
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   759
    PHYSFS_sint64 len;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   760
    PHYSFS_sint64 pos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   761
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   762
    /* 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
   763
    pos = find_end_of_central_dir(in, &len);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   764
    BAIL_IF_MACRO(pos == -1, NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   765
	BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, pos), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   766
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   767
    /* check signature again, just in case. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   768
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   769
    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
   770
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   771
	/* number of this disk */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   772
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   773
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   774
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   775
	/* 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
   776
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   777
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   778
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   779
	/* 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
   780
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   781
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   782
	/* total number of entries in the central dir */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   783
    BAIL_IF_MACRO(!readui16(in, &zipinfo->entryCount), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   784
    BAIL_IF_MACRO(ui16 != zipinfo->entryCount, ERR_UNSUPPORTED_ARCHIVE, 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
	/* size of the central directory */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   787
    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
   788
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   789
	/* offset of central directory */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   790
    BAIL_IF_MACRO(!readui32(in, central_dir_ofs), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   791
    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
   792
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
     * 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
   795
     *  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
   796
     *  prepended by determining how far the central directory offset is
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   797
     *  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
   798
     *  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
   799
     *  data is at the start of the physical file.
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
	*data_start = pos - (*central_dir_ofs + ui32);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   802
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   803
    /* 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
   804
    *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
   805
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   806
	/* zipfile comment length */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   807
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   808
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   809
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   810
     * 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
   811
     *  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
   812
     *  file is corrupted, but we give up either way.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   813
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   814
    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
   815
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   816
    return(1);  /* made it. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   817
} /* parse_end_of_central_dir */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   818
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
static DirHandle *allocate_zip_dirhandle(const char *name)
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
    char *ptr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   823
    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
   824
    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
   825
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   826
    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
   827
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
   828
    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
   829
    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
   830
    {
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   831
        free(retval);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   832
        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   833
    } /* if */
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
    memset(retval->opaque, '\0', sizeof (ZIPinfo));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   836
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   837
    ptr = (char *) malloc(strlen(name) + 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   838
    if (ptr == NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   839
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   840
        free(retval->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   841
        free(retval);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   842
        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
   843
    } /* 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
   844
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   845
    ((ZIPinfo *) (retval->opaque))->archiveName = ptr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   846
    strcpy(((ZIPinfo *) (retval->opaque))->archiveName, name);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   847
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   848
    retval->funcs = &__PHYSFS_DirFunctions_ZIP;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   849
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   850
    return(retval);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   851
} /* allocate_zip_dirhandle */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   852
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
static DirHandle *ZIP_openArchive(const char *name, int forWriting)
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
    DirHandle *retval = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   857
    void *in = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   858
    PHYSFS_uint32 data_start;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   859
    PHYSFS_uint32 central_dir_ofs;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   860
    int success = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   861
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   862
    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   863
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   864
    if ((in = __PHYSFS_platformOpenRead(name)) == NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   865
        goto zip_openarchive_end;
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
    if ((retval = allocate_zip_dirhandle(name)) == NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   868
        goto zip_openarchive_end;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   869
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   870
    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
   871
        goto zip_openarchive_end;
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
    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
   874
        goto zip_openarchive_end;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   875
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   876
    success = 1;  /* ...and we're good to go.  :)  */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   877
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   878
zip_openarchive_end:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   879
    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
   880
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   881
        if (retval != 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 (retval->opaque != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   884
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   885
                if (((ZIPinfo *) (retval->opaque))->archiveName != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   886
                    free(((ZIPinfo *) (retval->opaque))->archiveName);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   887
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   888
                free(retval->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   889
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   890
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   891
            free(retval);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   892
            retval = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   893
        } /* 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
   894
    } /* 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
   895
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   896
    if (in != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   897
        __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
   898
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   899
    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
   900
} /* ZIP_openArchive */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   901
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   902
335
1d4720c018c3 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 254
diff changeset
   903
/* !!! 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
   904
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
   905
                                            const char *dirname,
ff60d39d0862 Architecture adjustment for enumerating files with regards to whether
Ryan C. Gordon <icculus@icculus.org>
parents: 39
diff changeset
   906
                                            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
   907
{
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   908
    ZIPinfo *zi = (ZIPinfo *) (h->opaque);
71
105bdb041c03 More win32 updates.
Ryan C. Gordon <icculus@icculus.org>
parents: 69
diff changeset
   909
    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
   910
    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
   911
    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
   912
    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
   913
    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
   914
    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
   915
    ZIPentry *entry;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   916
    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
   917
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   918
    dlen = strlen(dirname);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   919
    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
   920
    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
   921
    strcpy(d, dirname);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   922
    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
   923
    {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   924
        dlen--;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   925
        d[dlen] = '\0';
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   926
    } /* 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
   927
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   928
    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
   929
    {
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   930
        char *ptr;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   931
        char *add_file;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   932
        int this_dlen;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   933
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
   934
        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
   935
            continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   936
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
   937
        this_dlen = strlen(entry->name);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   938
        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
   939
            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
   940
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   941
        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
   942
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   943
        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
   944
        {
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   945
            this_dlen--;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   946
            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
   947
        } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   948
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   949
        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
   950
            continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   951
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   952
        if (*d == '\0')
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   953
            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
   954
        else
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   955
        {
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   956
            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
   957
                continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   958
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   959
            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
   960
            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
   961
                continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   962
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   963
            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
   964
        } /* else */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   965
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   966
        /* handle subdirectories... */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   967
        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
   968
        if (ptr != NULL)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   969
        {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   970
            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
   971
            *ptr = '\0';
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   972
            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
   973
            {
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
   974
                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
   975
                    break;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   976
            } /* for */
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
            if (j != NULL)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   979
                continue;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   980
        } /* 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
   981
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   982
        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
   983
        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
   984
            break;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   985
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   986
        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
   987
        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
   988
        {
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   989
            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
   990
            break;
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   991
        } /* if */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   992
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   993
        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
   994
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   995
        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
   996
            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
   997
        else
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   998
            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
   999
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1000
        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
  1001
        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
  1002
    } /* for */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1003
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
  1004
    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
  1005
    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
  1006
} /* ZIP_enumerateFiles */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1007
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1008
335
1d4720c018c3 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 254
diff changeset
  1009
/* !!! 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
  1010
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
  1011
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1012
    char buf[MAXZIPENTRYSIZE];
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1013
    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
  1014
    int dlen;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1015
    char *d;
71
105bdb041c03 More win32 updates.
Ryan C. Gordon <icculus@icculus.org>
parents: 69
diff changeset
  1016
    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
  1017
    ZIPentry *entry;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1018
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1019
    dlen = strlen(name);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1020
    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
  1021
    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
  1022
    strcpy(d, name);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1023
    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
  1024
    {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1025
        dlen--;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1026
        d[dlen] = '\0';
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1027
    } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1028
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1029
    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
  1030
    {
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
  1031
        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
  1032
        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
  1033
            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
  1034
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1035
        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
  1036
        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
  1037
        {
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1038
            this_dlen--;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1039
            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
  1040
        } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1041
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1042
        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
  1043
             (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
  1044
        {
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
  1045
            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
  1046
            free(d);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1047
            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
  1048
            {
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
  1049
                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
  1050
                    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
  1051
            } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1052
            return(retval);
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1053
        } /* if */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1054
    } /* for */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1055
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1056
    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
  1057
    return(-1);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1058
} /* ZIP_exists_symcheck */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1059
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1060
21
b1ea58d70a56 Archive implementation (Build Groupfiles), other tweaks.
Ryan C. Gordon <icculus@icculus.org>
parents: 20
diff changeset
  1061
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
  1062
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1063
    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
  1064
    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
  1065
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1066
    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
  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 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
  1069
    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
  1070
    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
  1071
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
  1072
    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
  1073
} /* ZIP_exists */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1074
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1075
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1076
static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *name)
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1077
{
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1078
    ZIPinfo *zi = (ZIPinfo *) (h->opaque);
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1079
    int pos = ZIP_exists_symcheck(h, name, SYMLINK_RECURSE_COUNT);
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1080
    ZIPentry *entry;
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1081
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1082
    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
  1083
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1084
    entry = &zi->entries[pos];
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1085
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1086
    /* 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
  1087
    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
  1088
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1089
    return(entry->last_mod_time);
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1090
} /* ZIP_getLastModTime */
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1091
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
  1092
21
b1ea58d70a56 Archive implementation (Build Groupfiles), other tweaks.
Ryan C. Gordon <icculus@icculus.org>
parents: 20
diff changeset
  1093
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
  1094
{
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
  1095
    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
  1096
    int is_sym;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1097
    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
  1098
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1099
    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
  1100
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
  1101
    /* 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
  1102
    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
  1103
    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
  1104
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
  1105
    dlen = strlen(name);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1106
335
1d4720c018c3 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 254
diff changeset
  1107
    /* !!! FIXME: yikes. Better way to check? */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1108
    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
  1109
} /* ZIP_isDirectory */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1110
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
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_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
  1113
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1114
    int pos = ZIP_exists_symcheck(h, name, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1115
    BAIL_IF_MACRO(pos == -1, ERR_NO_SUCH_FILE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1116
    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
  1117
} /* ZIP_isSymLink */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1118
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
  1119
21
b1ea58d70a56 Archive implementation (Build Groupfiles), other tweaks.
Ryan C. Gordon <icculus@icculus.org>
parents: 20
diff changeset
  1120
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
  1121
{
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1122
    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
  1123
    ZIPinfo *zi = ((ZIPinfo *) (h->opaque));
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
  1124
    ZIPfileinfo *finfo = NULL;
55
986740ba58ab Avoids unzLocateFile(), since we already did all the searching ourselves.
Ryan C. Gordon <icculus@icculus.org>
parents: 53
diff changeset
  1125
    int pos = ZIP_exists_symcheck(h, filename, SYMLINK_RECURSE_COUNT);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1126
    void *in;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1127
55
986740ba58ab Avoids unzLocateFile(), since we already did all the searching ourselves.
Ryan C. Gordon <icculus@icculus.org>
parents: 53
diff changeset
  1128
    BAIL_IF_MACRO(pos == -1, ERR_NO_SUCH_FILE, NULL);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1129
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1130
    /* if it's a symlink, then we ran into a possible symlink loop. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1131
    BAIL_IF_MACRO(zi->entries[pos].symlink != NULL, ERR_TOO_MANY_SYMLINKS, 0);
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
  1132
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1133
    in = __PHYSFS_platformOpenRead(zi->archiveName);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1134
    BAIL_IF_MACRO(in == NULL, ERR_IO_ERROR, NULL);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1135
    if (!zip_set_open_position(in, &zi->entries[pos]))
55
986740ba58ab Avoids unzLocateFile(), since we already did all the searching ourselves.
Ryan C. Gordon <icculus@icculus.org>
parents: