-/* $OpenBSD: disk.c,v 1.63 2021/07/13 15:03:34 krw Exp $ */
+/* $OpenBSD: disk.c,v 1.64 2021/07/15 21:23:54 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
+#include <sys/param.h> /* DEV_BSIZE */
#include <sys/ioctl.h>
#include <sys/dkio.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <util.h>
struct disklabel dl;
void
-DISK_open(const int rw)
+DISK_open(const char *name, const int oflags)
{
struct stat st;
uint64_t sz, spc;
- disk.dk_fd = opendev(disk.dk_name, rw ? O_RDWR : O_RDONLY, OPENDEV_PART,
- NULL);
+ disk.dk_name = strdup(name);
+ if (disk.dk_name == NULL)
+ err(1, "DISK_Open('%s')", name);
+
+ disk.dk_fd = opendev(disk.dk_name, oflags, OPENDEV_PART, NULL);
if (disk.dk_fd == -1)
err(1, "%s", disk.dk_name);
if (fstat(disk.dk_fd, &st) == -1)
err(1, "%s", disk.dk_name);
if (!S_ISCHR(st.st_mode))
errx(1, "%s is not a character device", disk.dk_name);
-
- /* Get label geometry. */
- if (ioctl(disk.dk_fd, DIOCGPDINFO, &dl) == -1) {
- warn("DIOCGPDINFO");
+ if (ioctl(disk.dk_fd, DIOCGPDINFO, &dl) == -1)
+ err(1, "DIOCGPDINFO");
+
+ unit_types[SECTORS].ut_conversion = dl.d_secsize;
+
+ /* Set geometry to use in MBR partitions. */
+ if (disk.dk_size > 0) {
+ /* -l has set disk size. */
+ sz = DL_BLKTOSEC(&dl, disk.dk_size);
+ disk.dk_heads = 1;
+ disk.dk_sectors = 64;
+ } else if (disk.dk_cylinders > 0) {
+ /* -c/-h/-c has set disk geometry. */
+ sz = disk.dk_cylinders * disk.dk_heads * disk.dk_sectors;
+ sz = DL_BLKTOSEC(&dl, sz);
+ disk.dk_sectors = DL_BLKTOSEC(&dl, disk.dk_sectors);
} else {
- unit_types[SECTORS].ut_conversion = dl.d_secsize;
- if (disk.dk_size == 0) {
- /* -l or -c/-h/-s not used. Use disklabel info. */
- disk.dk_cylinders = dl.d_ncylinders;
- disk.dk_heads = dl.d_ntracks;
- disk.dk_sectors = dl.d_nsectors;
- /* MBR handles only first UINT32_MAX sectors. */
- spc = (uint64_t)disk.dk_heads * disk.dk_sectors;
- sz = DL_GETDSIZE(&dl);
- if (sz > UINT32_MAX) {
- disk.dk_cylinders = UINT32_MAX / spc;
- disk.dk_size = disk.dk_cylinders * spc;
- } else
- disk.dk_size = sz;
- }
+ sz = DL_GETDSIZE(&dl);
+ disk.dk_heads = dl.d_ntracks;
+ disk.dk_sectors = dl.d_nsectors;
}
- if (disk.dk_size == 0 || disk.dk_cylinders == 0 || disk.dk_heads == 0 ||
- disk.dk_sectors == 0 || unit_types[SECTORS].ut_conversion == 0)
- errx(1, "Can't get disk geometry, please use [-chs] or [-l]"
- "to specify.");
+ if (sz > UINT32_MAX)
+ sz = UINT32_MAX; /* MBR knows nothing > UINT32_MAX. */
+
+ spc = disk.dk_heads * disk.dk_sectors;
+ disk.dk_cylinders = sz / spc;
+ disk.dk_size = disk.dk_cylinders * spc;
+
+ if (disk.dk_size == 0)
+ errx(1, "dk_size == 0");
}
/*
-/* $OpenBSD: fdisk.c,v 1.119 2021/07/12 14:06:19 krw Exp $ */
+/* $OpenBSD: fdisk.c,v 1.120 2021/07/15 21:23:54 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
unsigned int bps;
int e_flag = 0, g_flag = 0, i_flag = 0, u_flag = 0;
int verbosity = TERSE;
- int c_arg = 0, h_arg = 0, s_arg = 0;
- uint32_t l_arg = 0;
+ int oflags = O_RDONLY;
char *query;
while ((ch = getopt(argc, argv, "Aiegpuvf:c:h:s:l:b:y")) != -1) {
switch(ch) {
case 'A':
A_flag = 1;
+ oflags = O_RDWR;
break;
case 'i':
i_flag = 1;
+ oflags = O_RDWR;
break;
case 'u':
u_flag = 1;
+ oflags = O_RDWR;
break;
case 'e':
e_flag = 1;
+ oflags = O_RDWR;
break;
case 'f':
mbrfile = optarg;
break;
case 'c':
- c_arg = strtonum(optarg, 1, 262144, &errstr);
+ disk.dk_cylinders = strtonum(optarg, 1, 262144, &errstr);
if (errstr)
errx(1, "Cylinder argument %s [1..262144].",
errstr);
- disk.dk_cylinders = c_arg;
- disk.dk_size = c_arg * h_arg * s_arg;
+ disk.dk_size = 0;
break;
case 'h':
- h_arg = strtonum(optarg, 1, 256, &errstr);
+ disk.dk_heads = strtonum(optarg, 1, 256, &errstr);
if (errstr)
errx(1, "Head argument %s [1..256].", errstr);
- disk.dk_heads = h_arg;
- disk.dk_size = c_arg * h_arg * s_arg;
+ disk.dk_size = 0;
break;
case 's':
- s_arg = strtonum(optarg, 1, 63, &errstr);
+ disk.dk_sectors = strtonum(optarg, 1, 63, &errstr);
if (errstr)
errx(1, "Sector argument %s [1..63].", errstr);
- disk.dk_sectors = s_arg;
- disk.dk_size = c_arg * h_arg * s_arg;
+ disk.dk_size = 0;
break;
case 'g':
g_flag = 1;
parse_b(optarg, &b_sectors, &b_offset, &b_type);
break;
case 'l':
- l_arg = strtonum(optarg, BLOCKALIGNMENT, UINT32_MAX, &errstr);
+ disk.dk_size = strtonum(optarg, BLOCKALIGNMENT, UINT32_MAX, &errstr);
if (errstr)
errx(1, "Block argument %s [%u..%u].", errstr,
BLOCKALIGNMENT, UINT32_MAX);
- disk.dk_cylinders = l_arg / BLOCKALIGNMENT;
- disk.dk_heads = 1;
- disk.dk_sectors = BLOCKALIGNMENT;
- disk.dk_size = l_arg;
+ disk.dk_cylinders = disk.dk_heads = disk.dk_sectors = 0;
break;
case 'y':
y_flag = 1;
/* Argument checking */
if (argc != 1 || (i_flag && u_flag) ||
(i_flag == 0 && g_flag) ||
- (b_sectors && !(i_flag || A_flag)) ||
- ((c_arg | h_arg | s_arg) && !(c_arg && h_arg && s_arg)) ||
- ((c_arg | h_arg | s_arg) && l_arg))
+ (b_sectors && !(i_flag || A_flag)))
usage();
- disk.dk_name = argv[0];
- DISK_open(A_flag || i_flag || u_flag || e_flag);
+ if ((disk.dk_cylinders || disk.dk_heads || disk.dk_sectors) &&
+ (disk.dk_cylinders * disk.dk_heads * disk.dk_sectors == 0))
+ usage();
+
+ DISK_open(argv[0], oflags);
+
bps = DL_BLKSPERSEC(&dl);
if (b_sectors > 0) {
if (b_sectors % bps != 0)
b_sectors = DL_BLKTOSEC(&dl, b_sectors);
b_offset = DL_BLKTOSEC(&dl, b_offset);
}
- if (l_arg > 0) {
- if (l_arg % bps != 0)
- l_arg += bps - l_arg % bps;
- l_arg = DL_BLKTOSEC(&dl, l_arg);
- disk.dk_cylinders = l_arg / BLOCKALIGNMENT;
- disk.dk_heads = 1;
- disk.dk_sectors = BLOCKALIGNMENT;
- disk.dk_size = l_arg;
- }
/* "proc exec" for man page display */
if (pledge("stdio rpath wpath disklabel proc exec", NULL) == -1)
if (efi != -1)
GPT_read(ANYGPT);
- if (!(A_flag || i_flag || u_flag || e_flag)) {
+ if (oflags == O_RDONLY) {
if (pledge("stdio", NULL) == -1)
err(1, "pledge");
USER_print_disk(verbosity);