archivers/wad.c
changeset 610 1d8057a5d08e
parent 609 3a91332776e0
child 622 c8e67ca63ad6
--- a/archivers/wad.c	Mon Dec 15 04:01:18 2003 +0000
+++ b/archivers/wad.c	Thu Dec 18 19:53:20 2003 +0000
@@ -58,7 +58,7 @@
 
 typedef struct
 {
-    char name[9];
+    char name[18];
     PHYSFS_uint32 startPos;
     PHYSFS_uint32 size;
 } WADentry;
@@ -309,6 +309,9 @@
     PHYSFS_uint32 fileCount;
     PHYSFS_uint32 directoryOffset;
     WADentry *entry;
+    char lastDirectory[9],buffer[9];
+
+    lastDirectory[8] = 0; /* Make sure lastDirectory stays null-terminated. */
 
     BAIL_IF_MACRO(!wad_open(name, forWriting, &fh, &fileCount,&directoryOffset), NULL, 0);
     info->entryCount = fileCount;
@@ -412,34 +415,47 @@
     LinkedStringList *retval = NULL, *p = NULL;
     PHYSFS_uint32 max = info->entryCount;
     PHYSFS_uint32 i;
-
-    /* no directories in WAD files. */
-    BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
+    char *sep;
 
-    for (i = 0; i < max; i++, entry++)
-        retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
-
+    if (dirname[0] == 0)
+    {
+        for (i = 0; i < max; i++, entry++)
+        {
+            if (strchr(entry->name, '/') == NULL)
+            {
+                retval = __PHYSFS_addToLinkedStringList(retval, &p,
+                                                        entry->name, -1);
+            } /* if */
+        } /* for */
+    } /* if */
+    else
+    {
+        for (i = 0; i < max; i++, entry++)
+        {
+            sep = strchr(entry->name, '/');
+            if (sep != NULL)
+            {
+                if (strncmp(dirname, entry->name, (sep-entry->name)) == 0)
+                {
+                    retval = __PHYSFS_addToLinkedStringList(retval, &p,
+                                                            sep + 1, -1);
+                } /* if */
+            } /* if */
+        } /* for */
+    } /* else */
+    
     return(retval);
 } /* WAD_enumerateFiles */
 
 
 static WADentry *wad_find_entry(WADinfo *info, const char *name)
 {
-    char *ptr = strchr(name, '.');
     WADentry *a = info->entries;
     PHYSFS_sint32 lo = 0;
     PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
     PHYSFS_sint32 middle;
     int rc;
 
-    /*
-     * Rule out filenames to avoid unneeded processing...no dirs,
-     *   big filenames, or extensions > 3 chars.
-     */
-    BAIL_IF_MACRO((ptr) && (strlen(ptr) > 4), ERR_NO_SUCH_FILE, NULL);
-    BAIL_IF_MACRO(strlen(name) > 12, ERR_NO_SUCH_FILE, NULL);
-    BAIL_IF_MACRO(strchr(name, '/') != NULL, ERR_NO_SUCH_FILE, NULL);
-
     while (lo <= hi)
     {
         middle = lo + ((hi - lo) / 2);
@@ -464,8 +480,31 @@
 
 static int WAD_isDirectory(DirHandle *h, const char *name, int *fileExists)
 {
-    *fileExists = WAD_exists(h, name);
-    return(0);  /* never directories in a wad. */
+    WADentry *entry = wad_find_entry(((WADinfo *) h->opaque), name);
+    if (entry != NULL)
+    {
+        char *n;
+
+        *fileExists = 1;
+
+        /* Can't be a directory if it's a subdirectory. */
+        if (strchr(entry->name, '/') != NULL)
+            return(0);
+
+        /* Check if it matches "MAP??" or "E?M?" ... */
+        n = entry->name;
+        if ((n[0] == 'E' && n[2] == 'M') ||
+            (n[0] == 'M' && n[1] == 'A' && n[2] == 'P' && n[6] == 0))
+        {
+            return(1);
+        } /* if */
+        return(0);
+    } /* if */
+    else
+    {
+        *fileExists = 0;
+        return(0);
+    } /* else */
 } /* WAD_isDirectory */