Lots of bugfixes, enhancements, and corrections due to the work on
test_physfs exposing problems.
This commit is contained in:
parent
16584701b5
commit
7d90c12f74
|
@ -222,7 +222,7 @@ static LinkedStringList *GRP_enumerateFiles(DirHandle *h, const char *dirname)
|
|||
buf[12] = '\0'; /* FILENAME.EXT is all you get. */
|
||||
|
||||
l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
|
||||
if (l != NULL)
|
||||
if (l == NULL)
|
||||
break;
|
||||
|
||||
l->str = (char *) malloc(strlen(buf) + 1);
|
||||
|
@ -232,6 +232,8 @@ static LinkedStringList *GRP_enumerateFiles(DirHandle *h, const char *dirname)
|
|||
break;
|
||||
} /* if */
|
||||
|
||||
strcpy(l->str, buf);
|
||||
|
||||
if (retval == NULL)
|
||||
retval = l;
|
||||
else
|
||||
|
|
|
@ -162,7 +162,7 @@ static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, const char *dirname)
|
|||
} /* else */
|
||||
|
||||
l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
|
||||
if (l != NULL)
|
||||
if (l == NULL)
|
||||
break;
|
||||
|
||||
l->str = (char *) malloc(strlen(ptr) + 1);
|
||||
|
@ -172,6 +172,8 @@ static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, const char *dirname)
|
|||
break;
|
||||
} /* if */
|
||||
|
||||
strcpy(l->str, ptr);
|
||||
|
||||
if (retval == NULL)
|
||||
retval = l;
|
||||
else
|
||||
|
|
120
physfs.c
120
physfs.c
|
@ -11,7 +11,11 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include "physfs.h"
|
||||
|
||||
|
@ -303,7 +307,6 @@ static char *calculateBaseDir(const char *argv0)
|
|||
const char *dirsep = PHYSFS_getDirSeparator();
|
||||
char *retval;
|
||||
char *ptr;
|
||||
int allocSize = 0;
|
||||
|
||||
/*
|
||||
* See if the platform driver wants to handle this for us...
|
||||
|
@ -337,35 +340,34 @@ static char *calculateBaseDir(const char *argv0)
|
|||
/*
|
||||
* Last ditch effort: it's the current working directory. (*shrug*)
|
||||
*/
|
||||
do
|
||||
{
|
||||
allocSize += 100;
|
||||
ptr = (char *) realloc(retval, allocSize);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
if (retval != NULL)
|
||||
free(retval);
|
||||
BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
|
||||
} /* if */
|
||||
|
||||
retval = ptr;
|
||||
ptr = getcwd(retval, allocSize);
|
||||
} while (ptr == NULL);
|
||||
|
||||
return(retval);
|
||||
return(__PHYSFS_platformCurrentDir());
|
||||
} /* calculateBaseDir */
|
||||
|
||||
|
||||
int PHYSFS_init(const char *argv0)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
|
||||
BAIL_IF_MACRO(argv0 == NULL, ERR_INVALID_ARGUMENT, 0);
|
||||
|
||||
baseDir = calculateBaseDir(argv0);
|
||||
BAIL_IF_MACRO(baseDir == NULL, NULL, 0);
|
||||
ptr = __PHYSFS_platformRealPath(baseDir);
|
||||
free(baseDir);
|
||||
BAIL_IF_MACRO(ptr == NULL, NULL, 0);
|
||||
baseDir = ptr;
|
||||
|
||||
BAIL_IF_MACRO(!appendDirSep(&baseDir), NULL, 0);
|
||||
|
||||
userDir = calculateUserDir();
|
||||
if (userDir != NULL)
|
||||
{
|
||||
ptr = __PHYSFS_platformRealPath(userDir);
|
||||
free(userDir);
|
||||
userDir = ptr;
|
||||
} /* if */
|
||||
|
||||
if ((userDir == NULL) || (!appendDirSep(&userDir)))
|
||||
{
|
||||
free(baseDir);
|
||||
|
@ -624,15 +626,30 @@ int PHYSFS_setSaneConfig(const char *appName, const char *archiveExt,
|
|||
const char *userdir = PHYSFS_getUserDir();
|
||||
const char *dirsep = PHYSFS_getDirSeparator();
|
||||
char *str;
|
||||
int rc;
|
||||
|
||||
/* set write dir... */
|
||||
str = malloc(strlen(userdir) + (strlen(appName) * 2) +
|
||||
(strlen(dirsep) * 2) + 2);
|
||||
BAIL_IF_MACRO(str == NULL, ERR_OUT_OF_MEMORY, 0);
|
||||
sprintf(str, "%s%s.%s", userdir, dirsep, appName);
|
||||
rc = PHYSFS_setWriteDir(str);
|
||||
BAIL_IF_MACRO(!rc, NULL, 0);
|
||||
sprintf(str, "%s.%s", userdir, appName);
|
||||
|
||||
if (!PHYSFS_setWriteDir(str))
|
||||
{
|
||||
if ( (!PHYSFS_setWriteDir(userdir)) ||
|
||||
(!PHYSFS_mkdir(str + strlen(userdir))) )
|
||||
{
|
||||
PHYSFS_setWriteDir(NULL);
|
||||
free(str);
|
||||
BAIL_IF_MACRO(1, ERR_CANT_SET_WRITE_DIR, 0);
|
||||
} /* if */
|
||||
} /* if */
|
||||
|
||||
if (!PHYSFS_setWriteDir(str))
|
||||
{
|
||||
PHYSFS_setWriteDir(NULL);
|
||||
free(str);
|
||||
BAIL_IF_MACRO(1, ERR_CANT_SET_WRITE_DIR, 0);
|
||||
} /* if */
|
||||
|
||||
/* Put write dir related dirs on search path... */
|
||||
PHYSFS_addToSearchPath(str, 1);
|
||||
|
@ -648,7 +665,7 @@ int PHYSFS_setSaneConfig(const char *appName, const char *archiveExt,
|
|||
(strlen(dirsep) * 2) + 2);
|
||||
if (str != NULL)
|
||||
{
|
||||
sprintf(str, "%s%s.%s", basedir, dirsep, appName);
|
||||
sprintf(str, "%s.%s", basedir, appName);
|
||||
PHYSFS_addToSearchPath(str, 1);
|
||||
free(str);
|
||||
} /* if */
|
||||
|
@ -725,6 +742,9 @@ char *__PHYSFS_convertToDependent(const char *prepend,
|
|||
char *i2;
|
||||
size_t allocSize;
|
||||
|
||||
while (*dirName == '/')
|
||||
dirName++;
|
||||
|
||||
allocSize = strlen(dirName) + 1;
|
||||
if (prepend != NULL)
|
||||
allocSize += strlen(prepend) + sepsize;
|
||||
|
@ -836,7 +856,12 @@ int PHYSFS_mkdir(const char *dirName)
|
|||
int retval = 0;
|
||||
|
||||
BAIL_IF_MACRO(writeDir == NULL, ERR_NO_WRITE_DIR, 0);
|
||||
|
||||
h = writeDir->dirHandle;
|
||||
|
||||
while (*dirName == '/')
|
||||
dirName++;
|
||||
|
||||
BAIL_IF_MACRO(h->funcs->mkdir == NULL, ERR_NOT_SUPPORTED, 0);
|
||||
BAIL_IF_MACRO(!__PHYSFS_verifySecurity(h, dirName), NULL, 0);
|
||||
|
||||
|
@ -872,6 +897,10 @@ int PHYSFS_delete(const char *fname)
|
|||
BAIL_IF_MACRO(writeDir == NULL, ERR_NO_WRITE_DIR, 0);
|
||||
h = writeDir->dirHandle;
|
||||
BAIL_IF_MACRO(h->funcs->remove == NULL, ERR_NOT_SUPPORTED, 0);
|
||||
|
||||
while (*fname == '/')
|
||||
fname++;
|
||||
|
||||
BAIL_IF_MACRO(!__PHYSFS_verifySecurity(h, fname), NULL, 0);
|
||||
return(h->funcs->remove(h, fname));
|
||||
} /* PHYSFS_delete */
|
||||
|
@ -881,6 +910,9 @@ const char *PHYSFS_getRealDir(const char *filename)
|
|||
{
|
||||
DirInfo *i;
|
||||
|
||||
while (*filename == '/')
|
||||
filename++;
|
||||
|
||||
for (i = searchPath; i != NULL; i = i->next)
|
||||
{
|
||||
DirHandle *h = i->dirHandle;
|
||||
|
@ -900,8 +932,6 @@ static int countList(LinkedStringList *list)
|
|||
int retval = 0;
|
||||
LinkedStringList *i;
|
||||
|
||||
assert(list != NULL);
|
||||
|
||||
for (i = list; i != NULL; i = i->next)
|
||||
retval++;
|
||||
|
||||
|
@ -947,23 +977,27 @@ static void insertStringListItem(LinkedStringList **final,
|
|||
for (i = *final; i != NULL; i = i->next)
|
||||
{
|
||||
rc = strcmp(i->str, item->str);
|
||||
if (rc == 0) /* already in list. */
|
||||
if (rc > 0) /* insertion point. */
|
||||
break;
|
||||
else if (rc == 0) /* already in list. */
|
||||
{
|
||||
free(item->str);
|
||||
free(item);
|
||||
return;
|
||||
} /* if */
|
||||
else if (rc > 0) /* insertion point. */
|
||||
{
|
||||
if (prev == NULL)
|
||||
*final = item;
|
||||
else
|
||||
prev->next = item;
|
||||
item->next = i;
|
||||
return;
|
||||
} /* else if */
|
||||
prev = i;
|
||||
} /* for */
|
||||
|
||||
/*
|
||||
* If we are here, we are either at the insertion point.
|
||||
* This may be the end of the list, or the list may be empty, too.
|
||||
*/
|
||||
if (prev == NULL)
|
||||
*final = item;
|
||||
else
|
||||
prev->next = item;
|
||||
|
||||
item->next = i;
|
||||
} /* insertStringListItem */
|
||||
|
||||
|
||||
|
@ -989,6 +1023,9 @@ char **PHYSFS_enumerateFiles(const char *path)
|
|||
LinkedStringList *rc;
|
||||
LinkedStringList *finalList = NULL;
|
||||
|
||||
while (*path == '/')
|
||||
path++;
|
||||
|
||||
for (i = searchPath; i != NULL; i = i->next)
|
||||
{
|
||||
DirHandle *h = i->dirHandle;
|
||||
|
@ -1006,6 +1043,9 @@ char **PHYSFS_enumerateFiles(const char *path)
|
|||
|
||||
int PHYSFS_exists(const char *fname)
|
||||
{
|
||||
while (*fname == '/')
|
||||
fname++;
|
||||
|
||||
return(PHYSFS_getRealDir(fname) != NULL);
|
||||
} /* PHYSFS_exists */
|
||||
|
||||
|
@ -1014,6 +1054,9 @@ int PHYSFS_isDirectory(const char *fname)
|
|||
{
|
||||
DirInfo *i;
|
||||
|
||||
while (*fname == '/')
|
||||
fname++;
|
||||
|
||||
for (i = searchPath; i != NULL; i = i->next)
|
||||
{
|
||||
DirHandle *h = i->dirHandle;
|
||||
|
@ -1035,6 +1078,9 @@ int PHYSFS_isSymbolicLink(const char *fname)
|
|||
if (!allowSymLinks)
|
||||
return(0);
|
||||
|
||||
while (*fname == '/')
|
||||
fname++;
|
||||
|
||||
for (i = searchPath; i != NULL; i = i->next)
|
||||
{
|
||||
DirHandle *h = i->dirHandle;
|
||||
|
@ -1057,6 +1103,9 @@ static PHYSFS_file *doOpenWrite(const char *fname, int appending)
|
|||
const DirFunctions *f = (h == NULL) ? NULL : h->funcs;
|
||||
FileHandleList *list;
|
||||
|
||||
while (*fname == '/')
|
||||
fname++;
|
||||
|
||||
BAIL_IF_MACRO(!h, ERR_NO_WRITE_DIR, NULL);
|
||||
BAIL_IF_MACRO(!__PHYSFS_verifySecurity(h, fname), NULL, NULL);
|
||||
|
||||
|
@ -1097,6 +1146,9 @@ PHYSFS_file *PHYSFS_openRead(const char *fname)
|
|||
FileHandleList *list;
|
||||
DirInfo *i;
|
||||
|
||||
while (*fname == '/')
|
||||
fname++;
|
||||
|
||||
list = (FileHandleList *) malloc(sizeof (FileHandleList));
|
||||
BAIL_IF_MACRO(!list, ERR_OUT_OF_MEMORY, NULL);
|
||||
|
||||
|
|
4
physfs.h
4
physfs.h
|
@ -313,6 +313,10 @@ const char *PHYSFS_getDirSeparator(void);
|
|||
* unless you feel there's a specific danger in allowing them, you should
|
||||
* permit them.
|
||||
*
|
||||
* Symlinks are only explicitly checked when dealing with filenames
|
||||
* in platform-independent notation. That is, when setting up your
|
||||
* search and write paths, etc, symlinks are never checked for.
|
||||
*
|
||||
* Symbolic link permission can be enabled or disabled at any time, and is
|
||||
* disabled by default.
|
||||
*
|
||||
|
|
|
@ -249,6 +249,8 @@ typedef struct __PHYSFS_DIRFUNCTIONS__
|
|||
#define ERR_PAST_EOF "Past end of file"
|
||||
#define ERR_ARC_IS_READ_ONLY "Archive is read-only"
|
||||
#define ERR_IO_ERROR "I/O error"
|
||||
#define ERR_CANT_SET_WRITE_DIR "Can't set write directory."
|
||||
|
||||
|
||||
/*
|
||||
* Call this to set the message returned by PHYSFS_getLastError().
|
||||
|
@ -417,6 +419,29 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname);
|
|||
int __PHYSFS_platformFileLength(FILE *handle);
|
||||
|
||||
|
||||
/*
|
||||
* Get the current working directory. The return value should be an
|
||||
* absolute path in platform-dependent notation. The caller will deallocate
|
||||
* the return value with the standard C runtime free() function when it
|
||||
* is done with it.
|
||||
* On error, return NULL and set the error message.
|
||||
*/
|
||||
char *__PHYSFS_platformCurrentDir(void);
|
||||
|
||||
|
||||
/*
|
||||
* Get the real physical path to a file. (path) is specified in
|
||||
* platform-dependent notation, as should your return value be.
|
||||
* All relative paths should be removed, leaving you with an absolute
|
||||
* path. Symlinks should be resolved, too, so that the returned value is
|
||||
* the most direct path to a file.
|
||||
* The return value will be deallocated with the standard C runtime free()
|
||||
* function when the caller is done with it.
|
||||
* On error, return NULL and set the error message.
|
||||
*/
|
||||
char *__PHYSFS_platformRealPath(const char *path);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
@ -303,8 +304,14 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname)
|
|||
if (ent == NULL) /* we're done. */
|
||||
break;
|
||||
|
||||
if (strcmp(ent->d_name, ".") == 0)
|
||||
continue;
|
||||
|
||||
if (strcmp(ent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
|
||||
if (l != NULL)
|
||||
if (l == NULL)
|
||||
break;
|
||||
|
||||
l->str = (char *) malloc(strlen(ent->d_name) + 1);
|
||||
|
@ -314,6 +321,8 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname)
|
|||
break;
|
||||
} /* if */
|
||||
|
||||
strcpy(l->str, ent->d_name);
|
||||
|
||||
if (retval == NULL)
|
||||
retval = l;
|
||||
else
|
||||
|
@ -337,5 +346,43 @@ int __PHYSFS_platformFileLength(FILE *handle)
|
|||
} /* __PHYSFS_platformFileLength */
|
||||
|
||||
|
||||
char *__PHYSFS_platformCurrentDir(void)
|
||||
{
|
||||
int allocSize = 0;
|
||||
char *retval = NULL;
|
||||
char *ptr;
|
||||
|
||||
do
|
||||
{
|
||||
allocSize += 100;
|
||||
ptr = (char *) realloc(retval, allocSize);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
if (retval != NULL)
|
||||
free(retval);
|
||||
BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
|
||||
} /* if */
|
||||
|
||||
retval = ptr;
|
||||
ptr = getcwd(retval, allocSize);
|
||||
} while (ptr == NULL);
|
||||
|
||||
return(retval);
|
||||
} /* __PHYSFS_platformCurrentDir */
|
||||
|
||||
|
||||
char *__PHYSFS_platformRealPath(const char *path)
|
||||
{
|
||||
char resolved_path[MAXPATHLEN];
|
||||
char *retval = NULL;
|
||||
|
||||
errno = 0;
|
||||
BAIL_IF_MACRO(!realpath(path, resolved_path), strerror(errno), NULL);
|
||||
retval = malloc(strlen(resolved_path) + 1);
|
||||
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||
strcpy(retval, resolved_path);
|
||||
return(retval);
|
||||
} /* __PHYSFS_platformRealPath */
|
||||
|
||||
/* end of unix.c ... */
|
||||
|
||||
|
|
Loading…
Reference in New Issue