Added PHYSFS_getLastModTime() API. (Thanks, John Hall!)
authorRyan C. Gordon <icculus@icculus.org>
Sat, 25 May 2002 09:41:14 +0000
changeset 240 052041af9001
parent 239 f5a5cbef2ee8
child 241 9353a112793f
Added PHYSFS_getLastModTime() API. (Thanks, John Hall!)
archivers/dir.c
archivers/grp.c
archivers/zip.c
physfs.c
physfs.h
physfs_internal.h
platform/macclassic.c
platform/posix.c
platform/skeleton.c
platform/win32.c
--- 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 ... */