archivers/zip.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 03 Oct 2018 22:45:05 -0400
branchstable-1.0
changeset 1648 93b4c3bc6b9d
parent 1390 60449ca1b00a
permissions -rw-r--r--
Fixed Win10's GetUserProfileDirectory() bug in stable-1.0 branch.
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>
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
    19
#ifndef _WIN32_WCE
504
3420d82f9b01 Some cleanups for PocketPC port.
Ryan C. Gordon <icculus@icculus.org>
parents: 494
diff changeset
    20
#include <errno.h>
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
    21
#include <time.h>
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
    22
#endif
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
/*
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    30
 * 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
    31
 *  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
    32
 *  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
    33
 *  PHYSFS_read().
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    34
 *
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    35
 * 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
    36
 *  read data directly into the buffer passed to PHYSFS_read().
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    37
 *
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    38
 * 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
    39
 *  value.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    40
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    41
#define ZIP_READBUFSIZE   (16 * 1024)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    42
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
    43
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    44
/*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    45
 * 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
    46
 *  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
    47
 *  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
    48
 *  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
    49
 *  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
    50
 *  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
    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
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
    53
{
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
    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
    55
    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
    56
    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
    57
    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
    58
    ZIP_BROKEN_FILE,
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
    59
    ZIP_BROKEN_SYMLINK
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
    60
} 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
    61
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
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    63
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    64
 * One 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
    65
 */
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
    66
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
    67
{
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
    68
    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
    69
    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
    70
    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
    71
    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
    72
    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
    73
    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
    74
    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
    75
    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
    76
    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
    77
    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
    78
    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
    79
} 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
    80
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    81
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    82
 * One ZIPinfo is kept for each open ZIP archive.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    83
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    84
typedef struct
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    85
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    86
    char *archiveName;        /* path to ZIP in platform-dependent notation. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    87
    PHYSFS_uint16 entryCount; /* Number of files in ZIP.                     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    88
    ZIPentry *entries;        /* info on all files in ZIP.                   */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    89
} ZIPinfo;
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
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    92
 * 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
    93
 */
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
    94
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
    95
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    96
    ZIPentry *entry;                      /* Info on file.              */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    97
    void *handle;                         /* physical file handle.      */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    98
    PHYSFS_uint32 compressed_position;    /* offset in compressed data. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    99
    PHYSFS_uint32 uncompressed_position;  /* tell() position.           */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   100
    PHYSFS_uint8 *buffer;                 /* decompression buffer.      */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   101
    z_stream stream;                      /* zlib stream state.         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   102
} ZIPfileinfo;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   103
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   104
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   105
/* Magic numbers... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   106
#define ZIP_LOCAL_FILE_SIG          0x04034b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   107
#define ZIP_CENTRAL_DIR_SIG         0x02014b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   108
#define ZIP_END_OF_CENTRAL_DIR_SIG  0x06054b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   109
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   110
/* compression methods... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   111
#define COMPMETH_NONE 0
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   112
/* ...and others... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   113
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   114
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   115
#define UNIX_FILETYPE_MASK    0170000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   116
#define UNIX_FILETYPE_SYMLINK 0120000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   117
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   118
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   119
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
   120
                              PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
467
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   121
static PHYSFS_sint64 ZIP_write(FileHandle *handle, const void *buffer,
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   122
                               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
   123
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
   124
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
   125
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
   126
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
   127
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
   128
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
   129
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
   130
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
   131
                                            const char *dirname,
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   132
                                            int omitSymLinks);
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   133
static int ZIP_exists(DirHandle *h, const char *name);
467
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   134
static int ZIP_isDirectory(DirHandle *h, const char *name, int *fileExists);
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   135
static int ZIP_isSymLink(DirHandle *h, const char *name, int *fileExists);
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   136
static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *n, int *e);
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   137
static FileHandle *ZIP_openRead(DirHandle *h, const char *filename, int *e);
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   138
static FileHandle *ZIP_openWrite(DirHandle *h, const char *filename);
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   139
static FileHandle *ZIP_openAppend(DirHandle *h, const char *filename);
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   140
static void ZIP_dirClose(DirHandle *h);
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
   141
static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry);
467
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   142
static int ZIP_remove(DirHandle *h, const char *name);
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   143
static int ZIP_mkdir(DirHandle *h, const char *name);
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
   144
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   145
399
02dd53688315 Changed DirFunctions struct a little.
Ryan C. Gordon <icculus@icculus.org>
parents: 379
diff changeset
   146
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
02dd53688315 Changed DirFunctions struct a little.
Ryan C. Gordon <icculus@icculus.org>
parents: 379
diff changeset
   147
{
02dd53688315 Changed DirFunctions struct a little.
Ryan C. Gordon <icculus@icculus.org>
parents: 379
diff changeset
   148
    "ZIP",
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   149
    ZIP_ARCHIVE_DESCRIPTION,
766
3970811e14f4 Changed my email address.
Ryan C. Gordon <icculus@icculus.org>
parents: 716
diff changeset
   150
    "Ryan C. Gordon <icculus@icculus.org>",
399
02dd53688315 Changed DirFunctions struct a little.
Ryan C. Gordon <icculus@icculus.org>
parents: 379
diff changeset
   151
    "http://icculus.org/physfs/",
02dd53688315 Changed DirFunctions struct a little.
Ryan C. Gordon <icculus@icculus.org>
parents: 379
diff changeset
   152
};
02dd53688315 Changed DirFunctions struct a little.
Ryan C. Gordon <icculus@icculus.org>
parents: 379
diff changeset
   153
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   154
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
   155
{
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   156
    ZIP_read,       /* read() method       */
467
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   157
    ZIP_write,      /* write() method      */
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   158
    ZIP_eof,        /* eof() method        */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   159
    ZIP_tell,       /* tell() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   160
    ZIP_seek,       /* seek() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   161
    ZIP_fileLength, /* fileLength() method */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   162
    ZIP_fileClose   /* fileClose() method  */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   163
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   164
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   165
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   166
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
   167
{
399
02dd53688315 Changed DirFunctions struct a little.
Ryan C. Gordon <icculus@icculus.org>
parents: 379
diff changeset
   168
    &__PHYSFS_ArchiveInfo_ZIP,
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   169
    ZIP_isArchive,          /* isArchive() method      */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   170
    ZIP_openArchive,        /* openArchive() method    */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   171
    ZIP_enumerateFiles,     /* enumerateFiles() method */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   172
    ZIP_exists,             /* exists() method         */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   173
    ZIP_isDirectory,        /* isDirectory() method    */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   174
    ZIP_isSymLink,          /* isSymLink() method      */
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
   175
    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
   176
    ZIP_openRead,           /* openRead() method       */
467
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   177
    ZIP_openWrite,          /* openWrite() method      */
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   178
    ZIP_openAppend,         /* openAppend() method     */
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   179
    ZIP_remove,             /* remove() method         */
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   180
    ZIP_mkdir,              /* mkdir() method          */
93
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   181
    ZIP_dirClose            /* dirClose() method       */
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   182
};
74d1df359be3 Patched to compile with an ancient version of CodeWarrior.
Ryan C. Gordon <icculus@icculus.org>
parents: 71
diff changeset
   183
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
   184
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   185
static const char *zlib_error_string(int rc)
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   186
{
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   187
    switch (rc)
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   188
    {
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   189
        case Z_OK: return(NULL);  /* not an error. */
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   190
        case Z_STREAM_END: return(NULL); /* not an error. */
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   191
#ifndef _WIN32_WCE
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   192
        case Z_ERRNO: return(strerror(errno));
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   193
#endif
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   194
        case Z_NEED_DICT: return(ERR_ZLIB_NEED_DICT);
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   195
        case Z_DATA_ERROR: return(ERR_ZLIB_DATA_ERROR);
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   196
        case Z_MEM_ERROR: return(ERR_ZLIB_MEMORY_ERROR);
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   197
        case Z_BUF_ERROR: return(ERR_ZLIB_BUFFER_ERROR);
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   198
        case Z_VERSION_ERROR: return(ERR_ZLIB_VERSION_ERROR);
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   199
        default: return(ERR_ZLIB_UNKNOWN_ERROR);
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   200
    } /* switch */
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   201
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   202
    return(NULL);
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   203
} /* zlib_error_string */
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   204
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   205
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   206
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   207
 * 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
   208
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   209
static int zlib_err(int rc)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   210
{
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   211
    const char *str = zlib_error_string(rc);
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   212
    if (str != NULL)
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   213
        __PHYSFS_setError(str);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   214
    return(rc);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   215
} /* zlib_err */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   216
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   217
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   218
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   219
 * 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
   220
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   221
static int readui32(void *in, PHYSFS_uint32 *val)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   222
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   223
    PHYSFS_uint32 v;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   224
    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
   225
    *val = PHYSFS_swapULE32(v);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   226
    return(1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   227
} /* readui32 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   228
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   229
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
 * 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
   232
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   233
static int readui16(void *in, PHYSFS_uint16 *val)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   234
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   235
    PHYSFS_uint16 v;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   236
    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
   237
    *val = PHYSFS_swapULE16(v);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   238
    return(1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   239
} /* readui16 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   240
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
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
   243
                              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
   244
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   245
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   246
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   247
    PHYSFS_sint64 retval = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   248
    PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   249
    PHYSFS_sint64 avail = entry->uncompressed_size -
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   250
                          finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   251
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   252
    BAIL_IF_MACRO(maxread == 0, NULL, 0);    /* quick rejection. */
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
    if (avail < maxread)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   255
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   256
        maxread = avail - (avail % objSize);
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   257
        objCount = (PHYSFS_uint32) (maxread / objSize);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   258
        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
   259
        __PHYSFS_setError(ERR_PAST_EOF);   /* this is always true here. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   260
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   261
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   262
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   263
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   264
        retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   265
    } /* if */
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
    else
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
        finfo->stream.next_out = buf;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   270
        finfo->stream.avail_out = objSize * objCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   271
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   272
        while (retval < maxread)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   273
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   274
            PHYSFS_uint32 before = finfo->stream.total_out;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   275
            int rc;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   276
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   277
            if (finfo->stream.avail_in == 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   278
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   279
                PHYSFS_sint64 br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   280
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   281
                br = entry->compressed_size - finfo->compressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   282
                if (br > 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   283
                {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   284
                    if (br > ZIP_READBUFSIZE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   285
                        br = ZIP_READBUFSIZE;
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
                    br = __PHYSFS_platformRead(finfo->handle,
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   288
                                               finfo->buffer,
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   289
                                               1, (PHYSFS_uint32) br);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   290
                    if (br <= 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   291
                        break;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   292
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   293
                    finfo->compressed_position += (PHYSFS_uint32) br;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   294
                    finfo->stream.next_in = finfo->buffer;
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   295
                    finfo->stream.avail_in = (PHYSFS_uint32) br;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   296
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   297
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   298
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   299
            rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   300
            retval += (finfo->stream.total_out - before);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   301
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   302
            if (rc != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   303
                break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   304
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   305
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   306
        retval /= objSize;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   307
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   308
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   309
    if (retval > 0)
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   310
        finfo->uncompressed_position += (PHYSFS_uint32) (retval * objSize);
337
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
    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
   313
} /* ZIP_read */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   314
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   315
467
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   316
static PHYSFS_sint64 ZIP_write(FileHandle *handle, const void *buf,
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   317
                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   318
{
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   319
    BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   320
} /* ZIP_write */
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   321
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   322
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   323
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
   324
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   325
    ZIPfileinfo *finfo = ((ZIPfileinfo *) (handle->opaque));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   326
    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
   327
} /* ZIP_eof */
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
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   330
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
   331
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   332
    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
   333
} /* ZIP_tell */
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 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
   337
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   338
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   339
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   340
    void *in = finfo->handle;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   341
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   342
    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
   343
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   344
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   345
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   346
        PHYSFS_sint64 newpos = offset + entry->offset;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   347
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0);
551
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   348
        finfo->uncompressed_position = (PHYSFS_uint32) offset;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   349
    } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   350
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   351
    else
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   352
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   353
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   354
         * If seeking backwards, we need to redecode the file
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   355
         *  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
   356
         *  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
   357
         *  decode, but we don't rewind first.
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   358
         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   359
        if (offset < finfo->uncompressed_position)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   360
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   361
            /* 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
   362
            z_stream str;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   363
            memset(&str, '\0', sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   364
            if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   365
                return(0);
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   366
345
cbcb27547864 Seeking backwards in ZIP_seek() works now.
Ryan C. Gordon <icculus@icculus.org>
parents: 342
diff changeset
   367
            if (!__PHYSFS_platformSeek(in, entry->offset))
cbcb27547864 Seeking backwards in ZIP_seek() works now.
Ryan C. Gordon <icculus@icculus.org>
parents: 342
diff changeset
   368
                return(0);
cbcb27547864 Seeking backwards in ZIP_seek() works now.
Ryan C. Gordon <icculus@icculus.org>
parents: 342
diff changeset
   369
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   370
            inflateEnd(&finfo->stream);
1390
60449ca1b00a Fix bug with copying z_stream objects around in zip archiver (thanks, Andrei!).
Ryan C. Gordon <icculus@icculus.org>
parents: 1166
diff changeset
   371
            inflateCopy(&finfo->stream, &str);
60449ca1b00a Fix bug with copying z_stream objects around in zip archiver (thanks, Andrei!).
Ryan C. Gordon <icculus@icculus.org>
parents: 1166
diff changeset
   372
            inflateEnd(&str);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   373
            finfo->uncompressed_position = finfo->compressed_position = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   374
        } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   375
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   376
        while (finfo->uncompressed_position != offset)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   377
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   378
            PHYSFS_uint8 buf[512];
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   379
            PHYSFS_uint32 maxread;
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   380
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   381
            maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   382
            if (maxread > sizeof (buf))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   383
                maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   384
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   385
            if (ZIP_read(handle, buf, maxread, 1) != 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   386
                return(0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   387
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   388
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   389
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   390
    return(1);
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   391
} /* ZIP_seek */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   392
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   393
132
b53fa5093749 Added typedefs and platform-specific i/o.
Ryan C. Gordon <icculus@icculus.org>
parents: 95
diff changeset
   394
static PHYSFS_sint64 ZIP_fileLength(FileHandle *handle)
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   395
{
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   396
    ZIPfileinfo *finfo = (ZIPfileinfo *) (handle->opaque);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   397
    return(finfo->entry->uncompressed_size);
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   398
} /* ZIP_fileLength */
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   399
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   400
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   401
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
   402
{
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   403
    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
   404
    BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   405
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   406
    if (finfo->entry->compression_method != COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   407
        inflateEnd(&finfo->stream);
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->buffer != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   410
        free(finfo->buffer);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   411
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   412
    free(finfo);
429
72ca216c756a Patched memory leaks (thanks, Valgrind!)
Ryan C. Gordon <icculus@icculus.org>
parents: 427
diff changeset
   413
    free(handle);
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   414
    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
   415
} /* ZIP_fileClose */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   416
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   417
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
   418
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
   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
    PHYSFS_uint8 buf[256];
413
d669d303317d Initialized some variables to stop compiler whining.
Ryan C. Gordon <icculus@icculus.org>
parents: 402
diff changeset
   421
    PHYSFS_sint32 i = 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   422
    PHYSFS_sint64 filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   423
    PHYSFS_sint64 filepos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   424
    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
   425
    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
   426
    int found = 0;
413
d669d303317d Initialized some variables to stop compiler whining.
Ryan C. Gordon <icculus@icculus.org>
parents: 402
diff changeset
   427
    PHYSFS_uint32 extra = 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   428
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   429
    filelen = __PHYSFS_platformFileLength(in);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   430
    BAIL_IF_MACRO(filelen == -1, NULL, 0);
541
2be2fff14b7a Another attempt at type size correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 540
diff changeset
   431
    BAIL_IF_MACRO(filelen > 0xFFFFFFFF, "ZIP bigger than 2 gigs?!", 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   432
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
     * 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
   435
     *  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
   436
     *  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
   437
     *  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
   438
     *  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
   439
     *  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
   440
     *  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
   441
     *  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
   442
     *  and call it a corrupted zipfile.
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   443
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   444
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   445
    if (sizeof (buf) < filelen)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   446
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   447
        filepos = filelen - sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   448
        maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   449
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   450
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   451
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   452
        filepos = 0;
541
2be2fff14b7a Another attempt at type size correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 540
diff changeset
   453
        maxread = (PHYSFS_uint32) filelen;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   454
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   455
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
   456
    while ((totalread < filelen) && (totalread < 65557))
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   457
    {
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
   458
        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
   459
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
        /* 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
   461
        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
   462
        {
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
            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
   464
                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
   465
            *((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
   466
            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
   467
        } /* 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
   468
        else
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   469
        {
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
   470
            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
   471
                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
   472
            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
   473
        } /* 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
   474
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
        extra = *((PHYSFS_uint32 *) (&buf[0]));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   476
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
   477
        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
   478
        {
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
            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
   480
                (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
   481
                (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
   482
                (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
   483
            {
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
                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
   485
                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
   486
            } /* 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
   487
        } /* 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
   488
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
        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
   490
            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
   491
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
        filepos -= (maxread - 4);
896
0895ab155ef1 Backport from devbranch:
Ryan C. Gordon <icculus@icculus.org>
parents: 766
diff changeset
   493
        if (filepos < 0)
0895ab155ef1 Backport from devbranch:
Ryan C. Gordon <icculus@icculus.org>
parents: 766
diff changeset
   494
            filepos = 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
   495
    } /* 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
   496
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   497
    BAIL_IF_MACRO(!found, ERR_NOT_AN_ARCHIVE, -1);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   498
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   499
    if (len != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   500
        *len = filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   501
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
   502
    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
   503
} /* zip_find_end_of_central_dir */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   504
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   505
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   506
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
   507
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   508
    PHYSFS_uint32 sig;
446
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   509
    int retval = 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   510
    void *in;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   511
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   512
    in = __PHYSFS_platformOpenRead(filename);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   513
    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
   514
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   515
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   516
     * 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
   517
     *  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
   518
     */
446
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   519
    if (readui32(in, &sig))
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   520
    {
446
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   521
        retval = (sig == ZIP_LOCAL_FILE_SIG);
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   522
        if (!retval)
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   523
        {
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   524
            /*
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   525
             * No sig...might be a ZIP with data at the start
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   526
             *  (a self-extracting executable, etc), so we'll have to do
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   527
             *  it the hard way...
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   528
             */
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   529
            retval = (zip_find_end_of_central_dir(in, NULL) != -1);
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   530
        } /* if */
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   531
    } /* if */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   532
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   533
    __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
   534
    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
   535
} /* ZIP_isArchive */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   536
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   537
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
   538
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
   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
    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
   541
    for (i = 0; i < max; i++)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   542
    {
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
   543
        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
   544
        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
   545
            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
   546
    } /* 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
   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
    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
   549
} /* 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
   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
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   552
/*
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   553
 * This will find the ZIPentry associated with a path in platform-independent
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   554
 *  notation. Directories don't have ZIPentries associated with them, but 
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   555
 *  (*isDir) will be set to non-zero if a dir was hit.
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   556
 */
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   557
static ZIPentry *zip_find_entry(ZIPinfo *info, const char *path, int *isDir)
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
   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
    ZIPentry *a = info->entries;
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   560
    PHYSFS_sint32 pathlen = strlen(path);
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   561
    PHYSFS_sint32 lo = 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
   562
    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
   563
    PHYSFS_sint32 middle;
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   564
    const char *thispath = NULL;
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
   565
    int rc;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   566
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
   567
    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
   568
    {
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   569
        middle = lo + ((hi - lo) / 2);
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   570
        thispath = a[middle].name;
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   571
        rc = strncmp(path, thispath, pathlen);
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   572
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   573
        if (rc > 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
   574
            lo = middle + 1;
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   575
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   576
        else if (rc < 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
   577
            hi = middle - 1;
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   578
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   579
        else /* substring match...might be dir or entry or nothing. */
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   580
        {
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   581
            if (isDir != NULL)
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   582
            {
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   583
                *isDir = (thispath[pathlen] == '/');
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   584
                if (*isDir)
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   585
                    return(NULL);
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   586
            } /* if */
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   587
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   588
            if (thispath[pathlen] == '\0') /* found entry? */
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   589
                return(&a[middle]);
1144
a39b2d2f50b9 Backported zip/qpak dir fix from dev branch to stable-1.0.
Ryan C. Gordon <icculus@icculus.org>
parents: 927
diff changeset
   590
            /* adjust search params, try again. */
a39b2d2f50b9 Backported zip/qpak dir fix from dev branch to stable-1.0.
Ryan C. Gordon <icculus@icculus.org>
parents: 927
diff changeset
   591
            else if (thispath[pathlen] > '/')
a39b2d2f50b9 Backported zip/qpak dir fix from dev branch to stable-1.0.
Ryan C. Gordon <icculus@icculus.org>
parents: 927
diff changeset
   592
                hi = middle - 1;
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   593
            else
1144
a39b2d2f50b9 Backported zip/qpak dir fix from dev branch to stable-1.0.
Ryan C. Gordon <icculus@icculus.org>
parents: 927
diff changeset
   594
                lo = middle + 1;
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   595
        } /* if */
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   596
    } /* while */
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   597
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   598
    if (isDir != NULL)
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   599
        *isDir = 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
   600
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
    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
   602
} /* zip_find_entry */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   603
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
   604
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
/* 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
   606
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
   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
    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
   609
    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
   610
    {
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
        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
   612
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   613
            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
   614
                *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
   615
            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
   616
        } /* while */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   617
    } /* 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
   618
} /* zip_convert_dos_path */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   619
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   620
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
   621
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
   622
{
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
   623
    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
   624
    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
   625
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
   626
    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
   627
    {
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
   628
        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
   629
        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
   630
            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
   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 + 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
   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
            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
   635
            {
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
                /* 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
   637
                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
   638
            } /* 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
   639
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
            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
   641
            {
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
                /* 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
   643
                *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
   644
            } /* 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
   645
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
   646
            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
   647
            {
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
                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
   649
                {
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
                    /* 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
   651
                    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
   652
                    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
   653
                    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
   654
                    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   655
                        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
   656
                        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
   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
                            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
   659
                            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
   660
                        } /* 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
   661
                    } /* 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
   662
                } /* 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
   663
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
                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
   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
                    /* 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
   667
                    *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
   668
                } /* 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
   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
        } /* 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
   671
        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
   672
        {
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
            prevptr = ptr;
1166
c3212f7b8a52 Backport from dev branch: infinite loop in zip_expand_symlink_path().
Ryan C. Gordon <icculus@icculus.org>
parents: 1144
diff changeset
   674
            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
   675
        } /* 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
   676
    } /* 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
   677
} /* 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
   678
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   679
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   680
/*
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
   681
 * 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
   682
 *  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
   683
 *  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
   684
 *  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
   685
 *  function.
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   686
 */
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
   687
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
   688
{
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
   689
    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
   690
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
    zip_expand_symlink_path(path);
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   692
    entry = zip_find_entry(info, path, NULL);
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
   693
    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
   694
    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   695
        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
   696
            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
   697
        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
   698
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   699
            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
   700
                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
   701
        } /* 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
   702
    } /* 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
   703
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   704
    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
   705
    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
   706
} /* 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
   707
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   708
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
   709
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
   710
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   711
    char *path;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   712
    PHYSFS_uint32 size = entry->uncompressed_size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   713
    int rc = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   714
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
   715
    /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   716
     * 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
   717
     *  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
   718
     *  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
   719
     */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   720
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   721
    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
   722
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   723
    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
   724
    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
   725
    
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   726
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   727
        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
   728
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   729
    else  /* symlink target path is compressed... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   730
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   731
        z_stream stream;
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   732
        PHYSFS_uint32 compsize = entry->compressed_size;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   733
        PHYSFS_uint8 *compressed = (PHYSFS_uint8 *) malloc(compsize);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   734
        if (compressed != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   735
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   736
            if (__PHYSFS_platformRead(in, compressed, compsize, 1) == 1)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   737
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   738
                memset(&stream, '\0', sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   739
                stream.next_in = compressed;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   740
                stream.avail_in = compsize;
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
   741
                stream.next_out = (unsigned char *) path;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   742
                stream.avail_out = size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   743
                if (zlib_err(inflateInit2(&stream, -MAX_WBITS)) == Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   744
                {
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   745
                    rc = zlib_err(inflate(&stream, Z_FINISH));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   746
                    inflateEnd(&stream);
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   747
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   748
                    /* both are acceptable outcomes... */
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   749
                    rc = ((rc == Z_OK) || (rc == Z_STREAM_END));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   750
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   751
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   752
            free(compressed);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   753
        } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   754
    } /* else */
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   755
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   756
    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
   757
        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
   758
    else
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   759
    {
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
   760
        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
   761
        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
   762
        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
   763
    } /* 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
   764
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(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
   766
} /* 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
   767
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   768
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
/*
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
 * 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
   771
 */
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
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
   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
    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
   775
    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
   776
    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
   777
    PHYSFS_uint16 extralen;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   778
551
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   779
    /*
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   780
     * crc and (un)compressed_size are always zero if this is a "JAR"
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   781
     *  archive created with Sun's Java tools, apparently. We only
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   782
     *  consider this archive corrupted if those entries don't match and
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   783
     *  aren't zero. That seems to work well.
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   784
     */
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   785
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
   786
    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
   787
    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
   788
    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
   789
    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
   790
    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
   791
    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
   792
    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
   793
    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
   794
    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
   795
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
551
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   796
    BAIL_IF_MACRO(ui32 && (ui32 != entry->crc), ERR_CORRUPTED, 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
   797
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
551
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   798
    BAIL_IF_MACRO(ui32 && (ui32 != entry->compressed_size), ERR_CORRUPTED, 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
   799
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
551
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   800
    BAIL_IF_MACRO(ui32 && (ui32 != entry->uncompressed_size),ERR_CORRUPTED,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
   801
    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
   802
    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
   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
    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
   805
    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
   806
} /* 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
   807
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   808
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
   809
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
   810
{
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
    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
   812
    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
   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
    /* 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
   815
    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
   816
    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
   817
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   818
    /* 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
   819
    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
   820
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   821
    /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   822
     * 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
   823
     *  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
   824
     *  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
   825
     *  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
   826
     *  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
   827
     */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   828
    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
   829
    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   830
        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
   831
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   832
        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
   833
        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
   834
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   835
            /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   836
             * 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
   837
             *  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
   838
             *  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
   839
             */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   840
            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
   841
                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
   842
        } /* 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
   843
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   844
        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
   845
            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
   846
        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
   847
            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
   848
    } /* 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
   849
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
    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
   851
} /* 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
   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_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
   855
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   856
    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
   857
    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
   858
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   859
    switch (hosttype)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   860
    {
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   861
            /*
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   862
             * 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
   863
             *  symlinks, according to the Info-ZIP project.
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   864
             */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   865
        case 0:  /* FS_FAT_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   866
        case 1:  /* AMIGA_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   867
        case 2:  /* VMS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   868
        case 4:  /* VM_CSM_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   869
        case 6:  /* FS_HPFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   870
        case 11: /* FS_NTFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   871
        case 14: /* FS_VFAT_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   872
        case 13: /* ACORN_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   873
        case 15: /* MVS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   874
        case 18: /* THEOS_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   875
            break;  /* do nothing. */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   876
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   877
        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
   878
            retval = 1;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   879
            break;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   880
    } /* switch */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   881
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   882
    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
   883
} /* 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
   884
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   885
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
   886
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
   887
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   888
    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
   889
           (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
   890
           (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
   891
} /* 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
   892
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   893
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   894
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
   895
{
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   896
    PHYSFS_uint16 xattr = ((extern_attr >> 16) & 0xFFFF);
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   897
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   898
    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
   899
              (zip_version_does_symlinks(entry->version)) &&
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   900
              (entry->uncompressed_size > 0) &&
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   901
              ((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
   902
           );
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
   903
} /* 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
   904
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   905
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
   906
static 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
   907
{
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   908
#ifdef _WIN32_WCE
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 566
diff changeset
   909
    /* We have no struct tm and no mktime right now.
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 566
diff changeset
   910
       FIXME: This should probably be fixed at some point.
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 566
diff changeset
   911
    */
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   912
    return -1;
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   913
#else
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
   914
    PHYSFS_uint32 dosdate;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   915
    struct tm unixtime;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   916
    memset(&unixtime, '\0', sizeof (unixtime));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   917
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
   918
    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
   919
    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
   920
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   921
    /* 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
   922
    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
   923
    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
   924
    unixtime.tm_mday = ((dosdate     ) & 0x1F);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   925
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
   926
    /* 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
   927
    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
   928
    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
   929
    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
   930
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   931
    /* 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
   932
    unixtime.tm_isdst = -1;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   933
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   934
    return((PHYSFS_sint64) mktime(&unixtime));
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   935
#endif
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
   936
} /* zip_dos_time_to_physfs_time */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   937
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   938
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
   939
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
   940
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   941
    PHYSFS_uint16 fnamelen, extralen, commentlen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   942
    PHYSFS_uint32 external_attr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   943
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   944
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   945
    PHYSFS_sint64 si64;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   946
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   947
    /* sanity check with central directory signature... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   948
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   949
    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
   950
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   951
    /* Get the pertinent parts of the record... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   952
    BAIL_IF_MACRO(!readui16(in, &entry->version), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   953
    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
   954
    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
   955
    BAIL_IF_MACRO(!readui16(in, &entry->compression_method), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   956
    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
   957
    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
   958
    BAIL_IF_MACRO(!readui32(in, &entry->crc), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   959
    BAIL_IF_MACRO(!readui32(in, &entry->compressed_size), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   960
    BAIL_IF_MACRO(!readui32(in, &entry->uncompressed_size), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   961
    BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   962
    BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   963
    BAIL_IF_MACRO(!readui16(in, &commentlen), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   964
    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
   965
    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
   966
    BAIL_IF_MACRO(!readui32(in, &external_attr), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   967
    BAIL_IF_MACRO(!readui32(in, &entry->offset), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   968
    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
   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
    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
   971
    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
   972
                            ZIP_UNRESOLVED_SYMLINK : ZIP_UNRESOLVED_FILE;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   973
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   974
    entry->name = (char *) malloc(fnamelen + 1);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   975
    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
   976
    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
   977
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   978
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   979
    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
   980
    zip_convert_dos_path(entry, entry->name);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   981
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   982
    si64 = __PHYSFS_platformTell(in);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   983
    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
   984
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   985
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   986
        /* 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
   987
    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
   988
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   989
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   990
    return(1);  /* success. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   991
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
   992
zip_load_entry_puked:
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   993
    free(entry->name);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   994
    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
   995
} /* 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
   996
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
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
   998
static int zip_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
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
   999
{
927
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1000
    if (one != two)
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1001
    {
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1002
        const ZIPentry *a = (const ZIPentry *) _a;
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1003
        return(strcmp(a[one].name, a[two].name));
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1004
    } /* if */
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1005
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1006
    return 0;
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
  1007
} /* zip_entry_cmp */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1008
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1009
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
  1010
static void zip_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
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
  1011
{
927
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1012
    if (one != two)
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1013
    {
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1014
        ZIPentry tmp;
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1015
        ZIPentry *first = &(((ZIPentry *) _a)[one]);
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1016
        ZIPentry *second = &(((ZIPentry *) _a)[two]);
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1017
        memcpy(&tmp, first, sizeof (ZIPentry));
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1018
        memcpy(first, second, sizeof (ZIPentry));
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1019
        memcpy(second, &tmp, sizeof (ZIPentry));
8867d6c60ebf Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 896
diff changeset
  1020
    } /* if */
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
  1021
} /* zip_entry_swap */
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
  1022
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
static int zip_load_entries(void *in, DirHandle *dirh,
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1025
                            PHYSFS_uint32 data_ofs, PHYSFS_uint32 central_ofs)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1026
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1027
    ZIPinfo *info = (ZIPinfo *) dirh->opaque;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1028
    PHYSFS_uint32 max = info->entryCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1029
    PHYSFS_uint32 i;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1030
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1031
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, central_ofs), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1032
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
  1033
    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
  1034
    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
  1035
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
    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
  1037
    {
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
  1038
        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
  1039
        {
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
  1040
            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
  1041
            return(0);
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1042
        } /* 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
  1043
    } /* 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
  1044
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
  1045
    __PHYSFS_sort(info->entries, max, zip_entry_cmp, zip_entry_swap);
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
  1046
    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
  1047
} /* 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
  1048
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
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
  1050
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
  1051
                                        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
  1052
                                        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
  1053
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1054
    ZIPinfo *zipinfo = (ZIPinfo *) dirh->opaque;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1055
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1056
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1057
    PHYSFS_sint64 len;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1058
    PHYSFS_sint64 pos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1059
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1060
    /* 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
  1061
    pos = zip_find_end_of_central_dir(in, &len);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1062
    BAIL_IF_MACRO(pos == -1, NULL, 0);
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1063
    BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, pos), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1064
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1065
    /* check signature again, just in case. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1066
    BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1067
    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
  1068
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1069
    /* number of this disk */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1070
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1071
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1072
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1073
    /* number of the disk with the start of the central directory */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1074
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1075
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1076
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1077
    /* total number of entries in the central dir on this disk */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1078
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1079
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1080
    /* total number of entries in the central dir */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1081
    BAIL_IF_MACRO(!readui16(in, &zipinfo->entryCount), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1082
    BAIL_IF_MACRO(ui16 != zipinfo->entryCount, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1083
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1084
    /* size of the central directory */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1085
    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
  1086
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1087
    /* offset of central directory */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1088
    BAIL_IF_MACRO(!readui32(in, central_dir_ofs), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1089
    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
  1090
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
     * 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
  1093
     *  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
  1094
     *  prepended by determining how far the central directory offset is
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1095
     *  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
  1096
     *  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
  1097
     *  data is at the start of the physical file.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1098
     */
541
2be2fff14b7a Another attempt at type size correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 540
diff changeset
  1099
    *data_start = (PHYSFS_uint32) (pos - (*central_dir_ofs + ui32));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1100
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1101
    /* 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
  1102
    *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
  1103
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1104
    /* zipfile comment length */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1105
    BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1106
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
     * 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
  1109
     *  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
  1110
     *  file is corrupted, but we give up either way.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1111
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1112
    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
  1113
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1114
    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
  1115
} /* zip_parse_end_of_central_dir */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1116
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1117
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
d