src/physfs_archiver_zip.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 17 May 2020 01:41:52 -0400
changeset 1691 c66c9326b05d
parent 1617 67ca4c4f043e
permissions -rw-r--r--
7z: Make error handling a little more robust.
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
1258
074d08049aa7 Changed so that this builds a reasonable default with no command line #defines.
Ryan C. Gordon <icculus@icculus.org>
parents: 1247
diff changeset
    10
#define __PHYSICSFS_INTERNAL__
074d08049aa7 Changed so that this builds a reasonable default with no command line #defines.
Ryan C. Gordon <icculus@icculus.org>
parents: 1247
diff changeset
    11
#include "physfs_internal.h"
074d08049aa7 Changed so that this builds a reasonable default with no command line #defines.
Ryan C. Gordon <icculus@icculus.org>
parents: 1247
diff changeset
    12
074d08049aa7 Changed so that this builds a reasonable default with no command line #defines.
Ryan C. Gordon <icculus@icculus.org>
parents: 1247
diff changeset
    13
#if PHYSFS_SUPPORTS_ZIP
214
19846c18071b Initial autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 194
diff changeset
    14
504
3420d82f9b01 Some cleanups for PocketPC port.
Ryan C. Gordon <icculus@icculus.org>
parents: 494
diff changeset
    15
#include <errno.h>
254
c66bbbe50f14 Implemeted getLastModTime method.
Ryan C. Gordon <icculus@icculus.org>
parents: 240
diff changeset
    16
#include <time.h>
1129
d81afe4b0a97 Cleaned up some #includes.
Ryan C. Gordon <icculus@icculus.org>
parents: 1125
diff changeset
    17
1207
42e2aad5ab02 Replaced zlib with a hacked up copy of miniz: http://code.google.com/p/miniz/
Ryan C. Gordon <icculus@icculus.org>
parents: 1206
diff changeset
    18
#include "physfs_miniz.h"
42e2aad5ab02 Replaced zlib with a hacked up copy of miniz: http://code.google.com/p/miniz/
Ryan C. Gordon <icculus@icculus.org>
parents: 1206
diff changeset
    19
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
    20
/*
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
    21
 * 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
    22
 *  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
    23
 *  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
    24
 *  PHYSFS_read().
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    25
 *
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    26
 * 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
    27
 *  read data directly into the buffer passed to PHYSFS_read().
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    28
 *
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    29
 * 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
    30
 *  value.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    31
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    32
#define ZIP_READBUFSIZE   (16 * 1024)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    33
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
    34
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    35
/*
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
 * 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
    37
 *  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
    38
 *  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
    39
 *  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
    40
 *  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
    41
 *  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
    42
 */
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
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
    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
    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
    46
    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
    47
    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
    48
    ZIP_RESOLVED,
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
    49
    ZIP_DIRECTORY,
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    50
    ZIP_BROKEN_FILE,
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
    51
    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
    52
} 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
    53
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
    54
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    55
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    56
 * 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
    57
 */
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
    58
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
    59
{
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
    60
    __PHYSFS_DirTreeEntry tree;         /* manages directory tree         */
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
    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
    62
    ZipResolveType resolved;            /* Have we resolved file/symlink? */
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
    63
    PHYSFS_uint64 offset;               /* offset of data in archive      */
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
    64
    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
    65
    PHYSFS_uint16 version_needed;       /* version needed to extract      */
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
    66
    PHYSFS_uint16 general_bits;         /* general purpose bits           */
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
    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                         */
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
    69
    PHYSFS_uint64 compressed_size;      /* compressed size                */
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
    70
    PHYSFS_uint64 uncompressed_size;    /* uncompressed size              */
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
    71
    PHYSFS_sint64 last_mod_time;        /* last file mod time             */
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
    72
    PHYSFS_uint32 dos_mod_time;         /* original MS-DOS style 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
    73
} 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
    74
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    75
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    76
 * One ZIPinfo is kept for each open ZIP archive.
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    77
 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    78
typedef struct
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    79
{
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
    80
    __PHYSFS_DirTree tree;    /* manages directory tree.                */
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
    81
    PHYSFS_Io *io;            /* the i/o interface for this archive.    */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
    82
    int zip64;                /* non-zero if this is a Zip64 archive.   */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
    83
    int has_crypto;           /* non-zero if any entry uses encryption. */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    84
} ZIPinfo;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    85
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    86
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    87
 * 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
    88
 */
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
    89
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
    90
{
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    91
    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
    92
    PHYSFS_Io *io;                        /* physical file handle.      */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    93
    PHYSFS_uint32 compressed_position;    /* offset in compressed data. */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    94
    PHYSFS_uint32 uncompressed_position;  /* tell() position.           */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    95
    PHYSFS_uint8 *buffer;                 /* decompression buffer.      */
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
    96
    PHYSFS_uint32 crypto_keys[3];         /* for "traditional" crypto.  */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
    97
    PHYSFS_uint32 initial_crypto_keys[3]; /* for "traditional" crypto.  */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    98
    z_stream stream;                      /* zlib stream state.         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
    99
} ZIPfileinfo;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   100
32
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   101
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   102
/* Magic numbers... */
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   103
#define ZIP_LOCAL_FILE_SIG                          0x04034b50
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   104
#define ZIP_CENTRAL_DIR_SIG                         0x02014b50
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   105
#define ZIP_END_OF_CENTRAL_DIR_SIG                  0x06054b50
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   106
#define ZIP64_END_OF_CENTRAL_DIR_SIG                0x06064b50
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   107
#define ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG  0x07064b50
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   108
#define ZIP64_EXTENDED_INFO_EXTRA_FIELD_SIG         0x0001
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   109
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   110
/* compression methods... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   111
#define COMPMETH_NONE 0
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   112
/* ...and others... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   113
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   114
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   115
#define UNIX_FILETYPE_MASK    0170000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   116
#define UNIX_FILETYPE_SYMLINK 0120000
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   117
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   118
#define ZIP_GENERAL_BITS_TRADITIONAL_CRYPTO   (1 << 0)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   119
#define ZIP_GENERAL_BITS_IGNORE_LOCAL_HEADER  (1 << 3)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   120
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   121
/* support for "traditional" PKWARE encryption. */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   122
static int zip_entry_is_tradional_crypto(const ZIPentry *entry)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   123
{
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   124
    return (entry->general_bits & ZIP_GENERAL_BITS_TRADITIONAL_CRYPTO) != 0;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   125
} /* zip_entry_is_traditional_crypto */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   126
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   127
static int zip_entry_ignore_local_header(const ZIPentry *entry)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   128
{
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   129
    return (entry->general_bits & ZIP_GENERAL_BITS_IGNORE_LOCAL_HEADER) != 0;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   130
} /* zip_entry_is_traditional_crypto */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   131
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   132
static PHYSFS_uint32 zip_crypto_crc32(const PHYSFS_uint32 crc, const PHYSFS_uint8 val)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   133
{
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   134
    int i;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   135
    PHYSFS_uint32 xorval = (crc ^ ((PHYSFS_uint32) val)) & 0xFF;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   136
    for (i = 0; i < 8; i++)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   137
        xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   138
    return xorval ^ (crc >> 8);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   139
} /* zip_crc32 */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   140
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   141
static void zip_update_crypto_keys(PHYSFS_uint32 *keys, const PHYSFS_uint8 val)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   142
{
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   143
    keys[0] = zip_crypto_crc32(keys[0], val);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   144
    keys[1] = keys[1] + (keys[0] & 0x000000FF);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   145
    keys[1] = (keys[1] * 134775813) + 1;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   146
    keys[2] = zip_crypto_crc32(keys[2], (PHYSFS_uint8) ((keys[1] >> 24) & 0xFF));
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   147
} /* zip_update_crypto_keys */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   148
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   149
static PHYSFS_uint8 zip_decrypt_byte(const PHYSFS_uint32 *keys)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   150
{
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   151
    const PHYSFS_uint16 tmp = keys[2] | 2;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   152
    return (PHYSFS_uint8) ((tmp * (tmp ^ 1)) >> 8);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   153
} /* zip_decrypt_byte */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   154
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   155
static PHYSFS_sint64 zip_read_decrypt(ZIPfileinfo *finfo, void *buf, PHYSFS_uint64 len)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   156
{
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   157
    PHYSFS_Io *io = finfo->io;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   158
    const PHYSFS_sint64 br = io->read(io, buf, len);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   159
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   160
    /* Decompression the new data if necessary. */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   161
    if (zip_entry_is_tradional_crypto(finfo->entry) && (br > 0))
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   162
    {
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   163
        PHYSFS_uint32 *keys = finfo->crypto_keys;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   164
        PHYSFS_uint8 *ptr = (PHYSFS_uint8 *) buf;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   165
        PHYSFS_sint64 i;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   166
        for (i = 0; i < br; i++, ptr++)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   167
        {
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   168
            const PHYSFS_uint8 ch = *ptr ^ zip_decrypt_byte(keys);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   169
            zip_update_crypto_keys(keys, ch);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   170
            *ptr = ch;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   171
        } /* for */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   172
    } /* if  */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   173
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   174
    return br;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   175
} /* zip_read_decrypt */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   176
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   177
static int zip_prep_crypto_keys(ZIPfileinfo *finfo, const PHYSFS_uint8 *crypto_header, const PHYSFS_uint8 *password)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   178
{
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   179
    /* It doesn't appear to be documented in PKWare's APPNOTE.TXT, but you
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   180
       need to use a different byte in the header to verify the password
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   181
       if general purpose bit 3 is set. Discovered this from Info-Zip.
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   182
       That's what the (verifier) value is doing, below. */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   183
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   184
    PHYSFS_uint32 *keys = finfo->crypto_keys;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   185
    const ZIPentry *entry = finfo->entry;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   186
    const int usedate = zip_entry_ignore_local_header(entry);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   187
    const PHYSFS_uint8 verifier = (PHYSFS_uint8) ((usedate ? (entry->dos_mod_time >> 8) : (entry->crc >> 24)) & 0xFF);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   188
    PHYSFS_uint8 finalbyte = 0;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   189
    int i = 0;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   190
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   191
    /* initialize vector with defaults, then password, then header. */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   192
    keys[0] = 305419896;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   193
    keys[1] = 591751049;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   194
    keys[2] = 878082192;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   195
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   196
    while (*password)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   197
        zip_update_crypto_keys(keys, *(password++));
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   198
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   199
    for (i = 0; i < 12; i++)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   200
    {
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   201
        const PHYSFS_uint8 c = crypto_header[i] ^ zip_decrypt_byte(keys);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   202
        zip_update_crypto_keys(keys, c);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   203
        finalbyte = c;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   204
    } /* for */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   205
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   206
    /* you have a 1/256 chance of passing this test incorrectly. :/ */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   207
    if (finalbyte != verifier)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   208
        BAIL(PHYSFS_ERR_BAD_PASSWORD, 0);
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   209
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   210
    /* save the initial vector for seeking purposes. Not secure!! */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   211
    memcpy(finfo->initial_crypto_keys, finfo->crypto_keys, 12);
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   212
    return 1;
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   213
} /* zip_prep_crypto_keys */
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   214
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   215
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   216
/*
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   217
 * 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
   218
 */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   219
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
   220
{
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
   221
    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
   222
} /* zlibPhysfsAlloc */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   223
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   224
/*
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   225
 * 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
   226
 */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   227
static void zlibPhysfsFree(voidpf opaque, voidpf address)
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   228
{
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   229
    ((PHYSFS_Allocator *) opaque)->Free(address);
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   230
} /* zlibPhysfsFree */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   231
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   232
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   233
/*
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   234
 * 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
   235
 */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   236
static void initializeZStream(z_stream *pstr)
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   237
{
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   238
    memset(pstr, '\0', sizeof (z_stream));
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   239
    pstr->zalloc = zlibPhysfsAlloc;
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   240
    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
   241
    pstr->opaque = &allocator;
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   242
} /* initializeZStream */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   243
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   244
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1220
diff changeset
   245
static PHYSFS_ErrorCode zlib_error_code(int rc)
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   246
{
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   247
    switch (rc)
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   248
    {
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1220
diff changeset
   249
        case Z_OK: return PHYSFS_ERR_OK;  /* not an error. */
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1220
diff changeset
   250
        case Z_STREAM_END: return PHYSFS_ERR_OK; /* not an error. */
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1220
diff changeset
   251
        case Z_ERRNO: return PHYSFS_ERR_IO;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1220
diff changeset
   252
        case Z_MEM_ERROR: return PHYSFS_ERR_OUT_OF_MEMORY;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1220
diff changeset
   253
        default: return PHYSFS_ERR_CORRUPT;
427
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   254
    } /* switch */
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   255
} /* zlib_error_string */
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   256
c38ace41039f Natural language #defines and build system support.
Ryan C. Gordon <icculus@icculus.org>
parents: 413
diff changeset
   257
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   258
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   259
 * 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
   260
 */
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1220
diff changeset
   261
static int zlib_err(const int rc)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   262
{
1328
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   263
    PHYSFS_setErrorCode(zlib_error_code(rc));
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
   264
    return rc;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   265
} /* zlib_err */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   266
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   267
/*
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   268
 * Read an unsigned 64-bit int and swap to native byte order.
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   269
 */
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   270
static int readui64(PHYSFS_Io *io, PHYSFS_uint64 *val)
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   271
{
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   272
    PHYSFS_uint64 v;
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   273
    BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &v, sizeof (v)), 0);
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   274
    *val = PHYSFS_swapULE64(v);
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   275
    return 1;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   276
} /* readui64 */
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   277
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   278
/*
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   279
 * 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
   280
 */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   281
static int readui32(PHYSFS_Io *io, PHYSFS_uint32 *val)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   282
{
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   283
    PHYSFS_uint32 v;
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   284
    BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &v, sizeof (v)), 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   285
    *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
   286
    return 1;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   287
} /* readui32 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   288
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   289
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   290
/*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   291
 * 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
   292
 */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   293
static int readui16(PHYSFS_Io *io, PHYSFS_uint16 *val)
337
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
    PHYSFS_uint16 v;
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   296
    BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &v, sizeof (v)), 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   297
    *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
   298
    return 1;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   299
} /* readui16 */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   300
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   301
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   302
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
   303
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   304
    ZIPfileinfo *finfo = (ZIPfileinfo *) _io->opaque;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   305
    ZIPentry *entry = finfo->entry;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   306
    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
   307
    PHYSFS_sint64 maxread = (PHYSFS_sint64) len;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   308
    PHYSFS_sint64 avail = entry->uncompressed_size -
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   309
                          finfo->uncompressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   310
1098
4e86cec1143f Moved all the file i/o from stdio-style to POSIX-style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1085
diff changeset
   311
    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
   312
        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
   313
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   314
    BAIL_IF_ERRPASS(maxread == 0, 0);    /* quick rejection. */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   315
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   316
    if (entry->compression_method == COMPMETH_NONE)
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   317
        retval = zip_read_decrypt(finfo, buf, maxread);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   318
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   319
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   320
        finfo->stream.next_out = buf;
1208
3edcb015089a Fixed some compiler warnings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1207
diff changeset
   321
        finfo->stream.avail_out = (uInt) maxread;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   322
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   323
        while (retval < maxread)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   324
        {
1522
d3d65a6e715c Fixed compiler warning.
Ryan C. Gordon <icculus@icculus.org>
parents: 1520
diff changeset
   325
            const PHYSFS_uint32 before = (PHYSFS_uint32) finfo->stream.total_out;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   326
            int rc;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   327
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   328
            if (finfo->stream.avail_in == 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   329
            {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   330
                PHYSFS_sint64 br;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   331
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   332
                br = entry->compressed_size - finfo->compressed_position;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   333
                if (br > 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   334
                {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   335
                    if (br > ZIP_READBUFSIZE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   336
                        br = ZIP_READBUFSIZE;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   337
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   338
                    br = zip_read_decrypt(finfo, finfo->buffer, (PHYSFS_uint64) br);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   339
                    if (br <= 0)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   340
                        break;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   341
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   342
                    finfo->compressed_position += (PHYSFS_uint32) br;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   343
                    finfo->stream.next_in = finfo->buffer;
1457
8b22357e79f0 Fixed some compiler warnings with Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1423
diff changeset
   344
                    finfo->stream.avail_in = (unsigned int) br;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   345
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   346
            } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   347
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   348
            rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   349
            retval += (finfo->stream.total_out - before);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   350
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   351
            if (rc != Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   352
                break;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   353
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   354
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   355
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   356
    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
   357
        finfo->uncompressed_position += (PHYSFS_uint32) retval;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   358
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
   359
    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
   360
} /* ZIP_read */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   361
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   362
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   363
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
   364
{
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   365
    BAIL(PHYSFS_ERR_READ_ONLY, -1);
467
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   366
} /* ZIP_write */
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   367
99664d9842cb Bunch of tedious corrections, optimizations, and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 464
diff changeset
   368
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   369
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
   370
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   371
    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
   372
} /* ZIP_tell */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   373
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   374
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   375
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
   376
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   377
    ZIPfileinfo *finfo = (ZIPfileinfo *) _io->opaque;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   378
    ZIPentry *entry = finfo->entry;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   379
    PHYSFS_Io *io = finfo->io;
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   380
    const int encrypted = zip_entry_is_tradional_crypto(entry);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   381
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   382
    BAIL_IF(offset > entry->uncompressed_size, PHYSFS_ERR_PAST_EOF, 0);
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   383
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   384
    if (!encrypted && (entry->compression_method == COMPMETH_NONE))
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   385
    {
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   386
        PHYSFS_sint64 newpos = offset + entry->offset;
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   387
        BAIL_IF_ERRPASS(!io->seek(io, newpos), 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
   388
        finfo->uncompressed_position = (PHYSFS_uint32) offset;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   389
    } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   390
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   391
    else
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   392
    {
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   393
        /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   394
         * If seeking backwards, we need to redecode the file
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   395
         *  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
   396
         *  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
   397
         *  decode, but we don't rewind first.
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   398
         */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   399
        if (offset < finfo->uncompressed_position)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   400
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   401
            /* 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
   402
            z_stream str;
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   403
            initializeZStream(&str);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   404
            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
   405
                return 0;
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   406
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   407
            if (!io->seek(io, entry->offset + (encrypted ? 12 : 0)))
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
   408
                return 0;
345
cbcb27547864 Seeking backwards in ZIP_seek() works now.
Ryan C. Gordon <icculus@icculus.org>
parents: 342
diff changeset
   409
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   410
            inflateEnd(&finfo->stream);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   411
            memcpy(&finfo->stream, &str, sizeof (z_stream));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   412
            finfo->uncompressed_position = finfo->compressed_position = 0;
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   413
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   414
            if (encrypted)
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
   415
                memcpy(finfo->crypto_keys, finfo->initial_crypto_keys, 12);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   416
        } /* if */
50
989b413188e5 Added individual file i/o code. Untested.
Ryan C. Gordon <icculus@icculus.org>
parents: 46
diff changeset
   417
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   418
        while (finfo->uncompressed_position != offset)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   419
        {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   420
            PHYSFS_uint8 buf[512];
540
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   421
            PHYSFS_uint32 maxread;
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   422
a6b6f0a54cd2 Attempt at type correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 538
diff changeset
   423
            maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   424
            if (maxread > sizeof (buf))
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   425
                maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   426
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   427
            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
   428
                return 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   429
        } /* while */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   430
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   431
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
   432
    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
   433
} /* ZIP_seek */
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   434
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   435
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   436
static PHYSFS_sint64 ZIP_length(PHYSFS_Io *io)
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   437
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   438
    const ZIPfileinfo *finfo = (ZIPfileinfo *) io->opaque;
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   439
    return (PHYSFS_sint64) finfo->entry->uncompressed_size;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   440
} /* ZIP_length */
28
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   441
529214f57d1b Added PHYSFS_fileLength(). Bleh.
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
   442
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   443
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
   444
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   445
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
   446
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   447
    ZIPfileinfo *origfinfo = (ZIPfileinfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   448
    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
   449
    ZIPfileinfo *finfo = (ZIPfileinfo *) allocator.Malloc(sizeof (ZIPfileinfo));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   450
    GOTO_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, failed);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   451
    GOTO_IF(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, failed);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   452
    memset(finfo, '\0', sizeof (*finfo));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   453
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   454
    finfo->entry = origfinfo->entry;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   455
    finfo->io = zip_get_io(origfinfo->io, NULL, finfo->entry);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   456
    GOTO_IF_ERRPASS(!finfo->io, failed);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   457
1617
67ca4c4f043e Fixed crash when duplicating PHYSFS_Io for zipfiles.
Ryan C. Gordon <icculus@icculus.org>
parents: 1584
diff changeset
   458
    initializeZStream(&finfo->stream);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   459
    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
   460
    {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   461
        finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   462
        GOTO_IF(!finfo->buffer, PHYSFS_ERR_OUT_OF_MEMORY, failed);
1269
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   463
        if (zlib_err(inflateInit2(&finfo->stream, -MAX_WBITS)) != Z_OK)
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   464
            goto failed;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   465
    } /* if */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   466
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   467
    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
   468
    retval->opaque = finfo;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   469
    return retval;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   470
1269
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   471
failed:
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   472
    if (finfo != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   473
    {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   474
        if (finfo->io != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   475
            finfo->io->destroy(finfo->io);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   476
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   477
        if (finfo->buffer != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   478
        {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   479
            allocator.Free(finfo->buffer);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   480
            inflateEnd(&finfo->stream);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   481
        } /* if */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   482
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   483
        allocator.Free(finfo);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   484
    } /* if */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   485
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   486
    if (retval != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   487
        allocator.Free(retval);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   488
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   489
    return NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   490
} /* ZIP_duplicate */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   491
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   492
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
   493
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   494
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
   495
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   496
    ZIPfileinfo *finfo = (ZIPfileinfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   497
    finfo->io->destroy(finfo->io);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   498
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   499
    if (finfo->entry->compression_method != COMPMETH_NONE)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   500
        inflateEnd(&finfo->stream);
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
    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
   503
        allocator.Free(finfo->buffer);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   504
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 658
diff changeset
   505
    allocator.Free(finfo);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   506
    allocator.Free(io);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   507
} /* 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
   508
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   509
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   510
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
   511
{
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1276
diff changeset
   512
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   513
    ZIP_read,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   514
    ZIP_write,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   515
    ZIP_seek,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   516
    ZIP_tell,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   517
    ZIP_length,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   518
    ZIP_duplicate,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   519
    ZIP_flush,
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1276
diff changeset
   520
    ZIP_destroy
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   521
};
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   522
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   523
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   524
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   525
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
   526
{
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   527
    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
   528
    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
   529
    PHYSFS_sint32 i = 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   530
    PHYSFS_sint64 filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   531
    PHYSFS_sint64 filepos;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   532
    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
   533
    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
   534
    int found = 0;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   535
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   536
    filelen = io->length(io);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   537
    BAIL_IF_ERRPASS(filelen == -1, -1);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   538
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   539
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   540
     * 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
   541
     *  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
   542
     *  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
   543
     *  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
   544
     *  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
   545
     *  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
   546
     *  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
   547
     *  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
   548
     *  and call it a corrupted zipfile.
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   549
     */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   550
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   551
    if (sizeof (buf) < filelen)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   552
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   553
        filepos = filelen - sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   554
        maxread = sizeof (buf);
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   555
    } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   556
    else
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   557
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   558
        filepos = 0;
541
2be2fff14b7a Another attempt at type size correctness.
Ryan C. Gordon <icculus@icculus.org>
parents: 540
diff changeset
   559
        maxread = (PHYSFS_uint32) filelen;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   560
    } /* else */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   561
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   562
    while ((totalread < filelen) && (totalread < 65557))
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   563
    {
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   564
        BAIL_IF_ERRPASS(!io->seek(io, filepos), -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
   565
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   566
        /* 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
   567
        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
   568
        {
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   569
            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
   570
                return -1;
996
0410dc655d45 Fixed strict-aliasing issue that gcc 4.4 complains about.
Ryan C. Gordon <icculus@icculus.org>
parents: 928
diff changeset
   571
            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
   572
            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
   573
        } /* 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
   574
        else
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   575
        {
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   576
            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
   577
                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
   578
            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
   579
        } /* 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
   580
996
0410dc655d45 Fixed strict-aliasing issue that gcc 4.4 complains about.
Ryan C. Gordon <icculus@icculus.org>
parents: 928
diff changeset
   581
        memcpy(&extra, buf, sizeof (extra));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   582
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
   583
        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
   584
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   585
            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
   586
                (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
   587
                (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
   588
                (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
   589
            {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   590
                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
   591
                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
   592
            } /* 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
   593
        } /* 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
   594
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
        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
   596
            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
   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
        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
   599
        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
   600
            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
   601
    } /* 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
   602
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   603
    BAIL_IF(!found, PHYSFS_ERR_UNSUPPORTED, -1);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   604
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   605
    if (len != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   606
        *len = filelen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   607
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
   608
    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
   609
} /* zip_find_end_of_central_dir */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   610
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   611
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   612
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
   613
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   614
    PHYSFS_uint32 sig = 0;
446
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   615
    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
   616
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   617
    /*
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   618
     * 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
   619
     *  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
   620
     */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   621
    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
   622
    {
446
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   623
        retval = (sig == ZIP_LOCAL_FILE_SIG);
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   624
        if (!retval)
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   625
        {
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   626
            /*
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   627
             * 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
   628
             *  (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
   629
             *  it the hard way...
e1f7fe003b70 Fix for correct cleanup on read error.
Ryan C. Gordon <icculus@icculus.org>
parents: 429
diff changeset
   630
             */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   631
            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
   632
        } /* 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
   633
    } /* if */
09a8197fad3b Initial work on ZIPfile support. Not complete. Not very pleased with this
Ryan C. Gordon <icculus@icculus.org>
parents: 29
diff changeset
   634
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
   635
    return retval;
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1111
diff changeset
   636
} /* isZip */
20
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   637
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   638
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   639
/* Convert paths from old, buggy DOS zippers... */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   640
static void zip_convert_dos_path(const PHYSFS_uint16 entryversion, char *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
   641
{
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   642
    const PHYSFS_uint8 hosttype = (PHYSFS_uint8) ((entryversion >> 8) & 0xFF);
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
   643
    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
   644
    {
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
        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
   646
        {
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
            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
   648
                *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
   649
            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
   650
        } /* while */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   651
    } /* 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
   652
} /* zip_convert_dos_path */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   653
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   654
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
   655
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
   656
{
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
   657
    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
   658
    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
   659
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
   660
    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
   661
    {
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
   662
        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
   663
        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
   664
            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
   665
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   666
        if (*(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
   667
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   668
            if (*(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
   669
            {
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
                /* 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
   671
                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
   672
            } /* 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
   673
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   674
            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
   675
            {
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
                /* 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
   677
                *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
   678
            } /* 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
   679
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
   680
            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
   681
            {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   682
                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
   683
                {
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
                    /* 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
   685
                    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
   686
                    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
   687
                    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
   688
                    {
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
                        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
   690
                        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
   691
                        {
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
                            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
   693
                            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
   694
                        } /* 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
   695
                    } /* 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
   696
                } /* 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
   697
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
                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
   699
                {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   700
                    /* 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
   701
                    *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
   702
                } /* if */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   703
            } /* 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
   704
        } /* 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
   705
        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
   706
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   707
            prevptr = ptr;
1162
49950eab0ef8 Fixed infinite loop in zip_expand_symlink_path().
Ryan C. Gordon <icculus@icculus.org>
parents: 1142
diff changeset
   708
            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
   709
        } /* 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
   710
    } /* 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
   711
} /* 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
   712
1579
f8c1de3af573 zip: add some zip_resolve() calls, deal with DirTree-inserted parent dirs.
Ryan C. Gordon <icculus@icculus.org>
parents: 1571
diff changeset
   713
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   714
static inline ZIPentry *zip_find_entry(ZIPinfo *info, const char *path)
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   715
{
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   716
    return (ZIPentry *) __PHYSFS_DirTreeFind(&info->tree, path);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   717
} /* zip_find_entry */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   718
658
1981818c6170 Removed all the forward declaration cruft from the archivers.
Ryan C. Gordon <icculus@icculus.org>
parents: 657
diff changeset
   719
/* (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
   720
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
   721
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   722
/*
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
   723
 * 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
   724
 *  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
   725
 *  hit a real file and then return a pointer to the final non-symlink entry.
1269
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   726
 *  If there's a problem, return NULL.
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   727
 */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   728
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
   729
{
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
   730
    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
   731
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   732
    zip_expand_symlink_path(path);
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   733
    entry = zip_find_entry(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
   734
    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
   735
    {
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   736
        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
   737
            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
   738
        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
   739
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   740
            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
   741
                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
   742
        } /* 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
   743
    } /* 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
   744
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
   745
    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
   746
} /* 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
   747
efdde0d21521 Implementation compiles and links with no actual archive support. No test
Ryan C. Gordon <icculus@icculus.org>
parents: 17
diff changeset
   748
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   749
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
   750
{
1582
526d606206fa Fixed some compiler warnings on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1581
diff changeset
   751
    const size_t size = (size_t) entry->uncompressed_size;
1269
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   752
    char *path = NULL;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   753
    int rc = 0;
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
    /*
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
     * 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
   757
     *  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
   758
     *  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
   759
     */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   760
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   761
    BAIL_IF_ERRPASS(!io->seek(io, entry->offset), 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
   762
1269
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   763
    path = (char *) __PHYSFS_smallAlloc(size + 1);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   764
    BAIL_IF(!path, PHYSFS_ERR_OUT_OF_MEMORY, 0);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   765
    
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   766
    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
   767
        rc = __PHYSFS_readAll(io, path, size);
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   768
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   769
    else  /* symlink target path is compressed... */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   770
    {
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   771
        z_stream stream;
1582
526d606206fa Fixed some compiler warnings on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1581
diff changeset
   772
        const size_t complen = (size_t) 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
   773
        PHYSFS_uint8 *compressed = (PHYSFS_uint8*) __PHYSFS_smallAlloc(complen);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   774
        if (compressed != NULL)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   775
        {
1203
55f147714ce2 Cleaned up all the readAll() cut and paste.
Ryan C. Gordon <icculus@icculus.org>
parents: 1162
diff changeset
   776
            if (__PHYSFS_readAll(io, compressed, complen))
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   777
            {
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 579
diff changeset
   778
                initializeZStream(&stream);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   779
                stream.next_in = compressed;
1457
8b22357e79f0 Fixed some compiler warnings with Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1423
diff changeset
   780
                stream.avail_in = (unsigned int) complen;
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
   781
                stream.next_out = (unsigned char *) path;
1457
8b22357e79f0 Fixed some compiler warnings with Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1423
diff changeset
   782
                stream.avail_out = (unsigned int) size;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   783
                if (zlib_err(inflateInit2(&stream, -MAX_WBITS)) == Z_OK)
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   784
                {
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   785
                    rc = zlib_err(inflate(&stream, Z_FINISH));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   786
                    inflateEnd(&stream);
340
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   787
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   788
                    /* both are acceptable outcomes... */
24a11f8566f8 Symlink fixes. Still broken, though.
Ryan C. Gordon <icculus@icculus.org>
parents: 337
diff changeset
   789
                    rc = ((rc == Z_OK) || (rc == Z_STREAM_END));
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   790
                } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   791
            } /* if */
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 809
diff changeset
   792
            __PHYSFS_smallFree(compressed);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   793
        } /* if */
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   794
    } /* else */
143
337505f94c10 Platform abstracted i/o, other bugfixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   795
1269
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   796
    if (rc)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   797
    {
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
        path[entry->uncompressed_size] = '\0';    /* null-terminate it. */
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   799
        zip_convert_dos_path(entry->version, path);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   800
        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
   801
    } /* 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
   802
1269
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   803
    __PHYSFS_smallFree(path);
8a7e381fbc29 More FIXME cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 1267
diff changeset
   804
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
   805
    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
   806
} /* 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
   807
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
/*
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
 * 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
   811
 */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   812
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
   813
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   814
    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
   815
    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
   816
    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
   817
    PHYSFS_uint16 extralen;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   818
551
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   819
    /*
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   820
     * 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
   821
     *  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
   822
     *  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
   823
     *  aren't zero. That seems to work well.
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   824
     * We also ignore a mismatch if the value is 0xFFFFFFFF here, since it's
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   825
     *  possible that's a Zip64 thing.
551
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   826
     */
f0fc464fd51b Fixed seeking in uncompressed zip entries and handle Java-created JAR files.
Ryan C. Gordon <icculus@icculus.org>
parents: 541
diff changeset
   827
1384
d844add9a935 Added a mostly-harmless FIXME.
Ryan C. Gordon <icculus@icculus.org>
parents: 1383
diff changeset
   828
    /* !!! FIXME: apparently these are zero if general purpose bit 3 is set,
d844add9a935 Added a mostly-harmless FIXME.
Ryan C. Gordon <icculus@icculus.org>
parents: 1383
diff changeset
   829
       !!! FIXME:  which is probably true for Jar files, fwiw, but we don't
d844add9a935 Added a mostly-harmless FIXME.
Ryan C. Gordon <icculus@icculus.org>
parents: 1383
diff changeset
   830
       !!! FIXME:  care about these values anyhow. */
d844add9a935 Added a mostly-harmless FIXME.
Ryan C. Gordon <icculus@icculus.org>
parents: 1383
diff changeset
   831
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   832
    BAIL_IF_ERRPASS(!io->seek(io, entry->offset), 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   833
    BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   834
    BAIL_IF(ui32 != ZIP_LOCAL_FILE_SIG, PHYSFS_ERR_CORRUPT, 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   835
    BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   836
    BAIL_IF(ui16 != entry->version_needed, PHYSFS_ERR_CORRUPT, 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   837
    BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);  /* general bits. */
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   838
    BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   839
    BAIL_IF(ui16 != entry->compression_method, PHYSFS_ERR_CORRUPT, 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   840
    BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);  /* date/time */
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   841
    BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   842
    BAIL_IF(ui32 && (ui32 != entry->crc), PHYSFS_ERR_CORRUPT, 0);
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   843
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   844
    BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   845
    BAIL_IF(ui32 && (ui32 != 0xFFFFFFFF) &&
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   846
                  (ui32 != entry->compressed_size), PHYSFS_ERR_CORRUPT, 0);
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   847
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   848
    BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   849
    BAIL_IF(ui32 && (ui32 != 0xFFFFFFFF) &&
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   850
                 (ui32 != entry->uncompressed_size), PHYSFS_ERR_CORRUPT, 0);
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   851
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   852
    BAIL_IF_ERRPASS(!readui16(io, &fnamelen), 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   853
    BAIL_IF_ERRPASS(!readui16(io, &extralen), 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
   854
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   855
    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
   856
    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
   857
} /* 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
   858
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   859
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   860
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
   861
{
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   862
    int retval = 1;
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   863
    const ZipResolveType resolve_type = entry->resolved;
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   864
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   865
    if (resolve_type == ZIP_DIRECTORY)
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   866
        return 1;   /* we're good. */
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
   867
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   868
    /* Don't bother if we've failed to resolve this entry before. */
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   869
    BAIL_IF(resolve_type == ZIP_BROKEN_FILE, PHYSFS_ERR_CORRUPT, 0);
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   870
    BAIL_IF(resolve_type == ZIP_BROKEN_SYMLINK, PHYSFS_ERR_CORRUPT, 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
   871
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   872
    /* uhoh...infinite symlink loop! */
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1393
diff changeset
   873
    BAIL_IF(resolve_type == ZIP_RESOLVING, PHYSFS_ERR_SYMLINK_LOOP, 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
   874
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   875
    /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   876
     * 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
   877
     *  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
   878
     *  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
   879
     *  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
   880
     *  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
   881
     */
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
    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
   883
    {
1579
f8c1de3af573 zip: add some zip_resolve() calls, deal with DirTree-inserted parent dirs.
Ryan C. Gordon <icculus@icculus.org>
parents: 1571
diff changeset
   884
        if (entry->tree.isdir)  /* an ancestor dir that DirTree filled in? */
f8c1de3af573 zip: add some zip_resolve() calls, deal with DirTree-inserted parent dirs.
Ryan C. Gordon <icculus@icculus.org>
parents: 1571
diff changeset
   885
        {
f8c1de3af573 zip: add some zip_resolve() calls, deal with DirTree-inserted parent dirs.
Ryan C. Gordon <icculus@icculus.org>
parents: 1571
diff changeset
   886
            entry->resolved = ZIP_DIRECTORY;
f8c1de3af573 zip: add some zip_resolve() calls, deal with DirTree-inserted parent dirs.
Ryan C. Gordon <icculus@icculus.org>
parents: 1571
diff changeset
   887
            return 1;
f8c1de3af573 zip: add some zip_resolve() calls, deal with DirTree-inserted parent dirs.
Ryan C. Gordon <icculus@icculus.org>
parents: 1571
diff changeset
   888
        } /* 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
   889
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   890
        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
   891
        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
   892
        {
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   893
            /*
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   894
             * 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
   895
             *  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
   896
             *  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
   897
             */
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   898
            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
   899
                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
   900
        } /* 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
   901
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   902
        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
   903
            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
   904
        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
   905
            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
   906
    } /* 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
   907
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
   908
    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
   909
} /* 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
   910
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
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   912
static int zip_entry_is_symlink(const ZIPentry *entry)
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   913
{
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   914
    return ((entry->resolved == ZIP_UNRESOLVED_SYMLINK) ||
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   915
            (entry->resolved == ZIP_BROKEN_SYMLINK) ||
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   916
            (entry->symlink));
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   917
} /* zip_entry_is_symlink */
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   918
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   919
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
   920
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
   921
{
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   922
    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
   923
    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
   924
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   925
    switch (hosttype)
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   926
    {
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   927
            /*
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   928
             * 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
   929
             *  symlinks, according to the Info-ZIP project.
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   930
             */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   931
        case 0:  /* FS_FAT_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   932
        case 1:  /* AMIGA_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   933
        case 2:  /* VMS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   934
        case 4:  /* VM_CSM_  */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   935
        case 6:  /* FS_HPFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   936
        case 11: /* FS_NTFS_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   937
        case 14: /* FS_VFAT_ */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   938
        case 13: /* ACORN_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   939
        case 15: /* MVS_     */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   940
        case 18: /* THEOS_   */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   941
            break;  /* do nothing. */
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   942
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   943
        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
   944
            retval = 1;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   945
            break;
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   946
    } /* switch */
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   947
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
   948
    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
   949
} /* 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
   950
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   951
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   952
static inline int zip_has_symlink_attr(const ZIPentry *entry,
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   953
                                       const 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
   954
{
342
cef50576cb0b Fixed symlink detection.
Ryan C. Gordon <icculus@icculus.org>
parents: 340
diff changeset
   955
    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
   956
    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
   957
             (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
   958
             ((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
   959
} /* 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
   960
66d9a112b0f7 Now with all directory functions implemented (and debugged?). No file
Ryan C. Gordon <icculus@icculus.org>
parents: 41
diff changeset
   961
538
8752e3c0dbf9 Now compiles on CodeWarrior 6 for MacOS Classic again.
Ryan C. Gordon <icculus@icculus.org>
parents: 504
diff changeset
   962
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
   963
{
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
   964
    PHYSFS_uint32 dosdate;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   965
    struct tm unixtime;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   966
    memset(&unixtime, '\0', sizeof (unixtime));
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   967
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
   968
    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
   969
    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
   970
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   971
    /* 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
   972
    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
   973
    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
   974
    unixtime.tm_mday = ((dosdate     ) & 0x1F);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   975
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
    /* 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
   977
    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
   978
    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
   979
    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
   980
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   981
    /* 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
   982
    unixtime.tm_isdst = -1;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   983
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
   984
    return ((PHYSFS_sint64) mktime(&unixtime));
365
3d087cde1252 My rewrite continues. I'm mostly satisfied with this code now, minus debugging.
Ryan C. Gordon <icculus@icculus.org>
parents: 345
diff changeset
   985
} /* zip_dos_time_to_physfs_time */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   986
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   987
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   988
static ZIPentry *zip_load_entry(ZIPinfo *info, const int zip64,
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   989
                                const PHYSFS_uint64 ofs_fixup)
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   990
{
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
   991
    PHYSFS_Io *io = info->io;
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   992
    ZIPentry entry;
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
   993
    ZIPentry *retval = NULL;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   994
    PHYSFS_uint16 fnamelen, extralen, commentlen;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   995
    PHYSFS_uint32 external_attr;
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   996
    PHYSFS_uint32 starting_disk;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   997
    PHYSFS_uint64 offset;
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   998
    PHYSFS_uint16 ui16;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
   999
    PHYSFS_uint32 ui32;
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1000
    PHYSFS_sint64 si64;
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1001
    char *name = NULL;
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1002
    int isdir = 0;
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1003
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1004
    /* sanity check with central directory signature... */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1005
    BAIL_IF_ERRPASS(!readui32(io, &ui32), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1006
    BAIL_IF(ui32 != ZIP_CENTRAL_DIR_SIG, PHYSFS_ERR_CORRUPT, NULL);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1007
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1008
    memset(&entry, '\0', sizeof (entry));
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1009
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1010
    /* Get the pertinent parts of the record... */
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1011
    BAIL_IF_ERRPASS(!readui16(io, &entry.version), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1012
    BAIL_IF_ERRPASS(!readui16(io, &entry.version_needed), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1013
    BAIL_IF_ERRPASS(!readui16(io, &entry.general_bits), NULL);  /* general bits */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1014
    BAIL_IF_ERRPASS(!readui16(io, &entry.compression_method), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1015
    BAIL_IF_ERRPASS(!readui32(io, &entry.dos_mod_time), NULL);
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1375
diff changeset
  1016
    entry.last_mod_time = zip_dos_time_to_physfs_time(entry.dos_mod_time);
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1017
    BAIL_IF_ERRPASS(!readui32(io, &entry.crc), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1018
    BAIL_IF_ERRPASS(!readui32(io, &ui32), NULL);
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1019
    entry.compressed_size = (PHYSFS_uint64) ui32;
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1020
    BAIL_IF_ERRPASS(!readui32(io, &ui32), NULL);
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1021
    entry.uncompressed_size = (PHYSFS_uint64) ui32;
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1022
    BAIL_IF_ERRPASS(!readui16(io, &fnamelen), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1023
    BAIL_IF_ERRPASS(!readui16(io, &extralen), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1024
    BAIL_IF_ERRPASS(!readui16(io, &commentlen), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1025
    BAIL_IF_ERRPASS(!readui16(io, &ui16), NULL);
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1026
    starting_disk = (PHYSFS_uint32) ui16;
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1027
    BAIL_IF_ERRPASS(!readui16(io, &ui16), NULL);  /* internal file attribs */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1028
    BAIL_IF_ERRPASS(!readui32(io, &external_attr), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1029
    BAIL_IF_ERRPASS(!readui32(io, &ui32), NULL);
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1030
    offset = (PHYSFS_uint64) ui32;
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
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1032
    name = (char *) __PHYSFS_smallAlloc(fnamelen + 1);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1033
    BAIL_IF(!name, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1034
    if (!__PHYSFS_readAll(io, name, fnamelen))
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1035
    {
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1036
        __PHYSFS_smallFree(name);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1037
        return NULL;
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1038
    } /* if */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1039
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1040
    if (name[fnamelen - 1] == '/')
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1041
    {
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1042
        name[fnamelen - 1] = '\0';
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1043
        isdir = 1;
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1044
    } /* if */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1045
    name[fnamelen] = '\0';  /* null-terminate the filename. */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1046
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1047
    zip_convert_dos_path(entry.version, name);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1048
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1049
    retval = (ZIPentry *) __PHYSFS_DirTreeAdd(&info->tree, name, isdir);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1050
    __PHYSFS_smallFree(name);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1051
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1052
    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1053
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1054
    /* It's okay to BAIL without freeing retval, because it's stored in the
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1055
       __PHYSFS_DirTree and will be freed later anyhow. */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1056
    BAIL_IF(retval->last_mod_time != 0, PHYSFS_ERR_CORRUPT, NULL); /* dupe? */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1057
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1058
    /* Move the data we already read into place in the official object. */
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1059
    memcpy(((PHYSFS_uint8 *) retval) + sizeof (__PHYSFS_DirTreeEntry),
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1060
           ((PHYSFS_uint8 *) &entry) + sizeof (__PHYSFS_DirTreeEntry),
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1061
           sizeof (*retval) - sizeof (__PHYSFS_DirTreeEntry));
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1062
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1063
    retval->symlink = NULL;  /* will be resolved later, if necessary. */
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1064
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1065
    if (isdir)
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1066
        retval->resolved = ZIP_DIRECTORY;
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1067
    else
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1068
    {
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1069
        retval->resolved = (zip_has_symlink_attr(retval, external_attr)) ?
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1070
                                ZIP_UNRESOLVED_SYMLINK : ZIP_UNRESOLVED_FILE;
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1071
    } /* else */
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1072
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1073
    si64 = io->tell(io);
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1074
    BAIL_IF_ERRPASS(si64 == -1, NULL);
337
28500f02eb87 ZIP archiver rewrite.
Ryan C. Gordon <icculus@icculus.org>
parents: 335
diff changeset
  1075
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1076
    /* If the actual sizes didn't fit in 32-bits, look for the Zip64
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1077
        extended information extra field... */
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1078
    if ( (zip64) &&
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1079
         ((offset == 0xFFFFFFFF) ||
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1080
          (starting_disk == 0xFFFFFFFF) ||
1372
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1081
          (retval->compressed_size == 0xFFFFFFFF) ||
1a64a2857a0c zip: Reworked how we organize ZIP entries.
Ryan C. Gordon <icculus@icculus.org>
parents: 1369
diff changeset
  1082
          (retval->uncompressed_size == 0xFFFFFFFF)) )
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1083
    {
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1084
        int found = 0;
1581
ad04b99afb88 Fixed some warnings that Xcode brought up.
Ryan C. Gordon <icculus@icculus.org>
parents: 1579
diff changeset
  1085
        PHYSFS_uint16 sig = 0;
ad04b99afb88 Fixed some warnings that Xcode brought up.
Ryan C. Gordon <icculus@icculus.org>
parents: 1579
diff changeset
  1086
        PHYSFS_uint16 len = 0;
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1087
        while (extralen > 4)
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1088
        {
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1089
            BAIL_IF_ERRPASS(!readui16(io, &sig), NULL);
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1090
            BAIL_IF_ERRPASS(!readui16(io, &len), NULL);
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1091
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1092
            si64 += 4 + len;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1093
            extralen -= 4 + len;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1094
            if (sig != ZIP64_EXTENDED_INFO_EXTRA_FIELD_SIG)
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1095
            {
1462
e4995ae256a7 Moved ZIP tree management up to a higher level, to be reused elsewhere.
Ryan C. Gordon <icculus@icculus.org>
parents: 1458
diff changeset
  1096
                BAIL_IF_ERRPASS(!io->seek(io, si64), NULL);
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1097
                continue;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1098
            } /* if */
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1099
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1100
            found = 1;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1101
            break;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
  1102
        } /* while */
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: