Centralize responsibility for filtering symlinks during enumeration.
--- a/src/archiver_dir.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_dir.c Thu Nov 29 11:47:16 2012 -0500
@@ -67,7 +67,7 @@
static void DIR_enumerateFiles(void *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
{
char *d;
@@ -75,8 +75,7 @@
CVT_TO_DEPENDENT(d, opaque, dname);
if (d != NULL)
{
- __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb,
- origdir, callbackdata);
+ __PHYSFS_platformEnumerateFiles(d, cb, origdir, callbackdata);
__PHYSFS_smallFree(d);
} /* if */
} /* DIR_enumerateFiles */
@@ -187,6 +186,7 @@
"Ryan C. Gordon <icculus@icculus.org>",
"http://icculus.org/physfs/",
},
+ 1, /* supportsSymlinks */
DIR_openArchive, /* openArchive() method */
DIR_enumerateFiles, /* enumerateFiles() method */
DIR_openRead, /* openRead() method */
--- a/src/archiver_grp.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_grp.c Thu Nov 29 11:47:16 2012 -0500
@@ -94,6 +94,7 @@
"Ryan C. Gordon <icculus@icculus.org>",
"http://icculus.org/physfs/",
},
+ 0, /* supportsSymlinks */
GRP_openArchive, /* openArchive() method */
UNPK_enumerateFiles, /* enumerateFiles() method */
UNPK_openRead, /* openRead() method */
--- a/src/archiver_hog.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_hog.c Thu Nov 29 11:47:16 2012 -0500
@@ -100,6 +100,7 @@
"Bradley Bell <btb@icculus.org>",
"http://icculus.org/physfs/",
},
+ 0, /* supportsSymlinks */
HOG_openArchive, /* openArchive() method */
UNPK_enumerateFiles, /* enumerateFiles() method */
UNPK_openRead, /* openRead() method */
--- a/src/archiver_iso9660.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_iso9660.c Thu Nov 29 11:47:16 2012 -0500
@@ -817,7 +817,6 @@
******************************************************************************/
static void ISO9660_enumerateFiles(void *opaque, const char *dname,
- int omitSymLinks,
PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
{
@@ -953,6 +952,7 @@
"Christoph Nelles <evilazrael@evilazrael.de>",
"http://www.evilazrael.de/",
},
+ 0, /* supportsSymlinks */
ISO9660_openArchive, /* openArchive() method */
ISO9660_enumerateFiles, /* enumerateFiles() method */
ISO9660_openRead, /* openRead() method */
--- a/src/archiver_lzma.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_lzma.c Thu Nov 29 11:47:16 2012 -0500
@@ -532,7 +532,7 @@
static void LZMA_enumerateFiles(void *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
{
size_t dlen = strlen(dname),
@@ -685,6 +685,7 @@
"Dennis Schridde <devurandom@gmx.net>",
"http://icculus.org/physfs/",
},
+ 0, /* supportsSymlinks */
LZMA_openArchive, /* openArchive() method */
LZMA_enumerateFiles, /* enumerateFiles() method */
LZMA_openRead, /* openRead() method */
--- a/src/archiver_mvl.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_mvl.c Thu Nov 29 11:47:16 2012 -0500
@@ -87,6 +87,7 @@
"Bradley Bell <btb@icculus.org>",
"http://icculus.org/physfs/",
},
+ 0, /* supportsSymlinks */
MVL_openArchive, /* openArchive() method */
UNPK_enumerateFiles, /* enumerateFiles() method */
UNPK_openRead, /* openRead() method */
--- a/src/archiver_qpak.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_qpak.c Thu Nov 29 11:47:16 2012 -0500
@@ -103,6 +103,7 @@
"Ryan C. Gordon <icculus@icculus.org>",
"http://icculus.org/physfs/",
},
+ 0, /* supportsSymlinks */
QPAK_openArchive, /* openArchive() method */
UNPK_enumerateFiles, /* enumerateFiles() method */
UNPK_openRead, /* openRead() method */
--- a/src/archiver_slb.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_slb.c Thu Nov 29 11:47:16 2012 -0500
@@ -108,6 +108,7 @@
"Aleksi Nurmi <aleksi.nurmi@gmail.com>",
"http://bitbucket.org/ahnurmi/",
},
+ 0, /* supportsSymlinks */
SLB_openArchive, /* openArchive() method */
UNPK_enumerateFiles, /* enumerateFiles() method */
UNPK_openRead, /* openRead() method */
--- a/src/archiver_unpacked.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_unpacked.c Thu Nov 29 11:47:16 2012 -0500
@@ -243,7 +243,7 @@
void UNPK_enumerateFiles(void *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
{
UNPKinfo *info = ((UNPKinfo *) opaque);
--- a/src/archiver_wad.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_wad.c Thu Nov 29 11:47:16 2012 -0500
@@ -111,6 +111,7 @@
"Travis Wells <traviswells@mchsi.com>",
"http://www.3dmm2.com/doom/",
},
+ 0, /* supportsSymlinks */
WAD_openArchive, /* openArchive() method */
UNPK_enumerateFiles, /* enumerateFiles() method */
UNPK_openRead, /* openRead() method */
--- a/src/archiver_zip.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/archiver_zip.c Thu Nov 29 11:47:16 2012 -0500
@@ -1488,7 +1488,7 @@
static void ZIP_enumerateFiles(void *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
{
ZIPinfo *info = ((ZIPinfo *) opaque);
@@ -1510,9 +1510,6 @@
char *e = info->entries[i].name;
if ((dlen) && ((strncmp(e, dname, dlen) != 0) || (e[dlen] != '/')))
break; /* past end of this dir; we're done. */
-
- if ((omitSymLinks) && (zip_entry_is_symlink(&info->entries[i])))
- i++;
else
{
char *add = e + dlen_inc;
@@ -1701,6 +1698,7 @@
"Ryan C. Gordon <icculus@icculus.org>",
"http://icculus.org/physfs/",
},
+ 1, /* supportsSymlinks */
ZIP_openArchive, /* openArchive() method */
ZIP_enumerateFiles, /* enumerateFiles() method */
ZIP_openRead, /* openRead() method */
--- a/src/physfs.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/physfs.c Thu Nov 29 11:47:16 2012 -0500
@@ -2245,6 +2245,40 @@
} /* enumerateFromMountPoint */
+typedef struct SymlinkFilterData
+{
+ PHYSFS_EnumFilesCallback callback;
+ void *callbackData;
+ DirHandle *dirhandle;
+} SymlinkFilterData;
+
+static void enumCallbackFilterSymLinks(void *_data, const char *origdir,
+ const char *fname)
+{
+ const char *trimmedDir = (*origdir == '/') ? (origdir+1) : origdir;
+ const size_t slen = strlen(trimmedDir) + strlen(fname) + 2;
+ char *path = (char *) __PHYSFS_smallAlloc(slen);
+
+ if (path != NULL)
+ {
+ SymlinkFilterData *data = (SymlinkFilterData *) _data;
+ const DirHandle *dh = data->dirhandle;
+ PHYSFS_Stat statbuf;
+ int exists = 0;
+
+ sprintf(path, "%s%s%s", trimmedDir, *trimmedDir ? "/" : "", fname);
+ if (dh->funcs->stat(dh->opaque, path, &exists, &statbuf))
+ {
+ /* Pass it on to the application if it's not a symlink. */
+ if (statbuf.filetype != PHYSFS_FILETYPE_SYMLINK)
+ data->callback(data->callbackData, origdir, fname);
+ } /* if */
+
+ __PHYSFS_smallFree(path);
+ } /* if */
+} /* enumCallbackFilterSymLinks */
+
+
/* !!! FIXME: this should report error conditions. */
void PHYSFS_enumerateFilesCallback(const char *_fname,
PHYSFS_EnumFilesCallback callback,
@@ -2263,10 +2297,17 @@
if (sanitizePlatformIndependentPath(_fname, fname))
{
DirHandle *i;
- int noSyms;
+ SymlinkFilterData filterdata;
__PHYSFS_platformGrabMutex(stateLock);
- noSyms = !allowSymLinks;
+
+ if (!allowSymLinks)
+ {
+ memset(&filterdata, '\0', sizeof (filterdata));
+ filterdata.callback = callback;
+ filterdata.callbackData = data;
+ } /* if */
+
for (i = searchPath; i != NULL; i = i->next)
{
char *arcfname = fname;
@@ -2275,8 +2316,18 @@
else if (verifyPath(i, &arcfname, 0))
{
- i->funcs->enumerateFiles(i->opaque, arcfname, noSyms,
- callback, _fname, data);
+ if ((!allowSymLinks) && (i->funcs->supportsSymlinks))
+ {
+ filterdata.dirhandle = i;
+ i->funcs->enumerateFiles(i->opaque, arcfname,
+ enumCallbackFilterSymLinks,
+ _fname, &filterdata);
+ } /* if */
+ else
+ {
+ i->funcs->enumerateFiles(i->opaque, arcfname,
+ callback, _fname, data);
+ } /* else */
} /* else if */
} /* for */
__PHYSFS_platformReleaseMutex(stateLock);
--- a/src/physfs.h Thu Nov 29 11:45:01 2012 -0500
+++ b/src/physfs.h Thu Nov 29 11:47:16 2012 -0500
@@ -3408,14 +3408,11 @@
* List all files in (dirname). Each file is passed to (cb),
* where a copy is made if appropriate, so you should dispose of
* it properly upon return from the callback.
- * You should omit symlinks if (omitSymLinks) is non-zero.
* If you have a failure, report as much as you can.
* (dirname) is in platform-independent notation.
*/
-
-// !!! FIXME: get rid of this omitsymlinks nonsense.
void (*enumerateFiles)(void *opaque, const char *dirname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata);
/**
--- a/src/physfs_internal.h Thu Nov 29 11:45:01 2012 -0500
+++ b/src/physfs_internal.h Thu Nov 29 11:47:16 2012 -0500
@@ -301,7 +301,7 @@
void UNPK_closeArchive(void *opaque);
void *UNPK_openArchive(PHYSFS_Io *io,UNPKentry *e,const PHYSFS_uint32 n);
void UNPK_enumerateFiles(void *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata);
PHYSFS_Io *UNPK_openRead(void *opaque, const char *fnm, int *fileExists);
PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name);
@@ -555,7 +555,6 @@
* metaentries should always be ignored.
*/
void __PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks,
PHYSFS_EnumFilesCallback callback,
const char *origdir,
void *callbackdata);
--- a/src/platform_posix.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/platform_posix.c Thu Nov 29 11:47:16 2012 -0500
@@ -122,31 +122,13 @@
void __PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks,
PHYSFS_EnumFilesCallback callback,
const char *origdir,
void *callbackdata)
{
DIR *dir;
struct dirent *ent;
- int bufsize = 0;
char *buf = NULL;
- int dlen = 0;
-
- if (omitSymLinks) /* !!! FIXME: this malloc sucks. */
- {
- dlen = strlen(dirname);
- bufsize = dlen + 256;
- buf = (char *) allocator.Malloc(bufsize);
- if (buf == NULL)
- return;
- strcpy(buf, dirname);
- if (buf[dlen - 1] != '/')
- {
- buf[dlen++] = '/';
- buf[dlen] = '\0';
- } /* if */
- } /* if */
errno = 0;
dir = opendir(dirname);
@@ -160,35 +142,9 @@
{
if (strcmp(ent->d_name, ".") == 0)
continue;
-
- if (strcmp(ent->d_name, "..") == 0)
+ else if (strcmp(ent->d_name, "..") == 0)
continue;
- if (omitSymLinks)
- {
- PHYSFS_Stat statbuf;
- int exists = 0;
- char *p;
- int len = strlen(ent->d_name) + dlen + 1;
- if (len > bufsize)
- {
- p = (char *) allocator.Realloc(buf, len);
- if (p == NULL)
- continue;
- buf = p;
- bufsize = len;
- } /* if */
-
- strcpy(buf + dlen, ent->d_name);
-
- if (!__PHYSFS_platformStat(buf, &exists, &statbuf))
- continue;
- else if (!exists)
- continue; /* probably can't happen, but just in case. */
- else if (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK)
- continue;
- } /* if */
-
callback(callbackdata, origdir, ent->d_name);
} /* while */
--- a/src/platform_windows.c Thu Nov 29 11:45:01 2012 -0500
+++ b/src/platform_windows.c Thu Nov 29 11:47:16 2012 -0500
@@ -487,7 +487,6 @@
void __PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks,
PHYSFS_EnumFilesCallback callback,
const char *origdir,
void *callbackdata)
@@ -538,8 +537,6 @@
continue;
if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
continue;
- if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
- continue;
utf8 = unicodeToUtf8Heap(fn);
if (utf8 != NULL)