2 * Copyright (c) 2025 Tobias Heider <tobhe@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 #include <sys/disklabel.h>
28 #include <sys/types.h>
29 #include <sys/sysctl.h>
30 #include <sys/mount.h>
31 #include <sys/ioctl.h>
32 #include <sys/param.h>
34 #define MEG(x) ((x) * 1024LL * (1024 / DEV_BSIZE))
35 #define GIG(x) (MEG(x) * 1024LL)
37 struct statfs *mntbuf;
50 sysctl_disknames_get(void)
54 int mib[2] = { CTL_HW, HW_DISKNAMES } ;
57 ret = sysctl(mib, 2, NULL, &len, NULL, 0);
59 err(1, "%s: sysctl", __func__);
65 ret = sysctl(mib, 2, buf, &len, NULL, 0);
67 err(1, "%s: sysctl", __func__);
73 print_partition(const char *devname, const struct disklabel *dl, int i, int last,
76 const struct partition *pp = &dl->d_partitions[i];
77 char sbuf[FMT_SCALED_STRSIZE];
82 if (DL_GETPSIZE(pp)) {
83 printf("\n%c-- %s%s%c\t", last ? '`' : '|',devname,
84 isduid(devname, OPENDEV_PART) ? "." : "",
88 if(fmt_scaled(DL_GETPSIZE(pp) * dl->d_secsize, sbuf) == -1)
89 err(1, "%s: fmt_scaled()", __func__);
92 printf("%16llu", DL_GETPSIZE(pp));
94 printf("\t%8s", fstypenames[pp->p_fstype]);
96 dplen = asprintf(&dp, "/dev/%s%c", devname, DL_PARTNUM2NAME(i));
98 for (j = 0; j < mntsize; j++)
99 if (strncmp(mntbuf[j].f_mntfromname, dp, dplen) == 0)
100 printf("\t%s", mntbuf[j].f_mntonname);
106 print_device(char *devname, int human)
108 struct dk_inquiry di;
113 /* Only root is allowed to do this */
114 dev = opendev(devname, O_RDONLY, OPENDEV_PART, NULL);
116 err(1, "failed to open %s",devname);
118 if (ioctl(dev, DIOCINQ, &di) == -1)
119 err(1, "%s: ioctl(DIOCINQ)", __func__);
120 if (ioctl(dev, DIOCGDINFO, &dl) == -1)
121 err(1, "%s: ioctl(DIOCGDINFO)", __func__);
123 printf("%s", devname);
124 const uint8_t duid_zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0};
125 if (!isduid(devname, OPENDEV_PART) && (memcmp(dl.d_uid, duid_zero, sizeof(duid_zero)) != 0)) {
126 printf(":%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
127 dl.d_uid[0], dl.d_uid[1], dl.d_uid[2], dl.d_uid[3],
128 dl.d_uid[4], dl.d_uid[5], dl.d_uid[6], dl.d_uid[7]);
130 printf(" [%s %s]", di.vendor, di.product);
133 for (i = 0; i < dl.d_npartitions; i++)
134 if (DL_GETPSIZE(&dl.d_partitions[i]))
137 for (i = 0; i < dl.d_npartitions; i++)
138 print_partition(devname, &dl, i, i == last_i, human);
143 main(int argc, char *argv[])
145 char *disks = sysctl_disknames_get();
149 while ((ch = getopt(argc, argv, "h")) != -1) {
161 if ((mntsize = getmntinfo(&mntbuf, MNT_WAIT)) == 0)
162 err(1, "%s: getmntinfo", __func__);
165 printf("DISK \t TOTAL\t FSTYPE\tMOUNT\n");
167 printf("DISK \t TOTAL\t FSTYPE\tMOUNT\n");
170 if (argc == 1 && argv[0] != NULL) {
171 print_device(argv[0], human);
175 /* Print all of those disks*/
176 while ((p = strsep(&disks, ",")) != NULL) {
180 errx(1, "%s: strsep", __func__);
182 print_device(p, human);