فهرست منبع

Removed isDirectory, isSymLink and exists methods from internal code.

Use the PhysFS stat() interface instead.
Ryan C. Gordon 15 سال پیش
والد
کامیت
7f0e7105a7
17فایلهای تغییر یافته به همراه79 افزوده شده و 590 حذف شده
  1. 7 45
      src/archiver_dir.c
  2. 0 23
      src/archiver_grp.c
  3. 0 23
      src/archiver_hog.c
  4. 0 29
      src/archiver_iso9660.c
  5. 0 27
      src/archiver_lzma.c
  6. 0 23
      src/archiver_mvl.c
  7. 0 33
      src/archiver_qpak.c
  8. 0 44
      src/archiver_wad.c
  9. 2 48
      src/archiver_zip.c
  10. 22 78
      src/physfs.c
  11. 21 7
      src/physfs.h
  12. 3 54
      src/physfs_internal.h
  13. 6 26
      src/platform_os2.c
  14. 0 34
      src/platform_pocketpc.c
  15. 10 26
      src/platform_posix.c
  16. 0 68
      src/platform_windows.c
  17. 8 2
      test/test_physfs.c

+ 7 - 45
src/archiver_dir.c

@@ -18,13 +18,17 @@
 
 static void *DIR_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
 {
+    PHYSFS_Stat statbuf;
     const char *dirsep = PHYSFS_getDirSeparator();
     char *retval = NULL;
     const size_t namelen = strlen(name);
     const size_t seplen = strlen(dirsep);
+    int exists = 0;
 
     assert(io == NULL);  /* shouldn't create an Io for these. */
-    BAIL_IF_MACRO(!__PHYSFS_platformIsDirectory(name), ERR_NOT_AN_ARCHIVE, NULL);
+    BAIL_IF_MACRO(!__PHYSFS_platformStat(name, &exists, &statbuf), NULL, NULL);
+    if ((!exists) || (statbuf.filetype != PHYSFS_FILETYPE_DIRECTORY))
+        BAIL_MACRO(ERR_NOT_AN_ARCHIVE, NULL);
 
     retval = allocator.Malloc(namelen + seplen + 1);
     BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
@@ -55,46 +59,6 @@ static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
 } /* DIR_enumerateFiles */
 
 
-static int DIR_exists(dvoid *opaque, const char *name)
-{
-    char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
-    int retval;
-
-    BAIL_IF_MACRO(f == NULL, NULL, 0);
-    retval = __PHYSFS_platformExists(f);
-    allocator.Free(f);
-    return retval;
-} /* DIR_exists */
-
-
-static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
-    int retval = 0;
-
-    BAIL_IF_MACRO(d == NULL, NULL, 0);
-    *fileExists = __PHYSFS_platformExists(d);
-    if (*fileExists)
-        retval = __PHYSFS_platformIsDirectory(d);
-    allocator.Free(d);
-    return retval;
-} /* DIR_isDirectory */
-
-
-static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
-    int retval = 0;
-
-    BAIL_IF_MACRO(f == NULL, NULL, 0);
-    *fileExists = __PHYSFS_platformExists(f);
-    if (*fileExists)
-        retval = __PHYSFS_platformIsSymLink(f);
-    allocator.Free(f);
-    return retval;
-} /* DIR_isSymLink */
-
-
 static PHYSFS_Io *doOpen(dvoid *opaque, const char *name,
                          const int mode, int *fileExists)
 {
@@ -113,7 +77,8 @@ static PHYSFS_Io *doOpen(dvoid *opaque, const char *name,
     allocator.Free(f);
     if (io == NULL)
     {
-        *fileExists = __PHYSFS_platformExists(f);
+        PHYSFS_Stat statbuf;
+        __PHYSFS_platformStat(f, fileExists, &statbuf);
         return NULL;
     } /* if */
 
@@ -197,9 +162,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
     &__PHYSFS_ArchiveInfo_DIR,
     DIR_openArchive,        /* openArchive() method    */
     DIR_enumerateFiles,     /* enumerateFiles() method */
-    DIR_exists,             /* exists() method         */
-    DIR_isDirectory,        /* isDirectory() method    */
-    DIR_isSymLink,          /* isSymLink() method      */
     DIR_openRead,           /* openRead() method       */
     DIR_openWrite,          /* openWrite() method      */
     DIR_openAppend,         /* openAppend() method     */

+ 0 - 23
src/archiver_grp.c

@@ -319,26 +319,6 @@ static GRPentry *grp_find_entry(const GRPinfo *info, const char *name)
 } /* grp_find_entry */
 
 
-static int GRP_exists(dvoid *opaque, const char *name)
-{
-    return (grp_find_entry((GRPinfo *) opaque, name) != NULL);
-} /* GRP_exists */
-
-
-static int GRP_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = GRP_exists(opaque, name);
-    return 0;  /* never directories in a groupfile. */
-} /* GRP_isDirectory */
-
-
-static int GRP_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = GRP_exists(opaque, name);
-    return 0;  /* never symlinks in a groupfile. */
-} /* GRP_isSymLink */
-
-
 static PHYSFS_Io *GRP_openRead(dvoid *opaque, const char *fnm, int *fileExists)
 {
     PHYSFS_Io *retval = NULL;
@@ -443,9 +423,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_GRP =
     &__PHYSFS_ArchiveInfo_GRP,
     GRP_openArchive,        /* openArchive() method    */
     GRP_enumerateFiles,     /* enumerateFiles() method */
-    GRP_exists,             /* exists() method         */
-    GRP_isDirectory,        /* isDirectory() method    */
-    GRP_isSymLink,          /* isSymLink() method      */
     GRP_openRead,           /* openRead() method       */
     GRP_openWrite,          /* openWrite() method      */
     GRP_openAppend,         /* openAppend() method     */

+ 0 - 23
src/archiver_hog.c

@@ -335,26 +335,6 @@ static HOGentry *hog_find_entry(const HOGinfo *info, const char *name)
 } /* hog_find_entry */
 
 
-static int HOG_exists(dvoid *opaque, const char *name)
-{
-    return (hog_find_entry((HOGinfo *) opaque, name) != NULL);
-} /* HOG_exists */
-
-
-static int HOG_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = HOG_exists(opaque, name);
-    return 0;  /* never directories in a groupfile. */
-} /* HOG_isDirectory */
-
-
-static int HOG_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = HOG_exists(opaque, name);
-    return 0;  /* never symlinks in a groupfile. */
-} /* HOG_isSymLink */
-
-
 static PHYSFS_Io *HOG_openRead(dvoid *opaque, const char *fnm, int *fileExists)
 {
     PHYSFS_Io *retval = NULL;
@@ -459,9 +439,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_HOG =
     &__PHYSFS_ArchiveInfo_HOG,
     HOG_openArchive,        /* openArchive() method    */
     HOG_enumerateFiles,     /* enumerateFiles() method */
-    HOG_exists,             /* exists() method         */
-    HOG_isDirectory,        /* isDirectory() method    */
-    HOG_isSymLink,          /* isSymLink() method      */
     HOG_openRead,           /* openRead() method       */
     HOG_openWrite,          /* openWrite() method      */
     HOG_openAppend,         /* openAppend() method     */

+ 0 - 29
src/archiver_iso9660.c

@@ -875,16 +875,6 @@ static void ISO9660_enumerateFiles(dvoid *opaque, const char *dname,
 } /* ISO9660_enumerateFiles */
 
 
-static int ISO9660_exists(dvoid *opaque, const char *name)
-{
-    ISO9660Handle *handle = (ISO9660Handle*) opaque;
-    ISO9660FileDescriptor descriptor;
-    int exists = 0;
-    BAIL_IF_MACRO(iso_find_dir_entry(handle, name, &descriptor, &exists), NULL, -1);
-    return exists;
-} /* ISO9660_exists */
-
-
 static int ISO9660_stat(dvoid *opaque, const char *name, int *exists,
                         PHYSFS_Stat *stat)
 {
@@ -928,22 +918,6 @@ static int ISO9660_stat(dvoid *opaque, const char *name, int *exists,
 } /* ISO9660_stat */
 
 
-static int ISO9660_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    ISO9660Handle *handle = (ISO9660Handle*) opaque;
-    ISO9660FileDescriptor descriptor;
-    BAIL_IF_MACRO(iso_find_dir_entry(handle, name, &descriptor, fileExists), NULL, 0);
-    return descriptor.flags.directory;
-} /* ISO9660_isDirectory */
-
-
-static int ISO9660_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = ISO9660_exists(opaque, name);
-    return 0;
-} /* ISO9660_isSymLink */
-
-
 /*******************************************************************************
  * Not supported functions
  ******************************************************************************/
@@ -986,9 +960,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660 =
     &__PHYSFS_ArchiveInfo_ISO9660,
     ISO9660_openArchive,        /* openArchive() method    */
     ISO9660_enumerateFiles,     /* enumerateFiles() method */
-    ISO9660_exists,             /* exists() method         */
-    ISO9660_isDirectory,        /* isDirectory() method    */
-    ISO9660_isSymLink,          /* isSymLink() method      */
     ISO9660_openRead,           /* openRead() method       */
     ISO9660_openWrite,          /* openWrite() method      */
     ISO9660_openAppend,         /* openAppend() method     */

+ 0 - 27
src/archiver_lzma.c

@@ -581,30 +581,6 @@ static void LZMA_enumerateFiles(dvoid *opaque, const char *dname,
 } /* LZMA_enumerateFiles */
 
 
-static int LZMA_exists(dvoid *opaque, const char *name)
-{
-    LZMAarchive *archive = (LZMAarchive *) opaque;
-    return (lzma_find_file(archive, name) != NULL);
-} /* LZMA_exists */
-
-
-static int LZMA_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    LZMAarchive *archive = (LZMAarchive *) opaque;
-    LZMAfile *file = lzma_find_file(archive, name);
-
-    *fileExists = (file != NULL);
-
-    return ((file == NULL) ? 0 : file->item->IsDirectory);
-} /* LZMA_isDirectory */
-
-
-static int LZMA_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* LZMA_isSymLink */
-
-
 static PHYSFS_Io *LZMA_openRead(dvoid *opaque, const char *name, int *fileExists)
 {
     LZMAarchive *archive = (LZMAarchive *) opaque;
@@ -719,9 +695,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_LZMA =
     &__PHYSFS_ArchiveInfo_LZMA,
     LZMA_openArchive,        /* openArchive() method    */
     LZMA_enumerateFiles,     /* enumerateFiles() method */
-    LZMA_exists,             /* exists() method         */
-    LZMA_isDirectory,        /* isDirectory() method    */
-    LZMA_isSymLink,          /* isSymLink() method      */
     LZMA_openRead,           /* openRead() method       */
     LZMA_openWrite,          /* openWrite() method      */
     LZMA_openAppend,         /* openAppend() method     */

+ 0 - 23
src/archiver_mvl.c

@@ -316,26 +316,6 @@ static MVLentry *mvl_find_entry(const MVLinfo *info, const char *name)
 } /* mvl_find_entry */
 
 
-static int MVL_exists(dvoid *opaque, const char *name)
-{
-    return (mvl_find_entry((MVLinfo *) opaque, name) != NULL);
-} /* MVL_exists */
-
-
-static int MVL_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = MVL_exists(opaque, name);
-    return 0;  /* never directories in a groupfile. */
-} /* MVL_isDirectory */
-
-
-static int MVL_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = MVL_exists(opaque, name);
-    return 0;  /* never symlinks in a groupfile. */
-} /* MVL_isSymLink */
-
-
 static PHYSFS_Io *MVL_openRead(dvoid *opaque, const char *fnm, int *fileExists)
 {
     PHYSFS_Io *retval = NULL;
@@ -440,9 +420,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_MVL =
     &__PHYSFS_ArchiveInfo_MVL,
     MVL_openArchive,        /* openArchive() method    */
     MVL_enumerateFiles,     /* enumerateFiles() method */
-    MVL_exists,             /* exists() method         */
-    MVL_isDirectory,        /* isDirectory() method    */
-    MVL_isSymLink,          /* isSymLink() method      */
     MVL_openRead,           /* openRead() method       */
     MVL_openWrite,          /* openWrite() method      */
     MVL_openAppend,         /* openAppend() method     */

+ 0 - 33
src/archiver_qpak.c

@@ -451,36 +451,6 @@ static QPAKentry *qpak_find_entry(const QPAKinfo *info, const char *path,
 } /* qpak_find_entry */
 
 
-static int QPAK_exists(dvoid *opaque, const char *name)
-{
-    int isDir;    
-    QPAKinfo *info = (QPAKinfo *) opaque;
-    QPAKentry *entry = qpak_find_entry(info, name, &isDir);
-    return ((entry != NULL) || (isDir));
-} /* QPAK_exists */
-
-
-static int QPAK_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    QPAKinfo *info = (QPAKinfo *) opaque;
-    int isDir;
-    QPAKentry *entry = qpak_find_entry(info, name, &isDir);
-
-    *fileExists = ((isDir) || (entry != NULL));
-    if (isDir)
-        return 1; /* definitely a dir. */
-
-    BAIL_MACRO(ERR_NO_SUCH_FILE, 0);
-} /* QPAK_isDirectory */
-
-
-static int QPAK_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = QPAK_exists(opaque, name);
-    return 0;  /* never symlinks in a quake pak. */
-} /* QPAK_isSymLink */
-
-
 static PHYSFS_Io *QPAK_openRead(dvoid *opaque, const char *fnm, int *fileExists)
 {
     PHYSFS_Io *io = NULL;
@@ -595,9 +565,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_QPAK =
     &__PHYSFS_ArchiveInfo_QPAK,
     QPAK_openArchive,        /* openArchive() method    */
     QPAK_enumerateFiles,     /* enumerateFiles() method */
-    QPAK_exists,             /* exists() method         */
-    QPAK_isDirectory,        /* isDirectory() method    */
-    QPAK_isSymLink,          /* isSymLink() method      */
     QPAK_openRead,           /* openRead() method       */
     QPAK_openWrite,          /* openWrite() method      */
     QPAK_openAppend,         /* openAppend() method     */

+ 0 - 44
src/archiver_wad.c

@@ -336,47 +336,6 @@ static WADentry *wad_find_entry(const WADinfo *info, const char *name)
 } /* wad_find_entry */
 
 
-static int WAD_exists(dvoid *opaque, const char *name)
-{
-    return (wad_find_entry((WADinfo *) opaque, name) != NULL);
-} /* WAD_exists */
-
-
-static int WAD_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    WADentry *entry = wad_find_entry(((WADinfo *) opaque), name);
-    const int exists = (entry != NULL);
-    *fileExists = exists;
-    if (exists)
-    {
-        char *n;
-
-        /* Can't be a directory if it's a subdirectory. */
-        if (strchr(entry->name, '/') != NULL)
-            return 0;
-
-        /* !!! FIXME: this isn't really something we should do. */
-        /* !!! FIXME: I probably broke enumeration up there, too. */
-        /* 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 */
-    } /* if */
-
-    return 0;
-} /* WAD_isDirectory */
-
-
-static int WAD_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    *fileExists = WAD_exists(opaque, name);
-    return 0;  /* never symlinks in a wad. */
-} /* WAD_isSymLink */
-
-
 static PHYSFS_Io *WAD_openRead(dvoid *opaque, const char *fnm, int *fileExists)
 {
     PHYSFS_Io *retval = NULL;
@@ -481,9 +440,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_WAD =
     &__PHYSFS_ArchiveInfo_WAD,
     WAD_openArchive,        /* openArchive() method    */
     WAD_enumerateFiles,     /* enumerateFiles() method */
-    WAD_exists,             /* exists() method         */
-    WAD_isDirectory,        /* isDirectory() method    */
-    WAD_isSymLink,          /* isSymLink() method      */
     WAD_openRead,           /* openRead() method       */
     WAD_openWrite,          /* openWrite() method      */
     WAD_openAppend,         /* openAppend() method     */

+ 2 - 48
src/archiver_zip.c

@@ -1257,51 +1257,6 @@ static void ZIP_enumerateFiles(dvoid *opaque, const char *dname,
 } /* ZIP_enumerateFiles */
 
 
-static int ZIP_exists(dvoid *opaque, const char *name)
-{
-    int isDir;    
-    ZIPinfo *info = (ZIPinfo *) opaque;
-    ZIPentry *entry = zip_find_entry(info, name, &isDir);
-    return ((entry != NULL) || (isDir));
-} /* ZIP_exists */
-
-
-static int ZIP_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
-    ZIPinfo *info = (ZIPinfo *) opaque;
-    int isDir;
-    ZIPentry *entry = zip_find_entry(info, name, &isDir);
-
-    *fileExists = ((isDir) || (entry != NULL));
-    if (isDir)
-        return 1; /* definitely a dir. */
-
-    /* Follow symlinks. This means we might need to resolve entries. */
-    BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, 0);
-
-    if (entry->resolved == ZIP_UNRESOLVED_SYMLINK) /* gotta resolve it. */
-    {
-        if (!zip_resolve(info->io, info, entry))
-            return 0;
-    } /* if */
-
-    BAIL_IF_MACRO(entry->resolved == ZIP_BROKEN_SYMLINK, NULL, 0);
-    BAIL_IF_MACRO(entry->symlink == NULL, ERR_NOT_A_DIR, 0);
-
-    return (zip_find_start_of_dir(info, entry->symlink->name, 1) >= 0);
-} /* ZIP_isDirectory */
-
-
-static int ZIP_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
-    int isDir;
-    const 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);
-} /* ZIP_isSymLink */
-
-
 static PHYSFS_Io *zip_get_io(PHYSFS_Io *io, ZIPinfo *inf, ZIPentry *entry)
 {
     int success;
@@ -1424,6 +1379,8 @@ static int ZIP_stat(dvoid *opaque, const char *filename, int *exists,
     const ZIPinfo *info = (const ZIPinfo *) opaque;
     const ZIPentry *entry = zip_find_entry(info, filename, &isDir);
 
+    /* !!! FIXME: does this need to resolve entries here? */
+
     *exists = isDir || (entry != 0);
     if (!*exists)
         return 0;
@@ -1469,9 +1426,6 @@ const PHYSFS_Archiver __PHYSFS_Archiver_ZIP =
     &__PHYSFS_ArchiveInfo_ZIP,
     ZIP_openArchive,        /* openArchive() method    */
     ZIP_enumerateFiles,     /* enumerateFiles() method */
-    ZIP_exists,             /* exists() method         */
-    ZIP_isDirectory,        /* isDirectory() method    */
-    ZIP_isSymLink,          /* isSymLink() method      */
     ZIP_openRead,           /* openRead() method       */
     ZIP_openWrite,          /* openWrite() method      */
     ZIP_openAppend,         /* openAppend() method     */

+ 22 - 78
src/physfs.c

@@ -859,8 +859,6 @@ static DirHandle *openDirectory(PHYSFS_Io *io, const char *d, int forWriting)
 
     if (io == NULL)
     {
-        BAIL_IF_MACRO(!__PHYSFS_platformExists(d), ERR_NO_SUCH_FILE, NULL);
-
         /* DIR gets first shot (unlike the rest, it doesn't deal with files). */
         retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting);
         if (retval != NULL)
@@ -1830,11 +1828,14 @@ static int verifyPath(DirHandle *h, char **_fname, int allowMissing)
     {
         while (1)
         {
+            PHYSFS_Stat statbuf;
             int rc = 0;
             end = strchr(start, '/');
 
             if (end != NULL) *end = '\0';
-            rc = h->funcs->isSymLink(h->opaque, fname, &retval);
+            rc = h->funcs->stat(h->opaque, fname, &retval, &statbuf);
+            if (rc)
+                rc = (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
             if (end != NULL) *end = '/';
 
             BAIL_IF_MACRO(rc, ERR_SYMLINK_DISALLOWED, 0);   /* insecure. */
@@ -1887,7 +1888,11 @@ static int doMkdir(const char *_dname, char *dname)
 
         /* only check for existance if all parent dirs existed, too... */
         if (exists)
-            retval = h->funcs->isDirectory(h->opaque, dname, &exists);
+        {
+            PHYSFS_Stat statbuf;
+            const int rc = h->funcs->stat(h->opaque, dname, &exists, &statbuf);
+            retval = ((rc) && (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY));
+        } /* if */
 
         if (!exists)
             retval = h->funcs->mkdir(h->opaque, dname);
@@ -1981,9 +1986,12 @@ const char *PHYSFS_getRealDir(const char *_fname)
             } /* if */
             else if (verifyPath(i, &arcfname, 0))
             {
-                if (i->funcs->exists(i->opaque, arcfname))
+                PHYSFS_Stat statbuf;
+                int exists = 0;
+                if (i->funcs->stat(i->opaque, arcfname, &exists, &statbuf))
                 {
-                    retval = i->dirName;
+                    if (exists)
+                        retval = i->dirName;
                     break;
                 } /* if */
             } /* if */
@@ -2157,83 +2165,19 @@ PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname)
 } /* PHYSFS_getLastModTime */
 
 
-int PHYSFS_isDirectory(const char *_fname)
+int PHYSFS_isDirectory(const char *fname)
 {
-    int retval = 0;
-    size_t len;
-    char *fname;
-
-    BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
-    len = strlen(_fname) + 1;
-    fname = (char *) __PHYSFS_smallAlloc(len);
-    BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
-
-    if (!sanitizePlatformIndependentPath(_fname, fname))
-        retval = 0;
-
-    else if (*fname == '\0')
-        retval = 1;  /* Root is always a dir.  :) */
-
-    else
-    {
-        DirHandle *i;
-        int exists = 0;
-
-        __PHYSFS_platformGrabMutex(stateLock);
-        for (i = searchPath; ((i != NULL) && (!exists)); i = i->next)
-        {
-            char *arcfname = fname;
-            if ((exists = partOfMountPoint(i, arcfname)) != 0)
-                retval = 1;
-            else if (verifyPath(i, &arcfname, 0))
-                retval = i->funcs->isDirectory(i->opaque, arcfname, &exists);
-        } /* for */
-        __PHYSFS_platformReleaseMutex(stateLock);
-    } /* else */
-
-    __PHYSFS_smallFree(fname);
-    return retval;
+    PHYSFS_Stat statbuf;
+    BAIL_IF_MACRO(!PHYSFS_stat(fname, &statbuf), NULL, 0);
+    return (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY);
 } /* PHYSFS_isDirectory */
 
 
-int PHYSFS_isSymbolicLink(const char *_fname)
+int PHYSFS_isSymbolicLink(const char *fname)
 {
-    int retval = 0;
-    size_t len;
-    char *fname;
-
-    BAIL_IF_MACRO(!allowSymLinks, ERR_SYMLINK_DISALLOWED, 0);
-
-    BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
-    len = strlen(_fname) + 1;
-    fname = (char *) __PHYSFS_smallAlloc(len);
-    BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
-
-    if (!sanitizePlatformIndependentPath(_fname, fname))
-        retval = 0;
-
-    else if (*fname == '\0')
-        retval = 1;  /* Root is never a symlink. */
-
-    else
-    {
-        DirHandle *i;
-        int fileExists = 0;
-
-        __PHYSFS_platformGrabMutex(stateLock);
-        for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next)
-        {
-            char *arcfname = fname;
-            if ((fileExists = partOfMountPoint(i, arcfname)) != 0)
-                retval = 0;  /* virtual dir...not a symlink. */
-            else if (verifyPath(i, &arcfname, 0))
-                retval = i->funcs->isSymLink(i->opaque, arcfname, &fileExists);
-        } /* for */
-        __PHYSFS_platformReleaseMutex(stateLock);
-    } /* else */
-
-    __PHYSFS_smallFree(fname);
-    return retval;
+    PHYSFS_Stat statbuf;
+    BAIL_IF_MACRO(!PHYSFS_stat(fname, &statbuf), NULL, 0);
+    return (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
 } /* PHYSFS_isSymbolicLink */
 
 

+ 21 - 7
src/physfs.h

@@ -665,6 +665,11 @@ PHYSFS_DECL const char *PHYSFS_getDirSeparator(void);
  *  in platform-independent notation. That is, when setting up your
  *  search and write paths, etc, symlinks are never checked for.
  *
+ * Please note that PHYSFS_stat() will always check the path specified; if
+ *  that path is a symlink, it will not be followed in any case. If symlinks
+ *  aren't permitted through this function, PHYSFS_stat() ignores them, and
+ *  would treat the query as if the path didn't exist at all.
+ *
  * Symbolic link permission can be enabled or disabled at any time after
  *  you've called PHYSFS_init(), and is disabled by default.
  *
@@ -1086,9 +1091,6 @@ PHYSFS_DECL char **PHYSFS_enumerateFiles(const char *dir);
  *
  *    \param fname filename in platform-independent notation.
  *   \return non-zero if filename exists. zero otherwise.
- *
- * \sa PHYSFS_isDirectory
- * \sa PHYSFS_isSymbolicLink
  */
 PHYSFS_DECL int PHYSFS_exists(const char *fname);
 
@@ -1097,6 +1099,9 @@ PHYSFS_DECL int PHYSFS_exists(const char *fname);
  * \fn int PHYSFS_isDirectory(const char *fname)
  * \brief Determine if a file in the search path is really a directory.
  *
+ * \deprecated As of PhysicsFS 2.1, use PHYSFS_stat() instead. This
+ *             function just wraps it anyhow.
+ *
  * Determine if the first occurence of (fname) in the search path is
  *  really a directory entry.
  *
@@ -1107,16 +1112,19 @@ PHYSFS_DECL int PHYSFS_exists(const char *fname);
  *    \param fname filename in platform-independent notation.
  *   \return non-zero if filename exists and is a directory.  zero otherwise.
  *
+ * \sa PHYSFS_stat
  * \sa PHYSFS_exists
- * \sa PHYSFS_isSymbolicLink
  */
-PHYSFS_DECL int PHYSFS_isDirectory(const char *fname);
+PHYSFS_DECL int PHYSFS_isDirectory(const char *fname) PHYSFS_DEPRECATED;
 
 
 /**
  * \fn int PHYSFS_isSymbolicLink(const char *fname)
  * \brief Determine if a file in the search path is really a symbolic link.
  *
+ * \deprecated As of PhysicsFS 2.1, use PHYSFS_stat() instead. This
+ *             function just wraps it anyhow.
+ *
  * Determine if the first occurence of (fname) in the search path is
  *  really a symbolic link.
  *
@@ -1127,10 +1135,10 @@ PHYSFS_DECL int PHYSFS_isDirectory(const char *fname);
  *    \param fname filename in platform-independent notation.
  *   \return non-zero if filename exists and is a symlink.  zero otherwise.
  *
+ * \sa PHYSFS_stat
  * \sa PHYSFS_exists
- * \sa PHYSFS_isDirectory
  */
-PHYSFS_DECL int PHYSFS_isSymbolicLink(const char *fname);
+PHYSFS_DECL int PHYSFS_isSymbolicLink(const char *fname) PHYSFS_DEPRECATED;
 
 
 /**
@@ -2603,6 +2611,12 @@ typedef struct PHYSFS_Stat
  *
  * Obtain various information about a file or directory from the meta data.
  *
+ * This function will never follow symbolic links. If you haven't enabled
+ *  symlinks with PHYSFS_permitSymbolicLinks(), stat'ing a symlink will be
+ *  treated like stat'ing a non-existant file. If symlinks are enabled,
+ *  stat'ing a symlink will give you information on the link itself and not
+ *  what it points to.
+ *
  *    \param fname filename to check, in platform-indepedent notation.
  *    \param stat pointer to structure to fill in with data about (fname).
  *   \return non-zero on success, zero on failure. On failure, (stat)'s

+ 3 - 54
src/physfs_internal.h

@@ -731,9 +731,9 @@ typedef struct
      *  openArchive() method, then pass it as the "opaque" dvoid to the
      *  others.
      *
-     * Symlinks should always be followed; PhysicsFS will use the
-     *  isSymLink() method and make a judgement on whether to
-     *  continue to call other methods based on that.
+     * Symlinks should always be followed (except in stat()); PhysicsFS will
+     *  use the stat() method to check for symlinks and make a judgement on
+     *  whether to continue to call other methods based on that.
      */
 
         /*
@@ -765,35 +765,6 @@ typedef struct
                             const char *origdir,
                             void *callbackdata);
 
-        /*
-         * Returns non-zero if filename can be opened for reading.
-         *  This filename is in platform-independent notation.
-         *  You should not follow symlinks.
-         */
-    int (*exists)(dvoid *opaque, const char *name);
-
-        /*
-         * Returns non-zero if filename is really a directory.
-         *  This filename is in platform-independent notation.
-         *  Symlinks should be followed; if what the symlink points
-         *  to is missing, or isn't a directory, then the retval is zero.
-         *
-         * Regardless of success or failure, please set *fileExists to
-         *  non-zero if the file existed (even if it's a broken symlink!),
-         *  zero if it did not.
-         */
-    int (*isDirectory)(dvoid *opaque, const char *name, int *fileExists);
-
-        /*
-         * Returns non-zero if filename is really a symlink.
-         *  This filename is in platform-independent notation.
-         *
-         * Regardless of success or failure, please set *fileExists to
-         *  non-zero if the file existed (even if it's a broken symlink!),
-         *  zero if it did not.
-         */
-    int (*isSymLink)(dvoid *opaque, const char *name, int *fileExists);
-
         /*
          * Open file for reading.
          *  This filename is in platform-independent notation.
@@ -1274,28 +1245,6 @@ char *__PHYSFS_platformGetUserDir(void);
  */
 void *__PHYSFS_platformGetThreadID(void);
 
-/*
- * Return non-zero if filename (in platform-dependent notation) exists.
- *  Symlinks should NOT be followed; at this stage, we do not care what the
- *  symlink points to. Please call __PHYSFS_SetError() with the details of
- *  why the file does not exist, if it doesn't; you are in a better position
- *  to know (path not found, bogus filename, file itself is missing, etc).
- */
-int __PHYSFS_platformExists(const char *fname);
-
-/*
- * Return non-zero if filename (in platform-dependent notation) is a symlink.
- */
-int __PHYSFS_platformIsSymLink(const char *fname);
-
-/*
- * Return non-zero if filename (in platform-dependent notation) is a symlink.
- *  Symlinks should be followed; if what the symlink points to is missing,
- *  or isn't a directory, then the retval is false.
- */
-int __PHYSFS_platformIsDirectory(const char *fname);
-
-
 /*
  * Convert (dirName) to platform-dependent notation, then prepend (prepend)
  *  and append (append) to the converted string.

+ 6 - 26
src/platform_os2.c

@@ -297,31 +297,6 @@ char *__PHYSFS_platformGetUserDir(void)
 } /* __PHYSFS_platformGetUserDir */
 
 
-int __PHYSFS_platformExists(const char *_fname)
-{
-    const unsigned char *fname = (const unsigned char *) _fname;
-    FILESTATUS3 fs;
-    APIRET rc = DosQueryPathInfo(fname, FIL_STANDARD, &fs, sizeof (fs));
-    return (os2err(rc) == NO_ERROR);
-} /* __PHYSFS_platformExists */
-
-
-int __PHYSFS_platformIsSymLink(const char *fname)
-{
-    return 0;  /* no symlinks in OS/2. */
-} /* __PHYSFS_platformIsSymlink */
-
-
-int __PHYSFS_platformIsDirectory(const char *_fname)
-{
-    const unsigned char *fname = (const unsigned char *) _fname;
-    FILESTATUS3 fs;
-    APIRET rc = DosQueryPathInfo(fname, FIL_STANDARD, &fs, sizeof (fs));
-    BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, 0)
-    return ((fs.attrFile & FILE_DIRECTORY) != 0);
-} /* __PHYSFS_platformIsDirectory */
-
-
 /* !!! FIXME: can we lose the malloc here? */
 char *__PHYSFS_platformCvtToDependent(const char *prepend,
                                       const char *dirName,
@@ -598,8 +573,13 @@ void __PHYSFS_platformClose(void *opaque)
 
 int __PHYSFS_platformDelete(const char *_path)
 {
+    FILESTATUS3 fs;
     const unsigned char *path = (const unsigned char *) _path;
-    if (__PHYSFS_platformIsDirectory(_path))
+    APIRET rc = os2err(DosQueryPathInfo(path, FIL_STANDARD, &fs, sizeof (fs)));
+
+    BAIL_IF_MACRO(rc != NO_ERROR, NULL, 0);
+
+    if (fs.attrFile & FILE_DIRECTORY)
         return (os2err(DosDeleteDir(path)) == NO_ERROR);
 
     return (os2err(DosDelete(path)) == NO_ERROR);

+ 0 - 34
src/platform_pocketpc.c

@@ -167,40 +167,6 @@ void *__PHYSFS_platformGetThreadID(void)
 } /* __PHYSFS_platformGetThreadID */
 
 
-int __PHYSFS_platformExists(const char *fname)
-{
-    int retval = 0;
-    wchar_t *w_fname = NULL;
-
-    UTF8_TO_UNICODE_STACK_MACRO(w_fname, fname);
-    if (w_fname != NULL)
-        retval = (GetFileAttributes(w_fname) != INVALID_FILE_ATTRIBUTES);
-    __PHYSFS_smallFree(w_fname);
-
-    return retval;
-} /* __PHYSFS_platformExists */
-
-
-int __PHYSFS_platformIsSymLink(const char *fname)
-{
-    BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
-} /* __PHYSFS_platformIsSymlink */
-
-
-int __PHYSFS_platformIsDirectory(const char *fname)
-{
-    int retval = 0;
-    wchar_t *w_fname = NULL;
-
-    UTF8_TO_UNICODE_STACK_MACRO(w_fname, fname);
-    if (w_fname != NULL)
-        retval = ((GetFileAttributes(w_fname) & FILE_ATTRIBUTE_DIRECTORY) != 0);
-    __PHYSFS_smallFree(w_fname);
-
-    return retval;
-} /* __PHYSFS_platformIsDirectory */
-
-
 char *__PHYSFS_platformCvtToDependent(const char *prepend,
                                       const char *dirName,
                                       const char *append)

+ 10 - 26
src/platform_posix.c

@@ -116,30 +116,6 @@ char *__PHYSFS_platformGetUserDir(void)
 } /* __PHYSFS_platformGetUserDir */
 
 
-int __PHYSFS_platformExists(const char *fname)
-{
-    struct stat statbuf;
-    BAIL_IF_MACRO(lstat(fname, &statbuf) == -1, strerror(errno), 0);
-    return 1;
-} /* __PHYSFS_platformExists */
-
-
-int __PHYSFS_platformIsSymLink(const char *fname)
-{
-    struct stat statbuf;
-    BAIL_IF_MACRO(lstat(fname, &statbuf) == -1, strerror(errno), 0);
-    return ( (S_ISLNK(statbuf.st_mode)) ? 1 : 0 );
-} /* __PHYSFS_platformIsSymlink */
-
-
-int __PHYSFS_platformIsDirectory(const char *fname)
-{
-    struct stat statbuf;
-    BAIL_IF_MACRO(stat(fname, &statbuf) == -1, strerror(errno), 0);
-    return ( (S_ISDIR(statbuf.st_mode)) ? 1 : 0 );
-} /* __PHYSFS_platformIsDirectory */
-
-
 char *__PHYSFS_platformCvtToDependent(const char *prepend,
                                       const char *dirName,
                                       const char *append)
@@ -213,6 +189,8 @@ void __PHYSFS_platformEnumerateFiles(const char *dirname,
 
         if (omitSymLinks)
         {
+            PHYSFS_Stat statbuf;
+            int exists = 0;
             char *p;
             int len = strlen(ent->d_name) + dlen + 1;
             if (len > bufsize)
@@ -225,8 +203,14 @@ void __PHYSFS_platformEnumerateFiles(const char *dirname,
             } /* if */
 
             strcpy(buf + dlen, ent->d_name);
-            if (__PHYSFS_platformIsSymLink(buf))
-                continue;
+
+            if (__PHYSFS_platformStat(buf, &exists, &statbuf))
+            {
+                if (!exists)
+                    continue;
+                else if (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK)
+                    continue;
+            } /* if */
         } /* if */
 
         callback(callbackdata, origdir, ent->d_name);

+ 0 - 68
src/platform_windows.c

@@ -563,29 +563,6 @@ void *__PHYSFS_platformGetThreadID(void)
 } /* __PHYSFS_platformGetThreadID */
 
 
-static int doPlatformExists(LPWSTR wpath)
-{
-    BAIL_IF_MACRO
-    (
-        pGetFileAttributesW(wpath) == PHYSFS_INVALID_FILE_ATTRIBUTES,
-        winApiStrError(), 0
-    );
-    return 1;
-} /* doPlatformExists */
-
-
-int __PHYSFS_platformExists(const char *fname)
-{
-    int retval = 0;
-    LPWSTR wpath;
-    UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
-    BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
-    retval = doPlatformExists(wpath);
-    __PHYSFS_smallFree(wpath);
-    return retval;
-} /* __PHYSFS_platformExists */
-
-
 static int isSymlinkAttrs(const DWORD attr, const DWORD tag)
 {
     return ( (attr & FILE_ATTRIBUTE_REPARSE_POINT) && 
@@ -593,51 +570,6 @@ static int isSymlinkAttrs(const DWORD attr, const DWORD tag)
 } /* isSymlinkAttrs */
 
 
-int __PHYSFS_platformIsSymLink(const char *fname)
-{
-    /* !!! FIXME:
-     * Windows Vista can have NTFS symlinks. Can older Windows releases have
-     *  them when talking to a network file server? What happens when you
-     *  mount a NTFS partition on XP that was plugged into a Vista install
-     *  that made a symlink?
-     */
-
-    int retval = 0;
-    LPWSTR wpath;
-    HANDLE dir;
-    WIN32_FIND_DATAW entw;
-
-    /* no unicode entry points? Probably no symlinks. */
-    BAIL_IF_MACRO(pFindFirstFileW == NULL, NULL, 0);
-
-    UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
-    BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
-
-    /* !!! FIXME: filter wildcard chars? */
-    dir = pFindFirstFileW(wpath, &entw);
-    if (dir != INVALID_HANDLE_VALUE)
-    {
-        retval = isSymlinkAttrs(entw.dwFileAttributes, entw.dwReserved0);
-        FindClose(dir);
-    } /* if */
-
-    __PHYSFS_smallFree(wpath);
-    return retval;
-} /* __PHYSFS_platformIsSymlink */
-
-
-int __PHYSFS_platformIsDirectory(const char *fname)
-{
-    int retval = 0;
-    LPWSTR wpath;
-    UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
-    BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
-    retval = ((pGetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY) != 0);
-    __PHYSFS_smallFree(wpath);
-    return retval;
-} /* __PHYSFS_platformIsDirectory */
-
-
 char *__PHYSFS_platformCvtToDependent(const char *prepend,
                                       const char *dirName,
                                       const char *append)

+ 8 - 2
test/test_physfs.c

@@ -751,6 +751,7 @@ static int cmd_exists(char *args)
 
 static int cmd_isdir(char *args)
 {
+    PHYSFS_Stat statbuf;
     int rc;
 
     if (*args == '\"')
@@ -759,7 +760,9 @@ static int cmd_isdir(char *args)
         args[strlen(args) - 1] = '\0';
     } /* if */
 
-    rc = PHYSFS_isDirectory(args);
+    rc = PHYSFS_stat(args, &statbuf);
+    if (rc)
+        rc = (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY);
     printf("File %s a directory.\n", rc ? "is" : "is NOT");
     return 1;
 } /* cmd_isdir */
@@ -767,6 +770,7 @@ static int cmd_isdir(char *args)
 
 static int cmd_issymlink(char *args)
 {
+    PHYSFS_Stat statbuf;
     int rc;
 
     if (*args == '\"')
@@ -775,7 +779,9 @@ static int cmd_issymlink(char *args)
         args[strlen(args) - 1] = '\0';
     } /* if */
 
-    rc = PHYSFS_isSymbolicLink(args);
+    rc = PHYSFS_stat(args, &statbuf);
+    if (rc)
+        rc = (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
     printf("File %s a symlink.\n", rc ? "is" : "is NOT");
     return 1;
 } /* cmd_issymlink */