Bug Summary

File:src/sbin/newfs_msdos/newfs_msdos.c
Warning:line 661, column 12
Potential leak of memory pointed to by 'img'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name newfs_msdos.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/newfs_msdos/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/newfs_msdos/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/newfs_msdos/newfs_msdos.c
1/* $OpenBSD: newfs_msdos.c,v 1.28 2021/07/11 15:39:58 kettenis Exp $ */
2
3/*
4 * Copyright (c) 1998 Robert Nordier
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
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
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <sys/param.h> /* powerof2 */
31#include <sys/stat.h>
32#include <sys/disklabel.h>
33#include <sys/ioctl.h>
34#include <sys/dkio.h>
35#include <sys/mount.h>
36
37#include <ctype.h>
38#include <err.h>
39#include <errno(*__errno()).h>
40#include <fcntl.h>
41#include <paths.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46#include <limits.h>
47#include <util.h>
48
49#define MINIMUM(a, b)(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b))
50#define MAXIMUM(a, b)(((a) > (b)) ? (a) : (b)) (((a) > (b)) ? (a) : (b))
51
52#define MAXU160xffff 0xffff /* maximum unsigned 16-bit quantity */
53#define BPN4 4 /* bits per nibble */
54#define NPB2 2 /* nibbles per byte */
55
56#define DOSMAGIC0xaa55 0xaa55 /* DOS magic number */
57#define MINBPS512 512 /* minimum bytes per sector */
58#define MAXSPC128 128 /* maximum sectors per cluster */
59#define MAXNFT16 16 /* maximum number of FATs */
60#define DEFBLK4096 4096 /* default block size */
61#define DEFBLK162048 2048 /* default block size FAT16 */
62#define DEFRDE512 512 /* default root directory entries */
63#define RESFTE2 2 /* reserved FAT entries */
64#define MINCLS121 1 /* minimum FAT12 clusters */
65#define MINCLS160xff5 0xff5 /* minimum FAT16 clusters */
66#define MINCLS320xfff5 0xfff5 /* minimum FAT32 clusters */
67#define MAXCLS120xff4 0xff4 /* maximum FAT12 clusters */
68#define MAXCLS160xfff4 0xfff4 /* maximum FAT16 clusters */
69#define MAXCLS320xffffff4 0xffffff4 /* maximum FAT32 clusters */
70
71#define mincls(fat)((fat) == 12 ? 1 : (fat) == 16 ? 0xff5 : 0xfff5) ((fat) == 12 ? MINCLS121 : \
72 (fat) == 16 ? MINCLS160xff5 : \
73 MINCLS320xfff5)
74
75#define maxcls(fat)((fat) == 12 ? 0xff4 : (fat) == 16 ? 0xfff4 : 0xffffff4) ((fat) == 12 ? MAXCLS120xff4 : \
76 (fat) == 16 ? MAXCLS160xfff4 : \
77 MAXCLS320xffffff4)
78
79#define mk1(p, x)(p) = (u_int8_t)(x) \
80 (p) = (u_int8_t)(x)
81
82#define mk2(p, x)(p)[0] = (u_int8_t)(x), (p)[1] = (u_int8_t)((x) >> 010) \
83 (p)[0] = (u_int8_t)(x), \
84 (p)[1] = (u_int8_t)((x) >> 010)
85
86#define mk4(p, x)(p)[0] = (u_int8_t)(x), (p)[1] = (u_int8_t)((x) >> 010)
, (p)[2] = (u_int8_t)((x) >> 020), (p)[3] = (u_int8_t)(
(x) >> 030)
\
87 (p)[0] = (u_int8_t)(x), \
88 (p)[1] = (u_int8_t)((x) >> 010), \
89 (p)[2] = (u_int8_t)((x) >> 020), \
90 (p)[3] = (u_int8_t)((x) >> 030)
91
92#define argto1(arg, lo, msg)argtou(arg, lo, 0xff, msg) argtou(arg, lo, 0xff, msg)
93#define argto2(arg, lo, msg)argtou(arg, lo, 0xffff, msg) argtou(arg, lo, 0xffff, msg)
94#define argto4(arg, lo, msg)argtou(arg, lo, 0xffffffff, msg) argtou(arg, lo, 0xffffffff, msg)
95#define argtox(arg, lo, msg)argtou(arg, lo, (2147483647 *2U +1U), msg) argtou(arg, lo, UINT_MAX(2147483647 *2U +1U), msg)
96
97struct bs {
98 u_int8_t jmp[3]; /* bootstrap entry point */
99 u_int8_t oem[8]; /* OEM name and version */
100};
101
102struct bsbpb {
103 u_int8_t bps[2]; /* bytes per sector */
104 u_int8_t spc; /* sectors per cluster */
105 u_int8_t res[2]; /* reserved sectors */
106 u_int8_t nft; /* number of FATs */
107 u_int8_t rde[2]; /* root directory entries */
108 u_int8_t sec[2]; /* total sectors */
109 u_int8_t mid; /* media descriptor */
110 u_int8_t spf[2]; /* sectors per FAT */
111 u_int8_t spt[2]; /* sectors per track */
112 u_int8_t hds[2]; /* drive heads */
113 u_int8_t hid[4]; /* hidden sectors */
114 u_int8_t bsec[4]; /* big total sectors */
115};
116
117struct bsxbpb {
118 u_int8_t bspf[4]; /* big sectors per FAT */
119 u_int8_t xflg[2]; /* FAT control flags */
120 u_int8_t vers[2]; /* file system version */
121 u_int8_t rdcl[4]; /* root directory start cluster */
122 u_int8_t infs[2]; /* file system info sector */
123 u_int8_t bkbs[2]; /* backup boot sector */
124 u_int8_t rsvd[12]; /* reserved */
125};
126
127struct bsx {
128 u_int8_t drv; /* drive number */
129 u_int8_t rsvd; /* reserved */
130 u_int8_t sig; /* extended boot signature */
131 u_int8_t volid[4]; /* volume ID number */
132 u_int8_t label[11]; /* volume label */
133 u_int8_t type[8]; /* file system type */
134};
135
136struct de {
137 u_int8_t namext[11]; /* name and extension */
138 u_int8_t attr; /* attributes */
139 u_int8_t rsvd[10]; /* reserved */
140 u_int8_t time[2]; /* creation time */
141 u_int8_t date[2]; /* creation date */
142 u_int8_t clus[2]; /* starting cluster */
143 u_int8_t size[4]; /* size */
144};
145
146struct bpb {
147 u_int bps; /* bytes per sector */
148 u_int spc; /* sectors per cluster */
149 u_int res; /* reserved sectors */
150 u_int nft; /* number of FATs */
151 u_int rde; /* root directory entries */
152 u_int sec; /* total sectors */
153 u_int mid; /* media descriptor */
154 u_int spf; /* sectors per FAT */
155 u_int spt; /* sectors per track */
156 u_int hds; /* drive heads */
157 u_int hid; /* hidden sectors */
158 u_int bsec; /* big total sectors */
159 u_int bspf; /* big sectors per FAT */
160 u_int rdcl; /* root directory start cluster */
161 u_int infs; /* file system info sector */
162 u_int bkbs; /* backup boot sector */
163};
164
165static struct {
166 const char *name;
167 struct bpb bpb;
168} stdfmt[] = {
169 {"160", {512, 1, 1, 2, 64, 320, 0xfe, 1, 8, 1}},
170 {"180", {512, 1, 1, 2, 64, 360, 0xfc, 2, 9, 1}},
171 {"320", {512, 2, 1, 2, 112, 640, 0xff, 1, 8, 2}},
172 {"360", {512, 2, 1, 2, 112, 720, 0xfd, 2, 9, 2}},
173 {"720", {512, 2, 1, 2, 112, 1440, 0xf9, 3, 9, 2}},
174 {"1200", {512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2}},
175 {"1440", {512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2}},
176 {"2880", {512, 2, 1, 2, 240, 5760, 0xf0, 9, 36, 2}}
177};
178
179static u_int8_t bootcode[] = {
180 0xfa, /* cli */
181 0x31, 0xc0, /* xor ax,ax */
182 0x8e, 0xd0, /* mov ss,ax */
183 0xbc, 0x00, 0x7c, /* mov sp,7c00h */
184 0xfb, /* sti */
185 0x8e, 0xd8, /* mov ds,ax */
186 0xe8, 0x00, 0x00, /* call $ + 3 */
187 0x5e, /* pop si */
188 0x83, 0xc6, 0x19, /* add si,+19h */
189 0xbb, 0x07, 0x00, /* mov bx,0007h */
190 0xfc, /* cld */
191 0xac, /* lodsb */
192 0x84, 0xc0, /* test al,al */
193 0x74, 0x06, /* jz $ + 8 */
194 0xb4, 0x0e, /* mov ah,0eh */
195 0xcd, 0x10, /* int 10h */
196 0xeb, 0xf5, /* jmp $ - 9 */
197 0x30, 0xe4, /* xor ah,ah */
198 0xcd, 0x16, /* int 16h */
199 0xcd, 0x19, /* int 19h */
200 0x0d, 0x0a,
201 'N', 'o', 'n', '-', 's', 'y', 's', 't',
202 'e', 'm', ' ', 'd', 'i', 's', 'k',
203 0x0d, 0x0a,
204 'P', 'r', 'e', 's', 's', ' ', 'a', 'n',
205 'y', ' ', 'k', 'e', 'y', ' ', 't', 'o',
206 ' ', 'r', 'e', 'b', 'o', 'o', 't',
207 0x0d, 0x0a,
208 0
209};
210
211static void check_mounted(const char *, mode_t);
212static void getstdfmt(const char *, struct bpb *);
213static void getdiskinfo(int, const char *, const char *, int,
214 struct bpb *);
215static void print_bpb(struct bpb *);
216static u_int ckgeom(const char *, u_int, const char *);
217static u_int argtou(const char *, u_int, u_int, const char *);
218static int oklabel(const char *);
219static void mklabel(u_int8_t *, const char *);
220static void setstr(u_int8_t *, const char *, size_t);
221static __dead__attribute__((__noreturn__)) void usage(void);
222
223/*
224 * Construct a FAT12, FAT16, or FAT32 file system.
225 */
226int
227main(int argc, char *argv[])
228{
229 static char opts[] = "NB:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:qr:s:t:u:";
230 static const char *opt_B, *opt_L, *opt_O, *opt_f;
231 static u_int opt_F, opt_I, opt_S, opt_a, opt_b, opt_c, opt_e;
232 static u_int opt_h, opt_i, opt_k, opt_m, opt_n, opt_o, opt_r;
233 static u_int opt_s, opt_u;
234 static int opt_N;
235 static int Iflag, mflag, oflag;
236 char buf[PATH_MAX1024];
237 struct stat sb;
238 struct timeval tv;
239 struct bpb bpb;
240 struct tm *tm;
241 struct bs *bs;
242 struct bsbpb *bsbpb;
243 struct bsxbpb *bsxbpb;
244 struct bsx *bsx;
245 struct de *de;
246 u_int8_t *img;
247 const char *dtype, *bname;
248 char *sname, *fname;
249 ssize_t n;
250 time_t now;
251 u_int fat, bss, rds, cls, dir, lsn, x, x1, x2;
252 int ch, fd, fd1;
253
254 if (pledge("stdio rpath wpath disklabel", NULL((void *)0)) == -1)
1
Assuming the condition is false
2
Taking false branch
255 err(1, "pledge");
256
257 while ((ch = getopt(argc, argv, opts)) != -1)
3
Assuming the condition is false
4
Loop condition is false. Execution continues on line 340
258 switch (ch) {
259 case 'N':
260 opt_N = 1;
261 break;
262 case 'B':
263 opt_B = optarg;
264 break;
265 case 'F':
266 opt_F = strtonum(optarg, 1, INT_MAX2147483647, NULL((void *)0));
267 if (!(opt_F == 12 || opt_F == 16 || opt_F == 32))
268 errx(1, "%s: bad FAT type", optarg);
269 break;
270 case 'I':
271 opt_I = argto4(optarg, 0, "volume ID")argtou(optarg, 0, 0xffffffff, "volume ID");
272 Iflag = 1;
273 break;
274 case 'L':
275 if (!oklabel(optarg))
276 errx(1, "%s: bad volume label", optarg);
277 opt_L = optarg;
278 break;
279 case 'O':
280 if (strlen(optarg) > 8)
281 errx(1, "%s: bad OEM string", optarg);
282 opt_O = optarg;
283 break;
284 case 'S':
285 opt_S = argto2(optarg, 1, "bytes/sector")argtou(optarg, 1, 0xffff, "bytes/sector");
286 break;
287 case 'a':
288 opt_a = argto4(optarg, 1, "sectors/FAT")argtou(optarg, 1, 0xffffffff, "sectors/FAT");
289 break;
290 case 'b':
291 opt_b = argtox(optarg, 1, "block size")argtou(optarg, 1, (2147483647 *2U +1U), "block size");
292 opt_c = 0;
293 break;
294 case 'c':
295 opt_c = argto1(optarg, 1, "sectors/cluster")argtou(optarg, 1, 0xff, "sectors/cluster");
296 opt_b = 0;
297 break;
298 case 'e':
299 opt_e = argto2(optarg, 1, "directory entries")argtou(optarg, 1, 0xffff, "directory entries");
300 break;
301 case 'f':
302 opt_f = optarg;
303 break;
304 case 'h':
305 opt_h = argto2(optarg, 1, "drive heads")argtou(optarg, 1, 0xffff, "drive heads");
306 break;
307 case 'i':
308 opt_i = argto2(optarg, 1, "info sector")argtou(optarg, 1, 0xffff, "info sector");
309 break;
310 case 'k':
311 opt_k = argto2(optarg, 1, "backup sector")argtou(optarg, 1, 0xffff, "backup sector");
312 break;
313 case 'm':
314 opt_m = argto1(optarg, 0, "media descriptor")argtou(optarg, 0, 0xff, "media descriptor");
315 mflag = 1;
316 break;
317 case 'n':
318 opt_n = argto1(optarg, 1, "number of FATs")argtou(optarg, 1, 0xff, "number of FATs");
319 break;
320 case 'o':
321 opt_o = argto4(optarg, 0, "hidden sectors")argtou(optarg, 0, 0xffffffff, "hidden sectors");
322 oflag = 1;
323 break;
324 case 'q': /* Compat with newfs -q */
325 break;
326 case 'r':
327 opt_r = argto2(optarg, 1, "reserved sectors")argtou(optarg, 1, 0xffff, "reserved sectors");
328 break;
329 case 's':
330 opt_s = argto4(optarg, 1, "file system size")argtou(optarg, 1, 0xffffffff, "file system size");
331 break;
332 case 't': /* Compat with newfs -t */
333 break;
334 case 'u':
335 opt_u = argto2(optarg, 1, "sectors/track")argtou(optarg, 1, 0xffff, "sectors/track");
336 break;
337 default:
338 usage();
339 }
340 argc -= optind;
341 argv += optind;
342 if (argc < 1 || argc > 2)
5
Assuming 'argc' is >= 1
6
Assuming 'argc' is <= 2
7
Taking false branch
343 usage();
344 sname = *argv++;
345 dtype = *argv;
346 if ((fd = opendev(sname, opt_N
7.1
'opt_N' is 0
? O_RDONLY0x0000 : O_RDWR0x0002, 0, &fname)) == -1
||
8
'?' condition is false
9
Assuming the condition is false
11
Taking false branch
347 fstat(fd, &sb))
10
Assuming the condition is false
348 err(1, "%s", fname);
349 if (!opt_N
11.1
'opt_N' is 0
)
12
Taking true branch
350 check_mounted(fname, sb.st_mode);
351 if (S_ISBLK(sb.st_mode)((sb.st_mode & 0170000) == 0060000))
13
Assuming the condition is false
14
Taking false branch
352 errx(1, "%s: block device", fname);
353 if (!S_ISCHR(sb.st_mode)((sb.st_mode & 0170000) == 0020000))
15
Taking true branch
354 warnx("warning: %s is not a character device", fname);
355 memset(&bpb, 0, sizeof(bpb));
356 if (opt_f
15.1
'opt_f' is null
) {
16
Taking false branch
357 getstdfmt(opt_f, &bpb);
358 bpb.bsec = bpb.sec;
359 bpb.sec = 0;
360 bpb.bspf = bpb.spf;
361 bpb.spf = 0;
362 }
363 if (opt_h
16.1
'opt_h' is 0
)
17
Taking false branch
364 bpb.hds = opt_h;
365 if (opt_u
17.1
'opt_u' is 0
)
18
Taking false branch
366 bpb.spt = opt_u;
367 if (opt_S
18.1
'opt_S' is 0
)
19
Taking false branch
368 bpb.bps = opt_S;
369 if (opt_s
19.1
'opt_s' is 0
)
20
Taking false branch
370 bpb.bsec = opt_s;
371 if (oflag
20.1
'oflag' is 0
)
21
Taking false branch
372 bpb.hid = opt_o;
373 if (!(opt_f
21.1
'opt_f' is null
|| (opt_h
21.2
'opt_h' is 0
&& opt_u && opt_S && opt_s && oflag)))
22
Taking true branch
374 getdiskinfo(fd, fname, dtype, oflag, &bpb);
375 if (!powerof2(bpb.bps)((((bpb.bps)-1)&(bpb.bps))==0))
23
Assuming the condition is true
24
Taking false branch
376 errx(1, "bytes/sector (%u) is not a power of 2", bpb.bps);
377 if (bpb.bps < MINBPS512)
25
Assuming field 'bps' is >= MINBPS
26
Taking false branch
378 errx(1, "bytes/sector (%u) is too small; minimum is %u",
379 bpb.bps, MINBPS512);
380 if (!(fat = opt_F)) {
27
Assuming 'fat' is 0
28
Taking true branch
381 if (opt_f
28.1
'opt_f' is null
)
29
Taking false branch
382 fat = 12;
383 else if (!opt_e
29.1
'opt_e' is 0
&& (opt_i
29.2
'opt_i' is 0
|| opt_k
29.3
'opt_k' is 0
))
30
Taking false branch
384 fat = 32;
385 }
386 if ((fat
30.1
'fat' is not equal to 32
== 32 && opt_e) || (fat
30.2
'fat' is not equal to 32
!= 32 && (opt_i
30.3
'opt_i' is 0
|| opt_k
30.4
'opt_k' is 0
)))
31
Taking false branch
387 errx(1, "-%c is not a legal FAT%s option",
388 fat == 32 ? 'e' : opt_i ? 'i' : 'k',
389 fat == 32 ? "32" : "12/16");
390 if (opt_f
31.1
'opt_f' is null
&& fat == 32)
391 bpb.rde = 0;
392 if (opt_b
31.2
'opt_b' is 0
) {
32
Taking false branch
393 if (!powerof2(opt_b)((((opt_b)-1)&(opt_b))==0))
394 errx(1, "block size (%u) is not a power of 2", opt_b);
395 if (opt_b < bpb.bps)
396 errx(1, "block size (%u) is too small; minimum is %u",
397 opt_b, bpb.bps);
398 if (opt_b > bpb.bps * MAXSPC128)
399 errx(1, "block size (%u) is too large; maximum is %u",
400 opt_b, bpb.bps * MAXSPC128);
401 bpb.spc = opt_b / bpb.bps;
402 }
403 if (opt_c
32.1
'opt_c' is 0
) {
33
Taking false branch
404 if (!powerof2(opt_c)((((opt_c)-1)&(opt_c))==0))
405 errx(1, "sectors/cluster (%u) is not a power of 2", opt_c);
406 bpb.spc = opt_c;
407 }
408 if (opt_r
33.1
'opt_r' is 0
)
34
Taking false branch
409 bpb.res = opt_r;
410 if (opt_n
34.1
'opt_n' is 0
) {
35
Taking false branch
411 if (opt_n > MAXNFT16)
412 errx(1, "number of FATs (%u) is too large; maximum is %u",
413 opt_n, MAXNFT16);
414 bpb.nft = opt_n;
415 }
416 if (opt_e
35.1
'opt_e' is 0
)
36
Taking false branch
417 bpb.rde = opt_e;
418 if (mflag
36.1
'mflag' is 0
) {
37
Taking false branch
419 if (opt_m < 0xf0)
420 errx(1, "illegal media descriptor (%#x)", opt_m);
421 bpb.mid = opt_m;
422 }
423 if (opt_a
37.1
'opt_a' is 0
)
38
Taking false branch
424 bpb.bspf = opt_a;
425 if (opt_i
38.1
'opt_i' is 0
)
39
Taking false branch
426 bpb.infs = opt_i;
427 if (opt_k
39.1
'opt_k' is 0
)
40
Taking false branch
428 bpb.bkbs = opt_k;
429 bss = 1;
430 bname = NULL((void *)0);
431 fd1 = -1;
432 if (opt_B
40.1
'opt_B' is null
) {
41
Taking false branch
433 bname = opt_B;
434 if (!strchr(bname, '/')) {
435 snprintf(buf, sizeof(buf), "/boot/%s", bname);
436 if (!(bname = strdup(buf)))
437 err(1, NULL((void *)0));
438 }
439 if ((fd1 = open(bname, O_RDONLY0x0000)) == -1 || fstat(fd1, &sb))
440 err(1, "%s", bname);
441 if (!S_ISREG(sb.st_mode)((sb.st_mode & 0170000) == 0100000) || sb.st_size % bpb.bps ||
442 sb.st_size < bpb.bps || sb.st_size > bpb.bps * MAXU160xffff)
443 errx(1, "%s: inappropriate file type or format", bname);
444 bss = sb.st_size / bpb.bps;
445 }
446 if (!bpb.nft)
42
Assuming field 'nft' is not equal to 0
43
Taking false branch
447 bpb.nft = 2;
448 if (!fat
43.1
'fat' is 0
) {
44
Taking true branch
449 if (bpb.bsec < (bpb.res ? bpb.res : bss) +
45
Assuming field 'res' is 0
46
'?' condition is false
54
Assuming the condition is false
55
Taking false branch
450 howmany((RESFTE + (bpb.spc ? MINCLS16 : MAXCLS12 + 1)) *((((2 + (bpb.spc ? 0xff5 : 0xff4 + 1)) * ((bpb.spc ? 16 : 12)
/ 4)) + ((bpb.bps * 2) - 1)) / (bpb.bps * 2))
47
Assuming field 'spc' is 0
48
'?' condition is false
49
'?' condition is false
451 ((bpb.spc ? 16 : 12) / BPN), bpb.bps * NPB)((((2 + (bpb.spc ? 0xff5 : 0xff4 + 1)) * ((bpb.spc ? 16 : 12)
/ 4)) + ((bpb.bps * 2) - 1)) / (bpb.bps * 2))
*
452 bpb.nft +
453 howmany(bpb.rde ? bpb.rde : DEFRDE,(((bpb.rde ? bpb.rde : 512) + ((bpb.bps / sizeof(struct de)) -
1)) / (bpb.bps / sizeof(struct de)))
50
Assuming field 'rde' is 0
51
'?' condition is false
454 bpb.bps / sizeof(struct de))(((bpb.rde ? bpb.rde : 512) + ((bpb.bps / sizeof(struct de)) -
1)) / (bpb.bps / sizeof(struct de)))
+
455 (bpb.spc
51.1
Field 'spc' is 0
? MINCLS160xff5 : MAXCLS120xff4 + 1) *
52
'?' condition is false
456 (bpb.spc
52.1
Field 'spc' is 0
? bpb.spc : howmany(DEFBLK, bpb.bps)(((4096) + ((bpb.bps) - 1)) / (bpb.bps)))
)
53
'?' condition is false
457 fat = 12;
458 else if (bpb.rde
55.1
Field 'rde' is 0
|| bpb.bsec <
58
Assuming the condition is false
59
Taking false branch
459 (bpb.res
55.2
Field 'res' is 0
? bpb.res : bss) +
56
'?' condition is false
460 howmany((RESFTE + MAXCLS16) * 2, bpb.bps)((((2 + 0xfff4) * 2) + ((bpb.bps) - 1)) / (bpb.bps)) * bpb.nft +
461 howmany(DEFRDE, bpb.bps / sizeof(struct de))(((512) + ((bpb.bps / sizeof(struct de)) - 1)) / (bpb.bps / sizeof
(struct de)))
+
462 (MAXCLS160xfff4 + 1) *
463 (bpb.spc
56.1
Field 'spc' is 0
? bpb.spc : howmany(8192, bpb.bps)(((8192) + ((bpb.bps) - 1)) / (bpb.bps)))
)
57
'?' condition is false
464 fat = 16;
465 else
466 fat = 32;
467 }
468 x = bss;
469 if (fat
59.1
'fat' is equal to 32
== 32) {
60
Taking true branch
470 if (!bpb.infs) {
61
Assuming field 'infs' is not equal to 0
62
Taking false branch
471 if (x == MAXU160xffff || x == bpb.bkbs)
472 errx(1, "no room for info sector");
473 bpb.infs = x;
474 }
475 if (bpb.infs != MAXU160xffff && x <= bpb.infs)
63
Assuming field 'infs' is equal to MAXU16
476 x = bpb.infs + 1;
477 if (!bpb.bkbs) {
64
Assuming field 'bkbs' is not equal to 0
65
Taking false branch
478 if (x == MAXU160xffff)
479 errx(1, "no room for backup sector");
480 bpb.bkbs = x;
481 } else if (bpb.bkbs != MAXU160xffff && bpb.bkbs == bpb.infs)
66
Assuming field 'bkbs' is equal to MAXU16
482 errx(1, "backup sector would overwrite info sector");
483 if (bpb.bkbs
66.1
Field 'bkbs' is equal to MAXU16
!= MAXU160xffff && x <= bpb.bkbs)
484 x = bpb.bkbs + 1;
485 }
486 if (!bpb.res
66.2
Field 'res' is 0
)
67
Taking true branch
487 bpb.res = fat
67.1
'fat' is equal to 32
== 32 ? MAXIMUM(x, MAXIMUM(16384 / bpb.bps, 4))(((x) > ((((16384 / bpb.bps) > (4)) ? (16384 / bpb.bps)
: (4)))) ? (x) : ((((16384 / bpb.bps) > (4)) ? (16384 / bpb
.bps) : (4))))
: x;
68
'?' condition is true
69
Assuming the condition is false
70
'?' condition is false
71
'?' condition is false
72
'?' condition is false
488 else if (bpb.res < x)
489 errx(1, "too few reserved sectors");
490 if (fat
72.1
'fat' is equal to 32
!= 32 && !bpb.rde)
491 bpb.rde = DEFRDE512;
492 rds = howmany(bpb.rde, bpb.bps / sizeof(struct de))(((bpb.rde) + ((bpb.bps / sizeof(struct de)) - 1)) / (bpb.bps
/ sizeof(struct de)))
;
493 if (!bpb.spc
72.2
Field 'spc' is 0
)
73
Taking true branch
494 for (bpb.spc = howmany(fat == 16 ? DEFBLK16 : DEFBLK, bpb.bps)(((fat == 16 ? 2048 : 4096) + ((bpb.bps) - 1)) / (bpb.bps));
74
'?' condition is false
495 bpb.spc < MAXSPC128 &&
75
Assuming field 'spc' is >= MAXSPC
496 bpb.res +
497 howmany((RESFTE + maxcls(fat)) * (fat / BPN),((((2 + ((fat) == 12 ? 0xff4 : (fat) == 16 ? 0xfff4 : 0xffffff4
)) * (fat / 4)) + ((bpb.bps * 2) - 1)) / (bpb.bps * 2))
498 bpb.bps * NPB)((((2 + ((fat) == 12 ? 0xff4 : (fat) == 16 ? 0xfff4 : 0xffffff4
)) * (fat / 4)) + ((bpb.bps * 2) - 1)) / (bpb.bps * 2))
* bpb.nft +
499 rds +
500 (u_int64_t)(maxcls(fat)((fat) == 12 ? 0xff4 : (fat) == 16 ? 0xfff4 : 0xffffff4) + 1) * bpb.spc <= bpb.bsec;
501 bpb.spc <<= 1);
502 if (fat
75.1
'fat' is equal to 32
!= 32 && bpb.bspf > MAXU160xffff)
503 errx(1, "too many sectors/FAT for FAT12/16");
504 x1 = bpb.res + rds;
505 x = bpb.bspf ? bpb.bspf : 1;
76
Assuming field 'bspf' is 0
77
'?' condition is false
506 if (x1 + (u_int64_t)x * bpb.nft > bpb.bsec)
78
Assuming the condition is false
79
Taking false branch
507 errx(1, "meta data exceeds file system size");
508 x1 += x * bpb.nft;
509 x = (u_int64_t)(bpb.bsec - x1) * bpb.bps * NPB2 /
510 (bpb.spc * bpb.bps * NPB2 + fat / BPN4 * bpb.nft);
511 x2 = howmany((RESFTE + MINIMUM(x, maxcls(fat))) * (fat / BPN),((((2 + (((x) < (((fat) == 12 ? 0xff4 : (fat) == 16 ? 0xfff4
: 0xffffff4))) ? (x) : (((fat) == 12 ? 0xff4 : (fat) == 16 ?
0xfff4 : 0xffffff4)))) * (fat / 4)) + ((bpb.bps * 2) - 1)) /
(bpb.bps * 2))
80
'?' condition is false
81
'?' condition is false
82
Assuming the condition is false
83
'?' condition is false
84
'?' condition is false
85
'?' condition is false
512 bpb.bps * NPB)((((2 + (((x) < (((fat) == 12 ? 0xff4 : (fat) == 16 ? 0xfff4
: 0xffffff4))) ? (x) : (((fat) == 12 ? 0xff4 : (fat) == 16 ?
0xfff4 : 0xffffff4)))) * (fat / 4)) + ((bpb.bps * 2) - 1)) /
(bpb.bps * 2))
;
513 if (!bpb.bspf
85.1
Field 'bspf' is 0
) {
86
Taking true branch
514 bpb.bspf = x2;
515 x1 += (bpb.bspf - 1) * bpb.nft;
516 }
517 cls = (bpb.bsec - x1) / bpb.spc;
518 x = (u_int64_t)bpb.bspf * bpb.bps * NPB2 / (fat / BPN4) - RESFTE2;
519 if (cls > x)
87
Assuming 'cls' is <= 'x'
88
Taking false branch
520 cls = x;
521 if (bpb.bspf < x2
88.1
'x2' is <= field 'bspf'
)
89
Taking false branch
522 warnx("warning: sectors/FAT limits file system to %u clusters",
523 cls);
524 if (cls < mincls(fat)((fat) == 12 ? 1 : (fat) == 16 ? 0xff5 : 0xfff5))
90
'?' condition is false
91
'?' condition is false
92
Assuming the condition is false
93
Taking false branch
525 errx(1, "%u clusters too few clusters for FAT%u, need %u", cls, fat,
526 mincls(fat)((fat) == 12 ? 1 : (fat) == 16 ? 0xff5 : 0xfff5));
527 if (cls > maxcls(fat)((fat) == 12 ? 0xff4 : (fat) == 16 ? 0xfff4 : 0xffffff4)) {
94
'?' condition is false
95
'?' condition is false
96
Assuming the condition is false
97
Taking false branch
528 cls = maxcls(fat)((fat) == 12 ? 0xff4 : (fat) == 16 ? 0xfff4 : 0xffffff4);
529 bpb.bsec = x1 + (cls + 1) * bpb.spc - 1;
530 warnx("warning: FAT type limits file system to %u sectors",
531 bpb.bsec);
532 }
533 printf("%s: %u sector%s in %u FAT%u cluster%s "
534 "(%u bytes/cluster)\n", fname, cls * bpb.spc,
535 cls * bpb.spc == 1 ? "" : "s", cls, fat,
98
Assuming the condition is false
99
'?' condition is false
536 cls
99.1
'cls' is not equal to 1
== 1 ? "" : "s", bpb.bps * bpb.spc);
100
'?' condition is false
537 if (!bpb.mid)
101
Assuming field 'mid' is not equal to 0
102
Taking false branch
538 bpb.mid = !bpb.hid ? 0xf0 : 0xf8;
539 if (fat
102.1
'fat' is equal to 32
== 32)
103
Taking true branch
540 bpb.rdcl = RESFTE2;
541 if (bpb.hid + bpb.bsec <= MAXU160xffff) {
104
Assuming the condition is false
105
Taking false branch
542 bpb.sec = bpb.bsec;
543 bpb.bsec = 0;
544 }
545 if (fat
105.1
'fat' is equal to 32
!= 32) {
106
Taking false branch
546 bpb.spf = bpb.bspf;
547 bpb.bspf = 0;
548 }
549 print_bpb(&bpb);
550 if (!opt_N
106.1
'opt_N' is 0
) {
107
Taking true branch
551 gettimeofday(&tv, NULL((void *)0));
552 now = tv.tv_sec;
553 tm = localtime(&now);
554 if (!(img = malloc(bpb.bps)))
108
Memory is allocated
109
Assuming 'img' is non-null
110
Taking false branch
555 err(1, NULL((void *)0));
556 dir = bpb.res + (bpb.spf
110.1
Field 'spf' is not equal to 0
? bpb.spf : bpb.bspf) * bpb.nft;
111
'?' condition is true
557 for (lsn = 0; lsn < dir + (fat
111.1
'fat' is equal to 32
== 32 ? bpb.spc : rds)
; lsn++) {
112
'?' condition is true
113
Assuming the condition is false
114
Loop condition is false. Execution continues on line 661
558 x = lsn;
559 if (opt_B &&
560 fat == 32 && bpb.bkbs != MAXU160xffff &&
561 bss <= bpb.bkbs && x >= bpb.bkbs) {
562 x -= bpb.bkbs;
563 if (!x && lseek(fd1, 0, SEEK_SET0))
564 err(1, "%s", bname);
565 }
566 if (opt_B && x < bss) {
567 if ((n = read(fd1, img, bpb.bps)) == -1)
568 err(1, "%s", bname);
569 if (n != bpb.bps)
570 errx(1, "%s: can't read sector %u", bname, x);
571 } else
572 memset(img, 0, bpb.bps);
573 if (!lsn ||
574 (fat == 32 && bpb.bkbs != MAXU160xffff && lsn == bpb.bkbs)) {
575 x1 = sizeof(struct bs);
576 bsbpb = (struct bsbpb *)(img + x1);
577 mk2(bsbpb->bps, bpb.bps)(bsbpb->bps)[0] = (u_int8_t)(bpb.bps), (bsbpb->bps)[1] =
(u_int8_t)((bpb.bps) >> 010)
;
578 mk1(bsbpb->spc, bpb.spc)(bsbpb->spc) = (u_int8_t)(bpb.spc);
579 mk2(bsbpb->res, bpb.res)(bsbpb->res)[0] = (u_int8_t)(bpb.res), (bsbpb->res)[1] =
(u_int8_t)((bpb.res) >> 010)
;
580 mk1(bsbpb->nft, bpb.nft)(bsbpb->nft) = (u_int8_t)(bpb.nft);
581 mk2(bsbpb->rde, bpb.rde)(bsbpb->rde)[0] = (u_int8_t)(bpb.rde), (bsbpb->rde)[1] =
(u_int8_t)((bpb.rde) >> 010)
;
582 mk2(bsbpb->sec, bpb.sec)(bsbpb->sec)[0] = (u_int8_t)(bpb.sec), (bsbpb->sec)[1] =
(u_int8_t)((bpb.sec) >> 010)
;
583 mk1(bsbpb->mid, bpb.mid)(bsbpb->mid) = (u_int8_t)(bpb.mid);
584 mk2(bsbpb->spf, bpb.spf)(bsbpb->spf)[0] = (u_int8_t)(bpb.spf), (bsbpb->spf)[1] =
(u_int8_t)((bpb.spf) >> 010)
;
585 mk2(bsbpb->spt, bpb.spt)(bsbpb->spt)[0] = (u_int8_t)(bpb.spt), (bsbpb->spt)[1] =
(u_int8_t)((bpb.spt) >> 010)
;
586 mk2(bsbpb->hds, bpb.hds)(bsbpb->hds)[0] = (u_int8_t)(bpb.hds), (bsbpb->hds)[1] =
(u_int8_t)((bpb.hds) >> 010)
;
587 mk4(bsbpb->hid, bpb.hid)(bsbpb->hid)[0] = (u_int8_t)(bpb.hid), (bsbpb->hid)[1] =
(u_int8_t)((bpb.hid) >> 010), (bsbpb->hid)[2] = (u_int8_t
)((bpb.hid) >> 020), (bsbpb->hid)[3] = (u_int8_t)((bpb
.hid) >> 030)
;
588 mk4(bsbpb->bsec, bpb.bsec)(bsbpb->bsec)[0] = (u_int8_t)(bpb.bsec), (bsbpb->bsec)[
1] = (u_int8_t)((bpb.bsec) >> 010), (bsbpb->bsec)[2]
= (u_int8_t)((bpb.bsec) >> 020), (bsbpb->bsec)[3] =
(u_int8_t)((bpb.bsec) >> 030)
;
589 x1 += sizeof(struct bsbpb);
590 if (fat == 32) {
591 bsxbpb = (struct bsxbpb *)(img + x1);
592 mk4(bsxbpb->bspf, bpb.bspf)(bsxbpb->bspf)[0] = (u_int8_t)(bpb.bspf), (bsxbpb->bspf
)[1] = (u_int8_t)((bpb.bspf) >> 010), (bsxbpb->bspf)
[2] = (u_int8_t)((bpb.bspf) >> 020), (bsxbpb->bspf)[
3] = (u_int8_t)((bpb.bspf) >> 030)
;
593 mk2(bsxbpb->xflg, 0)(bsxbpb->xflg)[0] = (u_int8_t)(0), (bsxbpb->xflg)[1] = (
u_int8_t)((0) >> 010)
;
594 mk2(bsxbpb->vers, 0)(bsxbpb->vers)[0] = (u_int8_t)(0), (bsxbpb->vers)[1] = (
u_int8_t)((0) >> 010)
;
595 mk4(bsxbpb->rdcl, bpb.rdcl)(bsxbpb->rdcl)[0] = (u_int8_t)(bpb.rdcl), (bsxbpb->rdcl
)[1] = (u_int8_t)((bpb.rdcl) >> 010), (bsxbpb->rdcl)
[2] = (u_int8_t)((bpb.rdcl) >> 020), (bsxbpb->rdcl)[
3] = (u_int8_t)((bpb.rdcl) >> 030)
;
596 mk2(bsxbpb->infs, bpb.infs)(bsxbpb->infs)[0] = (u_int8_t)(bpb.infs), (bsxbpb->infs
)[1] = (u_int8_t)((bpb.infs) >> 010)
;
597 mk2(bsxbpb->bkbs, bpb.bkbs)(bsxbpb->bkbs)[0] = (u_int8_t)(bpb.bkbs), (bsxbpb->bkbs
)[1] = (u_int8_t)((bpb.bkbs) >> 010)
;
598 x1 += sizeof(struct bsxbpb);
599 }
600 bsx = (struct bsx *)(img + x1);
601 mk1(bsx->sig, 0x29)(bsx->sig) = (u_int8_t)(0x29);
602 if (Iflag)
603 x = opt_I;
604 else
605 x = (((u_int)(1 + tm->tm_mon) << 8 |
606 (u_int)tm->tm_mday) +
607 ((u_int)tm->tm_sec << 8 |
608 (u_int)(tv.tv_usec / 10))) << 16 |
609 ((u_int)(1900 + tm->tm_year) +
610 ((u_int)tm->tm_hour << 8 |
611 (u_int)tm->tm_min));
612 mk4(bsx->volid, x)(bsx->volid)[0] = (u_int8_t)(x), (bsx->volid)[1] = (u_int8_t
)((x) >> 010), (bsx->volid)[2] = (u_int8_t)((x) >>
020), (bsx->volid)[3] = (u_int8_t)((x) >> 030)
;
613 mklabel(bsx->label, opt_L ? opt_L : "NO NAME");
614 snprintf(buf, sizeof buf, "FAT%u", fat);
615 setstr(bsx->type, buf, sizeof(bsx->type));
616 if (!opt_B) {
617 x1 += sizeof(struct bsx);
618 bs = (struct bs *)img;
619 mk1(bs->jmp[0], 0xeb)(bs->jmp[0]) = (u_int8_t)(0xeb);
620 mk1(bs->jmp[1], x1 - 2)(bs->jmp[1]) = (u_int8_t)(x1 - 2);
621 mk1(bs->jmp[2], 0x90)(bs->jmp[2]) = (u_int8_t)(0x90);
622 setstr(bs->oem, opt_O ? opt_O : "BSD 4.4",
623 sizeof(bs->oem));
624 memcpy(img + x1, bootcode, sizeof(bootcode));
625 mk2(img + MINBPS - 2, DOSMAGIC)(img + 512 - 2)[0] = (u_int8_t)(0xaa55), (img + 512 - 2)[1] =
(u_int8_t)((0xaa55) >> 010)
;
626 }
627 } else if (fat == 32 && bpb.infs != MAXU160xffff &&
628 (lsn == bpb.infs ||
629 (bpb.bkbs != MAXU160xffff &&
630 lsn == bpb.bkbs + bpb.infs))) {
631 mk4(img, 0x41615252)(img)[0] = (u_int8_t)(0x41615252), (img)[1] = (u_int8_t)((0x41615252
) >> 010), (img)[2] = (u_int8_t)((0x41615252) >> 020
), (img)[3] = (u_int8_t)((0x41615252) >> 030)
;
632 mk4(img + MINBPS - 28, 0x61417272)(img + 512 - 28)[0] = (u_int8_t)(0x61417272), (img + 512 - 28
)[1] = (u_int8_t)((0x61417272) >> 010), (img + 512 - 28
)[2] = (u_int8_t)((0x61417272) >> 020), (img + 512 - 28
)[3] = (u_int8_t)((0x61417272) >> 030)
;
633 mk4(img + MINBPS - 24, 0xffffffff)(img + 512 - 24)[0] = (u_int8_t)(0xffffffff), (img + 512 - 24
)[1] = (u_int8_t)((0xffffffff) >> 010), (img + 512 - 24
)[2] = (u_int8_t)((0xffffffff) >> 020), (img + 512 - 24
)[3] = (u_int8_t)((0xffffffff) >> 030)
;
634 mk4(img + MINBPS - 20, 0xffffffff)(img + 512 - 20)[0] = (u_int8_t)(0xffffffff), (img + 512 - 20
)[1] = (u_int8_t)((0xffffffff) >> 010), (img + 512 - 20
)[2] = (u_int8_t)((0xffffffff) >> 020), (img + 512 - 20
)[3] = (u_int8_t)((0xffffffff) >> 030)
;
635 mk2(img + MINBPS - 2, DOSMAGIC)(img + 512 - 2)[0] = (u_int8_t)(0xaa55), (img + 512 - 2)[1] =
(u_int8_t)((0xaa55) >> 010)
;
636 } else if (lsn >= bpb.res && lsn < dir &&
637 !((lsn - bpb.res) %
638 (bpb.spf ? bpb.spf : bpb.bspf))) {
639 mk1(img[0], bpb.mid)(img[0]) = (u_int8_t)(bpb.mid);
640 for (x = 1; x < fat * (fat == 32 ? 3 : 2) / 8; x++)
641 mk1(img[x], fat == 32 && x % 4 == 3 ? 0x0f : 0xff)(img[x]) = (u_int8_t)(fat == 32 && x % 4 == 3 ? 0x0f :
0xff)
;
642 } else if (lsn == dir && opt_L) {
643 de = (struct de *)img;
644 mklabel(de->namext, opt_L);
645 mk1(de->attr, 050)(de->attr) = (u_int8_t)(050);
646 x = (u_int)tm->tm_hour << 11 |
647 (u_int)tm->tm_min << 5 |
648 (u_int)tm->tm_sec >> 1;
649 mk2(de->time, x)(de->time)[0] = (u_int8_t)(x), (de->time)[1] = (u_int8_t
)((x) >> 010)
;
650 x = (u_int)(tm->tm_year - 80) << 9 |
651 (u_int)(tm->tm_mon + 1) << 5 |
652 (u_int)tm->tm_mday;
653 mk2(de->date, x)(de->date)[0] = (u_int8_t)(x), (de->date)[1] = (u_int8_t
)((x) >> 010)
;
654 }
655 if ((n = write(fd, img, bpb.bps)) == -1)
656 err(1, "%s", fname);
657 if (n != bpb.bps)
658 errx(1, "%s: can't write sector %u", fname, lsn);
659 }
660 }
661 return 0;
115
Potential leak of memory pointed to by 'img'
662}
663
664/*
665 * Exit with error if file system is mounted.
666 */
667static void
668check_mounted(const char *fname, mode_t mode)
669{
670 struct statfs *mp;
671 const char *s1, *s2;
672 size_t len;
673 int n, r;
674
675 if (!(n = getmntinfo(&mp, MNT_NOWAIT2)))
676 err(1, "getmntinfo");
677 len = sizeof(_PATH_DEV"/dev/") - 1;
678 s1 = fname;
679 if (!strncmp(s1, _PATH_DEV"/dev/", len))
680 s1 += len;
681 r = S_ISCHR(mode)((mode & 0170000) == 0020000) && s1 != fname && *s1 == 'r';
682 for (; n--; mp++) {
683 s2 = mp->f_mntfromname;
684 if (!strncmp(s2, _PATH_DEV"/dev/", len))
685 s2 += len;
686 if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) ||
687 !strcmp(s1, s2))
688 errx(1, "%s is mounted on %s", fname, mp->f_mntonname);
689 }
690}
691
692/*
693 * Get a standard format.
694 */
695static void
696getstdfmt(const char *fmt, struct bpb *bpb)
697{
698 u_int x, i;
699
700 x = sizeof(stdfmt) / sizeof(stdfmt[0]);
701 for (i = 0; i < x && strcmp(fmt, stdfmt[i].name); i++);
702 if (i == x)
703 errx(1, "%s: unknown standard format", fmt);
704 *bpb = stdfmt[i].bpb;
705}
706
707/*
708 * Get disk slice, partition, and geometry information.
709 */
710static void
711getdiskinfo(int fd, const char *fname, const char *dtype, int oflag,
712 struct bpb *bpb)
713{
714 struct disklabel dl, *lp;
715 const char *s1, *s2;
716 int part, i;
717
718 part = -1;
719 s1 = fname;
720 if ((s2 = strrchr(s1, '/')))
721 s1 = s2 + 1;
722 for (s2 = s1; *s2 && !isdigit((unsigned char)*s2); s2++);
723 if (!*s2 || s2 == s1)
724 s2 = NULL((void *)0);
725 else
726 while (isdigit((unsigned char)*++s2));
727 s1 = s2;
728 if (s2 && *s2 >= 'a' && *s2 <= 'a' + MAXPARTITIONS16 - 1) {
729 part = *s2++ - 'a';
730 }
731 if (!s2 || (*s2 && *s2 != '.'))
732 errx(1, "%s: can't figure out partition info", fname);
733 if ((((!oflag && part != -1) || !bpb->bsec)) ||
734 !bpb->bps || !bpb->spt || !bpb->hds) {
735 lp = &dl;
736 i = ioctl(fd, DIOCGDINFO((unsigned long)0x40000000 | ((sizeof(struct disklabel) &
0x1fff) << 16) | ((('d')) << 8) | ((101)))
, lp);
737 if (i == -1) {
738 if (!dtype) {
739 warn("ioctl (GDINFO)");
740 errx(1, "%s: can't read disk label; "
741 "disk type must be specified", fname);
742 } else if (!(lp = getdiskbyname(dtype)))
743 errx(1, "%s: unknown disk type", dtype);
744 }
745 if (part == -1)
746 part = RAW_PART2;
747 if (part >= lp->d_npartitions ||
748 !DL_GETPSIZE(&lp->d_partitions[part])(((u_int64_t)(&lp->d_partitions[part])->p_sizeh <<
32) + (&lp->d_partitions[part])->p_size)
)
749 errx(1, "%s: partition is unavailable", fname);
750 if (!oflag && part != -1)
751 bpb->hid += DL_GETPOFFSET(&lp->d_partitions[part])(((u_int64_t)(&lp->d_partitions[part])->p_offseth <<
32) + (&lp->d_partitions[part])->p_offset)
;
752 if (!bpb->bsec)
753 bpb->bsec = DL_GETPSIZE(&lp->d_partitions[part])(((u_int64_t)(&lp->d_partitions[part])->p_sizeh <<
32) + (&lp->d_partitions[part])->p_size)
;
754 if (!bpb->bps)
755 bpb->bps = ckgeom(fname, lp->d_secsize, "bytes/sector");
756 if (!bpb->spt)
757 bpb->spt = ckgeom(fname, lp->d_nsectors, "sectors/track");
758 if (!bpb->hds)
759 bpb->hds = ckgeom(fname, lp->d_ntracks, "drive heads");
760 if (bpb->spt > 63) {
761 bpb->hds = bpb->hds * bpb->spt / 63;
762 bpb->spt = 63;
763 }
764 }
765}
766
767/*
768 * Print out BPB values.
769 */
770static void
771print_bpb(struct bpb *bpb)
772{
773 printf("bps=%u spc=%u res=%u nft=%u", bpb->bps, bpb->spc, bpb->res,
774 bpb->nft);
775 if (bpb->rde)
776 printf(" rde=%u", bpb->rde);
777 if (bpb->sec)
778 printf(" sec=%u", bpb->sec);
779 printf(" mid=%#x", bpb->mid);
780 if (bpb->spf)
781 printf(" spf=%u", bpb->spf);
782 printf(" spt=%u hds=%u hid=%u", bpb->spt, bpb->hds, bpb->hid);
783 if (bpb->bsec)
784 printf(" bsec=%u", bpb->bsec);
785 if (!bpb->spf) {
786 printf(" bspf=%u rdcl=%u", bpb->bspf, bpb->rdcl);
787 printf(" infs=");
788 printf(bpb->infs == MAXU160xffff ? "%#x" : "%u", bpb->infs);
789 printf(" bkbs=");
790 printf(bpb->bkbs == MAXU160xffff ? "%#x" : "%u", bpb->bkbs);
791 }
792 printf("\n");
793}
794
795/*
796 * Check a disk geometry value.
797 */
798static u_int
799ckgeom(const char *fname, u_int val, const char *msg)
800{
801 if (!val)
802 errx(1, "%s: no default %s", fname, msg);
803 if (val > MAXU160xffff)
804 errx(1, "%s: illegal %s", fname, msg);
805 return val;
806}
807
808/*
809 * Convert and check a numeric option argument.
810 */
811static u_int
812argtou(const char *arg, u_int lo, u_int hi, const char *msg)
813{
814 char *s;
815 u_long x;
816
817 errno(*__errno()) = 0;
818 x = strtoul(arg, &s, 0);
819 if (errno(*__errno()) || !*arg || *s || x < lo || x > hi)
820 errx(1, "%s: bad %s", arg, msg);
821 return x;
822}
823
824/*
825 * Check a volume label.
826 */
827static int
828oklabel(const char *src)
829{
830 int c = 0, i;
831
832 for (i = 0; i <= 11; i++) {
833 c = (u_char)*src++;
834 if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))
835 break;
836 }
837 return i && !c;
838}
839
840/*
841 * Make a volume label.
842 */
843static void
844mklabel(u_int8_t *dest, const char *src)
845{
846 int c, i;
847
848 for (i = 0; i < 11; i++) {
849 c = *src ? toupper((unsigned char)*src++) : ' ';
850 *dest++ = !i && c == '\xe5' ? 5 : c;
851 }
852}
853
854/*
855 * Copy string, padding with spaces.
856 */
857static void
858setstr(u_int8_t *dest, const char *src, size_t len)
859{
860 while (len--)
861 *dest++ = *src ? *src++ : ' ';
862}
863
864/*
865 * Print usage message.
866 */
867static __dead__attribute__((__noreturn__)) void
868usage(void)
869{
870 extern const char *__progname;
871
872 fprintf(stderr(&__sF[2]), "usage: %s "
873 "[-N] [-a FAT-size] [-B boot] [-b block-size]\n"
874 "\t[-c cluster-size] [-e dirents] [-F FAT-type] [-f format]\n"
875 "\t[-h heads] [-I volid] [-i info] [-k backup] [-L label]\n"
876 "\t[-m media] [-n FATs] [-O OEM] [-o hidden] [-r reserved]\n"
877 "\t[-S sector-size] [-s total] [-u track-size] special\n"
878 "\t[disktype]\n",
879 __progname);
880 exit(1);
881}