1 /* $OpenBSD: user.c,v 1.21 2003/06/11 06:22:12 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Tobias Weingartner 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <err.h> 29 #include <util.h> 30 #include <stdio.h> 31 #include <unistd.h> 32 #include <string.h> 33 #include <sys/fcntl.h> 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #include <sys/disklabel.h> 37 #include <machine/param.h> 38 #include "user.h" 39 #include "disk.h" 40 #include "misc.h" 41 #include "mbr.h" 42 #include "cmd.h" 43 44 45 /* Our command table */ 46 static cmd_table_t cmd_table[] = { 47 {"help", Xhelp, "Command help list"}, 48 {"manual", Xmanual, "Show entire OpenBSD man page for fdisk"}, 49 {"reinit", Xreinit, "Re-initialize loaded MBR (to defaults)"}, 50 {"setpid", Xsetpid, "Set the identifier of a given table entry"}, 51 {"disk", Xdisk, "Edit current drive stats"}, 52 {"edit", Xedit, "Edit given table entry"}, 53 {"flag", Xflag, "Flag given table entry as bootable"}, 54 {"update", Xupdate, "Update machine code in loaded MBR"}, 55 {"select", Xselect, "Select extended partition table entry MBR"}, 56 {"print", Xprint, "Print loaded MBR partition table"}, 57 {"write", Xwrite, "Write loaded MBR to disk"}, 58 {"exit", Xexit, "Exit edit of current MBR, without saving changes"}, 59 {"quit", Xquit, "Quit edit of current MBR, saving current changes"}, 60 {"abort", Xabort, "Abort program without saving current changes"}, 61 {NULL, NULL, NULL} 62 }; 63 64 65 int 66 USER_init(disk_t *disk, mbr_t *tt, int preserve) 67 { 68 int fd, yn; 69 char mbr_buf[DEV_BSIZE]; 70 char *msgp = "\nDo you wish to write new MBR?"; 71 char *msgk = "\nDo you wish to write new MBR and partition table?"; 72 73 if (preserve) 74 MBR_pcopy(disk, tt); 75 else 76 MBR_init(disk, tt); 77 78 /* Write sector 0 */ 79 printf("\a\n" 80 "\t-----------------------------------------------------\n" 81 "\t------ ATTENTION - UPDATING MASTER BOOT RECORD ------\n" 82 "\t-----------------------------------------------------\n"); 83 if (preserve) 84 yn = ask_yn(msgp); 85 else 86 yn = ask_yn(msgk); 87 88 if (yn) { 89 fd = DISK_open(disk->name, O_RDWR); 90 MBR_make(tt, mbr_buf); 91 MBR_write(fd, (off_t)0, mbr_buf); 92 DISK_close(fd); 93 } else 94 printf("MBR is unchanged\n"); 95 96 return (0); 97 } 98 99 int modified; 100 101 int 102 USER_modify(disk_t *disk, mbr_t *tt, off_t offset, off_t reloff) 103 { 104 static int editlevel; 105 char mbr_buf[DEV_BSIZE]; 106 mbr_t mbr; 107 cmd_t cmd; 108 int i, st, fd; 109 110 /* One level deeper */ 111 editlevel += 1; 112 113 /* Set up command table pointer */ 114 cmd.table = cmd_table; 115 116 /* Read MBR & partition */ 117 fd = DISK_open(disk->name, O_RDONLY); 118 MBR_read(fd, offset, mbr_buf); 119 DISK_close(fd); 120 121 /* Parse the sucker */ 122 MBR_parse(disk, mbr_buf, offset, reloff, &mbr); 123 124 printf("Enter 'help' for information\n"); 125 126 /* Edit cycle */ 127 do { 128 again: 129 printf("fdisk:%c%d> ", (modified)?'*':' ', editlevel); 130 fflush(stdout); 131 ask_cmd(&cmd); 132 133 if (cmd.cmd[0] == '\0') 134 goto again; 135 for (i = 0; cmd_table[i].cmd != NULL; i++) 136 if (strstr(cmd_table[i].cmd, cmd.cmd)==cmd_table[i].cmd) 137 break; 138 139 /* Quick hack to put in '?' == 'help' */ 140 if (!strcmp(cmd.cmd, "?")) 141 i = 0; 142 143 /* Check for valid command */ 144 if (cmd_table[i].cmd == NULL) { 145 printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd); 146 continue; 147 } else 148 strlcpy(cmd.cmd, cmd_table[i].cmd, sizeof cmd.cmd); 149 150 /* Call function */ 151 st = cmd_table[i].fcn(&cmd, disk, &mbr, tt, offset); 152 153 /* Update status */ 154 if (st == CMD_EXIT) 155 break; 156 if (st == CMD_SAVE) 157 break; 158 if (st == CMD_CLEAN) 159 modified = 0; 160 if (st == CMD_DIRTY) 161 modified = 1; 162 } while (1); 163 164 /* Write out MBR */ 165 if (modified) { 166 if (st == CMD_SAVE) { 167 printf("Writing current MBR to disk.\n"); 168 fd = DISK_open(disk->name, O_RDWR); 169 MBR_make(&mbr, mbr_buf); 170 MBR_write(fd, offset, mbr_buf); 171 close(fd); 172 } else 173 printf("Aborting changes to current MBR.\n"); 174 } 175 176 /* One level less */ 177 editlevel -= 1; 178 179 return (0); 180 } 181 182 int 183 USER_print_disk(disk_t *disk) 184 { 185 int fd, offset, firstoff, i; 186 char mbr_buf[DEV_BSIZE]; 187 mbr_t mbr; 188 189 fd = DISK_open(disk->name, O_RDONLY); 190 offset = firstoff = 0; 191 192 DISK_printmetrics(disk, NULL); 193 194 do { 195 MBR_read(fd, (off_t)offset, mbr_buf); 196 MBR_parse(disk, mbr_buf, offset, firstoff, &mbr); 197 198 printf("Offset: %d\t", (int)offset); 199 MBR_print(&mbr, NULL); 200 201 /* Print out extended partitions too */ 202 for (offset = i = 0; i < 4; i++) 203 if (mbr.part[i].id == DOSPTYP_EXTEND || 204 mbr.part[i].id == DOSPTYP_EXTENDL) { 205 offset = mbr.part[i].bs; 206 if (firstoff == 0) 207 firstoff = offset; 208 } 209 } while (offset); 210 211 return (DISK_close(fd)); 212 } 213 214