From 1f5b571be72f00e6b1a65c3de1a04da92b28e9fd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 21 Aug 2002 02:59:15 +0000 Subject: [PATCH] Bunch of tedious corrections, optimizations, and cleanups. --- archivers/dir.c | 76 ++++++++++++++++++++------- archivers/grp.c | 80 +++++++++++++++++++++------- archivers/qpak.c | 87 ++++++++++++++++++++++++------- archivers/zip.c | 74 +++++++++++++++++++++----- physfs.c | 129 ++++++++++++++-------------------------------- physfs_internal.h | 32 +++++++++--- platform/posix.c | 33 +++++------- platform/win32.c | 4 +- 8 files changed, 325 insertions(+), 190 deletions(-) diff --git a/archivers/dir.c b/archivers/dir.c index 8304d547..4e7395b5 100644 --- a/archivers/dir.c +++ b/archivers/dir.c @@ -24,6 +24,10 @@ static PHYSFS_sint64 DIR_read(FileHandle *handle, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount); static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer, 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 PHYSFS_sint64 DIR_tell(FileHandle *handle); static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset); @@ -35,10 +39,10 @@ static LinkedStringList *DIR_enumerateFiles(DirHandle *h, const char *dname, int omitSymLinks); static int DIR_exists(DirHandle *h, const char *name); -static int DIR_isDirectory(DirHandle *h, const char *name); -static int DIR_isSymLink(DirHandle *h, const char *name); -static FileHandle *DIR_openRead(DirHandle *h, const char *filename); -static PHYSFS_sint64 DIR_getLastModTime(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, int *fileExists); +static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist); +static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *f, int *e); static FileHandle *DIR_openWrite(DirHandle *h, const char *filename); static FileHandle *DIR_openAppend(DirHandle *h, const char *filename); 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 = { DIR_read, /* read() method */ - NULL, /* write() method */ + DIR_dummyWrite, /* write() method */ DIR_eof, /* eof() method */ DIR_tell, /* tell() method */ DIR_seek, /* seek() method */ @@ -69,7 +73,7 @@ static const FileFunctions __PHYSFS_FileFunctions_DIR = static const FileFunctions __PHYSFS_FileFunctions_DIRW = { - NULL, /* read() method */ + DIR_dummyRead, /* read() method */ DIR_write, /* write() method */ DIR_eof, /* eof() method */ DIR_tell, /* tell() method */ @@ -116,6 +120,20 @@ static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer, } /* 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) { return(__PHYSFS_platformEOF(handle->opaque)); @@ -217,37 +235,45 @@ static int DIR_exists(DirHandle *h, const char *name) } /* 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); - int retval; + int retval = 0; BAIL_IF_MACRO(d == NULL, NULL, 0); - retval = __PHYSFS_platformIsDirectory(d); + *fileExists = __PHYSFS_platformExists(d); + if (*fileExists) + retval = __PHYSFS_platformIsDirectory(d); free(d); return(retval); } /* 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); - int retval; + int retval = 0; BAIL_IF_MACRO(f == NULL, NULL, 0); - retval = __PHYSFS_platformIsSymLink(f); + *fileExists = __PHYSFS_platformExists(f); + if (*fileExists) + retval = __PHYSFS_platformIsSymLink(f); free(f); return(retval); } /* 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); - PHYSFS_sint64 retval; + PHYSFS_sint64 retval = -1; BAIL_IF_MACRO(d == NULL, NULL, 0); - retval = __PHYSFS_platformGetLastModTime(d); + *fileExists = __PHYSFS_platformExists(d); + if (*fileExists) + retval = __PHYSFS_platformGetLastModTime(d); free(d); return(retval); } /* DIR_getLastModTime */ @@ -255,7 +281,7 @@ static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *name) static FileHandle *doOpen(DirHandle *h, const char *name, void *(*openFunc)(const char *filename), - const FileFunctions *fileFuncs) + int *fileExists, const FileFunctions *fileFuncs) { char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL); void *rc; @@ -263,6 +289,16 @@ static FileHandle *doOpen(DirHandle *h, const char *name, 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)); if (!retval) { @@ -287,23 +323,23 @@ static FileHandle *doOpen(DirHandle *h, const char *name, } /* 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)); } /* DIR_openRead */ 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)); } /* DIR_openWrite */ 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)); } /* DIR_openAppend */ diff --git a/archivers/grp.c b/archivers/grp.c index 5d235af7..0baac76b 100644 --- a/archivers/grp.c +++ b/archivers/grp.c @@ -67,6 +67,8 @@ typedef struct static void GRP_dirClose(DirHandle *h); static PHYSFS_sint64 GRP_read(FileHandle *handle, void *buffer, 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 PHYSFS_sint64 GRP_tell(FileHandle *handle); static int GRP_seek(FileHandle *handle, PHYSFS_uint64 offset); @@ -78,10 +80,14 @@ static LinkedStringList *GRP_enumerateFiles(DirHandle *h, const char *dirname, int omitSymLinks); static int GRP_exists(DirHandle *h, const char *name); -static int GRP_isDirectory(DirHandle *h, const char *name); -static int GRP_isSymLink(DirHandle *h, const char *name); -static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *name); -static FileHandle *GRP_openRead(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, int *fileExists); +static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *n, int *e); +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 = { @@ -95,7 +101,7 @@ const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP = static const FileFunctions __PHYSFS_FileFunctions_GRP = { GRP_read, /* read() method */ - NULL, /* write() method */ + GRP_write, /* write() method */ GRP_eof, /* eof() method */ GRP_tell, /* tell() method */ GRP_seek, /* seek() method */ @@ -115,10 +121,10 @@ const DirFunctions __PHYSFS_DirFunctions_GRP = GRP_isSymLink, /* isSymLink() method */ GRP_getLastModTime, /* getLastModTime() method */ GRP_openRead, /* openRead() method */ - NULL, /* openWrite() method */ - NULL, /* openAppend() method */ - NULL, /* remove() method */ - NULL, /* mkdir() method */ + GRP_openWrite, /* openWrite() method */ + GRP_openAppend, /* openAppend() method */ + GRP_remove, /* remove() method */ + GRP_mkdir, /* mkdir() method */ GRP_dirClose /* dirClose() method */ }; @@ -154,6 +160,13 @@ static PHYSFS_sint64 GRP_read(FileHandle *handle, void *buffer, } /* 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) { GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque); @@ -427,37 +440,44 @@ static int GRP_exists(DirHandle *h, const char *name) } /* 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. */ } /* 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. */ } /* 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); - if (grp_find_entry(info, name) == NULL) - return(-1); /* no such entry. */ + PHYSFS_sint64 retval = -1; - /* Just return the time of the GRP itself in the physical filesystem. */ - return(((GRPinfo *) h->opaque)->last_mod_time); + *fileExists = (grp_find_entry(info, name) != NULL); + if (*fileExists) /* use time of GRP itself in the physical filesystem. */ + retval = ((GRPinfo *) h->opaque)->last_mod_time; + + return(retval); } /* 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); FileHandle *retval; GRPfileinfo *finfo; GRPentry *entry; - entry = grp_find_entry(info, name); + entry = grp_find_entry(info, fnm); + *fileExists = (entry != NULL); BAIL_IF_MACRO(entry == NULL, NULL, NULL); retval = (FileHandle *) malloc(sizeof (FileHandle)); @@ -486,6 +506,30 @@ static FileHandle *GRP_openRead(DirHandle *h, const char *name) return(retval); } /* 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 */ /* end of grp.c ... */ diff --git a/archivers/qpak.c b/archivers/qpak.c index f7b72c36..ed789d3c 100644 --- a/archivers/qpak.c +++ b/archivers/qpak.c @@ -73,19 +73,25 @@ static void QPAK_dirClose(DirHandle *h); static LinkedStringList *QPAK_enumerateFiles(DirHandle *h, const char *dirname, int omitSymLinks); static int QPAK_exists(DirHandle *h, const char *name); -static int QPAK_isDirectory(DirHandle *h, const char *name); -static int QPAK_isSymLink(DirHandle *h, const char *name); -static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *name); -static FileHandle *QPAK_openRead(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, int *e); +static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *n, int *e); +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, - 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 PHYSFS_sint64 QPAK_tell(FileHandle *handle); static int QPAK_seek(FileHandle *handle, PHYSFS_uint64 offset); static PHYSFS_sint64 QPAK_fileLength(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 = @@ -99,7 +105,7 @@ const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK = static const FileFunctions __PHYSFS_FileFunctions_QPAK = { QPAK_read, /* read() method */ - NULL, /* write() method */ + QPAK_write, /* write() method */ QPAK_eof, /* eof() method */ QPAK_tell, /* tell() method */ QPAK_seek, /* seek() method */ @@ -118,10 +124,10 @@ const DirFunctions __PHYSFS_DirFunctions_QPAK = QPAK_isSymLink, /* isSymLink() method */ QPAK_getLastModTime, /* getLastModTime() method */ QPAK_openRead, /* openRead() method */ - NULL, /* openWrite() method */ - NULL, /* openAppend() method */ - NULL, /* remove() method */ - NULL, /* mkdir() method */ + QPAK_openWrite, /* openWrite() method */ + QPAK_openAppend, /* openAppend() method */ + QPAK_remove, /* remove() method */ + QPAK_mkdir, /* mkdir() method */ QPAK_dirClose /* dirClose() method */ }; @@ -308,7 +314,7 @@ static QPAKdirectory *qpak_findDirectory(QPAKdirectory *root, const char *name) } /* while */ } /* else */ - return(0); + BAIL_MACRO(ERR_NO_SUCH_PATH, 0); } /* qpak_findDirectory */ @@ -390,7 +396,7 @@ static QPAKentry *qpak_findEntry(QPAKdirectory *root, const char *name) thisFile = thisFile->next; } /* while */ - return(0); + BAIL_MACRO(ERR_NO_SUCH_FILE, 0); } /* qpak_findEntry */ @@ -585,22 +591,45 @@ static int QPAK_exists(DirHandle *h, const char *name) } /* 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; - return(qpak_findDirectory(info->root, name) != 0); + *fileExists = (qpak_findDirectory(info->root, name) != 0); + return(*fileExists); } /* 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 */ } /* QPAK_isSymlink */ -static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *name) +static int QPAK_remove(DirHandle *h, const char *name) +{ + BAIL_MACRO(ERR_NOT_SUPPORTED, 0); +} /* QPAK_remove */ + + +static int QPAK_mkdir(DirHandle *h, const char *name) { - return(__PHYSFS_platformGetLastModTime(((QPAKinfo *) h->opaque)->filename)); + 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 */ @@ -620,13 +649,14 @@ static void *qpak_getFileHandle(const char *name, QPAKentry *entry) } /* 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; - QPAKentry *entry = qpak_findEntry(driver->root, name); + QPAKentry *entry = qpak_findEntry(driver->root, fnm); QPAKfileinfo *fileDriver = 0; FileHandle *result = 0; + *fileExists = (entry != NULL); if (entry == NULL) return(NULL); @@ -658,6 +688,18 @@ static FileHandle *QPAK_openRead(DirHandle *h, const char *name) } /* 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, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) { @@ -678,6 +720,13 @@ static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer, } /* 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) { QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque); diff --git a/archivers/zip.c b/archivers/zip.c index 42f796a4..3ae55528 100644 --- a/archivers/zip.c +++ b/archivers/zip.c @@ -118,6 +118,8 @@ typedef struct static PHYSFS_sint64 ZIP_read(FileHandle *handle, void *buffer, 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 PHYSFS_sint64 ZIP_tell(FileHandle *handle); static int ZIP_seek(FileHandle *handle, PHYSFS_uint64 offset); @@ -129,12 +131,16 @@ static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, const char *dirname, int omitSymLinks); static int ZIP_exists(DirHandle *h, const char *name); -static int ZIP_isDirectory(DirHandle *h, const char *name); -static int ZIP_isSymLink(DirHandle *h, const char *name); -static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *name); -static FileHandle *ZIP_openRead(DirHandle *h, const char *filename); +static int ZIP_isDirectory(DirHandle *h, const char *name, int *fileExists); +static int ZIP_isSymLink(DirHandle *h, const char *name, int *fileExists); +static PHYSFS_sint64 ZIP_getLastModTime(DirHandle *h, const char *n, int *e); +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 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 = @@ -148,7 +154,7 @@ const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP = static const FileFunctions __PHYSFS_FileFunctions_ZIP = { ZIP_read, /* read() method */ - NULL, /* write() method */ + ZIP_write, /* write() method */ ZIP_eof, /* eof() method */ ZIP_tell, /* tell() method */ ZIP_seek, /* seek() method */ @@ -168,10 +174,10 @@ const DirFunctions __PHYSFS_DirFunctions_ZIP = ZIP_isSymLink, /* isSymLink() method */ ZIP_getLastModTime, /* getLastModTime() method */ ZIP_openRead, /* openRead() method */ - NULL, /* openWrite() method */ - NULL, /* openAppend() method */ - NULL, /* remove() method */ - NULL, /* mkdir() method */ + ZIP_openWrite, /* openWrite() method */ + ZIP_openAppend, /* openAppend() method */ + ZIP_remove, /* remove() method */ + ZIP_mkdir, /* mkdir() method */ ZIP_dirClose /* dirClose() method */ }; @@ -305,6 +311,13 @@ static PHYSFS_sint64 ZIP_read(FileHandle *handle, void *buf, } /* 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) { ZIPfileinfo *finfo = ((ZIPfileinfo *) (handle->opaque)); @@ -1233,15 +1246,18 @@ static int ZIP_exists(DirHandle *h, const char *name) } /* 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); + *fileExists = (entry != NULL); BAIL_IF_MACRO(entry == NULL, NULL, -1); return(entry->last_mod_time); } /* 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; 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); if (pos >= 0) + { + *fileExists = 1; return(1); /* definitely a dir. */ + } /* if */ /* Follow symlinks. This means we might need to resolve entries. */ entry = zip_find_entry(info, name); + *fileExists = (entry != NULL); BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, 0); if (entry->resolved == ZIP_UNRESOLVED_SYMLINK) /* gotta resolve it. */ @@ -1273,9 +1293,10 @@ static int ZIP_isDirectory(DirHandle *h, const char *name) } /* 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); + *fileExists = (entry != NULL); BAIL_IF_MACRO(entry == NULL, NULL, 0); return(zip_entry_is_symlink(entry)); } /* ZIP_isSymLink */ @@ -1305,14 +1326,15 @@ static void *zip_get_file_handle(const char *fn, ZIPinfo *inf, ZIPentry *entry) } /* 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; - ZIPentry *entry = zip_find_entry(info, filename); + ZIPentry *entry = zip_find_entry(info, fnm); FileHandle *retval = NULL; ZIPfileinfo *finfo = NULL; void *in; + *fileExists = (entry != NULL); BAIL_IF_MACRO(entry == NULL, NULL, NULL); in = zip_get_file_handle(info->archiveName, info, entry); @@ -1354,6 +1376,18 @@ static FileHandle *ZIP_openRead(DirHandle *h, const char *filename) } /* 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) { ZIPinfo *zi = (ZIPinfo *) (h->opaque); @@ -1363,6 +1397,18 @@ static void ZIP_dirClose(DirHandle *h) free(h); } /* 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 */ /* end of zip.c ... */ diff --git a/physfs.c b/physfs.c index 639788d4..abbbad72 100644 --- a/physfs.c +++ b/physfs.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "physfs.h" #define __PHYSICSFS_INTERNAL__ @@ -70,7 +69,6 @@ extern const DirFunctions __PHYSFS_DirFunctions_QPAK; extern const DirFunctions __PHYSFS_DirFunctions_DIR; -// !!! FIXME: This is stored with dirFunctions now, too. static const PHYSFS_ArchiveInfo *supported_types[] = { #if (defined PHYSFS_SUPPORTS_ZIP) @@ -1198,10 +1196,12 @@ char * __PHYSFS_convertToDependent(const char *prepend, int __PHYSFS_verifySecurity(DirHandle *h, const char *fname) { int retval = 1; + int fileExists; char *start; char *end; char *str; + /* !!! FIXME: Can we ditch this malloc()? */ start = str = malloc(strlen(fname) + 1); BAIL_IF_MACRO(str == NULL, ERR_OUT_OF_MEMORY, 0); strcpy(str, fname); @@ -1222,11 +1222,16 @@ int __PHYSFS_verifySecurity(DirHandle *h, const char *fname) break; } /* if */ - if ((!allowSymLinks) && (h->funcs->isSymLink(h, str))) + if (!allowSymLinks) { - __PHYSFS_setError(ERR_SYMLINK_DISALLOWED); - retval = 0; - break; + if (h->funcs->isSymLink(h, str, &fileExists)) + { + __PHYSFS_setError(ERR_SYMLINK_DISALLOWED); + retval = 0; + break; + } /* if */ + + /* !!! FIXME: Abort early here if !fileExists? */ } /* if */ if (end == NULL) @@ -1256,7 +1261,6 @@ int PHYSFS_mkdir(const char *dname) __PHYSFS_platformGrabMutex(stateLock); BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0); 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); start = str = malloc(strlen(dname) + 1); 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); 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); retval = h->funcs->remove(h, fname); @@ -1311,28 +1314,24 @@ int PHYSFS_delete(const char *fname) const char *PHYSFS_getRealDir(const char *filename) { PhysDirInfo *i; + const char *retval = NULL; while (*filename == '/') filename++; __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; if (__PHYSFS_verifySecurity(h, filename)) { - if (!h->funcs->exists(h, filename)) - __PHYSFS_setError(ERR_NO_SUCH_FILE); - else - { - __PHYSFS_platformReleaseMutex(stateLock); - return(i->dirName); - } /* else */ + if (h->funcs->exists(h, filename)) + retval = i->dirName; } /* if */ } /* for */ __PHYSFS_platformReleaseMutex(stateLock); - return(NULL); + return(retval); } /* PHYSFS_getRealDir */ @@ -1467,6 +1466,8 @@ int PHYSFS_exists(const char *fname) PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname) { PhysDirInfo *i; + PHYSFS_sint64 retval = -1; + int fileExists = 0; BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0); while (*fname == '/') @@ -1476,95 +1477,67 @@ PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname) return(1); __PHYSFS_platformGrabMutex(stateLock); - for (i = searchPath; i != NULL; i = i->next) + for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next) { DirHandle *h = i->dirHandle; if (__PHYSFS_verifySecurity(h, fname)) - { - 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 */ + retval = h->funcs->getLastModTime(h, fname, &fileExists); } /* for */ __PHYSFS_platformReleaseMutex(stateLock); - return(-1); /* error set in verifysecurity/exists */ + return(retval); } /* PHYSFS_getLastModTime */ int PHYSFS_isDirectory(const char *fname) { PhysDirInfo *i; + int retval = 0; + int fileExists = 0; BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0); while (*fname == '/') fname++; - if (*fname == '\0') - return(1); + BAIL_IF_MACRO(*fname == '\0', NULL, 1); /* Root is always a dir. :) */ __PHYSFS_platformGrabMutex(stateLock); - for (i = searchPath; i != NULL; i = i->next) + for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next) { DirHandle *h = i->dirHandle; if (__PHYSFS_verifySecurity(h, fname)) - { - 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 */ + retval = h->funcs->isDirectory(h, fname, &fileExists); } /* for */ __PHYSFS_platformReleaseMutex(stateLock); - return(0); + return(retval); } /* PHYSFS_isDirectory */ int PHYSFS_isSymbolicLink(const char *fname) { PhysDirInfo *i; + int retval = 0; + int fileExists = 0; - if (!allowSymLinks) - return(0); + BAIL_IF_MACRO(!allowSymLinks, ERR_SYMLINK_DISALLOWED, 0); BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0); while (*fname == '/') fname++; + BAIL_IF_MACRO(*fname == '\0', NULL, 0); /* Root is never a symlink */ + __PHYSFS_platformGrabMutex(stateLock); - for (i = searchPath; i != NULL; i = i->next) + for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next) { DirHandle *h = i->dirHandle; if (__PHYSFS_verifySecurity(h, fname)) - { - 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 */ + retval = h->funcs->isSymLink(h, fname, &fileExists); } /* for */ __PHYSFS_platformReleaseMutex(stateLock); - return(0); + return(retval); } /* PHYSFS_isSymbolicLink */ @@ -1620,9 +1593,10 @@ PHYSFS_file *PHYSFS_openAppend(const char *filename) PHYSFS_file *PHYSFS_openRead(const char *fname) { - PHYSFS_file *retval; + PHYSFS_file *retval = NULL; FileHandle *rc = NULL; FileHandleList *list; + int fileExists = 0; PhysDirInfo *i; BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, NULL); @@ -1631,17 +1605,12 @@ PHYSFS_file *PHYSFS_openRead(const char *fname) __PHYSFS_platformGrabMutex(stateLock); 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; if (__PHYSFS_verifySecurity(h, fname)) - { - rc = h->funcs->openRead(h, fname); - if (rc != NULL) - break; - } /* if */ + rc = h->funcs->openRead(h, fname, &fileExists); } /* for */ - BAIL_IF_MACRO_MUTEX(rc == NULL, NULL, stateLock, NULL); list = (FileHandleList *) malloc(sizeof (FileHandleList)); @@ -1711,9 +1680,6 @@ PHYSFS_sint64 PHYSFS_read(PHYSFS_file *handle, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) { 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)); } /* PHYSFS_read */ @@ -1722,9 +1688,6 @@ PHYSFS_sint64 PHYSFS_write(PHYSFS_file *handle, const void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) { 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)); } /* PHYSFS_write */ @@ -1732,9 +1695,6 @@ PHYSFS_sint64 PHYSFS_write(PHYSFS_file *handle, const void *buffer, int PHYSFS_eof(PHYSFS_file *handle) { 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)); } /* PHYSFS_eof */ @@ -1742,9 +1702,6 @@ int PHYSFS_eof(PHYSFS_file *handle) PHYSFS_sint64 PHYSFS_tell(PHYSFS_file *handle) { 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)); } /* PHYSFS_tell */ @@ -1752,10 +1709,6 @@ PHYSFS_sint64 PHYSFS_tell(PHYSFS_file *handle) int PHYSFS_seek(PHYSFS_file *handle, PHYSFS_uint64 pos) { 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)); } /* PHYSFS_seek */ @@ -1763,10 +1716,6 @@ int PHYSFS_seek(PHYSFS_file *handle, PHYSFS_uint64 pos) PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_file *handle) { 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)); } /* PHYSFS_filelength */ diff --git a/physfs_internal.h b/physfs_internal.h index 84f531bc..805a603e 100644 --- a/physfs_internal.h +++ b/physfs_internal.h @@ -842,6 +842,7 @@ typedef struct __PHYSFS_DIRFUNCTIONS__ /* * Returns non-zero if filename can be opened for reading. * This filename is in platform-independent notation. + * You should not follow symlinks. */ int (*exists)(DirHandle *r, const char *name); @@ -850,22 +851,34 @@ typedef struct __PHYSFS_DIRFUNCTIONS__ * This filename is in platform-independent notation. * Symlinks should be followed; if what the symlink points * 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. * 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. * Returns -1 on failure, or the file's mtime in seconds since * the epoch (Jan 1, 1970) on success. * 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. @@ -874,8 +887,12 @@ typedef struct __PHYSFS_DIRFUNCTIONS__ * you can opt to fail for the second call. * Fail if the file does not exist. * 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. @@ -1245,8 +1262,10 @@ int __PHYSFS_platformStricmp(const char *str1, const char *str2); /* * Return non-zero if filename (in platform-dependent notation) exists. - * Symlinks should be followed; if what the symlink points to is missing, - * then the retval is false. + * Symlinks should NOT be followed; at this stage, we do not care what the + * 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); @@ -1258,7 +1277,6 @@ int __PHYSFS_platformExists(const char *fname); */ PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname); - /* * Return non-zero if filename (in platform-dependent notation) is a symlink. */ diff --git a/platform/posix.c b/platform/posix.c index 03a71f5a..85d28753 100644 --- a/platform/posix.c +++ b/platform/posix.c @@ -144,10 +144,17 @@ int __PHYSFS_platformStricmp(const char *x, const char *y) } /* __PHYSFS_platformStricmp */ +#if (defined __PHYSFS_NO_SYMLINKS__) +#define doStat stat +#else +#define doStat lstat +#endif + int __PHYSFS_platformExists(const char *fname) { struct stat statbuf; - return(stat(fname, &statbuf) == 0); + BAIL_IF_MACRO(doStat(fname, &statbuf) == -1, strerror(errno), 0); + return(1); } /* __PHYSFS_platformExists */ @@ -156,18 +163,9 @@ int __PHYSFS_platformIsSymLink(const char *fname) #if (defined __PHYSFS_NO_SYMLINKS__) return(0); #else - struct stat statbuf; - int retval = 0; - - if (lstat(fname, &statbuf) == 0) - { - if (S_ISLNK(statbuf.st_mode)) - retval = 1; - } /* if */ - - return(retval); - + BAIL_IF_MACRO(lstat(fname, &statbuf) == -1, strerror(errno), 0); + return( (S_ISLNK(statbuf.st_mode)) ? 1 : 0 ); #endif } /* __PHYSFS_platformIsSymlink */ @@ -175,15 +173,8 @@ int __PHYSFS_platformIsSymLink(const char *fname) int __PHYSFS_platformIsDirectory(const char *fname) { struct stat statbuf; - int retval = 0; - - if (stat(fname, &statbuf) == 0) - { - if (S_ISDIR(statbuf.st_mode)) - retval = 1; - } /* if */ - - return(retval); + BAIL_IF_MACRO(stat(fname, &statbuf) == -1, strerror(errno), 0); + return( (S_ISDIR(statbuf.st_mode)) ? 1 : 0 ); } /* __PHYSFS_platformIsDirectory */ diff --git a/platform/win32.c b/platform/win32.c index e4bc65d2..f992f0bf 100644 --- a/platform/win32.c +++ b/platform/win32.c @@ -369,7 +369,9 @@ int __PHYSFS_platformStricmp(const char *x, const char *y) 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 */