Cleaned up archiver interface to not deal with DirHandles anymore,
authorRyan C. Gordon <icculus@icculus.org>
Sun, 26 Sep 2004 00:25:04 +0000
changeset 648 5c993684b8f2
parent 647 c83b6827fc7d
child 649 85aeb90378bc
Cleaned up archiver interface to not deal with DirHandles anymore, which simplifies things, removes some responsibility and code duplication from the archivers, and trims some malloc pressure. Also ripped up the allocation hook code a little. We'll try to screw with memory locking later, since it makes everything ugly and complex. Oh well.
CHANGELOG
archivers/dir.c
archivers/grp.c
archivers/hog.c
archivers/mix.c
archivers/mvl.c
archivers/qpak.c
archivers/wad.c
archivers/zip.c
physfs.c
physfs.h
physfs_internal.h
platform/posix.c
--- a/CHANGELOG	Sun Sep 26 00:24:05 2004 +0000
+++ b/CHANGELOG	Sun Sep 26 00:25:04 2004 +0000
@@ -2,6 +2,12 @@
  * CHANGELOG.
  */
 
+09252004 - Cleaned up archiver interface to not deal with DirHandles anymore,
+           which simplifies things, removes some responsibility and code
+           duplication from the archivers, and trims some malloc pressure.
+           Ripped up the allocation hook code a little. We'll try to screw
+           with memory locking later, since it makes everything ugly and
+           complex. Oh well.
 09232004 - Started adding allocation hooks.
 09222004 - Happy September. Added Spanish translation back in.
 04092004 - Added MIX support for legacy Westwood titles (Thanks, Sebastian!).
--- a/archivers/dir.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/archivers/dir.c	Sun Sep 26 00:25:04 2004 +0000
@@ -32,20 +32,20 @@
 static PHYSFS_sint64 DIR_fileLength(FileHandle *handle);
 static int DIR_fileClose(FileHandle *handle);
 static int DIR_isArchive(const char *filename, int forWriting);
-static DirHandle *DIR_openArchive(const char *name, int forWriting);
-static LinkedStringList *DIR_enumerateFiles(DirHandle *h,
+static void *DIR_openArchive(const char *name, int forWriting);
+static LinkedStringList *DIR_enumerateFiles(void *opaque,
                                             const char *dname,
                                             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);
-static int DIR_remove(DirHandle *h, const char *name);
-static int DIR_mkdir(DirHandle *h, const char *name);
-static void DIR_dirClose(DirHandle *h);
+static int DIR_exists(void *opaque, const char *name);
+static int DIR_isDirectory(void *opaque, const char *name, int *fileExists);
+static int DIR_isSymLink(void *opaque, const char *name, int *fileExists);
+static FileHandle *DIR_openRead(void *opaque, const char *fnm, int *exist);
+static PHYSFS_sint64 DIR_getLastModTime(void *opaque, const char *f, int *e);
+static FileHandle *DIR_openWrite(void *opaque, const char *filename);
+static FileHandle *DIR_openAppend(void *opaque, const char *filename);
+static int DIR_remove(void *opaque, const char *name);
+static int DIR_mkdir(void *opaque, const char *name);
+static void DIR_dirClose(void *opaque);
 
 
 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
@@ -177,41 +177,34 @@
 } /* DIR_isArchive */
 
 
-static DirHandle *DIR_openArchive(const char *name, int forWriting)
+static void *DIR_openArchive(const char *name, int forWriting)
 {
     const char *dirsep = PHYSFS_getDirSeparator();
-    DirHandle *retval = NULL;
+    char *retval = NULL;
     size_t namelen = strlen(name);
     size_t seplen = strlen(dirsep);
 
+    /* !!! FIXME: when is this not called right before openArchive? */
     BAIL_IF_MACRO(!DIR_isArchive(name, forWriting),
-                    ERR_UNSUPPORTED_ARCHIVE, NULL);
+                    ERR_UNSUPPORTED_ARCHIVE, 0);
 
-    retval = (DirHandle *) malloc(sizeof (DirHandle));
+    retval = malloc(namelen + seplen + 1);
     BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-    retval->opaque = malloc(namelen + seplen + 1);
-    if (retval->opaque == NULL)
-    {
-        free(retval);
-        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
-    } /* if */
 
         /* make sure there's a dir separator at the end of the string */
-    strcpy((char *) (retval->opaque), name);
+    strcpy(retval, name);
     if (strcmp((name + namelen) - seplen, dirsep) != 0)
-        strcat((char *) (retval->opaque), dirsep);
-
-    retval->funcs = &__PHYSFS_DirFunctions_DIR;
+        strcat(retval, dirsep);
 
     return(retval);
 } /* DIR_openArchive */
 
 
-static LinkedStringList *DIR_enumerateFiles(DirHandle *h,
+static LinkedStringList *DIR_enumerateFiles(void *opaque,
                                             const char *dname,
                                             int omitSymLinks)
 {
-    char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque),dname,NULL);
+    char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL);
     LinkedStringList *retval;
 
     BAIL_IF_MACRO(d == NULL, NULL, NULL);
@@ -221,9 +214,9 @@
 } /* DIR_enumerateFiles */
 
 
-static int DIR_exists(DirHandle *h, const char *name)
+static int DIR_exists(void *opaque, const char *name)
 {
-    char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
+    char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
     int retval;
 
     BAIL_IF_MACRO(f == NULL, NULL, 0);
@@ -233,9 +226,9 @@
 } /* DIR_exists */
 
 
-static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists)
+static int DIR_isDirectory(void *opaque, const char *name, int *fileExists)
 {
-    char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
+    char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
     int retval = 0;
 
     BAIL_IF_MACRO(d == NULL, NULL, 0);
@@ -247,9 +240,9 @@
 } /* DIR_isDirectory */
 
 
-static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists)
+static int DIR_isSymLink(void *opaque, const char *name, int *fileExists)
 {
-    char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
+    char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
     int retval = 0;
 
     BAIL_IF_MACRO(f == NULL, NULL, 0);
@@ -261,11 +254,11 @@
 } /* DIR_isSymLink */
 
 
-static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h,
+static PHYSFS_sint64 DIR_getLastModTime(void *opaque,
                                         const char *name,
                                         int *fileExists)
 {
-    char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
+    char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
     PHYSFS_sint64 retval = -1;
 
     BAIL_IF_MACRO(d == NULL, NULL, 0);
@@ -277,11 +270,11 @@
 } /* DIR_getLastModTime */
 
 
-static FileHandle *doOpen(DirHandle *h, const char *name,
+static FileHandle *doOpen(void *opaque, const char *name,
                           void *(*openFunc)(const char *filename),
                           int *fileExists, const FileFunctions *fileFuncs)
 {
-    char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
+    char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
     void *rc;
     FileHandle *retval;
 
@@ -314,37 +307,36 @@
     } /* if */
 
     retval->opaque = (void *) rc;
-    retval->dirHandle = h;
     retval->funcs = fileFuncs;
 
     return(retval);
 } /* doOpen */
 
 
-static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist)
+static FileHandle *DIR_openRead(void *opaque, const char *fnm, int *exist)
 {
-    return(doOpen(h, fnm, __PHYSFS_platformOpenRead, exist,
+    return(doOpen(opaque, fnm, __PHYSFS_platformOpenRead, exist,
                   &__PHYSFS_FileFunctions_DIR));
 } /* DIR_openRead */
 
 
-static FileHandle *DIR_openWrite(DirHandle *h, const char *filename)
+static FileHandle *DIR_openWrite(void *opaque, const char *filename)
 {
-    return(doOpen(h, filename, __PHYSFS_platformOpenWrite, NULL,
+    return(doOpen(opaque, filename, __PHYSFS_platformOpenWrite, NULL,
                   &__PHYSFS_FileFunctions_DIRW));
 } /* DIR_openWrite */
 
 
-static FileHandle *DIR_openAppend(DirHandle *h, const char *filename)
+static FileHandle *DIR_openAppend(void *opaque, const char *filename)
 {
-    return(doOpen(h, filename, __PHYSFS_platformOpenAppend, NULL,
+    return(doOpen(opaque, filename, __PHYSFS_platformOpenAppend, NULL,
                   &__PHYSFS_FileFunctions_DIRW));
 } /* DIR_openAppend */
 
 
-static int DIR_remove(DirHandle *h, const char *name)
+static int DIR_remove(void *opaque, const char *name)
 {
-    char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
+    char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
     int retval;
 
     BAIL_IF_MACRO(f == NULL, NULL, 0);
@@ -354,9 +346,9 @@
 } /* DIR_remove */
 
 
-static int DIR_mkdir(DirHandle *h, const char *name)
+static int DIR_mkdir(void *opaque, const char *name)
 {
-    char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
+    char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
     int retval;
 
     BAIL_IF_MACRO(f == NULL, NULL, 0);
@@ -366,10 +358,9 @@
 } /* DIR_mkdir */
 
 
-static void DIR_dirClose(DirHandle *h)
+static void DIR_dirClose(void *opaque)
 {
-    free(h->opaque);
-    free(h);
+    free(opaque);
 } /* DIR_dirClose */
 
 /* end of dir.c ... */
--- a/archivers/grp.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/archivers/grp.c	Sun Sep 26 00:25:04 2004 +0000
@@ -61,7 +61,7 @@
 } GRPfileinfo;
 
 
-static void GRP_dirClose(DirHandle *h);
+static void GRP_dirClose(void *opaque);
 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,
@@ -72,19 +72,19 @@
 static PHYSFS_sint64 GRP_fileLength(FileHandle *handle);
 static int GRP_fileClose(FileHandle *handle);
 static int GRP_isArchive(const char *filename, int forWriting);
-static DirHandle *GRP_openArchive(const char *name, int forWriting);
-static LinkedStringList *GRP_enumerateFiles(DirHandle *h,
+static void *GRP_openArchive(const char *name, int forWriting);
+static LinkedStringList *GRP_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             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);
+static int GRP_exists(void *opaque, const char *name);
+static int GRP_isDirectory(void *opaque, const char *name, int *fileExists);
+static int GRP_isSymLink(void *opaque, const char *name, int *fileExists);
+static PHYSFS_sint64 GRP_getLastModTime(void *opaque, const char *n, int *e);
+static FileHandle *GRP_openRead(void *opaque, const char *name, int *exist);
+static FileHandle *GRP_openWrite(void *opaque, const char *name);
+static FileHandle *GRP_openAppend(void *opaque, const char *name);
+static int GRP_remove(void *opaque, const char *name);
+static int GRP_mkdir(void *opaque, const char *name);
 
 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP =
 {
@@ -127,13 +127,12 @@
 
 
 
-static void GRP_dirClose(DirHandle *h)
+static void GRP_dirClose(void *opaque)
 {
-    GRPinfo *info = ((GRPinfo *) h->opaque);
+    GRPinfo *info = ((GRPinfo *) opaque);
     free(info->filename);
     free(info->entries);
     free(info);
-    free(h);
 } /* GRP_dirClose */
 
 
@@ -329,22 +328,14 @@
 } /* grp_load_entries */
 
 
-static DirHandle *GRP_openArchive(const char *name, int forWriting)
+static void *GRP_openArchive(const char *name, int forWriting)
 {
-    GRPinfo *info;
-    DirHandle *retval = malloc(sizeof (DirHandle));
     PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
+    GRPinfo *info = malloc(sizeof (GRPinfo));
 
-    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-    info = retval->opaque = malloc(sizeof (GRPinfo));
-    if (info == NULL)
-    {
-        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
-        goto GRP_openArchive_failed;
-    } /* if */
+    BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, 0);
 
     memset(info, '\0', sizeof (GRPinfo));
-
     info->filename = (char *) malloc(strlen(name) + 1);
     if (info->filename == NULL)
     {
@@ -357,32 +348,28 @@
 
     strcpy(info->filename, name);
     info->last_mod_time = modtime;
-    retval->funcs = &__PHYSFS_DirFunctions_GRP;
-    return(retval);
+
+    return(info);
 
 GRP_openArchive_failed:
-    if (retval != NULL)
+    if (info != NULL)
     {
-        if (retval->opaque != NULL)
-        {
-            if (info->filename != NULL)
-                free(info->filename);
-            if (info->entries != NULL)
-                free(info->entries);
-            free(info);
-        } /* if */
-        free(retval);
+        if (info->filename != NULL)
+            free(info->filename);
+        if (info->entries != NULL)
+            free(info->entries);
+        free(info);
     } /* if */
 
     return(NULL);
 } /* GRP_openArchive */
 
 
-static LinkedStringList *GRP_enumerateFiles(DirHandle *h,
+static LinkedStringList *GRP_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks)
 {
-    GRPinfo *info = ((GRPinfo *) h->opaque);
+    GRPinfo *info = ((GRPinfo *) opaque);
     GRPentry *entry = info->entries;
     LinkedStringList *retval = NULL, *p = NULL;
     PHYSFS_uint32 max = info->entryCount;
@@ -431,44 +418,44 @@
 } /* grp_find_entry */
 
 
-static int GRP_exists(DirHandle *h, const char *name)
+static int GRP_exists(void *opaque, const char *name)
 {
-    return(grp_find_entry(((GRPinfo *) h->opaque), name) != NULL);
+    return(grp_find_entry(((GRPinfo *) opaque), name) != NULL);
 } /* GRP_exists */
 
 
-static int GRP_isDirectory(DirHandle *h, const char *name, int *fileExists)
+static int GRP_isDirectory(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = GRP_exists(h, name);
+    *fileExists = GRP_exists(opaque, name);
     return(0);  /* never directories in a groupfile. */
 } /* GRP_isDirectory */
 
 
-static int GRP_isSymLink(DirHandle *h, const char *name, int *fileExists)
+static int GRP_isSymLink(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = GRP_exists(h, name);
+    *fileExists = GRP_exists(opaque, name);
     return(0);  /* never symlinks in a groupfile. */
 } /* GRP_isSymLink */
 
 
-static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h,
+static PHYSFS_sint64 GRP_getLastModTime(void *opaque,
                                         const char *name,
                                         int *fileExists)
 {
-    GRPinfo *info = ((GRPinfo *) h->opaque);
+    GRPinfo *info = ((GRPinfo *) 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;
+        retval = info->last_mod_time;
 
     return(retval);
 } /* GRP_getLastModTime */
 
 
-static FileHandle *GRP_openRead(DirHandle *h, const char *fnm, int *fileExists)
+static FileHandle *GRP_openRead(void *opaque, const char *fnm, int *fileExists)
 {
-    GRPinfo *info = ((GRPinfo *) h->opaque);
+    GRPinfo *info = ((GRPinfo *) opaque);
     FileHandle *retval;
     GRPfileinfo *finfo;
     GRPentry *entry;
@@ -499,30 +486,29 @@
     finfo->entry = entry;
     retval->opaque = (void *) finfo;
     retval->funcs = &__PHYSFS_FileFunctions_GRP;
-    retval->dirHandle = h;
     return(retval);
 } /* GRP_openRead */
 
 
-static FileHandle *GRP_openWrite(DirHandle *h, const char *name)
+static FileHandle *GRP_openWrite(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* GRP_openWrite */
 
 
-static FileHandle *GRP_openAppend(DirHandle *h, const char *name)
+static FileHandle *GRP_openAppend(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* GRP_openAppend */
 
 
-static int GRP_remove(DirHandle *h, const char *name)
+static int GRP_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* GRP_remove */
 
 
-static int GRP_mkdir(DirHandle *h, const char *name)
+static int GRP_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* GRP_mkdir */
--- a/archivers/hog.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/archivers/hog.c	Sun Sep 26 00:25:04 2004 +0000
@@ -75,7 +75,7 @@
 } HOGfileinfo;
 
 
-static void HOG_dirClose(DirHandle *h);
+static void HOG_dirClose(void *opaque);
 static PHYSFS_sint64 HOG_read(FileHandle *handle, void *buffer,
                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
 static PHYSFS_sint64 HOG_write(FileHandle *handle, const void *buffer,
@@ -86,19 +86,19 @@
 static PHYSFS_sint64 HOG_fileLength(FileHandle *handle);
 static int HOG_fileClose(FileHandle *handle);
 static int HOG_isArchive(const char *filename, int forWriting);
-static DirHandle *HOG_openArchive(const char *name, int forWriting);
-static LinkedStringList *HOG_enumerateFiles(DirHandle *h,
+static void *HOG_openArchive(const char *name, int forWriting);
+static LinkedStringList *HOG_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks);
-static int HOG_exists(DirHandle *h, const char *name);
-static int HOG_isDirectory(DirHandle *h, const char *name, int *fileExists);
-static int HOG_isSymLink(DirHandle *h, const char *name, int *fileExists);
-static PHYSFS_sint64 HOG_getLastModTime(DirHandle *h, const char *n, int *e);
-static FileHandle *HOG_openRead(DirHandle *h, const char *name, int *exist);
-static FileHandle *HOG_openWrite(DirHandle *h, const char *name);
-static FileHandle *HOG_openAppend(DirHandle *h, const char *name);
-static int HOG_remove(DirHandle *h, const char *name);
-static int HOG_mkdir(DirHandle *h, const char *name);
+static int HOG_exists(void *opaque, const char *name);
+static int HOG_isDirectory(void *opaque, const char *name, int *fileExists);
+static int HOG_isSymLink(void *opaque, const char *name, int *fileExists);
+static PHYSFS_sint64 HOG_getLastModTime(void *opaque, const char *n, int *e);
+static FileHandle *HOG_openRead(void *opaque, const char *name, int *exist);
+static FileHandle *HOG_openWrite(void *opaque, const char *name);
+static FileHandle *HOG_openAppend(void *opaque, const char *name);
+static int HOG_remove(void *opaque, const char *name);
+static int HOG_mkdir(void *opaque, const char *name);
 
 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_HOG =
 {
@@ -141,13 +141,12 @@
 
 
 
-static void HOG_dirClose(DirHandle *h)
+static void HOG_dirClose(void *opaque)
 {
-    HOGinfo *info = ((HOGinfo *) h->opaque);
+    HOGinfo *info = ((HOGinfo *) opaque);
     free(info->filename);
     free(info->entries);
     free(info);
-    free(h);
 } /* HOG_dirClose */
 
 
@@ -369,22 +368,13 @@
 } /* hog_load_entries */
 
 
-static DirHandle *HOG_openArchive(const char *name, int forWriting)
+static void *HOG_openArchive(const char *name, int forWriting)
 {
-    HOGinfo *info;
-    DirHandle *retval = malloc(sizeof (DirHandle));
     PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
+    HOGinfo *info = malloc(sizeof (HOGinfo));
 
-    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-    info = retval->opaque = malloc(sizeof (HOGinfo));
-    if (info == NULL)
-    {
-        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
-        goto HOG_openArchive_failed;
-    } /* if */
-
+    BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, 0);
     memset(info, '\0', sizeof (HOGinfo));
-
     info->filename = (char *) malloc(strlen(name) + 1);
     if (info->filename == NULL)
     {
@@ -397,32 +387,28 @@
 
     strcpy(info->filename, name);
     info->last_mod_time = modtime;
-    retval->funcs = &__PHYSFS_DirFunctions_HOG;
-    return(retval);
+
+    return(info);
 
 HOG_openArchive_failed:
-    if (retval != NULL)
+    if (info != NULL)
     {
-        if (retval->opaque != NULL)
-        {
-            if (info->filename != NULL)
-                free(info->filename);
-            if (info->entries != NULL)
-                free(info->entries);
-            free(info);
-        } /* if */
-        free(retval);
+        if (info->filename != NULL)
+            free(info->filename);
+        if (info->entries != NULL)
+            free(info->entries);
+        free(info);
     } /* if */
 
     return(NULL);
 } /* HOG_openArchive */
 
 
-static LinkedStringList *HOG_enumerateFiles(DirHandle *h,
+static LinkedStringList *HOG_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks)
 {
-    HOGinfo *info = ((HOGinfo *) h->opaque);
+    HOGinfo *info = ((HOGinfo *) opaque);
     HOGentry *entry = info->entries;
     LinkedStringList *retval = NULL, *p = NULL;
     PHYSFS_uint32 max = info->entryCount;
@@ -471,44 +457,44 @@
 } /* hog_find_entry */
 
 
-static int HOG_exists(DirHandle *h, const char *name)
+static int HOG_exists(void *opaque, const char *name)
 {
-    return(hog_find_entry(((HOGinfo *) h->opaque), name) != NULL);
+    return(hog_find_entry(((HOGinfo *) opaque), name) != NULL);
 } /* HOG_exists */
 
 
-static int HOG_isDirectory(DirHandle *h, const char *name, int *fileExists)
+static int HOG_isDirectory(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = HOG_exists(h, name);
+    *fileExists = HOG_exists(opaque, name);
     return(0);  /* never directories in a groupfile. */
 } /* HOG_isDirectory */
 
 
-static int HOG_isSymLink(DirHandle *h, const char *name, int *fileExists)
+static int HOG_isSymLink(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = HOG_exists(h, name);
+    *fileExists = HOG_exists(opaque, name);
     return(0);  /* never symlinks in a groupfile. */
 } /* HOG_isSymLink */
 
 
-static PHYSFS_sint64 HOG_getLastModTime(DirHandle *h,
+static PHYSFS_sint64 HOG_getLastModTime(void *opaque,
                                         const char *name,
                                         int *fileExists)
 {
-    HOGinfo *info = ((HOGinfo *) h->opaque);
+    HOGinfo *info = ((HOGinfo *) opaque);
     PHYSFS_sint64 retval = -1;
 
     *fileExists = (hog_find_entry(info, name) != NULL);
     if (*fileExists)  /* use time of HOG itself in the physical filesystem. */
-        retval = ((HOGinfo *) h->opaque)->last_mod_time;
+        retval = info->last_mod_time;
 
     return(retval);
 } /* HOG_getLastModTime */
 
 
-static FileHandle *HOG_openRead(DirHandle *h, const char *fnm, int *fileExists)
+static FileHandle *HOG_openRead(void *opaque, const char *fnm, int *fileExists)
 {
-    HOGinfo *info = ((HOGinfo *) h->opaque);
+    HOGinfo *info = ((HOGinfo *) opaque);
     FileHandle *retval;
     HOGfileinfo *finfo;
     HOGentry *entry;
@@ -539,30 +525,29 @@
     finfo->entry = entry;
     retval->opaque = (void *) finfo;
     retval->funcs = &__PHYSFS_FileFunctions_HOG;
-    retval->dirHandle = h;
     return(retval);
 } /* HOG_openRead */
 
 
-static FileHandle *HOG_openWrite(DirHandle *h, const char *name)
+static FileHandle *HOG_openWrite(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* HOG_openWrite */
 
 
-static FileHandle *HOG_openAppend(DirHandle *h, const char *name)
+static FileHandle *HOG_openAppend(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* HOG_openAppend */
 
 
-static int HOG_remove(DirHandle *h, const char *name)
+static int HOG_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* HOG_remove */
 
 
-static int HOG_mkdir(DirHandle *h, const char *name)
+static int HOG_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* HOG_mkdir */
--- a/archivers/mix.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/archivers/mix.c	Sun Sep 26 00:25:04 2004 +0000
@@ -80,7 +80,7 @@
     void *handle; /* filehandle */
 } MIXfileinfo;
 
-static void MIX_dirClose(DirHandle *h);
+static void MIX_dirClose(void *opaque);
 static PHYSFS_sint64 MIX_read(FileHandle *handle, void *buffer,
                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
 static PHYSFS_sint64 MIX_write(FileHandle *handle, const void *buffer,
@@ -91,19 +91,19 @@
 static PHYSFS_sint64 MIX_fileLength(FileHandle *handle);
 static int MIX_fileClose(FileHandle *handle);
 static int MIX_isArchive(const char *filename, int forWriting);
-static DirHandle *MIX_openArchive(const char *name, int forWriting);
-static LinkedStringList *MIX_enumerateFiles(DirHandle *h,
+static void *MIX_openArchive(const char *name, int forWriting);
+static LinkedStringList *MIX_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks);
-static int MIX_exists(DirHandle *h, const char *name);
-static int MIX_isDirectory(DirHandle *h, const char *name, int *fileExists);
-static int MIX_isSymLink(DirHandle *h, const char *name, int *fileExists);
-static PHYSFS_sint64 MIX_getLastModTime(DirHandle *h, const char *n, int *e);
-static FileHandle *MIX_openRead(DirHandle *h, const char *name, int *exist);
-static FileHandle *MIX_openWrite(DirHandle *h, const char *name);
-static FileHandle *MIX_openAppend(DirHandle *h, const char *name);
-static int MIX_remove(DirHandle *h, const char *name);
-static int MIX_mkdir(DirHandle *h, const char *name);
+static int MIX_exists(void *opaque, const char *name);
+static int MIX_isDirectory(void *opaque, const char *name, int *fileExists);
+static int MIX_isSymLink(void *opaque, const char *name, int *fileExists);
+static PHYSFS_sint64 MIX_getLastModTime(void *opaque, const char *n, int *e);
+static FileHandle *MIX_openRead(void *opaque, const char *name, int *exist);
+static FileHandle *MIX_openWrite(void *opaque, const char *name);
+static FileHandle *MIX_openAppend(void *opaque, const char *name);
+static int MIX_remove(void *opaque, const char *name);
+static int MIX_mkdir(void *opaque, const char *name);
 
 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_MIX =
 {
@@ -176,12 +176,11 @@
 } /* MIX_hash */
 
 
-static void MIX_dirClose(DirHandle *h)
+static void MIX_dirClose(void *opaque)
 {
-    MIXinfo *info = ((MIXinfo *) h->opaque);
+    MIXinfo *info = ((MIXinfo *) opaque);
     free(info->entry);
     free(info->filename);
-    free(h);
 } /* MIX_dirClose */
 
 
@@ -290,102 +289,82 @@
 } /* readui16 */
 
 
-static DirHandle *MIX_openArchive(const char *name, int forWriting)
+static void *MIX_openArchive(const char *name, int forWriting)
 {
-    PHYSFS_uint32 i;
-    DirHandle *retval;
-    MIXheader header;
-    MIXinfo *info;
-    MIXentry *entries;
-    void *handle;
-    char *fname;
-    
-    retval = (DirHandle *) malloc(sizeof (DirHandle));
-    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
+    PHYSFS_uint32 i = 0;
+    MIXinfo *info = NULL;
+    void *handle = NULL;
 
     info = (MIXinfo *) malloc(sizeof (MIXinfo));
-    if (info == NULL)
-    {
-        free(retval);
-        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
-    } /* if */
+    BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, 0);
+    memset(info, '\0', sizeof (MIXinfo));
 
-    fname = (char*) malloc(strlen(name) + 1);
-    if (fname == NULL)
+    info->filename = (char *) malloc(strlen(name) + 1);
+    if (info->filename == NULL)
     {
-        free(retval);
-        free(info);
-        BAIL_MACRO(ERR_OUT_OF_MEMORY,NULL);
+        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
+        goto MIX_openArchive_failed;
     } /* if */
     
     /* store filename */
-    strcpy(fname, name);
+    strcpy(info->filename, name);
     
     /* open the file */
     handle = __PHYSFS_platformOpenRead(name);
     if (!handle)
-    {
-        free(retval);
-        free(info);
-        return(NULL);
-    } /* if */
-        
+        goto MIX_openArchive_failed;
+
     /* read the MIX header */
-    if ( (!readui16(handle, &header.num_files)) ||
-         (!readui32(handle, &header.filesize)) )
-    {
-        free(retval);
-        free(info);
-        __PHYSFS_platformClose(handle);
-        return(NULL);
-    } /* if */
+    if ( (!readui16(handle, &info->header.num_files)) ||
+         (!readui32(handle, &info->header.filesize)) )
+        goto MIX_openArchive_failed;
+
+    info->delta = 6 + (info->header.num_files * 12);
 
     /* allocate space for the entries and read the entries */
-    entries = (MIXentry *) malloc(sizeof (MIXentry) * header.num_files);
-    if (!entries)
+    info->entry = malloc(sizeof (MIXentry) * info->header.num_files);
+    if (info->entry == NULL)
     {
-        free(retval);
-        free(info);
-        __PHYSFS_platformClose(handle);
-        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
+        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
+        goto MIX_openArchive_failed;
     } /* if */
     
     /* read the directory list */
     for (i = 0; i < header.num_files; i++)
     {
-        if ( (!readui32(handle, &entries[i].hash)) ||
-             (!readui32(handle, &entries[i].start_offset)) ||
-             (!readui32(handle, &entries[i].end_offset)) )
-        {
-            free(entries);
-            free(retval);
-            free(info);
-            __PHYSFS_platformClose(handle);
-            return(NULL);
-        } /* if */
+        if ( (!readui32(handle, &info->entry[i].hash)) ||
+             (!readui32(handle, &info->entry[i].start_offset)) ||
+             (!readui32(handle, &info->entry[i].end_offset)) )
+            goto MIX_openArchive_failed;
     } /* for */
 
     __PHYSFS_platformClose(handle);
 
-    /* create our driver structure and create the DirHandle */
-    info->header = header;
-    info->entry = entries;
-    info->filename = fname;
-    info->delta = 6 + (header.num_files*12);
-    
-    retval->funcs = &__PHYSFS_DirFunctions_MIX;
-    retval->opaque = info;
-    
-    return(retval);
+    return(info);
+
+MIX_openArchive_failed:
+    if (info != NULL)
+    {
+        if (info->filename != NULL)
+            free(info->filename);
+        if (info->entry != NULL)
+            free(info->entry);
+        free(info);
+    } /* if */
+
+    if (handle != NULL)
+        __PHYSFS_platformClose(handle);
+
+    return(NULL);
 } /* MIX_openArchive */
 
 
-static LinkedStringList *MIX_enumerateFiles(DirHandle *h,
+static LinkedStringList *MIX_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks)
 {
     LinkedStringList *retval = NULL, *p = NULL;
-    MIXinfo *info = (MIXinfo*)h->opaque;
+    MIXinfo *info = (MIXinfo*) opaque;
     MIXentry *entry = info->entry;
     int i;
     char buffer[32];
@@ -420,38 +399,38 @@
 } /* MIX_find_entry */
 
 
-static int MIX_exists(DirHandle *h, const char *name)
+static int MIX_exists(void *opaque, const char *name)
 {
-    return(MIX_find_entry(((MIXinfo *) h->opaque), name) != NULL);
+    return(MIX_find_entry(((MIXinfo *) opaque), name) != NULL);
 } /* MIX_exists */
 
 
-static int MIX_isDirectory(DirHandle *h, const char *name, int *fileExists)
+static int MIX_isDirectory(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = MIX_exists(h, name);
+    *fileExists = MIX_exists(opaque, name);
     return(0);  /* never directories in a MIX */
 } /* MIX_isDirectory */
 
 
-static int MIX_isSymLink(DirHandle *h, const char *name, int *fileExists)
+static int MIX_isSymLink(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = MIX_exists(h, name);
+    *fileExists = MIX_exists(opaque, name);
     return(0);  /* never symlinks in a MIX. */
 } /* MIX_isSymLink */
 
 
-static PHYSFS_sint64 MIX_getLastModTime(DirHandle *h,
+static PHYSFS_sint64 MIX_getLastModTime(void *opaque,
                                         const char *name,
                                         int *fileExists)
 {
-    BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
+    BAIL_MACRO(ERR_NOT_SUPPORTED, 0);  /* !!! FIXME: return .MIX's modtime. */
 } /* MIX_getLastModTime */
 
 
-static FileHandle *MIX_openRead(DirHandle *h, const char *fnm, int *fileExists)
+static FileHandle *MIX_openRead(void *opaque, const char *fnm, int *fileExists)
 {
     FileHandle *retval;
-    MIXinfo *info = ((MIXinfo*)h->opaque);
+    MIXinfo *info = ((MIXinfo*) opaque);
     MIXfileinfo *finfo;
     MIXentry *entry;
     
@@ -488,31 +467,30 @@
     
     retval->opaque = (void *) finfo;
     retval->funcs = &__PHYSFS_FileFunctions_MIX;
-    retval->dirHandle = h;
-    
+
     return(retval);
 } /* MIX_openRead */
 
 
-static FileHandle *MIX_openWrite(DirHandle *h, const char *name)
+static FileHandle *MIX_openWrite(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* MIX_openWrite */
 
 
-static FileHandle *MIX_openAppend(DirHandle *h, const char *name)
+static FileHandle *MIX_openAppend(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* MIX_openAppend */
 
 
-static int MIX_remove(DirHandle *h, const char *name)
+static int MIX_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* MIX_remove */
 
 
-static int MIX_mkdir(DirHandle *h, const char *name)
+static int MIX_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* MIX_mkdir */
--- a/archivers/mvl.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/archivers/mvl.c	Sun Sep 26 00:25:04 2004 +0000
@@ -64,7 +64,7 @@
 } MVLfileinfo;
 
 
-static void MVL_dirClose(DirHandle *h);
+static void MVL_dirClose(void *opaque);
 static PHYSFS_sint64 MVL_read(FileHandle *handle, void *buffer,
                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
 static PHYSFS_sint64 MVL_write(FileHandle *handle, const void *buffer,
@@ -75,19 +75,19 @@
 static PHYSFS_sint64 MVL_fileLength(FileHandle *handle);
 static int MVL_fileClose(FileHandle *handle);
 static int MVL_isArchive(const char *filename, int forWriting);
-static DirHandle *MVL_openArchive(const char *name, int forWriting);
-static LinkedStringList *MVL_enumerateFiles(DirHandle *h,
+static void *MVL_openArchive(const char *name, int forWriting);
+static LinkedStringList *MVL_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks);
-static int MVL_exists(DirHandle *h, const char *name);
-static int MVL_isDirectory(DirHandle *h, const char *name, int *fileExists);
-static int MVL_isSymLink(DirHandle *h, const char *name, int *fileExists);
-static PHYSFS_sint64 MVL_getLastModTime(DirHandle *h, const char *n, int *e);
-static FileHandle *MVL_openRead(DirHandle *h, const char *name, int *exist);
-static FileHandle *MVL_openWrite(DirHandle *h, const char *name);
-static FileHandle *MVL_openAppend(DirHandle *h, const char *name);
-static int MVL_remove(DirHandle *h, const char *name);
-static int MVL_mkdir(DirHandle *h, const char *name);
+static int MVL_exists(void *opaque, const char *name);
+static int MVL_isDirectory(void *opaque, const char *name, int *fileExists);
+static int MVL_isSymLink(void *opaque, const char *name, int *fileExists);
+static PHYSFS_sint64 MVL_getLastModTime(void *opaque, const char *n, int *e);
+static FileHandle *MVL_openRead(void *opaque, const char *name, int *exist);
+static FileHandle *MVL_openWrite(void *opaque, const char *name);
+static FileHandle *MVL_openAppend(void *opaque, const char *name);
+static int MVL_remove(void *opaque, const char *name);
+static int MVL_mkdir(void *opaque, const char *name);
 
 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_MVL =
 {
@@ -130,13 +130,12 @@
 
 
 
-static void MVL_dirClose(DirHandle *h)
+static void MVL_dirClose(void *opaque)
 {
-    MVLinfo *info = ((MVLinfo *) h->opaque);
+    MVLinfo *info = ((MVLinfo *) opaque);
     free(info->filename);
     free(info->entries);
     free(info);
-    free(h);
 } /* MVL_dirClose */
 
 
@@ -327,20 +326,12 @@
 } /* mvl_load_entries */
 
 
-static DirHandle *MVL_openArchive(const char *name, int forWriting)
+static void *MVL_openArchive(const char *name, int forWriting)
 {
-    MVLinfo *info;
-    DirHandle *retval = malloc(sizeof (DirHandle));
     PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
+    MVLinfo *info = malloc(sizeof (MVLinfo));
 
-    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-    info = retval->opaque = malloc(sizeof (MVLinfo));
-    if (info == NULL)
-    {
-        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
-        goto MVL_openArchive_failed;
-    } /* if */
-
+    BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, NULL);
     memset(info, '\0', sizeof (MVLinfo));
 
     info->filename = (char *) malloc(strlen(name) + 1);
@@ -355,32 +346,27 @@
 
     strcpy(info->filename, name);
     info->last_mod_time = modtime;
-    retval->funcs = &__PHYSFS_DirFunctions_MVL;
-    return(retval);
+    return(info);
 
 MVL_openArchive_failed:
-    if (retval != NULL)
+    if (info != NULL)
     {
-        if (retval->opaque != NULL)
-        {
-            if (info->filename != NULL)
-                free(info->filename);
-            if (info->entries != NULL)
-                free(info->entries);
-            free(info);
-        } /* if */
-        free(retval);
+        if (info->filename != NULL)
+            free(info->filename);
+        if (info->entries != NULL)
+            free(info->entries);
+        free(info);
     } /* if */
 
     return(NULL);
 } /* MVL_openArchive */
 
 
-static LinkedStringList *MVL_enumerateFiles(DirHandle *h,
+static LinkedStringList *MVL_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks)
 {
-    MVLinfo *info = ((MVLinfo *) h->opaque);
+    MVLinfo *info = ((MVLinfo *) opaque);
     MVLentry *entry = info->entries;
     LinkedStringList *retval = NULL, *p = NULL;
     PHYSFS_uint32 max = info->entryCount;
@@ -429,44 +415,44 @@
 } /* mvl_find_entry */
 
 
-static int MVL_exists(DirHandle *h, const char *name)
+static int MVL_exists(void *opaque, const char *name)
 {
-    return(mvl_find_entry(((MVLinfo *) h->opaque), name) != NULL);
+    return(mvl_find_entry(((MVLinfo *) opaque), name) != NULL);
 } /* MVL_exists */
 
 
-static int MVL_isDirectory(DirHandle *h, const char *name, int *fileExists)
+static int MVL_isDirectory(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = MVL_exists(h, name);
+    *fileExists = MVL_exists(opaque, name);
     return(0);  /* never directories in a groupfile. */
 } /* MVL_isDirectory */
 
 
-static int MVL_isSymLink(DirHandle *h, const char *name, int *fileExists)
+static int MVL_isSymLink(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = MVL_exists(h, name);
+    *fileExists = MVL_exists(opaque, name);
     return(0);  /* never symlinks in a groupfile. */
 } /* MVL_isSymLink */
 
 
-static PHYSFS_sint64 MVL_getLastModTime(DirHandle *h,
+static PHYSFS_sint64 MVL_getLastModTime(void *opaque,
                                         const char *name,
                                         int *fileExists)
 {
-    MVLinfo *info = ((MVLinfo *) h->opaque);
+    MVLinfo *info = ((MVLinfo *) opaque);
     PHYSFS_sint64 retval = -1;
 
     *fileExists = (mvl_find_entry(info, name) != NULL);
     if (*fileExists)  /* use time of MVL itself in the physical filesystem. */
-        retval = ((MVLinfo *) h->opaque)->last_mod_time;
+        retval = info->last_mod_time;
 
     return(retval);
 } /* MVL_getLastModTime */
 
 
-static FileHandle *MVL_openRead(DirHandle *h, const char *fnm, int *fileExists)
+static FileHandle *MVL_openRead(void *opaque, const char *fnm, int *fileExists)
 {
-    MVLinfo *info = ((MVLinfo *) h->opaque);
+    MVLinfo *info = ((MVLinfo *) opaque);
     FileHandle *retval;
     MVLfileinfo *finfo;
     MVLentry *entry;
@@ -497,30 +483,29 @@
     finfo->entry = entry;
     retval->opaque = (void *) finfo;
     retval->funcs = &__PHYSFS_FileFunctions_MVL;
-    retval->dirHandle = h;
     return(retval);
 } /* MVL_openRead */
 
 
-static FileHandle *MVL_openWrite(DirHandle *h, const char *name)
+static FileHandle *MVL_openWrite(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* MVL_openWrite */
 
 
-static FileHandle *MVL_openAppend(DirHandle *h, const char *name)
+static FileHandle *MVL_openAppend(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* MVL_openAppend */
 
 
-static int MVL_remove(DirHandle *h, const char *name)
+static int MVL_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* MVL_remove */
 
 
-static int MVL_mkdir(DirHandle *h, const char *name)
+static int MVL_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* MVL_mkdir */
--- a/archivers/qpak.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/archivers/qpak.c	Sun Sep 26 00:25:04 2004 +0000
@@ -78,7 +78,7 @@
 #define QPAK_SIGNATURE 0x4b434150   /* "PACK" in ASCII. */
 
 
-static void QPAK_dirClose(DirHandle *h);
+static void QPAK_dirClose(void *opaque);
 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,
@@ -89,19 +89,19 @@
 static PHYSFS_sint64 QPAK_fileLength(FileHandle *handle);
 static int QPAK_fileClose(FileHandle *handle);
 static int QPAK_isArchive(const char *filename, int forWriting);
-static DirHandle *QPAK_openArchive(const char *name, int forWriting);
-static LinkedStringList *QPAK_enumerateFiles(DirHandle *h,
+static void *QPAK_openArchive(const char *name, int forWriting);
+static LinkedStringList *QPAK_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks);
-static int QPAK_exists(DirHandle *h, const char *name);
-static int QPAK_isDirectory(DirHandle *h, const char *name, int *fileExists);
-static int QPAK_isSymLink(DirHandle *h, const char *name, int *fileExists);
-static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *n, int *e);
-static FileHandle *QPAK_openRead(DirHandle *h, const char *name, int *exist);
-static FileHandle *QPAK_openWrite(DirHandle *h, const char *name);
-static FileHandle *QPAK_openAppend(DirHandle *h, const char *name);
-static int QPAK_remove(DirHandle *h, const char *name);
-static int QPAK_mkdir(DirHandle *h, const char *name);
+static int QPAK_exists(void *opaque, const char *name);
+static int QPAK_isDirectory(void *opaque, const char *name, int *fileExists);
+static int QPAK_isSymLink(void *opaque, const char *name, int *fileExists);
+static PHYSFS_sint64 QPAK_getLastModTime(void *opaque, const char *n, int *e);
+static FileHandle *QPAK_openRead(void *opaque, const char *name, int *exist);
+static FileHandle *QPAK_openWrite(void *opaque, const char *name);
+static FileHandle *QPAK_openAppend(void *opaque, const char *name);
+static int QPAK_remove(void *opaque, const char *name);
+static int QPAK_mkdir(void *opaque, const char *name);
 
 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK =
 {
@@ -144,13 +144,12 @@
 
 
 
-static void QPAK_dirClose(DirHandle *h)
+static void QPAK_dirClose(void *opaque)
 {
-    QPAKinfo *info = ((QPAKinfo *) h->opaque);
+    QPAKinfo *info = ((QPAKinfo *) opaque);
     free(info->filename);
     free(info->entries);
     free(info);
-    free(h);
 } /* QPAK_dirClose */
 
 
@@ -361,20 +360,12 @@
 } /* qpak_load_entries */
 
 
-static DirHandle *QPAK_openArchive(const char *name, int forWriting)
+static void *QPAK_openArchive(const char *name, int forWriting)
 {
-    QPAKinfo *info;
-    DirHandle *retval = malloc(sizeof (DirHandle));
+    QPAKinfo *info = malloc(sizeof (QPAKinfo));
     PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
 
-    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-    info = retval->opaque = malloc(sizeof (QPAKinfo));
-    if (info == NULL)
-    {
-        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
-        goto QPAK_openArchive_failed;
-    } /* if */
-
+    BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, NULL);
     memset(info, '\0', sizeof (QPAKinfo));
 
     info->filename = (char *) malloc(strlen(name) + 1);
@@ -389,21 +380,16 @@
 
     strcpy(info->filename, name);
     info->last_mod_time = modtime;
-    retval->funcs = &__PHYSFS_DirFunctions_QPAK;
-    return(retval);
+    return(info);
 
 QPAK_openArchive_failed:
-    if (retval != NULL)
+    if (info != NULL)
     {
-        if (retval->opaque != NULL)
-        {
-            if (info->filename != NULL)
-                free(info->filename);
-            if (info->entries != NULL)
-                free(info->entries);
-            free(info);
-        } /* if */
-        free(retval);
+        if (info->filename != NULL)
+            free(info->filename);
+        if (info->entries != NULL)
+            free(info->entries);
+        free(info);
     } /* if */
 
     return(NULL);
@@ -463,11 +449,11 @@
 } /* qpak_find_start_of_dir */
 
 
-static LinkedStringList *QPAK_enumerateFiles(DirHandle *h,
+static LinkedStringList *QPAK_enumerateFiles(void *opaque,
                                              const char *dirname,
                                              int omitSymLinks)
 {
-    QPAKinfo *info = ((QPAKinfo *) h->opaque);
+    QPAKinfo *info = ((QPAKinfo *) opaque);
     LinkedStringList *retval = NULL, *p = NULL;
     PHYSFS_sint32 dlen, dlen_inc, max, i;
 
@@ -558,18 +544,18 @@
 } /* qpak_find_entry */
 
 
-static int QPAK_exists(DirHandle *h, const char *name)
+static int QPAK_exists(void *opaque, const char *name)
 {
     int isDir;    
-    QPAKinfo *info = (QPAKinfo *) h->opaque;
+    QPAKinfo *info = (QPAKinfo *) opaque;
     QPAKentry *entry = qpak_find_entry(info, name, &isDir);
     return((entry != NULL) || (isDir));
 } /* QPAK_exists */
 
 
-static int QPAK_isDirectory(DirHandle *h, const char *name, int *fileExists)
+static int QPAK_isDirectory(void *opaque, const char *name, int *fileExists)
 {
-    QPAKinfo *info = (QPAKinfo *) h->opaque;
+    QPAKinfo *info = (QPAKinfo *) opaque;
     int isDir;
     QPAKentry *entry = qpak_find_entry(info, name, &isDir);
 
@@ -581,19 +567,19 @@
 } /* QPAK_isDirectory */
 
 
-static int QPAK_isSymLink(DirHandle *h, const char *name, int *fileExists)
+static int QPAK_isSymLink(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = QPAK_exists(h, name);
+    *fileExists = QPAK_exists(opaque, name);
     return(0);  /* never symlinks in a quake pak. */
 } /* QPAK_isSymLink */
 
 
-static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h,
+static PHYSFS_sint64 QPAK_getLastModTime(void *opaque,
                                         const char *name,
                                         int *fileExists)
 {
     int isDir;
-    QPAKinfo *info = ((QPAKinfo *) h->opaque);
+    QPAKinfo *info = ((QPAKinfo *) opaque);
     PHYSFS_sint64 retval = -1;
     QPAKentry *entry = qpak_find_entry(info, name, &isDir);
 
@@ -605,9 +591,9 @@
 } /* QPAK_getLastModTime */
 
 
-static FileHandle *QPAK_openRead(DirHandle *h, const char *fnm, int *fileExists)
+static FileHandle *QPAK_openRead(void *opaque, const char *fnm, int *fileExists)
 {
-    QPAKinfo *info = ((QPAKinfo *) h->opaque);
+    QPAKinfo *info = ((QPAKinfo *) opaque);
     FileHandle *retval;
     QPAKfileinfo *finfo;
     QPAKentry *entry;
@@ -640,30 +626,29 @@
     finfo->entry = entry;
     retval->opaque = (void *) finfo;
     retval->funcs = &__PHYSFS_FileFunctions_QPAK;
-    retval->dirHandle = h;
     return(retval);
 } /* QPAK_openRead */
 
 
-static FileHandle *QPAK_openWrite(DirHandle *h, const char *name)
+static FileHandle *QPAK_openWrite(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* QPAK_openWrite */
 
 
-static FileHandle *QPAK_openAppend(DirHandle *h, const char *name)
+static FileHandle *QPAK_openAppend(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* QPAK_openAppend */
 
 
-static int QPAK_remove(DirHandle *h, const char *name)
+static int QPAK_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* QPAK_remove */
 
 
-static int QPAK_mkdir(DirHandle *h, const char *name)
+static int QPAK_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* QPAK_mkdir */
--- a/archivers/wad.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/archivers/wad.c	Sun Sep 26 00:25:04 2004 +0000
@@ -80,7 +80,7 @@
 } WADfileinfo;
 
 
-static void WAD_dirClose(DirHandle *h);
+static void WAD_dirClose(void *opaque);
 static PHYSFS_sint64 WAD_read(FileHandle *handle, void *buffer,
                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
 static PHYSFS_sint64 WAD_write(FileHandle *handle, const void *buffer,
@@ -91,19 +91,19 @@
 static PHYSFS_sint64 WAD_fileLength(FileHandle *handle);
 static int WAD_fileClose(FileHandle *handle);
 static int WAD_isArchive(const char *filename, int forWriting);
-static DirHandle *WAD_openArchive(const char *name, int forWriting);
-static LinkedStringList *WAD_enumerateFiles(DirHandle *h,
+static void *WAD_openArchive(const char *name, int forWriting);
+static LinkedStringList *WAD_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks);
-static int WAD_exists(DirHandle *h, const char *name);
-static int WAD_isDirectory(DirHandle *h, const char *name, int *fileExists);
-static int WAD_isSymLink(DirHandle *h, const char *name, int *fileExists);
-static PHYSFS_sint64 WAD_getLastModTime(DirHandle *h, const char *n, int *e);
-static FileHandle *WAD_openRead(DirHandle *h, const char *name, int *exist);
-static FileHandle *WAD_openWrite(DirHandle *h, const char *name);
-static FileHandle *WAD_openAppend(DirHandle *h, const char *name);
-static int WAD_remove(DirHandle *h, const char *name);
-static int WAD_mkdir(DirHandle *h, const char *name);
+static int WAD_exists(void *opaque, const char *name);
+static int WAD_isDirectory(void *opaque, const char *name, int *fileExists);
+static int WAD_isSymLink(void *opaque, const char *name, int *fileExists);
+static PHYSFS_sint64 WAD_getLastModTime(void *opaque, const char *n, int *e);
+static FileHandle *WAD_openRead(void *opaque, const char *name, int *exist);
+static FileHandle *WAD_openWrite(void *opaque, const char *name);
+static FileHandle *WAD_openAppend(void *opaque, const char *name);
+static int WAD_remove(void *opaque, const char *name);
+static int WAD_mkdir(void *opaque, const char *name);
 
 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_WAD =
 {
@@ -146,13 +146,12 @@
 
 
 
-static void WAD_dirClose(DirHandle *h)
+static void WAD_dirClose(void *opaque)
 {
-    WADinfo *info = ((WADinfo *) h->opaque);
+    WADinfo *info = ((WADinfo *) opaque);
     free(info->filename);
     free(info->entries);
     free(info);
-    free(h);
 } /* WAD_dirClose */
 
 
@@ -357,20 +356,12 @@
 } /* wad_load_entries */
 
 
-static DirHandle *WAD_openArchive(const char *name, int forWriting)
+static void *WAD_openArchive(const char *name, int forWriting)
 {
-    WADinfo *info;
-    DirHandle *retval = malloc(sizeof (DirHandle));
     PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
+    WADinfo *info = malloc(sizeof (WADinfo));
 
-    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-    info = retval->opaque = malloc(sizeof (WADinfo));
-    if (info == NULL)
-    {
-        __PHYSFS_setError(ERR_OUT_OF_MEMORY);
-        goto WAD_openArchive_failed;
-    } /* if */
-
+    BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, NULL);
     memset(info, '\0', sizeof (WADinfo));
 
     info->filename = (char *) malloc(strlen(name) + 1);
@@ -385,32 +376,27 @@
 
     strcpy(info->filename, name);
     info->last_mod_time = modtime;
-    retval->funcs = &__PHYSFS_DirFunctions_WAD;
-    return(retval);
+    return(info);
 
 WAD_openArchive_failed:
-    if (retval != NULL)
+    if (info != NULL)
     {
-        if (retval->opaque != NULL)
-        {
-            if (info->filename != NULL)
-                free(info->filename);
-            if (info->entries != NULL)
-                free(info->entries);
-            free(info);
-        } /* if */
-        free(retval);
+        if (info->filename != NULL)
+            free(info->filename);
+        if (info->entries != NULL)
+            free(info->entries);
+        free(info);
     } /* if */
 
     return(NULL);
 } /* WAD_openArchive */
 
 
-static LinkedStringList *WAD_enumerateFiles(DirHandle *h,
+static LinkedStringList *WAD_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks)
 {
-    WADinfo *info = ((WADinfo *) h->opaque);
+    WADinfo *info = ((WADinfo *) opaque);
     WADentry *entry = info->entries;
     LinkedStringList *retval = NULL, *p = NULL;
     PHYSFS_uint32 max = info->entryCount;
@@ -472,15 +458,15 @@
 } /* wad_find_entry */
 
 
-static int WAD_exists(DirHandle *h, const char *name)
+static int WAD_exists(void *opaque, const char *name)
 {
-    return(wad_find_entry(((WADinfo *) h->opaque), name) != NULL);
+    return(wad_find_entry(((WADinfo *) opaque), name) != NULL);
 } /* WAD_exists */
 
 
-static int WAD_isDirectory(DirHandle *h, const char *name, int *fileExists)
+static int WAD_isDirectory(void *opaque, const char *name, int *fileExists)
 {
-    WADentry *entry = wad_find_entry(((WADinfo *) h->opaque), name);
+    WADentry *entry = wad_find_entry(((WADinfo *) opaque), name);
     if (entry != NULL)
     {
         char *n;
@@ -508,31 +494,31 @@
 } /* WAD_isDirectory */
 
 
-static int WAD_isSymLink(DirHandle *h, const char *name, int *fileExists)
+static int WAD_isSymLink(void *opaque, const char *name, int *fileExists)
 {
-    *fileExists = WAD_exists(h, name);
+    *fileExists = WAD_exists(opaque, name);
     return(0);  /* never symlinks in a wad. */
 } /* WAD_isSymLink */
 
 
-static PHYSFS_sint64 WAD_getLastModTime(DirHandle *h,
+static PHYSFS_sint64 WAD_getLastModTime(void *opaque,
                                         const char *name,
                                         int *fileExists)
 {
-    WADinfo *info = ((WADinfo *) h->opaque);
+    WADinfo *info = ((WADinfo *) opaque);
     PHYSFS_sint64 retval = -1;
 
     *fileExists = (wad_find_entry(info, name) != NULL);
     if (*fileExists)  /* use time of WAD itself in the physical filesystem. */
-        retval = ((WADinfo *) h->opaque)->last_mod_time;
+        retval = info->last_mod_time;
 
     return(retval);
 } /* WAD_getLastModTime */
 
 
-static FileHandle *WAD_openRead(DirHandle *h, const char *fnm, int *fileExists)
+static FileHandle *WAD_openRead(void *opaque, const char *fnm, int *fileExists)
 {
-    WADinfo *info = ((WADinfo *) h->opaque);
+    WADinfo *info = ((WADinfo *) opaque);
     FileHandle *retval;
     WADfileinfo *finfo;
     WADentry *entry;
@@ -563,30 +549,29 @@
     finfo->entry = entry;
     retval->opaque = (void *) finfo;
     retval->funcs = &__PHYSFS_FileFunctions_WAD;
-    retval->dirHandle = h;
     return(retval);
 } /* WAD_openRead */
 
 
-static FileHandle *WAD_openWrite(DirHandle *h, const char *name)
+static FileHandle *WAD_openWrite(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* WAD_openWrite */
 
 
-static FileHandle *WAD_openAppend(DirHandle *h, const char *name)
+static FileHandle *WAD_openAppend(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* WAD_openAppend */
 
 
-static int WAD_remove(DirHandle *h, const char *name)
+static int WAD_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* WAD_remove */
 
 
-static int WAD_mkdir(DirHandle *h, const char *name)
+static int WAD_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* WAD_mkdir */
--- a/archivers/zip.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/archivers/zip.c	Sun Sep 26 00:25:04 2004 +0000
@@ -126,21 +126,21 @@
 static PHYSFS_sint64 ZIP_fileLength(FileHandle *handle);
 static int ZIP_fileClose(FileHandle *handle);
 static int ZIP_isArchive(const char *filename, int forWriting);
-static DirHandle *ZIP_openArchive(const char *name, int forWriting);
-static LinkedStringList *ZIP_enumerateFiles(DirHandle *h,
+static void *ZIP_openArchive(const char *name, int forWriting);
+static LinkedStringList *ZIP_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             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_exists(void *opaque, const char *name);
+static int ZIP_isDirectory(void *opaque, const char *name, int *fileExists);
+static int ZIP_isSymLink(void *opaque, const char *name, int *fileExists);
+static PHYSFS_sint64 ZIP_getLastModTime(void *opaque, const char *n, int *e);
+static FileHandle *ZIP_openRead(void *opaque, const char *filename, int *e);
+static FileHandle *ZIP_openWrite(void *opaque, const char *filename);
+static FileHandle *ZIP_openAppend(void *opaque, const char *filename);
+static void ZIP_dirClose(void *opaque);
 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);
+static int ZIP_remove(void *opaque, const char *name);
+static int ZIP_mkdir(void *opaque, const char *name);
 
 
 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
@@ -188,32 +188,15 @@
  */
 static voidpf zlibPhysfsAlloc(voidpf opaque, uInt items, uInt size)
 {
-    /* must lock the whole time, since zlib doesn't deal with that. :( */
-    PHYSFS_allocator *allocator = __PHYSFS_getAllocator();
-    size_t total = (items * size) + sizeof (PHYSFS_memhandle);
-    PHYSFS_memhandle h = allocator->malloc(total);
-    char *ptr;
-    PHYSFS_memhandle *ph;
-    if (h == NULL)
-        return(NULL);
-
-    ptr = (char *) allocator->lock(h);
-    ph = (PHYSFS_memhandle *) ptr;
-    *ph = h; /* tuck the memhandle in front of the memory block... */
-    return(ptr + sizeof (PHYSFS_memhandle));
+    return(((PHYSFS_allocator *) opaque)->malloc(items * size));
 } /* zlibPhysfsAlloc */
 
-
 /*
  * Bridge physfs allocation functions to zlib's format...
  */
 static void zlibPhysfsFree(voidpf opaque, voidpf address)
 {
-    char *ptr = ((char *) address) - (sizeof (PHYSFS_memhandle));
-    PHYSFS_allocator *allocator = __PHYSFS_getAllocator();
-    PHYSFS_memhandle *ph = (PHYSFS_memhandle *) ptr;
-    allocator->unlock(*ph);
-    allocator->free(*ph);
+    ((PHYSFS_allocator *) opaque)->free(address);
 } /* zlibPhysfsFree */
 
 
@@ -225,6 +208,7 @@
     memset(pstr, '\0', sizeof (z_stream));
     pstr->zalloc = zlibPhysfsAlloc;
     pstr->zfree = zlibPhysfsFree;
+    pstr->opaque = __PHYSFS_getAllocator();
 } /* initializeZStream */
 
 
@@ -1052,10 +1036,9 @@
 } /* zip_entry_swap */
 
 
-static int zip_load_entries(void *in, DirHandle *dirh,
+static int zip_load_entries(void *in, ZIPinfo *info,
                             PHYSFS_uint32 data_ofs, PHYSFS_uint32 central_ofs)
 {
-    ZIPinfo *info = (ZIPinfo *) dirh->opaque;
     PHYSFS_uint32 max = info->entryCount;
     PHYSFS_uint32 i;
 
@@ -1078,11 +1061,10 @@
 } /* zip_load_entries */
 
 
-static int zip_parse_end_of_central_dir(void *in, DirHandle *dirh,
+static int zip_parse_end_of_central_dir(void *in, ZIPinfo *info,
                                         PHYSFS_uint32 *data_start,
                                         PHYSFS_uint32 *central_dir_ofs)
 {
-    ZIPinfo *zipinfo = (ZIPinfo *) dirh->opaque;
     PHYSFS_uint32 ui32;
     PHYSFS_uint16 ui16;
     PHYSFS_sint64 len;
@@ -1109,8 +1091,8 @@
     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);
+    BAIL_IF_MACRO(!readui16(in, &info->entryCount), NULL, 0);
+    BAIL_IF_MACRO(ui16 != info->entryCount, ERR_UNSUPPORTED_ARCHIVE, 0);
 
     /* size of the central directory */
     BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
@@ -1146,86 +1128,62 @@
 } /* zip_parse_end_of_central_dir */
 
 
-static DirHandle *zip_allocate_dirhandle(const char *name)
+static ZIPinfo *zip_create_zipinfo(const char *name)
 {
     char *ptr;
-    ZIPinfo *info;
-    DirHandle *retval = malloc(sizeof (DirHandle));
-    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
-    memset(retval, '\0', sizeof (DirHandle));
-
-    info = (ZIPinfo *) malloc(sizeof (ZIPinfo));
-    if (info == NULL)
-    {
-        free(retval);
-        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
-    } /* if */
-
+    ZIPinfo *info = (ZIPinfo *) malloc(sizeof (ZIPinfo));
+    BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, 0);
     memset(info, '\0', sizeof (ZIPinfo));
 
     ptr = (char *) malloc(strlen(name) + 1);
     if (ptr == NULL)
     {
         free(info);
-        free(retval);
         BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
     } /* if */
 
     info->archiveName = ptr;
     strcpy(info->archiveName, name);
-    retval->opaque = info;
-    retval->funcs = &__PHYSFS_DirFunctions_ZIP;
-    return(retval);
-} /* zip_allocate_dirhandle */
+    return(info);
+} /* zip_create_zipinfo */
 
 
-static DirHandle *ZIP_openArchive(const char *name, int forWriting)
+static void *ZIP_openArchive(const char *name, int forWriting)
 {
-    DirHandle *retval = NULL;
     void *in = NULL;
+    ZIPinfo *info = NULL;
     PHYSFS_uint32 data_start;
     PHYSFS_uint32 cent_dir_ofs;
-    int success = 0;
 
     BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
 
     if ((in = __PHYSFS_platformOpenRead(name)) == NULL)
-        goto zip_openarchive_end;
+        goto zip_openarchive_failed;
     
-    if ((retval = zip_allocate_dirhandle(name)) == NULL)
-        goto zip_openarchive_end;
+    if ((info = zip_create_zipinfo(name)) == NULL)
+        goto zip_openarchive_failed;
 
-    if (!zip_parse_end_of_central_dir(in, retval, &data_start, &cent_dir_ofs))
-        goto zip_openarchive_end;
-
-    if (!zip_load_entries(in, retval, data_start, cent_dir_ofs))
-        goto zip_openarchive_end;
-
-    success = 1;  /* ...and we're good to go.  :)  */
+    if (!zip_parse_end_of_central_dir(in, info, &data_start, &cent_dir_ofs))
+        goto zip_openarchive_failed;
 
-zip_openarchive_end:
-    if (!success)  /* clean up for failures. */
+    if (!zip_load_entries(in, info, data_start, cent_dir_ofs))
+        goto zip_openarchive_failed;
+
+    __PHYSFS_platformClose(in);
+    return(info);
+
+zip_openarchive_failed:
+    if (info != NULL)
     {
-        if (retval != NULL)
-        {
-            if (retval->opaque != NULL)
-            {
-                if (((ZIPinfo *) (retval->opaque))->archiveName != NULL)
-                    free(((ZIPinfo *) (retval->opaque))->archiveName);
-
-                free(retval->opaque);
-            } /* if */
-
-            free(retval);
-            retval = NULL;
-        } /* if */
+        if (info->archiveName != NULL)
+            free(info->archiveName);
+        free(info);
     } /* if */
 
     if (in != NULL)
-        __PHYSFS_platformClose(in);  /* Close this even with success. */
+        __PHYSFS_platformClose(in);
 
-    return(retval);
+    return(NULL);
 } /* ZIP_openArchive */
 
 
@@ -1282,11 +1240,11 @@
 } /* zip_find_start_of_dir */
 
 
-static LinkedStringList *ZIP_enumerateFiles(DirHandle *h,
+static LinkedStringList *ZIP_enumerateFiles(void *opaque,
                                             const char *dirname,
                                             int omitSymLinks)
 {
-    ZIPinfo *info = ((ZIPinfo *) h->opaque);
+    ZIPinfo *info = ((ZIPinfo *) opaque);
     LinkedStringList *retval = NULL, *p = NULL;
     PHYSFS_sint32 dlen, dlen_inc, max, i;
 
@@ -1329,21 +1287,21 @@
 } /* ZIP_enumerateFiles */
 
 
-static int ZIP_exists(DirHandle *h, const char *name)
+static int ZIP_exists(void *opaque, const char *name)
 {
     int isDir;    
-    ZIPinfo *info = (ZIPinfo *) h->opaque;
+    ZIPinfo *info = (ZIPinfo *) opaque;
     ZIPentry *entry = zip_find_entry(info, name, &isDir);
     return((entry != NULL) || (isDir));
 } /* ZIP_exists */
 
 
-static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h,
+static PHYSFS_sint64 ZIP_getLastModTime(void *opaque,
                                         const char *name,
                                         int *fileExists)
 {
     int isDir;
-    ZIPinfo *info = (ZIPinfo *) h->opaque;
+    ZIPinfo *info = (ZIPinfo *) opaque;
     ZIPentry *entry = zip_find_entry(info, name, &isDir);
 
     *fileExists = ((isDir) || (entry != NULL));
@@ -1355,9 +1313,9 @@
 } /* ZIP_getLastModTime */
 
 
-static int ZIP_isDirectory(DirHandle *h, const char *name, int *fileExists)
+static int ZIP_isDirectory(void *opaque, const char *name, int *fileExists)
 {
-    ZIPinfo *info = (ZIPinfo *) h->opaque;
+    ZIPinfo *info = (ZIPinfo *) opaque;
     int isDir;
     ZIPentry *entry = zip_find_entry(info, name, &isDir);
 
@@ -1386,10 +1344,10 @@
 } /* ZIP_isDirectory */
 
 
-static int ZIP_isSymLink(DirHandle *h, const char *name, int *fileExists)
+static int ZIP_isSymLink(void *opaque, const char *name, int *fileExists)
 {
     int isDir;
-    ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name, &isDir);
+    ZIPentry *entry = zip_find_entry((ZIPinfo *) opaque, name, &isDir);
     *fileExists = ((isDir) || (entry != NULL));
     BAIL_IF_MACRO(entry == NULL, NULL, 0);
     return(zip_entry_is_symlink(entry));
@@ -1420,9 +1378,9 @@
 } /* zip_get_file_handle */
 
 
-static FileHandle *ZIP_openRead(DirHandle *h, const char *fnm, int *fileExists)
+static FileHandle *ZIP_openRead(void *opaque, const char *fnm, int *fileExists)
 {
-    ZIPinfo *info = (ZIPinfo *) h->opaque;
+    ZIPinfo *info = (ZIPinfo *) opaque;
     ZIPentry *entry = zip_find_entry(info, fnm, NULL);
     FileHandle *retval = NULL;
     ZIPfileinfo *finfo = NULL;
@@ -1445,7 +1403,6 @@
 
     retval->opaque = (void *) finfo;
     retval->funcs = &__PHYSFS_FileFunctions_ZIP;
-    retval->dirHandle = h;
 
     memset(finfo, '\0', sizeof (ZIPfileinfo));
     finfo->handle = in;
@@ -1471,35 +1428,34 @@
 } /* ZIP_openRead */
 
 
-static FileHandle *ZIP_openWrite(DirHandle *h, const char *filename)
+static FileHandle *ZIP_openWrite(void *opaque, const char *filename)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* ZIP_openWrite */
 
 
-static FileHandle *ZIP_openAppend(DirHandle *h, const char *filename)
+static FileHandle *ZIP_openAppend(void *opaque, const char *filename)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
 } /* ZIP_openAppend */
 
 
-static void ZIP_dirClose(DirHandle *h)
+static void ZIP_dirClose(void *opaque)
 {
-    ZIPinfo *zi = (ZIPinfo *) (h->opaque);
+    ZIPinfo *zi = (ZIPinfo *) (opaque);
     zip_free_entries(zi->entries, zi->entryCount);
     free(zi->archiveName);
     free(zi);
-    free(h);
 } /* ZIP_dirClose */
 
 
-static int ZIP_remove(DirHandle *h, const char *name)
+static int ZIP_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* ZIP_remove */
 
 
-static int ZIP_mkdir(DirHandle *h, const char *name)
+static int ZIP_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
 } /* ZIP_mkdir */
--- a/physfs.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/physfs.c	Sun Sep 26 00:25:04 2004 +0000
@@ -25,6 +25,22 @@
 #define __PHYSICSFS_INTERNAL__
 #include "physfs_internal.h"
 
+
+/* !!! FIXME: Get rid of this. Merge it with PhysDirInfo. */
+typedef struct __PHYSFS_DIRHANDLE__
+{
+        /*
+         * This is reserved for the driver to store information.
+         */
+    void *opaque;
+
+        /*
+         * Pointer to the directory i/o functions for this handle.
+         */
+    const struct __PHYSFS_DIRFUNCTIONS__ *funcs;
+} DirHandle;
+
+
 typedef struct __PHYSFS_ERRMSGTYPE__
 {
     PHYSFS_uint64 tid;
@@ -529,8 +545,32 @@
 } /* find_filename_extension */
 
 
+static DirHandle *tryOpenDir(const DirFunctions *f, const char *d, int fw)
+{
+    DirHandle *retval = NULL;
+    if (f->isArchive(d, fw))  /* fw == "for writing" */
+    {
+        void *opaque = f->openArchive(d, fw);
+        if (opaque != NULL)
+        {
+            retval = (DirHandle *) allocator.malloc(sizeof (DirHandle));
+            if (retval == NULL)
+                f->dirClose(opaque);
+            else
+            {
+                retval->funcs = f;
+                retval->opaque = opaque;
+            } /* else */
+        } /* if */
+    } /* if */
+
+    return(retval);
+} /* tryOpenDir */
+
+
 static DirHandle *openDirectory(const char *d, int forWriting)
 {
+    DirHandle *retval = NULL;
     const DirFunctions **i;
     const char *ext;
 
@@ -540,37 +580,28 @@
     if (ext != NULL)
     {
         /* Look for archivers with matching file extensions first... */
-        for (i = dirFunctions; *i != NULL; i++)
+        for (i = dirFunctions; (*i != NULL) && (retval == NULL); i++)
         {
             if (__PHYSFS_platformStricmp(ext, (*i)->info->extension) == 0)
-            {
-                if ((*i)->isArchive(d, forWriting))
-                    return( (*i)->openArchive(d, forWriting) );
-            } /* if */
+                retval = tryOpenDir(*i, d, forWriting);
         } /* for */
 
         /* failing an exact file extension match, try all the others... */
-        for (i = dirFunctions; *i != NULL; i++)
+        for (i = dirFunctions; (*i != NULL) && (retval == NULL); i++)
         {
             if (__PHYSFS_platformStricmp(ext, (*i)->info->extension) != 0)
-            {
-                if ((*i)->isArchive(d, forWriting))
-                    return( (*i)->openArchive(d, forWriting) );
-            } /* if */
+                retval = tryOpenDir(*i, d, forWriting);
         } /* for */
     } /* if */
 
     else  /* no extension? Try them all. */
     {
-        for (i = dirFunctions; *i != NULL; i++)
-        {
-            if ((*i)->isArchive(d, forWriting))
-                return( (*i)->openArchive(d, forWriting) );
-        } /* for */
+        for (i = dirFunctions; (*i != NULL) && (retval == NULL); i++)
+            retval = tryOpenDir(*i, d, forWriting);
     } /* else */
 
-    __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
-    return(NULL);
+    BAIL_IF_MACRO(retval == NULL, ERR_UNSUPPORTED_ARCHIVE, NULL);
+    return(retval);
 } /* openDirectory */
 
 
@@ -584,10 +615,12 @@
     dirHandle = openDirectory(newDir, forWriting);
     BAIL_IF_MACRO(dirHandle == NULL, NULL, 0);
 
+    /* !!! FIXME: get rid of this allocation */
     di = (PhysDirInfo *) malloc(sizeof (PhysDirInfo));
     if (di == NULL)
     {
-        dirHandle->funcs->dirClose(dirHandle);
+        dirHandle->funcs->dirClose(dirHandle->opaque);
+        free(dirHandle);
         BAIL_IF_MACRO(di == NULL, ERR_OUT_OF_MEMORY, 0);
     } /* if */
 
@@ -595,7 +628,8 @@
     if (di->dirName == NULL)
     {
         free(di);
-        dirHandle->funcs->dirClose(dirHandle);
+        dirHandle->funcs->dirClose(dirHandle->opaque);
+        free(dirHandle);
         BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
     } /* if */
 
@@ -620,7 +654,8 @@
         BAIL_IF_MACRO(h == di->dirHandle, ERR_FILES_STILL_OPEN, 0);
     } /* for */
     
-    di->dirHandle->funcs->dirClose(di->dirHandle);
+    di->dirHandle->funcs->dirClose(di->dirHandle->opaque);
+    free(di->dirHandle);
     free(di->dirName);
     free(di);
     return(1);
@@ -767,6 +802,8 @@
     if (!externalAllocator)
         setDefaultAllocator();
 
+    BAIL_IF_MACRO(!allocator.init(), NULL, 0);
+
     BAIL_IF_MACRO(!__PHYSFS_platformInit(), NULL, 0);
 
     BAIL_IF_MACRO(!initializeMutexes(), NULL, 0);
@@ -891,6 +928,8 @@
     __PHYSFS_platformDestroyMutex(errorLock);
     __PHYSFS_platformDestroyMutex(stateLock);
 
+    allocator.deinit();
+
     errorLock = stateLock = NULL;
     return(1);
 } /* PHYSFS_deinit */
@@ -1253,6 +1292,18 @@
 } /* __PHYSFS_convertToDependent */
 
 
+/*
+ * Verify that (fname) (in platform-independent notation), in relation
+ *  to (h) is secure. That means that each element of fname is checked
+ *  for symlinks (if they aren't permitted). Also, elements such as
+ *  ".", "..", or ":" are flagged.
+ *
+ * With some exceptions (like PHYSFS_mkdir(), which builds multiple subdirs
+ *  at a time), you should always pass zero for "allowMissing" for efficiency.
+ *
+ * Returns non-zero if string is safe, zero if there's a security issue.
+ *  PHYSFS_getLastError() will specify what was wrong.
+ */
 int __PHYSFS_verifySecurity(DirHandle *h, const char *fname, int allowMissing)
 {
     int retval = 1;
@@ -1286,7 +1337,7 @@
 
         if (!allowSymLinks)
         {
-            if (h->funcs->isSymLink(h, str, &retval))
+            if (h->funcs->isSymLink(h->opaque, str, &retval))
             {
                 __PHYSFS_setError(ERR_SYMLINK_DISALLOWED);
                 free(str);
@@ -1348,10 +1399,10 @@
 
         /* only check for existance if all parent dirs existed, too... */
         if (exists)
-            retval = h->funcs->isDirectory(h, str, &exists);
+            retval = h->funcs->isDirectory(h->opaque, str, &exists);
 
         if (!exists)
-            retval = h->funcs->mkdir(h, str);
+            retval = h->funcs->mkdir(h->opaque, str);
 
         if (!retval)
             break;
@@ -1384,7 +1435,7 @@
     BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0);
     h = writeDir->dirHandle;
     BAIL_IF_MACRO_MUTEX(!__PHYSFS_verifySecurity(h,fname,0),NULL,stateLock,0);
-    retval = h->funcs->remove(h, fname);
+    retval = h->funcs->remove(h->opaque, fname);
 
     __PHYSFS_platformReleaseMutex(stateLock);
     return(retval);
@@ -1405,7 +1456,7 @@
         DirHandle *h = i->dirHandle;
         if (__PHYSFS_verifySecurity(h, filename, 0))
         {
-            if (h->funcs->exists(h, filename))
+            if (h->funcs->exists(h->opaque, filename))
                 retval = i->dirName;
         } /* if */
     } /* for */
@@ -1522,7 +1573,7 @@
         DirHandle *h = i->dirHandle;
         if (__PHYSFS_verifySecurity(h, path, 0))
         {
-            rc = h->funcs->enumerateFiles(h, path, omitSymLinks);
+            rc = h->funcs->enumerateFiles(h->opaque, path, omitSymLinks);
             interpolateStringLists(&finalList, rc);
         } /* if */
     } /* for */
@@ -1561,7 +1612,7 @@
     {
         DirHandle *h = i->dirHandle;
         if (__PHYSFS_verifySecurity(h, fname, 0))
-            retval = h->funcs->getLastModTime(h, fname, &fileExists);
+            retval = h->funcs->getLastModTime(h->opaque, fname, &fileExists);
     } /* for */
     __PHYSFS_platformReleaseMutex(stateLock);
 
@@ -1586,7 +1637,7 @@
     {
         DirHandle *h = i->dirHandle;
         if (__PHYSFS_verifySecurity(h, fname, 0))
-            retval = h->funcs->isDirectory(h, fname, &fileExists);
+            retval = h->funcs->isDirectory(h->opaque, fname, &fileExists);
     } /* for */
     __PHYSFS_platformReleaseMutex(stateLock);
 
@@ -1613,7 +1664,7 @@
     {
         DirHandle *h = i->dirHandle;
         if (__PHYSFS_verifySecurity(h, fname, 0))
-            retval = h->funcs->isSymLink(h, fname, &fileExists);
+            retval = h->funcs->isSymLink(h->opaque, fname, &fileExists);
     } /* for */
     __PHYSFS_platformReleaseMutex(stateLock);
 
@@ -1643,11 +1694,16 @@
     BAIL_IF_MACRO_MUTEX(!list, ERR_OUT_OF_MEMORY, stateLock, NULL);
 
     f = h->funcs;
-    rc = (appending) ? f->openAppend(h, fname) : f->openWrite(h, fname);
+    if (appending)
+        rc = f->openAppend(h->opaque, fname);
+    else
+        rc = f->openWrite(h->opaque, fname);
+
     if (rc == NULL)
         free(list);
     else
     {
+        rc->dirHandle = h;
         rc->buffer = NULL;  /* just in case. */
         rc->buffill = rc->bufpos = rc->bufsize = 0;  /* just in case. */
         rc->forReading = 0;
@@ -1679,8 +1735,9 @@
     PHYSFS_file *retval = NULL;
     FileHandle *rc = NULL;
     FileHandleList *list;
+    DirHandle *h = NULL;
     int fileExists = 0;
-    PhysDirInfo *i;
+    PhysDirInfo *i = NULL;
 
     BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, NULL);
     while (*fname == '/')
@@ -1690,12 +1747,14 @@
     BAIL_IF_MACRO_MUTEX(!searchPath, ERR_NOT_IN_SEARCH_PATH, stateLock, NULL);
     for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next)
     {
-        DirHandle *h = i->dirHandle;
+        h = i->dirHandle;
         if (__PHYSFS_verifySecurity(h, fname, 0))
-            rc = h->funcs->openRead(h, fname, &fileExists);
+            rc = h->funcs->openRead(h->opaque, fname, &fileExists);
     } /* for */
     BAIL_IF_MACRO_MUTEX(rc == NULL, NULL, stateLock, NULL);
 
+    rc->dirHandle = h;
+
     list = (FileHandleList *) malloc(sizeof (FileHandleList));
     BAIL_IF_MACRO_MUTEX(!list, ERR_OUT_OF_MEMORY, stateLock, NULL);
     list->handle.opaque = (void *) rc;
@@ -2020,11 +2079,11 @@
 static void setDefaultAllocator(void)
 {
     assert(!externalAllocator);
-    allocator.malloc = __PHYSFS_platformMalloc;
-    allocator.realloc = __PHYSFS_platformRealloc;
-    allocator.free = __PHYSFS_platformFree;
-    allocator.lock = __PHYSFS_platformLock;
-    allocator.unlock = __PHYSFS_platformUnlock;
+    allocator.init = __PHYSFS_platformAllocatorInit;
+    allocator.deinit = __PHYSFS_platformAllocatorDeinit;
+    allocator.malloc = __PHYSFS_platformAllocatorMalloc;
+    allocator.realloc = __PHYSFS_platformAllocatorRealloc;
+    allocator.free = __PHYSFS_platformAllocatorFree;
 } /* setDefaultAllocator */
 
 
--- a/physfs.h	Sun Sep 26 00:24:05 2004 +0000
+++ b/physfs.h	Sun Sep 26 00:25:04 2004 +0000
@@ -1822,28 +1822,6 @@
 
 /* Everything above this line is part of the PhysicsFS 1.0 API. */
 
-
-/**
- * \typedef PHYSFS_memhandle
- * \brief Used to represent memory blocks.
- *
- * (This is for limited, hardcore use. If you don't immediately see a need
- *  for it, you can probably ignore this forever.)
- *
- * The allocator routines will pass these around. They are void pointers
- *  because it's convenient for systems to have handles be the same size
- *  as a pointer, but they shouldn't be assumed to point to valid memory
- *  (or to memory at all). The allocator in use will convert from memhandles
- *  to valid pointers to allocated memory. A memhandle of NULL is considered
- *  to be bogus (so malloc can return a NULL handle), even though it's not
- *  technically a NULL pointer in itself.
- *
- * \sa PHYSFS_allocator
- * \sa PHYSFS_setAllocator
- */
-typedef void *PHYSFS_memhandle;
-
-
 /**
  * \struct PHYSFS_allocator
  * \brief PhysicsFS allocation function pointers.
@@ -1852,28 +1830,18 @@
  *  for it, you can probably ignore this forever.)
  *
  * You create one of these structures for use with PHYSFS_setAllocator.
- *  It should be noted that, in order to accomodate platforms like PalmOS,
- *  we don't just ask for a block of memory and get a pointer. We work on
- *  a "handle" system, which requires PhysicsFS to "lock" before accessing,
- *  and "unlock" when not using. This is also useful for systems that are
- *  concerned about memory fragmentation; you can rearrange unlocked memory
- *  blocks in your address space, since PhysicsFS will re-request the pointer
- *  by relocking the block.
+ *  Allocators are assumed to be reentrant by the caller; please mutex
+ *  accordingly.
  *
- * Locked memory is assumed to be non-reentrant, and locking an already-locked
- *  handle (and unlocking an unlocked handle) has undefined results. Use
- *  mutexes if not sure.
- *
- * \sa PHYSFS_memhandle
  * \sa PHYSFS_setAllocator
  */
 typedef struct
 {
-    PHYSFS_memhandle (*malloc)(size_t);
-    PHYSFS_memhandle (*realloc)(PHYSFS_memhandle, size_t);
-    void (*free)(PHYSFS_memhandle);
-    void *(*lock)(PHYSFS_memhandle);
-    void *(*unlock)(PHYSFS_memhandle);
+    int (*init)(void);
+    void (*deinit)(void);
+    void *(*malloc)(size_t);
+    void *(*realloc)(void *, size_t);
+    void (*free)(void *);
 } PHYSFS_allocator;
 
 
--- a/physfs_internal.h	Sun Sep 26 00:24:05 2004 +0000
+++ b/physfs_internal.h	Sun Sep 26 00:25:04 2004 +0000
@@ -1029,20 +1029,6 @@
 } FileFunctions;
 
 
-typedef struct __PHYSFS_DIRHANDLE__
-{
-        /*
-         * This is reserved for the driver to store information.
-         */
-    void *opaque;
-
-        /*
-         * Pointer to the directory i/o functions for this handle.
-         */
-    const struct __PHYSFS_DIRFUNCTIONS__ *funcs;
-} DirHandle;
-
-
 /*
  * Symlinks should always be followed; PhysicsFS will use
  *  DirFunctions->isSymLink() and make a judgement on whether to
@@ -1062,14 +1048,16 @@
     int (*isArchive)(const char *filename, int forWriting);
 
         /*
-         * Return a DirHandle for dir/archive (name).
+         * Open a dirhandle for dir/archive (name).
          *  This filename is in platform-dependent notation.
          *  forWriting is non-zero if this is to be used for
          *  the write directory, and zero if this is to be used for an
          *  element of the search path.
          * Returns NULL on failure, and calls __PHYSFS_setError().
+         *  Returns non-NULL on success. The pointer returned will be
+         *  passed as the "opaque" parameter for later calls.
          */
-    DirHandle *(*openArchive)(const char *name, int forWriting);
+    void *(*openArchive)(const char *name, int forWriting);
 
         /*
          * Returns a list of all files in dirname. Each element of this list
@@ -1079,7 +1067,7 @@
          * If you have a memory failure, return as much as you can.
          *  This dirname is in platform-independent notation.
          */
-    LinkedStringList *(*enumerateFiles)(DirHandle *r,
+    LinkedStringList *(*enumerateFiles)(void *opaque,
                                         const char *dirname,
                                         int omitSymLinks);
 
@@ -1089,7 +1077,7 @@
          *  This filename is in platform-independent notation.
          *  You should not follow symlinks.
          */
-    int (*exists)(DirHandle *r, const char *name);
+    int (*exists)(void *opaque, const char *name);
 
         /*
          * Returns non-zero if filename is really a directory.
@@ -1101,7 +1089,7 @@
          *  non-zero if the file existed (even if it's a broken symlink!),
          *  zero if it did not.
          */
-    int (*isDirectory)(DirHandle *r, const char *name, int *fileExists);
+    int (*isDirectory)(void *opaque, const char *name, int *fileExists);
 
         /*
          * Returns non-zero if filename is really a symlink.
@@ -1111,7 +1099,7 @@
          *  non-zero if the file existed (even if it's a broken symlink!),
          *  zero if it did not.
          */
-    int (*isSymLink)(DirHandle *r, const char *name, int *fileExists);
+    int (*isSymLink)(void *opaque, const char *name, int *fileExists);
 
         /*
          * Retrieve the last modification time (mtime) of a file.
@@ -1123,7 +1111,7 @@
          *  non-zero if the file existed (even if it's a broken symlink!),
          *  zero if it did not.
          */
-    PHYSFS_sint64 (*getLastModTime)(DirHandle *r, const char *fnm, int *exist);
+    PHYSFS_sint64 (*getLastModTime)(void *opaque, const char *fnm, int *exist);
 
         /*
          * Open file for reading, and return a FileHandle.
@@ -1137,7 +1125,7 @@
          *  non-zero if the file existed (even if it's a broken symlink!),
          *  zero if it did not.
          */
-    FileHandle *(*openRead)(DirHandle *r, const char *fname, int *fileExists);
+    FileHandle *(*openRead)(void *opaque, const char *fname, int *fileExists);
 
         /*
          * Open file for writing, and return a FileHandle.
@@ -1150,7 +1138,7 @@
          *  you can opt to fail for the second call.
          * Returns NULL on failure, and calls __PHYSFS_setError().
          */
-    FileHandle *(*openWrite)(DirHandle *r, const char *filename);
+    FileHandle *(*openWrite)(void *opaque, const char *filename);
 
         /*
          * Open file for appending, and return a FileHandle.
@@ -1162,7 +1150,7 @@
          *  you can opt to fail for the second call.
          * Returns NULL on failure, and calls __PHYSFS_setError().
          */
-    FileHandle *(*openAppend)(DirHandle *r, const char *filename);
+    FileHandle *(*openAppend)(void *opaque, const char *filename);
 
         /*
          * Delete a file in the archive/directory.
@@ -1171,7 +1159,7 @@
          *  This method may be NULL.
          * On failure, call __PHYSFS_setError().
          */
-    int (*remove)(DirHandle *r, const char *filename);
+    int (*remove)(void *opaque, const char *filename);
 
         /*
          * Create a directory in the archive/directory.
@@ -1183,14 +1171,15 @@
          *  This method may be NULL.
          * On failure, call __PHYSFS_setError().
          */
-    int (*mkdir)(DirHandle *r, const char *filename);
+    int (*mkdir)(void *opaque, const char *filename);
 
         /*
-         * Close directories/archives, and free the handle, including
-         *  the "opaque" entry. This should assume that it won't be called if
-         *  there are still files open from this DirHandle.
+         * Close directories/archives, and free any associated memory,
+         *  including (opaque) itself if applicable. Implementation can assume
+         *  that it won't be called if there are still files open from
+         *  this archive.
          */
-    void (*dirClose)(DirHandle *r);
+    void (*dirClose)(void *opaque);
 } DirFunctions;
 
 
@@ -1222,21 +1211,6 @@
                                   const char *append);
 
 /*
- * Verify that (fname) (in platform-independent notation), in relation
- *  to (h) is secure. That means that each element of fname is checked
- *  for symlinks (if they aren't permitted). Also, elements such as
- *  ".", "..", or ":" are flagged.
- *
- * With some exceptions (like PHYSFS_mkdir(), which builds multiple subdirs
- *  at a time), you should always pass zero for "allowMissing" for efficiency.
- *
- * Returns non-zero if string is safe, zero if there's a security issue.
- *  PHYSFS_getLastError() will specify what was wrong.
- */
-int __PHYSFS_verifySecurity(DirHandle *h, const char *fname, int allowMissing);
-
-
-/*
  * Use this to build the list that your enumerate function should return.
  *  See zip.c for an example of proper use.
  */
@@ -1699,33 +1673,39 @@
 void __PHYSFS_platformReleaseMutex(void *mutex);
 
 /*
- * Implement malloc. It's safe to just pass through from the C runtime.
+ * Called during PHYSFS_init() to initialize the allocator, if the user
+ *  hasn't selected their own allocator via PHYSFS_setAllocator().
+ *  Return zero on initialization error (which will make PHYSFS_init() fail,
+ *  too), non-zero on success.
  */
-PHYSFS_memhandle __PHYSFS_platformMalloc(size_t s);
+int __PHYSFS_platformAllocatorInit(void);
+
+/*
+ * Called during PHYSFS_deinit() to deinitialize the allocator, if the user
+ *  hasn't selected their own allocator via PHYSFS_setAllocator().
+ */
+void __PHYSFS_platformAllocatorDeinit(void);
+
+/*
+ * Implement malloc. It's safe to just pass through from the C runtime.
+ *  This is used for allocation if the user hasn't selected their own
+ *  allocator via PHYSFS_setAllocator().
+ */
+void *__PHYSFS_platformAllocatorMalloc(size_t s);
 
 /*
  * Implement realloc. It's safe to just pass through from the C runtime.
+ *  This is used for allocation if the user hasn't selected their own
+ *  allocator via PHYSFS_setAllocator().
  */
-PHYSFS_memhandle __PHYSFS_platformRealloc(PHYSFS_memhandle h, size_t s);
+void *__PHYSFS_platformAllocatorRealloc(void *ptr, size_t s);
 
 /*
  * Implement free. It's safe to just pass through from the C runtime.
- */
-void __PHYSFS_platformFree(PHYSFS_memhandle h);
-
-/*
- * Lock a memhandle. If you are just passing through from the C runtime,
- *  it is safe to make this a no-op. Otherwise, convert to a real pointer
- *  in the address space and return it.
+ *  This is used for deallocation if the user hasn't selected their own
+ *  allocator via PHYSFS_setAllocator().
  */
-void *__PHYSFS_platformLock(PHYSFS_memhandle h);
-
-/*
- * Unlock a memhandle. If you are just passing through from the C runtime,
- *  it is safe to make this a no-op. Otherwise, you can consider the data in
- *  the address space safe to move around until the handle is relocked.
- */
-void __PHYSFS_platformUnlock(PHYSFS_memhandle h);
+void __PHYSFS_platformAllocatorFree(void *ptr);
 
 #ifdef __cplusplus
 }
--- a/platform/posix.c	Sun Sep 26 00:24:05 2004 +0000
+++ b/platform/posix.c	Sun Sep 26 00:25:04 2004 +0000
@@ -501,35 +501,34 @@
 } /* __PHYSFS_platformGetLastModTime */
 
 
-PHYSFS_memhandle __PHYSFS_platformMalloc(size_t s)
+int __PHYSFS_platformAllocatorInit(void)
+{
+    return(1);  /* always succeeds. */
+} /* __PHYSFS_platformAllocatorInit */
+
+
+void __PHYSFS_platformAllocatorDeinit(void)
 {
-    assert(sizeof (h) == sizeof (void *));
-    return((PHYSFS_memhandle) malloc(s));
+    /* no-op */
+} /* __PHYSFS_platformAllocatorInit */
+
+
+void *__PHYSFS_platformAllocatorMalloc(size_t s)
+{
+    return(malloc(s));
 } /* __PHYSFS_platformMalloc */
 
 
-PHYSFS_memhandle __PHYSFS_platformRealloc(PHYSFS_memhandle h, size_t s)
+void *__PHYSFS_platformAllocatorRealloc(void *ptr, size_t s)
 {
-    return((PHYSFS_memhandle) realloc((void *) h, s));
+    return(realloc(ptr, s));
 } /* __PHYSFS_platformRealloc */
 
 
-void __PHYSFS_platformFree(PHYSFS_memhandle h)
-{
-    free((void *) h);
-} /* __PHYSFS_platformFree */
-
-
-void *__PHYSFS_platformLock(PHYSFS_memhandle h)
+void __PHYSFS_platformAllocatorFree(void *ptr)
 {
-    return((void *) h);
-} /* __PHYSFS_platformLock */
-
-
-void __PHYSFS_platformUnlock(PHYSFS_memhandle h)
-{
-    /* no-op. */
-} /* __PHYSFS_platformUnlock */
+    free(ptr);
+} /* __PHYSFS_platformAllocatorFree */
 
 #endif /* !defined WIN32 */