diff options
author | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
---|---|---|
committer | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
commit | 5fd83771641d15c418f747bd343ba6738d3875f7 (patch) | |
tree | 5abf0f78f680d9837dbd93d4d4c3933bb7509599 /diskdev_cmds/fdisk.tproj/cmd.c | |
download | apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip |
Import macOS userland
adv_cmds-176
basic_cmds-55
bootstrap_cmds-116.100.1
developer_cmds-66
diskdev_cmds-667.40.1
doc_cmds-53.60.1
file_cmds-321.40.3
mail_cmds-35
misc_cmds-34
network_cmds-606.40.1
patch_cmds-17
remote_cmds-63
shell_cmds-216.60.1
system_cmds-880.60.2
text_cmds-106
Diffstat (limited to 'diskdev_cmds/fdisk.tproj/cmd.c')
-rw-r--r-- | diskdev_cmds/fdisk.tproj/cmd.c | 507 |
1 files changed, 507 insertions, 0 deletions
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); +} |