src/archiver_zip.c
author Ryan C. Gordon <icculus@icculus.org>
Fri, 09 Mar 2012 04:50:27 -0500
changeset 1203 55f147714ce2
parent 1162 49950eab0ef8
child 1206 3b27dbea4e1a
permissions -rw-r--r--
Cleaned up all the readAll() cut and paste.
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
 *
809
116b8fe30371 Renamed LICENSE to LICENSE.txt
Ryan C. Gordon <icculus@icculus.org>
parents: 808
diff changeset
     4
 * Please see the file LICENSE.txt in the source's root directory.
17
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 (defined PHYSFS_SUPPORTS_ZIP)
19846c18071b Initial autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 194
diff changeset
    11
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
    12
#ifndef _WIN32_WCE
504
3420d82f9b01 Some cleanups for PocketPC port.
Ryan C. Gordon <icculus@icculus.org>
parents: 494
diff changeset
    13
#include <errno.h>
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
    14
#include <time.h>
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
    15
#endif
1129
d81afe4b0a97 Cleaned up some #includes.
Ryan C. Gordon <icculus@icculus.org>
parents: 1125
diff changeset
    16
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    17
#include "zlib.h"
17
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    18
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    19
#define __PHYSICSFS_INTERNAL__
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    20
#include "physfs_internal.h"
7337737f5120 Moved from root source dir.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    21
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
    22
/*
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
    23
 * A buffer of ZIP_READBUFSIZE is allocated for each compressed file opened,
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
    24
 *  and is freed when you close the file; compressed data is read into
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    25
 *  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
    26
 *  PHYSFS_read().
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    27
 *
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    28
 * 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
    29
 *  read data directly into the buffer passed to PHYSFS_read().
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    30
 *
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    31
 * 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
    32
 *  value.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    33
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    34
#define ZIP_READBUFSIZE   (16 * 1024)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    35
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
    36
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    37
/*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    38
 * 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
    39
 *  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
    40
 *  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
    41
 *  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
    42
 *  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
    43
 *  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
    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
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
    46
{
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
    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
    48
    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
    49
    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
    50
    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
    51
    ZIP_BROKEN_FILE,
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
    52
    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
    53
} 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
    54
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
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    56
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    57
 * 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
    58
 */
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
    59
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
    60
{
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
    61
    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
    62
    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
    63
    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
    64
    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
    65
    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
    66
    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
    67
    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
    68
    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
    69
    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
    70
    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
    71
    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
    72
} 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
    73
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    74
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    75
 * One ZIPinfo is kept for each open ZIP archive.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    76
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    77
typedef struct
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    78
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
    79
    PHYSFS_Io *io;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    80
    PHYSFS_uint16 entryCount; /* Number of files in ZIP.                     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    81
    ZIPentry *entries;        /* info on all files in ZIP.                   */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    82
} ZIPinfo;
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
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    85
 * 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
    86
 */
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
    87
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
    88
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    89
    ZIPentry *entry;                      /* Info on file.              */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
    90
    PHYSFS_Io *io;                        /* physical file handle.      */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    91
    PHYSFS_uint32 compressed_position;    /* offset in compressed data. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    92
    PHYSFS_uint32 uncompressed_position;  /* tell() position.           */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    93
    PHYSFS_uint8 *buffer;                 /* decompression buffer.      */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    94
    z_stream stream;                      /* zlib stream state.         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    95
} ZIPfileinfo;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    96
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
    97
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    98
/* Magic numbers... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    99
#define ZIP_LOCAL_FILE_SIG          0x04034b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   100
#define ZIP_CENTRAL_DIR_SIG         0x02014b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   101
#define ZIP_END_OF_CENTRAL_DIR_SIG  0x06054b50
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   102
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   103
/* compression methods... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   104
#define COMPMETH_NONE 0
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   105
/* ...and others... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   106
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   107
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   108
#define UNIX_FILETYPE_MASK    0170000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   109
#define UNIX_FILETYPE_SYMLINK 0120000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   110
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   111
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   112
/*
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   113
 * Bridge physfs allocation functions to zlib's format...
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   114
 */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   115
static voidpf zlibPhysfsAlloc(voidpf opaque, uInt items, uInt size)
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   116
{
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   117
    return ((PHYSFS_Allocator *) opaque)->Malloc(items * size);
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   118
} /* zlibPhysfsAlloc */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   119
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   120
/*
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   121
 * Bridge physfs allocation functions to zlib's format...
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   122
 */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   123
static void zlibPhysfsFree(voidpf opaque, voidpf address)
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   124
{
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   125
    ((PHYSFS_Allocator *) opaque)->Free(address);
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   126
} /* zlibPhysfsFree */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   127
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   128
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   129
/*
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   130
 * Construct a new z_stream to a sane state.
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   131
 */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   132
static void initializeZStream(z_stream *pstr)
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   133
{
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   134
    memset(pstr, '\0', sizeof (z_stream));
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   135
    pstr->zalloc = zlibPhysfsAlloc;
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   136
    pstr->zfree = zlibPhysfsFree;
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   137
    pstr->opaque = &allocator;
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   138
} /* initializeZStream */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   139
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   140
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   141
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
   142
{
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   143
    switch (rc)
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   144
    {
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   145
        case Z_OK: return NULL;  /* not an error. */
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   146
        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
   147
#ifndef _WIN32_WCE
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   148
        case Z_ERRNO: return strerror(errno);
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   149
#endif
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   150
        case Z_NEED_DICT: return ERR_NEED_DICT;
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   151
        case Z_DATA_ERROR: return ERR_DATA_ERROR;
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   152
        case Z_MEM_ERROR: return ERR_MEMORY_ERROR;
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   153
        case Z_BUF_ERROR: return ERR_BUFFER_ERROR;
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   154
        case Z_VERSION_ERROR: return ERR_VERSION_ERROR;
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   155
        default: return ERR_UNKNOWN_ERROR;
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   156
    } /* switch */
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   157
} /* zlib_error_string */
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   158
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   159
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   160
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   161
 * 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
   162
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   163
static int zlib_err(int rc)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   164
{
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   165
    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
   166
    if (str != NULL)
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   167
        __PHYSFS_setError(str);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   168
    return rc;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   169
} /* zlib_err */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   170
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   171
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   172
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   173
 * 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
   174
 */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   175
static int readui32(PHYSFS_Io *io, PHYSFS_uint32 *val)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   176
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   177
    PHYSFS_uint32 v;
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   178
    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &v, sizeof (v)), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   179
    *val = PHYSFS_swapULE32(v);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   180
    return 1;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   181
} /* readui32 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   182
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   183
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   184
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   185
 * 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
   186
 */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   187
static int readui16(PHYSFS_Io *io, PHYSFS_uint16 *val)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   188
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   189
    PHYSFS_uint16 v;
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   190
    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &v, sizeof (v)), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   191
    *val = PHYSFS_swapULE16(v);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   192
    return 1;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   193
} /* readui16 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   194
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   195
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   196
static PHYSFS_sint64 ZIP_read(PHYSFS_Io *_io, void *buf, PHYSFS_uint64 len)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   197
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   198
    ZIPfileinfo *finfo = (ZIPfileinfo *) _io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   199
    PHYSFS_Io *io = finfo->io;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   200
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   201
    PHYSFS_sint64 retval = 0;
1098
4e86cec1143f Moved all the file i/o from stdio-style to POSIX-style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1085
diff changeset
   202
    PHYSFS_sint64 maxread = (PHYSFS_sint64) len;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   203
    PHYSFS_sint64 avail = entry->uncompressed_size -
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   204
                          finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   205
1098
4e86cec1143f Moved all the file i/o from stdio-style to POSIX-style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1085
diff changeset
   206
    if (avail < maxread)
4e86cec1143f Moved all the file i/o from stdio-style to POSIX-style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1085
diff changeset
   207
        maxread = avail;
4e86cec1143f Moved all the file i/o from stdio-style to POSIX-style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1085
diff changeset
   208
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   209
    BAIL_IF_MACRO(maxread == 0, NULL, 0);    /* quick rejection. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   210
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   211
    if (entry->compression_method == COMPMETH_NONE)
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   212
        retval = io->read(io, buf, maxread);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   213
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   214
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   215
        finfo->stream.next_out = buf;
1098
4e86cec1143f Moved all the file i/o from stdio-style to POSIX-style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1085
diff changeset
   216
        finfo->stream.avail_out = maxread;
337
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
        while (retval < maxread)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   219
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   220
            PHYSFS_uint32 before = finfo->stream.total_out;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   221
            int rc;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   222
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   223
            if (finfo->stream.avail_in == 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   224
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   225
                PHYSFS_sint64 br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   226
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   227
                br = entry->compressed_size - finfo->compressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   228
                if (br > 0)
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
                    if (br > ZIP_READBUFSIZE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   231
                        br = ZIP_READBUFSIZE;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   232
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   233
                    br = io->read(io, finfo->buffer, (PHYSFS_uint64) br);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   234
                    if (br <= 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   235
                        break;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   236
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   237
                    finfo->compressed_position += (PHYSFS_uint32) br;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   238
                    finfo->stream.next_in = finfo->buffer;
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   239
                    finfo->stream.avail_in = (PHYSFS_uint32) br;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   240
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   241
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   242
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   243
            rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   244
            retval += (finfo->stream.total_out - before);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   245
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   246
            if (rc != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   247
                break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   248
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   249
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   250
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   251
    if (retval > 0)
1098
4e86cec1143f Moved all the file i/o from stdio-style to POSIX-style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1085
diff changeset
   252
        finfo->uncompressed_position += (PHYSFS_uint32) retval;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   253
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   254
    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
   255
} /* ZIP_read */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   256
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   257
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   258
static PHYSFS_sint64 ZIP_write(PHYSFS_Io *io, const void *b, PHYSFS_uint64 len)
467
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   259
{
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   260
    BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   261
} /* ZIP_write */
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   262
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   263
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   264
static PHYSFS_sint64 ZIP_tell(PHYSFS_Io *io)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   265
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   266
    return ((ZIPfileinfo *) io->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
   267
} /* ZIP_tell */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   268
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   269
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   270
static int ZIP_seek(PHYSFS_Io *_io, 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
   271
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   272
    ZIPfileinfo *finfo = (ZIPfileinfo *) _io->opaque;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   273
    ZIPentry *entry = finfo->entry;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   274
    PHYSFS_Io *io = finfo->io;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   275
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   276
    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
   277
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   278
    if (entry->compression_method == COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   279
    {
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   280
        const PHYSFS_sint64 newpos = offset + entry->offset;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   281
        BAIL_IF_MACRO(!io->seek(io, 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
   282
        finfo->uncompressed_position = (PHYSFS_uint32) offset;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   283
    } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   284
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   285
    else
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   286
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   287
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   288
         * If seeking backwards, we need to redecode the file
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   289
         *  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
   290
         *  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
   291
         *  decode, but we don't rewind first.
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   292
         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   293
        if (offset < finfo->uncompressed_position)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   294
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   295
            /* 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
   296
            z_stream str;
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   297
            initializeZStream(&str);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   298
            if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   299
                return 0;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   300
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   301
            if (!io->seek(io, entry->offset))
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   302
                return 0;
345
cbcb27547864 Seeking backwards in ZIP_seek() works now.
Ryan C. Gordon <icculus@icculus.org>
parents: 342
diff changeset
   303
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   304
            inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   305
            memcpy(&finfo->stream, &str, sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   306
            finfo->uncompressed_position = finfo->compressed_position = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   307
        } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   308
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   309
        while (finfo->uncompressed_position != offset)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   310
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   311
            PHYSFS_uint8 buf[512];
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   312
            PHYSFS_uint32 maxread;
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   313
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   314
            maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   315
            if (maxread > sizeof (buf))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   316
                maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   317
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   318
            if (ZIP_read(_io, buf, maxread) != maxread)
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   319
                return 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   320
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   321
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   322
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   323
    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
   324
} /* ZIP_seek */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   325
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   326
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   327
static PHYSFS_sint64 ZIP_length(PHYSFS_Io *io)
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   328
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   329
    const ZIPfileinfo *finfo = (ZIPfileinfo *) io->opaque;
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   330
    return finfo->entry->uncompressed_size;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   331
} /* ZIP_length */
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   332
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   333
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   334
static PHYSFS_Io *zip_get_io(PHYSFS_Io *io, ZIPinfo *inf, ZIPentry *entry);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   335
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   336
static PHYSFS_Io *ZIP_duplicate(PHYSFS_Io *io)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   337
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   338
    ZIPfileinfo *origfinfo = (ZIPfileinfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   339
    PHYSFS_Io *retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   340
    ZIPfileinfo *finfo = (ZIPfileinfo *) allocator.Malloc(sizeof (ZIPfileinfo));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   341
    GOTO_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, ZIP_duplicate_failed);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   342
    GOTO_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, ZIP_duplicate_failed);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   343
    memset(finfo, '\0', sizeof (*finfo));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   344
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   345
    finfo->entry = origfinfo->entry;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   346
    finfo->io = zip_get_io(origfinfo->io, NULL, finfo->entry);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   347
    GOTO_IF_MACRO(finfo->io == NULL, NULL, ZIP_duplicate_failed);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   348
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   349
    if (finfo->entry->compression_method != COMPMETH_NONE)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   350
    {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   351
        finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   352
        GOTO_IF_MACRO(!finfo->buffer, ERR_OUT_OF_MEMORY, ZIP_duplicate_failed);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   353
        if (zlib_err(inflateInit2(&finfo->stream, -MAX_WBITS)) != Z_OK)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   354
            goto ZIP_duplicate_failed;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   355
    } /* if */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   356
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   357
    memcpy(retval, io, sizeof (PHYSFS_Io));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   358
    retval->opaque = finfo;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   359
    return retval;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   360
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   361
ZIP_duplicate_failed:
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   362
    if (finfo != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   363
    {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   364
        if (finfo->io != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   365
            finfo->io->destroy(finfo->io);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   366
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   367
        if (finfo->buffer != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   368
        {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   369
            allocator.Free(finfo->buffer);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   370
            inflateEnd(&finfo->stream);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   371
        } /* if */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   372
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   373
        allocator.Free(finfo);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   374
    } /* if */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   375
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   376
    if (retval != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   377
        allocator.Free(retval);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   378
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   379
    return NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   380
} /* ZIP_duplicate */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   381
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   382
static int ZIP_flush(PHYSFS_Io *io) { return 1;  /* no write support. */ }
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   383
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   384
static void ZIP_destroy(PHYSFS_Io *io)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   385
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   386
    ZIPfileinfo *finfo = (ZIPfileinfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   387
    finfo->io->destroy(finfo->io);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   388
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   389
    if (finfo->entry->compression_method != COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   390
        inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   391
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   392
    if (finfo->buffer != NULL)
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   393
        allocator.Free(finfo->buffer);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   394
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   395
    allocator.Free(finfo);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   396
    allocator.Free(io);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   397
} /* ZIP_destroy */
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   398
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   399
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   400
static const PHYSFS_Io ZIP_Io =
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   401
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   402
    ZIP_read,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   403
    ZIP_write,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   404
    ZIP_seek,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   405
    ZIP_tell,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   406
    ZIP_length,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   407
    ZIP_duplicate,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   408
    ZIP_flush,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   409
    ZIP_destroy,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   410
    NULL
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   411
};
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   412
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   413
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   414
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   415
static PHYSFS_sint64 zip_find_end_of_central_dir(PHYSFS_Io *io, PHYSFS_sint64 *len)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   416
{
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
   417
    PHYSFS_uint8 buf[256];
1085
1ad575ce53c8 Merged changeset 1084:ee3d2e6e1161 from stable-2.0: unitialized array fix.
Ryan C. Gordon <icculus@icculus.org>
parents: 1054
diff changeset
   418
    PHYSFS_uint8 extra[4] = { 0, 0, 0, 0 };
413
d669d303317d Initialized some variables to stop compiler whining.
Ryan C. Gordon <icculus@icculus.org>
parents: 402
diff changeset
   419
    PHYSFS_sint32 i = 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   420
    PHYSFS_sint64 filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   421
    PHYSFS_sint64 filepos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   422
    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
   423
    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
   424
    int found = 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   425
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   426
    filelen = io->length(io);
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   427
    BAIL_IF_MACRO(filelen == -1, NULL, 0);  /* !!! FIXME: unlocalized string */
1107
b3d42c9117ec Actually, that's FOUR gigabytes.
Ryan C. Gordon <icculus@icculus.org>
parents: 1106
diff changeset
   428
    BAIL_IF_MACRO(filelen > 0xFFFFFFFF, "ZIP bigger than 4 gigs?!", 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   429
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   430
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   431
     * 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
   432
     *  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
   433
     *  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
   434
     *  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
   435
     *  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
   436
     *  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
   437
     *  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
   438
     *  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
   439
     *  and call it a corrupted zipfile.
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   440
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   441
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   442
    if (sizeof (buf) < filelen)
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
        filepos = filelen - sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   445
        maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   446
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   447
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   448
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   449
        filepos = 0;
541
2be2fff14b7a Another attempt at type size correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 540
diff changeset
   450
        maxread = (PHYSFS_uint32) filelen;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   451
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   452
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
   453
    while ((totalread < filelen) && (totalread < 65557))
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   454
    {
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   455
        BAIL_IF_MACRO(!io->seek(io, filepos), NULL, -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
   456
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   457
        /* 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
   458
        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
   459
        {
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   460
            if (!__PHYSFS_readAll(io, buf, maxread - 4))
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   461
                return -1;
996
0410dc655d45 Fixed strict-aliasing issue that gcc 4.4 complains about.
Ryan C. Gordon <icculus@icculus.org>
parents: 928
diff changeset
   462
            memcpy(&buf[maxread - 4], &extra, sizeof (extra));
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
   463
            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
   464
        } /* 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
   465
        else
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   466
        {
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   467
            if (!__PHYSFS_readAll(io, buf, maxread))
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   468
                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
   469
            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
   470
        } /* 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
   471
996
0410dc655d45 Fixed strict-aliasing issue that gcc 4.4 complains about.
Ryan C. Gordon <icculus@icculus.org>
parents: 928
diff changeset
   472
        memcpy(&extra, buf, sizeof (extra));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   473
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
   474
        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
   475
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   476
            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
   477
                (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
   478
                (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
   479
                (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
   480
            {
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
                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
   482
                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
   483
            } /* 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
   484
        } /* 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
   485
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 (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
   487
            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
   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
        filepos -= (maxread - 4);
895
8bf07c014a43 Fixed zip archiver: could do bogus seek if a small, non-zip file got put
Ryan C. Gordon <icculus@icculus.org>
parents: 894
diff changeset
   490
        if (filepos < 0)
8bf07c014a43 Fixed zip archiver: could do bogus seek if a small, non-zip file got put
Ryan C. Gordon <icculus@icculus.org>
parents: 894
diff changeset
   491
            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
   492
    } /* 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
   493
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   494
    BAIL_IF_MACRO(!found, ERR_NOT_AN_ARCHIVE, -1);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   495
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   496
    if (len != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   497
        *len = filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   498
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   499
    return (filepos + i);
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
   500
} /* zip_find_end_of_central_dir */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   501
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   502
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   503
static int isZip(PHYSFS_Io *io)
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   504
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   505
    PHYSFS_uint32 sig = 0;
446
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   506
    int retval = 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
   507
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   508
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   509
     * 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
   510
     *  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
   511
     */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   512
    if (readui32(io, &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
   513
    {
446
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   514
        retval = (sig == ZIP_LOCAL_FILE_SIG);
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   515
        if (!retval)
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   516
        {
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   517
            /*
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   518
             * 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
   519
             *  (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
   520
             *  it the hard way...
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   521
             */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   522
            retval = (zip_find_end_of_central_dir(io, NULL) != -1);
446
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   523
        } /* 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
   524
    } /* if */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   525
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   526
    return retval;
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1111
diff changeset
   527
} /* isZip */
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   528
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   529
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
   530
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
   531
{
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
   532
    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
   533
    for (i = 0; i < max; i++)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   534
    {
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   535
        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
   536
        if (entry->name != NULL)
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   537
            allocator.Free(entry->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
   538
    } /* 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
   539
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   540
    allocator.Free(entries);
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
   541
} /* 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
   542
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
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   544
/*
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   545
 * 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
   546
 *  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
   547
 *  (*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
   548
 */
1054
57f4af811ffb THIS is Christoph's PHYSFS_stat() work.
Ryan C. Gordon <icculus@icculus.org>
parents: 1053
diff changeset
   549
static ZIPentry *zip_find_entry(const ZIPinfo *info, const char *path,
57f4af811ffb THIS is Christoph's PHYSFS_stat() work.
Ryan C. Gordon <icculus@icculus.org>
parents: 1053
diff changeset
   550
                                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
   551
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   552
    ZIPentry *a = info->entries;
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   553
    PHYSFS_sint32 pathlen = strlen(path);
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   554
    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
   555
    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
   556
    PHYSFS_sint32 middle;
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   557
    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
   558
    int rc;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   559
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
   560
    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
   561
    {
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   562
        middle = lo + ((hi - lo) / 2);
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   563
        thispath = a[middle].name;
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   564
        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
   565
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   566
        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
   567
            lo = middle + 1;
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   568
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   569
        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
   570
            hi = middle - 1;
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   571
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   572
        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
   573
        {
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   574
            if (isDir != NULL)
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   575
            {
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   576
                *isDir = (thispath[pathlen] == '/');
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   577
                if (*isDir)
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   578
                    return NULL;
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   579
            } /* if */
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   580
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   581
            if (thispath[pathlen] == '\0') /* found entry? */
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   582
                return &a[middle];
1142
25880a820248 Fixed bug in directory search for zip and qpak archivers (thanks, Michal!)
Ryan C. Gordon <icculus@icculus.org>
parents: 1129
diff changeset
   583
            /* adjust search params, try again. */
25880a820248 Fixed bug in directory search for zip and qpak archivers (thanks, Michal!)
Ryan C. Gordon <icculus@icculus.org>
parents: 1129
diff changeset
   584
            else if (thispath[pathlen] > '/')
25880a820248 Fixed bug in directory search for zip and qpak archivers (thanks, Michal!)
Ryan C. Gordon <icculus@icculus.org>
parents: 1129
diff changeset
   585
                hi = middle - 1;
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   586
            else
1142
25880a820248 Fixed bug in directory search for zip and qpak archivers (thanks, Michal!)
Ryan C. Gordon <icculus@icculus.org>
parents: 1129
diff changeset
   587
                lo = middle + 1;
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   588
        } /* if */
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
   589
    } /* while */
483
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   590
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   591
    if (isDir != NULL)
d788c84d8694 Fixed bug that prevented use when symlinks were disallowed.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   592
        *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
   593
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   594
    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
   595
} /* zip_find_entry */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   596
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
   597
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   598
/* 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
   599
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
   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
    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
   602
    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
   603
    {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   604
        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
   605
        {
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
            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
   607
                *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
   608
            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
   609
        } /* while */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   610
    } /* 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
   611
} /* zip_convert_dos_path */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   612
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   613
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   614
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
   615
{
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
   616
    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
   617
    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
   618
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
   619
    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
   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
        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
   622
        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
   623
            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
   624
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   625
        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
   626
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   627
            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
   628
            {
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
                /* 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
   630
                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
   631
            } /* 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
   632
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
            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
   634
            {
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
                /* 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
   636
                *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
   637
            } /* 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
   638
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
   639
            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
   640
            {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   641
                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
   642
                {
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
                    /* 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
   644
                    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
   645
                    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
   646
                    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
   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
                        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
   649
                        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
   650
                        {
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
                            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
   652
                            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
   653
                        } /* 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
   654
                    } /* 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
   655
                } /* 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
   656
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
                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
   658
                {
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
                    /* 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
   660
                    *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
   661
                } /* 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
   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
        } /* 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
   664
        else
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   665
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   666
            prevptr = ptr;
1162
49950eab0ef8 Fixed infinite loop in zip_expand_symlink_path().
Ryan C. Gordon <icculus@icculus.org>
parents: 1142
diff changeset
   667
            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
   668
        } /* else */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   669
    } /* 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
   670
} /* 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
   671
658
1981818c6170 Removed all the forward declaration cruft from the archivers.
Ryan C. Gordon <icculus@icculus.org>
parents: 657
diff changeset
   672
/* (forward reference: zip_follow_symlink and zip_resolve call each other.) */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   673
static int zip_resolve(PHYSFS_Io *io, ZIPinfo *info, ZIPentry *entry);
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   674
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   675
/*
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   676
 * 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
   677
 *  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
   678
 *  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
   679
 *  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
   680
 *  function.
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   681
 */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   682
static ZIPentry *zip_follow_symlink(PHYSFS_Io *io, 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
   683
{
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
   684
    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
   685
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   686
    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
   687
    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
   688
    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
   689
    {
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   690
        if (!zip_resolve(io, info, entry))  /* recursive! */
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   691
            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
   692
        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
   693
        {
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
            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
   695
                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
   696
        } /* 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
   697
    } /* 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
   698
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   699
    allocator.Free(path);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   700
    return entry;
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
   701
} /* 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
   702
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   703
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   704
static int zip_resolve_symlink(PHYSFS_Io *io, 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
   705
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   706
    char *path;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   707
    const PHYSFS_uint32 size = entry->uncompressed_size;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   708
    int rc = 0;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   709
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
   710
    /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   711
     * 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
   712
     *  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
   713
     *  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
   714
     */
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
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   716
    BAIL_IF_MACRO(!io->seek(io, entry->offset), 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
   717
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   718
    path = (char *) allocator.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
   719
    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
   720
    
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   721
    if (entry->compression_method == COMPMETH_NONE)
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   722
        rc = __PHYSFS_readAll(io, path, size);
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   723
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   724
    else  /* symlink target path is compressed... */
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
        z_stream stream;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   727
        const PHYSFS_uint32 complen = entry->compressed_size;
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 809
diff changeset
   728
        PHYSFS_uint8 *compressed = (PHYSFS_uint8*) __PHYSFS_smallAlloc(complen);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   729
        if (compressed != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   730
        {
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   731
            if (__PHYSFS_readAll(io, compressed, complen))
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   732
            {
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   733
                initializeZStream(&stream);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   734
                stream.next_in = compressed;
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 809
diff changeset
   735
                stream.avail_in = complen;
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
   736
                stream.next_out = (unsigned char *) path;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   737
                stream.avail_out = size;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   738
                if (zlib_err(inflateInit2(&stream, -MAX_WBITS)) == Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   739
                {
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   740
                    rc = zlib_err(inflate(&stream, Z_FINISH));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   741
                    inflateEnd(&stream);
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   742
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   743
                    /* both are acceptable outcomes... */
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   744
                    rc = ((rc == Z_OK) || (rc == Z_STREAM_END));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   745
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   746
            } /* if */
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 809
diff changeset
   747
            __PHYSFS_smallFree(compressed);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   748
        } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   749
    } /* else */
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   750
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   751
    if (!rc)
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   752
        allocator.Free(path);
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
   753
    else
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   754
    {
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
   755
        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
   756
        zip_convert_dos_path(entry, path);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   757
        entry->symlink = zip_follow_symlink(io, info, path);
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
   758
    } /* 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
   759
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   760
    return (entry->symlink != 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
   761
} /* 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
   762
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   763
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   764
/*
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
 * 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
   766
 */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   767
static int zip_parse_local(PHYSFS_Io *io, ZIPentry *entry)
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
   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
    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
   770
    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
   771
    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
   772
    PHYSFS_uint16 extralen;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   773
551
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   774
    /*
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   775
     * 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
   776
     *  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
   777
     *  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
   778
     *  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
   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
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   781
    BAIL_IF_MACRO(!io->seek(io, entry->offset), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   782
    BAIL_IF_MACRO(!readui32(io, &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
   783
    BAIL_IF_MACRO(ui32 != ZIP_LOCAL_FILE_SIG, ERR_CORRUPTED, 0);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   784
    BAIL_IF_MACRO(!readui16(io, &ui16), 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
   785
    BAIL_IF_MACRO(ui16 != entry->version_needed, ERR_CORRUPTED, 0);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   786
    BAIL_IF_MACRO(!readui16(io, &ui16), NULL, 0);  /* general bits. */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   787
    BAIL_IF_MACRO(!readui16(io, &ui16), 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
   788
    BAIL_IF_MACRO(ui16 != entry->compression_method, ERR_CORRUPTED, 0);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   789
    BAIL_IF_MACRO(!readui32(io, &ui32), NULL, 0);  /* date/time */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   790
    BAIL_IF_MACRO(!readui32(io, &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
   791
    BAIL_IF_MACRO(ui32 && (ui32 != entry->crc), ERR_CORRUPTED, 0);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   792
    BAIL_IF_MACRO(!readui32(io, &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
   793
    BAIL_IF_MACRO(ui32 && (ui32 != entry->compressed_size), ERR_CORRUPTED, 0);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   794
    BAIL_IF_MACRO(!readui32(io, &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
   795
    BAIL_IF_MACRO(ui32 && (ui32 != entry->uncompressed_size),ERR_CORRUPTED,0);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   796
    BAIL_IF_MACRO(!readui16(io, &fnamelen), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   797
    BAIL_IF_MACRO(!readui16(io, &extralen), 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
   798
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
    entry->offset += fnamelen + extralen + 30;
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   800
    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
   801
} /* 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
   802
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   803
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   804
static int zip_resolve(PHYSFS_Io *io, ZIPinfo *info, ZIPentry *entry)
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
   805
{
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
    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
   807
    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
   808
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
    /* 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
   810
    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
   811
    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
   812
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   813
    /* 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
   814
    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
   815
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
    /*
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
     * 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
   818
     *  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
   819
     *  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
   820
     *  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
   821
     *  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
   822
     */
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
    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
   824
    {
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
        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
   826
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   827
        retval = zip_parse_local(io, entry);
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
   828
        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
   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
            /*
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
             * 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
   832
             *  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
   833
             *  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
   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
            if (resolve_type == ZIP_UNRESOLVED_SYMLINK)
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   836
                retval = zip_resolve_symlink(io, info, entry);
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
   837
        } /* 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
   838
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
        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
   840
            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
   841
        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
   842
            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
   843
    } /* 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
   844
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   845
    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
   846
} /* 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
   847
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   848
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
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
   850
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   851
    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
   852
    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
   853
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   854
    switch (hosttype)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   855
    {
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   856
            /*
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   857
             * 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
   858
             *  symlinks, according to the Info-ZIP project.
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   859
             */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   860
        case 0:  /* FS_FAT_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   861
        case 1:  /* AMIGA_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   862
        case 2:  /* VMS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   863
        case 4:  /* VM_CSM_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   864
        case 6:  /* FS_HPFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   865
        case 11: /* FS_NTFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   866
        case 14: /* FS_VFAT_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   867
        case 13: /* ACORN_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   868
        case 15: /* MVS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   869
        case 18: /* THEOS_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   870
            break;  /* do nothing. */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   871
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   872
        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
   873
            retval = 1;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   874
            break;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   875
    } /* switch */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   876
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   877
    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
   878
} /* 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
   879
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   880
894
6d152b4900ea Minor const correctness tweak in zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 852
diff changeset
   881
static int zip_entry_is_symlink(const ZIPentry *entry)
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
   882
{
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   883
    return ((entry->resolved == ZIP_UNRESOLVED_SYMLINK) ||
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   884
            (entry->resolved == ZIP_BROKEN_SYMLINK) ||
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   885
            (entry->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
   886
} /* 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
   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
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
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
   890
{
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   891
    PHYSFS_uint16 xattr = ((extern_attr >> 16) & 0xFFFF);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   892
    return ( (zip_version_does_symlinks(entry->version)) &&
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   893
             (entry->uncompressed_size > 0) &&
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   894
             ((xattr & UNIX_FILETYPE_MASK) == UNIX_FILETYPE_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
   895
} /* 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
   896
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   897
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
   898
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
   899
{
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   900
#ifdef _WIN32_WCE
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 566
diff changeset
   901
    /* 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
   902
       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
   903
    */
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   904
    return -1;
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   905
#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
   906
    PHYSFS_uint32 dosdate;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   907
    struct tm unixtime;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   908
    memset(&unixtime, '\0', sizeof (unixtime));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   909
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   910
    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
   911
    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
   912
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   913
    /* 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
   914
    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
   915
    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
   916
    unixtime.tm_mday = ((dosdate     ) & 0x1F);
337
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
    /* 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
   919
    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
   920
    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
   921
    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
   922
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   923
    /* 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
   924
    unixtime.tm_isdst = -1;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   925
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   926
    return ((PHYSFS_sint64) mktime(&unixtime));
566
1e640d4acab9 PocketPC fixes (thanks, David Hedbor!)
Ryan C. Gordon <icculus@icculus.org>
parents: 551
diff changeset
   927
#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
   928
} /* zip_dos_time_to_physfs_time */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   929
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   930
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   931
static int zip_load_entry(PHYSFS_Io *io, ZIPentry *entry, PHYSFS_uint32 ofs_fixup)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   932
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   933
    PHYSFS_uint16 fnamelen, extralen, commentlen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   934
    PHYSFS_uint32 external_attr;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   935
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   936
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   937
    PHYSFS_sint64 si64;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   938
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   939
    /* sanity check with central directory signature... */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   940
    BAIL_IF_MACRO(!readui32(io, &ui32), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   941
    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
   942
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   943
    /* Get the pertinent parts of the record... */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   944
    BAIL_IF_MACRO(!readui16(io, &entry->version), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   945
    BAIL_IF_MACRO(!readui16(io, &entry->version_needed), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   946
    BAIL_IF_MACRO(!readui16(io, &ui16), NULL, 0);  /* general bits */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   947
    BAIL_IF_MACRO(!readui16(io, &entry->compression_method), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   948
    BAIL_IF_MACRO(!readui32(io, &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
   949
    entry->last_mod_time = zip_dos_time_to_physfs_time(ui32);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   950
    BAIL_IF_MACRO(!readui32(io, &entry->crc), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   951
    BAIL_IF_MACRO(!readui32(io, &entry->compressed_size), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   952
    BAIL_IF_MACRO(!readui32(io, &entry->uncompressed_size), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   953
    BAIL_IF_MACRO(!readui16(io, &fnamelen), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   954
    BAIL_IF_MACRO(!readui16(io, &extralen), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   955
    BAIL_IF_MACRO(!readui16(io, &commentlen), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   956
    BAIL_IF_MACRO(!readui16(io, &ui16), NULL, 0);  /* disk number start */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   957
    BAIL_IF_MACRO(!readui16(io, &ui16), NULL, 0);  /* internal file attribs */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   958
    BAIL_IF_MACRO(!readui32(io, &external_attr), NULL, 0);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   959
    BAIL_IF_MACRO(!readui32(io, &entry->offset), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   960
    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
   961
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   962
    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
   963
    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
   964
                            ZIP_UNRESOLVED_SYMLINK : ZIP_UNRESOLVED_FILE;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   965
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   966
    entry->name = (char *) allocator.Malloc(fnamelen + 1);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   967
    BAIL_IF_MACRO(entry->name == NULL, ERR_OUT_OF_MEMORY, 0);
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   968
    if (!__PHYSFS_readAll(io, entry->name, fnamelen))
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
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   970
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   971
    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
   972
    zip_convert_dos_path(entry, entry->name);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   973
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   974
    si64 = io->tell(io);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   975
    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
   976
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   977
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   978
        /* seek to the start of the next entry in the central directory... */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   979
    if (!io->seek(io, 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
   980
        goto zip_load_entry_puked;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   981
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   982
    return 1;  /* success. */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   983
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
zip_load_entry_puked:
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   985
    allocator.Free(entry->name);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   986
    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
   987
} /* 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
   988
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   989
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
   990
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
   991
{
928
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
   992
    if (one != two)
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
   993
    {
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
   994
        const ZIPentry *a = (const ZIPentry *) _a;
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
   995
        return strcmp(a[one].name, a[two].name);
928
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
   996
    } /* if */
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
   997
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
   998
    return 0;
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
   999
} /* zip_entry_cmp */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1000
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1001
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
  1002
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
  1003
{
928
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1004
    if (one != two)
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1005
    {
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1006
        ZIPentry tmp;
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1007
        ZIPentry *first = &(((ZIPentry *) _a)[one]);
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1008
        ZIPentry *second = &(((ZIPentry *) _a)[two]);
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1009
        memcpy(&tmp, first, sizeof (ZIPentry));
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1010
        memcpy(first, second, sizeof (ZIPentry));
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1011
        memcpy(second, &tmp, sizeof (ZIPentry));
0e37b8163248 Various archiver swap and compare functions now check if they are
Ryan C. Gordon <icculus@icculus.org>
parents: 895
diff changeset
  1012
    } /* if */
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
  1013
} /* 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
  1014
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
  1015
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1016
static int zip_load_entries(PHYSFS_Io *io, ZIPinfo *info,
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1017
                            PHYSFS_uint32 data_ofs, PHYSFS_uint32 central_ofs)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1018
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1019
    PHYSFS_uint32 max = info->entryCount;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1020
    PHYSFS_uint32 i;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1021
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1022
    BAIL_IF_MACRO(!io->seek(io, central_ofs), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1023
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
  1024
    info->entries = (ZIPentry *) allocator.Malloc(sizeof (ZIPentry) * max);
53
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1025
    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
  1026
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1027
    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
  1028
    {
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1029
        if (!zip_load_entry(io, &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
  1030
        {
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
  1031
            zip_free_entries(info->entries, i);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
  1032
            return 0;
46
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
  1033
        } /* 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
  1034
    } /* 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
  1035
464
21c8e0d1578c Generalized sorting routines, and removed individual implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 446
diff changeset
  1036
    __PHYSFS_sort(info->entries, max, zip_entry_cmp, zip_entry_swap);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
  1037
    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
  1038
} /* 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
  1039
6c3c990f006e ZIP entries are now cached at openArchive time, which cleans up the race
Ryan C. Gordon <icculus@icculus.org>
parents: 52
diff changeset
  1040
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1041
static int zip_parse_end_of_central_dir(PHYSFS_Io *io, ZIPinfo *info,
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
  1042
                                        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
  1043
                                        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
  1044
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1045
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1046
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1047
    PHYSFS_sint64 len;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1048
    PHYSFS_sint64 pos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1049
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1050
    /* find the end-of-central-dir record, and seek to it. */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1051
    pos = zip_find_end_of_central_dir(io, &len);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1052
    BAIL_IF_MACRO(pos == -1, NULL, 0);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1053
    BAIL_IF_MACRO(!io->seek(io, pos), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1054
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1055
    /* check signature again, just in case. */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1056
    BAIL_IF_MACRO(!readui32(io, &ui32), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1057
    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
  1058
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1059
    /* number of this disk */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1060
    BAIL_IF_MACRO(!readui16(io, &ui16), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1061
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1062
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1063
    /* number of the disk with the start of the central directory */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1064
    BAIL_IF_MACRO(!readui16(io, &ui16), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1065
    BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1066
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1067
    /* total number of entries in the central dir on this disk */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1068
    BAIL_IF_MACRO(!readui16(io, &ui16), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1069
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1070
    /* total number of entries in the central dir */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1071
    BAIL_IF_MACRO(!readui16(io, &info->entryCount), NULL, 0);
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 646
diff changeset
  1072
    BAIL_IF_MACRO(ui16 != info->entryCount, ERR_UNSUPPORTED_ARCHIVE, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1073
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1074
    /* size of the central directory */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1075
    BAIL_IF_MACRO(!readui32(io, &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
  1076
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1077
    /* offset of central directory */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1078
    BAIL_IF_MACRO(!readui32(io, central_dir_ofs), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1079
    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
  1080
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1081
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1082
     * 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
  1083
     *  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
  1084
     *  prepended by determining how far the central directory offset is
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1085
     *  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
  1086
     *  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
  1087
     *  data is at the start of the physical file.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1088
     */
541
2be2fff14b7a Another attempt at type size correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 540
diff changeset
  1089
    *data_start = (PHYSFS_uint32) (pos - (*central_dir_ofs + ui32));
337
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
    /* 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
  1092
    *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
  1093
491
b8853d8a09cb Fixed infinite loop bug, cleaned out tab chars.
Ryan C. Gordon <icculus@icculus.org>
parents: 483
diff changeset
  1094
    /* zipfile comment length */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1095
    BAIL_IF_MACRO(!readui16(io, &ui16), NULL, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1096
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1097
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1098
     * 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
  1099
     *  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
  1100
     *  file is corrupted, but we give up either way.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1101
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1102
    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
  1103
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 997
diff changeset
  1104
    return 1;  /* made it. */
365