From 7f0e7105a74c4521c4ca2343b9005754d0274db5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 5 Sep 2010 02:41:13 -0400 Subject: [PATCH] Removed isDirectory, isSymLink and exists methods from internal code. Use the PhysFS stat() interface instead. --- src/archiver_dir.c | 52 +++------------------ src/archiver_grp.c | 23 --------- src/archiver_hog.c | 23 --------- src/archiver_iso9660.c | 29 ------------ src/archiver_lzma.c | 27 ----------- src/archiver_mvl.c | 23 --------- src/archiver_qpak.c | 33 ------------- src/archiver_wad.c | 44 ------------------ src/archiver_zip.c | 50 +------------------- src/physfs.c | 100 +++++++++------------------------------- src/physfs.h | 28 ++++++++--- src/physfs_internal.h | 57 ++--------------------- src/platform_os2.c | 32 +++---------- src/platform_pocketpc.c | 34 -------------- src/platform_posix.c | 36 ++++----------- src/platform_windows.c | 68 --------------------------- test/test_physfs.c | 10 +++- 17 files changed, 79 insertions(+), 590 deletions(-) diff --git a/src/archiver_dir.c b/src/archiver_dir.c index 6c5332e1..0301c3fb 100644 --- a/src/archiver_dir.c +++ b/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 */ diff --git a/src/archiver_grp.c b/src/archiver_grp.c index b8632fc4..bbf5f10d 100644 --- a/src/archiver_grp.c +++ b/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 */ diff --git a/src/archiver_hog.c b/src/archiver_hog.c index f8d65bcf..bebfad4c 100644 --- a/src/archiver_hog.c +++ b/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 */ diff --git a/src/archiver_iso9660.c b/src/archiver_iso9660.c index d3b78ebf..ac102588 100644 --- a/src/archiver_iso9660.c +++ b/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 */ diff --git a/src/archiver_lzma.c b/src/archiver_lzma.c index 8d27edb9..b824b3e4 100644 --- a/src/archiver_lzma.c +++ b/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 */ diff --git a/src/archiver_mvl.c b/src/archiver_mvl.c index 173fd39b..e91fa0f5 100644 --- a/src/archiver_mvl.c +++ b/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 */ diff --git a/src/archiver_qpak.c b/src/archiver_qpak.c index 53a244e6..d5b65df7 100644 --- a/src/archiver_qpak.c +++ b/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 */ diff --git a/src/archiver_wad.c b/src/archiver_wad.c index 790abdac..d41ff45f 100644 --- a/src/archiver_wad.c +++ b/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 */ diff --git a/src/archiver_zip.c b/src/archiver_zip.c index a110e015..053c0b0a 100644 --- a/src/archiver_zip.c +++ b/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 */ diff --git a/src/physfs.c b/src/physfs.c index e617f119..240cf7de 100644 --- a/src/physfs.c +++ b/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 */ diff --git a/src/physfs.h b/src/physfs.h index 3380376c..f82305ee 100644 --- a/src/physfs.h +++ b/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 diff --git a/src/physfs_internal.h b/src/physfs_internal.h index 461509df..f5deb2ff 100644 --- a/src/physfs_internal.h +++ b/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. diff --git a/src/platform_os2.c b/src/platform_os2.c index 4f022e3c..9b549522 100644 --- a/src/platform_os2.c +++ b/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); diff --git a/src/platform_pocketpc.c b/src/platform_pocketpc.c index 0c99e6ae..c94bdc1e 100644 --- a/src/platform_pocketpc.c +++ b/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) diff --git a/src/platform_posix.c b/src/platform_posix.c index 9573e473..7ff4a30f 100644 --- a/src/platform_posix.c +++ b/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); diff --git a/src/platform_windows.c b/src/platform_windows.c index e756e5ac..b286578d 100644 --- a/src/platform_windows.c +++ b/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) diff --git a/test/test_physfs.c b/test/test_physfs.c index 6b1121ad..2b77e772 100644 --- a/test/test_physfs.c +++ b/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 */