From c27d51d8a81d687d666de109099fef1a5abbfe6e Mon Sep 17 00:00:00 2001 From: delphij Date: Mon, 16 Jul 2018 03:59:40 +0000 Subject: [PATCH] MFC r318355,318366: add -T (timestamp) option for reproducible builds --- sbin/newfs_msdos/mkfs_msdos.c | 14 +++++++++++--- sbin/newfs_msdos/mkfs_msdos.h | 2 ++ sbin/newfs_msdos/newfs_msdos.8 | 15 ++++++++++++--- sbin/newfs_msdos/newfs_msdos.c | 25 +++++++++++++++++++++++-- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/sbin/newfs_msdos/mkfs_msdos.c b/sbin/newfs_msdos/mkfs_msdos.c index 90d7df855a2..0fb3377540c 100644 --- a/sbin/newfs_msdos/mkfs_msdos.c +++ b/sbin/newfs_msdos/mkfs_msdos.c @@ -573,9 +573,17 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) } print_bpb(&bpb); if (!o.no_create) { - gettimeofday(&tv, NULL); - now = tv.tv_sec; - tm = localtime(&now); + if (o.timestamp_set) { + tv.tv_sec = now = o.timestamp; + tv.tv_usec = 0; + tm = gmtime(&now); + } else { + gettimeofday(&tv, NULL); + now = tv.tv_sec; + tm = localtime(&now); + } + + if (!(img = malloc(bpb.bpbBytesPerSec))) { warn(NULL); goto done; diff --git a/sbin/newfs_msdos/mkfs_msdos.h b/sbin/newfs_msdos/mkfs_msdos.h index 970af3612c9..2f5d7dcb12a 100644 --- a/sbin/newfs_msdos/mkfs_msdos.h +++ b/sbin/newfs_msdos/mkfs_msdos.h @@ -42,6 +42,7 @@ AOPT('L', const char *, volume_label, -1, "Volume Label") \ AOPT('N', bool, no_create, -2, "Don't create filesystem, print params only") \ AOPT('O', const char *, OEM_string, -1, "OEM string") \ AOPT('S', uint16_t, bytes_per_sector, 1, "Bytes per sector") \ +AOPT('T', time_t, timestamp, 0, "Timestamp") \ AOPT('a', uint32_t, sectors_per_fat, 1, "Sectors per FAT") \ AOPT('b', uint32_t, block_size, 1, "Block size") \ AOPT('c', uint8_t, sectors_per_cluster, 1, "Sectors per cluster") \ @@ -61,6 +62,7 @@ struct msdos_options { #define AOPT(_opt, _type, _name, _min, _desc) _type _name; ALLOPTS #undef AOPT + uint32_t timestamp_set:1; uint32_t volume_id_set:1; uint32_t media_descriptor_set:1; uint32_t hidden_sectors_set:1; diff --git a/sbin/newfs_msdos/newfs_msdos.8 b/sbin/newfs_msdos/newfs_msdos.8 index 967e1513556..a5e9b956b5f 100644 --- a/sbin/newfs_msdos/newfs_msdos.8 +++ b/sbin/newfs_msdos/newfs_msdos.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 9, 2015 +.Dd May 16, 2017 .Dt NEWFS_MSDOS 8 .Os .Sh NAME @@ -38,10 +38,11 @@ .Op Fl B Ar boot .Op Fl C Ar create-size .Op Fl F Ar FAT-type -.Op Fl I Ar VolumeId +.Op Fl I Ar VolumeID .Op Fl L Ar label .Op Fl O Ar OEM .Op Fl S Ar sector-size +.Op Fl T Ar timestamp .Op Fl a Ar FAT-size .Op Fl b Ar block-size .Op Fl c Ar cluster-size @@ -117,6 +118,14 @@ The default is Number of bytes per sector. Acceptable values are powers of 2 in the range 512 through 32768, inclusive. +.It Fl T Ar timestamp +Create the filesystem as though the current time is +.Ar timestamp . +The default filesystem volume ID is derived from the time. +.Ar timestamp +can be a pathname (where the timestamp is derived from +that file) or an integer value interpreted +as the number of seconds since the Epoch. .It Fl a Ar FAT-size Number of sectors per FAT. .It Fl b Ar block-size @@ -163,7 +172,7 @@ File system size. Number of sectors per track. .El .Sh NOTES -If some parameters (e.g. size, number of sectors, etc.) are not specified +If some parameters (e.g., size, number of sectors, etc.) are not specified through options or disktype, the program tries to generate them automatically. In particular, the size is determined as the device or file size minus the offset specified with the diff --git a/sbin/newfs_msdos/newfs_msdos.c b/sbin/newfs_msdos/newfs_msdos.c index a82c575bd21..dc312140cd4 100644 --- a/sbin/newfs_msdos/newfs_msdos.c +++ b/sbin/newfs_msdos/newfs_msdos.c @@ -33,7 +33,7 @@ static const char rcsid[] = #endif /* not lint */ #include - +#include #include #include #include @@ -53,13 +53,30 @@ static u_int argtou(const char *, u_int, u_int, const char *); static off_t argtooff(const char *, const char *); static void usage(void); +static time_t +get_tstamp(const char *b) +{ + struct stat st; + char *eb; + long long l; + + if (stat(b, &st) != -1) + return (time_t)st.st_mtime; + + errno = 0; + l = strtoll(b, &eb, 0); + if (b == eb || *eb || errno) + errx(EXIT_FAILURE, "Can't parse timestamp '%s'", b); + return (time_t)l; +} + /* * Construct a FAT12, FAT16, or FAT32 file system. */ int main(int argc, char *argv[]) { - static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:u:"; + static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:T:u:"; struct msdos_options o; const char *fname, *dtype; char buf[MAXPATHLEN]; @@ -144,6 +161,10 @@ main(int argc, char *argv[]) case 's': o.size = argto4(optarg, 1, "file system size"); break; + case 'T': + o.timestamp_set = 1; + o.timestamp = get_tstamp(optarg); + break; case 'u': o.sectors_per_track = argto2(optarg, 1, "sectors/track"); break; -- 2.45.0