Added callback APIs and ripped up the internals everywhere to use them.

This commit is contained in:
Ryan C. Gordon 2004-09-29 06:09:29 +00:00
parent 80535e9b83
commit c2765f8571
21 changed files with 492 additions and 468 deletions

View File

@ -2,6 +2,13 @@
* CHANGELOG.
*/
09292004 - Every API that can return a list of strings can now use a
callback mechanism if the application wants to do it's own
allocation or handling on a per-item basis. The guts of those
APIs that create string lists now use the callbacks themselves to
build the lists, too. The callback functionality goes all the way
down to the archivers and platform drivers where appropriate, which
cleans things up and simplifies some internal tasks very nicely.
09262004 - Did the same thing to FileHandles than I did to DirHandles, but
this triggered massive tweaking in physfs.c. A lot of code got
little cleanups, which was nice. Less malloc pressure, too, since

2
TODO
View File

@ -22,7 +22,6 @@ Some might be dupes, some might be done already.
- Cygwin should use unix/posix and not win32 platform code.
- Add "mount points"
- Expose the archiver registration mechanism to the outside world.
- Set up a mechanism for file enumeration that employs a callback.
- Allow the application to provide allocation services.
- Find some way to relax or remove the security model for external tools.
- Non-blocking I/O
@ -41,7 +40,6 @@ Some might be dupes, some might be done already.
- Deprecate PHYSFS_setSaneConfig and move it to extras?
- (Re)move the profiling code in physfs.c.
- Why is physfsrwops.c cut-and-pasted into the ruby bindings?
- Get rid of addToLinkedStringList
- Replace code from SDL...
- MIX grabs all archives that no other archivers claim.
- MIX enumerates files as hash values.

View File

@ -29,9 +29,9 @@ static PHYSFS_sint64 DIR_fileLength(fvoid *opaque);
static int DIR_fileClose(fvoid *opaque);
static int DIR_isArchive(const char *filename, int forWriting);
static void *DIR_openArchive(const char *name, int forWriting);
static LinkedStringList *DIR_enumerateFiles(dvoid *opaque,
const char *dname,
int omitSymLinks);
static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata);
static int DIR_exists(dvoid *opaque, const char *name);
static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -165,17 +165,16 @@ static void *DIR_openArchive(const char *name, int forWriting)
} /* DIR_openArchive */
static LinkedStringList *DIR_enumerateFiles(dvoid *opaque,
const char *dname,
int omitSymLinks)
static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
{
char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL);
LinkedStringList *retval;
BAIL_IF_MACRO(d == NULL, NULL, NULL);
retval = __PHYSFS_platformEnumerateFiles(d, omitSymLinks);
if (d != NULL)
{
__PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb, callbackdata);
free(d);
return(retval);
} /* if */
} /* DIR_enumerateFiles */

View File

@ -72,9 +72,9 @@ static PHYSFS_sint64 GRP_fileLength(fvoid *opaque);
static int GRP_fileClose(fvoid *opaque);
static int GRP_isArchive(const char *filename, int forWriting);
static void *GRP_openArchive(const char *name, int forWriting);
static LinkedStringList *GRP_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks);
static void GRP_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata);
static int GRP_exists(dvoid *opaque, const char *name);
static int GRP_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int GRP_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -359,23 +359,21 @@ GRP_openArchive_failed:
} /* GRP_openArchive */
static LinkedStringList *GRP_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks)
static void GRP_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
{
/* no directories in GRP files. */
if (*dname != '\0')
{
GRPinfo *info = (GRPinfo *) opaque;
GRPentry *entry = info->entries;
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i;
/* no directories in GRP files. */
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
for (i = 0; i < max; i++, entry++)
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
return(retval);
cb(callbackdata, entry->name);
} /* if */
} /* GRP_enumerateFiles */

View File

@ -86,9 +86,9 @@ static PHYSFS_sint64 HOG_fileLength(fvoid *opaque);
static int HOG_fileClose(fvoid *opaque);
static int HOG_isArchive(const char *filename, int forWriting);
static void *HOG_openArchive(const char *name, int forWriting);
static LinkedStringList *HOG_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks);
static void HOG_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata);
static int HOG_exists(dvoid *opaque, const char *name);
static int HOG_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int HOG_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -398,23 +398,21 @@ HOG_openArchive_failed:
} /* HOG_openArchive */
static LinkedStringList *HOG_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks)
static void HOG_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
{
HOGinfo *info = ((HOGinfo *) opaque);
/* no directories in HOG files. */
if (*dname != '\0')
{
HOGinfo *info = (HOGinfo *) opaque;
HOGentry *entry = info->entries;
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i;
/* no directories in HOG files. */
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
for (i = 0; i < max; i++, entry++)
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
return(retval);
cb(callbackdata, entry->name);
} /* if */
} /* HOG_enumerateFiles */

View File

@ -91,9 +91,9 @@ static PHYSFS_sint64 MIX_fileLength(fvoid *opaque);
static int MIX_fileClose(fvoid *opaque);
static int MIX_isArchive(const char *filename, int forWriting);
static void *MIX_openArchive(const char *name, int forWriting);
static LinkedStringList *MIX_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks);
static void MIX_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
static int MIX_exists(dvoid *opaque, const char *name);
static int MIX_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int MIX_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -354,11 +354,13 @@ MIX_openArchive_failed:
} /* MIX_openArchive */
static LinkedStringList *MIX_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks)
static void MIX_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
{
LinkedStringList *retval = NULL, *p = NULL;
/* no directories in MIX files. */
if (*dirname != '\0')
{
MIXinfo *info = (MIXinfo*) opaque;
MIXentry *entry = info->entry;
int i;
@ -367,10 +369,9 @@ static LinkedStringList *MIX_enumerateFiles(dvoid *opaque,
for (i = 0; i < info->header.num_files; i++, entry++)
{
sprintf(buffer, "%X", entry->hash);
retval = __PHYSFS_addToLinkedStringList(retval, &p, buffer, -1);
cb(callbackdata, buffer);
} /* for */
return(retval);
} /* if */
} /* MIX_enumerateFiles */

View File

@ -75,9 +75,9 @@ static PHYSFS_sint64 MVL_fileLength(fvoid *opaque);
static int MVL_fileClose(fvoid *opaque);
static int MVL_isArchive(const char *filename, int forWriting);
static void *MVL_openArchive(const char *name, int forWriting);
static LinkedStringList *MVL_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks);
static void MVL_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata);
static int MVL_exists(dvoid *opaque, const char *name);
static int MVL_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int MVL_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -356,23 +356,21 @@ MVL_openArchive_failed:
} /* MVL_openArchive */
static LinkedStringList *MVL_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks)
static void MVL_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
{
/* no directories in MVL files. */
if (*dname != '\0')
{
MVLinfo *info = ((MVLinfo *) opaque);
MVLentry *entry = info->entries;
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i;
/* no directories in MVL files. */
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
for (i = 0; i < max; i++, entry++)
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
return(retval);
cb(callbackdata, entry->name);
} /* if */
} /* MVL_enumerateFiles */

View File

@ -89,9 +89,9 @@ static PHYSFS_sint64 QPAK_fileLength(fvoid *opaque);
static int QPAK_fileClose(fvoid *opaque);
static int QPAK_isArchive(const char *filename, int forWriting);
static void *QPAK_openArchive(const char *name, int forWriting);
static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks);
static void QPAK_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata);
static int QPAK_exists(dvoid *opaque, const char *name);
static int QPAK_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int QPAK_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -443,19 +443,36 @@ static PHYSFS_sint32 qpak_find_start_of_dir(QPAKinfo *info, const char *path,
} /* qpak_find_start_of_dir */
static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks)
/*
* Moved to seperate function so we can use alloca then immediately throw
* away the allocated stack space...
*/
static void doEnumCallback(PHYSFS_StringCallback cb, void *callbackdata,
const char *str, PHYSFS_sint32 ln)
{
char *newstr = alloca(ln + 1);
if (newstr == NULL)
return;
memcpy(newstr, str, ln);
newstr[ln] = '\0';
cb(callbackdata, newstr);
} /* doEnumCallback */
static void QPAK_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
{
QPAKinfo *info = ((QPAKinfo *) opaque);
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_sint32 dlen, dlen_inc, max, i;
i = qpak_find_start_of_dir(info, dirname, 0);
BAIL_IF_MACRO(i == -1, ERR_NO_SUCH_FILE, NULL);
i = qpak_find_start_of_dir(info, dname, 0);
if (i == -1) /* no such directory. */
return;
dlen = strlen(dirname);
if ((dlen > 0) && (dirname[dlen - 1] == '/')) /* ignore trailing slash. */
dlen = strlen(dname);
if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
dlen--;
dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
@ -466,13 +483,13 @@ static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque,
char *ptr;
PHYSFS_sint32 ln;
char *e = info->entries[i].name;
if ((dlen) && ((QPAK_strncmp(e, dirname, dlen)) || (e[dlen] != '/')))
if ((dlen) && ((QPAK_strncmp(e, dname, dlen)) || (e[dlen] != '/')))
break; /* past end of this dir; we're done. */
add = e + dlen_inc;
ptr = strchr(add, '/');
ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
retval = __PHYSFS_addToLinkedStringList(retval, &p, add, ln);
doEnumCallback(cb, callbackdata, add, ln);
ln += dlen_inc; /* point past entry to children... */
/* increment counter and skip children of subdirs... */
@ -483,8 +500,6 @@ static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque,
break;
} /* while */
} /* while */
return(retval);
} /* QPAK_enumerateFiles */

View File

@ -91,9 +91,9 @@ static PHYSFS_sint64 WAD_fileLength(fvoid *opaque);
static int WAD_fileClose(fvoid *opaque);
static int WAD_isArchive(const char *filename, int forWriting);
static void *WAD_openArchive(const char *name, int forWriting);
static LinkedStringList *WAD_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks);
static void WAD_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata);
static int WAD_exists(dvoid *opaque, const char *name);
static int WAD_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int WAD_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -386,45 +386,39 @@ WAD_openArchive_failed:
} /* WAD_openArchive */
static LinkedStringList *WAD_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks)
static void WAD_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
{
WADinfo *info = ((WADinfo *) opaque);
WADentry *entry = info->entries;
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i;
const char *name;
char *sep;
if (dirname[0] == 0)
if (*dname == '\0') /* root directory enumeration? */
{
for (i = 0; i < max; i++, entry++)
{
if (strchr(entry->name, '/') == NULL)
{
retval = __PHYSFS_addToLinkedStringList(retval, &p,
entry->name, -1);
} /* if */
name = entry->name;
if (strchr(name, '/') == NULL)
cb(callbackdata, name);
} /* for */
} /* if */
else
{
for (i = 0; i < max; i++, entry++)
{
sep = strchr(entry->name, '/');
name = entry->name;
sep = strchr(name, '/');
if (sep != NULL)
{
if (strncmp(dirname, entry->name, (sep-entry->name)) == 0)
{
retval = __PHYSFS_addToLinkedStringList(retval, &p,
sep + 1, -1);
} /* if */
if (strncmp(dname, name, (sep - name)) == 0)
cb(callbackdata, sep + 1);
} /* if */
} /* for */
} /* else */
return(retval);
} /* WAD_enumerateFiles */

View File

@ -127,9 +127,9 @@ static PHYSFS_sint64 ZIP_fileLength(fvoid *opaque);
static int ZIP_fileClose(fvoid *opaque);
static int ZIP_isArchive(const char *filename, int forWriting);
static void *ZIP_openArchive(const char *name, int forWriting);
static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks);
static void ZIP_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata);
static int ZIP_exists(dvoid *opaque, const char *name);
static int ZIP_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int ZIP_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -1235,19 +1235,36 @@ static PHYSFS_sint32 zip_find_start_of_dir(ZIPinfo *info, const char *path,
} /* zip_find_start_of_dir */
static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
const char *dirname,
int omitSymLinks)
/*
* Moved to seperate function so we can use alloca then immediately throw
* away the allocated stack space...
*/
static void doEnumCallback(PHYSFS_StringCallback cb, void *callbackdata,
const char *str, PHYSFS_sint32 ln)
{
char *newstr = alloca(ln + 1);
if (newstr == NULL)
return;
memcpy(newstr, str, ln);
newstr[ln] = '\0';
cb(callbackdata, newstr);
} /* doEnumCallback */
static void ZIP_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
{
ZIPinfo *info = ((ZIPinfo *) opaque);
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_sint32 dlen, dlen_inc, max, i;
i = zip_find_start_of_dir(info, dirname, 0);
BAIL_IF_MACRO(i == -1, ERR_NO_SUCH_FILE, NULL);
i = zip_find_start_of_dir(info, dname, 0);
if (i == -1) /* no such directory. */
return;
dlen = strlen(dirname);
if ((dlen > 0) && (dirname[dlen - 1] == '/')) /* ignore trailing slash. */
dlen = strlen(dname);
if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
dlen--;
dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
@ -1255,7 +1272,7 @@ static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
while (i < max)
{
char *e = info->entries[i].name;
if ((dlen) && ((strncmp(e, dirname, dlen) != 0) || (e[dlen] != '/')))
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])))
@ -1265,7 +1282,7 @@ static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
char *add = e + dlen_inc;
char *ptr = strchr(add, '/');
PHYSFS_sint32 ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
retval = __PHYSFS_addToLinkedStringList(retval, &p, add, ln);
doEnumCallback(cb, callbackdata, add, ln);
ln += dlen_inc; /* point past entry to children... */
/* increment counter and skip children of subdirs... */
@ -1277,8 +1294,6 @@ static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
} /* while */
} /* else */
} /* while */
return(retval);
} /* ZIP_enumerateFiles */

205
physfs.c
View File

@ -189,6 +189,54 @@ static PHYSFS_Allocator allocator;
/* functions ... */
typedef struct
{
char **list;
PHYSFS_uint32 size;
const char *errorstr;
} EnumStringListCallbackData;
static void enumStringListCallback(void *data, const char *str)
{
void *ptr;
char *newstr;
EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
if (pecd->errorstr)
return;
ptr = realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
newstr = malloc(strlen(str) + 1);
if (ptr != NULL)
pecd->list = (char **) ptr;
if ((ptr == NULL) || (newstr == NULL))
{
pecd->errorstr = ERR_OUT_OF_MEMORY;
pecd->list[pecd->size] = NULL;
PHYSFS_freeList(pecd->list);
return;
} /* if */
strcpy(newstr, str);
pecd->list[pecd->size] = newstr;
pecd->size++;
} /* enumStringListCallback */
static char **doEnumStringList(void (*func)(PHYSFS_StringCallback, void *))
{
EnumStringListCallbackData ecd;
memset(&ecd, '\0', sizeof (ecd));
ecd.list = (char **) malloc(sizeof (char *));
BAIL_IF_MACRO(ecd.list == NULL, ERR_OUT_OF_MEMORY, NULL);
func(enumStringListCallback, &ecd);
BAIL_IF_MACRO(ecd.errorstr != NULL, ecd.errorstr, NULL);
ecd.list[ecd.size] = NULL;
return(ecd.list);
} /* doEnumStringList */
static void __PHYSFS_bubble_sort(void *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi,
int (*cmpfn)(void *, PHYSFS_uint32, PHYSFS_uint32),
void (*swapfn)(void *, PHYSFS_uint32, PHYSFS_uint32))
@ -838,7 +886,6 @@ static int closeFileHandleList(FileHandle **list)
{
FileHandle *i;
FileHandle *next = NULL;
FileHandle *h;
for (i = *list; i != NULL; i = next)
{
@ -937,10 +984,16 @@ const char *PHYSFS_getDirSeparator(void)
char **PHYSFS_getCdRomDirs(void)
{
return(__PHYSFS_platformDetectAvailableCDs());
return(doEnumStringList(__PHYSFS_platformDetectAvailableCDs));
} /* PHYSFS_getCdRomDirs */
void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback callback, void *data)
{
__PHYSFS_platformDetectAvailableCDs(callback, data);
} /* PHYSFS_getCdRomDirsCallback */
const char *PHYSFS_getBaseDir(void)
{
return(baseDir); /* this is calculated in PHYSFS_init()... */
@ -1060,42 +1113,21 @@ int PHYSFS_removeFromSearchPath(const char *oldDir)
char **PHYSFS_getSearchPath(void)
{
int count = 1;
int x;
return(doEnumStringList(PHYSFS_getSearchPathCallback));
} /* PHYSFS_getSearchPath */
void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback callback, void *data)
{
DirHandle *i;
char **retval;
__PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next)
count++;
retval = (char **) malloc(sizeof (char *) * count);
BAIL_IF_MACRO_MUTEX(!retval, ERR_OUT_OF_MEMORY, stateLock, NULL);
count--;
retval[count] = NULL;
for (i = searchPath, x = 0; x < count; i = i->next, x++)
{
retval[x] = (char *) malloc(strlen(i->dirName) + 1);
if (retval[x] == NULL) /* this is friggin' ugly. */
{
while (x > 0)
{
x--;
free(retval[x]);
} /* while */
free(retval);
BAIL_MACRO_MUTEX(ERR_OUT_OF_MEMORY, stateLock, NULL);
} /* if */
strcpy(retval[x], i->dirName);
} /* for */
callback(data, i->dirName);
__PHYSFS_platformReleaseMutex(stateLock);
return(retval);
} /* PHYSFS_getSearchPath */
} /* PHYSFS_getSearchPathCallback */
int PHYSFS_setSaneConfig(const char *organization, const char *appName,
@ -1441,7 +1473,7 @@ const char *PHYSFS_getRealDir(const char *filename)
return(retval);
} /* PHYSFS_getRealDir */
#if 0
static int countList(LinkedStringList *list)
{
int retval = 0;
@ -1529,34 +1561,114 @@ static void interpolateStringLists(LinkedStringList **final,
newList = next;
} /* while */
} /* interpolateStringLists */
#endif
static int locateInStringList(const char *str,
char **list,
PHYSFS_uint32 *pos)
{
PHYSFS_uint32 hi = *pos - 1;
PHYSFS_uint32 lo = 0;
PHYSFS_uint32 i = hi / 2;
int cmp;
while (hi != lo)
{
cmp = strcmp(list[i], str);
if (cmp == 0) /* it's in the list already. */
return(1);
else if (cmp < 0)
hi = i;
else
lo = i;
i = lo + ((hi - lo) / 2);
} /* while */
/* hi == lo, check it in case it's the match... */
cmp = strcmp(list[lo], str);
if (cmp == 0)
return(1);
/* not in the list, set insertion point... */
*pos = (cmp < 0) ? lo : lo + 1;
return(0);
} /* locateInStringList */
static void enumFilesCallback(void *data, const char *str)
{
PHYSFS_uint32 pos;
void *ptr;
char *newstr;
EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
/*
* See if file is in the list already, and if not, insert it in there
* alphabetically...
*/
pos = pecd->size;
if (pos > 0)
{
if (locateInStringList(str, pecd->list, &pos))
return; /* already in the list. */
} /* if */
ptr = realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
newstr = malloc(strlen(str) + 1);
if (ptr != NULL)
pecd->list = (char **) ptr;
if ((ptr == NULL) || (newstr == NULL))
return; /* better luck next time. */
strcpy(newstr, str);
if (pos != pecd->size)
{
memmove(&pecd->list[pos+1], &pecd->list[pos],
sizeof (char *) * ((pecd->size) - pos));
} /* if */
pecd->list[pos] = newstr;
pecd->size++;
} /* enumFilesCallback */
char **PHYSFS_enumerateFiles(const char *path)
{
DirHandle *i;
char **retval = NULL;
LinkedStringList *rc;
LinkedStringList *finalList = NULL;
int omitSymLinks = !allowSymLinks;
EnumStringListCallbackData ecd;
memset(&ecd, '\0', sizeof (ecd));
ecd.list = (char **) malloc(sizeof (char *));
BAIL_IF_MACRO(ecd.list == NULL, ERR_OUT_OF_MEMORY, NULL);
PHYSFS_enumerateFilesCallback(path, enumFilesCallback, &ecd);
ecd.list[ecd.size] = NULL;
return(ecd.list);
} /* PHYSFS_enumerateFiles */
void PHYSFS_enumerateFilesCallback(const char *path,
PHYSFS_StringCallback callback,
void *data)
{
DirHandle *i;
int noSyms;
if ((path == NULL) || (callback == NULL))
return;
BAIL_IF_MACRO(path == NULL, ERR_INVALID_ARGUMENT, NULL);
while (*path == '/')
path++;
__PHYSFS_platformGrabMutex(stateLock);
noSyms = !allowSymLinks;
for (i = searchPath; i != NULL; i = i->next)
{
if (__PHYSFS_verifySecurity(i, path, 0))
{
rc = i->funcs->enumerateFiles(i->opaque, path, omitSymLinks);
interpolateStringLists(&finalList, rc);
} /* if */
i->funcs->enumerateFiles(i->opaque, path, noSyms, callback, data);
} /* for */
__PHYSFS_platformReleaseMutex(stateLock);
retval = convertStringListToPhysFSList(finalList);
return(retval);
} /* PHYSFS_enumerateFiles */
} /* PHYSFS_enumerateFilesCallback */
int PHYSFS_exists(const char *fname)
@ -2077,6 +2189,5 @@ PHYSFS_Allocator *__PHYSFS_getAllocator(void)
return(&allocator);
} /* __PHYFS_getAllocator */
/* end of physfs.c ... */

View File

@ -1874,6 +1874,22 @@ typedef struct
__EXPORT__ int PHYSFS_setAllocator(PHYSFS_Allocator *allocator);
/*
* it is not safe to call physfs functions in these callbacks, as they may
* be holding non recursive mutexes.
*/
/* !!! FIXME: comment! */
typedef void (*PHYSFS_StringCallback)(void *data, const char *);
__EXPORT__ void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback c, void *d);
__EXPORT__ void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback c, void *d);
__EXPORT__ void PHYSFS_enumerateFilesCallback(const char *dir,
PHYSFS_StringCallback c,
void *d);
/* Everything above this line is part of the PhysicsFS 2.0 API. */

View File

@ -979,17 +979,18 @@ typedef struct
void *(*openArchive)(const char *name, int forWriting);
/*
* Returns a list of all files in dirname. Each element of this list
* (and its "str" field) will be deallocated with the system's free()
* function by the caller, so be sure to explicitly malloc() each
* chunk. Omit symlinks if (omitSymLinks) is non-zero.
* If you have a memory failure, return as much as you can.
* This dirname is in platform-independent notation.
* List all files in (dirname). Each file is passed to (callback),
* 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.
*/
LinkedStringList *(*enumerateFiles)(dvoid *opaque,
void (*enumerateFiles)(dvoid *opaque,
const char *dirname,
int omitSymLinks);
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata);
/*
* Returns non-zero if filename can be opened for reading.
@ -1445,10 +1446,13 @@ int __PHYSFS_platformFlush(void *opaque);
int __PHYSFS_platformClose(void *opaque);
/*
* Platform implementation of PHYSFS_getCdRomDirs()...
* See physfs.h. The retval should be freeable via PHYSFS_freeList().
* Platform implementation of PHYSFS_getCdRomDirsCallback()...
* CD directories are discovered and reported to the callback one at a time.
* Pointers passed to the callback are assumed to be invalid to the
* application after the callback returns, so you can free them or whatever.
* Callback does not assume results will be sorted in any meaningful way.
*/
char **__PHYSFS_platformDetectAvailableCDs(void);
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data);
/*
* Calculate the base dir, if your platform needs special consideration.
@ -1559,8 +1563,10 @@ void __PHYSFS_platformTimeslice(void);
* uses platform-independent notation. Note that ".", "..", and other
* metaentries should always be ignored.
*/
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks);
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata);
/*

View File

@ -47,20 +47,6 @@ int __PHYSFS_platformDeinit(void)
} /* __PHYSFS_platformDeinit */
/* caller needs to malloc() mntpnt, and expect us to free() it. */
static void addDisc(char *mntpnt, char ***discs, int *disccount)
{
char **tmp = (char **) realloc(*discs, sizeof (char *) * (*disccount + 1));
if (tmp)
{
tmp[*disccount - 1] = mntpnt;
*discs = tmp;
(*disccount)++;
} /* if */
} /* addDisc */
static char *getMountPoint(const char *devname)
{
BVolumeRoster mounts;
@ -101,10 +87,10 @@ static char *getMountPoint(const char *devname)
* This function is lifted from Simple Directmedia Layer (SDL):
* http://www.libsdl.org/
*/
static void tryDir(const char *dirname, char ***discs, int *disccount)
static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
{
BDirectory dir;
dir.SetTo(dirname);
dir.SetTo(d);
if (dir.InitCheck() != B_NO_ERROR)
return;
@ -127,7 +113,7 @@ static void tryDir(const char *dirname, char ***discs, int *disccount)
if (entry.IsDirectory())
{
if (strcmp(e.name, "floppy") != 0)
tryDir(name, discs, disccount);
tryDir(name, callback, data);
} /* if */
else
@ -147,7 +133,10 @@ static void tryDir(const char *dirname, char ***discs, int *disccount)
{
char *mntpnt = getMountPoint(name);
if (mntpnt != NULL)
addDisc(mntpnt, discs, disccount);
{
callback(data, mntpnt);
free(mntpnt); /* !!! FIXME: lose this malloc! */
} /* if */
} /* if */
} /* if */
} /* if */
@ -159,14 +148,9 @@ static void tryDir(const char *dirname, char ***discs, int *disccount)
} /* tryDir */
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
tryDir("/dev/disk", &retval, &cd_count);
retval[cd_count - 1] = NULL;
return(retval);
tryDir("/dev/disk", cb, data);
} /* __PHYSFS_platformDetectAvailableCDs */

View File

@ -177,17 +177,12 @@ int __PHYSFS_platformDeinit(void)
* CD detection code is borrowed from Apple Technical Q&A DV18.
* http://developer.apple.com/qa/dv/dv18.html
*/
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
DriverGestaltParam pb;
DrvQEl *dqp;
OSErr status;
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1;
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
*retval = NULL;
pb.csCode = kDriverGestaltCode;
pb.driverGestaltSelector = kdgDeviceType;
@ -201,6 +196,7 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
if ((status == noErr) && (pb.driverGestaltResponse == kdgCDType))
{
Str63 volName;
size_t size;
HParamBlockRec hpbr;
memset(&hpbr, '\0', sizeof (HParamBlockRec));
hpbr.volumeParam.ioNamePtr = volName;
@ -208,27 +204,15 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
hpbr.volumeParam.ioVolIndex = 0;
if (PBHGetVInfoSync(&hpbr) == noErr)
{
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
if (tmp)
{
char *str = (char *) malloc(volName[0] + 1);
retval = tmp;
if (str != NULL)
{
memcpy(str, &volName[1], volName[0]);
str[volName[0]] = '\0';
retval[cd_count-1] = str;
cd_count++;
} /* if */
} /* if */
size = (size_t) volName[0]; /* convert to ASCIZ string... */
memmove(&volName[0], &volName[1], size);
volName[size] = '\0';
cb(data, volName);
} /* if */
} /* if */
dqp = (DrvQEl *) dqp->qLink;
} /* while */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
@ -577,10 +561,12 @@ void __PHYSFS_platformTimeslice(void)
} /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks)
/* returns int so we can use BAIL*MACRO... */
static int macClassicEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{
LinkedStringList *ret = NULL, *p = NULL;
UInt16 i;
UInt16 max;
FSSpec spec;
@ -606,6 +592,7 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
for (i = 1; i <= max; i++)
{
size_t size;
FSSpec aliasspec;
Boolean alias = 0;
Boolean folder = 0;
@ -629,10 +616,20 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
continue;
/* still here? Add it to the list. */
ret = __PHYSFS_addToLinkedStringList(ret, &p, (const char *) &str255[1], str255[0]);
size = (size_t) str255[0]; /* (convert to ASCIZ string...) */
memmove(&str255[0], &str255[1], size);
str255[size] = '\0';
callback(callbackdata, str255);
} /* for */
} /* macClassicEnumerateFiles */
return(ret);
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{
macClassicEnumerateFiles(dirname, omitSymLinks, callback, callbackdata);
} /* __PHYSFS_platformEnumerateFiles */

View File

@ -254,20 +254,12 @@ static int is_cdrom_drive(ULONG drive)
} /* is_cdrom_drive */
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
ULONG dummy;
ULONG drivemap;
ULONG dummy = 0;
ULONG drivemap = 0;
ULONG i, bit;
APIRET rc;
char **retval;
PHYSFS_uint32 cd_count = 1; /* we count the NULL entry. */
retval = (char **) malloc(sizeof (char *));
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
*retval = NULL;
rc = DosQueryCurrentDisk(&dummy, &drivemap);
APIRET rc = DosQueryCurrentDisk(&dummy, &drivemap);
BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, retval);
for (i = 0, bit = 1; i < 26; i++, bit <<= 1)
@ -276,27 +268,12 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
{
if ((is_cdrom_drive(i)) && (disc_is_inserted(i)))
{
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
if (tmp)
{
char *str = (char *) malloc(4);
retval = tmp;
retval[cd_count - 1] = str;
if (str)
{
str[0] = ('A' + i);
str[1] = ':';
str[2] = '\\';
str[3] = '\0';
cd_count++;
} /* if */
} /* if */
char drive[4] = "x:\\";
drive[0] = ('A' + i);
cb(data, drive);
} /* if */
} /* if */
} /* for */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
@ -417,11 +394,12 @@ char *__PHYSFS_platformCvtToDependent(const char *prepend,
} /* __PHYSFS_platformCvtToDependent */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks)
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{
char spec[CCHMAXPATH];
LinkedStringList *ret = NULL, *p = NULL;
FILEFINDBUF3 fb;
HDIR hdir = HDIR_CREATE;
ULONG count = 1;
@ -439,13 +417,12 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
while (count == 1)
{
if ((strcmp(fb.achName, ".") != 0) && (strcmp(fb.achName, "..") != 0))
ret = __PHYSFS_addToLinkedStringList(ret, &p, fb.achName, -1);
callback(callbackdata, fb.achName);
DosFindNext(hdir, &fb, sizeof (fb), &count);
} /* while */
DosFindClose(hdir);
return(ret);
} /* __PHYSFS_platformEnumerateFiles */

View File

@ -67,52 +67,53 @@ static const char *win32strerror(void)
static char *UnicodeToAsc(const wchar_t *w_str)
{
char *str=NULL;
char *str = NULL;
if(w_str!=NULL)
if (w_str != NULL)
{
int len=wcslen(w_str)+1;
str=(char *)malloc(len);
int len = wcslen(w_str) + 1;
str = (char *) malloc(len);
if(WideCharToMultiByte(CP_ACP,0,w_str,-1,str,len,NULL,NULL)==0)
{ //Conversion failed
if (WideCharToMultiByte(CP_ACP,0,w_str,-1,str,len,NULL,NULL) == 0)
{ /*Conversion failed */
free(str);
return NULL;
}
return(NULL);
} /* if */
else
{ //Conversion successful
{ /* Conversion successful */
return(str);
}
} /* else */
} /* if */
}
else
{ //Given NULL string
{ /* Given NULL string */
return NULL;
}
}
} /* UnicodeToAsc */
static wchar_t *AscToUnicode(const char *str)
{
wchar_t *w_str=NULL;
if(str!=NULL)
wchar_t *w_str = NULL;
if (str != NULL)
{
int len=strlen(str)+1;
w_str=(wchar_t *)malloc(sizeof(wchar_t)*len);
if(MultiByteToWideChar(CP_ACP,0,str,-1,w_str,len)==0)
int len = strlen(str) + 1;
w_str = (wchar_t *) malloc(sizeof (wchar_t) * len);
if (MultiByteToWideChar(CP_ACP,0,str,-1,w_str,len) == 0)
{
free(w_str);
return NULL;
}
return(NULL);
} /* if */
else
{
return(w_str);
}
}
} /* else */
} /* if */
else
{
return NULL;
}
}
return(NULL);
} /* else */
} /* AscToUnicode */
static char *getExePath()
@ -177,9 +178,9 @@ int __PHYSFS_platformDeinit(void)
} /* __PHYSFS_platformDeinit */
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
/* no-op on this platform. */
} /* __PHYSFS_platformDetectAvailableCDs */
@ -293,12 +294,11 @@ void __PHYSFS_platformTimeslice(void)
} /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks)
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{
LinkedStringList *retval = NULL;
LinkedStringList *l = NULL;
LinkedStringList *prev = NULL;
HANDLE dir;
WIN32_FIND_DATA ent;
char *SearchPath;
@ -328,43 +328,29 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
free(w_SearchPath);
free(SearchPath);
if(dir == INVALID_HANDLE_VALUE)
{
return NULL;
}
if (dir == INVALID_HANDLE_VALUE)
return;
do
{
const char *str;
if (wcscmp(ent.cFileName, L".") == 0)
continue;
if (wcscmp(ent.cFileName, L"..") == 0)
continue;
l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
if (l == NULL)
/* !!! FIXME: avoid malloc in UnicodeToAsc? */
str = UnicodeToAsc(ent.cFileName);
if (str == NULL)
break;
l->str=UnicodeToAsc(ent.cFileName);
if (l->str == NULL)
{
free(l);
break;
}
if (retval == NULL)
retval = l;
else
prev->next = l;
prev = l;
l->next = NULL;
callback(callbackdata, str);
free(str);
} while (FindNextFile(dir, &ent) != 0);
FindClose(dir);
return(retval);
} /* __PHYSFS_platformEnumerateFiles */
@ -381,7 +367,6 @@ char *__PHYSFS_platformRealPath(const char *path)
strcpy(retval,path);
return(retval);
} /* __PHYSFS_platformRealPath */

View File

@ -225,22 +225,24 @@ char *__PHYSFS_platformCvtToDependent(const char *prepend,
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks)
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{
LinkedStringList *retval = NULL, *p = NULL;
DIR *dir;
struct dirent *ent;
int bufsize = 0;
char *buf = NULL;
int dlen = 0;
if (omitSymLinks)
if (omitSymLinks) /* !!! FIXME: this malloc sucks. */
{
dlen = strlen(dirname);
bufsize = dlen + 256;
buf = (char *) malloc(bufsize);
BAIL_IF_MACRO(buf == NULL, ERR_OUT_OF_MEMORY, NULL);
if (buf == NULL)
return;
strcpy(buf, dirname);
if (buf[dlen - 1] != '/')
{
@ -255,7 +257,7 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
{
if (buf != NULL)
free(buf);
BAIL_IF_MACRO(1, strerror(errno), NULL);
return;
} /* if */
while ((ent = readdir(dir)) != NULL)
@ -284,14 +286,13 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
continue;
} /* if */
retval = __PHYSFS_addToLinkedStringList(retval, &p, ent->d_name, -1);
callback(callbackdata, ent->d_name);
} /* while */
if (buf != NULL)
free(buf);
closedir(dir);
return(retval);
} /* __PHYSFS_platformEnumerateFiles */

View File

@ -32,9 +32,8 @@ int __PHYSFS_platformDeinit(void)
} /* __PHYSFS_platformDeinit */
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformDetectAvailableCDs */
@ -105,10 +104,11 @@ void __PHYSFS_platformTimeslice(void)
} /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks)
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformEnumerateFiles */

View File

@ -76,12 +76,8 @@ int __PHYSFS_platformDeinit(void)
#ifdef PHYSFS_NO_CDROM_SUPPORT
/* Stub version for platforms without CD-ROM support. */
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
char **retval = (char **) malloc(sizeof (char *));
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
*retval = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
@ -166,13 +162,11 @@ static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
} /* darwinIsMountedDisc */
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
const char *devPrefix = "/dev/";
int prefixLen = strlen(devPrefix);
mach_port_t masterPort = 0;
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
struct statfs *mntbufp;
int i, mounts;
@ -191,38 +185,17 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
dev += prefixLen;
if (darwinIsMountedDisc(dev, masterPort))
{
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
if (tmp)
{
retval = tmp;
retval[cd_count - 1] = (char *) malloc(strlen(mnt) + 1);
if (retval[cd_count - 1])
{
strcpy(retval[cd_count - 1], mnt);
cd_count++;
} /* if */
} /* if */
} /* if */
cb(data, mnt);
} /* for */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#elif (defined PHYSFS_HAVE_SYS_UCRED_H)
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
struct statfs *mntbufp = NULL;
int mounts;
int i;
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
mounts = getmntinfo(&mntbufp, MNT_WAIT);
struct statfs *mntbufp = NULL;
int mounts = getmntinfo(&mntbufp, MNT_WAIT);
for (i = 0; i < mounts; i++)
{
@ -236,40 +209,23 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
/* add other mount types here */
if (add_it)
{
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
if (tmp)
{
retval = tmp;
retval[cd_count - 1] = (char *)
malloc(strlen(mntbufp[i].f_mntonname) + 1);
if (retval[cd_count - 1])
{
strcpy(retval[cd_count - 1], mntbufp[i].f_mntonname);
cd_count++;
} /* if */
} /* if */
} /* if */
cb(data, mntbufp[i].f_mntonname);
} /* for */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#elif (defined PHYSFS_HAVE_MNTENT_H)
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
FILE *mounts = NULL;
struct mntent *ent = NULL;
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
*retval = NULL;
mounts = setmntent("/etc/mtab", "r");
BAIL_IF_MACRO(mounts == NULL, ERR_IO_ERROR, retval);
if (mounts == NULL)
{
__PHYSFS_setError(ERR_IO_ERROR);
return;
} /* if */
while ( (ent = getmntent(mounts)) != NULL )
{
@ -280,25 +236,11 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
/* add other mount types here */
if (add_it)
{
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
if (tmp)
{
retval = tmp;
retval[cd_count-1] = (char *) malloc(strlen(ent->mnt_dir) + 1);
if (retval[cd_count - 1])
{
strcpy(retval[cd_count - 1], ent->mnt_dir);
cd_count++;
} /* if */
} /* if */
} /* if */
cb(data, ent->mnt_dir);
} /* while */
endmntent(mounts);
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#endif

View File

@ -268,33 +268,17 @@ static BOOL mediaInDrive(const char *drive)
} /* mediaInDrive */
char **__PHYSFS_platformDetectAvailableCDs(void)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
char drive_str[4] = "x:\\";
for (drive_str[0] = 'A'; drive_str[0] <= 'Z'; drive_str[0]++)
char ch;
for (ch = 'A'; ch <= 'Z'; ch++)
{
drive_str[0] = ch;
if (GetDriveType(drive_str) == DRIVE_CDROM && mediaInDrive(drive_str))
{
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
if (tmp)
{
retval = tmp;
retval[cd_count - 1] = (char *) malloc(4);
if (retval[cd_count - 1])
{
strcpy(retval[cd_count - 1], drive_str);
cd_count++;
} /* if */
} /* if */
} /* if */
cb(data, drive_str);
} /* for */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_detectAvailableCDs */
} /* __PHYSFS_platformDetectAvailableCDs */
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
@ -454,18 +438,20 @@ void __PHYSFS_platformTimeslice(void)
} /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks)
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{
LinkedStringList *retval = NULL, *p = NULL;
HANDLE dir;
WIN32_FIND_DATA ent;
char *SearchPath;
size_t len = strlen(dirname);
char *SearchPath;
/* Allocate a new string for path, maybe '\\', "*", and NULL terminator */
SearchPath = (char *) alloca(len + 3);
BAIL_IF_MACRO(SearchPath == NULL, ERR_OUT_OF_MEMORY, NULL);
if (SearchPath == NULL)
return;
/* Copy current dirname */
strcpy(SearchPath, dirname);
@ -481,11 +467,8 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
strcat(SearchPath, "*");
dir = FindFirstFile(SearchPath, &ent);
BAIL_IF_MACRO
(
dir == INVALID_HANDLE_VALUE,
win32strerror(), NULL
);
if (dir == INVALID_HANDLE_VALUE)
return;
do
{
@ -495,11 +478,10 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
if (strcmp(ent.cFileName, "..") == 0)
continue;
retval = __PHYSFS_addToLinkedStringList(retval, &p, ent.cFileName, -1);
callback(callbackdata, ent.cFileName);
} while (FindNextFile(dir, &ent) != 0);
FindClose(dir);
return(retval);
} /* __PHYSFS_platformEnumerateFiles */