aboutsummaryrefslogtreecommitdiffstats
path: root/diskdev_cmds/fdisk.tproj
diff options
context:
space:
mode:
Diffstat (limited to 'diskdev_cmds/fdisk.tproj')
-rw-r--r--diskdev_cmds/fdisk.tproj/auto.c155
-rw-r--r--diskdev_cmds/fdisk.tproj/auto.h31
-rw-r--r--diskdev_cmds/fdisk.tproj/cmd.c507
-rw-r--r--diskdev_cmds/fdisk.tproj/cmd.h105
-rw-r--r--diskdev_cmds/fdisk.tproj/disk.c309
-rw-r--r--diskdev_cmds/fdisk.tproj/disk.h83
-rw-r--r--diskdev_cmds/fdisk.tproj/fdisk.8377
-rw-r--r--diskdev_cmds/fdisk.tproj/fdisk.c289
-rw-r--r--diskdev_cmds/fdisk.tproj/getrawpartition.c87
-rw-r--r--diskdev_cmds/fdisk.tproj/mbr.c553
-rw-r--r--diskdev_cmds/fdisk.tproj/mbr.h114
-rw-r--r--diskdev_cmds/fdisk.tproj/mbrcode.h119
-rw-r--r--diskdev_cmds/fdisk.tproj/misc.c183
-rw-r--r--diskdev_cmds/fdisk.tproj/misc.h74
-rw-r--r--diskdev_cmds/fdisk.tproj/opendev.c111
-rw-r--r--diskdev_cmds/fdisk.tproj/part.c425
-rw-r--r--diskdev_cmds/fdisk.tproj/part.h80
-rw-r--r--diskdev_cmds/fdisk.tproj/user.c275
-rw-r--r--diskdev_cmds/fdisk.tproj/user.h65
-rw-r--r--diskdev_cmds/fdisk.tproj/util.h137
20 files changed, 4079 insertions, 0 deletions
diff --git a/diskdev_cmds/fdisk.tproj/auto.c b/diskdev_cmds/fdisk.tproj/auto.c
new file mode 100644
index 0000000..155f7ab
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/auto.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Auto partitioning code.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <err.h>
+#include "disk.h"
+#include "mbr.h"
+#include "auto.h"
+
+int AUTO_boothfs __P((disk_t *, mbr_t *));
+int AUTO_hfs __P((disk_t *, mbr_t *));
+int AUTO_dos __P((disk_t *, mbr_t *));
+int AUTO_raid __P((disk_t *, mbr_t *));
+
+/* The default style is the first one in the list */
+struct _auto_style {
+ char *style_name;
+ int (*style_fn)(disk_t *, mbr_t *);
+ char *description;
+} style_fns[] = {
+ {"boothfs", AUTO_boothfs, "8Mb boot plus HFS+ root partition"},
+ {"hfs", AUTO_hfs, "Entire disk as one HFS+ partition"},
+ {"dos", AUTO_dos, "Entire disk as one DOS partition"},
+ {"raid", AUTO_raid, "Entire disk as one 0xAC partition"},
+ {0,0}
+};
+
+void
+AUTO_print_styles(FILE *f)
+{
+ struct _auto_style *fp;
+ int i;
+
+ for (i=0, fp = &style_fns[0]; fp->style_name != NULL; i++, fp++) {
+ fprintf(f, " %-10s %s%s\n", fp->style_name, fp->description, (i==0) ? " (default)" : "");
+ }
+}
+
+
+int
+AUTO_init(disk_t *disk, char *style, mbr_t *mbr)
+{
+ struct _auto_style *fp;
+
+ for (fp = &style_fns[0]; fp->style_name != NULL; fp++) {
+ /* If style is NULL, use the first (default) style */
+ if (style == NULL || strcasecmp(style, fp->style_name) == 0) {
+ return (*fp->style_fn)(disk, mbr);
+ }
+ }
+ warnx("No such auto-partition style %s", style);
+ return AUTO_ERR;
+}
+
+
+static int
+use_whole_disk(disk_t *disk, unsigned char id, mbr_t *mbr)
+{
+ MBR_clear(mbr);
+ mbr->part[0].id = id;
+ mbr->part[0].bs = 63;
+ mbr->part[0].ns = disk->real->size - 63;
+ PRT_fix_CHS(disk, &mbr->part[0], 0);
+ return AUTO_OK;
+}
+
+/* DOS style: one partition for the whole disk */
+int
+AUTO_dos(disk_t *disk, mbr_t *mbr)
+{
+ int cc;
+ cc = use_whole_disk(disk, 0x0C, mbr);
+ if (cc == AUTO_OK) {
+ mbr->part[0].flag = DOSACTIVE;
+ }
+ return cc;
+}
+
+/* HFS style: one partition for the whole disk */
+int
+AUTO_hfs(disk_t *disk, mbr_t *mbr)
+{
+ int cc;
+ cc = use_whole_disk(disk, 0xAF, mbr);
+ if (cc == AUTO_OK) {
+ mbr->part[0].flag = DOSACTIVE;
+ }
+ return cc;
+}
+
+/* One boot partition, one HFS+ root partition */
+int
+AUTO_boothfs (disk_t *disk, mbr_t *mbr)
+{
+ /* Check disk size. */
+ if (disk->real->size < 16 * 2048) {
+ errx(1, "Disk size must be greater than 16Mb");
+ return AUTO_ERR;
+ }
+
+ MBR_clear(mbr);
+
+ /* 8MB boot partition */
+ mbr->part[0].id = 0xAB;
+ mbr->part[0].bs = 63;
+ mbr->part[0].ns = 8 * 1024 * 2;
+ mbr->part[0].flag = DOSACTIVE;
+ PRT_fix_CHS(disk, &mbr->part[0], 0);
+
+ /* Rest of the disk for rooting */
+ mbr->part[1].id = 0xAF;
+ mbr->part[1].bs = (mbr->part[0].bs + mbr->part[0].ns);
+ mbr->part[1].ns = disk->real->size - mbr->part[0].ns - 63;
+ PRT_fix_CHS(disk, &mbr->part[1], 1);
+
+ return AUTO_OK;
+}
+
+
+
+/* RAID style: one 0xAC partition for the whole disk */
+int
+AUTO_raid(disk_t *disk, mbr_t *mbr)
+{
+ return use_whole_disk(disk, 0xAC, mbr);
+}
+
diff --git a/diskdev_cmds/fdisk.tproj/auto.h b/diskdev_cmds/fdisk.tproj/auto.h
new file mode 100644
index 0000000..c9259d4
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/auto.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include "mbr.h"
+
+/* Prototypes */
+void AUTO_print_styles __P((FILE *));
+int AUTO_init __P((disk_t *, char *, mbr_t *));
+
+#define AUTO_OK 0
+#define AUTO_ERR -1
diff --git a/diskdev_cmds/fdisk.tproj/cmd.c b/diskdev_cmds/fdisk.tproj/cmd.c
new file mode 100644
index 0000000..41cee77
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/cmd.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 2002-2005 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <memory.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/fcntl.h>
+#include "disk.h"
+#include "misc.h"
+#include "user.h"
+#include "part.h"
+#include "cmd.h"
+#include "auto.h"
+#define MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+int
+Xerase(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ bzero(mbr->part, sizeof(mbr->part));
+ mbr->signature = MBR_SIGNATURE;
+ return (CMD_DIRTY);
+}
+
+int
+Xreinit(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ /* Copy template MBR */
+ MBR_make(tt);
+ MBR_parse(disk, offset, 0, mbr);
+
+ MBR_init(disk, mbr);
+
+ /* Tell em we did something */
+ printf("In memory copy is initialized to:\n");
+ printf("Offset: %d\t", offset);
+ MBR_print(mbr);
+ printf("Use 'write' to update disk.\n");
+
+ return (CMD_DIRTY);
+}
+
+int
+Xauto(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ if (cmd->args[0] == '\0') {
+ printf("usage: auto <style>\n");
+ printf(" where style is one of:\n");
+ AUTO_print_styles(stdout);
+ return (CMD_CONT);
+ }
+
+ if (AUTO_init(disk, cmd->args, mbr) != AUTO_OK) {
+ return (CMD_CONT);
+ }
+ MBR_make(mbr);
+ return (CMD_DIRTY);
+}
+
+int
+Xdisk(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ int maxcyl = 1024;
+ int maxhead = 256;
+ int maxsec = 63;
+
+ /* Print out disk info */
+ DISK_printmetrics(disk);
+
+#if defined (__powerpc__) || defined (__mips__)
+ maxcyl = 9999999;
+ maxhead = 9999999;
+ maxsec = 9999999;
+#endif
+
+ /* Ask for new info */
+ if (ask_yn("Change disk geometry?", 0)) {
+ disk->real->cylinders = ask_num("BIOS Cylinders", ASK_DEC,
+ disk->real->cylinders, 1, maxcyl, NULL);
+ disk->real->heads = ask_num("BIOS Heads", ASK_DEC,
+ disk->real->heads, 1, maxhead, NULL);
+ disk->real->sectors = ask_num("BIOS Sectors", ASK_DEC,
+ disk->real->sectors, 1, maxsec, NULL);
+
+ disk->real->size = disk->real->cylinders * disk->real->heads
+ * disk->real->sectors;
+ }
+
+ return (CMD_CONT);
+}
+
+int
+Xedit(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ int pn, num, ret;
+ prt_t *pp;
+
+ ret = CMD_CONT;
+
+ if (!isdigit(cmd->args[0])) {
+ printf("Invalid argument: %s <partition number>\n", cmd->cmd);
+ return (ret);
+ }
+ pn = atoi(cmd->args) - 1;
+
+ if (pn < 0 || pn > 3) {
+ printf("Invalid partition number.\n");
+ return (ret);
+ }
+
+ /* Print out current table entry */
+ pp = &mbr->part[pn];
+ PRT_print(0, NULL);
+ PRT_print(pn, pp);
+
+#define EDIT(p, f, v, n, m, h) \
+ if ((num = ask_num(p, f, v, n, m, h)) != v) \
+ ret = CMD_DIRTY; \
+ v = num;
+
+ /* Ask for partition type */
+ EDIT("Partition id ('0' to disable) ", ASK_HEX, pp->id, 0, 0xFF, PRT_printall);
+
+ /* Unused, so just zero out */
+ if (pp->id == DOSPTYP_UNUSED) {
+ memset(pp, 0, sizeof(*pp));
+ printf("Partition %d is disabled.\n", pn + 1);
+ return (ret);
+ }
+
+ /* Change table entry */
+ if (ask_yn("Do you wish to edit in CHS mode?", 0)) {
+ int maxcyl, maxhead, maxsect;
+
+ /* Shorter */
+ maxcyl = disk->real->cylinders - 1;
+ maxhead = disk->real->heads - 1;
+ maxsect = disk->real->sectors;
+
+ /* Get data */
+ EDIT("BIOS Starting cylinder", ASK_DEC, pp->scyl, 0, maxcyl, NULL);
+ EDIT("BIOS Starting head", ASK_DEC, pp->shead, 0, maxhead, NULL);
+ EDIT("BIOS Starting sector", ASK_DEC, pp->ssect, 1, maxsect, NULL);
+ EDIT("BIOS Ending cylinder", ASK_DEC, pp->ecyl, 0, maxcyl, NULL);
+ EDIT("BIOS Ending head", ASK_DEC, pp->ehead, 0, maxhead, NULL);
+ EDIT("BIOS Ending sector", ASK_DEC, pp->esect, 1, maxsect, NULL);
+ /* Fix up off/size values */
+ PRT_fix_BN(disk, pp, pn);
+ /* Fix up CHS values for LBA */
+ PRT_fix_CHS(disk, pp, pn);
+ } else {
+ u_int m;
+
+ if (pn == 0) {
+ pp->bs = 63 + offset;
+ } else {
+ if (mbr->part[pn-1].id != 0) {
+ pp->bs = mbr->part[pn-1].bs + mbr->part[pn-1].ns;
+ }
+ }
+ /* Get data */
+ EDIT("Partition offset", ASK_DEC, pp->bs, 0,
+ disk->real->size, NULL);
+ m = MAX(pp->ns, disk->real->size - pp->bs);
+ if ( m > disk->real->size - pp->bs) {
+ /* dont have default value extend beyond end of disk */
+ m = disk->real->size - pp->bs;
+ }
+ pp->ns = m;
+ EDIT("Partition size", ASK_DEC, pp->ns, 1,
+ m, NULL);
+
+ /* Fix up CHS values */
+ PRT_fix_CHS(disk, pp, pn);
+ }
+#undef EDIT
+ return (ret);
+}
+
+int
+Xsetpid(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ int pn, num, ret;
+ prt_t *pp;
+
+ ret = CMD_CONT;
+
+ if (!isdigit(cmd->args[0])) {
+ printf("Invalid argument: %s <partition number>\n", cmd->cmd);
+ return (ret);
+ }
+ pn = atoi(cmd->args) - 1;
+
+ if (pn < 0 || pn > 3) {
+ printf("Invalid partition number.\n");
+ return (ret);
+ }
+
+ /* Print out current table entry */
+ pp = &mbr->part[pn];
+ PRT_print(0, NULL);
+ PRT_print(pn, pp);
+
+#define EDIT(p, f, v, n, m, h) \
+ if ((num = ask_num(p, f, v, n, m, h)) != v) \
+ ret = CMD_DIRTY; \
+ v = num;
+
+ /* Ask for partition type */
+ EDIT("Partition id ('0' to disable) ", ASK_HEX, pp->id, 0, 0xFF, PRT_printall);
+
+#undef EDIT
+ return (ret);
+}
+int
+Xselect(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ static int firstoff = 0;
+ int off;
+ int pn;
+
+ if (!isdigit(cmd->args[0])) {
+ printf("Invalid argument: %s <partition number>\n", cmd->cmd);
+ return (CMD_CONT);
+ }
+
+ pn = atoi(cmd->args) - 1;
+ if (pn < 0 || pn > 3) {
+ printf("Invalid partition number.\n");
+ return (CMD_CONT);
+ }
+
+ off = mbr->part[pn].bs;
+
+ /* Sanity checks */
+ if ((mbr->part[pn].id != DOSPTYP_EXTEND) &&
+ (mbr->part[pn].id != DOSPTYP_EXTENDL)) {
+ printf("Partition %d is not an extended partition.\n", pn + 1);
+ return (CMD_CONT);
+ }
+
+ if (firstoff == 0)
+ firstoff = off;
+
+ if (!off) {
+ printf("Loop to offset 0! Not selected.\n");
+ return (CMD_CONT);
+ } else {
+ printf("Selected extended partition %d\n", pn + 1);
+ printf("New MBR at offset %d.\n", off);
+ }
+
+ /* Recursion is beautifull! */
+ USER_modify(disk, tt, off, firstoff);
+ return (CMD_CONT);
+}
+
+int
+Xprint(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+
+ DISK_printmetrics(disk);
+ printf("Offset: %d\t", offset);
+ MBR_print(mbr);
+
+ return (CMD_CONT);
+}
+
+int
+Xwrite(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ int fd;
+ int shared = 0;
+
+ fd = DISK_openshared(disk->name, O_RDWR, &shared);
+ if(shared) {
+ if(!ask_yn("Device could not be accessed exclusively.\nA reboot will be needed for changes to take effect. OK?", 0)) {
+ close(fd);
+ printf("MBR unchanged\n");
+ return (CMD_CONT);
+ }
+ }
+
+ printf("Writing MBR at offset %d.\n", offset);
+
+ MBR_make(mbr);
+ MBR_write(disk, fd, mbr);
+ close(fd);
+ return (CMD_CLEAN);
+}
+
+int
+Xquit(cmd, disk, r, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *r;
+ mbr_t *tt;
+ int offset;
+{
+
+ /* Nothing to do here */
+ return (CMD_SAVE);
+}
+
+int
+Xabort(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ exit(0);
+
+ /* NOTREACHED */
+ return (CMD_CONT);
+}
+
+
+int
+Xexit(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+
+ /* Nothing to do here */
+ return (CMD_EXIT);
+}
+
+int
+Xhelp(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ cmd_table_t *cmd_table = cmd->table;
+ int i;
+
+ /* Hmm, print out cmd_table here... */
+ for (i = 0; cmd_table[i].cmd != NULL; i++)
+ printf("\t%s\t\t%s\n", cmd_table[i].cmd, cmd_table[i].help);
+ return (CMD_CONT);
+}
+
+int
+Xupdate(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ extern char *mbr_binary;
+ /* Update code */
+ memcpy(mbr->code, mbr_binary, MBR_CODE_SIZE);
+ printf("Machine code updated.\n");
+ return (CMD_DIRTY);
+}
+
+int
+Xflag(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ int i, pn = -1;
+
+ /* Parse partition table entry number */
+ if (!isdigit(cmd->args[0])) {
+ printf("Invalid argument: %s <partition number>\n", cmd->cmd);
+ return (CMD_CONT);
+ }
+ pn = atoi(cmd->args) - 1;
+
+ if (pn < 0 || pn > 3) {
+ printf("Invalid partition number.\n");
+ return (CMD_CONT);
+ }
+
+ /* Set active flag */
+ for (i = 0; i < 4; i++) {
+ if (i == pn)
+ mbr->part[i].flag = DOSACTIVE;
+ else
+ mbr->part[i].flag = 0x00;
+ }
+
+ printf("Partition %d marked active.\n", pn + 1);
+ return (CMD_DIRTY);
+}
+
+int
+Xmanual(cmd, disk, mbr, tt, offset)
+ cmd_t *cmd;
+ disk_t *disk;
+ mbr_t *mbr;
+ mbr_t *tt;
+ int offset;
+{
+ system("man 8 fdisk");
+ return (CMD_CONT);
+}
diff --git a/diskdev_cmds/fdisk.tproj/cmd.h b/diskdev_cmds/fdisk.tproj/cmd.h
new file mode 100644
index 0000000..0c2b727
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/cmd.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CMD_H
+#define _CMD_H
+
+/* Includes */
+#include "disk.h"
+#include "mbr.h"
+
+
+/* Constants (returned by cmd funs) */
+#define CMD_EXIT 0x0000
+#define CMD_SAVE 0x0001
+#define CMD_CONT 0x0002
+#define CMD_CLEAN 0x0003
+#define CMD_DIRTY 0x0004
+
+
+/* Data types */
+struct _cmd_table_t;
+typedef struct _cmd_t {
+ struct _cmd_table_t *table;
+ char cmd[10];
+ char args[100];
+} cmd_t;
+
+typedef struct _cmd_table_t {
+ char *cmd;
+ int (*fcn)(cmd_t *, disk_t *, mbr_t *, mbr_t *, int);
+ char *help;
+} cmd_table_t;
+
+
+/* Prototypes */
+int Xerase __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xreinit __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xauto __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xdisk __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xmanual __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xedit __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xsetpid __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xselect __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xprint __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xwrite __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xexit __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xquit __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xabort __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xhelp __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xflag __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+int Xupdate __P((cmd_t *, disk_t *, mbr_t *, mbr_t *, int));
+
+#endif /* _CMD_H */
+
+
diff --git a/diskdev_cmds/fdisk.tproj/disk.c b/diskdev_cmds/fdisk.tproj/disk.c
new file mode 100644
index 0000000..2d04113
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/disk.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2002, 2012 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 1997, 2001 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <util.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/reboot.h>
+#include <sys/disk.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#ifdef __i386__
+#include <pexpert/i386/boot.h>
+#endif
+#include "disk.h"
+
+int
+DISK_open(disk, mode)
+ char *disk;
+ int mode;
+{
+ int fd;
+ struct stat st;
+
+ fd = open(disk, mode);
+ if (fd == -1)
+ err(1, "%s", disk);
+ if (fstat(fd, &st) == -1)
+ err(1, "%s", disk);
+ /* Don't be so picky about needing a character device */
+ if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode))
+ errx(1, "%s is not a character device or a regular file", disk);
+ return (fd);
+}
+
+int
+DISK_openshared(disk, mode, shared)
+ char *disk;
+ int mode;
+ int *shared;
+{
+ int fd;
+ struct stat st;
+ *shared = 0;
+
+ fd = open(disk, mode|O_EXLOCK);
+ if (fd == -1) {
+ // if we can't have exclusive access, attempt
+ // to gracefully degrade to shared access
+ fd = open(disk, mode|O_SHLOCK);
+ if(fd == -1)
+ err(1, "%s", disk);
+
+ *shared = 1;
+ }
+
+ if (fstat(fd, &st) == -1)
+ err(1, "%s", disk);
+ /* Don't be so picky about needing a character device */
+ if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode))
+ errx(1, "%s is not a character device or a regular file", disk);
+ return (fd);
+}
+
+int
+DISK_close(fd)
+ int fd;
+{
+
+ return (close(fd));
+}
+
+/* Given a size in the metrics,
+ * fake up a CHS geometry.
+ */
+void
+DISK_fake_CHS(DISK_metrics *lm)
+{
+ int heads = 4;
+ int spt = 63;
+ int cylinders = (lm->size / heads / spt);
+
+ while (cylinders > 1024 && heads < 256) {
+ heads *= 2;
+ cylinders /= 2;
+ }
+ if (heads == 256) {
+ heads = 255;
+ cylinders = (lm->size / heads / spt);
+ }
+ lm->cylinders = cylinders;
+ lm->heads = heads;
+ lm->sectors = spt;
+}
+
+/* Routine to go after the disklabel for geometry
+ * information. This should work everywhere, but
+ * in the land of PC, things are not always what
+ * they seem.
+ */
+DISK_metrics *
+DISK_getlabelmetrics(name)
+ char *name;
+{
+ DISK_metrics *lm = NULL;
+ long long size;
+ uint32_t sector_size;
+ int fd;
+ struct stat st;
+
+ /* Get label metrics */
+ if ((fd = DISK_open(name, O_RDONLY)) != -1) {
+ lm = malloc(sizeof(DISK_metrics));
+
+ if (fstat(fd, &st) == -1)
+ err(1, "%s", name);
+ if (!S_ISREG(st.st_mode) || S_ISBLK(st.st_mode)) {
+ if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size) == -1) {
+ err(1, "Could not get disk block count");
+ free(lm);
+ return NULL;
+ }
+ if (ioctl(fd, DKIOCGETBLOCKSIZE, &sector_size) == -1) {
+ err(1, "Could not get disk block size");
+ free(lm);
+ return NULL;
+ }
+ } else {
+ sector_size = 512;
+ size = st.st_size / sector_size;
+ }
+
+ lm->sector_size = sector_size;
+ lm->size = size;
+ DISK_fake_CHS(lm);
+ DISK_close(fd);
+ }
+
+ return (lm);
+}
+
+/*
+ * Don't try to get BIOS disk metrics.
+ */
+DISK_metrics *
+DISK_getbiosmetrics(name)
+ char *name;
+{
+ return (NULL);
+}
+
+/* This is ugly, and convoluted. All the magic
+ * for disk geo/size happens here. Basically,
+ * the real size is the one we will use in the
+ * rest of the program, the label size is what we
+ * got from the disklabel. If the disklabel fails,
+ * we assume we are working with a normal file,
+ * and should request the user to specify the
+ * geometry he/she wishes to use.
+ */
+int
+DISK_getmetrics(disk, user)
+ disk_t *disk;
+ DISK_metrics *user;
+{
+
+ disk->label = DISK_getlabelmetrics(disk->name);
+ disk->bios = DISK_getbiosmetrics(disk->name);
+
+ /* If user supplied, use that */
+ if (user) {
+ disk->real = user;
+ return (0);
+ }
+
+ /* Fixup bios metrics to include cylinders past 1023 boundary */
+ if(disk->label && disk->bios){
+ int cyls, secs;
+
+ cyls = disk->label->size / (disk->bios->heads * disk->bios->sectors);
+ secs = cyls * (disk->bios->heads * disk->bios->sectors);
+ if (disk->label->size < secs) {
+ errx(1, "BIOS fixup botch (%u sectors)", disk->label->size - secs);
+ }
+ disk->bios->cylinders = cyls;
+ disk->bios->size = secs;
+ }
+
+ /* If we have a (fixed) BIOS geometry, use that */
+ if (disk->bios) {
+ disk->real = disk->bios;
+ return (0);
+ }
+
+ /* If we have a label, use that */
+ if (disk->label) {
+ disk->real = disk->label;
+ return (0);
+ }
+
+ /* Can not get geometry, punt */
+ disk->real = NULL;
+ return (1);
+}
+
+/* Get the disk's native sector size, updating the metrics' sector_size field.
+ */
+ int
+DISK_get_sector_size(disk, user)
+ disk_t *disk;
+ DISK_metrics *user;
+{
+ int ret;
+ int fd;
+ uint32_t sector_size;
+
+ /* Default to 512 bytes per sector, in case of failure. */
+ user->sector_size = 512;
+ ret = 1;
+
+ fd = DISK_open(disk->name, O_RDONLY);
+ if (fd == -1) {
+ err(1, "Could not open %s", disk->name);
+ } else {
+ if (ioctl(fd, DKIOCGETBLOCKSIZE, &sector_size) == -1) {
+ err(1, "Could not get disk block size");
+ } else {
+ user->sector_size = sector_size;
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
+int
+DISK_printmetrics(disk)
+ disk_t *disk;
+{
+
+ printf("Disk: %s\t", disk->name);
+ if (disk->real) {
+ printf("geometry: %u/%u/%u [%u sectors]\n", disk->real->cylinders,
+ disk->real->heads, disk->real->sectors, disk->real->size);
+ if (disk->real->sector_size != 512)
+ printf("Sector size: %u bytes\n", disk->real->sector_size);
+ } else {
+ printf("geometry: <none>\n");
+ }
+
+ return (0);
+}
+
diff --git a/diskdev_cmds/fdisk.tproj/disk.h b/diskdev_cmds/fdisk.tproj/disk.h
new file mode 100644
index 0000000..a8a97ef
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/disk.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2002,2012 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DISK_H
+#define _DISK_H
+
+/* Data types */
+typedef struct _DISK_metrics {
+ unsigned int cylinders;
+ unsigned int heads;
+ unsigned int sectors;
+ unsigned int size; /* Number of sectors in disk */
+ unsigned int sector_size; /* Bytes per sector */
+} DISK_metrics;
+
+typedef struct _disk_t {
+ char *name;
+ DISK_metrics *bios; /* Metrics as reported by BIOS (always NULL) */
+ DISK_metrics *label; /* As reported by device ioctls */
+ DISK_metrics *real; /* Metrics we're using (BIOS, ioctls, user-supplied) */
+} disk_t;
+
+/* Prototypes */
+int DISK_open __P((char *, int));
+int DISK_openshared __P((char *, int, int *));
+int DISK_close __P((int));
+int DISK_getmetrics __P((disk_t *, DISK_metrics *));
+int DISK_get_sector_size __P((disk_t *, DISK_metrics *));
+int DISK_printmetrics __P((disk_t *));
+void DISK_fake_CHS __P((DISK_metrics *));
+
+#endif /* _DISK_H */
+
diff --git a/diskdev_cmds/fdisk.tproj/fdisk.8 b/diskdev_cmds/fdisk.tproj/fdisk.8
new file mode 100644
index 0000000..c74c091
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/fdisk.8
@@ -0,0 +1,377 @@
+.\" $OpenBSD: fdisk.8,v 1.38 2002/01/04 21:20:56 kjell Exp $
+.\"
+.\" Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+.\"
+.\" "Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+.\" Reserved. This file contains Original Code and/or Modifications of
+.\" Original Code as defined in and that are subject to the Apple Public
+.\" Source License Version 1.2 (the 'License'). You may not use this file
+.\" except in compliance with the License. Please obtain a copy of the
+.\" License at http://www.apple.com/publicsource and read it before using
+.\" this file.
+.\"
+.\" The Original Code and all software distributed under the License are
+.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+.\" License for the specific language governing rights and limitations
+.\" under the License."
+.\"
+.\" Copyright (c) 1997 Tobias Weingartner
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 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. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Tobias Weingartner.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd January 3, 2002
+.Dt FDISK 8
+.Os
+.Sh NAME
+.Nm fdisk
+.Nd DOS partition maintenance program
+.Sh SYNOPSIS
+.Nm fdisk
+.Op Fl ieu
+.Op Fl f Ar mbrname
+.Op Fl c Ar cylinders
+.Op Fl h Ar heads
+.Op Fl s Ar sectors
+.Op Fl S Ar size
+.Op Fl b Ar size
+.Ar device
+.Sh DESCRIPTION
+In order for the BIOS to boot the kernel, certain conventions must be
+adhered to.
+Sector 0 of a bootable hard disk must contain boot code,
+an MBR partition table, and a magic number (0xAA55).
+These MBR partitions (also
+known as BIOS partitions) can be used to break the disk up into several
+pieces.
+.Pp
+The BIOS loads sector 0 of the boot disk into memory, verifies
+the magic number, and begins executing the code at the first byte.
+The normal DOS MBR boot code searches the MBR partition table for an
+.Dq active
+partition (indicated by a
+.Ql \&*
+in the first column), and if one
+is found, the boot block from that partition is loaded and executed in
+place of the original (MBR) boot block.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl i
+Initialize the MBR sector.
+.It Fl a Ar style
+Specify an automatic partitioning style.
+.It Fl e
+Edit existing MBR sectors.
+.It Fl f Ar mbrname
+Specifies an alternate MBR template file.
+.It Fl u
+Update MBR code, preserving existing partition table.
+.It Fl y
+Do not ask for confirmation before writing.
+.It Fl d
+Dump partition table in a format readable by the -r option.
+.It Fl r
+Read a partition table from the standard input.
+.It Fl t
+Test if the disk is partitioned.
+.It Xo Fl c Ar cylinders ,
+.Fl h Ar heads ,
+.Fl s Ar sectors
+.Xc
+Specifies an alternate BIOS geometry for
+.Nm
+to use.
+.It Fl S Ar size
+Specify the disk size in blocks.
+.It Fl b Ar size
+Specify the number of bytes per disk block.
+.El
+.Pp
+The DOS
+.Nm
+program can be used to divide space on the disk into partitions and set
+one active.
+This
+.Nm
+program serves a similar purpose to the DOS program.
+When called with no special flags, it prints the MBR partition
+table of the specified device, i.e.,
+.Bd -literal
+ # fdisk fd0
+ Disk: fd0 geometry: 80/2/18 [2880 sectors]
+ Offset: 0 Signature: 0xAA55
+ Starting Ending
+ #: id cyl hd sec - cyl hd sec [ start - size]
+ ----------------------------------------------------------------------
+ *1: A6 0 0 1 - 79 1 18 [ 0 - 2880] OpenBSD
+ 2: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
+ 3: A7 0 0 2 - 79 1 18 [ 1 - 2879] NEXTSTEP
+ 4: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
+.Ed
+.Pp
+The geometry displayed is a synthetic geometry unless another geometry
+has been selected using the
+.Fl c ,
+.Fl h ,
+.Fl s ,
+.Fl S ,
+and
+.Fl b
+options.
+In the future,
+.Nm
+will read the BIOS geometry from the IOKit registry.
+.Pp
+In this example,
+the disk is divided into two partitions that happen to fill the disk.
+The first partition overlaps the third partition.
+(Used for debugging purposes.)
+.Bl -tag -width "start/size"
+.It Em "#"
+Number of partition table entry.
+A
+.Dq \&*
+denotes the bootable partition.
+.It Em "id"
+System identifier.
+.Ox
+reserves the
+magic number 166 decimal (A6 in hex).
+If no 166 partition is found, it will use an older
+.Fx
+partition (with a magic number of 165 or A5 in hex).
+.It Em "cyl/hd/sec"
+These fields provide the starting and ending address of the partition
+in BIOS geometry
+.It Em "start/size"
+These fields provide the starting sector and size in sectors of the
+partition in linear block addresses.
+.El
+.Pp
+.Em NOTE :
+The sectors field is
+.Dq 1 based ,
+and the start field is
+.Dq 0 based .
+The CHS values may need to be in the BIOS's geometry
+for older systems to be able to boot and use the drive correctly;
+most modern systems prefer the starting sector and size
+in preference to the CHS values.
+.Pp
+The
+.Fl i
+flag is used to indicate that the partition data is to be initialized.
+In this mode,
+.Nm
+will completely overwrite the primary MBR and partition table, either
+using the default MBR template, or the one specified by the
+.Fl f
+flag.
+.Pp
+In the default template, partition number 1 will be configured as a
+Darwin boot
+partition spanning from cylinder 0, head 1, sector 1, and extending
+for 8 megabytes.
+Partition number 2 will be configured as a
+Darwin HFS
+partition spanning the rest of the disk.
+This mode is designed to initialize an MBR the very first time,
+or when it has been corrupted beyond repair.
+.Pp
+You can specify other default partition styles with the
+.Fl a
+flag. The available styles are:
+.Bl -tag -width "start/size"
+.It Em "boothfs"
+Creates an 8Mb boot partition (type AB hex)
+and makes the rest of the disk
+a Darwin HFS partition (type AF hex).
+.It Em "hfs"
+Makes the entire disk one HFS+ partition (type AF hex).
+.It Em "dos"
+Makes the entire disk one DOS partition (type 0C hex).
+.It Em "raid"
+Makes the entire disk one type AC hex partition.
+.El
+.Pp
+The
+.Fl u
+flag is used to update the MBR code on a given drive.
+The MBR code extends from offset 0x000 to the start of the partition table
+at offset 0x1BE.
+It is similar to the
+.Fl i
+flag, except the existing partition table is preserved. This
+is useful for writing new MBR code onto an existing drive, and is
+equivalent to the DOS command
+.Dq FDISK /MBR .
+Note that this option will overwrite the NT disk signature, if present.
+The
+.Fl u
+and
+.Fl i
+flags may not be specified together.
+.Pp
+The flag
+.Fl e
+is used to modify a partition table using a interactive edit mode of the
+.Nm
+program.
+This mode is designed to allow you to change any partition on the
+drive you choose, including extended partitions.
+It is a very powerful mode,
+but is safe as long as you do not execute the
+.Em write
+command, or answer in the negative (the default) when
+.Nm
+asks you about writing out changes.
+.Sh COMMAND MODE
+When you first enter this mode, you are presented with a prompt, that looks
+like so:
+.Em "fdisk: 0>" .
+This prompt has two important pieces of information for you.
+It will tell
+you if the in-memory copy of the boot block has been modified or not.
+If it has been modified, the prompt will change to look like:
+.Em "fdisk:*0>" .
+The second piece of information pertains to the number given in the prompt.
+This number specifies the disk offset of the currently selected boot block
+you are editing.
+This number could be something different that zero when
+you are editing extended partitions.
+The list of commands and their explanations are given below.
+.Bl -tag -width "update"
+.It Em help
+Display a list of commands that
+.Nm
+understands in the interactive edit mode.
+.It Em manual
+Display this manual page.
+.It Em reinit
+Initialize the currently selected, in-memory copy of the
+boot block.
+.It Em auto
+Partition the disk with one of the automatic partition styles.
+.It Em disk
+Display the current drive geometry that
+.Nm
+has
+probed.
+You are given a chance to edit it if you wish.
+.It Em edit
+Edit a given table entry in the memory copy of
+the current boot block.
+You may edit either in BIOS geometry mode,
+or in sector offsets and sizes.
+.It Em setpid
+Change the partition
+identifier of the given partition table entry.
+This command is particularly useful for reassigning
+an existing partition to OpenBSD.
+.It Em flag
+Make the given partition table entry bootable.
+Only one entry can be marked bootable.
+If you wish to boot from an extended
+partition, you will need to mark the partition table entry for the
+extended partition as bootable.
+.It Em update
+Update the machine code in the memory copy of the currently selected
+boot block.
+Note that this option will overwrite the NT disk
+signature, if present.
+.It Em select
+Select and load into memory the boot block pointed
+to by the extended partition table entry in the current boot block.
+.It Em print
+Print the currently selected in-memory copy of the boot
+block and its MBR table to the terminal.
+.It Em write
+Write the in-memory copy of the boot block to disk.
+You will be asked to confirm this operation.
+.It Em exit
+Exit the current level of
+.Nm fdisk ,
+either returning to the
+previously selected in-memory copy of a boot block, or exiting the
+program if there is none.
+.It Em quit
+Exit the current level of
+.Nm fdisk ,
+either returning to the
+previously selected in-memory copy of a boot block, or exiting the
+program if there is none.
+Unlike
+.Em exit
+it does write the modified block out.
+.It Em abort
+Quit program without saving current changes.
+.El
+.Sh NOTES
+The automatic calculation of starting cylinder etc. uses
+a set of figures that represent what the BIOS thinks is the
+geometry of the drive.
+These figures are by default taken from the in-core disklabel, or
+values that
+.Em /boot
+has passed to the kernel, but
+.Nm
+gives you an opportunity to change them if there is a need to.
+This allows the user to create a bootblock that can work with drives
+that use geometry translation under a potentially different BIOS.
+.Pp
+If you hand craft your disk layout,
+please make sure that the
+.Ox
+partition starts on a cylinder boundary.
+(This restriction may be changed in the future.)
+.Pp
+Editing an existing partition is risky, and may cause you to
+lose all the data in that partition.
+.Pp
+You should run this program interactively once or twice to see how it works.
+This is completely safe as long as you answer the
+.Dq write
+questions in the
+negative.
+.Sh FILES
+.Bl -tag -width /usr/mdec/mbr -compact
+.It Pa /usr/mdec/mbr
+default MBR template
+.El
+.Sh SEE ALSO
+.Xr gpt 8 ,
+.Xr pdisk 8
+.Sh BUGS
+There are subtleties
+.Nm
+detects that are not explained in this manual page.
+As well, chances are that some of the subtleties it should detect are being
+steamrolled.
+Caveat Emptor.
diff --git a/diskdev_cmds/fdisk.tproj/fdisk.c b/diskdev_cmds/fdisk.tproj/fdisk.c
new file mode 100644
index 0000000..e7b45cb
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/fdisk.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include "disk.h"
+#include "user.h"
+#include "auto.h"
+
+#define _PATH_MBR "/usr/standalone/i386/boot0"
+
+void
+usage()
+{
+ extern char * __progname;
+ fprintf(stderr, "usage: %s "
+ "[-ieu] [-f mbrboot] [-c cyl -h head -s sect] [-S size] [-r] [-a style] disk\n"
+ "\t-i: initialize disk with new MBR\n"
+ "\t-u: update MBR code, preserve partition table\n"
+ "\t-e: edit MBRs on disk interactively\n"
+ "\t-f: specify non-standard MBR template\n"
+ "\t-chs: specify disk geometry\n"
+ "\t-S: specify disk size\n"
+ "\t-r: read partition specs from stdin (implies -i)\n"
+ "\t-a: auto-partition with the given style\n"
+ "\t-d: dump partition table\n"
+ "\t-y: don't ask any questions\n"
+ "\t-t: test if disk is partitioned\n"
+ "`disk' is of the form /dev/rdisk0.\n",
+ __progname);
+ fprintf(stderr, "auto-partition styles:\n");
+ AUTO_print_styles(stderr);
+ exit(1);
+}
+
+char *mbr_binary = NULL;
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int ch, fd;
+ int i_flag = 0, m_flag = 0, u_flag = 0, r_flag = 0, d_flag = 0, y_flag = 0, t_flag = 0;
+ int c_arg = 0, h_arg = 0, s_arg = 0;
+ int size_arg = 0;
+ int block_size_arg = 0;
+ disk_t disk;
+ DISK_metrics *usermetrics;
+ char *mbrfile = _PATH_MBR;
+ mbr_t *mp;
+ char *auto_style = NULL;
+
+ while ((ch = getopt(argc, argv, "ieuf:c:h:s:b:S:ra:dyt")) != -1) {
+ switch(ch) {
+ case 'i':
+ i_flag = 1;
+ break;
+ case 'u':
+ u_flag = 1;
+ break;
+ case 'e':
+ m_flag = 1;
+ break;
+ case 'f':
+ mbrfile = optarg;
+ break;
+ case 'c':
+ c_arg = atoi(optarg);
+ if (c_arg < 1 || c_arg > 262144)
+ errx(1, "Cylinder argument out of range.");
+ break;
+ case 'h':
+ h_arg = atoi(optarg);
+ if (h_arg < 1 || h_arg > 256)
+ errx(1, "Head argument out of range.");
+ break;
+ case 's':
+ s_arg = atoi(optarg);
+ if (s_arg < 1 || s_arg > 63)
+ errx(1, "Sector argument out of range.");
+ break;
+ case 'b':
+ block_size_arg = atoi(optarg);
+ if (block_size_arg & (block_size_arg - 1))
+ errx(1, "Block size argument not a power of two.");
+ if (block_size_arg < 512 || block_size_arg > 4096)
+ errx(1, "Block size argument out of range 512..4096.");
+ break;
+ case 'S':
+ size_arg = atoi(optarg);
+ break;
+ case 'r':
+ r_flag = 1;
+ break;
+ case 'a':
+ auto_style = optarg;
+ break;
+ case 'd':
+ d_flag = 1;
+ break;
+ case 'y':
+ y_flag = 1;
+ break;
+ case 't':
+ t_flag = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ /* Argument checking */
+ if (argc != 1)
+ usage();
+ else
+ disk.name = argv[0];
+
+ if (i_flag && u_flag) errx(1, "-i and -u cannot be specified simultaneously");
+
+ /* Put in supplied geometry if there */
+ if (c_arg | h_arg | s_arg | size_arg | block_size_arg) {
+ usermetrics = malloc(sizeof(DISK_metrics));
+ if (usermetrics != NULL) {
+ if (c_arg && h_arg && s_arg) {
+ usermetrics->cylinders = c_arg;
+ usermetrics->heads = h_arg;
+ usermetrics->sectors = s_arg;
+ if (size_arg) {
+ usermetrics->size = size_arg;
+ } else {
+ usermetrics->size = c_arg * h_arg * s_arg;
+ }
+ } else {
+ if (size_arg) {
+ usermetrics->size = size_arg;
+ DISK_fake_CHS(usermetrics);
+ } else {
+ errx(1, "Please specify a full geometry with [-chs].");
+ }
+ }
+ if (block_size_arg) {
+ usermetrics->sector_size = block_size_arg;
+ } else {
+ DISK_get_sector_size(&disk, usermetrics);
+ }
+ }
+ } else {
+ usermetrics = NULL;
+ }
+
+ /* Get the geometry */
+ disk.real = NULL;
+ if (DISK_getmetrics(&disk, usermetrics))
+ errx(1, "Can't get disk geometry, please use [-chs] to specify.");
+
+ /* If only testing, read MBR and silently exit */
+ if (t_flag) {
+ mbr_t *mbr;
+
+ mp = mbr = MBR_read_all(&disk);
+ while (mp) {
+ if (mp->signature != MBR_SIGNATURE) {
+ MBR_free(mbr);
+ exit(1);
+ }
+ mp = mp->next;
+ }
+ MBR_free(mbr);
+ exit(0);
+ }
+
+ /* If not editing the disk, print out current MBRs on disk */
+ if ((i_flag + r_flag + u_flag + m_flag) == 0) {
+ exit(USER_print_disk(&disk, d_flag));
+ }
+
+ /* Parse mbr template or read partition specs, to pass on later */
+ if (auto_style && r_flag) {
+ errx(1, "Can't specify both -r and -a");
+ }
+
+ mbr_binary = (char *)malloc(MBR_CODE_SIZE);
+ if ((fd = open(mbrfile, O_RDONLY)) == -1) {
+ warn("could not open MBR file %s", mbrfile);
+ bzero(mbr_binary, MBR_CODE_SIZE);
+ } else {
+ int cc;
+ cc = read(fd, mbr_binary, MBR_CODE_SIZE);
+ if (cc < MBR_CODE_SIZE) {
+ err(1, "could not read MBR code");
+ }
+ close(fd);
+ }
+
+ if (u_flag) {
+ /* Don't hose the partition table; just write the boot code */
+ mp = MBR_read_all(&disk);
+ bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
+ MBR_make(mp);
+ } else if (i_flag) {
+ /* If they didn't specify -a, they'll get the default auto style */
+ mp = MBR_alloc(NULL);
+ if (AUTO_init(&disk, auto_style, mp) != AUTO_OK) {
+ errx(1, "error initializing disk");
+ }
+ bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
+ MBR_make(mp);
+ } else if (r_flag) {
+ mp = MBR_parse_spec(stdin, &disk);
+ bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
+ MBR_make(mp);
+ } else {
+ /* Use what's on the disk. */
+ mp = MBR_read_all(&disk);
+ }
+
+ /* Now do what we are supposed to */
+ if (i_flag || r_flag || u_flag) {
+ USER_write(&disk, mp, u_flag, y_flag);
+ }
+
+ if (m_flag) {
+ USER_modify(&disk, mp, 0, 0);
+ }
+
+ if (mbr_binary)
+ free(mbr_binary);
+
+ return (0);
+}
diff --git a/diskdev_cmds/fdisk.tproj/getrawpartition.c b/diskdev_cmds/fdisk.tproj/getrawpartition.c
new file mode 100644
index 0000000..9cfcb35
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/getrawpartition.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. 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
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: getrawpartition.c,v 1.4 1999/07/02 15:49:12 simonb Exp $");
+#endif
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <util.h>
+
+int
+getrawpartition()
+{
+#if 0
+ int rawpart, mib[2];
+ size_t varlen;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_RAWPARTITION;
+ varlen = sizeof(rawpart);
+ if (sysctl(mib, 2, &rawpart, &varlen, NULL, 0) < 0)
+ return (-1);
+
+ return (rawpart);
+#else
+ return 0 - 'a';
+#endif
+}
diff --git a/diskdev_cmds/fdisk.tproj/mbr.c b/diskdev_cmds/fdisk.tproj/mbr.c
new file mode 100644
index 0000000..90c8809
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/mbr.c
@@ -0,0 +1,553 @@
+/*
+ * Copyright (c) 2002, 2005 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <util.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <memory.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#if 0
+#include <sys/dkio.h>
+#endif
+#include <machine/param.h>
+#include "disk.h"
+#include "misc.h"
+#include "mbr.h"
+#include "part.h"
+
+
+void
+MBR_init(disk, mbr)
+ disk_t *disk;
+ mbr_t *mbr;
+{
+ /* Fix up given mbr for this disk */
+ mbr->part[0].flag = 0;
+ mbr->part[1].flag = 0;
+ mbr->part[2].flag = 0;
+#if !defined(DOSPTYP_OPENBSD)
+ mbr->part[3].flag = 0;
+ mbr->signature = MBR_SIGNATURE;
+#else
+
+ mbr->part[3].flag = DOSACTIVE;
+ mbr->signature = DOSMBR_SIGNATURE;
+
+ /* Use whole disk, save for first head, on first cyl. */
+ mbr->part[3].id = DOSPTYP_OPENBSD;
+ mbr->part[3].scyl = 0;
+ mbr->part[3].shead = 1;
+ mbr->part[3].ssect = 1;
+
+ /* Go right to the end */
+ mbr->part[3].ecyl = disk->real->cylinders - 1;
+ mbr->part[3].ehead = disk->real->heads - 1;
+ mbr->part[3].esect = disk->real->sectors;
+
+ /* Fix up start/length fields */
+ PRT_fix_BN(disk, &mbr->part[3], 3);
+
+#if defined(__powerpc__) || defined(__mips__)
+ /* Now fix up for the MS-DOS boot partition on PowerPC. */
+ mbr->part[0].flag = DOSACTIVE; /* Boot from dos part */
+ mbr->part[3].flag = 0;
+ mbr->part[3].ns += mbr->part[3].bs;
+ mbr->part[3].bs = mbr->part[0].bs + mbr->part[0].ns;
+ mbr->part[3].ns -= mbr->part[3].bs;
+ PRT_fix_CHS(disk, &mbr->part[3], 3);
+ if ((mbr->part[3].shead != 1) || (mbr->part[3].ssect != 1)) {
+ /* align the partition on a cylinder boundary */
+ mbr->part[3].shead = 0;
+ mbr->part[3].ssect = 1;
+ mbr->part[3].scyl += 1;
+ }
+ /* Fix up start/length fields */
+ PRT_fix_BN(disk, &mbr->part[3], 3);
+#endif
+#endif
+}
+
+void
+MBR_parse(disk, offset, reloff, mbr)
+ disk_t *disk;
+ off_t offset;
+ off_t reloff;
+ mbr_t *mbr;
+{
+ int i;
+ unsigned char *mbr_buf = mbr->buf;
+
+ memcpy(mbr->code, mbr_buf, MBR_CODE_SIZE);
+ mbr->offset = offset;
+ mbr->reloffset = reloff;
+ mbr->signature = getshort(&mbr_buf[MBR_SIG_OFF]);
+
+ for (i = 0; i < NDOSPART; i++)
+ PRT_parse(disk, &mbr_buf[MBR_PART_OFF + MBR_PART_SIZE * i],
+ offset, reloff, &mbr->part[i], i);
+}
+
+void
+MBR_make(mbr)
+ mbr_t *mbr;
+{
+ int i;
+ unsigned char *mbr_buf = mbr->buf;
+
+ memcpy(mbr_buf, mbr->code, MBR_CODE_SIZE);
+ putshort(&mbr_buf[MBR_SIG_OFF], mbr->signature);
+
+ for (i = 0; i < NDOSPART; i++)
+ PRT_make(&mbr->part[i], mbr->offset, mbr->reloffset,
+ &mbr_buf[MBR_PART_OFF + MBR_PART_SIZE * i]);
+}
+
+void
+MBR_print(mbr)
+ mbr_t *mbr;
+{
+ int i;
+
+ /* Header */
+ printf("Signature: 0x%X\n",
+ (int)mbr->signature);
+ PRT_print(0, NULL);
+
+ /* Entries */
+ for (i = 0; i < NDOSPART; i++)
+ PRT_print(i, &mbr->part[i]);
+}
+
+int
+MBR_read(disk, fd, where, mbr)
+ disk_t *disk;
+ int fd;
+ off_t where;
+ mbr_t *mbr;
+{
+ off_t off;
+ int len;
+ int size;
+ unsigned char *buf = mbr->buf;
+
+ size = disk->real->sector_size;
+ where *= size;
+ off = lseek(fd, where, SEEK_SET);
+ if (off != where)
+ return (off);
+ len = read(fd, buf, size);
+ if (len != size)
+ return (len);
+ return (0);
+}
+
+int
+MBR_write(disk, fd, mbr)
+ disk_t *disk;
+ int fd;
+ mbr_t *mbr;
+{
+ off_t off;
+ int len;
+ int size;
+ unsigned char *buf = mbr->buf;
+ off_t where;
+
+ size = disk->real->sector_size;
+ where = mbr->offset * size;
+ off = lseek(fd, where, SEEK_SET);
+ if (off != where)
+ return (off);
+ len = write(fd, buf, size);
+ if (len != size)
+ return (len);
+#if defined(DIOCRLDINFO)
+ (void) ioctl(fd, DIOCRLDINFO, 0);
+#endif
+ return (0);
+}
+
+void
+MBR_pcopy(disk, mbr)
+ disk_t *disk;
+ mbr_t *mbr;
+{
+ /*
+ * Copy partition table from the disk indicated
+ * to the supplied mbr structure
+ */
+
+ int i, fd, offset = 0, reloff = 0;
+ mbr_t *mbrd;
+
+ mbrd = MBR_alloc(NULL);
+ fd = DISK_open(disk->name, O_RDONLY);
+ MBR_read(disk, fd, offset, mbrd);
+ DISK_close(fd);
+ MBR_parse(disk, offset, reloff, mbrd);
+ for (i = 0; i < NDOSPART; i++) {
+ PRT_parse(disk, &mbrd->buf[MBR_PART_OFF +
+ MBR_PART_SIZE * i],
+ offset, reloff, &mbr->part[i], i);
+ PRT_print(i, &mbr->part[i]);
+ }
+ MBR_free(mbrd);
+}
+
+
+static int
+parse_number(char *str, int default_val, int base) {
+ if (str != NULL && *str != '\0') {
+ default_val = strtol(str, NULL, base);
+ }
+ return default_val;
+}
+
+static inline int
+null_arg(char *arg) {
+ if (arg == NULL || *arg == 0)
+ return 1;
+ else
+ return 0;
+}
+
+/* Parse a partition spec into a partition structure.
+ * Spec is of the form:
+ * <start>,<size>,<id>,<bootable>[,<c,h,s>,<c,h,s>]
+ * We require passing in the disk and mbr so we can
+ * set reasonable defaults for values, e.g. "the whole disk"
+ * or "starting after the last partition."
+ */
+#define N_ARGS 10
+static int
+MBR_parse_one_spec(char *line, disk_t *disk, mbr_t *mbr, int pn)
+{
+ int i;
+ char *args[N_ARGS];
+ prt_t *part = &mbr->part[pn];
+ int next_start, next_size;
+
+ /* There are up to 10 arguments. */
+ for (i=0; i<N_ARGS; i++) {
+ char *arg;
+ while (isspace(*line))
+ line++;
+ arg = strsep(&line, ",\n");
+ if (arg == NULL || line == NULL) {
+ break;
+ }
+ args[i] = arg;
+ }
+ for (; i<N_ARGS; i++) {
+ args[i] = NULL;
+ }
+ /* Set reasonable defaults. */
+ if (pn == 0) {
+ next_start = 0;
+ } else {
+ next_start = mbr->part[pn-1].bs + mbr->part[pn-1].ns;
+ }
+ next_size = disk->real->size;
+ for(i=0; i<pn; i++) {
+ next_size -= mbr->part[i].ns;
+ }
+
+ part->id = parse_number(args[2], 0xA8, 16);
+ if (!null_arg(args[3]) && *args[3] == '*') {
+ part->flag = 0x80;
+ } else {
+ part->flag = 0;
+ }
+ /* If you specify the start or end sector,
+ you have to give both. */
+ if ((null_arg(args[0]) && !null_arg(args[1])) ||
+ (!null_arg(args[0]) && null_arg(args[1]))) {
+ errx(1, "You must specify both start and size, or neither");
+ return -1;
+ }
+
+ /* If you specify one of the CHS args,
+ you have to give them all. */
+ if (!null_arg(args[4])) {
+ for (i=5; i<10; i++) {
+ if (null_arg(args[i])) {
+ errx(1, "Either all CHS arguments must be specified, or none");
+ return -1;
+ }
+ }
+
+ part->scyl = parse_number(args[4], 0, 10);
+ part->shead = parse_number(args[5], 0, 10);
+ part->ssect = parse_number(args[6], 0, 10);
+ part->scyl = parse_number(args[7], 0, 10);
+ part->shead = parse_number(args[8], 0, 10);
+ part->ssect = parse_number(args[9], 0, 10);
+ if (null_arg(args[0])) {
+ PRT_fix_BN(disk, part, pn);
+ }
+ } else {
+ /* See if they gave no CHS and no start/end */
+ if (null_arg(args[0])) {
+ errx(1, "You must specify either start sector and size or CHS");
+ return -1;
+ }
+ }
+ if (!null_arg(args[0])) {
+ part->bs = parse_number(args[0], next_start, 10);
+ part->ns = parse_number(args[1], next_size, 10);
+ PRT_fix_CHS(disk, part, pn);
+ }
+ return 0;
+}
+
+
+typedef struct _mbr_chain {
+ mbr_t mbr;
+ struct _mbr_chain *next;
+} mbr_chain_t;
+
+/* Parse some number of MBR spec lines.
+ * Spec is of the form:
+ * <start>,<size>,<id>,<bootable>[,<c,h,s>,<c,h,s>]
+ *
+ */
+mbr_t *
+MBR_parse_spec(FILE *f, disk_t *disk)
+{
+ int lineno;
+ int offset, firstoffset;
+ mbr_t *mbr, *head, *prev_mbr;
+
+ head = mbr = prev_mbr = NULL;
+ firstoffset = 0;
+ do {
+
+ offset = 0;
+ for (lineno = 0; lineno < NDOSPART && !feof(f); lineno++) {
+ char line[256];
+ char *str;
+ prt_t *part;
+
+ do {
+ str = fgets(line, 256, f);
+ } while ((str != NULL) && (*str == '\0'));
+ if (str == NULL) {
+ break;
+ }
+
+ if (mbr == NULL) {
+ mbr = MBR_alloc(prev_mbr);
+ if (head == NULL)
+ head = mbr;
+ }
+
+ if (MBR_parse_one_spec(line, disk, mbr, lineno)) {
+ /* MBR_parse_one_spec printed the error message. */
+ return NULL;
+ }
+ part = &mbr->part[lineno];
+ if ((part->id == DOSPTYP_EXTEND) || (part->id == DOSPTYP_EXTENDL)) {
+ offset = part->bs;
+ if (firstoffset == 0) firstoffset = offset;
+ }
+ }
+ /* If fewer lines than partitions, zero out the rest of the partitions */
+ if (mbr != NULL) {
+ for (; lineno < NDOSPART; lineno++) {
+ bzero(&mbr->part[lineno], sizeof(prt_t));
+ }
+ }
+ prev_mbr = mbr;
+ mbr = NULL;
+ } while (offset >= 0 && !feof(f));
+
+ return head;
+}
+
+void
+MBR_dump(mbr_t *mbr)
+{
+ int i;
+ prt_t *part;
+
+ for (i=0; i<NDOSPART; i++) {
+ part = &mbr->part[i];
+ printf("%d,%d,0x%02X,%c,%u,%u,%u,%u,%u,%u\n",
+ part->bs,
+ part->ns,
+ part->id,
+ (part->flag == 0x80) ? '*' : '-',
+ part->scyl,
+ part->shead,
+ part->ssect,
+ part->ecyl,
+ part->ehead,
+ part->esect);
+ }
+}
+
+mbr_t *
+MBR_alloc(mbr_t *parent)
+{
+ mbr_t *mbr = (mbr_t *)malloc(sizeof(mbr_t));
+ bzero(mbr, sizeof(mbr_t));
+ if (parent) {
+ parent->next = mbr;
+ }
+ mbr->signature = MBR_SIGNATURE;
+ return mbr;
+}
+
+void
+MBR_free(mbr_t *mbr)
+{
+ mbr_t *tmp;
+ while (mbr) {
+ tmp = mbr->next;
+ free(mbr);
+ mbr = tmp;
+ }
+}
+
+/* Read and parse all the partition tables on the disk,
+ * including extended partitions.
+ */
+mbr_t *
+MBR_read_all(disk_t *disk)
+{
+ mbr_t *mbr = NULL, *head = NULL;
+ int i, fd, offset, firstoff;
+
+ fd = DISK_open(disk->name, O_RDONLY);
+ firstoff = offset = 0;
+ do {
+ mbr = MBR_alloc(mbr);
+ if (head == NULL) {
+ head = mbr;
+ }
+ MBR_read(disk, fd, offset, mbr);
+ MBR_parse(disk, offset, firstoff, mbr);
+ if (mbr->signature != MBR_SIGNATURE) {
+ /* The MBR signature is invalid. */
+ break;
+ }
+ offset = 0;
+ for (i=0; i<NDOSPART; i++) {
+ prt_t *part = &mbr->part[i];
+ if ((part->id == DOSPTYP_EXTEND) || (part->id == DOSPTYP_EXTENDL)) {
+ offset = part->bs;
+ if (firstoff == 0) {
+ firstoff = offset;
+ }
+ }
+ }
+ } while (offset > 0);
+ DISK_close(fd);
+
+ return head;
+}
+
+
+int
+MBR_write_all(disk_t *disk, mbr_t *mbr)
+{
+ int result = 0;
+ int fd;
+
+ fd = DISK_open(disk->name, O_RDWR);
+ while (mbr) {
+ MBR_make(mbr);
+ result = MBR_write(disk, fd, mbr);
+ if (result)
+ break;
+ mbr = mbr->next;
+ }
+ DISK_close(fd);
+ return result;
+}
+
+void
+MBR_print_all(mbr_t *mbr) {
+ while (mbr) {
+ MBR_print(mbr);
+ mbr = mbr->next;
+ }
+}
+
+void
+MBR_dump_all(mbr_t *mbr) {
+ while (mbr) {
+ MBR_dump(mbr);
+ mbr = mbr->next;
+ }
+}
+
+void
+MBR_clear(mbr_t *mbr) {
+ int i;
+ if (mbr->next) {
+ MBR_free(mbr->next);
+ mbr->next = NULL;
+ }
+ for (i=0; i<4; i++) {
+ bzero(&mbr->part[i], sizeof(mbr->part[i]));
+ }
+ bzero(&mbr->buf, sizeof(mbr->buf));
+}
+
diff --git a/diskdev_cmds/fdisk.tproj/mbr.h b/diskdev_cmds/fdisk.tproj/mbr.h
new file mode 100644
index 0000000..52247ee
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/mbr.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MBR_H
+#define _MBR_H
+
+#include "part.h"
+
+#ifndef NDOSPART
+#define NDOSPART 4
+#define DOSPTYP_UNUSED 0
+#define DOSPTYP_EXTEND 5
+#define DOSPTYP_EXTENDL 15
+#define DOSACTIVE 128
+#endif
+
+/* Various constants */
+#define MBR_CODE_SIZE 0x1BE
+#define MBR_PART_SIZE 0x10
+#define MBR_PART_OFF 0x1BE
+#define MBR_SIG_OFF 0x1FE
+/* MBR_BUF_SIZE is the largest sector size we support */
+#define MBR_BUF_SIZE 4096
+
+#define MBR_SIGNATURE 0xAA55
+
+/* MBR type */
+typedef struct _mbr_t {
+ off_t reloffset; /* the offset of the first extended partition that contains all the rest */
+ off_t offset; /* the absolute offset of this partition */
+ struct _mbr_t *next; /* pointer to the next MBR in an extended partition chain */
+ unsigned char code[MBR_CODE_SIZE];
+ unsigned short signature;
+ prt_t part[NDOSPART];
+ unsigned char buf[MBR_BUF_SIZE];
+} mbr_t;
+
+/* Prototypes */
+void MBR_print_disk __P((char *));
+void MBR_print __P((mbr_t *));
+void MBR_print_all __P((mbr_t *));
+void MBR_parse __P((disk_t *, off_t, off_t, mbr_t *));
+void MBR_make __P((mbr_t *));
+void MBR_init __P((disk_t *, mbr_t *));
+int MBR_read __P((disk_t *,int, off_t, mbr_t *));
+int MBR_write __P((disk_t *,int, mbr_t *));
+void MBR_pcopy __P((disk_t *, mbr_t *));
+mbr_t * MBR_parse_spec __P((FILE *, disk_t *));
+void MBR_dump __P((mbr_t *));
+void MBR_dump_all __P((mbr_t *));
+mbr_t *MBR_alloc __P((mbr_t *));
+void MBR_free __P((mbr_t *));
+mbr_t * MBR_read_all __P((disk_t *));
+int MBR_write_all __P((disk_t *, mbr_t *));
+void MBR_clear __P((mbr_t *));
+
+/* Sanity check */
+#include <machine/param.h>
+#if (DEV_BSIZE != 512)
+#error "DEV_BSIZE != 512, somebody better fix me!"
+#endif
+
+#endif /* _MBR_H */
+
diff --git a/diskdev_cmds/fdisk.tproj/mbrcode.h b/diskdev_cmds/fdisk.tproj/mbrcode.h
new file mode 100644
index 0000000..2b8182e
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/mbrcode.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 2000 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/* Largely generated by:
+ * hexdump -ve '8/1 "0x%02x, " "\n"' /usr/mdec/mbr
+ */
+0xfa, 0xea, 0x06, 0x00, 0xc0, 0x07, 0x8c, 0xc8,
+0x8e, 0xd8, 0x8e, 0xd0, 0xbc, 0xfc, 0xff, 0xfb,
+0xb0, 0x53, 0xe8, 0xe2, 0x00, 0xb8, 0xa0, 0x07,
+0x8e, 0xc0, 0x31, 0xf6, 0x31, 0xff, 0xb9, 0x00,
+0x02, 0xfc, 0xf2, 0xa4, 0xea, 0x29, 0x00, 0xa0,
+0x07, 0xb0, 0x52, 0xe8, 0xc9, 0x00, 0x1e, 0x07,
+0x0e, 0x1f, 0xf6, 0xc2, 0x80, 0x75, 0x0b, 0x66,
+0xbe, 0x13, 0x01, 0x00, 0x00, 0xe8, 0xab, 0x00,
+0xb2, 0x80, 0x66, 0xbe, 0xbe, 0x01, 0x00, 0x00,
+0x66, 0xb9, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x4c,
+0xe8, 0xa4, 0x00, 0x8a, 0x44, 0x00, 0x3c, 0x80,
+0x74, 0x18, 0x66, 0x83, 0xc6, 0x10, 0xe2, 0xee,
+0x66, 0xbe, 0x3c, 0x01, 0x00, 0x00, 0xe8, 0x82,
+0x00, 0xfa, 0xf4, 0xb0, 0x2e, 0xe8, 0x87, 0x00,
+0xeb, 0xf7, 0xb0, 0x42, 0xe8, 0x80, 0x00, 0x8b,
+0x14, 0x8b, 0x4c, 0x02, 0x66, 0xb8, 0x01, 0x02,
+0x00, 0x00, 0x31, 0xdb, 0xcd, 0x13, 0x73, 0x13,
+0x80, 0xfa, 0x80, 0x75, 0xaa, 0x66, 0xbe, 0x2f,
+0x01, 0x00, 0x00, 0xe8, 0x55, 0x00, 0xe8, 0x33,
+0x00, 0xeb, 0xce, 0xb0, 0x43, 0xe8, 0x57, 0x00,
+0x66, 0x31, 0xc0, 0x66, 0xbb, 0xfe, 0x01, 0x00,
+0x00, 0x67, 0x8b, 0x03, 0x66, 0x3d, 0x55, 0xaa,
+0x00, 0x00, 0x74, 0x0b, 0x66, 0xbe, 0x52, 0x01,
+0x00, 0x00, 0xe8, 0x2e, 0x00, 0xeb, 0xaa, 0xb0,
+0x47, 0xe8, 0x33, 0x00, 0x66, 0xea, 0x00, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x66, 0xbb,
+0x03, 0x01, 0x00, 0x00, 0x50, 0x88, 0xe0, 0x66,
+0x83, 0xe0, 0x0f, 0xd7, 0xe8, 0x18, 0x00, 0x58,
+0x66, 0x83, 0xe0, 0x0f, 0xd7, 0xe8, 0x0f, 0x00,
+0x5b, 0x58, 0xc3, 0x50, 0xfc, 0xac, 0x84, 0xc0,
+0x74, 0x0f, 0xe8, 0x02, 0x00, 0xeb, 0xf6, 0x50,
+0x53, 0xb4, 0x0e, 0x31, 0xdb, 0x43, 0xcd, 0x10,
+0x5b, 0x58, 0xc3, 0x30, 0x31, 0x32, 0x33, 0x34,
+0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
+0x44, 0x45, 0x46, 0x4d, 0x42, 0x52, 0x20, 0x6f,
+0x6e, 0x20, 0x66, 0x6c, 0x6f, 0x70, 0x70, 0x79,
+0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6c, 0x64, 0x20,
+0x42, 0x49, 0x4f, 0x53, 0x0d, 0x0a, 0x00, 0x52,
+0x65, 0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f,
+0x72, 0x0d, 0x0a, 0x00, 0x4e, 0x6f, 0x20, 0x61,
+0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x70, 0x61,
+0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x0d,
+0x0a, 0x00, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69,
+0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
+0x75, 0x72, 0x65, 0x0d, 0x0a, 0x00, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+0x01, 0x00, 0xa6, 0xff, 0xff, 0xff, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x55, 0xaa,
diff --git a/diskdev_cmds/fdisk.tproj/misc.c b/diskdev_cmds/fdisk.tproj/misc.c
new file mode 100644
index 0000000..a477001
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/misc.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "misc.h"
+
+
+int
+ask_cmd(cmd_t *cmd)
+{
+ char lbuf[100], *cp, *buf;
+
+ /* Get input */
+ if (fgets(lbuf, sizeof lbuf, stdin) == NULL)
+ errx(1, "eof");
+ lbuf[strlen(lbuf)-1] = '\0';
+
+ /* Parse input */
+ buf = lbuf;
+ buf = &buf[strspn(buf, " \t")];
+ cp = &buf[strcspn(buf, " \t")];
+ *cp++ = '\0';
+ strncpy(cmd->cmd, buf, 10);
+ buf = &cp[strspn(cp, " \t")];
+ strncpy(cmd->args, buf, 100);
+
+ return (0);
+}
+
+int
+ask_num(const char *str, int flags, unsigned int dflt, unsigned int low, unsigned int high, void (*help) __P((void)))
+{
+ char lbuf[100], *cp;
+ unsigned int num;
+
+ do {
+again:
+ num = dflt;
+ if (flags == ASK_HEX)
+ printf("%s [%X - %X]: [%X] ", str, low, high, num);
+ else
+ printf("%s [%u - %u]: [%u] ", str, low, high, num);
+ if (help)
+ printf("(? for help) ");
+
+ if (fgets(lbuf, sizeof lbuf, stdin) == NULL)
+ errx(1, "eof");
+ lbuf[strlen(lbuf)-1] = '\0';
+
+ if (help && lbuf[0] == '?') {
+ (*help)();
+ goto again;
+ }
+
+ /* Convert */
+ cp = lbuf;
+ num = strtoul(lbuf, &cp, ((flags==ASK_HEX)?16:10));
+
+ /* Make sure only number present */
+ if (cp == lbuf)
+ num = dflt;
+ if (*cp != '\0') {
+ printf("'%s' is not a valid number.\n", lbuf);
+ num = low - 1;
+ } else if (num < low || num > high) {
+ printf("'%u' is out of range.\n", num);
+ }
+ } while (num < low || num > high);
+
+ return (num);
+}
+
+int
+ask_yn(const char *str, int default_answer)
+{
+ int ch, first;
+
+ printf("%s [%c] ", str, default_answer ? 'y' : 'n');
+ fflush(stdout);
+
+ first = ch = getchar();
+ while (ch != '\n' && ch != EOF)
+ ch = getchar();
+
+ if (ch == EOF || first == EOF)
+ errx(1, "eof");
+
+ if (first == '\n')
+ return default_answer;
+
+ return (first == 'y' || first == 'Y');
+}
+
+u_int16_t
+getshort(void *p)
+{
+ unsigned char *cp = p;
+
+ return (cp[0] | (cp[1] << 8));
+}
+
+void
+putshort(void *p, u_int16_t l)
+{
+ unsigned char *cp = p;
+
+ *cp++ = l;
+ *cp++ = l >> 8;
+}
+
+u_int32_t
+getlong(void *p)
+{
+ unsigned char *cp = p;
+
+ return (cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24));
+}
+
+void
+putlong(void *p, u_int32_t l)
+{
+ unsigned char *cp = p;
+
+ *cp++ = l;
+ *cp++ = l >> 8;
+ *cp++ = l >> 16;
+ *cp++ = l >> 24;
+}
diff --git a/diskdev_cmds/fdisk.tproj/misc.h b/diskdev_cmds/fdisk.tproj/misc.h
new file mode 100644
index 0000000..d3fa6ae
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/misc.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MISC_H
+#define _MISC_H
+
+#include <sys/types.h>
+#include "cmd.h"
+
+/* Constants */
+#define ASK_HEX 0x01
+#define ASK_DEC 0x02
+
+/* Prototypes */
+int ask_cmd __P((cmd_t *));
+int ask_num __P((const char *, int, unsigned int, unsigned int, unsigned int, void (*help) __P((void))));
+int ask_yn __P((const char *, int));
+u_int16_t getshort __P((void *));
+u_int32_t getlong __P((void *));
+void putshort __P((void *, u_int16_t));
+void putlong __P((void *, u_int32_t));
+
+#endif /* _MISC_H */
+
diff --git a/diskdev_cmds/fdisk.tproj/opendev.c b/diskdev_cmds/fdisk.tproj/opendev.c
new file mode 100644
index 0000000..538e4e6
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/opendev.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * Copyright (c) 2000, Todd C. Miller. All rights reserved.
+ * Copyright (c) 1996, Jason Downs. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "util.h"
+/*
+ * This routine is a generic rewrite of the original code found in
+ * disklabel(8).
+ */
+
+int
+opendev(path, oflags, dflags, realpath)
+ char *path;
+ int oflags;
+ int dflags;
+ char **realpath;
+{
+ int fd;
+ char *slash, *prefix;
+ static char namebuf[PATH_MAX];
+
+ /* Initial state */
+ if (realpath)
+ *realpath = path;
+ fd = -1;
+ errno = ENOENT;
+
+ if (dflags & OPENDEV_BLCK)
+ prefix = ""; /* block device */
+ else
+ prefix = "r"; /* character device */
+
+ if ((slash = strchr(path, '/')))
+ fd = open(path, oflags);
+ else if (dflags & OPENDEV_PART) {
+ /*
+ * First try raw partition (for removable drives)
+ */
+ if (snprintf(namebuf, sizeof(namebuf), "%s%s%s%c",
+ _PATH_DEV, prefix, path, 'a' + getrawpartition())
+ < sizeof(namebuf)) {
+ fd = open(namebuf, oflags);
+ if (realpath)
+ *realpath = namebuf;
+ } else
+ errno = ENAMETOOLONG;
+ }
+ if (!slash && fd == -1 && errno == ENOENT) {
+ if (snprintf(namebuf, sizeof(namebuf), "%s%s%s",
+ _PATH_DEV, prefix, path) < sizeof(namebuf)) {
+ fd = open(namebuf, oflags);
+ if (realpath)
+ *realpath = namebuf;
+ } else
+ errno = ENAMETOOLONG;
+ }
+ return (fd);
+}
diff --git a/diskdev_cmds/fdisk.tproj/part.c b/diskdev_cmds/fdisk.tproj/part.c
new file mode 100644
index 0000000..7191442
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/part.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <util.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <machine/param.h>
+#include "disk.h"
+#include "misc.h"
+#include "mbr.h"
+
+
+static const struct part_type {
+ int type;
+ char sname[14];
+ char *lname;
+} part_types[] = {
+ { 0x00, "unused ", "unused"},
+ { 0x01, "DOS FAT-12 ", "Primary DOS with 12 bit FAT"},
+ { 0x02, "XENIX / ", "XENIX / filesystem"},
+ { 0x03, "XENIX /usr ", "XENIX /usr filesystem"},
+ { 0x04, "DOS FAT-16 ", "Primary DOS with 16 bit FAT"},
+ { 0x05, "Extended DOS", "Extended DOS"},
+ { 0x06, "DOS > 32MB ", "Primary 'big' DOS (> 32MB)"},
+ { 0x07, "HPFS/QNX/AUX", "OS/2 HPFS, QNX-2 or Advanced UNIX"},
+ { 0x08, "AIX fs ", "AIX filesystem"},
+ { 0x09, "AIX/Coherent", "AIX boot partition or Coherent"},
+ { 0x0A, "OS/2 Bootmgr", "OS/2 Boot Manager or OPUS"},
+ { 0x0B, "Win95 FAT-32", "Primary Win95 w/ 32-bit FAT"},
+ { 0x0C, "Win95 FAT32L", "Primary Win95 w/ 32-bit FAT LBA-mapped"},
+ { 0x0E, "DOS FAT-16 ", "Primary DOS w/ 16-bit FAT, CHS-mapped"},
+ { 0x0F, "Extended LBA", "Extended DOS LBA-mapped"},
+ { 0x10, "OPUS ", "OPUS"},
+ { 0x11, "OS/2 hidden ", "OS/2 BM: hidden DOS 12-bit FAT"},
+ { 0x12, "Compaq Diag.", "Compaq Diagnostics"},
+ { 0x14, "OS/2 hidden ", "OS/2 BM: hidden DOS 16-bit FAT <32M or Novell DOS 7.0 bug"},
+ { 0x16, "OS/2 hidden ", "OS/2 BM: hidden DOS 16-bit FAT >=32M"},
+ { 0x17, "OS/2 hidden ", "OS/2 BM: hidden IFS"},
+ { 0x18, "AST swap ", "AST Windows swapfile"},
+ { 0x19, "Willowtech ", "Willowtech Photon coS"},
+ { 0x20, "Willowsoft ", "Willowsoft OFS1"},
+ { 0x24, "NEC DOS ", "NEC DOS"},
+ { 0x38, "Theos ", "Theos"},
+ { 0x39, "Plan 9 ", "Plan 9"},
+ { 0x40, "VENIX 286 ", "VENIX 286 or LynxOS"},
+ { 0x41, "Lin/Minux DR", "Linux/MINIX (sharing disk with DRDOS) or Personal RISC boot"},
+ { 0x42, "LinuxSwap DR", "SFS or Linux swap (sharing disk with DRDOS)"},
+ { 0x43, "Linux DR ", "Linux native (sharing disk with DRDOS)"},
+ { 0x4D, "QNX 4.2 Pri ", "QNX 4.2 Primary"},
+ { 0x4E, "QNX 4.2 Sec ", "QNX 4.2 Secondary"},
+ { 0x4F, "QNX 4.2 Ter ", "QNX 4.2 Tertiary"},
+ { 0x50, "DM ", "DM (disk manager)"},
+ { 0x51, "DM ", "DM6 Aux1 (or Novell)"},
+ { 0x52, "CP/M or SysV", "CP/M or Microport SysV/AT"},
+ { 0x53, "DM ", "DM6 Aux3"},
+ { 0x54, "Ontrack ", "Ontrack"},
+ { 0x55, "EZ-Drive ", "EZ-Drive (disk manager)"},
+ { 0x56, "Golden Bow ", "Golden Bow (disk manager)"},
+ { 0x5C, "Priam ", "Priam Edisk (disk manager)"},
+ { 0x61, "SpeedStor ", "SpeedStor"},
+ { 0x63, "ISC, HURD, *", "ISC, System V/386, GNU HURD or Mach"},
+ { 0x64, "Netware 2.xx", "Novell Netware 2.xx"},
+ { 0x65, "Netware 3.xx", "Novell Netware 3.xx"},
+ { 0x66, "Netware 386 ", "Novell 386 Netware"},
+ { 0x67, "Novell ", "Novell"},
+ { 0x68, "Novell ", "Novell"},
+ { 0x69, "Novell ", "Novell"},
+ { 0x70, "DiskSecure ", "DiskSecure Multi-Boot"},
+ { 0x75, "PCIX ", "PCIX"},
+ { 0x80, "Minix (old) ", "Minix 1.1 ... 1.4a"},
+ { 0x81, "Minix (new) ", "Minix 1.4b ... 1.5.10"},
+ { 0x82, "Linux swap ", "Linux swap"},
+ { 0x83, "Linux files*", "Linux filesystem"},
+ { 0x93, "Amoeba file*", "Amoeba filesystem"},
+ { 0x94, "Amoeba BBT ", "Amoeba bad block table"},
+ { 0x84, "OS/2 hidden ", "OS/2 hidden C: drive"},
+ { 0x85, "Linux ext. ", "Linux extended"},
+ { 0x86, "NT FAT VS ", "NT FAT volume set"},
+ { 0x87, "NTFS VS ", "NTFS volume set or HPFS mirrored"},
+ { 0x93, "Amoeba FS ", "Amoeba filesystem"},
+ { 0x94, "Amoeba BBT ", "Amoeba bad block table"},
+ { 0x99, "Mylex ", "Mylex EISA SCSI"},
+ { 0x9F, "BSDI ", "BSDI BSD/OS"},
+ { 0xA0, "NotebookSave", "Phoenix NoteBIOS save-to-disk"},
+ { 0xA5, "FreeBSD ", "FreeBSD"},
+ { 0xA6, "OpenBSD ", "OpenBSD"},
+ { 0xA7, "NEXTSTEP ", "NEXTSTEP"},
+ { 0xA8, "Darwin UFS ", "Darwin UFS partition"},
+ { 0xA9, "NetBSD ", "NetBSD"},
+ { 0xAB, "Darwin Boot ", "Darwin boot partition"},
+ { 0xAF, "HFS+ ", "Darwin HFS+ partition"},
+ { 0xB7, "BSDI filesy*", "BSDI BSD/386 filesystem"},
+ { 0xB8, "BSDI swap ", "BSDI BSD/386 swap"},
+ { 0xC0, "CTOS ", "CTOS"},
+ { 0xC1, "DRDOSs FAT12", "DRDOS/sec (FAT-12)"},
+ { 0xC4, "DRDOSs < 32M", "DRDOS/sec (FAT-16, < 32M)"},
+ { 0xC6, "DRDOSs >=32M", "DRDOS/sec (FAT-16, >= 32M)"},
+ { 0xC7, "HPFS Disbled", "Syrinx (Cyrnix?) or HPFS disabled"},
+ { 0xDB, "CPM/C.DOS/C*", "Concurrent CPM or C.DOS or CTOS"},
+ { 0xE1, "SpeedStor ", "DOS access or SpeedStor 12-bit FAT extended partition"},
+ { 0xE3, "SpeedStor ", "DOS R/O or SpeedStor or Storage Dimensions"},
+ { 0xE4, "SpeedStor ", "SpeedStor 16-bit FAT extended partition < 1024 cyl."},
+ { 0xEB, "BeOS/i386 ", "BeOS for Intel"},
+ { 0xF1, "SpeedStor ", "SpeedStor or Storage Dimensions"},
+ { 0xF2, "DOS 3.3+ Sec", "DOS 3.3+ Secondary"},
+ { 0xF4, "SpeedStor ", "SpeedStor >1024 cyl. or LANstep or IBM PS/2 IML"},
+ { 0xFF, "Xenix BBT ", "Xenix Bad Block Table"},
+};
+
+void
+PRT_printall()
+{
+ int i, idrows;
+
+ idrows = ((sizeof(part_types)/sizeof(struct part_type))+3)/4;
+
+ printf("Choose from the following Partition id values:\n");
+ for (i = 0; i < idrows; i++) {
+ printf("%02X %s %02X %s %02X %s"
+ , part_types[i ].type, part_types[i ].sname
+ , part_types[i+idrows ].type, part_types[i+idrows ].sname
+ , part_types[i+idrows*2].type, part_types[i+idrows*2].sname
+ );
+ if ((i+idrows*3) < (sizeof(part_types)/sizeof(struct part_type))) {
+ printf(" %02X %s\n"
+ , part_types[i+idrows*3].type, part_types[i+idrows*3].sname );
+ }
+ else
+ printf( "\n" );
+ }
+}
+
+const char *
+PRT_ascii_id(id)
+ int id;
+{
+ static char unknown[] = "<Unknown ID>";
+ int i;
+
+ for (i = 0; i < sizeof(part_types)/sizeof(struct part_type); i++) {
+ if (part_types[i].type == id)
+ return (part_types[i].sname);
+ }
+
+ return (unknown);
+}
+
+void
+PRT_parse(disk, prt, offset, reloff, partn, pn)
+ disk_t *disk;
+ void *prt;
+ off_t offset;
+ off_t reloff;
+ prt_t *partn;
+ int pn;
+{
+ unsigned char *p = prt;
+ off_t off;
+
+ partn->flag = *p++;
+ partn->shead = *p++;
+
+ partn->ssect = (*p) & 0x3F;
+ partn->scyl = ((*p << 2) & 0xFF00) | (*(p+1));
+ p += 2;
+
+ partn->id = *p++;
+ partn->ehead = *p++;
+ partn->esect = (*p) & 0x3F;
+ partn->ecyl = ((*p << 2) & 0xFF00) | (*(p+1));
+ p += 2;
+
+ if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
+ off = reloff;
+ else
+ off = offset;
+
+ partn->bs = getlong(p) + off;
+ partn->ns = getlong(p+4);
+
+
+ /* Zero out entry if not used */
+ if (partn->id == DOSPTYP_UNUSED ) {
+ memset(partn, 0, sizeof(*partn));
+ }
+}
+
+int
+PRT_check_chs(partn)
+ prt_t *partn;
+{
+ if ( (partn->shead > 255) ||
+ (partn->ssect >63) ||
+ (partn->scyl > 1023) ||
+ (partn->ehead >255) ||
+ (partn->esect >63) ||
+ (partn->ecyl > 1023) )
+ {
+ return 0;
+ }
+ return 1;
+}
+void
+PRT_make(partn, offset, reloff, prt)
+ prt_t *partn;
+ off_t offset;
+ off_t reloff;
+ void *prt;
+{
+ unsigned char *p = prt;
+ prt_t tmp;
+ off_t off;
+
+ tmp.shead = partn->shead;
+ tmp.ssect = partn->ssect;
+ tmp.scyl = (partn->scyl > 1023)? 1023: partn->scyl;
+ tmp.ehead = partn->ehead;
+ tmp.esect = partn->esect;
+ tmp.ecyl = (partn->ecyl > 1023)? 1023: partn->ecyl;
+ if (!PRT_check_chs(partn) && PRT_check_chs(&tmp)) {
+ partn->shead = tmp.shead;
+ partn->ssect = tmp.ssect;
+ partn->scyl = tmp.scyl;
+ partn->ehead = tmp.ehead;
+ partn->esect = tmp.esect;
+ partn->ecyl = tmp.ecyl;
+ printf("Cylinder values are modified to fit in CHS.\n");
+ }
+ if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
+ off = reloff;
+ else
+ off = offset;
+
+ if (PRT_check_chs(partn)) {
+ *p++ = partn->flag & 0xFF;
+
+ *p++ = partn->shead & 0xFF;
+ *p++ = (partn->ssect & 0x3F) | ((partn->scyl & 0x300) >> 2);
+ *p++ = partn->scyl & 0xFF;
+
+ *p++ = partn->id & 0xFF;
+
+ *p++ = partn->ehead & 0xFF;
+ *p++ = (partn->esect & 0x3F) | ((partn->ecyl & 0x300) >> 2);
+ *p++ = partn->ecyl & 0xFF;
+ } else {
+ /* should this really keep flag, id and set others to 0xff? */
+ *p++ = partn->flag & 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = partn->id & 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ printf("Warning CHS values out of bounds only saving LBA values\n");
+ }
+
+ putlong(p, partn->bs - off);
+ putlong(p+4, partn->ns);
+}
+
+void
+PRT_print(num, partn)
+ int num;
+ prt_t *partn;
+{
+
+ if (partn == NULL) {
+ printf(" Starting Ending\n");
+ printf(" #: id cyl hd sec - cyl hd sec [ start - size]\n");
+ printf("------------------------------------------------------------------------\n");
+ } else {
+ printf("%c%1d: %.2X %4u %3u %3u - %4u %3u %3u [%10u - %10u] %s\n",
+ (partn->flag == 0x80)?'*':' ',
+ num + 1, partn->id,
+ partn->scyl, partn->shead, partn->ssect,
+ partn->ecyl, partn->ehead, partn->esect,
+ partn->bs, partn->ns,
+ PRT_ascii_id(partn->id));
+ }
+}
+
+void
+PRT_fix_BN(disk, part, pn)
+ disk_t *disk;
+ prt_t *part;
+ int pn;
+{
+ int spt, tpc, spc;
+ int start = 0;
+ int end = 0;
+
+ /* Zero out entry if not used */
+ if (part->id == DOSPTYP_UNUSED ) {
+ memset(part, 0, sizeof(*part));
+ return;
+ }
+
+ /* Disk metrics */
+ spt = disk->real->sectors;
+ tpc = disk->real->heads;
+ spc = spt * tpc;
+
+ start += part->scyl * spc;
+ start += part->shead * spt;
+ start += part->ssect - 1;
+
+ end += part->ecyl * spc;
+ end += part->ehead * spt;
+ end += part->esect - 1;
+
+ /* XXX - Should handle this... */
+ if (start > end)
+ warn("Start of partition #%d after end!", pn);
+
+ part->bs = start;
+ part->ns = (end - start) + 1;
+}
+
+void
+PRT_fix_CHS(disk, part, pn)
+ disk_t *disk;
+ prt_t *part;
+ int pn;
+{
+ int spt, tpc, spc;
+ int start;
+ int cyl, head, sect;
+
+ /* Zero out entry if not used */
+ if (part->id == DOSPTYP_UNUSED ) {
+ memset(part, 0, sizeof(*part));
+ return;
+ }
+
+ /* Disk metrics */
+ spt = disk->real->sectors;
+ tpc = disk->real->heads;
+ spc = spt * tpc;
+
+ start = part->bs;
+
+ if(start <= spt) {
+ /* Figure out "real" starting CHS values */
+ cyl = (start / spc); start -= (cyl * spc);
+ head = (start / spt); start -= (head * spt);
+ sect = (start + 1);
+ } else {
+ cyl = 1023;
+ head = 254;
+ sect = 63;
+ }
+
+ part->scyl = cyl;
+ part->shead = head;
+ part->ssect = sect;
+
+ /* use fake geometry to trigger LBA mode */
+
+ cyl = 1023;
+ head = 254;
+ sect = 63;
+
+ part->ecyl = cyl;
+ part->ehead = head;
+ part->esect = sect;
+}
+
diff --git a/diskdev_cmds/fdisk.tproj/part.h b/diskdev_cmds/fdisk.tproj/part.h
new file mode 100644
index 0000000..049cf2c
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/part.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PART_H
+#define _PART_H
+
+/* Partition type */
+typedef struct _prt_t {
+ int shead, scyl, ssect;
+ int ehead, ecyl, esect;
+ int bs;
+ int ns;
+ unsigned char flag;
+ unsigned char id;
+} prt_t;
+
+/* Prototypes */
+void PRT_printall __P((void));
+const char *PRT_ascii_id __P((int));
+void PRT_parse __P((disk_t *, void *, off_t, off_t, prt_t *, int));
+void PRT_make __P((prt_t *, off_t, off_t, void *));
+void PRT_print __P((int, prt_t *));
+
+/* This does CHS -> bs/ns */
+void PRT_fix_BN __P((disk_t *, prt_t *, int));
+
+/* This does bs/ns -> CHS */
+void PRT_fix_CHS __P((disk_t *, prt_t *, int));
+#endif /* _PART_H */
+
diff --git a/diskdev_cmds/fdisk.tproj/user.c b/diskdev_cmds/fdisk.tproj/user.c
new file mode 100644
index 0000000..d44434e
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/user.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <util.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <machine/param.h>
+#include "user.h"
+#include "disk.h"
+#include "misc.h"
+#include "mbr.h"
+#include "cmd.h"
+
+
+/* Our command table */
+static cmd_table_t cmd_table[] = {
+ {"help", Xhelp, "Command help list"},
+ {"manual", Xmanual, "Show entire man page for fdisk"},
+ {"reinit", Xreinit, "Re-initialize loaded MBR (to defaults)"},
+ {"auto", Xauto, "Auto-partition the disk with a partition style"},
+ {"setpid", Xsetpid, "Set the identifier of a given table entry"},
+ {"disk", Xdisk, "Edit current drive stats"},
+ {"edit", Xedit, "Edit given table entry"},
+ {"erase", Xerase, "Erase current MBR"},
+ {"flag", Xflag, "Flag given table entry as bootable"},
+ {"update", Xupdate, "Update machine code in loaded MBR"},
+ {"select", Xselect, "Select extended partition table entry MBR"},
+ {"print", Xprint, "Print loaded MBR partition table"},
+ {"write", Xwrite, "Write loaded MBR to disk"},
+ {"exit", Xexit, "Exit edit of current MBR, without saving changes"},
+ {"quit", Xquit, "Quit edit of current MBR, saving current changes"},
+ {"abort", Xabort, "Abort program without saving current changes"},
+ {NULL, NULL, NULL}
+};
+
+
+int
+USER_write(disk, tt, preserve, force)
+ disk_t *disk;
+ mbr_t *tt; /* Template MBR to write */
+ int preserve; /* Preserve partition table and just write boot code */
+ int force; /* Don't ask any questions */
+{
+ int fd, yn;
+ char *msgp = "\nDo you wish to write new MBR?";
+ char *msgk = "\nDo you wish to write new MBR and partition table?";
+
+ /* Write sector 0 */
+ if (force) {
+ yn = 1;
+ } else {
+ printf("\a\n"
+ "\t-----------------------------------------------------\n"
+ "\t------ ATTENTION - UPDATING MASTER BOOT RECORD ------\n"
+ "\t-----------------------------------------------------\n");
+ if (preserve)
+ yn = ask_yn(msgp, 0);
+ else
+ yn = ask_yn(msgk, 0);
+ }
+
+ if (yn) {
+ if (preserve) {
+ int shared;
+ /* Only write the first one, if there's more than one in an extended partition chain */
+ /* Since we're updating boot code, we don't require exclusive access */
+ fd = DISK_openshared(disk->name, O_RDWR, &shared);
+ MBR_make(tt);
+ MBR_write(disk, fd, tt);
+ DISK_close(fd);
+ } else {
+ MBR_write_all(disk, tt);
+ }
+ } else {
+ printf("MBR is unchanged\n");
+ }
+
+ return (0);
+}
+
+
+int
+USER_modify(disk, tt, offset, reloff)
+ disk_t *disk;
+ mbr_t *tt;
+ off_t offset;
+ off_t reloff;
+{
+ static int editlevel;
+ mbr_t *mbr;
+ cmd_t cmd;
+ int i, st, fd;
+ int modified = 0;
+
+ /* One level deeper */
+ editlevel += 1;
+
+ /* Set up command table pointer */
+ cmd.table = cmd_table;
+
+ /* Read MBR & partition */
+ mbr = MBR_alloc(NULL);
+ fd = DISK_open(disk->name, O_RDONLY);
+ MBR_read(disk, fd, offset, mbr);
+ DISK_close(fd);
+
+ /* Parse the sucker */
+ MBR_parse(disk, offset, reloff, mbr);
+
+ if (mbr->signature != MBR_SIGNATURE) {
+ int yn = ask_yn("The signature for this MBR is invalid.\nWould you like to initialize the partition table?", 1);
+ if (yn) {
+ strlcpy(cmd.cmd, "erase", sizeof(cmd.cmd));
+ cmd.args[0] = '\0';
+ st = Xerase(&cmd, disk, mbr, tt, offset);
+ modified = 1;
+ }
+ }
+
+ printf("Enter 'help' for information\n");
+
+ /* Edit cycle */
+ do {
+again:
+ printf("fdisk:%c%d> ", (modified)?'*':' ', editlevel);
+ fflush(stdout);
+ ask_cmd(&cmd);
+
+ if (cmd.cmd[0] == '\0')
+ goto again;
+ for (i = 0; cmd_table[i].cmd != NULL; i++)
+ if (strstr(cmd_table[i].cmd, cmd.cmd)==cmd_table[i].cmd)
+ break;
+
+ /* Quick hack to put in '?' == 'help' */
+ if (!strcmp(cmd.cmd, "?"))
+ i = 0;
+
+ /* Check for valid command */
+ if (cmd_table[i].cmd == NULL) {
+ printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd);
+ continue;
+ } else
+ strlcpy(cmd.cmd, cmd_table[i].cmd, sizeof(cmd.cmd));
+
+ /* Call function */
+ st = cmd_table[i].fcn(&cmd, disk, mbr, tt, offset);
+
+ /* Update status */
+ if (st == CMD_EXIT)
+ break;
+ if (st == CMD_SAVE)
+ break;
+ if (st == CMD_CLEAN)
+ modified = 0;
+ if (st == CMD_DIRTY)
+ modified = 1;
+ } while (1);
+
+ /* Write out MBR */
+ if (modified) {
+ if (st == CMD_SAVE) {
+ int shared = 0;
+ printf("Writing current MBR to disk.\n");
+ fd = DISK_openshared(disk->name, O_RDWR, &shared);
+ if(shared) {
+ if(!ask_yn("Device could not be accessed exclusively.\nA reboot will be needed for changes to take effect. OK?", 0)) {
+ close(fd);
+ goto again;
+ }
+ }
+
+ MBR_make(mbr);
+ MBR_write(disk, fd, mbr);
+ close(fd);
+ } else {
+ int yn = ask_yn("MBR was modified; really quit without saving?", 0);
+ if (yn) {
+ printf("Aborting changes to current MBR.\n");
+ } else {
+ goto again;
+ }
+ }
+ }
+
+ /* One level less */
+ editlevel -= 1;
+
+ MBR_free(mbr);
+
+ return (0);
+}
+
+int
+USER_print_disk(disk, do_dump)
+ disk_t *disk;
+ int do_dump;
+{
+ int fd, offset, firstoff;
+ mbr_t *mbr;
+
+ fd = DISK_open(disk->name, O_RDONLY);
+ offset = firstoff = 0;
+
+ if (!do_dump)
+ DISK_printmetrics(disk);
+
+ mbr = MBR_read_all(disk);
+ if (do_dump)
+ MBR_dump_all(mbr);
+ else
+ MBR_print_all(mbr);
+ MBR_free(mbr);
+
+ return (DISK_close(fd));
+}
+
+
+
diff --git a/diskdev_cmds/fdisk.tproj/user.h b/diskdev_cmds/fdisk.tproj/user.h
new file mode 100644
index 0000000..7234c98
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/user.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USER_H
+#define _USER_H
+
+#include "disk.h"
+#include "mbr.h"
+
+/* Prototypes */
+int USER_write __P((disk_t *, mbr_t *, int, int));
+int USER_modify __P((disk_t *, mbr_t *, off_t, off_t));
+int USER_print_disk __P((disk_t *, int));
+#endif /* _USER_H */
+
diff --git a/diskdev_cmds/fdisk.tproj/util.h b/diskdev_cmds/fdisk.tproj/util.h
new file mode 100644
index 0000000..4e1600d
--- /dev/null
+++ b/diskdev_cmds/fdisk.tproj/util.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*-
+ * Copyright (c) 1995
+ * The Regents of the University of California. All rights reserved.
+ * Portions Copyright (c) 1996, Jason Downs. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _UTIL_H_
+#define _UTIL_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/*
+ * fparseln() specific operation flags.
+ */
+#define FPARSELN_UNESCESC 0x01
+#define FPARSELN_UNESCCONT 0x02
+#define FPARSELN_UNESCCOMM 0x04
+#define FPARSELN_UNESCREST 0x08
+#define FPARSELN_UNESCALL 0x0f
+
+/*
+ * opendev() specific operation flags.
+ */
+#define OPENDEV_PART 0x01 /* Try to open the raw partition. */
+#define OPENDEV_DRCT 0x02 /* Obsolete (now default behavior). */
+#define OPENDEV_BLCK 0x04 /* Open block, not character device. */
+
+/*
+ * uucplock(3) specific flags.
+ */
+#define UU_LOCK_INUSE (1)
+#define UU_LOCK_OK (0)
+#define UU_LOCK_OPEN_ERR (-1)
+#define UU_LOCK_READ_ERR (-2)
+#define UU_LOCK_CREAT_ERR (-3)
+#define UU_LOCK_WRITE_ERR (-4)
+#define UU_LOCK_LINK_ERR (-5)
+#define UU_LOCK_TRY_ERR (-6)
+#define UU_LOCK_OWNER_ERR (-7)
+
+/*
+ * stub struct definitions.
+ */
+struct __sFILE;
+struct login_cap;
+struct passwd;
+struct termios;
+struct winsize;
+
+__BEGIN_DECLS
+char *fparseln __P((struct __sFILE *, size_t *, size_t *, const char[3], int));
+int login_tty __P((int));
+int logout __P((const char *));
+void logwtmp __P((const char *, const char *, const char *));
+int opendev __P((char *, int, int, char **));
+int pidfile __P((const char *));
+void pw_setdir __P((const char *));
+char *pw_file __P((const char *));
+int pw_lock __P((int retries));
+int pw_mkdb __P((char *, int));
+int pw_abort __P((void));
+void pw_init __P((void));
+void pw_edit __P((int, const char *));
+void pw_prompt __P((void));
+void pw_copy __P((int, int, struct passwd *));
+void pw_getconf __P((char *, size_t, const char *, const char *));
+int pw_scan __P((char *, struct passwd *, int *));
+void pw_error __P((const char *, int, int));
+int openpty __P((int *, int *, char *, struct termios *,
+ struct winsize *));
+int opendisk __P((const char *path, int flags, char *buf, size_t buflen,
+ int iscooked));
+pid_t forkpty __P((int *, char *, struct termios *, struct winsize *));
+int getmaxpartitions __P((void));
+int getrawpartition __P((void));
+void login_fbtab __P((char *, uid_t, gid_t));
+int login_check_expire __P((struct __sFILE *, struct passwd *, char *, int));
+char *readlabelfs __P((char *, int));
+const char *uu_lockerr __P((int _uu_lockresult));
+int uu_lock __P((const char *_ttyname));
+int uu_lock_txfr __P((const char *_ttyname, pid_t _pid));
+int uu_unlock __P((const char *_ttyname));
+__END_DECLS
+
+#endif /* !_UTIL_H_ */