Bunch of tedious corrections, optimizations, and cleanups.

This commit is contained in:
Ryan C. Gordon 2002-08-21 02:59:15 +00:00
parent b772eede1d
commit 1f5b571be7
8 changed files with 325 additions and 190 deletions

View File

@ -24,6 +24,10 @@ static PHYSFS_sint64 DIR_read(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount); PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer, static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount); PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 DIR_dummyRead(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 DIR_dummyWrite(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static int DIR_eof(FileHandle *handle); static int DIR_eof(FileHandle *handle);
static PHYSFS_sint64 DIR_tell(FileHandle *handle); static PHYSFS_sint64 DIR_tell(FileHandle *handle);
static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset); static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset);
@ -35,10 +39,10 @@ static LinkedStringList *DIR_enumerateFiles(DirHandle *h,
const char *dname, const char *dname,
int omitSymLinks); int omitSymLinks);
static int DIR_exists(DirHandle *h, const char *name); static int DIR_exists(DirHandle *h, const char *name);
static int DIR_isDirectory(DirHandle *h, const char *name); static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists);
static int DIR_isSymLink(DirHandle *h, const char *name); static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists);
static FileHandle *DIR_openRead(DirHandle *h, const char *filename); static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist);
static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *name); static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *f, int *e);
static FileHandle *DIR_openWrite(DirHandle *h, const char *filename); static FileHandle *DIR_openWrite(DirHandle *h, const char *filename);
static FileHandle *DIR_openAppend(DirHandle *h, const char *filename); static FileHandle *DIR_openAppend(DirHandle *h, const char *filename);
static int DIR_remove(DirHandle *h, const char *name); static int DIR_remove(DirHandle *h, const char *name);
@ -58,7 +62,7 @@ const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
static const FileFunctions __PHYSFS_FileFunctions_DIR = static const FileFunctions __PHYSFS_FileFunctions_DIR =
{ {
DIR_read, /* read() method */ DIR_read, /* read() method */
NULL, /* write() method */ DIR_dummyWrite, /* write() method */
DIR_eof, /* eof() method */ DIR_eof, /* eof() method */
DIR_tell, /* tell() method */ DIR_tell, /* tell() method */
DIR_seek, /* seek() method */ DIR_seek, /* seek() method */
@ -69,7 +73,7 @@ static const FileFunctions __PHYSFS_FileFunctions_DIR =
static const FileFunctions __PHYSFS_FileFunctions_DIRW = static const FileFunctions __PHYSFS_FileFunctions_DIRW =
{ {
NULL, /* read() method */ DIR_dummyRead, /* read() method */
DIR_write, /* write() method */ DIR_write, /* write() method */
DIR_eof, /* eof() method */ DIR_eof, /* eof() method */
DIR_tell, /* tell() method */ DIR_tell, /* tell() method */
@ -116,6 +120,20 @@ static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
} /* DIR_write */ } /* DIR_write */
static PHYSFS_sint64 DIR_dummyRead(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* DIR_dummyRead */
static PHYSFS_sint64 DIR_dummyWrite(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* DIR_dummyWrite */
static int DIR_eof(FileHandle *handle) static int DIR_eof(FileHandle *handle)
{ {
return(__PHYSFS_platformEOF(handle->opaque)); return(__PHYSFS_platformEOF(handle->opaque));
@ -217,37 +235,45 @@ static int DIR_exists(DirHandle *h, const char *name)
} /* DIR_exists */ } /* DIR_exists */
static int DIR_isDirectory(DirHandle *h, const char *name) static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists)
{ {
char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL); char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
int retval; int retval = 0;
BAIL_IF_MACRO(d == NULL, NULL, 0); BAIL_IF_MACRO(d == NULL, NULL, 0);
retval = __PHYSFS_platformIsDirectory(d); *fileExists = __PHYSFS_platformExists(d);
if (*fileExists)
retval = __PHYSFS_platformIsDirectory(d);
free(d); free(d);
return(retval); return(retval);
} /* DIR_isDirectory */ } /* DIR_isDirectory */
static int DIR_isSymLink(DirHandle *h, const char *name) static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists)
{ {
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL); char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
int retval; int retval = 0;
BAIL_IF_MACRO(f == NULL, NULL, 0); BAIL_IF_MACRO(f == NULL, NULL, 0);
retval = __PHYSFS_platformIsSymLink(f); *fileExists = __PHYSFS_platformExists(f);
if (*fileExists)
retval = __PHYSFS_platformIsSymLink(f);
free(f); free(f);
return(retval); return(retval);
} /* DIR_isSymLink */ } /* DIR_isSymLink */
static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *name) static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h,
const char *name,
int *fileExists)
{ {
char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL); char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
PHYSFS_sint64 retval; PHYSFS_sint64 retval = -1;
BAIL_IF_MACRO(d == NULL, NULL, 0); BAIL_IF_MACRO(d == NULL, NULL, 0);
retval = __PHYSFS_platformGetLastModTime(d); *fileExists = __PHYSFS_platformExists(d);
if (*fileExists)
retval = __PHYSFS_platformGetLastModTime(d);
free(d); free(d);
return(retval); return(retval);
} /* DIR_getLastModTime */ } /* DIR_getLastModTime */
@ -255,7 +281,7 @@ static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *name)
static FileHandle *doOpen(DirHandle *h, const char *name, static FileHandle *doOpen(DirHandle *h, const char *name,
void *(*openFunc)(const char *filename), void *(*openFunc)(const char *filename),
const FileFunctions *fileFuncs) int *fileExists, const FileFunctions *fileFuncs)
{ {
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL); char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
void *rc; void *rc;
@ -263,6 +289,16 @@ static FileHandle *doOpen(DirHandle *h, const char *name,
BAIL_IF_MACRO(f == NULL, NULL, NULL); BAIL_IF_MACRO(f == NULL, NULL, NULL);
if (fileExists != NULL)
{
*fileExists = __PHYSFS_platformExists(f);
if (!(*fileExists))
{
free(f);
return(NULL);
} /* if */
} /* if */
retval = (FileHandle *) malloc(sizeof (FileHandle)); retval = (FileHandle *) malloc(sizeof (FileHandle));
if (!retval) if (!retval)
{ {
@ -287,23 +323,23 @@ static FileHandle *doOpen(DirHandle *h, const char *name,
} /* doOpen */ } /* doOpen */
static FileHandle *DIR_openRead(DirHandle *h, const char *filename) static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist)
{ {
return(doOpen(h, filename, __PHYSFS_platformOpenRead, return(doOpen(h, fnm, __PHYSFS_platformOpenRead, exist,
&__PHYSFS_FileFunctions_DIR)); &__PHYSFS_FileFunctions_DIR));
} /* DIR_openRead */ } /* DIR_openRead */
static FileHandle *DIR_openWrite(DirHandle *h, const char *filename) static FileHandle *DIR_openWrite(DirHandle *h, const char *filename)
{ {
return(doOpen(h, filename, __PHYSFS_platformOpenWrite, return(doOpen(h, filename, __PHYSFS_platformOpenWrite, NULL,
&__PHYSFS_FileFunctions_DIRW)); &__PHYSFS_FileFunctions_DIRW));
} /* DIR_openWrite */ } /* DIR_openWrite */
static FileHandle *DIR_openAppend(DirHandle *h, const char *filename) static FileHandle *DIR_openAppend(DirHandle *h, const char *filename)
{ {
return(doOpen(h, filename, __PHYSFS_platformOpenAppend, return(doOpen(h, filename, __PHYSFS_platformOpenAppend, NULL,
&__PHYSFS_FileFunctions_DIRW)); &__PHYSFS_FileFunctions_DIRW));
} /* DIR_openAppend */ } /* DIR_openAppend */

View File

@ -67,6 +67,8 @@ typedef struct
static void GRP_dirClose(DirHandle *h); static void GRP_dirClose(DirHandle *h);
static PHYSFS_sint64 GRP_read(FileHandle *handle, void *buffer, static PHYSFS_sint64 GRP_read(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount); PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 GRP_write(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static int GRP_eof(FileHandle *handle); static int GRP_eof(FileHandle *handle);
static PHYSFS_sint64 GRP_tell(FileHandle *handle); static PHYSFS_sint64 GRP_tell(FileHandle *handle);
static int GRP_seek(FileHandle *handle, PHYSFS_uint64 offset); static int GRP_seek(FileHandle *handle, PHYSFS_uint64 offset);
@ -78,10 +80,14 @@ static LinkedStringList *GRP_enumerateFiles(DirHandle *h,
const char *dirname, const char *dirname,
int omitSymLinks); int omitSymLinks);
static int GRP_exists(DirHandle *h, const char *name); static int GRP_exists(DirHandle *h, const char *name);
static int GRP_isDirectory(DirHandle *h, const char *name); static int GRP_isDirectory(DirHandle *h, const char *name, int *fileExists);
static int GRP_isSymLink(DirHandle *h, const char *name); static int GRP_isSymLink(DirHandle *h, const char *name, int *fileExists);
static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *name); static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *n, int *e);
static FileHandle *GRP_openRead(DirHandle *h, const char *name); static FileHandle *GRP_openRead(DirHandle *h, const char *name, int *exist);
static FileHandle *GRP_openWrite(DirHandle *h, const char *name);
static FileHandle *GRP_openAppend(DirHandle *h, const char *name);
static int GRP_remove(DirHandle *h, const char *name);
static int GRP_mkdir(DirHandle *h, const char *name);
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP = const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP =
{ {
@ -95,7 +101,7 @@ const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP =
static const FileFunctions __PHYSFS_FileFunctions_GRP = static const FileFunctions __PHYSFS_FileFunctions_GRP =
{ {
GRP_read, /* read() method */ GRP_read, /* read() method */
NULL, /* write() method */ GRP_write, /* write() method */
GRP_eof, /* eof() method */ GRP_eof, /* eof() method */
GRP_tell, /* tell() method */ GRP_tell, /* tell() method */
GRP_seek, /* seek() method */ GRP_seek, /* seek() method */
@ -115,10 +121,10 @@ const DirFunctions __PHYSFS_DirFunctions_GRP =
GRP_isSymLink, /* isSymLink() method */ GRP_isSymLink, /* isSymLink() method */
GRP_getLastModTime, /* getLastModTime() method */ GRP_getLastModTime, /* getLastModTime() method */
GRP_openRead, /* openRead() method */ GRP_openRead, /* openRead() method */
NULL, /* openWrite() method */ GRP_openWrite, /* openWrite() method */
NULL, /* openAppend() method */ GRP_openAppend, /* openAppend() method */
NULL, /* remove() method */ GRP_remove, /* remove() method */
NULL, /* mkdir() method */ GRP_mkdir, /* mkdir() method */
GRP_dirClose /* dirClose() method */ GRP_dirClose /* dirClose() method */
}; };
@ -154,6 +160,13 @@ static PHYSFS_sint64 GRP_read(FileHandle *handle, void *buffer,
} /* GRP_read */ } /* GRP_read */
static PHYSFS_sint64 GRP_write(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* GRP_write */
static int GRP_eof(FileHandle *handle) static int GRP_eof(FileHandle *handle)
{ {
GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque); GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
@ -427,37 +440,44 @@ static int GRP_exists(DirHandle *h, const char *name)
} /* GRP_exists */ } /* GRP_exists */
static int GRP_isDirectory(DirHandle *h, const char *name) static int GRP_isDirectory(DirHandle *h, const char *name, int *fileExists)
{ {
*fileExists = GRP_exists(h, name);
return(0); /* never directories in a groupfile. */ return(0); /* never directories in a groupfile. */
} /* GRP_isDirectory */ } /* GRP_isDirectory */
static int GRP_isSymLink(DirHandle *h, const char *name) static int GRP_isSymLink(DirHandle *h, const char *name, int *fileExists)
{ {
*fileExists = GRP_exists(h, name);
return(0); /* never symlinks in a groupfile. */ return(0); /* never symlinks in a groupfile. */
} /* GRP_isSymLink */ } /* GRP_isSymLink */
static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *name) static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h,
const char *name,
int *fileExists)
{ {
GRPinfo *info = ((GRPinfo *) h->opaque); GRPinfo *info = ((GRPinfo *) h->opaque);
if (grp_find_entry(info, name) == NULL) PHYSFS_sint64 retval = -1;
return(-1); /* no such entry. */
/* Just return the time of the GRP itself in the physical filesystem. */ *fileExists = (grp_find_entry(info, name) != NULL);
return(((GRPinfo *) h->opaque)->last_mod_time); if (*fileExists) /* use time of GRP itself in the physical filesystem. */
retval = ((GRPinfo *) h->opaque)->last_mod_time;
return(retval);
} /* GRP_getLastModTime */ } /* GRP_getLastModTime */
static FileHandle *GRP_openRead(DirHandle *h, const char *name) static FileHandle *GRP_openRead(DirHandle *h, const char *fnm, int *fileExists)
{ {
GRPinfo *info = ((GRPinfo *) h->opaque); GRPinfo *info = ((GRPinfo *) h->opaque);
FileHandle *retval; FileHandle *retval;
GRPfileinfo *finfo; GRPfileinfo *finfo;
GRPentry *entry; GRPentry *entry;
entry = grp_find_entry(info, name); entry = grp_find_entry(info, fnm);
*fileExists = (entry != NULL);
BAIL_IF_MACRO(entry == NULL, NULL, NULL); BAIL_IF_MACRO(entry == NULL, NULL, NULL);
retval = (FileHandle *) malloc(sizeof (FileHandle)); retval = (FileHandle *) malloc(sizeof (FileHandle));
@ -486,6 +506,30 @@ static FileHandle *GRP_openRead(DirHandle *h, const char *name)
return(retval); return(retval);
} /* GRP_openRead */ } /* GRP_openRead */
static FileHandle *GRP_openWrite(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
} /* GRP_openWrite */
static FileHandle *GRP_openAppend(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
} /* GRP_openAppend */
static int GRP_remove(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
} /* GRP_remove */
static int GRP_mkdir(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
} /* GRP_mkdir */
#endif /* defined PHYSFS_SUPPORTS_GRP */ #endif /* defined PHYSFS_SUPPORTS_GRP */
/* end of grp.c ... */ /* end of grp.c ... */

View File

@ -73,19 +73,25 @@ static void QPAK_dirClose(DirHandle *h);
static LinkedStringList *QPAK_enumerateFiles(DirHandle *h, const char *dirname, static LinkedStringList *QPAK_enumerateFiles(DirHandle *h, const char *dirname,
int omitSymLinks); int omitSymLinks);
static int QPAK_exists(DirHandle *h, const char *name); static int QPAK_exists(DirHandle *h, const char *name);
static int QPAK_isDirectory(DirHandle *h, const char *name); static int QPAK_isDirectory(DirHandle *h, const char *name, int *e);
static int QPAK_isSymLink(DirHandle *h, const char *name); static int QPAK_isSymLink(DirHandle *h, const char *name, int *e);
static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *name); static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *n, int *e);
static FileHandle *QPAK_openRead(DirHandle *h, const char *name); static FileHandle *QPAK_openRead(DirHandle *h, const char *name, int *e);
static FileHandle *QPAK_openWrite(DirHandle *h, const char *name);
static FileHandle *QPAK_openAppend(DirHandle *h, const char *name);
static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer, static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount); PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 QPAK_write(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static int QPAK_eof(FileHandle *handle); static int QPAK_eof(FileHandle *handle);
static PHYSFS_sint64 QPAK_tell(FileHandle *handle); static PHYSFS_sint64 QPAK_tell(FileHandle *handle);
static int QPAK_seek(FileHandle *handle, PHYSFS_uint64 offset); static int QPAK_seek(FileHandle *handle, PHYSFS_uint64 offset);
static PHYSFS_sint64 QPAK_fileLength(FileHandle *handle); static PHYSFS_sint64 QPAK_fileLength(FileHandle *handle);
static int QPAK_fileClose(FileHandle *handle); static int QPAK_fileClose(FileHandle *handle);
static int QPAK_remove(DirHandle *h, const char *name);
static int QPAK_mkdir(DirHandle *h, const char *name);
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK = const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK =
@ -99,7 +105,7 @@ const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK =
static const FileFunctions __PHYSFS_FileFunctions_QPAK = static const FileFunctions __PHYSFS_FileFunctions_QPAK =
{ {
QPAK_read, /* read() method */ QPAK_read, /* read() method */
NULL, /* write() method */ QPAK_write, /* write() method */
QPAK_eof, /* eof() method */ QPAK_eof, /* eof() method */
QPAK_tell, /* tell() method */ QPAK_tell, /* tell() method */
QPAK_seek, /* seek() method */ QPAK_seek, /* seek() method */
@ -118,10 +124,10 @@ const DirFunctions __PHYSFS_DirFunctions_QPAK =
QPAK_isSymLink, /* isSymLink() method */ QPAK_isSymLink, /* isSymLink() method */
QPAK_getLastModTime, /* getLastModTime() method */ QPAK_getLastModTime, /* getLastModTime() method */
QPAK_openRead, /* openRead() method */ QPAK_openRead, /* openRead() method */
NULL, /* openWrite() method */ QPAK_openWrite, /* openWrite() method */
NULL, /* openAppend() method */ QPAK_openAppend, /* openAppend() method */
NULL, /* remove() method */ QPAK_remove, /* remove() method */
NULL, /* mkdir() method */ QPAK_mkdir, /* mkdir() method */
QPAK_dirClose /* dirClose() method */ QPAK_dirClose /* dirClose() method */
}; };
@ -308,7 +314,7 @@ static QPAKdirectory *qpak_findDirectory(QPAKdirectory *root, const char *name)
} /* while */ } /* while */
} /* else */ } /* else */
return(0); BAIL_MACRO(ERR_NO_SUCH_PATH, 0);
} /* qpak_findDirectory */ } /* qpak_findDirectory */
@ -390,7 +396,7 @@ static QPAKentry *qpak_findEntry(QPAKdirectory *root, const char *name)
thisFile = thisFile->next; thisFile = thisFile->next;
} /* while */ } /* while */
return(0); BAIL_MACRO(ERR_NO_SUCH_FILE, 0);
} /* qpak_findEntry */ } /* qpak_findEntry */
@ -585,22 +591,45 @@ static int QPAK_exists(DirHandle *h, const char *name)
} /* QPAK_exists */ } /* QPAK_exists */
static int QPAK_isDirectory(DirHandle *h, const char *name) static int QPAK_isDirectory(DirHandle *h, const char *name, int *fileExists)
{ {
QPAKinfo *info = (QPAKinfo *) h->opaque; QPAKinfo *info = (QPAKinfo *) h->opaque;
return(qpak_findDirectory(info->root, name) != 0); *fileExists = (qpak_findDirectory(info->root, name) != 0);
return(*fileExists);
} /* QPAK_isDirectory */ } /* QPAK_isDirectory */
static int QPAK_isSymLink(DirHandle *h, const char *name) static int QPAK_isSymLink(DirHandle *h, const char *name, int *fileExists)
{ {
*fileExists = QPAK_exists(h, name);
return(0); /* we don't support symlinks for now */ return(0); /* we don't support symlinks for now */
} /* QPAK_isSymlink */ } /* QPAK_isSymlink */
static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *name) static int QPAK_remove(DirHandle *h, const char *name)
{ {
return(__PHYSFS_platformGetLastModTime(((QPAKinfo *) h->opaque)->filename)); BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
} /* QPAK_remove */
static int QPAK_mkdir(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
} /* QPAK_mkdir */
static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h,
const char *name,
int *fileExists)
{
QPAKinfo *info = (QPAKinfo *) h->opaque;
PHYSFS_sint64 retval = -1;
*fileExists = QPAK_exists(h, name);
if (*fileExists)
retval = __PHYSFS_platformGetLastModTime(info->filename);
return(retval);
} /* QPAK_getLastModTime */ } /* QPAK_getLastModTime */
@ -620,13 +649,14 @@ static void *qpak_getFileHandle(const char *name, QPAKentry *entry)
} /* qpak_getFileHandle */ } /* qpak_getFileHandle */
static FileHandle *QPAK_openRead(DirHandle *h, const char *name) static FileHandle *QPAK_openRead(DirHandle *h, const char *fnm, int *fileExists)
{ {
QPAKinfo *driver = (QPAKinfo *) h->opaque; QPAKinfo *driver = (QPAKinfo *) h->opaque;
QPAKentry *entry = qpak_findEntry(driver->root, name); QPAKentry *entry = qpak_findEntry(driver->root, fnm);
QPAKfileinfo *fileDriver = 0; QPAKfileinfo *fileDriver = 0;
FileHandle *result = 0; FileHandle *result = 0;
*fileExists = (entry != NULL);
if (entry == NULL) if (entry == NULL)
return(NULL); return(NULL);
@ -658,6 +688,18 @@ static FileHandle *QPAK_openRead(DirHandle *h, const char *name)
} /* QPAK_openRead */ } /* QPAK_openRead */
static FileHandle *QPAK_openWrite(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
} /* QPAK_openWrite */
static FileHandle *QPAK_openAppend(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
} /* QPAK_openAppend */
static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer, static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{ {
@ -678,6 +720,13 @@ static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer,
} /* QPAK_read */ } /* QPAK_read */
static PHYSFS_sint64 QPAK_write(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* QPAK_write */
static int QPAK_eof(FileHandle *handle) static int QPAK_eof(FileHandle *handle)
{ {
QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque); QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque);

View File

@ -118,6 +118,8 @@ typedef struct
static PHYSFS_sint64 ZIP_read(FileHandle *handle, void *buffer, static PHYSFS_sint64 ZIP_read(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount); PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 ZIP_write(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static int ZIP_eof(FileHandle *handle); static int ZIP_eof(FileHandle *handle);
static PHYSFS_sint64 ZIP_tell(FileHandle *handle); static PHYSFS_sint64 ZIP_tell(FileHandle *handle);
static int ZIP_seek(FileHandle *handle, PHYSFS_uint64 offset); static int ZIP_seek(FileHandle *handle, PHYSFS_uint64 offset);
@ -129,12 +131,16 @@ static LinkedStringList *ZIP_enumerateFiles(DirHandle *h,
const char *dirname, const char *dirname,
int omitSymLinks); int omitSymLinks);
static int ZIP_exists(DirHandle *h, const char *name); static int ZIP_exists(DirHandle *h, const char *name);
static int ZIP_isDirectory(DirHandle *h, const char *name); static int ZIP_isDirectory(DirHandle *h, const char *name, int *fileExists);
static int ZIP_isSymLink(DirHandle *h, const char *name); static int ZIP_isSymLink(DirHandle *h, const char *name, int *fileExists);
static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *name); static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *n, int *e);
static FileHandle *ZIP_openRead(DirHandle *h, const char *filename); static FileHandle *ZIP_openRead(DirHandle *h, const char *filename, int *e);
static FileHandle *ZIP_openWrite(DirHandle *h, const char *filename);
static FileHandle *ZIP_openAppend(DirHandle *h, const char *filename);
static void ZIP_dirClose(DirHandle *h); static void ZIP_dirClose(DirHandle *h);
static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry); static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry);
static int ZIP_remove(DirHandle *h, const char *name);
static int ZIP_mkdir(DirHandle *h, const char *name);
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP = const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
@ -148,7 +154,7 @@ const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
static const FileFunctions __PHYSFS_FileFunctions_ZIP = static const FileFunctions __PHYSFS_FileFunctions_ZIP =
{ {
ZIP_read, /* read() method */ ZIP_read, /* read() method */
NULL, /* write() method */ ZIP_write, /* write() method */
ZIP_eof, /* eof() method */ ZIP_eof, /* eof() method */
ZIP_tell, /* tell() method */ ZIP_tell, /* tell() method */
ZIP_seek, /* seek() method */ ZIP_seek, /* seek() method */
@ -168,10 +174,10 @@ const DirFunctions __PHYSFS_DirFunctions_ZIP =
ZIP_isSymLink, /* isSymLink() method */ ZIP_isSymLink, /* isSymLink() method */
ZIP_getLastModTime, /* getLastModTime() method */ ZIP_getLastModTime, /* getLastModTime() method */
ZIP_openRead, /* openRead() method */ ZIP_openRead, /* openRead() method */
NULL, /* openWrite() method */ ZIP_openWrite, /* openWrite() method */
NULL, /* openAppend() method */ ZIP_openAppend, /* openAppend() method */
NULL, /* remove() method */ ZIP_remove, /* remove() method */
NULL, /* mkdir() method */ ZIP_mkdir, /* mkdir() method */
ZIP_dirClose /* dirClose() method */ ZIP_dirClose /* dirClose() method */
}; };
@ -305,6 +311,13 @@ static PHYSFS_sint64 ZIP_read(FileHandle *handle, void *buf,
} /* ZIP_read */ } /* ZIP_read */
static PHYSFS_sint64 ZIP_write(FileHandle *handle, const void *buf,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* ZIP_write */
static int ZIP_eof(FileHandle *handle) static int ZIP_eof(FileHandle *handle)
{ {
ZIPfileinfo *finfo = ((ZIPfileinfo *) (handle->opaque)); ZIPfileinfo *finfo = ((ZIPfileinfo *) (handle->opaque));
@ -1233,15 +1246,18 @@ static int ZIP_exists(DirHandle *h, const char *name)
} /* ZIP_exists */ } /* ZIP_exists */
static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *name) static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h,
const char *name,
int *fileExists)
{ {
ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name); ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name);
*fileExists = (entry != NULL);
BAIL_IF_MACRO(entry == NULL, NULL, -1); BAIL_IF_MACRO(entry == NULL, NULL, -1);
return(entry->last_mod_time); return(entry->last_mod_time);
} /* ZIP_getLastModTime */ } /* ZIP_getLastModTime */
static int ZIP_isDirectory(DirHandle *h, const char *name) static int ZIP_isDirectory(DirHandle *h, const char *name, int *fileExists)
{ {
ZIPinfo *info = (ZIPinfo *) h->opaque; ZIPinfo *info = (ZIPinfo *) h->opaque;
PHYSFS_uint32 pos; PHYSFS_uint32 pos;
@ -1249,10 +1265,14 @@ static int ZIP_isDirectory(DirHandle *h, const char *name)
pos = zip_find_start_of_dir(info, name, 1); pos = zip_find_start_of_dir(info, name, 1);
if (pos >= 0) if (pos >= 0)
{
*fileExists = 1;
return(1); /* definitely a dir. */ return(1); /* definitely a dir. */
} /* if */
/* Follow symlinks. This means we might need to resolve entries. */ /* Follow symlinks. This means we might need to resolve entries. */
entry = zip_find_entry(info, name); entry = zip_find_entry(info, name);
*fileExists = (entry != NULL);
BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, 0); BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, 0);
if (entry->resolved == ZIP_UNRESOLVED_SYMLINK) /* gotta resolve it. */ if (entry->resolved == ZIP_UNRESOLVED_SYMLINK) /* gotta resolve it. */
@ -1273,9 +1293,10 @@ static int ZIP_isDirectory(DirHandle *h, const char *name)
} /* ZIP_isDirectory */ } /* ZIP_isDirectory */
static int ZIP_isSymLink(DirHandle *h, const char *name) static int ZIP_isSymLink(DirHandle *h, const char *name, int *fileExists)
{ {
ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name); ZIPentry *entry = zip_find_entry((ZIPinfo *) h->opaque, name);
*fileExists = (entry != NULL);
BAIL_IF_MACRO(entry == NULL, NULL, 0); BAIL_IF_MACRO(entry == NULL, NULL, 0);
return(zip_entry_is_symlink(entry)); return(zip_entry_is_symlink(entry));
} /* ZIP_isSymLink */ } /* ZIP_isSymLink */
@ -1305,14 +1326,15 @@ static void *zip_get_file_handle(const char *fn, ZIPinfo *inf, ZIPentry *entry)
} /* zip_get_file_handle */ } /* zip_get_file_handle */
static FileHandle *ZIP_openRead(DirHandle *h, const char *filename) static FileHandle *ZIP_openRead(DirHandle *h, const char *fnm, int *fileExists)
{ {
ZIPinfo *info = (ZIPinfo *) h->opaque; ZIPinfo *info = (ZIPinfo *) h->opaque;
ZIPentry *entry = zip_find_entry(info, filename); ZIPentry *entry = zip_find_entry(info, fnm);
FileHandle *retval = NULL; FileHandle *retval = NULL;
ZIPfileinfo *finfo = NULL; ZIPfileinfo *finfo = NULL;
void *in; void *in;
*fileExists = (entry != NULL);
BAIL_IF_MACRO(entry == NULL, NULL, NULL); BAIL_IF_MACRO(entry == NULL, NULL, NULL);
in = zip_get_file_handle(info->archiveName, info, entry); in = zip_get_file_handle(info->archiveName, info, entry);
@ -1354,6 +1376,18 @@ static FileHandle *ZIP_openRead(DirHandle *h, const char *filename)
} /* ZIP_openRead */ } /* ZIP_openRead */
static FileHandle *ZIP_openWrite(DirHandle *h, const char *filename)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
} /* ZIP_openWrite */
static FileHandle *ZIP_openAppend(DirHandle *h, const char *filename)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
} /* ZIP_openAppend */
static void ZIP_dirClose(DirHandle *h) static void ZIP_dirClose(DirHandle *h)
{ {
ZIPinfo *zi = (ZIPinfo *) (h->opaque); ZIPinfo *zi = (ZIPinfo *) (h->opaque);
@ -1363,6 +1397,18 @@ static void ZIP_dirClose(DirHandle *h)
free(h); free(h);
} /* ZIP_dirClose */ } /* ZIP_dirClose */
static int ZIP_remove(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
} /* ZIP_remove */
static int ZIP_mkdir(DirHandle *h, const char *name)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
} /* ZIP_mkdir */
#endif /* defined PHYSFS_SUPPORTS_ZIP */ #endif /* defined PHYSFS_SUPPORTS_ZIP */
/* end of zip.c ... */ /* end of zip.c ... */

129
physfs.c
View File

@ -22,7 +22,6 @@
#include <string.h> #include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#include "physfs.h" #include "physfs.h"
#define __PHYSICSFS_INTERNAL__ #define __PHYSICSFS_INTERNAL__
@ -70,7 +69,6 @@ extern const DirFunctions __PHYSFS_DirFunctions_QPAK;
extern const DirFunctions __PHYSFS_DirFunctions_DIR; extern const DirFunctions __PHYSFS_DirFunctions_DIR;
// !!! FIXME: This is stored with dirFunctions now, too.
static const PHYSFS_ArchiveInfo *supported_types[] = static const PHYSFS_ArchiveInfo *supported_types[] =
{ {
#if (defined PHYSFS_SUPPORTS_ZIP) #if (defined PHYSFS_SUPPORTS_ZIP)
@ -1198,10 +1196,12 @@ char * __PHYSFS_convertToDependent(const char *prepend,
int __PHYSFS_verifySecurity(DirHandle *h, const char *fname) int __PHYSFS_verifySecurity(DirHandle *h, const char *fname)
{ {
int retval = 1; int retval = 1;
int fileExists;
char *start; char *start;
char *end; char *end;
char *str; char *str;
/* !!! FIXME: Can we ditch this malloc()? */
start = str = malloc(strlen(fname) + 1); start = str = malloc(strlen(fname) + 1);
BAIL_IF_MACRO(str == NULL, ERR_OUT_OF_MEMORY, 0); BAIL_IF_MACRO(str == NULL, ERR_OUT_OF_MEMORY, 0);
strcpy(str, fname); strcpy(str, fname);
@ -1222,11 +1222,16 @@ int __PHYSFS_verifySecurity(DirHandle *h, const char *fname)
break; break;
} /* if */ } /* if */
if ((!allowSymLinks) && (h->funcs->isSymLink(h, str))) if (!allowSymLinks)
{ {
__PHYSFS_setError(ERR_SYMLINK_DISALLOWED); if (h->funcs->isSymLink(h, str, &fileExists))
retval = 0; {
break; __PHYSFS_setError(ERR_SYMLINK_DISALLOWED);
retval = 0;
break;
} /* if */
/* !!! FIXME: Abort early here if !fileExists? */
} /* if */ } /* if */
if (end == NULL) if (end == NULL)
@ -1256,7 +1261,6 @@ int PHYSFS_mkdir(const char *dname)
__PHYSFS_platformGrabMutex(stateLock); __PHYSFS_platformGrabMutex(stateLock);
BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0); BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0);
h = writeDir->dirHandle; h = writeDir->dirHandle;
BAIL_IF_MACRO_MUTEX(!h->funcs->mkdir, ERR_NOT_SUPPORTED, stateLock, 0);
BAIL_IF_MACRO_MUTEX(!__PHYSFS_verifySecurity(h, dname), NULL, stateLock, 0); BAIL_IF_MACRO_MUTEX(!__PHYSFS_verifySecurity(h, dname), NULL, stateLock, 0);
start = str = malloc(strlen(dname) + 1); start = str = malloc(strlen(dname) + 1);
BAIL_IF_MACRO_MUTEX(str == NULL, ERR_OUT_OF_MEMORY, stateLock, 0); BAIL_IF_MACRO_MUTEX(str == NULL, ERR_OUT_OF_MEMORY, stateLock, 0);
@ -1299,7 +1303,6 @@ int PHYSFS_delete(const char *fname)
BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0); BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0);
h = writeDir->dirHandle; h = writeDir->dirHandle;
BAIL_IF_MACRO_MUTEX(!h->funcs->remove, ERR_NOT_SUPPORTED, stateLock, 0);
BAIL_IF_MACRO_MUTEX(!__PHYSFS_verifySecurity(h, fname), NULL, stateLock, 0); BAIL_IF_MACRO_MUTEX(!__PHYSFS_verifySecurity(h, fname), NULL, stateLock, 0);
retval = h->funcs->remove(h, fname); retval = h->funcs->remove(h, fname);
@ -1311,28 +1314,24 @@ int PHYSFS_delete(const char *fname)
const char *PHYSFS_getRealDir(const char *filename) const char *PHYSFS_getRealDir(const char *filename)
{ {
PhysDirInfo *i; PhysDirInfo *i;
const char *retval = NULL;
while (*filename == '/') while (*filename == '/')
filename++; filename++;
__PHYSFS_platformGrabMutex(stateLock); __PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next) for (i = searchPath; ((i != NULL) && (retval == NULL)); i = i->next)
{ {
DirHandle *h = i->dirHandle; DirHandle *h = i->dirHandle;
if (__PHYSFS_verifySecurity(h, filename)) if (__PHYSFS_verifySecurity(h, filename))
{ {
if (!h->funcs->exists(h, filename)) if (h->funcs->exists(h, filename))
__PHYSFS_setError(ERR_NO_SUCH_FILE); retval = i->dirName;
else
{
__PHYSFS_platformReleaseMutex(stateLock);
return(i->dirName);
} /* else */
} /* if */ } /* if */
} /* for */ } /* for */
__PHYSFS_platformReleaseMutex(stateLock); __PHYSFS_platformReleaseMutex(stateLock);
return(NULL); return(retval);
} /* PHYSFS_getRealDir */ } /* PHYSFS_getRealDir */
@ -1467,6 +1466,8 @@ int PHYSFS_exists(const char *fname)
PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname) PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname)
{ {
PhysDirInfo *i; PhysDirInfo *i;
PHYSFS_sint64 retval = -1;
int fileExists = 0;
BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0); BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0);
while (*fname == '/') while (*fname == '/')
@ -1476,95 +1477,67 @@ PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname)
return(1); return(1);
__PHYSFS_platformGrabMutex(stateLock); __PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next) for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next)
{ {
DirHandle *h = i->dirHandle; DirHandle *h = i->dirHandle;
if (__PHYSFS_verifySecurity(h, fname)) if (__PHYSFS_verifySecurity(h, fname))
{ retval = h->funcs->getLastModTime(h, fname, &fileExists);
if (!h->funcs->exists(h, fname))
__PHYSFS_setError(ERR_NO_SUCH_FILE);
else
{
PHYSFS_sint64 retval = -1;
if (h->funcs->getLastModTime == NULL)
__PHYSFS_setError(ERR_NOT_SUPPORTED);
else
retval = h->funcs->getLastModTime(h, fname);
__PHYSFS_platformReleaseMutex(stateLock);
return(retval);
} /* else */
} /* if */
} /* for */ } /* for */
__PHYSFS_platformReleaseMutex(stateLock); __PHYSFS_platformReleaseMutex(stateLock);
return(-1); /* error set in verifysecurity/exists */ return(retval);
} /* PHYSFS_getLastModTime */ } /* PHYSFS_getLastModTime */
int PHYSFS_isDirectory(const char *fname) int PHYSFS_isDirectory(const char *fname)
{ {
PhysDirInfo *i; PhysDirInfo *i;
int retval = 0;
int fileExists = 0;
BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0); BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0);
while (*fname == '/') while (*fname == '/')
fname++; fname++;
if (*fname == '\0') BAIL_IF_MACRO(*fname == '\0', NULL, 1); /* Root is always a dir. :) */
return(1);
__PHYSFS_platformGrabMutex(stateLock); __PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next) for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next)
{ {
DirHandle *h = i->dirHandle; DirHandle *h = i->dirHandle;
if (__PHYSFS_verifySecurity(h, fname)) if (__PHYSFS_verifySecurity(h, fname))
{ retval = h->funcs->isDirectory(h, fname, &fileExists);
if (!h->funcs->exists(h, fname))
__PHYSFS_setError(ERR_NO_SUCH_FILE);
else
{
int retval = h->funcs->isDirectory(h, fname);
__PHYSFS_platformReleaseMutex(stateLock);
return(retval);
} /* else */
} /* if */
} /* for */ } /* for */
__PHYSFS_platformReleaseMutex(stateLock); __PHYSFS_platformReleaseMutex(stateLock);
return(0); return(retval);
} /* PHYSFS_isDirectory */ } /* PHYSFS_isDirectory */
int PHYSFS_isSymbolicLink(const char *fname) int PHYSFS_isSymbolicLink(const char *fname)
{ {
PhysDirInfo *i; PhysDirInfo *i;
int retval = 0;
int fileExists = 0;
if (!allowSymLinks) BAIL_IF_MACRO(!allowSymLinks, ERR_SYMLINK_DISALLOWED, 0);
return(0);
BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0); BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0);
while (*fname == '/') while (*fname == '/')
fname++; fname++;
BAIL_IF_MACRO(*fname == '\0', NULL, 0); /* Root is never a symlink */
__PHYSFS_platformGrabMutex(stateLock); __PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next) for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next)
{ {
DirHandle *h = i->dirHandle; DirHandle *h = i->dirHandle;
if (__PHYSFS_verifySecurity(h, fname)) if (__PHYSFS_verifySecurity(h, fname))
{ retval = h->funcs->isSymLink(h, fname, &fileExists);
if (!h->funcs->exists(h, fname))
__PHYSFS_setError(ERR_NO_SUCH_FILE);
else
{
int retval = h->funcs->isSymLink(h, fname);
__PHYSFS_platformReleaseMutex(stateLock);
return(retval);
} /* else */
} /* if */
} /* for */ } /* for */
__PHYSFS_platformReleaseMutex(stateLock); __PHYSFS_platformReleaseMutex(stateLock);
return(0); return(retval);
} /* PHYSFS_isSymbolicLink */ } /* PHYSFS_isSymbolicLink */
@ -1620,9 +1593,10 @@ PHYSFS_file *PHYSFS_openAppend(const char *filename)
PHYSFS_file *PHYSFS_openRead(const char *fname) PHYSFS_file *PHYSFS_openRead(const char *fname)
{ {
PHYSFS_file *retval; PHYSFS_file *retval = NULL;
FileHandle *rc = NULL; FileHandle *rc = NULL;
FileHandleList *list; FileHandleList *list;
int fileExists = 0;
PhysDirInfo *i; PhysDirInfo *i;
BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, NULL); BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, NULL);
@ -1631,17 +1605,12 @@ PHYSFS_file *PHYSFS_openRead(const char *fname)
__PHYSFS_platformGrabMutex(stateLock); __PHYSFS_platformGrabMutex(stateLock);
BAIL_IF_MACRO_MUTEX(!searchPath, ERR_NOT_IN_SEARCH_PATH, stateLock, NULL); BAIL_IF_MACRO_MUTEX(!searchPath, ERR_NOT_IN_SEARCH_PATH, stateLock, NULL);
for (i = searchPath; i != NULL; i = i->next) for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next)
{ {
DirHandle *h = i->dirHandle; DirHandle *h = i->dirHandle;
if (__PHYSFS_verifySecurity(h, fname)) if (__PHYSFS_verifySecurity(h, fname))
{ rc = h->funcs->openRead(h, fname, &fileExists);
rc = h->funcs->openRead(h, fname);
if (rc != NULL)
break;
} /* if */
} /* for */ } /* for */
BAIL_IF_MACRO_MUTEX(rc == NULL, NULL, stateLock, NULL); BAIL_IF_MACRO_MUTEX(rc == NULL, NULL, stateLock, NULL);
list = (FileHandleList *) malloc(sizeof (FileHandleList)); list = (FileHandleList *) malloc(sizeof (FileHandleList));
@ -1711,9 +1680,6 @@ PHYSFS_sint64 PHYSFS_read(PHYSFS_file *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{ {
FileHandle *h = (FileHandle *) handle->opaque; FileHandle *h = (FileHandle *) handle->opaque;
assert(h != NULL);
assert(h->funcs != NULL);
BAIL_IF_MACRO(h->funcs->read == NULL, ERR_NOT_SUPPORTED, -1);
return(h->funcs->read(h, buffer, objSize, objCount)); return(h->funcs->read(h, buffer, objSize, objCount));
} /* PHYSFS_read */ } /* PHYSFS_read */
@ -1722,9 +1688,6 @@ PHYSFS_sint64 PHYSFS_write(PHYSFS_file *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{ {
FileHandle *h = (FileHandle *) handle->opaque; FileHandle *h = (FileHandle *) handle->opaque;
assert(h != NULL);
assert(h->funcs != NULL);
BAIL_IF_MACRO(h->funcs->write == NULL, ERR_NOT_SUPPORTED, -1);
return(h->funcs->write(h, buffer, objSize, objCount)); return(h->funcs->write(h, buffer, objSize, objCount));
} /* PHYSFS_write */ } /* PHYSFS_write */
@ -1732,9 +1695,6 @@ PHYSFS_sint64 PHYSFS_write(PHYSFS_file *handle, const void *buffer,
int PHYSFS_eof(PHYSFS_file *handle) int PHYSFS_eof(PHYSFS_file *handle)
{ {
FileHandle *h = (FileHandle *) handle->opaque; FileHandle *h = (FileHandle *) handle->opaque;
assert(h != NULL);
assert(h->funcs != NULL);
BAIL_IF_MACRO(h->funcs->eof == NULL, ERR_NOT_SUPPORTED, -1);
return(h->funcs->eof(h)); return(h->funcs->eof(h));
} /* PHYSFS_eof */ } /* PHYSFS_eof */
@ -1742,9 +1702,6 @@ int PHYSFS_eof(PHYSFS_file *handle)
PHYSFS_sint64 PHYSFS_tell(PHYSFS_file *handle) PHYSFS_sint64 PHYSFS_tell(PHYSFS_file *handle)
{ {
FileHandle *h = (FileHandle *) handle->opaque; FileHandle *h = (FileHandle *) handle->opaque;
assert(h != NULL);
assert(h->funcs != NULL);
BAIL_IF_MACRO(h->funcs->tell == NULL, ERR_NOT_SUPPORTED, -1);
return(h->funcs->tell(h)); return(h->funcs->tell(h));
} /* PHYSFS_tell */ } /* PHYSFS_tell */
@ -1752,10 +1709,6 @@ PHYSFS_sint64 PHYSFS_tell(PHYSFS_file *handle)
int PHYSFS_seek(PHYSFS_file *handle, PHYSFS_uint64 pos) int PHYSFS_seek(PHYSFS_file *handle, PHYSFS_uint64 pos)
{ {
FileHandle *h = (FileHandle *) handle->opaque; FileHandle *h = (FileHandle *) handle->opaque;
assert(h != NULL);
assert(h->funcs != NULL);
BAIL_IF_MACRO(h->funcs->seek == NULL, ERR_NOT_SUPPORTED, 0);
BAIL_IF_MACRO(pos < 0, ERR_INVALID_ARGUMENT, 0);
return(h->funcs->seek(h, pos)); return(h->funcs->seek(h, pos));
} /* PHYSFS_seek */ } /* PHYSFS_seek */
@ -1763,10 +1716,6 @@ int PHYSFS_seek(PHYSFS_file *handle, PHYSFS_uint64 pos)
PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_file *handle) PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_file *handle)
{ {
FileHandle *h = (FileHandle *) handle->opaque; FileHandle *h = (FileHandle *) handle->opaque;
assert(h != NULL);
assert(h->funcs != NULL);
BAIL_IF_MACRO(h->funcs->fileLength == NULL, ERR_NOT_SUPPORTED, 0);
return(h->funcs->fileLength(h)); return(h->funcs->fileLength(h));
} /* PHYSFS_filelength */ } /* PHYSFS_filelength */

View File

@ -842,6 +842,7 @@ typedef struct __PHYSFS_DIRFUNCTIONS__
/* /*
* Returns non-zero if filename can be opened for reading. * Returns non-zero if filename can be opened for reading.
* This filename is in platform-independent notation. * This filename is in platform-independent notation.
* You should not follow symlinks.
*/ */
int (*exists)(DirHandle *r, const char *name); int (*exists)(DirHandle *r, const char *name);
@ -850,22 +851,34 @@ typedef struct __PHYSFS_DIRFUNCTIONS__
* This filename is in platform-independent notation. * This filename is in platform-independent notation.
* Symlinks should be followed; if what the symlink points * Symlinks should be followed; if what the symlink points
* to is missing, or isn't a directory, then the retval is zero. * 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)(DirHandle *r, const char *name); int (*isDirectory)(DirHandle *r, const char *name, int *fileExists);
/* /*
* Returns non-zero if filename is really a symlink. * Returns non-zero if filename is really a symlink.
* This filename is in platform-independent notation. * 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)(DirHandle *r, const char *name); int (*isSymLink)(DirHandle *r, const char *name, int *fileExists);
/* /*
* Retrieve the last modification time (mtime) of a file. * Retrieve the last modification time (mtime) of a file.
* Returns -1 on failure, or the file's mtime in seconds since * Returns -1 on failure, or the file's mtime in seconds since
* the epoch (Jan 1, 1970) on success. * the epoch (Jan 1, 1970) on success.
* This filename is in platform-independent notation. * This filename is in platform-independent notation.
*
* Regardless of success or failure, please set *exists to
* non-zero if the file existed (even if it's a broken symlink!),
* zero if it did not.
*/ */
PHYSFS_sint64 (*getLastModTime)(DirHandle *r, const char *filename); PHYSFS_sint64 (*getLastModTime)(DirHandle *r, const char *fnm, int *exist);
/* /*
* Open file for reading, and return a FileHandle. * Open file for reading, and return a FileHandle.
@ -874,8 +887,12 @@ typedef struct __PHYSFS_DIRFUNCTIONS__
* you can opt to fail for the second call. * you can opt to fail for the second call.
* Fail if the file does not exist. * Fail if the file does not exist.
* Returns NULL on failure, and calls __PHYSFS_setError(). * Returns NULL on failure, and calls __PHYSFS_setError().
*
* 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.
*/ */
FileHandle *(*openRead)(DirHandle *r, const char *filename); FileHandle *(*openRead)(DirHandle *r, const char *fname, int *fileExists);
/* /*
* Open file for writing, and return a FileHandle. * Open file for writing, and return a FileHandle.
@ -1245,8 +1262,10 @@ int __PHYSFS_platformStricmp(const char *str1, const char *str2);
/* /*
* Return non-zero if filename (in platform-dependent notation) exists. * Return non-zero if filename (in platform-dependent notation) exists.
* Symlinks should be followed; if what the symlink points to is missing, * Symlinks should NOT be followed; at this stage, we do not care what the
* then the retval is false. * 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); int __PHYSFS_platformExists(const char *fname);
@ -1258,7 +1277,6 @@ int __PHYSFS_platformExists(const char *fname);
*/ */
PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname); PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname);
/* /*
* Return non-zero if filename (in platform-dependent notation) is a symlink. * Return non-zero if filename (in platform-dependent notation) is a symlink.
*/ */

View File

@ -144,10 +144,17 @@ int __PHYSFS_platformStricmp(const char *x, const char *y)
} /* __PHYSFS_platformStricmp */ } /* __PHYSFS_platformStricmp */
#if (defined __PHYSFS_NO_SYMLINKS__)
#define doStat stat
#else
#define doStat lstat
#endif
int __PHYSFS_platformExists(const char *fname) int __PHYSFS_platformExists(const char *fname)
{ {
struct stat statbuf; struct stat statbuf;
return(stat(fname, &statbuf) == 0); BAIL_IF_MACRO(doStat(fname, &statbuf) == -1, strerror(errno), 0);
return(1);
} /* __PHYSFS_platformExists */ } /* __PHYSFS_platformExists */
@ -156,18 +163,9 @@ int __PHYSFS_platformIsSymLink(const char *fname)
#if (defined __PHYSFS_NO_SYMLINKS__) #if (defined __PHYSFS_NO_SYMLINKS__)
return(0); return(0);
#else #else
struct stat statbuf; struct stat statbuf;
int retval = 0; BAIL_IF_MACRO(lstat(fname, &statbuf) == -1, strerror(errno), 0);
return( (S_ISLNK(statbuf.st_mode)) ? 1 : 0 );
if (lstat(fname, &statbuf) == 0)
{
if (S_ISLNK(statbuf.st_mode))
retval = 1;
} /* if */
return(retval);
#endif #endif
} /* __PHYSFS_platformIsSymlink */ } /* __PHYSFS_platformIsSymlink */
@ -175,15 +173,8 @@ int __PHYSFS_platformIsSymLink(const char *fname)
int __PHYSFS_platformIsDirectory(const char *fname) int __PHYSFS_platformIsDirectory(const char *fname)
{ {
struct stat statbuf; struct stat statbuf;
int retval = 0; BAIL_IF_MACRO(stat(fname, &statbuf) == -1, strerror(errno), 0);
return( (S_ISDIR(statbuf.st_mode)) ? 1 : 0 );
if (stat(fname, &statbuf) == 0)
{
if (S_ISDIR(statbuf.st_mode))
retval = 1;
} /* if */
return(retval);
} /* __PHYSFS_platformIsDirectory */ } /* __PHYSFS_platformIsDirectory */

View File

@ -369,7 +369,9 @@ int __PHYSFS_platformStricmp(const char *x, const char *y)
int __PHYSFS_platformExists(const char *fname) int __PHYSFS_platformExists(const char *fname)
{ {
return(GetFileAttributes(fname) != INVALID_FILE_ATTRIBUTES); BAIL_IF_MACRO(GetFileAttributes(fname) == INVALID_FILE_ATTRIBUTES,
win32strerror(), 0);
return(1);
} /* __PHYSFS_platformExists */ } /* __PHYSFS_platformExists */