From: Steven Chamberlain <steven@pyro.eu.org>
Subject: Implement -T maximum-time argument
Date: Tue, 17 Nov 2015 01:19:39 +0000
Forwarded: no

--- a/src/usr.sbin/makefs/ffs.c
+++ b/src/usr.sbin/makefs/ffs.c
@@ -648,6 +648,27 @@ ffs_build_dinode1(struct ufs1_dinode *di
 	dinp->di_mtimensec = cur->inode->st.st_mtimensec;
 	dinp->di_ctimensec = cur->inode->st.st_ctimensec;
 #endif
+	/* if maxtime was given, clamp all timestamps to this */
+	if (fsopts->maxtime >= 0) {
+		if (dinp->di_atime >= fsopts->maxtime) {
+			dinp->di_atime = fsopts->maxtime;
+#if HAVE_STRUCT_STAT_ST_MTIMENSEC
+			dinp->di_atimensec = 0;
+#endif
+		}
+		if (dinp->di_mtime >= fsopts->maxtime) {
+			dinp->di_mtime = fsopts->maxtime;
+#if HAVE_STRUCT_STAT_ST_MTIMENSEC
+			dinp->di_mtimensec = 0;
+#endif
+		}
+		if (dinp->di_ctime >= fsopts->maxtime) {
+			dinp->di_ctime = fsopts->maxtime;
+#if HAVE_STRUCT_STAT_ST_MTIMENSEC
+			dinp->di_ctimensec = 0;
+#endif
+		}
+	}
 #if HAVE_STRUCT_STAT_ST_FLAGS
 	dinp->di_flags = cur->inode->st.st_flags;
 #endif
--- a/src/usr.sbin/makefs/makefs.8
+++ b/src/usr.sbin/makefs/makefs.8
@@ -180,6 +180,7 @@
 .Op Fl S Ar sector-size
 .Op Fl s Ar image-size
 .Op Fl t Ar fs-type
+.Op Fl T Ar maximum-time
 .Ar image-file
 .Ar directory
 .Sh DESCRIPTION
@@ -318,6 +319,10 @@ BSD fast file system (default).
 .It Sy cd9660
 ISO 9660 file system.
 .El
+.It Fl T Ar maximum-time
+Clamp superblock and file timestamps to
+.Ar maximum-time
+seconds since the Epoch.
 .It Fl x
 Exclude file system nodes not explicitly listed in the specfile.
 .El
--- a/src/usr.sbin/makefs/makefs.c
+++ b/src/usr.sbin/makefs/makefs.c
@@ -128,6 +128,7 @@ main(int argc, char *argv[])
 	(void)memset(&fsoptions, 0, sizeof(fsoptions));
 	fsoptions.fd = -1;
 	fsoptions.sectorsize = -1;
+	fsoptions.maxtime = -1;
 
 	if (fstype->prepare_options)
 		fstype->prepare_options(&fsoptions);
@@ -139,7 +140,7 @@ main(int argc, char *argv[])
 	start_time.tv_sec = start.tv_sec;
 	start_time.tv_nsec = start.tv_usec * 1000;
 
-	while ((ch = getopt(argc, argv, "B:b:d:f:F:M:m:N:o:s:S:t:x")) != -1) {
+	while ((ch = getopt(argc, argv, "B:b:d:f:F:M:m:N:o:s:S:t:T:x")) != -1) {
 		switch (ch) {
 
 		case 'B':
@@ -248,6 +249,14 @@ main(int argc, char *argv[])
 			fstype->prepare_options(&fsoptions);
 			break;
 
+		case 'T':
+			fsoptions.maxtime = strtoll(optarg, NULL, 10);
+			if (start_time.tv_sec >= fsoptions.maxtime) {
+				start_time.tv_sec = fsoptions.maxtime;
+				start_time.tv_nsec = 0;
+			}
+			break;
+
 		case 'x':
 			fsoptions.onlyspec = 1;
 			break;
@@ -342,7 +351,7 @@ usage(void)
 "usage: %s [-t fs-type] [-o fs-options] [-d debug-mask] [-B endian]\n"
 "\t[-S sector-size] [-M minimum-size] [-m maximum-size] [-s image-size]\n"
 "\t[-b free-blocks] [-f free-files] [-F mtree-specfile] [-x]\n"
-"\t[-N userdb-dir] image-file directory\n",
+"\t[-N userdb-dir] [-T maximum-time] image-file directory\n",
 	    prog);
 	exit(1);
 }
--- a/src/usr.sbin/makefs/makefs.h
+++ b/src/usr.sbin/makefs/makefs.h
@@ -161,6 +161,7 @@ typedef struct {
 	int	freeblockpc;	/* free block % */
 	int	needswap;	/* non-zero if byte swapping needed */
 	int	sectorsize;	/* sector size */
+	time_t	maxtime;	/* maximum allowed timestamp value */
 
 	void	*fs_specific;	/* File system specific additions. */
 } fsinfo_t;
