newfs_msdos: add -T (timestamp) option for reproducible builds

This includes some whitespace and minor bug fixes relative to NetBSD,
which will be submitted upstream at the conclusion of the makefs
msdos update.

NetBSD revs:
mkfs_msdos.c	1.11
mkfs_msdos.h	1.4
newfs_msdos.8	1.22
newfs_msdos.c	1.44

Submitted by:	Siva Mahadevan <smahadevan@freebsdfoundation.org>
Reviewed by:	emaste
Obtained from:	NetBSD
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Ed Maste 2017-05-16 17:04:50 +00:00
parent fcf0952c80
commit 28ef05f7c3
4 changed files with 44 additions and 6 deletions

View File

@ -566,9 +566,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;

View File

@ -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;

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 9, 2015
.Dd May 16, 2017
.Dt NEWFS_MSDOS 8
.Os
.Sh NAME
@ -55,6 +55,7 @@
.Op Fl o Ar hidden
.Op Fl r Ar reserved
.Op Fl s Ar total
.Op Fl T Ar timestamp
.Op Fl u Ar track-size
.Ar special
.Op Ar disktype
@ -159,6 +160,12 @@ Number of hidden sectors.
Number of reserved sectors.
.It Fl s Ar total
File system size.
.It Fl T Ar timestamp
Specify a timestamp to be used for filesystem creation so that
it can be consistent for reproducible builds.
The timestamp can be a pathname (where the timestamps are derived from
that file) or an integer value interpreted
as the number of seconds since the Epoch.
.It Fl u Ar track-size
Number of sectors per track.
.El

View File

@ -31,7 +31,7 @@ static const char rcsid[] =
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <err.h>
#include <errno.h>
#include <paths.h>
@ -51,13 +51,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];
@ -142,6 +159,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;