archivers/zip.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 23 Jul 2002 07:49:13 +0000
changeset 365 3d087cde1252
parent 345 cbcb27547864
child 368 29a96046cf23
permissions -rw-r--r--
My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
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
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    29
/*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    30
 * When sorting the zip entries in an archive, we use a modified QuickSort.
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    31
 *  When there are less then ZIP_QUICKSORT_THRESHOLD entries left to sort,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    32
 *  we switch over to an InsertionSort for the remainder. Tweak to taste.
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    33
 */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    34
#define ZIP_QUICKSORT_THRESHOLD 4
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    35
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    36
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    37
 * 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
    38
 *  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
    39
 *  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
    40
 *  PHYSFS_read().
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
 * 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
    43
 *  read data directly into the buffer passed to PHYSFS_read().
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
 * 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
    46
 *  value.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    47
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    48
#define ZIP_READBUFSIZE   (16 * 1024)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    49
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    50
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    51
/*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    52
 * Entries are "unresolved" until they are first opened. At that time,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    53
 *  local file headers parsed/validated, data offsets will be updated to look
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    54
 *  at the actual file data instead of the header, and symlinks will be
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    55
 *  followed and optimized. This means that we don't seek and read around the
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    56
 *  archive until forced to do so, and after the first time, we had to do
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    57
 *  less reading and parsing, which is very CD-ROM friendly.
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    58
 */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    59
typedef enum
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    60
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    61
    ZIP_UNRESOLVED_FILE,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    62
    ZIP_UNRESOLVED_SYMLINK,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    63
    ZIP_RESOLVING,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    64
    ZIP_RESOLVED,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    65
    ZIP_BROKEN_FILE,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    66
    ZIP_BROKEN_SYMLINK,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    67
} ZipResolveType;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    68
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    69
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    70
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    71
 * 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
    72
 */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    73
typedef struct _ZIPentry
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    74
{
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    75
    char *name;                         /* Name of file in archive        */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    76
    struct _ZIPentry *symlink;          /* NULL or file we symlink to     */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    77
    ZipResolveType resolved;            /* Have we resolved file/symlink? */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    78
    PHYSFS_uint32 offset;               /* offset of data in archive      */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    79
    PHYSFS_uint16 version;              /* version made by                */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    80
    PHYSFS_uint16 version_needed;       /* version needed to extract      */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    81
    PHYSFS_uint16 compression_method;   /* compression method             */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    82
    PHYSFS_uint32 crc;                  /* crc-32                         */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    83
    PHYSFS_uint32 compressed_size;      /* compressed size                */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    84
    PHYSFS_uint32 uncompressed_size;    /* uncompressed size              */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    85
    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
    86
} 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
    87
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    88
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    89
 * One ZIPinfo is kept for each open ZIP archive.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    90
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    91
typedef struct
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    92
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    93
    char *archiveName;        /* path to ZIP in platform-dependent notation. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    94
    PHYSFS_uint16 entryCount; /* Number of files in ZIP.                     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    95
    ZIPentry *entries;        /* info on all files in ZIP.                   */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    96
} ZIPinfo;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    97
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    98
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    99
 * 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
   100
 */
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
   101
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
   102
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   103
    ZIPentry *entry;                      /* Info on file.              */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   104
    void *handle;                         /* physical file handle.      */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   105
    PHYSFS_uint32 compressed_position;    /* offset in compressed data. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   106
    PHYSFS_uint32 uncompressed_position;  /* tell() position.           */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   107
    PHYSFS_uint8 *buffer;                 /* decompression buffer.      */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   108
    z_stream stream;                      /* zlib stream state.         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   109
} ZIPfileinfo;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   110
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   111
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   112
/* Magic numbers... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   113
#define ZIP_LOCAL_FILE_SIG          0x04034b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   114
#define ZIP_CENTRAL_DIR_SIG         0x02014b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   115
#define ZIP_END_OF_CENTRAL_DIR_SIG  0x06054b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   116
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   117
/* compression methods... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   118
#define COMPMETH_NONE 0
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   119
/* ...and others... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   120
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   121
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   122
#define UNIX_FILETYPE_MASK    0170000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   123
#define UNIX_FILETYPE_SYMLINK 0120000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   124
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   125
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   126
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
   127
                              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
   128
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
   129
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
   130
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
   131
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
   132
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
   133
static int ZIP_isArchive(const char *filename, int forWriting);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   134
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
   135
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
   136
                                            const char *dirname,
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   137
                                            int omitSymLinks);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   138
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
   139
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
   140
static int ZIP_isSymLink(DirHandle *h, const char *name);
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
   141
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
   142
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
   143
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
   144
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   145
static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   146
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   147
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   148
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
   149
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   150
    ZIP_read,       /* read() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   151
    NULL,           /* write() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   152
    ZIP_eof,        /* eof() method        */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   153
    ZIP_tell,       /* tell() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   154
    ZIP_seek,       /* seek() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   155
    ZIP_fileLength, /* fileLength() method */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   156
    ZIP_fileClose   /* fileClose() method  */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   157
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   158
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   159
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   160
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
   161
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   162
    ZIP_isArchive,          /* isArchive() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   163
    ZIP_openArchive,        /* openArchive() method    */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   164
    ZIP_enumerateFiles,     /* enumerateFiles() method */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   165
    ZIP_exists,             /* exists() method         */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   166
    ZIP_isDirectory,        /* isDirectory() method    */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   167
    ZIP_isSymLink,          /* isSymLink() method      */
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
   168
    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
   169
    ZIP_openRead,           /* openRead() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   170
    NULL,                   /* openWrite() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   171
    NULL,                   /* openAppend() method     */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   172
    NULL,                   /* remove() method         */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   173
    NULL,                   /* mkdir() method          */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   174
    ZIP_dirClose            /* dirClose() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   175
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   176
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   177
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
   178
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   179
    "ZIP",
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   180
    "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
   181
    "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
   182
    "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
   183
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   184
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
   185
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
   186
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   187
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   188
 * 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
   189
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   190
static int zlib_err(int rc)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   191
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   192
    const char *err = NULL;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   193
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   194
    switch (rc)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   195
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   196
        case Z_OK:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   197
        case Z_STREAM_END:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   198
            break;   /* not errors. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   199
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   200
        case Z_ERRNO:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   201
            err = strerror(errno);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   202
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   203
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   204
        case Z_NEED_DICT:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   205
            err = "zlib: need dictionary";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   206
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   207
        case Z_DATA_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   208
            err = "zlib: need dictionary";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   209
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   210
        case Z_MEM_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   211
            err = "zlib: memory error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   212
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   213
        case Z_BUF_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   214
            err = "zlib: buffer error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   215
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   216
        case Z_VERSION_ERROR:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   217
            err = "zlib: version error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   218
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   219
        default:
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   220
            err = "unknown zlib error";
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   221
            break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   222
    } /* switch */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   223
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   224
    if (err != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   225
        __PHYSFS_setError(err);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   226
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   227
    return(rc);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   228
} /* zlib_err */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   229
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
 * 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
   233
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   234
static int readui32(void *in, PHYSFS_uint32 *val)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   235
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   236
    PHYSFS_uint32 v;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   237
    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
   238
    *val = PHYSFS_swapULE32(v);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   239
    return(1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   240
} /* readui32 */
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
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
 * 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
   245
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   246
static int readui16(void *in, PHYSFS_uint16 *val)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   247
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   248
    PHYSFS_uint16 v;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   249
    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
   250
    *val = PHYSFS_swapULE16(v);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   251
    return(1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   252
} /* readui16 */
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
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   255
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
   256
                              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
   257
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   258
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   259
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   260
    PHYSFS_sint64 retval = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   261
    PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   262
    PHYSFS_sint64 avail = entry->uncompressed_size -
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   263
                          finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   264
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   265
    BAIL_IF_MACRO(maxread == 0, NULL, 0);    /* quick rejection. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   266
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   267
    if (avail < maxread)
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
        maxread = avail - (avail % objSize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   270
        objCount = maxread / objSize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   271
        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
   272
        __PHYSFS_setError(ERR_PAST_EOF);   /* this is always true here. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   273
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   274
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   275
    if (entry->compression_method == COMPMETH_NONE)
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
        retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   278
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   279
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   280
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   281
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   282
        finfo->stream.next_out = buf;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   283
        finfo->stream.avail_out = objSize * objCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   284
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   285
        while (retval < maxread)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   286
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   287
            PHYSFS_uint32 before = finfo->stream.total_out;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   288
            int rc;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   289
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   290
            if (finfo->stream.avail_in == 0)
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
                PHYSFS_sint64 br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   293
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   294
                br = entry->compressed_size - finfo->compressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   295
                if (br > 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   296
                {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   297
                    if (br > ZIP_READBUFSIZE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   298
                        br = ZIP_READBUFSIZE;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   299
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   300
                    br = __PHYSFS_platformRead(finfo->handle,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   301
                                               finfo->buffer,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   302
                                               1, br);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   303
                    if (br <= 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   304
                        break;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   305
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   306
                    finfo->compressed_position += br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   307
                    finfo->stream.next_in = finfo->buffer;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   308
                    finfo->stream.avail_in = br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   309
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   310
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   311
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   312
            rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   313
            retval += (finfo->stream.total_out - before);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   314
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   315
            if (rc != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   316
                break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   317
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   318
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   319
        retval /= objSize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   320
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   321
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   322
    if (retval > 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   323
        finfo->uncompressed_position += (retval * objSize);
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
    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
   326
} /* ZIP_read */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   327
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   328
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   329
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
   330
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   331
    ZIPfileinfo *finfo = ((ZIPfileinfo *) (handle->opaque));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   332
    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
   333
} /* ZIP_eof */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   334
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   335
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   336
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
   337
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   338
    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
   339
} /* ZIP_tell */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   340
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   341
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   342
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
   343
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   344
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   345
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   346
    void *in = finfo->handle;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   347
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   348
    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
   349
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   350
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   351
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   352
        PHYSFS_sint64 newpos = offset + entry->offset;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   353
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   354
        finfo->uncompressed_position = newpos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   355
    } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   356
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   357
    else
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   358
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   359
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   360
         * If seeking backwards, we need to redecode the file
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   361
         *  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
   362
         *  the offset we need. If seeking forward, we still need to
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   363
         *  decode, but we don't rewind first.
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   364
         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   365
        if (offset < finfo->uncompressed_position)
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
            /* 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
   368
            z_stream str;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   369
            memset(&str, '\0', sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   370
            if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   371
                return(0);
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   372
345
cbcb27547864 Seeking backwards in ZIP_seek() works now.
Ryan C. Gordon <icculus@icculus.org>
parents: 342
diff changeset
   373
            if (!__PHYSFS_platformSeek(in, entry->offset))
cbcb27547864 Seeking backwards in ZIP_seek() works now.
Ryan C. Gordon <icculus@icculus.org>
parents: 342
diff changeset
   374
                return(0);
cbcb27547864 Seeking backwards in ZIP_seek() works now.
Ryan C. Gordon <icculus@icculus.org>
parents: 342
diff changeset
   375
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   376
            inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   377
            memcpy(&finfo->stream, &str, sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   378
            finfo->uncompressed_position = finfo->compressed_position = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   379
        } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   380
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   381
        while (finfo->uncompressed_position != offset)
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
            PHYSFS_uint8 buf[512];
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   384
            PHYSFS_uint32 maxread = offset - finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   385
            if (maxread > sizeof (buf))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   386
                maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   387
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   388
            if (ZIP_read(handle, buf, maxread, 1) != 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   389
                return(0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   390
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   391
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   392
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   393
    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
   394
} /* ZIP_seek */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   395
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   396
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   397
static PHYSFS_sint64 ZIP_fileLength(FileHandle *handle)
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   398
{
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   399
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   400
    return(finfo->entry->uncompressed_size);
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   401
} /* ZIP_fileLength */
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   402
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   403
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   404
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
   405
{
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   406
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   407
    BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
337
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
    if (finfo->entry->compression_method != COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   410
        inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   411
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   412
    if (finfo->buffer != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   413
        free(finfo->buffer);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   414
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   415
    free(finfo);
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   416
    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
   417
} /* ZIP_fileClose */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   418
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   419
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   420
static PHYSFS_sint64 zip_find_end_of_central_dir(void *in, PHYSFS_sint64 *len)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   421
{
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   422
    PHYSFS_uint8 buf[256];
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   423
    PHYSFS_sint32 i;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   424
    PHYSFS_sint64 filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   425
    PHYSFS_sint64 filepos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   426
    PHYSFS_sint32 maxread;
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   427
    PHYSFS_sint32 totalread = 0;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   428
    int found = 0;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   429
    PHYSFS_uint32 extra;
337
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
    filelen = __PHYSFS_platformFileLength(in);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   432
    BAIL_IF_MACRO(filelen == -1, NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   433
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
     * 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
   436
     *  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
   437
     *  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
   438
     *  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
   439
     *  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
   440
     *  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
   441
     *  right place. The comment length field is 16 bits, so we can stop
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   442
     *  searching for that signature after a little more than 64k at most,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   443
     *  and call it a corrupted zipfile.
337
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
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   446
    if (sizeof (buf) < filelen)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   447
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   448
        filepos = filelen - sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   449
        maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   450
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   451
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   452
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   453
        filepos = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   454
        maxread = filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   455
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   456
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   457
    while ((totalread < filelen) && (totalread < 65557))
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   458
    {
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   459
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, filepos), NULL, -1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   460
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   461
        /* make sure we catch a signature between buffers. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   462
        if (totalread != 0)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   463
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   464
            if (__PHYSFS_platformRead(in, buf, maxread - 4, 1) != 1)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   465
                return(-1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   466
            *((PHYSFS_uint32 *) (&buf[maxread - 4])) = extra;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   467
            totalread += maxread - 4;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   468
        } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   469
        else
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   470
        {
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   471
            if (__PHYSFS_platformRead(in, buf, maxread, 1) != 1)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   472
                return(-1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   473
            totalread += maxread;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   474
        } /* else */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   475
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   476
        extra = *((PHYSFS_uint32 *) (&buf[0]));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   477
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   478
        for (i = maxread - 4; i > 0; i--)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   479
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   480
            if ((buf[i + 0] == 0x50) &&
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   481
                (buf[i + 1] == 0x4B) &&
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   482
                (buf[i + 2] == 0x05) &&
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   483
                (buf[i + 3] == 0x06) )
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   484
            {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   485
                found = 1;  /* that's the signature! */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   486
                break;  
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   487
            } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   488
        } /* for */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   489
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   490
        if (found)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   491
            break;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   492
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   493
        filepos -= (maxread - 4);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   494
    } /* while */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   495
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   496
    BAIL_IF_MACRO(!found, ERR_NOT_AN_ARCHIVE, -1);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   497
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   498
    if (len != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   499
        *len = filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   500
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   501
    return(filepos + i);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   502
} /* zip_find_end_of_central_dir */
337
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
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   505
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
   506
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   507
    PHYSFS_uint32 sig;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   508
    int retval;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   509
    void *in;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   510
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   511
    in = __PHYSFS_platformOpenRead(filename);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   512
    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
   513
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   514
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   515
     * 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
   516
     *  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
   517
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   518
    BAIL_IF_MACRO(!readui32(in, &sig), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   519
    retval = (sig == ZIP_LOCAL_FILE_SIG);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   520
    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
   521
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   522
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   523
         * 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
   524
         *  (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
   525
         *  it the hard way...
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   526
         */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   527
        retval = (zip_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
   528
    } /* if */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   529
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   530
    __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
   531
    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
   532
} /* ZIP_isArchive */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   533
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   534
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   535
static void zip_free_entries(ZIPentry *entries, PHYSFS_uint32 max)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   536
{
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   537
    PHYSFS_uint32 i;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   538
    for (i = 0; i < max; i++)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   539
    {
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   540
        ZIPentry *entry = &entries[i];
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   541
        if (entry->name != NULL)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   542
            free(entry->name);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   543
    } /* for */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   544
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   545
    free(entries);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   546
} /* zip_free_entries */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   547
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   548
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   549
static ZIPentry *zip_find_entry(ZIPinfo *info, const char *path)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   550
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   551
    ZIPentry *a = info->entries;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   552
    PHYSFS_sint32 lo = 0;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   553
    PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   554
    PHYSFS_sint32 middle;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   555
    int rc;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   556
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   557
    while (lo <= hi)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   558
    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   559
        middle = lo + ((hi - lo) / 2);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   560
        rc = strcmp(path, a[middle].name);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   561
        if (rc == 0)  /* found it! */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   562
            return(&a[middle]);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   563
        else if (rc > 0)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   564
            lo = middle + 1;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   565
        else
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   566
            hi = middle - 1;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   567
    } /* while */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   568
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   569
    BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   570
} /* zip_find_entry */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   571
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   572
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   573
/* Convert paths from old, buggy DOS zippers... */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   574
static void zip_convert_dos_path(ZIPentry *entry, char *path)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   575
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   576
    PHYSFS_uint8 hosttype = (PHYSFS_uint8) ((entry->version >> 8) & 0xFF);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   577
    if (hosttype == 0)  /* FS_FAT_ */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   578
    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   579
        while (*path)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   580
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   581
            if (*path == '\\')
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   582
                *path = '/';
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   583
            path++;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   584
        } /* while */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   585
    } /* if */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   586
} /* zip_convert_dos_path */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   587
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   588
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   589
static void zip_expand_symlink_path(char *path)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   590
{
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   591
    char *ptr = path;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   592
    char *prevptr = path;
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
   593
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   594
    while (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
   595
    {
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   596
        ptr = strchr(ptr, '/');
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   597
        if (ptr == NULL)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   598
            break;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   599
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   600
        if (*(ptr + 1) == '.')
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   601
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   602
            if (*(ptr + 2) == '/')
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   603
            {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   604
                /* current dir in middle of string: ditch it. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   605
                memmove(ptr, ptr + 2, strlen(ptr + 2) + 1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   606
            } /* else if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   607
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   608
            else if (*(ptr + 2) == '\0')
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   609
            {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   610
                /* current dir at end of string: ditch it. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   611
                *ptr = '\0';
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   612
            } /* else 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
   613
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   614
            else if (*(ptr + 2) == '.')
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   615
            {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   616
                if (*(ptr + 3) == '/')
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   617
                {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   618
                    /* parent dir in middle: move back one, if possible. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   619
                    memmove(prevptr, ptr + 4, strlen(ptr + 4) + 1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   620
                    ptr = prevptr;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   621
                    while (prevptr != path)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   622
                    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   623
                        prevptr--;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   624
                        if (*prevptr == '/')
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   625
                        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   626
                            prevptr++;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   627
                            break;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   628
                        } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   629
                    } /* while */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   630
                } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   631
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   632
                if (*(ptr + 3) == '\0')
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   633
                {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   634
                    /* parent dir at end: move back one, if possible. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   635
                    *prevptr = '\0';
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   636
                } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   637
            } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   638
        } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   639
        else
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   640
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   641
            prevptr = ptr;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   642
        } /* else */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   643
    } /* while */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   644
} /* zip_expand_symlink_path */
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
   645
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   646
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   647
/*
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   648
 * Look for the entry named by (path). If it exists, resolve it, and return
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   649
 *  a pointer to that entry. If it's another symlink, keep resolving until you
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   650
 *  hit a real file and then return a pointer to the final non-symlink entry.
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   651
 *  If there's a problem, return NULL. (path) is always free()'d by this
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   652
 *  function.
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   653
 */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   654
static ZIPentry *zip_follow_symlink(void *in, ZIPinfo *info, char *path)
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
   655
{
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   656
    ZIPentry *entry;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   657
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   658
    zip_expand_symlink_path(path);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   659
    entry = zip_find_entry(info, path);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   660
    if (entry != NULL)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   661
    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   662
        if (!zip_resolve(in, info, entry))  /* recursive! */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   663
            entry = NULL;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   664
        else
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   665
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   666
            if (entry->symlink != NULL)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   667
                entry = entry->symlink;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   668
        } /* else */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   669
    } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   670
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   671
    free(path);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   672
    return(entry);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   673
} /* zip_follow_symlink */
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   674
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   675
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   676
static int zip_resolve_symlink(void *in, ZIPinfo *info, ZIPentry *entry)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   677
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   678
    char *path;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   679
    PHYSFS_uint32 size = entry->uncompressed_size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   680
    int rc = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   681
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   682
    /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   683
     * We've already parsed the local file header of the symlink at this
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   684
     *  point. Now we need to read the actual link from the file data and
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   685
     *  follow it.
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   686
     */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   687
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   688
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, entry->offset), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   689
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   690
    path = (char *) malloc(size + 1);
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   691
    BAIL_IF_MACRO(path == NULL, ERR_OUT_OF_MEMORY, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   692
    
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   693
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   694
        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
   695
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   696
    else  /* symlink target path is compressed... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   697
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   698
        z_stream stream;
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   699
        PHYSFS_uint32 compsize = entry->compressed_size;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   700
        PHYSFS_uint8 *compressed = (PHYSFS_uint8 *) malloc(compsize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   701
        if (compressed != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   702
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   703
            if (__PHYSFS_platformRead(in, compressed, compsize, 1) == 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   704
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   705
                memset(&stream, '\0', sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   706
                stream.next_in = compressed;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   707
                stream.avail_in = compsize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   708
                stream.next_out = path;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   709
                stream.avail_out = size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   710
                if (zlib_err(inflateInit2(&stream, -MAX_WBITS)) == Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   711
                {
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   712
                    rc = zlib_err(inflate(&stream, Z_FINISH));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   713
                    inflateEnd(&stream);
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   714
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   715
                    /* both are acceptable outcomes... */
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   716
                    rc = ((rc == Z_OK) || (rc == Z_STREAM_END));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   717
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   718
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   719
            free(compressed);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   720
        } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   721
    } /* else */
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   722
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   723
    if (!rc)
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   724
        free(path);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   725
    else
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   726
    {
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   727
        path[entry->uncompressed_size] = '\0';    /* null-terminate it. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   728
        zip_convert_dos_path(entry, path);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   729
        entry->symlink = zip_follow_symlink(in, info, path);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   730
    } /* else */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   731
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   732
    return(entry->symlink != NULL);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   733
} /* zip_resolve_symlink */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   734
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   735
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   736
/*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   737
 * Parse the local file header of an entry, and update entry->offset.
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   738
 */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   739
static int zip_parse_local(void *in, ZIPentry *entry)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   740
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   741
    PHYSFS_uint32 ui32;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   742
    PHYSFS_uint16 ui16;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   743
    PHYSFS_uint16 fnamelen;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   744
    PHYSFS_uint16 extralen;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   745
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   746
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, entry->offset), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   747
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   748
    BAIL_IF_MACRO(ui32 != ZIP_LOCAL_FILE_SIG, ERR_CORRUPTED, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   749
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   750
    BAIL_IF_MACRO(ui16 != entry->version_needed, ERR_CORRUPTED, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   751
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);  /* general bits. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   752
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   753
    BAIL_IF_MACRO(ui16 != entry->compression_method, ERR_CORRUPTED, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   754
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);  /* date/time */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   755
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   756
    BAIL_IF_MACRO(ui32 != entry->crc, ERR_CORRUPTED, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   757
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   758
    BAIL_IF_MACRO(ui32 != entry->compressed_size, ERR_CORRUPTED, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   759
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   760
    BAIL_IF_MACRO(ui32 != entry->uncompressed_size, ERR_CORRUPTED, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   761
    BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   762
    BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   763
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   764
    entry->offset += fnamelen + extralen + 30;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   765
    return(1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   766
} /* zip_parse_local */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   767
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   768
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   769
static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   770
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   771
    int retval = 1;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   772
    ZipResolveType resolve_type = entry->resolved;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   773
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   774
    /* Don't bother if we've failed to resolve this entry before. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   775
    BAIL_IF_MACRO(resolve_type == ZIP_BROKEN_FILE, ERR_CORRUPTED, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   776
    BAIL_IF_MACRO(resolve_type == ZIP_BROKEN_SYMLINK, ERR_CORRUPTED, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   777
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   778
    /* uhoh...infinite symlink loop! */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   779
    BAIL_IF_MACRO(resolve_type == ZIP_RESOLVING, ERR_SYMLINK_LOOP, 0);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   780
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   781
    /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   782
     * We fix up the offset to point to the actual data on the
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   783
     *  first open, since we don't want to seek across the whole file on
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   784
     *  archive open (can be SLOW on large, CD-stored files), but we
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   785
     *  need to check the local file header...not just for corruption,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   786
     *  but since it stores offset info the central directory does not.
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   787
     */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   788
    if (resolve_type != ZIP_RESOLVED)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   789
    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   790
        entry->resolved = ZIP_RESOLVING;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   791
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   792
        retval = zip_parse_local(in, entry);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   793
        if (retval)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   794
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   795
            /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   796
             * If it's a symlink, find the original file. This will cause
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   797
             *  resolution of other entries (other symlinks and, eventually,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   798
             *  the real file) if all goes well.
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   799
             */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   800
            if (resolve_type == ZIP_UNRESOLVED_SYMLINK)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   801
                retval = zip_resolve_symlink(in, info, entry);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   802
        } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   803
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   804
        if (resolve_type == ZIP_UNRESOLVED_SYMLINK)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   805
            entry->resolved = ((retval) ? ZIP_RESOLVED : ZIP_BROKEN_SYMLINK);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   806
        else if (resolve_type == ZIP_UNRESOLVED_FILE)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   807
            entry->resolved = ((retval) ? ZIP_RESOLVED : ZIP_BROKEN_FILE);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   808
    } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   809
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   810
    return(retval);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   811
} /* zip_resolve */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   812
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   813
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   814
static int zip_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
   815
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   816
    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
   817
    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
   818
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   819
    switch (hosttype)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   820
    {
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   821
            /*
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   822
             * These are the platforms that can NOT build an archive with
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   823
             *  symlinks, according to the Info-ZIP project.
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   824
             */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   825
        case 0:  /* FS_FAT_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   826
        case 1:  /* AMIGA_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   827
        case 2:  /* VMS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   828
        case 4:  /* VM_CSM_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   829
        case 6:  /* FS_HPFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   830
        case 11: /* FS_NTFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   831
        case 14: /* FS_VFAT_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   832
        case 13: /* ACORN_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   833
        case 15: /* MVS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   834
        case 18: /* THEOS_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   835
            break;  /* do nothing. */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   836
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   837
        default:  /* assume the rest to be unix-like. */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   838
            retval = 1;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   839
            break;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   840
    } /* switch */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   841
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   842
    return(retval);
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   843
} /* zip_version_does_symlinks */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   844
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   845
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   846
static int zip_entry_is_symlink(ZIPentry *entry)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   847
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   848
    return((entry->resolved == ZIP_UNRESOLVED_SYMLINK) ||
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   849
           (entry->resolved == ZIP_BROKEN_SYMLINK) ||
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   850
           (entry->symlink));
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   851
} /* zip_entry_is_symlink */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   852
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   853
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   854
static int zip_has_symlink_attr(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
   855
{
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   856
    PHYSFS_uint16 xattr = ((extern_attr >> 16) & 0xFFFF);
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   857
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   858
    return (
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   859
              (zip_version_does_symlinks(entry->version)) &&
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   860
              (entry->uncompressed_size > 0) &&
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   861
              ((xattr & UNIX_FILETYPE_MASK) == UNIX_FILETYPE_SYMLINK)
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   862
           );
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   863
} /* zip_has_symlink_attr */
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   864
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   865
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   866
PHYSFS_sint64 zip_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
   867
{
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   868
    PHYSFS_uint32 dosdate;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   869
    struct tm unixtime;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   870
    memset(&unixtime, '\0', sizeof (unixtime));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   871
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   872
    dosdate = (PHYSFS_uint32) ((dostime >> 16) & 0xFFFF);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   873
    dostime &= 0xFFFF;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   874
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   875
    /* dissect date */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   876
    unixtime.tm_year = ((dosdate >> 9) & 0x7F) + 80;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   877
    unixtime.tm_mon  = ((dosdate >> 5) & 0x0F) - 1;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   878
    unixtime.tm_mday = ((dosdate     ) & 0x1F);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   879
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   880
    /* dissect time */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   881
    unixtime.tm_hour = ((dostime >> 11) & 0x1F);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   882
    unixtime.tm_min  = ((dostime >>  5) & 0x3F);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   883
    unixtime.tm_sec  = ((dostime <<  1) & 0x3E);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   884
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   885
    /* let mktime calculate daylight savings time. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   886
    unixtime.tm_isdst = -1;
337
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
    return((PHYSFS_sint64) mktime(&unixtime));
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   889
} /* zip_dos_time_to_physfs_time */
337
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
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   892
static int zip_load_entry(void *in, ZIPentry *entry, PHYSFS_uint32 ofs_fixup)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   893
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   894
    PHYSFS_uint16 fnamelen, extralen, commentlen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   895
    PHYSFS_uint32 external_attr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   896
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   897
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   898
    PHYSFS_sint64 si64;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   899
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   900
    /* sanity check with central directory signature... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   901
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   902
    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
   903
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   904
    /* Get the pertinent parts of the record... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   905
    BAIL_IF_MACRO(!readui16(in, &entry->version), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   906
    BAIL_IF_MACRO(!readui16(in, &entry->version_needed), NULL, 0);
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   907
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);  /* general bits */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   908
    BAIL_IF_MACRO(!readui16(in, &entry->compression_method), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   909
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   910
    entry->last_mod_time = zip_dos_time_to_physfs_time(ui32);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   911
    BAIL_IF_MACRO(!readui32(in, &entry->crc), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   912
    BAIL_IF_MACRO(!readui32(in, &entry->compressed_size), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   913
    BAIL_IF_MACRO(!readui32(in, &entry->uncompressed_size), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   914
    BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   915
    BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   916
    BAIL_IF_MACRO(!readui16(in, &commentlen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   917
    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
   918
    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
   919
    BAIL_IF_MACRO(!readui32(in, &external_attr), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   920
    BAIL_IF_MACRO(!readui32(in, &entry->offset), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   921
    entry->offset += ofs_fixup;
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   922
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   923
    entry->symlink = NULL;  /* will be resolved later, if necessary. */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   924
    entry->resolved = (zip_has_symlink_attr(entry, external_attr)) ?
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   925
                            ZIP_UNRESOLVED_SYMLINK : ZIP_UNRESOLVED_FILE;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   926
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   927
    entry->name = (char *) malloc(fnamelen + 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   928
    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
   929
    if (__PHYSFS_platformRead(in, entry->name, fnamelen, 1) != 1)
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   930
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   931
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   932
    entry->name[fnamelen] = '\0';  /* null-terminate the filename. */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   933
    zip_convert_dos_path(entry, entry->name);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   934
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   935
    si64 = __PHYSFS_platformTell(in);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   936
    if (si64 == -1)
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   937
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   938
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   939
        /* 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
   940
    if (!__PHYSFS_platformSeek(in, si64 + extralen + commentlen))
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   941
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   942
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   943
    return(1);  /* success. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   944
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   945
zip_load_entry_puked:
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   946
    free(entry->name);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   947
    return(0);  /* failure. */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   948
} /* zip_load_entry */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   949
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   950
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   951
static void zip_entry_swap(ZIPentry *a, PHYSFS_uint32 one, PHYSFS_uint32 two)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   952
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   953
    ZIPentry tmp;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   954
    memcpy(&tmp, &a[one], sizeof (ZIPentry));
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   955
    memcpy(&a[one], &a[two], sizeof (ZIPentry));
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   956
    memcpy(&a[two], &tmp, sizeof (ZIPentry));
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   957
} /* zip_entry_swap */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   958
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   959
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   960
static void zip_quick_sort(ZIPentry *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   961
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   962
    PHYSFS_uint32 i;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   963
    PHYSFS_uint32 j;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   964
    ZIPentry *v;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   965
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   966
	if ((hi - lo) > ZIP_QUICKSORT_THRESHOLD)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   967
	{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   968
		i = (hi + lo) / 2;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   969
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   970
		if (strcmp(a[lo].name, a[i].name) > 0) zip_entry_swap(a, lo, i);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   971
		if (strcmp(a[lo].name, a[hi].name) > 0) zip_entry_swap(a, lo, hi);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   972
		if (strcmp(a[i].name, a[hi].name) > 0) zip_entry_swap(a, i, hi);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   973
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   974
		j = hi - 1;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   975
		zip_entry_swap(a, i, j);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   976
		i = lo;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   977
		v = &a[j];
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   978
		while (1)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   979
		{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   980
			while(strcmp(a[++i].name, v->name) < 0) {}
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   981
			while(strcmp(a[--j].name, v->name) > 0) {}
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   982
			if (j < i)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   983
                break;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   984
			zip_entry_swap(a, i, j);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   985
		} /* while */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   986
		zip_entry_swap(a, i, hi-1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   987
		zip_quick_sort(a, lo, j);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   988
		zip_quick_sort(a, i+1, hi);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   989
	} /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   990
} /* zip_quick_sort */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   991
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   992
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   993
static void zip_insertion_sort(ZIPentry *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   994
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   995
    PHYSFS_uint32 i;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   996
    PHYSFS_uint32 j;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   997
    ZIPentry tmp;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   998
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   999
    for (i = lo + 1; i <= hi; i++)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1000
    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1001
        memcpy(&tmp, &a[i], sizeof (ZIPentry));
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1002
        j = i;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1003
        while ((j > lo) && (strcmp(a[j - 1].name, tmp.name) > 0))
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1004
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1005
            memcpy(&a[j], &a[j - 1], sizeof (ZIPentry));
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1006
            j--;
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1007
        } /* while */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1008
        memcpy(&a[j], &tmp, sizeof (ZIPentry));
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1009
    } /* for */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1010
} /* zip_insertion_sort */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1011
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1012
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1013
static void zip_sort_entries(ZIPentry *entries, PHYSFS_uint32 max)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1014
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1015
    /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1016
     * Fast Quicksort algorithm inspired by code from here:
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1017
     *   http://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1018
     */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1019
    if (max <= ZIP_QUICKSORT_THRESHOLD)
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1020
        zip_quick_sort(entries, 0, max - 1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1021
	zip_insertion_sort(entries, 0, max - 1);
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1022
} /* zip_sort_entries */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1023
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1024
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1025
static int zip_load_entries(void *in, DirHandle *dirh,
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1026
                            PHYSFS_uint32 data_ofs, PHYSFS_uint32 central_ofs)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1027
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1028
    ZIPinfo *info = (ZIPinfo *) dirh->opaque;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1029
    PHYSFS_uint32 max = info->entryCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1030
    PHYSFS_uint32 i;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1031
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1032
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, central_ofs), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1033
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
  1034
    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
  1035
    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
  1036
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1037
    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
  1038
    {
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1039
        if (!zip_load_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
  1040
        {
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1041
            zip_free_entries(info->entries, 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
  1042
            return(0);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1043
        } /* 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
  1044
    } /* 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
  1045
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1046
    zip_sort_entries(info->entries, max);
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
  1047
    return(1);
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1048
} /* zip_load_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
  1049
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
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1051
static int zip_parse_end_of_central_dir(void *in, DirHandle *dirh,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1052
                                        PHYSFS_uint32 *data_start,
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1053
                                        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
  1054
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1055
    ZIPinfo *zipinfo = (ZIPinfo *) dirh->opaque;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1056
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1057
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1058
    PHYSFS_sint64 len;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1059
    PHYSFS_sint64 pos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1060
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1061
    /* find the end-of-central-dir record, and seek to it. */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1062
    pos = zip_find_end_of_central_dir(in, &len);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1063
    BAIL_IF_MACRO(pos == -1, NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1064
	BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, pos), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1065
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1066
    /* check signature again, just in case. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1067
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1068
    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
  1069
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1070
	/* number of this disk */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1071
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1072
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1073
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1074
	/* 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
  1075
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1076
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1077
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1078
	/* 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
  1079
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1080
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1081
	/* total number of entries in the central dir */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1082
    BAIL_IF_MACRO(!readui16(in, &zipinfo->entryCount), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1083
    BAIL_IF_MACRO(ui16 != zipinfo->entryCount, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1084
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1085
	/* size of the central directory */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1086
    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
  1087
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1088
	/* offset of central directory */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1089
    BAIL_IF_MACRO(!readui32(in, central_dir_ofs), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1090
    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
  1091
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1092
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1093
     * 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
  1094
     *  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
  1095
     *  prepended by determining how far the central directory offset is
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1096
     *  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
  1097
     *  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
  1098
     *  data is at the start of the physical file.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1099
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1100
	*data_start = pos - (*central_dir_ofs + ui32);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1101
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1102
    /* 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
  1103
    *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
  1104
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1105
	/* zipfile comment length */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1106
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1107
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1108
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1109
     * 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
  1110
     *  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
  1111
     *  file is corrupted, but we give up either way.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1112
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1113
    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
  1114
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1115
    return(1);  /* made it. */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1116
} /* zip_parse_end_of_central_dir */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1117
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1118
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1119
static DirHandle *zip_allocate_dirhandle(const char *name)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1120
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1121
    char *ptr;
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1122
    ZIPinfo *info;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1123
    DirHandle *retval = malloc(sizeof (DirHandle));
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus&#