Lots of bugfixes, enhancements, and corrections due to the work on
test_physfs exposing problems.
--- a/archivers/grp.c Mon Jul 16 10:32:12 2001 +0000
+++ b/archivers/grp.c Mon Jul 16 14:36:02 2001 +0000
@@ -222,7 +222,7 @@
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 @@
break;
} /* if */
+ strcpy(l->str, buf);
+
if (retval == NULL)
retval = l;
else
--- a/archivers/zip.c Mon Jul 16 10:32:12 2001 +0000
+++ b/archivers/zip.c Mon Jul 16 14:36:02 2001 +0000
@@ -162,7 +162,7 @@
} /* else */
l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
- if (l != NULL)
+ if (l == NULL)
break;
l->str = (char *) malloc(strlen(ptr) + 1);
@@ -172,6 +172,8 @@
break;
} /* if */
+ strcpy(l->str, ptr);
+
if (retval == NULL)
retval = l;
else
--- a/physfs.c Mon Jul 16 10:32:12 2001 +0000
+++ b/physfs.c Mon Jul 16 14:36:02 2001 +0000
@@ -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 @@
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 @@
/*
* 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 @@
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 @@
(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 *i2;
size_t allocSize;
+ while (*dirName == '/')
+ dirName++;
+
allocSize = strlen(dirName) + 1;
if (prepend != NULL)
allocSize += strlen(prepend) + sepsize;
@@ -836,7 +856,12 @@
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 @@
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 @@
{
DirInfo *i;
+ while (*filename == '/')
+ filename++;
+
for (i = searchPath; i != NULL; i = i->next)
{
DirHandle *h = i->dirHandle;
@@ -900,8 +932,6 @@
int retval = 0;
LinkedStringList *i;
- assert(list != NULL);
-
for (i = list; i != NULL; i = i->next)
retval++;
@@ -947,23 +977,27 @@
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 @@
LinkedStringList *rc;
LinkedStringList *finalList = NULL;
+ while (*path == '/')
+ path++;
+
for (i = searchPath; i != NULL; i = i->next)
{
DirHandle *h = i->dirHandle;
@@ -1006,6 +1043,9 @@
int PHYSFS_exists(const char *fname)
{
+ while (*fname == '/')
+ fname++;
+
return(PHYSFS_getRealDir(fname) != NULL);
} /* PHYSFS_exists */
@@ -1014,6 +1054,9 @@
{
DirInfo *i;
+ while (*fname == '/')
+ fname++;
+
for (i = searchPath; i != NULL; i = i->next)
{
DirHandle *h = i->dirHandle;
@@ -1035,6 +1078,9 @@
if (!allowSymLinks)
return(0);
+ while (*fname == '/')
+ fname++;
+
for (i = searchPath; i != NULL; i = i->next)
{
DirHandle *h = i->dirHandle;
@@ -1057,6 +1103,9 @@
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 @@
FileHandleList *list;
DirInfo *i;
+ while (*fname == '/')
+ fname++;
+
list = (FileHandleList *) malloc(sizeof (FileHandleList));
BAIL_IF_MACRO(!list, ERR_OUT_OF_MEMORY, NULL);
--- a/physfs.h Mon Jul 16 10:32:12 2001 +0000
+++ b/physfs.h Mon Jul 16 14:36:02 2001 +0000
@@ -313,6 +313,10 @@
* 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.
*
--- a/physfs_internal.h Mon Jul 16 10:32:12 2001 +0000
+++ b/physfs_internal.h Mon Jul 16 14:36:02 2001 +0000
@@ -249,6 +249,8 @@
#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 @@
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
--- a/platform/unix.c Mon Jul 16 10:32:12 2001 +0000
+++ b/platform/unix.c Mon Jul 16 14:36:02 2001 +0000
@@ -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 @@
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 @@
break;
} /* if */
+ strcpy(l->str, ent->d_name);
+
if (retval == NULL)
retval = l;
else
@@ -337,5 +346,43 @@
} /* __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 ... */