From 25d017aa13555ad6275f6d3aa1113d2b0b092534 Mon Sep 17 00:00:00 2001 From: Sevan Janiyan Date: Sun, 4 Nov 2018 14:48:36 +0000 Subject: [PATCH] sbin/newfs_msdos: sync with NetBSD-8 Allow 0 timestamp. Grammar fixes. Use the create_size if given to compute the real size instead of stat'ing the file again, which might have been larger to start with. Document history. closes #274 Change-Id: Ibf881f22f351c7a17488b24a05c2110be1d65ae0 --- sbin/newfs_msdos/mkfs_msdos.c | 141 +++++++++++++++++++-------------- sbin/newfs_msdos/mkfs_msdos.h | 9 +-- sbin/newfs_msdos/newfs_msdos.8 | 24 ++++-- sbin/newfs_msdos/newfs_msdos.c | 37 ++++++++- 4 files changed, 137 insertions(+), 74 deletions(-) diff --git a/sbin/newfs_msdos/mkfs_msdos.c b/sbin/newfs_msdos/mkfs_msdos.c index 7fd6fe20b..05ae2c102 100644 --- a/sbin/newfs_msdos/mkfs_msdos.c +++ b/sbin/newfs_msdos/mkfs_msdos.c @@ -1,4 +1,4 @@ -/* $NetBSD: mkfs_msdos.c,v 1.9 2014/01/05 12:52:39 martin Exp $ */ +/* $NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $ */ /* * Copyright (c) 1998 Robert Nordier @@ -37,7 +37,7 @@ static const char rcsid[] = "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $"; #else -__RCSID("$NetBSD: mkfs_msdos.c,v 1.9 2014/01/05 12:52:39 martin Exp $"); +__RCSID("$NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $"); #endif #endif /* not lint */ @@ -235,7 +235,7 @@ static int got_siginfo = 0; /* received a SIGINFO */ static int check_mounted(const char *, mode_t); #endif static int getstdfmt(const char *, struct bpb *); -static int getbpbinfo(int, const char *, const char *, int, struct bpb *, int); +static int getbpbinfo(int, const char *, const char *, int, struct bpb *, off_t); static void print_bpb(struct bpb *); static int ckgeom(const char *, u_int, const char *); static int oklabel(const char *); @@ -331,20 +331,30 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) if (!(o.floppy || (o.drive_heads && o.sectors_per_track && o.bytes_per_sector && o.size && o.hidden_sectors_set))) { if (getbpbinfo(fd, fname, dtype, o.hidden_sectors_set, &bpb, - o.create_size != 0) == -1) + o.create_size) == -1) return -1; bpb.bsec -= (o.offset / bpb.bps); if (bpb.spc == 0) { /* set defaults */ - if (bpb.bsec <= 6000) /* about 3MB -> 512 bytes */ - bpb.spc = 1; - else if (bpb.bsec <= (1<<17)) /* 64M -> 4k */ - bpb.spc = 8; - else if (bpb.bsec <= (1<<19)) /* 256M -> 8k */ - bpb.spc = 16; - else if (bpb.bsec <= (1<<21)) /* 1G -> 16k */ - bpb.spc = 32; - else - bpb.spc = 64; /* otherwise 32k */ + /* minimum cluster size */ + switch (o.fat_type) { + case 12: + bpb.spc = 1; /* use 512 bytes */ + x = 2; /* up to 2MB */ + break; + case 16: + bpb.spc = 1; /* use 512 bytes */ + x = 32; /* up to 32MB */ + break; + default: + bpb.spc = 8; /* use 4k */ + x = 8192; /* up to 8GB */ + break; + } + x1 = howmany(bpb.bsec, (1048576 / 512)); /* -> MB */ + while (bpb.spc < 128 && x < x1) { + x *= 2; + bpb.spc *= 2; + } } } @@ -611,9 +621,15 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) printf("MBR type: %d\n", ch); 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.bps))) err(1, NULL); dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft; @@ -801,7 +817,7 @@ getstdfmt(const char *fmt, struct bpb *bpb) */ static int getbpbinfo(int fd, const char *fname, const char *dtype, int iflag, - struct bpb *bpb, int create) + struct bpb *bpb, off_t create_size) { const char *s1, *s2; int part; @@ -819,26 +835,31 @@ getbpbinfo(int fd, const char *fname, const char *dtype, int iflag, #ifndef MAKEFS int maxpartitions = getmaxpartitions(); + struct disk_geom geo; + struct dkwedge_info dkw; // XXX: Does not work with wedges if (s2 && *s2 >= 'a' && *s2 <= 'a' + maxpartitions - 1) { part = *s2++ - 'a'; } #endif - if (((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) || - !bpb->bps || !bpb->spt || !bpb->hds) { - u_int sector_size; - u_int nsectors; - u_int ntracks; - u_int size; -#ifndef MAKEFS - struct disk_geom geo; - struct dkwedge_info dkw; - if (!create && getdiskinfo(fname, fd, NULL, &geo, &dkw) != -1) { - sector_size = geo.dg_secsize = 512; - nsectors = geo.dg_nsectors = 63; - ntracks = geo.dg_ntracks = 255; + if (!(((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) || + !bpb->bps || !bpb->spt || !bpb->hds)) { + return 0; + } + + u_int sector_size = 512; + u_int nsectors = 63; + u_int ntracks = 255; + u_int size; + + if (create_size == 0) { +#ifndef MAKEFS + if (getdiskinfo(fname, fd, NULL, &geo, &dkw) != -1) { + sector_size = geo.dg_secsize; + nsectors = geo.dg_nsectors; + ntracks = geo.dg_ntracks; size = dkw.dkw_size; } else #endif @@ -849,39 +870,39 @@ getbpbinfo(int fd, const char *fname, const char *dtype, int iflag, warnx("Can't get disk size for `%s'", fname); return -1; } - /* create a fake geometry for a file image */ - sector_size = 512; - nsectors = 63; - ntracks = 255; size = st.st_size / sector_size; } - if (!bpb->bps) { - if (ckgeom(fname, sector_size, "bytes/sector") == -1) - return -1; - bpb->bps = sector_size; - } + } else { + size = create_size / sector_size; + } - if (nsectors > 63) { - /* - * The kernel doesn't accept BPB with spt > 63. - * (see sys/fs/msdosfs/msdosfs_vfsops.c:msdosfs_mountfs()) - * If values taken from disklabel don't match these - * restrictions, use popular BIOS default values instead. - */ - nsectors = 63; - } - if (!bpb->spt) { - if (ckgeom(fname, nsectors, "sectors/track") == -1) - return -1; - bpb->spt = nsectors; - } - if (!bpb->hds) - if (ckgeom(fname, ntracks, "drive heads") == -1) - return -1; - bpb->hds = ntracks; - if (!bpb->bsec) - bpb->bsec = size; + if (!bpb->bps) { + if (ckgeom(fname, sector_size, "bytes/sector") == -1) + return -1; + bpb->bps = sector_size; + } + + if (nsectors > 63) { + /* + * The kernel doesn't accept BPB with spt > 63. + * (see sys/fs/msdosfs/msdosfs_vfsops.c:msdosfs_mountfs()) + * If values taken from disklabel don't match these + * restrictions, use popular BIOS default values instead. + */ + nsectors = 63; + } + if (!bpb->spt) { + if (ckgeom(fname, nsectors, "sectors/track") == -1) + return -1; + bpb->spt = nsectors; } + if (!bpb->hds) + if (ckgeom(fname, ntracks, "drive heads") == -1) + return -1; + bpb->hds = ntracks; + if (!bpb->bsec) + bpb->bsec = size; + return 0; } diff --git a/sbin/newfs_msdos/mkfs_msdos.h b/sbin/newfs_msdos/mkfs_msdos.h index 1987636d9..ed31bd144 100644 --- a/sbin/newfs_msdos/mkfs_msdos.h +++ b/sbin/newfs_msdos/mkfs_msdos.h @@ -1,4 +1,4 @@ -/* $NetBSD: mkfs_msdos.h,v 1.2 2013/01/23 15:29:15 christos Exp $ */ +/* $NetBSD: mkfs_msdos.h,v 1.6 2017/02/17 09:29:35 wiz Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -15,9 +15,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -41,7 +38,7 @@ AOPT('C', off_t, create_size, 0, "Create file") \ AOPT('F', uint8_t, fat_type, 12, "FAT type (12, 16, or 32)") \ AOPT('I', uint32_t, volume_id, 0, "Volume ID") \ AOPT('L', char *, volume_label, -1, "Volume Label") \ -AOPT('N', bool, no_create, -2, "Don't create filesystem, print params only") \ +AOPT('N', bool, no_create, -2, "Don't create file system, print params only") \ AOPT('O', char *, OEM_string, -1, "OEM string") \ AOPT('S', uint16_t, bytes_per_sector, 1, "Bytes per sector") \ AOPT('a', uint32_t, sectors_per_fat, 1, "Sectors per FAT") \ @@ -63,6 +60,8 @@ struct msdos_options { #define AOPT(_opt, _type, _name, _min, _desc) _type _name; ALLOPTS #undef AOPT + time_t timestamp; + 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 cb39a20db..a848388c7 100644 --- a/sbin/newfs_msdos/newfs_msdos.8 +++ b/sbin/newfs_msdos/newfs_msdos.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: newfs_msdos.8,v 1.20 2014/04/24 23:49:40 christos Exp $ +.\" $NetBSD: newfs_msdos.8,v 1.23 2017/02/17 09:29:35 wiz Exp $ .\" .\" Copyright (c) 1998 Robert Nordier .\" All rights reserved. @@ -27,7 +27,7 @@ .\" .\" From: $FreeBSD: src/sbin/newfs_msdos/newfs_msdos.8,v 1.13 2001/08/14 10:01:48 ru Exp $ .\" -.Dd April 24, 2014 +.Dd February 16, 2017 .Dt NEWFS_MSDOS 8 .Os .Sh NAME @@ -57,6 +57,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 @@ -74,9 +75,9 @@ to determine geometry, if required. The options are as follow: .Bl -tag -width indent .It Fl N -Don't create a file system: just print out parameters. +Do not create a file system: just print out parameters. .It Fl @ Ar offset -Build the filesystem at the specified offset in bytes in the device or file. +Build the file system at the specified offset in bytes in the device or file. A suffix s, k, m, g (lower or upper case) appended to the offset specifies that the number is in sectors, kilobytes, megabytes or gigabytes, respectively. @@ -120,7 +121,7 @@ Sectors per cluster. Acceptable values are powers of 2 in the range 1 through 128. If the block or cluster size are not specified, the code uses a cluster between 512 bytes and 32K depending on -the filesystem size. +the file system size. .It Fl e Ar dirents Number of root directory entries (FAT12 and FAT16 only). .It Fl f Ar format @@ -147,6 +148,13 @@ Number of hidden sectors. Number of reserved sectors. .It Fl s Ar total File system size. +.It Fl T At timestamp +Specify a timestamp to be used for file system creation so that +it can be consistent for reproducible builds. +The timestamp can be a pathname, where the timestamps are derived from +that file, a parseable date for parsedate(3) (this option is not +yet available in the tools build), or an integer value interpreted +as the number of seconds from the Epoch. .It Fl u Ar track-size Number of sectors per track. .El @@ -174,7 +182,7 @@ option. When the geometry is not available, it is assumed to be 63 sectors, 255 heads. The size is then rounded to become -a multiple of the track size and avoid complaints by some filesystem code. +a multiple of the track size and avoid complaints by some file system code. .Pp FAT file system parameters occupy a "Boot Sector BPB (BIOS Parameter Block)" in the first of the "reserved" sectors which precede the actual @@ -233,6 +241,10 @@ Exit status is 0 on success and 1 on error. .Xr fdisk 8 , .Xr newfs 8 .Sh HISTORY +A +.Nm +utility appeared in +.Fx 3.0 . The .Nm command first appeared in diff --git a/sbin/newfs_msdos/newfs_msdos.c b/sbin/newfs_msdos/newfs_msdos.c index 6f7ca349c..9f333b4f9 100644 --- a/sbin/newfs_msdos/newfs_msdos.c +++ b/sbin/newfs_msdos/newfs_msdos.c @@ -1,4 +1,4 @@ -/* $NetBSD: newfs_msdos.c,v 1.43 2015/04/23 13:27:14 abs Exp $ */ +/* $NetBSD: newfs_msdos.c,v 1.45 2017/02/16 22:42:25 christos Exp $ */ /* * Copyright (c) 1998 Robert Nordier @@ -33,11 +33,12 @@ static const char rcsid[] = "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $"; #else -__RCSID("$NetBSD: newfs_msdos.c,v 1.43 2015/04/23 13:27:14 abs Exp $"); +__RCSID("$NetBSD: newfs_msdos.c,v 1.45 2017/02/16 22:42:25 christos Exp $"); #endif #endif /* not lint */ #include +#include #include #include #include @@ -45,6 +46,7 @@ __RCSID("$NetBSD: newfs_msdos.c,v 1.43 2015/04/23 13:27:14 abs Exp $"); #include #include #include +#include #include "mkfs_msdos.h" @@ -57,13 +59,38 @@ __dead static void usage(void); static u_int argtou(const char *, u_int, u_int, const char *); static off_t argtooff(const char *, const char *); +static time_t +get_tstamp(const char *b) +{ + struct stat st; + char *eb; + long long l; +#ifndef HAVE_NBTOOL_CONFIG_H + time_t when; +#endif + + if (stat(b, &st) != -1) + return (time_t)st.st_mtime; + +#ifndef HAVE_NBTOOL_CONFIG_H + errno = 0; + if ((when = parsedate(b, NULL, NULL)) != -1 || errno == 0) + return when; +#endif + 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; char *fname, *dtype; char buf[MAXPATHLEN]; @@ -142,6 +169,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.44.0