paragui-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[paragui-cvs] CVS: paragui/src/physfs/archivers qpak.c,NONE,1.1.2.1 Make


From: Alexander Pipelka <address@hidden>
Subject: [paragui-cvs] CVS: paragui/src/physfs/archivers qpak.c,NONE,1.1.2.1 Makefile.am,1.2.2.1,1.2.2.2 dir.c,1.2.2.1,1.2.2.2 grp.c,1.2.2.1,1.2.2.2 zip.c,1.2.2.1,1.2.2.2 unzip.c,1.2.2.1,NONE unzip.h,1.1.1.1,NONE
Date: Wed, 30 Oct 2002 15:15:50 -0500

Update of /cvsroot/paragui/paragui/src/physfs/archivers
In directory subversions:/tmp/cvs-serv29364/src/physfs/archivers

Modified Files:
      Tag: devel-opengl
        Makefile.am dir.c grp.c zip.c 
Added Files:
      Tag: devel-opengl
        qpak.c 
Removed Files:
      Tag: devel-opengl
        unzip.c unzip.h 
Log Message:
- GCC 3.2 compilation fixes
- updated physfs



--- NEW FILE ---
/*
 * Quake PAK support routines for PhysicsFS.
 *
 * This driver handles id Software Quake PAK files.
 *
 * Please see the file LICENSE in the source's root directory.
 *
 *  This file written by Ed Sinjiashvili.
 */

#if HAVE_CONFIG_H
#  include <config.h>
#endif

#if (defined PHYSFS_SUPPORTS_QPAK)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
#include "physfs.h"

#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"

#define QPAK_MAXDIRLEN 60

typedef struct
{
    char          name[56];
    PHYSFS_uint32 offset;
    PHYSFS_uint32 size;
} QPAKentry;

typedef struct tagQPAKdirentry
{
    char                   *name;
    QPAKentry              *entry;
    struct tagQPAKdirentry *next;
} QPAKdirentry;

typedef struct QPAKDirectory
{
    char name[QPAK_MAXDIRLEN];

    struct QPAKDirectory *dirs, *next;

    QPAKdirentry *files;
} QPAKdirectory;

typedef struct
{
    void               *handle;
    char               *filename;
    PHYSFS_uint32       dirOffset;
    PHYSFS_uint32       totalEntries;
    QPAKentry          *entries;
    QPAKdirectory      *root;
} QPAKinfo;

typedef struct
{
    void         *handle;
    QPAKentry    *entry;
    PHYSFS_sint64 curPos;
} QPAKfileinfo;


static int           QPAK_isArchive(const char *filename, int forWriting);
static DirHandle    *QPAK_openArchive(const char *name, int forWriting);
static void          QPAK_dirClose(DirHandle *h);
static LinkedStringList *QPAK_enumerateFiles(DirHandle *h, const char *dirname,
                                             int omitSymLinks);
static int           QPAK_exists(DirHandle *h, const char *name);
static int           QPAK_isDirectory(DirHandle *h, const char *name, int *e);
static int           QPAK_isSymLink(DirHandle *h, const char *name, int *e);
static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *n, int *e);
static FileHandle   *QPAK_openRead(DirHandle *h, const char *name, int *e);
static FileHandle   *QPAK_openWrite(DirHandle *h, const char *name);
static FileHandle   *QPAK_openAppend(DirHandle *h, const char *name);


static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer,
                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 QPAK_write(FileHandle *handle, const void *buffer,
                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static int           QPAK_eof(FileHandle *handle);
static PHYSFS_sint64 QPAK_tell(FileHandle *handle);
static int           QPAK_seek(FileHandle *handle, PHYSFS_uint64 offset);
static PHYSFS_sint64 QPAK_fileLength(FileHandle *handle);
static int           QPAK_fileClose(FileHandle *handle);
static int           QPAK_remove(DirHandle *h, const char *name);
static int           QPAK_mkdir(DirHandle *h, const char *name);


const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK =
{
    "PAK",
    "Quake PAK file format",
    "Ed Sinjiashvili <address@hidden>",
    "http://icculus.org/physfs/";,
};

static const FileFunctions __PHYSFS_FileFunctions_QPAK =
{
    QPAK_read,               /* read() method       */
    QPAK_write,              /* write() method      */
    QPAK_eof,                /* eof() method        */
    QPAK_tell,               /* tell() method       */
    QPAK_seek,               /* seek() method       */
    QPAK_fileLength,         /* fileLength() method */
    QPAK_fileClose           /* fileClose() method  */
};

const DirFunctions __PHYSFS_DirFunctions_QPAK =
{
    &__PHYSFS_ArchiveInfo_QPAK,
    QPAK_isArchive,          /* isArchive() method      */
    QPAK_openArchive,        /* openArchive() method    */
    QPAK_enumerateFiles,     /* enumerateFiles() method */
    QPAK_exists,             /* exists() method         */
    QPAK_isDirectory,        /* isDirectory() method    */
    QPAK_isSymLink,          /* isSymLink() method      */
    QPAK_getLastModTime,     /* getLastModTime() method */
    QPAK_openRead,           /* openRead() method       */
    QPAK_openWrite,          /* openWrite() method      */
    QPAK_openAppend,         /* openAppend() method     */
    QPAK_remove,             /* remove() method         */
    QPAK_mkdir,              /* mkdir() method          */
    QPAK_dirClose            /* dirClose() method       */
};


#define QPAK_MAGIC 0x4B434150  /* look like "PACK" in ascii. */


/*
 * Read an unsigned 32-bit int and swap to native byte order.
 */
static int readui32(void *in, PHYSFS_uint32 *val)
{
    PHYSFS_uint32 v;
    BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
    *val = PHYSFS_swapULE32(v);
    return(1);
} /* readui32 */


static int openQPak(const char *filename, int forWriting, void **fileHandle)
{
    PHYSFS_uint32 sig;

    *fileHandle = NULL;
    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);

    *fileHandle = __PHYSFS_platformOpenRead(filename);
    BAIL_IF_MACRO(*fileHandle == NULL, NULL, 0);
    
    if (!readui32(*fileHandle, &sig))
        goto openPak_failed;
    
    if (sig != QPAK_MAGIC)
    {
        __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
        goto openPak_failed;
    } /* if */

    return(1);

openPak_failed:
    if (*fileHandle != NULL)
        __PHYSFS_platformClose(*fileHandle);

    *fileHandle = NULL;
    return(0);
} /* openQPak */


static int QPAK_isArchive(const char *filename, int forWriting)
{
    void *fileHandle;
    int retval = openQPak(filename, forWriting, &fileHandle);

    if (fileHandle != NULL)
        __PHYSFS_platformClose(fileHandle);

    return(retval);
} /* QPAK_isArchive */


static int qpak_loadEntries(void *fh, int dirOffset, int numEntries,
                            QPAKentry *entries)
{
    PHYSFS_sint32 i;

    BAIL_IF_MACRO(__PHYSFS_platformSeek(fh, dirOffset) == 0, NULL, 0);

    for (i = 0; i < numEntries; i++, entries++)
    {
        PHYSFS_sint64 r = __PHYSFS_platformRead(fh, entries->name, 56, 1);
        BAIL_IF_MACRO(r == 0, NULL, 0);
        BAIL_IF_MACRO(!readui32(fh, &entries->offset), NULL, 0);
        BAIL_IF_MACRO(!readui32(fh, &entries->size), NULL, 0);
    } /* for */

    return(1);
} /* qpak_loadEntries */


static QPAKdirentry *qpak_newDirentry(char *name, QPAKentry *entry)
{
    QPAKdirentry *retval = (QPAKdirentry *) malloc(sizeof (QPAKdirentry));
    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, 0);

    retval->name  = name;
    retval->entry = entry;
    retval->next  = NULL;

    return(retval);
} /* qpak_newDirentry */


static void qpak_deleteDirentry(QPAKdirentry *e)
{
    while (e != NULL)
    {
        QPAKdirentry *next = e->next;
        free(e);
        e = next;
    } /* while */
} /* qpak_deleteDirentry */


static QPAKdirectory *qpak_newDirectory(char *name)
{
    QPAKdirectory *dir = (QPAKdirectory *) malloc(sizeof (QPAKdirectory));
    BAIL_IF_MACRO(dir == NULL, ERR_OUT_OF_MEMORY, 0);

    strcpy(dir->name, name);
    dir->dirs = NULL;
    dir->next = NULL;
    dir->files = NULL;

    return dir;
} /* qpak_newDirectory */


static void qpak_deleteDirectory(QPAKdirectory *d)
{
    while (d != NULL)
    {
        QPAKdirectory *next = d->next;
        qpak_deleteDirentry(d->files);
        qpak_deleteDirectory(d->dirs);
        free(d);
        d = next;
    } /* while */
} /* qpak_deleteDirectory */


static int qpak_addFile(QPAKdirectory *dir, char *name, QPAKentry *entry)
{
    QPAKdirentry *file = qpak_newDirentry(name, entry);
    if (file == NULL)
        return(0);

    /* !!! FIXME: Traversing a linkedlist gets slower with each added file. */
    if (dir->files == NULL)
    {
        dir->files = file;
    } /* if */
    else
    {
        QPAKdirentry *tail = dir->files;
        while (tail->next != NULL)
            tail = tail->next;

        tail->next = file;
    } /* else */

    return(1);
} /* qpak_addFile */


static QPAKdirectory *qpak_findDirectory(QPAKdirectory *root, const char *name)
{
    char *p = strchr(name, '/');

    if (p == NULL)
    {
        QPAKdirectory *thisDir = root->dirs;
        while (thisDir != NULL)
        {
            if (strcmp(thisDir->name, name) == 0)
                return(thisDir);
            thisDir = thisDir->next;
        } /* while */
    } /* if */

    else
    {
        char temp[QPAK_MAXDIRLEN];
        QPAKdirectory *thisDir = root->dirs;

        strncpy (temp, name, p - name);
        temp[p - name] = '\0';

        while (thisDir != NULL)
        {
            if (strcmp(thisDir->name, temp) == 0)
                return(qpak_findDirectory(thisDir, p + 1));
            thisDir = thisDir->next;
        } /* while */
    } /* else */

    BAIL_MACRO(ERR_NO_SUCH_PATH, 0);
} /* qpak_findDirectory */


static QPAKdirectory *qpak_addDir(QPAKdirectory *dir, char *name)
{
    QPAKdirectory *newDir = qpak_findDirectory(dir, name);
    if (newDir != 0)
        return(newDir);

    newDir = qpak_newDirectory(name);
    if (newDir == 0)
        return 0;

    if (dir->dirs == NULL)
    {
        dir->dirs = newDir;
    } /* if */

    else
    {
        QPAKdirectory *tail = dir->dirs;
        while (tail->next != NULL)
            tail = tail->next;

        tail->next = newDir;
    } /* else */

    return(newDir);
} /* qpak_addDir */


static int qpak_addEntry(QPAKdirectory *dir, char *name, QPAKentry *entry)
{
    char tempName[QPAK_MAXDIRLEN];
    QPAKdirectory *child;
    char *p = strchr(name, '/');
    if (p == NULL)
        return(qpak_addFile(dir, name, entry));

    strncpy(tempName, name, p - name);
    tempName[p - name] = '\0';

    child = qpak_addDir(dir, tempName);
    return(qpak_addEntry(child, p + 1, entry));
} /* qpak_addEntry */


static QPAKentry *qpak_findEntry(QPAKdirectory *root, const char *name)
{
    QPAKdirectory *dir = NULL;
    QPAKdirentry *thisFile = NULL;
    const char *t = strrchr (name, '/');

    if (t == NULL)
    {
        dir = root;
        t = name;
    } /* if */

    else
    {
        char temp[QPAK_MAXDIRLEN];
        strncpy(temp, name, t - name);
        temp[t - name] = '\0';
        dir = qpak_findDirectory(root, temp);
        t++;
    } /* else */

    if (dir == NULL)
        return(0);

    thisFile = dir->files;

    while (thisFile != NULL)
    {
        if (strcmp(thisFile->name, t) == 0)
            return(thisFile->entry);

        thisFile = thisFile->next;
    } /* while */

    BAIL_MACRO(ERR_NO_SUCH_FILE, 0);
} /* qpak_findEntry */


static int qpak_populateDirectories(QPAKentry *entries, int numEntries,
                                    QPAKdirectory *root)
{
    PHYSFS_sint32 i;
    QPAKentry *entry = entries;

    for (i = 0; i < numEntries; i++, entry++)
    {
        if (qpak_addEntry(root, entry->name, entry) == 0)
            return(0);
    } /* for */

    return(1);
} /* qpak_populateDirectories */


static void qpak_deletePakInfo(QPAKinfo *pakInfo)
{
    if (pakInfo->handle != NULL)
        __PHYSFS_platformClose(pakInfo->handle);

    if (pakInfo->filename != NULL)
        free(pakInfo->filename);

    if (pakInfo->entries != NULL)
        free(pakInfo->entries);

    qpak_deleteDirectory(pakInfo->root);

    free(pakInfo);
} /* qpak_deletePakInfo */


static int qpak_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
{
    QPAKentry *a = (QPAKentry *) _a;
    return(strcmp(a[one].name, a[two].name));
} /* qpak_entry_cmp */


static void qpak_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
{
    QPAKentry tmp;
    QPAKentry *first = &(((QPAKentry *) _a)[one]);
    QPAKentry *second = &(((QPAKentry *) _a)[two]);
    memcpy(&tmp, first, sizeof (QPAKentry));
    memcpy(first, second, sizeof (QPAKentry));
    memcpy(second, &tmp, sizeof (QPAKentry));
} /* qpak_entry_swap */


static DirHandle *QPAK_openArchive(const char *name, int forWriting)
{
    void *fh = NULL;
    PHYSFS_uint32 dirOffset, dirLength;
    QPAKinfo *pi;
    DirHandle *retval;

    retval = (DirHandle *) malloc(sizeof (DirHandle));
    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);

    pi = (QPAKinfo *) malloc(sizeof (QPAKinfo));
    if (pi == NULL)
    {
        free(retval);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
    } /* if */

    retval->opaque = pi;

    pi->filename = (char *) malloc(strlen(name) + 1);
    if (pi->filename == NULL)
    {
        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
        goto QPAK_openArchive_failed;
    } /* if */

    if (!openQPak(name, forWriting, &fh))
        goto QPAK_openArchive_failed;

    if (!readui32(fh, &dirOffset))
        goto QPAK_openArchive_failed;

    if (!readui32(fh, &dirLength))
        goto QPAK_openArchive_failed;

    if (__PHYSFS_platformFileLength(fh) < dirOffset + dirLength)
        goto QPAK_openArchive_failed;

    strcpy(pi->filename, name);
    pi->handle = fh;
    pi->dirOffset = dirOffset;
    pi->totalEntries = dirLength / 64;

    pi->entries = (QPAKentry *) malloc(pi->totalEntries * sizeof (QPAKentry));
    if (pi->entries == NULL)
    {
        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
        goto QPAK_openArchive_failed;
    } /* if */

    if (qpak_loadEntries(fh, dirOffset, pi->totalEntries, pi->entries) == 0)
        goto QPAK_openArchive_failed;

    __PHYSFS_sort(pi->entries, pi->totalEntries,
                  qpak_entry_cmp, qpak_entry_swap);

    pi->root = qpak_newDirectory("");
    if (pi->root == NULL)
        goto QPAK_openArchive_failed;

    if (qpak_populateDirectories(pi->entries, pi->totalEntries, pi->root) == 0)
        goto QPAK_openArchive_failed;

    retval->funcs = &__PHYSFS_DirFunctions_QPAK;
    return(retval);

QPAK_openArchive_failed:
    if (retval != NULL)
    {
        if (retval->opaque != NULL)
            qpak_deletePakInfo((QPAKinfo *) retval->opaque);

        free(retval);
    } /* if */

    if (fh != NULL)
        __PHYSFS_platformClose(fh);

    return(0);
} /* QPAK_openArchive */


static void QPAK_dirClose(DirHandle *dirHandle)
{
    qpak_deletePakInfo((QPAKinfo *) dirHandle->opaque);
    free(dirHandle);
} /* QPAK_dirClose */


static LinkedStringList *QPAK_enumerateFiles(DirHandle *h, const char *dirname,
                                             int omitSymLinks)
{
    LinkedStringList *retval = NULL, *p = NULL;
    QPAKdirectory *dir;
    QPAKinfo *info = (QPAKinfo *) h->opaque;

    if ((dirname == NULL) || (*dirname == '\0'))
        dir = info->root;
    else
        dir = qpak_findDirectory(info->root, dirname);

    if (dir != NULL)
    {
        QPAKdirectory *child = dir->dirs;
        QPAKdirentry *file = dir->files;

        while (child != NULL)
        {
            retval = __PHYSFS_addToLinkedStringList(retval, &p, child->name, 
-1);
            child = child->next;
        } /* while */

        while (file != NULL)
        {
            retval = __PHYSFS_addToLinkedStringList(retval, &p, file->name, -1);
            file = file->next;
        } /* while */
    } /* if */

    return(retval);
} /* QPAK_enumerateFiles */


static int QPAK_exists(DirHandle *h, const char *name)
{
    QPAKinfo *driver = (QPAKinfo *) h->opaque;

    if ((name == NULL) || (*name == '\0'))
        return(0);
    
    if (qpak_findDirectory(driver->root, name) != 0)
        return(1);

    if (qpak_findEntry(driver->root, name) != 0)
        return(1);

    return(0);
} /* QPAK_exists */


static int QPAK_isDirectory(DirHandle *h, const char *name, int *fileExists)
{
    QPAKinfo *info = (QPAKinfo *) h->opaque;
    *fileExists = (qpak_findDirectory(info->root, name) != 0);
    return(*fileExists);
} /* QPAK_isDirectory */


static int QPAK_isSymLink(DirHandle *h, const char *name, int *fileExists)
{
    *fileExists = QPAK_exists(h, name);
    return(0); /* we don't support symlinks for now */
} /* QPAK_isSymlink */


static int QPAK_remove(DirHandle *h, const char *name)
{
    BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
} /* QPAK_remove */


static int QPAK_mkdir(DirHandle *h, const char *name)
{
    BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
} /* QPAK_mkdir */


static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h,
                                         const char *name,
                                         int *fileExists)
{
    QPAKinfo *info = (QPAKinfo *) h->opaque;
    PHYSFS_sint64 retval = -1;

    *fileExists = QPAK_exists(h, name);
    if (*fileExists)
        retval = __PHYSFS_platformGetLastModTime(info->filename);

    return(retval);
} /* QPAK_getLastModTime */


static void *qpak_getFileHandle(const char *name, QPAKentry *entry)
{
    void *retval = __PHYSFS_platformOpenRead(name);
    if (retval == NULL)
        return(NULL);

    if (!__PHYSFS_platformSeek(retval, entry->offset))
    {
        __PHYSFS_platformClose(retval);
        return(NULL);
    } /* if */

    return(retval);
} /* qpak_getFileHandle */


static FileHandle *QPAK_openRead(DirHandle *h, const char *fnm, int *fileExists)
{
    QPAKinfo *driver = (QPAKinfo *) h->opaque;
    QPAKentry *entry = qpak_findEntry(driver->root, fnm);
    QPAKfileinfo *fileDriver = 0;
    FileHandle *result = 0;

    *fileExists = (entry != NULL);
    if (entry == NULL)
        return(NULL);
 
    fileDriver = (QPAKfileinfo *) malloc(sizeof (QPAKfileinfo));
    BAIL_IF_MACRO(fileDriver == NULL, ERR_OUT_OF_MEMORY, NULL);
    
    fileDriver->handle = qpak_getFileHandle(driver->filename, entry);
    if (fileDriver->handle == NULL)
    {
        free(fileDriver);
        return(NULL);
    } /* if */

    fileDriver->entry = entry;
    fileDriver->curPos = 0;

    result = (FileHandle *)malloc(sizeof (FileHandle));
    if (result == NULL)
    {
        __PHYSFS_platformClose(fileDriver->handle);
        free(fileDriver);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
    } /* if */

    result->opaque = fileDriver;
    result->dirHandle = h;
    result->funcs = &__PHYSFS_FileFunctions_QPAK;
    return(result);
} /* QPAK_openRead */


static FileHandle *QPAK_openWrite(DirHandle *h, const char *name)
{
    BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
} /* QPAK_openWrite */


static FileHandle *QPAK_openAppend(DirHandle *h, const char *name)
{
    BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
} /* QPAK_openAppend */


static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer,
                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
    QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque);
    QPAKentry *entry = finfo->entry;
    PHYSFS_uint64 bytesLeft = entry->size - finfo->curPos;
    PHYSFS_uint64 objsLeft = (bytesLeft / objSize);
    PHYSFS_sint64 rc;

    if (objsLeft < objCount)
        objCount = (PHYSFS_uint32) objsLeft;

    rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
    if (rc > 0)
        finfo->curPos += (rc * objSize);

    return(rc);
} /* QPAK_read */


static PHYSFS_sint64 QPAK_write(FileHandle *handle, const void *buffer,
                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
    BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* QPAK_write */


static int QPAK_eof(FileHandle *handle)
{
    QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque);
    QPAKentry *entry = finfo->entry;
    
    return(finfo->curPos >= (PHYSFS_sint64) entry->size);
} /* QPAK_eof */


static PHYSFS_sint64 QPAK_tell(FileHandle *handle)
{
    return(((QPAKfileinfo *) handle->opaque)->curPos);
} /* QPAK_tell */


static int QPAK_seek(FileHandle *handle, PHYSFS_uint64 offset)
{
    QPAKfileinfo *finfo = (QPAKfileinfo *) handle->opaque;
    QPAKentry *entry = finfo->entry;
    PHYSFS_uint64 newPos = entry->offset + offset;
    int rc;

    BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
    BAIL_IF_MACRO(newPos > entry->offset + entry->size, ERR_PAST_EOF, 0);
    rc = __PHYSFS_platformSeek(finfo->handle, newPos);
    if (rc)
        finfo->curPos = offset;

    return(rc);
}  /* QPAK_seek */


static PHYSFS_sint64 QPAK_fileLength(FileHandle *handle)
{
    return ((QPAKfileinfo *) handle->opaque)->entry->size;
} /* QPAK_fileLength */


static int QPAK_fileClose(FileHandle *handle)
{
    QPAKfileinfo *finfo = (QPAKfileinfo *) handle->opaque;
    BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
    free(finfo);
    free(handle);
    return(1);
} /* QPAK_fileClose */

#endif  /* defined PHYSFS_SUPPORTS_QPAK */

/* end of qpak.c ... */



Index: Makefile.am
===================================================================
RCS file: /cvsroot/paragui/paragui/src/physfs/archivers/Makefile.am,v
retrieving revision 1.2.2.1
retrieving revision 1.2.2.2
diff -C2 -r1.2.2.1 -r1.2.2.2
*** Makefile.am 31 Aug 2002 04:01:23 -0000      1.2.2.1
--- Makefile.am 30 Oct 2002 20:15:17 -0000      1.2.2.2
***************
*** 10,13 ****
        dir.c           \
        grp.c           \
!       zip.c
  
--- 10,14 ----
        dir.c           \
        grp.c           \
!       zip.c           \
!       qpak.c
  

Index: dir.c
===================================================================
RCS file: /cvsroot/paragui/paragui/src/physfs/archivers/dir.c,v
retrieving revision 1.2.2.1
retrieving revision 1.2.2.2
diff -C2 -r1.2.2.1 -r1.2.2.2
*** dir.c       31 Aug 2002 04:01:23 -0000      1.2.2.1
--- dir.c       30 Oct 2002 20:15:17 -0000      1.2.2.2
***************
*** 25,28 ****
--- 25,32 ----
  static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
                                 PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
+ static PHYSFS_sint64 DIR_dummyRead(FileHandle *handle, void *buffer,
+                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
+ static PHYSFS_sint64 DIR_dummyWrite(FileHandle *handle, const void *buffer,
+                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
  static int DIR_eof(FileHandle *handle);
  static PHYSFS_sint64 DIR_tell(FileHandle *handle);
***************
*** 36,43 ****
                                              int omitSymLinks);
  static int DIR_exists(DirHandle *h, const char *name);
! static int DIR_isDirectory(DirHandle *h, const char *name);
! static int DIR_isSymLink(DirHandle *h, const char *name);
! static FileHandle *DIR_openRead(DirHandle *h, const char *filename);
! static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *name);
  static FileHandle *DIR_openWrite(DirHandle *h, const char *filename);
  static FileHandle *DIR_openAppend(DirHandle *h, const char *filename);
--- 40,47 ----
                                              int omitSymLinks);
  static int DIR_exists(DirHandle *h, const char *name);
! static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists);
! static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists);
! static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist);
! static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *f, int *e);
  static FileHandle *DIR_openWrite(DirHandle *h, const char *filename);
  static FileHandle *DIR_openAppend(DirHandle *h, const char *filename);
***************
*** 59,63 ****
  {
      DIR_read,       /* read() method       */
!     NULL,           /* write() method      */
      DIR_eof,        /* eof() method        */
      DIR_tell,       /* tell() method       */
--- 63,67 ----
  {
      DIR_read,       /* read() method       */
!     DIR_dummyWrite, /* write() method      */
      DIR_eof,        /* eof() method        */
      DIR_tell,       /* tell() method       */
***************
*** 70,74 ****
  static const FileFunctions __PHYSFS_FileFunctions_DIRW =
  {
!     NULL,           /* read() method       */
      DIR_write,      /* write() method      */
      DIR_eof,        /* eof() method        */
--- 74,78 ----
  static const FileFunctions __PHYSFS_FileFunctions_DIRW =
  {
!     DIR_dummyRead,  /* read() method       */
      DIR_write,      /* write() method      */
      DIR_eof,        /* eof() method        */
***************
*** 117,120 ****
--- 121,138 ----
  
  
+ static PHYSFS_sint64 DIR_dummyRead(FileHandle *handle, void *buffer,
+                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
+ } /* DIR_dummyRead */
+ 
+ 
+ static PHYSFS_sint64 DIR_dummyWrite(FileHandle *handle, const void *buffer,
+                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
+ } /* DIR_dummyWrite */
+ 
+ 
  static int DIR_eof(FileHandle *handle)
  {
***************
*** 218,228 ****
  
  
! static int DIR_isDirectory(DirHandle *h, const char *name)
  {
      char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, 
NULL);
!     int retval;
  
      BAIL_IF_MACRO(d == NULL, NULL, 0);
!     retval = __PHYSFS_platformIsDirectory(d);
      free(d);
      return(retval);
--- 236,248 ----
  
  
! static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists)
  {
      char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, 
NULL);
!     int retval = 0;
  
      BAIL_IF_MACRO(d == NULL, NULL, 0);
!     *fileExists = __PHYSFS_platformExists(d);
!     if (*fileExists)
!         retval = __PHYSFS_platformIsDirectory(d);
      free(d);
      return(retval);
***************
*** 230,240 ****
  
  
! static int DIR_isSymLink(DirHandle *h, const char *name)
  {
      char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, 
NULL);
!     int retval;
  
      BAIL_IF_MACRO(f == NULL, NULL, 0);
!     retval = __PHYSFS_platformIsSymLink(f);
      free(f);
      return(retval);
--- 250,262 ----
  
  
! static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists)
  {
      char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, 
NULL);
!     int retval = 0;
  
      BAIL_IF_MACRO(f == NULL, NULL, 0);
!     *fileExists = __PHYSFS_platformExists(f);
!     if (*fileExists)
!         retval = __PHYSFS_platformIsSymLink(f);
      free(f);
      return(retval);
***************
*** 242,252 ****
  
  
! static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *name)
  {
      char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, 
NULL);
!     PHYSFS_sint64 retval;
  
      BAIL_IF_MACRO(d == NULL, NULL, 0);
!     retval = __PHYSFS_platformGetLastModTime(d);
      free(d);
      return(retval);
--- 264,278 ----
  
  
! static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h,
!                                         const char *name,
!                                         int *fileExists)
  {
      char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, 
NULL);
!     PHYSFS_sint64 retval = -1;
  
      BAIL_IF_MACRO(d == NULL, NULL, 0);
!     *fileExists = __PHYSFS_platformExists(d);
!     if (*fileExists)
!         retval = __PHYSFS_platformGetLastModTime(d);
      free(d);
      return(retval);
***************
*** 256,260 ****
  static FileHandle *doOpen(DirHandle *h, const char *name,
                            void *(*openFunc)(const char *filename),
!                           const FileFunctions *fileFuncs)
  {
      char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, 
NULL);
--- 282,286 ----
  static FileHandle *doOpen(DirHandle *h, const char *name,
                            void *(*openFunc)(const char *filename),
!                           int *fileExists, const FileFunctions *fileFuncs)
  {
      char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, 
NULL);
***************
*** 264,267 ****
--- 290,303 ----
      BAIL_IF_MACRO(f == NULL, NULL, NULL);
  
+     if (fileExists != NULL)
+     {
+         *fileExists = __PHYSFS_platformExists(f);
+         if (!(*fileExists))
+         {
+             free(f);
+             return(NULL);
+         } /* if */
+     } /* if */
+ 
      retval = (FileHandle *) malloc(sizeof (FileHandle));
      if (!retval)
***************
*** 288,294 ****
  
  
! static FileHandle *DIR_openRead(DirHandle *h, const char *filename)
  {
!     return(doOpen(h, filename, __PHYSFS_platformOpenRead,
                    &__PHYSFS_FileFunctions_DIR));
  } /* DIR_openRead */
--- 324,330 ----
  
  
! static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist)
  {
!     return(doOpen(h, fnm, __PHYSFS_platformOpenRead, exist,
                    &__PHYSFS_FileFunctions_DIR));
  } /* DIR_openRead */
***************
*** 297,301 ****
  static FileHandle *DIR_openWrite(DirHandle *h, const char *filename)
  {
!     return(doOpen(h, filename, __PHYSFS_platformOpenWrite,
                    &__PHYSFS_FileFunctions_DIRW));
  } /* DIR_openWrite */
--- 333,337 ----
  static FileHandle *DIR_openWrite(DirHandle *h, const char *filename)
  {
!     return(doOpen(h, filename, __PHYSFS_platformOpenWrite, NULL,
                    &__PHYSFS_FileFunctions_DIRW));
  } /* DIR_openWrite */
***************
*** 304,308 ****
  static FileHandle *DIR_openAppend(DirHandle *h, const char *filename)
  {
!     return(doOpen(h, filename, __PHYSFS_platformOpenAppend,
                    &__PHYSFS_FileFunctions_DIRW));
  } /* DIR_openAppend */
--- 340,344 ----
  static FileHandle *DIR_openAppend(DirHandle *h, const char *filename)
  {
!     return(doOpen(h, filename, __PHYSFS_platformOpenAppend, NULL,
                    &__PHYSFS_FileFunctions_DIRW));
  } /* DIR_openAppend */

Index: grp.c
===================================================================
RCS file: /cvsroot/paragui/paragui/src/physfs/archivers/grp.c,v
retrieving revision 1.2.2.1
retrieving revision 1.2.2.2
diff -C2 -r1.2.2.1 -r1.2.2.2
*** grp.c       31 Aug 2002 04:01:23 -0000      1.2.2.1
--- grp.c       30 Oct 2002 20:15:17 -0000      1.2.2.2
***************
*** 42,57 ****
  #include "physfs_internal.h"
  
- /*
-  * When sorting the grp entries in an archive, we use a modified QuickSort.
-  *  When there are less then GRP_QUICKSORT_THRESHOLD entries left to sort,
-  *  we switch over to an InsertionSort for the remainder. Tweak to taste.
-  */
- #define GRP_QUICKSORT_THRESHOLD 4
- 
  typedef struct
  {
      char name[13];
!     PHYSFS_uint64 startPos;
!     PHYSFS_uint64 size;
  } GRPentry;
  
--- 42,50 ----
  #include "physfs_internal.h"
  
  typedef struct
  {
      char name[13];
!     PHYSFS_uint32 startPos;
!     PHYSFS_uint32 size;
  } GRPentry;
  
***************
*** 68,72 ****
      void *handle;
      GRPentry *entry;
!     PHYSFS_sint64 curPos;
  } GRPfileinfo;
  
--- 61,65 ----
      void *handle;
      GRPentry *entry;
!     PHYSFS_uint32 curPos;
  } GRPfileinfo;
  
***************
*** 75,78 ****
--- 68,73 ----
  static PHYSFS_sint64 GRP_read(FileHandle *handle, void *buffer,
                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
+ static PHYSFS_sint64 GRP_write(FileHandle *handle, const void *buffer,
+                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
  static int GRP_eof(FileHandle *handle);
  static PHYSFS_sint64 GRP_tell(FileHandle *handle);
***************
*** 86,93 ****
                                              int omitSymLinks);
  static int GRP_exists(DirHandle *h, const char *name);
! static int GRP_isDirectory(DirHandle *h, const char *name);
! static int GRP_isSymLink(DirHandle *h, const char *name);
! static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *name);
! static FileHandle *GRP_openRead(DirHandle *h, const char *name);
  
  const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP =
--- 81,92 ----
                                              int omitSymLinks);
  static int GRP_exists(DirHandle *h, const char *name);
! static int GRP_isDirectory(DirHandle *h, const char *name, int *fileExists);
! static int GRP_isSymLink(DirHandle *h, const char *name, int *fileExists);
! static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *n, int *e);
! static FileHandle *GRP_openRead(DirHandle *h, const char *name, int *exist);
! static FileHandle *GRP_openWrite(DirHandle *h, const char *name);
! static FileHandle *GRP_openAppend(DirHandle *h, const char *name);
! static int GRP_remove(DirHandle *h, const char *name);
! static int GRP_mkdir(DirHandle *h, const char *name);
  
  const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP =
***************
*** 103,107 ****
  {
      GRP_read,       /* read() method       */
!     NULL,           /* write() method      */
      GRP_eof,        /* eof() method        */
      GRP_tell,       /* tell() method       */
--- 102,106 ----
  {
      GRP_read,       /* read() method       */
!     GRP_write,      /* write() method      */
      GRP_eof,        /* eof() method        */
      GRP_tell,       /* tell() method       */
***************
*** 123,130 ****
      GRP_getLastModTime,     /* getLastModTime() method */
      GRP_openRead,           /* openRead() method       */
!     NULL,                   /* openWrite() method      */
!     NULL,                   /* openAppend() method     */
!     NULL,                   /* remove() method         */
!     NULL,                   /* mkdir() method          */
      GRP_dirClose            /* dirClose() method       */
  };
--- 122,129 ----
      GRP_getLastModTime,     /* getLastModTime() method */
      GRP_openRead,           /* openRead() method       */
!     GRP_openWrite,          /* openWrite() method      */
!     GRP_openAppend,         /* openAppend() method     */
!     GRP_remove,             /* remove() method         */
!     GRP_mkdir,              /* mkdir() method          */
      GRP_dirClose            /* dirClose() method       */
  };
***************
*** 147,160 ****
      GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
      GRPentry *entry = finfo->entry;
!     PHYSFS_uint64 bytesLeft = entry->size - finfo->curPos;
!     PHYSFS_uint64 objsLeft = (bytesLeft / objSize);
      PHYSFS_sint64 rc;
  
      if (objsLeft < objCount)
!         objCount = (PHYSFS_uint32) objsLeft;
  
      rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
      if (rc > 0)
!         finfo->curPos += (rc * objSize);
  
      return(rc);
--- 146,159 ----
      GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
      GRPentry *entry = finfo->entry;
!     PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
!     PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
      PHYSFS_sint64 rc;
  
      if (objsLeft < objCount)
!         objCount = objsLeft;
  
      rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
      if (rc > 0)
!         finfo->curPos += (PHYSFS_uint32) (rc * objSize);
  
      return(rc);
***************
*** 162,170 ****
  
  
  static int GRP_eof(FileHandle *handle)
  {
      GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
      GRPentry *entry = finfo->entry;
!     return(finfo->curPos >= (PHYSFS_sint64) entry->size);
  } /* GRP_eof */
  
--- 161,176 ----
  
  
+ static PHYSFS_sint64 GRP_write(FileHandle *handle, const void *buffer,
+                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
+ } /* GRP_write */
+ 
+ 
  static int GRP_eof(FileHandle *handle)
  {
      GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
      GRPentry *entry = finfo->entry;
!     return(finfo->curPos >= entry->size);
  } /* GRP_eof */
  
***************
*** 180,191 ****
      GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
      GRPentry *entry = finfo->entry;
-     PHYSFS_uint64 newPos = (entry->startPos + offset);
      int rc;
  
      BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
!     BAIL_IF_MACRO(newPos > entry->startPos + entry->size, ERR_PAST_EOF, 0);
!     rc = __PHYSFS_platformSeek(finfo->handle, newPos);
      if (rc)
!         finfo->curPos = offset;
  
      return(rc);
--- 186,196 ----
      GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
      GRPentry *entry = finfo->entry;
      int rc;
  
      BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
!     BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
!     rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
      if (rc)
!         finfo->curPos = (PHYSFS_uint32) offset;
  
      return(rc);
***************
*** 195,199 ****
  static PHYSFS_sint64 GRP_fileLength(FileHandle *handle)
  {
!     return(((GRPfileinfo *) handle->opaque)->entry->size);
  } /* GRP_fileLength */
  
--- 200,205 ----
  static PHYSFS_sint64 GRP_fileLength(FileHandle *handle)
  {
!     GRPfileinfo *finfo = ((GRPfileinfo *) handle->opaque);
!     return((PHYSFS_sint64) finfo->entry->size);
  } /* GRP_fileLength */
  
***************
*** 259,334 ****
  
  
! static void grp_entry_swap(GRPentry *a, PHYSFS_uint32 one, PHYSFS_uint32 two)
  {
!     GRPentry tmp;
!     memcpy(&tmp, &a[one], sizeof (GRPentry));
!     memcpy(&a[one], &a[two], sizeof (GRPentry));
!     memcpy(&a[two], &tmp, sizeof (GRPentry));
! } /* grp_entry_swap */
  
  
! static void grp_quick_sort(GRPentry *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi)
  {
-     PHYSFS_uint32 i;
-     PHYSFS_uint32 j;
-     GRPentry *v;
- 
-       if ((hi - lo) > GRP_QUICKSORT_THRESHOLD)
-       {
-               i = (hi + lo) / 2;
- 
-               if (strcmp(a[lo].name, a[i].name) > 0) grp_entry_swap(a, lo, i);
-               if (strcmp(a[lo].name, a[hi].name) > 0) grp_entry_swap(a, lo, 
hi);
-               if (strcmp(a[i].name, a[hi].name) > 0) grp_entry_swap(a, i, hi);
- 
-               j = hi - 1;
-               grp_entry_swap(a, i, j);
-               i = lo;
-               v = &a[j];
-               while (1)
-               {
-                       while(strcmp(a[++i].name, v->name) < 0) {}
-                       while(strcmp(a[--j].name, v->name) > 0) {}
-                       if (j < i)
-                 break;
-                       grp_entry_swap(a, i, j);
-               } /* while */
-               grp_entry_swap(a, i, hi-1);
-               grp_quick_sort(a, lo, j);
-               grp_quick_sort(a, i+1, hi);
-       } /* if */
- } /* grp_quick_sort */
- 
- 
- static void grp_insertion_sort(GRPentry *a, PHYSFS_uint32 lo, PHYSFS_uint32 
hi)
- {
-     PHYSFS_uint32 i;
-     PHYSFS_uint32 j;
      GRPentry tmp;
! 
!     for (i = lo + 1; i <= hi; i++)
!     {
!         memcpy(&tmp, &a[i], sizeof (GRPentry));
!         j = i;
!         while ((j > lo) && (strcmp(a[j - 1].name, tmp.name) > 0))
!         {
!             memcpy(&a[j], &a[j - 1], sizeof (GRPentry));
!             j--;
!         } /* while */
!         memcpy(&a[j], &tmp, sizeof (GRPentry));
!     } /* for */
! } /* grp_insertion_sort */
! 
! 
! static void grp_sort_entries(GRPentry *entries, PHYSFS_uint32 max)
! {
!     /*
!      * Fast Quicksort algorithm inspired by code from here:
!      *   http://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
!      */
!     if (max <= GRP_QUICKSORT_THRESHOLD)
!         grp_quick_sort(entries, 0, max - 1);
!       grp_insertion_sort(entries, 0, max - 1);
! } /* grp_sort_entries */
  
  
--- 265,284 ----
  
  
! static int grp_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
  {
!     GRPentry *a = (GRPentry *) _a;
!     return(strcmp(a[one].name, a[two].name));
! } /* grp_entry_cmp */
  
  
! static void grp_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
  {
      GRPentry tmp;
!     GRPentry *first = &(((GRPentry *) _a)[one]);
!     GRPentry *second = &(((GRPentry *) _a)[two]);
!     memcpy(&tmp, first, sizeof (GRPentry));
!     memcpy(first, second, sizeof (GRPentry));
!     memcpy(second, &tmp, sizeof (GRPentry));
! } /* grp_entry_swap */
  
  
***************
*** 377,381 ****
      __PHYSFS_platformClose(fh);
  
!     grp_sort_entries(info->entries, info->entryCount);
      return(1);
  } /* grp_load_entries */
--- 327,332 ----
      __PHYSFS_platformClose(fh);
  
!     __PHYSFS_sort(info->entries, info->entryCount,
!                   grp_entry_cmp, grp_entry_swap);
      return(1);
  } /* grp_load_entries */
***************
*** 490,517 ****
  
  
! static int GRP_isDirectory(DirHandle *h, const char *name)
  {
      return(0);  /* never directories in a groupfile. */
  } /* GRP_isDirectory */
  
  
! static int GRP_isSymLink(DirHandle *h, const char *name)
  {
      return(0);  /* never symlinks in a groupfile. */
  } /* GRP_isSymLink */
  
  
! static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *name)
  {
      GRPinfo *info = ((GRPinfo *) h->opaque);
!     if (grp_find_entry(info, name) == NULL)
!         return(-1);  /* no such entry. */
  
!     /* Just return the time of the GRP itself in the physical filesystem. */
!     return(((GRPinfo *) h->opaque)->last_mod_time);
  } /* GRP_getLastModTime */
  
  
! static FileHandle *GRP_openRead(DirHandle *h, const char *name)
  {
      GRPinfo *info = ((GRPinfo *) h->opaque);
--- 441,474 ----
  
  
! static int GRP_isDirectory(DirHandle *h, const char *name, int *fileExists)
  {
+     *fileExists = GRP_exists(h, name);
      return(0);  /* never directories in a groupfile. */
  } /* GRP_isDirectory */
  
  
! static int GRP_isSymLink(DirHandle *h, const char *name, int *fileExists)
  {
+     *fileExists = GRP_exists(h, name);
      return(0);  /* never symlinks in a groupfile. */
  } /* GRP_isSymLink */
  
  
! static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h,
!                                         const char *name,
!                                         int *fileExists)
  {
      GRPinfo *info = ((GRPinfo *) h->opaque);
!     PHYSFS_sint64 retval = -1;
! 
!     *fileExists = (grp_find_entry(info, name) != NULL);
!     if (*fileExists)  /* use time of GRP itself in the physical filesystem. */
!         retval = ((GRPinfo *) h->opaque)->last_mod_time;
  
!     return(retval);
  } /* GRP_getLastModTime */
  
  
! static FileHandle *GRP_openRead(DirHandle *h, const char *fnm, int 
*fileExists)
  {
      GRPinfo *info = ((GRPinfo *) h->opaque);
***************
*** 520,524 ****
      GRPentry *entry;
  
!     entry = grp_find_entry(info, name);
      BAIL_IF_MACRO(entry == NULL, NULL, NULL);
  
--- 477,482 ----
      GRPentry *entry;
  
!     entry = grp_find_entry(info, fnm);
!     *fileExists = (entry != NULL);
      BAIL_IF_MACRO(entry == NULL, NULL, NULL);
  
***************
*** 548,551 ****
--- 506,533 ----
      return(retval);
  } /* GRP_openRead */
+ 
+ 
+ static FileHandle *GRP_openWrite(DirHandle *h, const char *name)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
+ } /* GRP_openWrite */
+ 
+ 
+ static FileHandle *GRP_openAppend(DirHandle *h, const char *name)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
+ } /* GRP_openAppend */
+ 
+ 
+ static int GRP_remove(DirHandle *h, const char *name)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
+ } /* GRP_remove */
+ 
+ 
+ static int GRP_mkdir(DirHandle *h, const char *name)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
+ } /* GRP_mkdir */
  
  #endif  /* defined PHYSFS_SUPPORTS_GRP */

Index: zip.c
===================================================================
RCS file: /cvsroot/paragui/paragui/src/physfs/archivers/zip.c,v
retrieving revision 1.2.2.1
retrieving revision 1.2.2.2
diff -C2 -r1.2.2.1 -r1.2.2.2
*** zip.c       31 Aug 2002 04:01:24 -0000      1.2.2.1
--- zip.c       30 Oct 2002 20:15:18 -0000      1.2.2.2
***************
*** 28,38 ****
  
  /*
-  * When sorting the zip entries in an archive, we use a modified QuickSort.
-  *  When there are less then ZIP_QUICKSORT_THRESHOLD entries left to sort,
-  *  we switch over to an InsertionSort for the remainder. Tweak to taste.
-  */
- #define ZIP_QUICKSORT_THRESHOLD 4
- 
- /*
   * A buffer of ZIP_READBUFSIZE is malloc() for each compressed file opened,
   *  and is free()'d when you close the file; compressed data is read into
--- 28,31 ----
***************
*** 126,129 ****
--- 119,124 ----
  static PHYSFS_sint64 ZIP_read(FileHandle *handle, void *buffer,
                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
+ static PHYSFS_sint64 ZIP_write(FileHandle *handle, const void *buffer,
+                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
  static int ZIP_eof(FileHandle *handle);
  static PHYSFS_sint64 ZIP_tell(FileHandle *handle);
***************
*** 137,146 ****
                                              int omitSymLinks);
  static int ZIP_exists(DirHandle *h, const char *name);
! static int ZIP_isDirectory(DirHandle *h, const char *name);
! static int ZIP_isSymLink(DirHandle *h, const char *name);
! static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *name);
! static FileHandle *ZIP_openRead(DirHandle *h, const char *filename);
  static void ZIP_dirClose(DirHandle *h);
  static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry);
  
  
--- 132,145 ----
                                              int omitSymLinks);
  static int ZIP_exists(DirHandle *h, const char *name);
! static int ZIP_isDirectory(DirHandle *h, const char *name, int *fileExists);
! static int ZIP_isSymLink(DirHandle *h, const char *name, int *fileExists);
! static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *n, int *e);
! static FileHandle *ZIP_openRead(DirHandle *h, const char *filename, int *e);
! static FileHandle *ZIP_openWrite(DirHandle *h, const char *filename);
! static FileHandle *ZIP_openAppend(DirHandle *h, const char *filename);
  static void ZIP_dirClose(DirHandle *h);
  static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry);
+ static int ZIP_remove(DirHandle *h, const char *name);
+ static int ZIP_mkdir(DirHandle *h, const char *name);
  
  
***************
*** 156,160 ****
  {
      ZIP_read,       /* read() method       */
!     NULL,           /* write() method      */
      ZIP_eof,        /* eof() method        */
      ZIP_tell,       /* tell() method       */
--- 155,159 ----
  {
      ZIP_read,       /* read() method       */
!     ZIP_write,      /* write() method      */
      ZIP_eof,        /* eof() method        */
      ZIP_tell,       /* tell() method       */
***************
*** 176,183 ****
      ZIP_getLastModTime,     /* getLastModTime() method */
      ZIP_openRead,           /* openRead() method       */
!     NULL,                   /* openWrite() method      */
!     NULL,                   /* openAppend() method     */
!     NULL,                   /* remove() method         */
!     NULL,                   /* mkdir() method          */
      ZIP_dirClose            /* dirClose() method       */
  };
--- 175,182 ----
      ZIP_getLastModTime,     /* getLastModTime() method */
      ZIP_openRead,           /* openRead() method       */
!     ZIP_openWrite,          /* openWrite() method      */
!     ZIP_openAppend,         /* openAppend() method     */
!     ZIP_remove,             /* remove() method         */
!     ZIP_mkdir,              /* mkdir() method          */
      ZIP_dirClose            /* dirClose() method       */
  };
***************
*** 313,316 ****
--- 312,322 ----
  
  
+ static PHYSFS_sint64 ZIP_write(FileHandle *handle, const void *buf,
+                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
+ } /* ZIP_write */
+ 
+ 
  static int ZIP_eof(FileHandle *handle)
  {
***************
*** 493,497 ****
  {
      PHYSFS_uint32 sig;
!     int retval;
      void *in;
  
--- 499,503 ----
  {
      PHYSFS_uint32 sig;
!     int retval = 0;
      void *in;
  
***************
*** 503,520 ****
       *  first local file record, so it makes for a quick determination.
       */
!     if(!readui32(in, &sig))
!     {
!       __PHYSFS_platformClose(in);
!       BAIL_IF_MACRO(1, NULL, 0);
!     }
!     retval = (sig == ZIP_LOCAL_FILE_SIG);
!     if (!retval)
      {
!         /*
!          * No sig...might be a ZIP with data at the start
!          *  (a self-extracting executable, etc), so we'll have to do
!          *  it the hard way...
!          */
!         retval = (zip_find_end_of_central_dir(in, NULL) != -1);
      } /* if */
  
--- 509,524 ----
       *  first local file record, so it makes for a quick determination.
       */
!     if (readui32(in, &sig))
      {
!         retval = (sig == ZIP_LOCAL_FILE_SIG);
!         if (!retval)
!         {
!             /*
!              * No sig...might be a ZIP with data at the start
!              *  (a self-extracting executable, etc), so we'll have to do
!              *  it the hard way...
!              */
!             retval = (zip_find_end_of_central_dir(in, NULL) != -1);
!         } /* if */
      } /* if */
  
***************
*** 538,547 ****
  
  
! static ZIPentry *zip_find_entry(ZIPinfo *info, const char *path)
  {
      ZIPentry *a = info->entries;
      PHYSFS_sint32 lo = 0;
      PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
      PHYSFS_sint32 middle;
      int rc;
  
--- 542,558 ----
  
  
! /*
!  * This will find the ZIPentry associated with a path in platform-independent
!  *  notation. Directories don't have ZIPentries associated with them, but 
!  *  (*isDir) will be set to non-zero if a dir was hit.
!  */
! static ZIPentry *zip_find_entry(ZIPinfo *info, const char *path, int *isDir)
  {
      ZIPentry *a = info->entries;
+     PHYSFS_sint32 pathlen = strlen(path);
      PHYSFS_sint32 lo = 0;
      PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
      PHYSFS_sint32 middle;
+     const char *thispath = NULL;
      int rc;
  
***************
*** 549,561 ****
      {
          middle = lo + ((hi - lo) / 2);
!         rc = strcmp(path, a[middle].name);
!         if (rc == 0)  /* found it! */
!             return(&a[middle]);
!         else if (rc > 0)
              lo = middle + 1;
!         else
              hi = middle - 1;
      } /* while */
  
      BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
  } /* zip_find_entry */
--- 560,591 ----
      {
          middle = lo + ((hi - lo) / 2);
!         thispath = a[middle].name;
!         rc = strncmp(path, thispath, pathlen);
! 
!         if (rc > 0)
              lo = middle + 1;
! 
!         else if (rc < 0)
              hi = middle - 1;
+ 
+         else /* substring match...might be dir or entry or nothing. */
+         {
+             if (isDir != NULL)
+             {
+                 *isDir = (thispath[pathlen] == '/');
+                 if (*isDir)
+                     return(NULL);
+             } /* if */
+ 
+             if (thispath[pathlen] == '\0') /* found entry? */
+                 return(&a[middle]);
+             else
+                 hi = middle - 1;  /* adjust search params, try again. */
+         } /* if */
      } /* while */
  
+     if (isDir != NULL)
+         *isDir = 0;
+ 
      BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
  } /* zip_find_entry */
***************
*** 648,652 ****
  
      zip_expand_symlink_path(path);
!     entry = zip_find_entry(info, path);
      if (entry != NULL)
      {
--- 678,682 ----
  
      zip_expand_symlink_path(path);
!     entry = zip_find_entry(info, path, NULL);
      if (entry != NULL)
      {
***************
*** 940,1015 ****
  
  
! static void zip_entry_swap(ZIPentry *a, PHYSFS_uint32 one, PHYSFS_uint32 two)
! {
!     ZIPentry tmp;
!     memcpy(&tmp, &a[one], sizeof (ZIPentry));
!     memcpy(&a[one], &a[two], sizeof (ZIPentry));
!     memcpy(&a[two], &tmp, sizeof (ZIPentry));
! } /* zip_entry_swap */
! 
! 
! static void zip_quick_sort(ZIPentry *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi)
  {
!     PHYSFS_uint32 i;
!     PHYSFS_uint32 j;
!     ZIPentry *v;
! 
!       if ((hi - lo) > ZIP_QUICKSORT_THRESHOLD)
!       {
!               i = (hi + lo) / 2;
! 
!               if (strcmp(a[lo].name, a[i].name) > 0) zip_entry_swap(a, lo, i);
!               if (strcmp(a[lo].name, a[hi].name) > 0) zip_entry_swap(a, lo, 
hi);
!               if (strcmp(a[i].name, a[hi].name) > 0) zip_entry_swap(a, i, hi);
! 
!               j = hi - 1;
!               zip_entry_swap(a, i, j);
!               i = lo;
!               v = &a[j];
!               while (1)
!               {
!                       while(strcmp(a[++i].name, v->name) < 0) {}
!                       while(strcmp(a[--j].name, v->name) > 0) {}
!                       if (j < i)
!                 break;
!                       zip_entry_swap(a, i, j);
!               } /* while */
!               zip_entry_swap(a, i, hi-1);
!               zip_quick_sort(a, lo, j);
!               zip_quick_sort(a, i+1, hi);
!       } /* if */
! } /* zip_quick_sort */
  
  
! static void zip_insertion_sort(ZIPentry *a, PHYSFS_uint32 lo, PHYSFS_uint32 
hi)
  {
-     PHYSFS_uint32 i;
-     PHYSFS_uint32 j;
      ZIPentry tmp;
! 
!     for (i = lo + 1; i <= hi; i++)
!     {
!         memcpy(&tmp, &a[i], sizeof (ZIPentry));
!         j = i;
!         while ((j > lo) && (strcmp(a[j - 1].name, tmp.name) > 0))
!         {
!             memcpy(&a[j], &a[j - 1], sizeof (ZIPentry));
!             j--;
!         } /* while */
!         memcpy(&a[j], &tmp, sizeof (ZIPentry));
!     } /* for */
! } /* zip_insertion_sort */
! 
! 
! static void zip_sort_entries(ZIPentry *entries, PHYSFS_uint32 max)
! {
!     /*
!      * Fast Quicksort algorithm inspired by code from here:
!      *   http://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
!      */
!     if (max <= ZIP_QUICKSORT_THRESHOLD)
!         zip_quick_sort(entries, 0, max - 1);
!       zip_insertion_sort(entries, 0, max - 1);
! } /* zip_sort_entries */
  
  
--- 970,989 ----
  
  
! static int zip_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
  {
!     ZIPentry *a = (ZIPentry *) _a;
!     return(strcmp(a[one].name, a[two].name));
! } /* zip_entry_cmp */
  
  
! static void zip_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
  {
      ZIPentry tmp;
!     ZIPentry *first = &(((ZIPentry *) _a)[one]);
!     ZIPentry *second = &(((ZIPentry *) _a)[two]);
!     memcpy(&tmp, first, sizeof (ZIPentry));
!     memcpy(first, second, sizeof (ZIPentry));
!     memcpy(second, &tmp, sizeof (ZIPentry));
! } /* zip_entry_swap */
  
  
***************
*** 1035,1039 ****
      } /* for */
  
!     zip_sort_entries(info->entries, max);
      return(1);
  } /* zip_load_entries */
--- 1009,1013 ----
      } /* for */
  
!     __PHYSFS_sort(info->entries, max, zip_entry_cmp, zip_entry_swap);
      return(1);
  } /* zip_load_entries */
***************
*** 1053,1057 ****
      pos = zip_find_end_of_central_dir(in, &len);
      BAIL_IF_MACRO(pos == -1, NULL, 0);
!       BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, pos), NULL, 0);
  
      /* check signature again, just in case. */
--- 1027,1031 ----
      pos = zip_find_end_of_central_dir(in, &len);
      BAIL_IF_MACRO(pos == -1, NULL, 0);
!     BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, pos), NULL, 0);
  
      /* check signature again, just in case. */
***************
*** 1059,1081 ****
      BAIL_IF_MACRO(ui32 != ZIP_END_OF_CENTRAL_DIR_SIG, ERR_NOT_AN_ARCHIVE, 0);
  
!       /* number of this disk */
      BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
      BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
  
!       /* number of the disk with the start of the central directory */
      BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
      BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
  
!       /* total number of entries in the central dir on this disk */
      BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
  
!       /* total number of entries in the central dir */
      BAIL_IF_MACRO(!readui16(in, &zipinfo->entryCount), NULL, 0);
      BAIL_IF_MACRO(ui16 != zipinfo->entryCount, ERR_UNSUPPORTED_ARCHIVE, 0);
  
!       /* size of the central directory */
      BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
  
!       /* offset of central directory */
      BAIL_IF_MACRO(!readui32(in, central_dir_ofs), NULL, 0);
      BAIL_IF_MACRO(pos < *central_dir_ofs + ui32, ERR_UNSUPPORTED_ARCHIVE, 0);
--- 1033,1055 ----
      BAIL_IF_MACRO(ui32 != ZIP_END_OF_CENTRAL_DIR_SIG, ERR_NOT_AN_ARCHIVE, 0);
  
!     /* number of this disk */
      BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
      BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
  
!     /* number of the disk with the start of the central directory */
      BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
      BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
  
!     /* total number of entries in the central dir on this disk */
      BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
  
!     /* total number of entries in the central dir */
      BAIL_IF_MACRO(!readui16(in, &zipinfo->entryCount), NULL, 0);
      BAIL_IF_MACRO(ui16 != zipinfo->entryCount, ERR_UNSUPPORTED_ARCHIVE, 0);
  
!     /* size of the central directory */
      BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
  
!     /* offset of central directory */
      BAIL_IF_MACRO(!readui32(in, central_dir_ofs), NULL, 0);
      BAIL_IF_MACRO(pos < *central_dir_ofs + ui32, ERR_UNSUPPORTED_ARCHIVE, 0);
***************
*** 1089,1098 ****
       *  data is at the start of the physical file.
       */
!       *data_start = pos - (*central_dir_ofs + ui32);
  
      /* Now that we know the difference, fix up the central dir offset... */
      *central_dir_ofs += *data_start;
  
!       /* zipfile comment length */
      BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
  
--- 1063,1072 ----
       *  data is at the start of the physical file.
       */
!     *data_start = pos - (*central_dir_ofs + ui32);
  
      /* Now that we know the difference, fix up the central dir offset... */
      *central_dir_ofs += *data_start;
  
!     /* zipfile comment length */
      BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
  
***************
*** 1222,1226 ****
              else 
              {
-                 
                  if (stop_on_first_find) /* Just checking dir's existance? */
                      return(middle);
--- 1196,1199 ----
***************
*** 1294,1305 ****
  static int ZIP_exists(DirHandle *h, const char *name)
  {
!     ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name);
!     return(entry != NULL);
  } /* ZIP_exists */
  
  
! static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *name)
  {
!     ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name);
      BAIL_IF_MACRO(entry == NULL, NULL, -1);
      return(entry->last_mod_time);
--- 1267,1289 ----
  static int ZIP_exists(DirHandle *h, const char *name)
  {
!     int isDir;    
!     ZIPinfo *info = (ZIPinfo *) h->opaque;
!     ZIPentry *entry = zip_find_entry(info, name, &isDir);
!     return((entry != NULL) || (isDir));
  } /* ZIP_exists */
  
  
! static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h,
!                                         const char *name,
!                                         int *fileExists)
  {
!     int isDir;
!     ZIPinfo *info = (ZIPinfo *) h->opaque;
!     ZIPentry *entry = zip_find_entry(info, name, &isDir);
! 
!     *fileExists = ((isDir) || (entry != NULL));
!     if (isDir)
!         return(1);  /* Best I can do for a dir... */
! 
      BAIL_IF_MACRO(entry == NULL, NULL, -1);
      return(entry->last_mod_time);
***************
*** 1307,1322 ****
  
  
! static int ZIP_isDirectory(DirHandle *h, const char *name)
  {
      ZIPinfo *info = (ZIPinfo *) h->opaque;
!     PHYSFS_uint32 pos;
!     ZIPentry *entry;
  
!     pos = zip_find_start_of_dir(info, name, 1);
!     if (pos >= 0)
          return(1); /* definitely a dir. */
  
      /* Follow symlinks. This means we might need to resolve entries. */
-     entry = zip_find_entry(info, name);
      BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, 0);
  
--- 1291,1305 ----
  
  
! static int ZIP_isDirectory(DirHandle *h, const char *name, int *fileExists)
  {
      ZIPinfo *info = (ZIPinfo *) h->opaque;
!     int isDir;
!     ZIPentry *entry = zip_find_entry(info, name, &isDir);
  
!     *fileExists = ((isDir) || (entry != NULL));
!     if (isDir)
          return(1); /* definitely a dir. */
  
      /* Follow symlinks. This means we might need to resolve entries. */
      BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, 0);
  
***************
*** 1339,1345 ****
  
  
! static int ZIP_isSymLink(DirHandle *h, const char *name)
  {
!     ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name);
      BAIL_IF_MACRO(entry == NULL, NULL, 0);
      return(zip_entry_is_symlink(entry));
--- 1322,1330 ----
  
  
! static int ZIP_isSymLink(DirHandle *h, const char *name, int *fileExists)
  {
!     int isDir;
!     ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name, &isDir);
!     *fileExists = ((isDir) || (entry != NULL));
      BAIL_IF_MACRO(entry == NULL, NULL, 0);
      return(zip_entry_is_symlink(entry));
***************
*** 1371,1382 ****
  
  
! static FileHandle *ZIP_openRead(DirHandle *h, const char *filename)
  {
      ZIPinfo *info = (ZIPinfo *) h->opaque;
!     ZIPentry *entry = zip_find_entry(info, filename);
      FileHandle *retval = NULL;
      ZIPfileinfo *finfo = NULL;
      void *in;
  
      BAIL_IF_MACRO(entry == NULL, NULL, NULL);
  
--- 1356,1368 ----
  
  
! static FileHandle *ZIP_openRead(DirHandle *h, const char *fnm, int 
*fileExists)
  {
      ZIPinfo *info = (ZIPinfo *) h->opaque;
!     ZIPentry *entry = zip_find_entry(info, fnm, NULL);
      FileHandle *retval = NULL;
      ZIPfileinfo *finfo = NULL;
      void *in;
  
+     *fileExists = (entry != NULL);
      BAIL_IF_MACRO(entry == NULL, NULL, NULL);
  
***************
*** 1420,1423 ****
--- 1406,1421 ----
  
  
+ static FileHandle *ZIP_openWrite(DirHandle *h, const char *filename)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
+ } /* ZIP_openWrite */
+ 
+ 
+ static FileHandle *ZIP_openAppend(DirHandle *h, const char *filename)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
+ } /* ZIP_openAppend */
+ 
+ 
  static void ZIP_dirClose(DirHandle *h)
  {
***************
*** 1428,1431 ****
--- 1426,1441 ----
      free(h);
  } /* ZIP_dirClose */
+ 
+ 
+ static int ZIP_remove(DirHandle *h, const char *name)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
+ } /* ZIP_remove */
+ 
+ 
+ static int ZIP_mkdir(DirHandle *h, const char *name)
+ {
+     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
+ } /* ZIP_mkdir */
  
  #endif  /* defined PHYSFS_SUPPORTS_ZIP */

--- unzip.c DELETED ---

--- unzip.h DELETED ---





reply via email to

[Prev in Thread] Current Thread [Next in Thread]