| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: mkfs_msdos.c,v 1.4 2013/01/24 00:10:09 christos Exp $ */ | | 1 | /* $NetBSD: mkfs_msdos.c,v 1.5 2013/01/24 19:24:56 christos Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1998 Robert Nordier | | 4 | * Copyright (c) 1998 Robert Nordier |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in | | 13 | * notice, this list of conditions and the following disclaimer in |
14 | * the documentation and/or other materials provided with the | | 14 | * the documentation and/or other materials provided with the |
| @@ -17,59 +17,67 @@ | | | @@ -17,59 +17,67 @@ |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS | | 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS |
18 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | | 18 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY | | 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY |
21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
23 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 23 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | | 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
25 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | | 25 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
26 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | | 26 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
| | | 30 | #if HAVE_NBTOOL_CONFIG_H |
| | | 31 | #include "nbtool_config.h" |
| | | 32 | #endif |
| | | 33 | |
30 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
31 | #ifndef lint | | 35 | #ifndef lint |
32 | #if 0 | | 36 | #if 0 |
33 | static const char rcsid[] = | | 37 | static const char rcsid[] = |
34 | "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $"; | | 38 | "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $"; |
35 | #else | | 39 | #else |
36 | __RCSID("$NetBSD: mkfs_msdos.c,v 1.4 2013/01/24 00:10:09 christos Exp $"); | | 40 | __RCSID("$NetBSD: mkfs_msdos.c,v 1.5 2013/01/24 19:24:56 christos Exp $"); |
37 | #endif | | 41 | #endif |
38 | #endif /* not lint */ | | 42 | #endif /* not lint */ |
39 | | | 43 | |
40 | #include <sys/types.h> | | 44 | #include <sys/types.h> |
41 | #include <sys/param.h> | | 45 | #include <sys/param.h> |
42 | #include <sys/mount.h> | | 46 | #include <sys/mount.h> |
43 | #include <sys/stat.h> | | 47 | #include <sys/stat.h> |
44 | #include <sys/time.h> | | 48 | #include <sys/time.h> |
| | | 49 | #ifndef MAKEFS |
45 | #include <sys/disk.h> | | 50 | #include <sys/disk.h> |
| | | 51 | #endif |
46 | | | 52 | |
47 | #include <ctype.h> | | 53 | #include <ctype.h> |
48 | #include <err.h> | | 54 | #include <err.h> |
49 | #include <errno.h> | | 55 | #include <errno.h> |
50 | #include <fcntl.h> | | 56 | #include <fcntl.h> |
51 | #include <paths.h> | | 57 | #include <paths.h> |
52 | #include <stdio.h> | | 58 | #include <stdio.h> |
53 | #include <stdlib.h> | | 59 | #include <stdlib.h> |
54 | #include <string.h> | | 60 | #include <string.h> |
55 | #include <time.h> | | 61 | #include <time.h> |
56 | #include <unistd.h> | | 62 | #include <unistd.h> |
57 | #include <signal.h> | | 63 | #include <signal.h> |
58 | | | 64 | |
59 | #include <util.h> | | 65 | #include <util.h> |
60 | #include <disktab.h> | | 66 | #include <disktab.h> |
61 | | | 67 | |
| | | 68 | #ifndef MAKEFS |
62 | #include "partutil.h" | | 69 | #include "partutil.h" |
| | | 70 | #endif |
63 | #include "mkfs_msdos.h" | | 71 | #include "mkfs_msdos.h" |
64 | | | 72 | |
65 | #define MAXU16 0xffff /* maximum unsigned 16-bit quantity */ | | 73 | #define MAXU16 0xffff /* maximum unsigned 16-bit quantity */ |
66 | #define BPN 4 /* bits per nibble */ | | 74 | #define BPN 4 /* bits per nibble */ |
67 | #define NPB 2 /* nibbles per byte */ | | 75 | #define NPB 2 /* nibbles per byte */ |
68 | | | 76 | |
69 | #define DOSMAGIC 0xaa55 /* DOS magic number */ | | 77 | #define DOSMAGIC 0xaa55 /* DOS magic number */ |
70 | #define MINBPS 512 /* minimum bytes per sector */ | | 78 | #define MINBPS 512 /* minimum bytes per sector */ |
71 | #define MAXSPC 128 /* maximum sectors per cluster */ | | 79 | #define MAXSPC 128 /* maximum sectors per cluster */ |
72 | #define MAXNFT 16 /* maximum number of FATs */ | | 80 | #define MAXNFT 16 /* maximum number of FATs */ |
73 | #define DEFBLK 4096 /* default block size */ | | 81 | #define DEFBLK 4096 /* default block size */ |
74 | #define DEFBLK16 2048 /* default block size FAT16 */ | | 82 | #define DEFBLK16 2048 /* default block size FAT16 */ |
75 | #define DEFRDE 512 /* default root directory entries */ | | 83 | #define DEFRDE 512 /* default root directory entries */ |
| @@ -213,27 +221,29 @@ static u_int8_t bootcode[] = { | | | @@ -213,27 +221,29 @@ static u_int8_t bootcode[] = { |
213 | 0x0d, 0x0a, | | 221 | 0x0d, 0x0a, |
214 | 'N', 'o', 'n', '-', 's', 'y', 's', 't', | | 222 | 'N', 'o', 'n', '-', 's', 'y', 's', 't', |
215 | 'e', 'm', ' ', 'd', 'i', 's', 'k', | | 223 | 'e', 'm', ' ', 'd', 'i', 's', 'k', |
216 | 0x0d, 0x0a, | | 224 | 0x0d, 0x0a, |
217 | 'P', 'r', 'e', 's', 's', ' ', 'a', 'n', | | 225 | 'P', 'r', 'e', 's', 's', ' ', 'a', 'n', |
218 | 'y', ' ', 'k', 'e', 'y', ' ', 't', 'o', | | 226 | 'y', ' ', 'k', 'e', 'y', ' ', 't', 'o', |
219 | ' ', 'r', 'e', 'b', 'o', 'o', 't', | | 227 | ' ', 'r', 'e', 'b', 'o', 'o', 't', |
220 | 0x0d, 0x0a, | | 228 | 0x0d, 0x0a, |
221 | 0 | | 229 | 0 |
222 | }; | | 230 | }; |
223 | | | 231 | |
224 | static int got_siginfo = 0; /* received a SIGINFO */ | | 232 | static int got_siginfo = 0; /* received a SIGINFO */ |
225 | | | 233 | |
| | | 234 | #ifndef MAKEFS |
226 | static int check_mounted(const char *, mode_t); | | 235 | static int check_mounted(const char *, mode_t); |
| | | 236 | #endif |
227 | static int getstdfmt(const char *, struct bpb *); | | 237 | static int getstdfmt(const char *, struct bpb *); |
228 | static int getbpbinfo(int, const char *, const char *, int, struct bpb *, int); | | 238 | static int getbpbinfo(int, const char *, const char *, int, struct bpb *, int); |
229 | static void print_bpb(struct bpb *); | | 239 | static void print_bpb(struct bpb *); |
230 | static int ckgeom(const char *, u_int, const char *); | | 240 | static int ckgeom(const char *, u_int, const char *); |
231 | static int oklabel(const char *); | | 241 | static int oklabel(const char *); |
232 | static void mklabel(u_int8_t *, const char *); | | 242 | static void mklabel(u_int8_t *, const char *); |
233 | static void setstr(u_int8_t *, const char *, size_t); | | 243 | static void setstr(u_int8_t *, const char *, size_t); |
234 | static void infohandler(int sig); | | 244 | static void infohandler(int sig); |
235 | | | 245 | |
236 | int | | 246 | int |
237 | mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) | | 247 | mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) |
238 | { | | 248 | { |
239 | char buf[MAXPATHLEN]; | | 249 | char buf[MAXPATHLEN]; |
| @@ -274,29 +284,31 @@ mkfs_msdos(const char *fname, const char | | | @@ -274,29 +284,31 @@ mkfs_msdos(const char *fname, const char |
274 | return -1; | | 284 | return -1; |
275 | } | | 285 | } |
276 | pos = lseek(fd, o.create_size - 1, SEEK_SET); | | 286 | pos = lseek(fd, o.create_size - 1, SEEK_SET); |
277 | if (write(fd, "\0", 1) != 1) { | | 287 | if (write(fd, "\0", 1) != 1) { |
278 | warn("failed to set file size"); | | 288 | warn("failed to set file size"); |
279 | return -1; | | 289 | return -1; |
280 | } | | 290 | } |
281 | pos = lseek(fd, 0, SEEK_SET); | | 291 | pos = lseek(fd, 0, SEEK_SET); |
282 | } else if ((fd = open(fname, o.no_create ? O_RDONLY : O_RDWR)) == -1 || | | 292 | } else if ((fd = open(fname, o.no_create ? O_RDONLY : O_RDWR)) == -1 || |
283 | fstat(fd, &sb)) { | | 293 | fstat(fd, &sb)) { |
284 | warn("%s", fname); | | 294 | warn("%s", fname); |
285 | return -1; | | 295 | return -1; |
286 | } | | 296 | } |
| | | 297 | #ifndef MAKEFS |
287 | if (!o.no_create) | | 298 | if (!o.no_create) |
288 | if (check_mounted(fname, sb.st_mode) == -1) | | 299 | if (check_mounted(fname, sb.st_mode) == -1) |
289 | return -1; | | 300 | return -1; |
| | | 301 | #endif |
290 | if (!S_ISCHR(sb.st_mode) && !o.create_size) { | | 302 | if (!S_ISCHR(sb.st_mode) && !o.create_size) { |
291 | warnx("warning, %s is not a character device", fname); | | 303 | warnx("warning, %s is not a character device", fname); |
292 | return -1; | | 304 | return -1; |
293 | } | | 305 | } |
294 | if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) { | | 306 | if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) { |
295 | warnx("cannot seek to %jd", (intmax_t)o.offset); | | 307 | warnx("cannot seek to %jd", (intmax_t)o.offset); |
296 | return -1; | | 308 | return -1; |
297 | } | | 309 | } |
298 | memset(&bpb, 0, sizeof(bpb)); | | 310 | memset(&bpb, 0, sizeof(bpb)); |
299 | if (o.floppy) { | | 311 | if (o.floppy) { |
300 | if (getstdfmt(o.floppy, &bpb) == -1) | | 312 | if (getstdfmt(o.floppy, &bpb) == -1) |
301 | return -1; | | 313 | return -1; |
302 | bpb.bsec = bpb.sec; | | 314 | bpb.bsec = bpb.sec; |
| @@ -593,27 +605,29 @@ mkfs_msdos(const char *fname, const char | | | @@ -593,27 +605,29 @@ mkfs_msdos(const char *fname, const char |
593 | * ? | | 605 | * ? |
594 | */ | | 606 | */ |
595 | } | | 607 | } |
596 | if (ch != 0) | | 608 | if (ch != 0) |
597 | printf("MBR type: %d\n", ch); | | 609 | printf("MBR type: %d\n", ch); |
598 | print_bpb(&bpb); | | 610 | print_bpb(&bpb); |
599 | if (!o.no_create) { | | 611 | if (!o.no_create) { |
600 | gettimeofday(&tv, NULL); | | 612 | gettimeofday(&tv, NULL); |
601 | now = tv.tv_sec; | | 613 | now = tv.tv_sec; |
602 | tm = localtime(&now); | | 614 | tm = localtime(&now); |
603 | if (!(img = malloc(bpb.bps))) | | 615 | if (!(img = malloc(bpb.bps))) |
604 | err(1, NULL); | | 616 | err(1, NULL); |
605 | dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft; | | 617 | dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft; |
| | | 618 | #ifdef SIGINFO |
606 | signal(SIGINFO, infohandler); | | 619 | signal(SIGINFO, infohandler); |
| | | 620 | #endif |
607 | for (lsn = 0; lsn < dir + (o.fat_type == 32 ? bpb.spc : rds); lsn++) { | | 621 | for (lsn = 0; lsn < dir + (o.fat_type == 32 ? bpb.spc : rds); lsn++) { |
608 | if (got_siginfo) { | | 622 | if (got_siginfo) { |
609 | fprintf(stderr,"%s: writing sector %u of %u (%u%%)\n", | | 623 | fprintf(stderr,"%s: writing sector %u of %u (%u%%)\n", |
610 | fname,lsn,(dir + (o.fat_type == 32 ? bpb.spc : rds)), | | 624 | fname,lsn,(dir + (o.fat_type == 32 ? bpb.spc : rds)), |
611 | (lsn*100)/(dir + (o.fat_type == 32 ? bpb.spc : rds))); | | 625 | (lsn*100)/(dir + (o.fat_type == 32 ? bpb.spc : rds))); |
612 | got_siginfo = 0; | | 626 | got_siginfo = 0; |
613 | } | | 627 | } |
614 | x = lsn; | | 628 | x = lsn; |
615 | if (o.bootstrap && | | 629 | if (o.bootstrap && |
616 | o.fat_type == 32 && bpb.bkbs != MAXU16 && | | 630 | o.fat_type == 32 && bpb.bkbs != MAXU16 && |
617 | bss <= bpb.bkbs && x >= bpb.bkbs) { | | 631 | bss <= bpb.bkbs && x >= bpb.bkbs) { |
618 | x -= bpb.bkbs; | | 632 | x -= bpb.bkbs; |
619 | if (!x && lseek(fd1, o.offset, SEEK_SET)) { | | 633 | if (!x && lseek(fd1, o.offset, SEEK_SET)) { |
| @@ -717,26 +731,27 @@ mkfs_msdos(const char *fname, const char | | | @@ -717,26 +731,27 @@ mkfs_msdos(const char *fname, const char |
717 | if ((n = write(fd, img, bpb.bps)) == -1) { | | 731 | if ((n = write(fd, img, bpb.bps)) == -1) { |
718 | warn("%s", fname); | | 732 | warn("%s", fname); |
719 | return -1; | | 733 | return -1; |
720 | } | | 734 | } |
721 | if ((size_t)n != bpb.bps) { | | 735 | if ((size_t)n != bpb.bps) { |
722 | warnx("%s: can't write sector %u", fname, lsn); | | 736 | warnx("%s: can't write sector %u", fname, lsn); |
723 | return -1; | | 737 | return -1; |
724 | } | | 738 | } |
725 | } | | 739 | } |
726 | } | | 740 | } |
727 | return 0; | | 741 | return 0; |
728 | } | | 742 | } |
729 | | | 743 | |
| | | 744 | #ifndef MAKEFS |
730 | /* | | 745 | /* |
731 | * return -1 with error if file system is mounted. | | 746 | * return -1 with error if file system is mounted. |
732 | */ | | 747 | */ |
733 | static int | | 748 | static int |
734 | check_mounted(const char *fname, mode_t mode) | | 749 | check_mounted(const char *fname, mode_t mode) |
735 | { | | 750 | { |
736 | struct statvfs *mp; | | 751 | struct statvfs *mp; |
737 | const char *s1, *s2; | | 752 | const char *s1, *s2; |
738 | size_t len; | | 753 | size_t len; |
739 | int n, r; | | 754 | int n, r; |
740 | | | 755 | |
741 | if (!(n = getmntinfo(&mp, MNT_NOWAIT))) { | | 756 | if (!(n = getmntinfo(&mp, MNT_NOWAIT))) { |
742 | warn("getmntinfo"); | | 757 | warn("getmntinfo"); |
| @@ -749,121 +764,131 @@ check_mounted(const char *fname, mode_t | | | @@ -749,121 +764,131 @@ check_mounted(const char *fname, mode_t |
749 | r = S_ISCHR(mode) && s1 != fname && *s1 == 'r'; | | 764 | r = S_ISCHR(mode) && s1 != fname && *s1 == 'r'; |
750 | for (; n--; mp++) { | | 765 | for (; n--; mp++) { |
751 | s2 = mp->f_mntfromname; | | 766 | s2 = mp->f_mntfromname; |
752 | if (!strncmp(s2, _PATH_DEV, len)) | | 767 | if (!strncmp(s2, _PATH_DEV, len)) |
753 | s2 += len; | | 768 | s2 += len; |
754 | if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) || | | 769 | if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) || |
755 | !strcmp(s1, s2)) { | | 770 | !strcmp(s1, s2)) { |
756 | warnx("%s is mounted on %s", fname, mp->f_mntonname); | | 771 | warnx("%s is mounted on %s", fname, mp->f_mntonname); |
757 | return -1; | | 772 | return -1; |
758 | } | | 773 | } |
759 | } | | 774 | } |
760 | return 0; | | 775 | return 0; |
761 | } | | 776 | } |
| | | 777 | #endif |
762 | | | 778 | |
763 | /* | | 779 | /* |
764 | * Get a standard format. | | 780 | * Get a standard format. |
765 | */ | | 781 | */ |
766 | static int | | 782 | static int |
767 | getstdfmt(const char *fmt, struct bpb *bpb) | | 783 | getstdfmt(const char *fmt, struct bpb *bpb) |
768 | { | | 784 | { |
769 | u_int x, i; | | 785 | u_int x, i; |
770 | | | 786 | |
771 | x = sizeof(stdfmt) / sizeof(stdfmt[0]); | | 787 | x = sizeof(stdfmt) / sizeof(stdfmt[0]); |
772 | for (i = 0; i < x && strcmp(fmt, stdfmt[i].name); i++); | | 788 | for (i = 0; i < x && strcmp(fmt, stdfmt[i].name); i++); |
773 | if (i == x) { | | 789 | if (i == x) { |
774 | warnx("%s: unknown standard format", fmt); | | 790 | warnx("%s: unknown standard format", fmt); |
775 | return -1; | | 791 | return -1; |
776 | } | | 792 | } |
777 | *bpb = stdfmt[i].bpb; | | 793 | *bpb = stdfmt[i].bpb; |
778 | return 0; | | 794 | return 0; |
779 | } | | 795 | } |
780 | | | 796 | |
781 | /* | | 797 | /* |
782 | * Get disk slice, partition, and geometry information. | | 798 | * Get disk slice, partition, and geometry information. |
783 | */ | | 799 | */ |
784 | static int | | 800 | static int |
785 | getbpbinfo(int fd, const char *fname, const char *dtype, int iflag, | | 801 | getbpbinfo(int fd, const char *fname, const char *dtype, int iflag, |
786 | struct bpb *bpb, int create) | | 802 | struct bpb *bpb, int create) |
787 | { | | 803 | { |
788 | struct disk_geom geo; | | | |
789 | struct dkwedge_info dkw; | | | |
790 | const char *s1, *s2; | | 804 | const char *s1, *s2; |
791 | int part; | | 805 | int part; |
792 | | | 806 | |
793 | part = -1; | | 807 | part = -1; |
794 | s1 = fname; | | 808 | s1 = fname; |
795 | if ((s2 = strrchr(s1, '/'))) | | 809 | if ((s2 = strrchr(s1, '/'))) |
796 | s1 = s2 + 1; | | 810 | s1 = s2 + 1; |
797 | for (s2 = s1; *s2 && !isdigit((unsigned char)*s2); s2++); | | 811 | for (s2 = s1; *s2 && !isdigit((unsigned char)*s2); s2++); |
798 | if (!*s2 || s2 == s1) | | 812 | if (!*s2 || s2 == s1) |
799 | s2 = NULL; | | 813 | s2 = NULL; |
800 | else | | 814 | else |
801 | while (isdigit((unsigned char)*++s2)); | | 815 | while (isdigit((unsigned char)*++s2)); |
802 | s1 = s2; | | 816 | s1 = s2; |
803 | | | 817 | |
804 | #ifndef MAKEFS | | 818 | #ifndef MAKEFS |
805 | int maxpartitions = getmaxpartitions(); | | 819 | int maxpartitions = getmaxpartitions(); |
806 | | | 820 | |
807 | // XXX: Does not work with wedges | | 821 | // XXX: Does not work with wedges |
808 | if (s2 && *s2 >= 'a' && *s2 <= 'a' + maxpartitions - 1) { | | 822 | if (s2 && *s2 >= 'a' && *s2 <= 'a' + maxpartitions - 1) { |
809 | part = *s2++ - 'a'; | | 823 | part = *s2++ - 'a'; |
810 | } | | 824 | } |
811 | #endif | | 825 | #endif |
812 | if (((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) || | | 826 | if (((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) || |
813 | !bpb->bps || !bpb->spt || !bpb->hds) { | | 827 | !bpb->bps || !bpb->spt || !bpb->hds) { |
814 | if (create | | 828 | u_int sector_size; |
| | | 829 | u_int nsectors; |
| | | 830 | u_int ntracks; |
| | | 831 | u_int size; |
815 | #ifndef MAKEFS | | 832 | #ifndef MAKEFS |
816 | || getdiskinfo(fname, fd, NULL, &geo, &dkw) == -1 | | 833 | struct disk_geom geo; |
| | | 834 | struct dkwedge_info dkw; |
| | | 835 | |
| | | 836 | if (!create && getdiskinfo(fname, fd, NULL, &geo, &dkw) != -1) { |
| | | 837 | sector_size = geo.dg_secsize = 512; |
| | | 838 | nsectors = geo.dg_nsectors = 63; |
| | | 839 | ntracks = geo.dg_ntracks = 255; |
| | | 840 | size = dkw.dkw_size; |
| | | 841 | } else |
817 | #endif | | 842 | #endif |
818 | ) { | | 843 | { |
819 | struct stat st; | | 844 | struct stat st; |
820 | | | 845 | |
821 | if (fstat(fd, &st) == -1) { | | 846 | if (fstat(fd, &st) == -1) { |
822 | warnx("Can't get disk size for `%s'", fname); | | 847 | warnx("Can't get disk size for `%s'", fname); |
823 | return -1; | | 848 | return -1; |
824 | } | | 849 | } |
825 | /* create a fake geometry for a file image */ | | 850 | /* create a fake geometry for a file image */ |
826 | geo.dg_secsize = 512; | | 851 | sector_size = 512; |
827 | geo.dg_nsectors = 63; | | 852 | nsectors = 63; |
828 | geo.dg_ntracks = 255; | | 853 | ntracks = 255; |
829 | dkw.dkw_size = st.st_size / geo.dg_secsize; | | 854 | size = st.st_size / sector_size; |
830 | } | | 855 | } |
831 | if (!bpb->bps) { | | 856 | if (!bpb->bps) { |
832 | if (ckgeom(fname, geo.dg_secsize, "bytes/sector") == -1) | | 857 | if (ckgeom(fname, sector_size, "bytes/sector") == -1) |
833 | return -1; | | 858 | return -1; |
834 | bpb->bps = geo.dg_secsize; | | 859 | bpb->bps = sector_size; |
835 | } | | 860 | } |
836 | | | 861 | |
837 | if (geo.dg_nsectors > 63) { | | 862 | if (nsectors > 63) { |
838 | /* | | 863 | /* |
839 | * The kernel doesn't accept BPB with spt > 63. | | 864 | * The kernel doesn't accept BPB with spt > 63. |
840 | * (see sys/fs/msdosfs/msdosfs_vfsops.c:msdosfs_mountfs()) | | 865 | * (see sys/fs/msdosfs/msdosfs_vfsops.c:msdosfs_mountfs()) |
841 | * If values taken from disklabel don't match these | | 866 | * If values taken from disklabel don't match these |
842 | * restrictions, use popular BIOS default values instead. | | 867 | * restrictions, use popular BIOS default values instead. |
843 | */ | | 868 | */ |
844 | geo.dg_nsectors = 63; | | 869 | nsectors = 63; |
845 | } | | 870 | } |
846 | if (!bpb->spt) { | | 871 | if (!bpb->spt) { |
847 | if (ckgeom(fname, geo.dg_nsectors, "sectors/track") == -1) | | 872 | if (ckgeom(fname, nsectors, "sectors/track") == -1) |
848 | return -1; | | 873 | return -1; |
849 | bpb->spt = geo.dg_nsectors; | | 874 | bpb->spt = nsectors; |
850 | } | | 875 | } |
851 | if (!bpb->hds) | | 876 | if (!bpb->hds) |
852 | if (ckgeom(fname, geo.dg_ntracks, "drive heads") == -1) | | 877 | if (ckgeom(fname, ntracks, "drive heads") == -1) |
853 | return -1; | | 878 | return -1; |
854 | bpb->hds = geo.dg_ntracks; | | 879 | bpb->hds = ntracks; |
855 | if (!bpb->bsec) | | 880 | if (!bpb->bsec) |
856 | bpb->bsec = dkw.dkw_size; | | 881 | bpb->bsec = size; |
857 | } | | 882 | } |
858 | return 0; | | 883 | return 0; |
859 | } | | 884 | } |
860 | | | 885 | |
861 | /* | | 886 | /* |
862 | * Print out BPB values. | | 887 | * Print out BPB values. |
863 | */ | | 888 | */ |
864 | static void | | 889 | static void |
865 | print_bpb(struct bpb *bpb) | | 890 | print_bpb(struct bpb *bpb) |
866 | { | | 891 | { |
867 | printf("bps=%u spc=%u res=%u nft=%u", bpb->bps, bpb->spc, bpb->res, | | 892 | printf("bps=%u spc=%u res=%u nft=%u", bpb->bps, bpb->spc, bpb->res, |
868 | bpb->nft); | | 893 | bpb->nft); |
869 | if (bpb->rde) | | 894 | if (bpb->rde) |