From 03097332ca1acdea07f31622f3c0bc1b630a6b17 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 21 Jul 2017 22:01:51 -0400 Subject: [PATCH] unpacked: let archivers specify create and modified times, hook up to iso9660. --- src/archiver_grp.c | 2 +- src/archiver_hog.c | 2 +- src/archiver_iso9660.c | 27 ++++++++++++++++++++------- src/archiver_mvl.c | 2 +- src/archiver_qpak.c | 2 +- src/archiver_slb.c | 2 +- src/archiver_unpacked.c | 9 +++++++-- src/archiver_wad.c | 2 +- src/physfs_internal.h | 1 + 9 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/archiver_grp.c b/src/archiver_grp.c index 167474b..cc3a600 100644 --- a/src/archiver_grp.c +++ b/src/archiver_grp.c @@ -47,7 +47,7 @@ static int grpLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc) *ptr = '\0'; /* trim extra spaces. */ size = PHYSFS_swapULE32(size); - BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, location, size), 0); + BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, location, size), 0); location += size; } /* for */ diff --git a/src/archiver_hog.c b/src/archiver_hog.c index 91eb41e..57943f3 100644 --- a/src/archiver_hog.c +++ b/src/archiver_hog.c @@ -50,7 +50,7 @@ static int hogLoadEntries(PHYSFS_Io *io, void *unpkarc) pos += 13 + 4; size = PHYSFS_swapULE32(size); - BAIL_IF_ERRPASS(!UNPK_addEntry(unpkarc, name, 0, pos, size), 0); + BAIL_IF_ERRPASS(!UNPK_addEntry(unpkarc, name, 0, -1, -1, pos, size), 0); pos += size; /* skip over entry */ diff --git a/src/archiver_iso9660.c b/src/archiver_iso9660.c index 5a3e28b..b77b295 100644 --- a/src/archiver_iso9660.c +++ b/src/archiver_iso9660.c @@ -30,6 +30,8 @@ #if PHYSFS_SUPPORTS_ISO9660 +#include + /* ISO9660 often stores values in both big and little endian formats: little first, followed by big. While technically there might be different values in each, we just always use the littleendian ones and swap ourselves. The @@ -42,8 +44,9 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet, static int iso9660AddEntry(PHYSFS_Io *io, const int joliet, const int isdir, const char *base, PHYSFS_uint8 *fname, - const int fnamelen, const PHYSFS_uint64 pos, - const PHYSFS_uint64 len, void *unpkarc) + const int fnamelen, const PHYSFS_sint64 timestamp, + const PHYSFS_uint64 pos, const PHYSFS_uint64 len, + void *unpkarc) { char *fullpath; char *fnamecpy; @@ -101,7 +104,8 @@ static int iso9660AddEntry(PHYSFS_Io *io, const int joliet, const int isdir, } /* if */ } /* else */ - entry = UNPK_addEntry(unpkarc, fullpath, isdir, pos, len); + entry = UNPK_addEntry(unpkarc, fullpath, isdir, + timestamp, timestamp, pos, len); if ((entry) && (isdir)) { @@ -130,6 +134,8 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet, PHYSFS_uint8 flags; PHYSFS_uint8 fnamelen; PHYSFS_uint8 fname[256]; + PHYSFS_sint64 timestamp; + struct tm t; int isdir; int multiextent; @@ -177,13 +183,20 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet, BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &fnamelen, 1), 0); BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, fname, fnamelen), 0); - /* !!! FIXME: we lost timestamps here. Add support into the unpacked - !!! FIXME: archiver, parse them out here (and parse them out of - !!! FIXME: extended attributes too?). */ + t.tm_sec = second; + t.tm_min = minute; + t.tm_hour = hour; + t.tm_mday = day; + t.tm_mon = month - 1; + t.tm_year = year; + t.tm_wday = 0; + t.tm_yday = 0; + t.tm_isdst = -1; + timestamp = (PHYSFS_sint64) mktime(&t); extent += extattrlen; /* skip extended attribute record. */ if (!iso9660AddEntry(io, joliet, isdir, base, fname, fnamelen, - extent * 2048, datalen, unpkarc)) + timestamp, extent * 2048, datalen, unpkarc)) { return 0; } /* if */ diff --git a/src/archiver_mvl.c b/src/archiver_mvl.c index 8abb57d..c6bb108 100644 --- a/src/archiver_mvl.c +++ b/src/archiver_mvl.c @@ -45,7 +45,7 @@ static int mvlLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc) BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &size, 4), 0); name[12] = '\0'; /* just in case. */ size = PHYSFS_swapULE32(size); - BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, location, size), 0); + BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, location, size), 0); location += size; } /* for */ diff --git a/src/archiver_qpak.c b/src/archiver_qpak.c index e1edce6..4b03602 100644 --- a/src/archiver_qpak.c +++ b/src/archiver_qpak.c @@ -49,7 +49,7 @@ static int qpakLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc) BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &size, 4), 0); size = PHYSFS_swapULE32(size); location = PHYSFS_swapULE32(location); - BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, location, size), 0); + BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, location, size), 0); } /* for */ return 1; diff --git a/src/archiver_slb.c b/src/archiver_slb.c index a1f5ec5..0d9c631 100644 --- a/src/archiver_slb.c +++ b/src/archiver_slb.c @@ -52,7 +52,7 @@ static int slbLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc) BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &size, 4), 0); size = PHYSFS_swapULE32(size); - BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, location, size), 0); + BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, location, size), 0); } /* for */ return 1; diff --git a/src/archiver_unpacked.c b/src/archiver_unpacked.c index bb60f55..c409d11 100644 --- a/src/archiver_unpacked.c +++ b/src/archiver_unpacked.c @@ -27,6 +27,8 @@ typedef struct __PHYSFS_DirTreeEntry tree; PHYSFS_uint64 startPos; PHYSFS_uint64 size; + PHYSFS_sint64 ctime; + PHYSFS_sint64 mtime; } UNPKentry; typedef struct @@ -255,8 +257,8 @@ int UNPK_stat(void *opaque, const char *path, PHYSFS_Stat *stat) stat->filesize = entry->size; } /* else */ - stat->modtime = -1; - stat->createtime = -1; + stat->modtime = entry->mtime; + stat->createtime = entry->ctime; stat->accesstime = -1; stat->readonly = 1; @@ -265,6 +267,7 @@ int UNPK_stat(void *opaque, const char *path, PHYSFS_Stat *stat) void *UNPK_addEntry(void *opaque, char *name, const int isdir, + const PHYSFS_sint64 ctime, const PHYSFS_sint64 mtime, const PHYSFS_uint64 pos, const PHYSFS_uint64 len) { UNPKinfo *info = (UNPKinfo *) opaque; @@ -275,6 +278,8 @@ void *UNPK_addEntry(void *opaque, char *name, const int isdir, entry->startPos = isdir ? 0 : pos; entry->size = isdir ? 0 : len; + entry->ctime = ctime; + entry->mtime = mtime; return entry; } /* UNPK_addEntry */ diff --git a/src/archiver_wad.c b/src/archiver_wad.c index b7d1068..c47af81 100644 --- a/src/archiver_wad.c +++ b/src/archiver_wad.c @@ -63,7 +63,7 @@ static int wadLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc) name[8] = '\0'; /* name might not be null-terminated in file. */ size = PHYSFS_swapULE32(size); location = PHYSFS_swapULE32(location); - BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, location, size), 0); + BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, location, size), 0); } /* for */ return 1; diff --git a/src/physfs_internal.h b/src/physfs_internal.h index 50881b2..6381bc8 100644 --- a/src/physfs_internal.h +++ b/src/physfs_internal.h @@ -346,6 +346,7 @@ void UNPK_abandonArchive(void *opaque); void UNPK_closeArchive(void *opaque); void *UNPK_openArchive(PHYSFS_Io *io); void *UNPK_addEntry(void *opaque, char *name, const int isdir, + const PHYSFS_sint64 ctime, const PHYSFS_sint64 mtime, const PHYSFS_uint64 pos, const PHYSFS_uint64 len); PHYSFS_Io *UNPK_openRead(void *opaque, const char *name); PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name);