Added PHYSFS_getLastModTime() API. (Thanks, John Hall!)
--- a/archivers/dir.c Sat May 25 09:40:51 2002 +0000
+++ b/archivers/dir.c Sat May 25 09:41:14 2002 +0000
@@ -38,6 +38,7 @@
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 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);
@@ -77,6 +78,7 @@
DIR_exists, /* exists() method */
DIR_isDirectory, /* isDirectory() method */
DIR_isSymLink, /* isSymLink() method */
+ DIR_getLastModTime, /* getLastModTime() method */
DIR_openRead, /* openRead() method */
DIR_openWrite, /* openWrite() method */
DIR_openAppend, /* openAppend() method */
@@ -241,6 +243,18 @@
} /* DIR_isSymLink */
+static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *name)
+{
+ char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
+ PHYSFS_sint64 retval;
+
+ BAIL_IF_MACRO(d == NULL, NULL, 0);
+ retval = __PHYSFS_platformGetMtime(d);
+ free(d);
+ return(retval);
+} /* DIR_getLastModTime */
+
+
static FileHandle *doOpen(DirHandle *h, const char *name,
void *(*openFunc)(const char *filename),
const FileFunctions *fileFuncs)
--- a/archivers/grp.c Sat May 25 09:40:51 2002 +0000
+++ b/archivers/grp.c Sat May 25 09:41:14 2002 +0000
@@ -98,6 +98,7 @@
GRP_exists, /* exists() method */
GRP_isDirectory, /* isDirectory() method */
GRP_isSymLink, /* isSymLink() method */
+ NULL, /* getLastModTime() method */
GRP_openRead, /* openRead() method */
NULL, /* openWrite() method */
NULL, /* openAppend() method */
--- a/archivers/zip.c Sat May 25 09:40:51 2002 +0000
+++ b/archivers/zip.c Sat May 25 09:41:14 2002 +0000
@@ -99,6 +99,7 @@
ZIP_exists, /* exists() method */
ZIP_isDirectory, /* isDirectory() method */
ZIP_isSymLink, /* isSymLink() method */
+ NULL, /* getLastModTime() method */ /* !!! FIXME: This can be determined in a zipfile. */
ZIP_openRead, /* openRead() method */
NULL, /* openWrite() method */
NULL, /* openAppend() method */
--- a/physfs.c Sat May 25 09:40:51 2002 +0000
+++ b/physfs.c Sat May 25 09:41:14 2002 +0000
@@ -1146,6 +1146,37 @@
} /* PHYSFS_exists */
+PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname)
+{
+ PhysDirInfo *i;
+
+ BAIL_IF_MACRO(fname == NULL, ERR_INVALID_ARGUMENT, 0);
+ while (*fname == '/')
+ fname++;
+
+ if (*fname == '\0') /* eh...punt if it's the root dir. */
+ return(1);
+
+ __PHYSFS_platformGrabMutex(stateLock);
+ for (i = searchPath; i != NULL; i = i->next)
+ {
+ DirHandle *h = i->dirHandle;
+ if (__PHYSFS_verifySecurity(h, fname))
+ {
+ if (h->funcs->exists(h, fname))
+ {
+ PHYSFS_sint64 retval = h->funcs->getLastModTime(h, fname);
+ __PHYSFS_platformReleaseMutex(stateLock);
+ return(retval);
+ } /* if */
+ } /* if */
+ } /* for */
+ __PHYSFS_platformReleaseMutex(stateLock);
+
+ return(0);
+} /* PHYSFS_getLastModTime */
+
+
int PHYSFS_isDirectory(const char *fname)
{
PhysDirInfo *i;
@@ -1405,6 +1436,7 @@
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 */
--- a/physfs.h Sat May 25 09:40:51 2002 +0000
+++ b/physfs.h Sat May 25 09:41:14 2002 +0000
@@ -784,6 +784,19 @@
/**
+ * Get the last modification time of a file. This is returned as a
+ * number of seconds since the epoch (Jan 1, 1970). The exact derivation
+ * and accuracy of this time depends on the particular archiver. If there
+ * is no reasonable way to obtain this information for a particular archiver,
+ * or there was some sort of error, this function returns (-1).
+ *
+ * @param filename filename to check.
+ * @return last modified time of the file. -1 if it can't be determined.
+ */
+__EXPORT__ PHYSFS_sint64 PHYSFS_getLastModTime(const char *filename);
+
+
+/**
* Read data from a PhysicsFS filehandle. The file must be opened for reading.
*
* @param handle handle returned from PHYSFS_openRead().
--- a/physfs_internal.h Sat May 25 09:40:51 2002 +0000
+++ b/physfs_internal.h Sat May 25 09:41:14 2002 +0000
@@ -176,6 +176,14 @@
int (*isSymLink)(DirHandle *r, const char *name);
/*
+ * 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.
+ */
+ PHYSFS_sint64 (*getLastModTime)(DirHandle *r, const char *filename);
+
+ /*
* Open file for reading, and return a FileHandle.
* This filename is in platform-independent notation.
* If you can't handle multiple opens of the same file,
@@ -267,6 +275,7 @@
#define ERR_NOT_A_DIR "Not a directory"
#define ERR_FILE_NOT_FOUND "File not found"
+
/*
* Call this to set the message returned by PHYSFS_getLastError().
* Please only use the ERR_* constants above, or add new constants to the
@@ -343,6 +352,7 @@
*/
int __PHYSFS_platformInit(void);
+
/*
* Deinitialize the platform. This is called when PHYSFS_deinit() is called
* from the application. You can use this to clean up anything you've
@@ -353,6 +363,7 @@
*/
int __PHYSFS_platformDeinit(void);
+
/*
* Open a file for reading. (filename) is in platform-dependent notation. The
* file pointer should be positioned on the first byte of the file.
@@ -368,6 +379,7 @@
*/
void *__PHYSFS_platformOpenRead(const char *filename);
+
/*
* Open a file for writing. (filename) is in platform-dependent notation. If
* the file exists, it should be truncated to zero bytes, and if it doesn't
@@ -384,6 +396,7 @@
*/
void *__PHYSFS_platformOpenWrite(const char *filename);
+
/*
* Open a file for appending. (filename) is in platform-dependent notation. If
* the file exists, the file pointer should be place just past the end of the
@@ -401,6 +414,7 @@
*/
void *__PHYSFS_platformOpenAppend(const char *filename);
+
/*
* Read more data from a platform-specific file handle. (opaque) should be
* cast to whatever data type your platform uses. Read a maximum of (count)
@@ -441,6 +455,7 @@
*/
int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos);
+
/*
* Get the file pointer's position, in an 8-bit byte offset from the start of
* the file. (opaque) should be cast to whatever data type your platform
@@ -453,6 +468,7 @@
*/
PHYSFS_sint64 __PHYSFS_platformTell(void *opaque);
+
/*
* Determine the current size of a file, in 8-bit bytes, from an open file.
*
@@ -544,10 +560,20 @@
int __PHYSFS_platformExists(const char *fname);
/*
+ * Return the last modified time (in seconds since the epoch) of a file.
+ * Returns -1 on failure. (fname) is in platform-dependent notation.
+ * Symlinks should be followed; if what the symlink points to is missing,
+ * then the retval is -1.
+ */
+PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname);
+
+
+/*
* Return non-zero if filename (in platform-dependent notation) is a symlink.
*/
int __PHYSFS_platformIsSymLink(const char *fname);
+
/*
* Return non-zero if filename (in platform-dependent notation) is a symlink.
* Symlinks should be followed; if what the symlink points to is missing,
@@ -555,6 +581,7 @@
*/
int __PHYSFS_platformIsDirectory(const char *fname);
+
/*
* Convert (dirName) to platform-dependent notation, then prepend (prepend)
* and append (append) to the converted string.
@@ -577,6 +604,7 @@
const char *dirName,
const char *append);
+
/*
* Make the current thread give up a timeslice. This is called in a loop
* while waiting for various external forces to get back to us.
@@ -626,6 +654,7 @@
*/
int __PHYSFS_platformMkDir(const char *path);
+
/*
* Remove a file or directory entry in the actual filesystem. (path) is
* specified in platform-dependent notation. Note that this deletes files
--- a/platform/macclassic.c Sat May 25 09:40:51 2002 +0000
+++ b/platform/macclassic.c Sat May 25 09:41:14 2002 +0000
@@ -805,5 +805,11 @@
/* no mutexes on MacOS Classic. */
} /* __PHYSFS_platformReleaseMutex */
+
+PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
+{
+ BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1); /* !!! FIXME! */
+} /* __PHYSFS_platformGetLastModTime */
+
/* end of macclassic.c ... */
--- a/platform/posix.c Sat May 25 09:40:51 2002 +0000
+++ b/platform/posix.c Sat May 25 09:41:14 2002 +0000
@@ -470,5 +470,13 @@
return(1);
} /* __PHYSFS_platformDelete */
+
+PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
+{
+ struct stat statbuf;
+ BAIL_IF_MACRO(stat(fname, &statbuf) < 0, strerror(errno), -1);
+ return statbuf.st_mtime;
+} /* __PHYSFS_platformGetLastModTime */
+
/* end of posix.c ... */
--- a/platform/skeleton.c Sat May 25 09:40:51 2002 +0000
+++ b/platform/skeleton.c Sat May 25 09:41:14 2002 +0000
@@ -221,5 +221,11 @@
/* not implemented, but can't call __PHYSFS_setError! */
} /* __PHYSFS_platformReleaseMutex */
+
+PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
+{
+ BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
+} /* __PHYSFS_platformGetLastModTime */
+
/* end of skeleton.c ... */
--- a/platform/win32.c Sat May 25 09:40:51 2002 +0000
+++ b/platform/win32.c Sat May 25 09:41:14 2002 +0000
@@ -886,5 +886,12 @@
return 1;
}
#endif
+
+
+PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
+{
+ BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1); /* !!! FIXME! */
+} /* __PHYSFS_platformGetLastModTime */
+
/* end of win32.c ... */