Root/
Source at commit 1445 created 12 years 11 months ago. By jrcs, Revert "Print the multiboot_magic" Only used for debugging purpose | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * This file contains Original Code and/or Modifications of Original Code␊ |
7 | * as defined in and that are subject to the Apple Public Source License␊ |
8 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
9 | * compliance with the License. Please obtain a copy of the License at␊ |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this␊ |
11 | * file.␊ |
12 | * ␊ |
13 | * The Original Code and all software distributed under the License are␊ |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
18 | * Please see the License for the specific language governing rights and␊ |
19 | * limitations under the License.␊ |
20 | * ␊ |
21 | * @APPLE_LICENSE_HEADER_END@␊ |
22 | */␊ |
23 | ␊ |
24 | ␊ |
25 | /*␊ |
26 | * Copyright (c) 1997 Tobias Weingartner␊ |
27 | * All rights reserved.␊ |
28 | *␊ |
29 | * Redistribution and use in source and binary forms, with or without␊ |
30 | * modification, are permitted provided that the following conditions␊ |
31 | * are met:␊ |
32 | * 1. Redistributions of source code must retain the above copyright␊ |
33 | * notice, this list of conditions and the following disclaimer.␊ |
34 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
35 | * notice, this list of conditions and the following disclaimer in the␊ |
36 | * documentation and/or other materials provided with the distribution.␊ |
37 | * 3. All advertising materials mentioning features or use of this software␊ |
38 | * must display the following acknowledgement:␊ |
39 | * This product includes software developed by Tobias Weingartner.␊ |
40 | * 4. The name of the author may not be used to endorse or promote products␊ |
41 | * derived from this software without specific prior written permission.␊ |
42 | *␊ |
43 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR␊ |
44 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES␊ |
45 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.␊ |
46 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,␊ |
47 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT␊ |
48 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,␊ |
49 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY␊ |
50 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT␊ |
51 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF␊ |
52 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.␊ |
53 | */␊ |
54 | ␊ |
55 | #include <err.h>␊ |
56 | #include <util.h>␊ |
57 | #include <stdio.h>␊ |
58 | #include <unistd.h>␊ |
59 | #include <string.h>␊ |
60 | #include <sys/fcntl.h>␊ |
61 | #include <sys/types.h>␊ |
62 | #include <sys/stat.h>␊ |
63 | #include <machine/param.h>␊ |
64 | #include "user.h"␊ |
65 | #include "disk.h"␊ |
66 | #include "misc.h"␊ |
67 | #include "mbr.h"␊ |
68 | #include "cmd.h"␊ |
69 | ␊ |
70 | ␊ |
71 | /* Our command table */␊ |
72 | static cmd_table_t cmd_table[] = {␊ |
73 | ␉{"help", Xhelp,␉"Command help list"},␊ |
74 | ␉{"manual", Xmanual,␉"Show entire man page for fdisk"},␊ |
75 | ␉{"reinit", Xreinit,␉"Re-initialize loaded MBR (to defaults)"},␊ |
76 | ␉{"auto", Xauto, "Auto-partition the disk with a partition style"},␊ |
77 | ␉{"setpid", Xsetpid,␉"Set the identifier of a given table entry"},␊ |
78 | ␉{"disk", Xdisk,␉"Edit current drive stats"},␊ |
79 | ␉{"edit", Xedit,␉"Edit given table entry"},␊ |
80 | ␉{"erase", Xerase, "Erase current MBR"},␊ |
81 | ␉{"flag", Xflag,␉"Flag given table entry as bootable"},␊ |
82 | ␉{"update", Xupdate,␉"Update machine code in loaded MBR"},␊ |
83 | ␉{"select", Xselect,␉"Select extended partition table entry MBR"},␊ |
84 | ␉{"print", Xprint,␉"Print loaded MBR partition table"},␊ |
85 | ␉{"write", Xwrite,␉"Write loaded MBR to disk"},␊ |
86 | ␉{"exit", Xexit,␉"Exit edit of current MBR, without saving changes"},␊ |
87 | ␉{"quit", Xquit,␉"Quit edit of current MBR, saving current changes"},␊ |
88 | ␉{"abort", Xabort,␉"Abort program without saving current changes"},␊ |
89 | ␉{NULL, NULL,␉NULL}␊ |
90 | };␊ |
91 | ␊ |
92 | ␊ |
93 | int␊ |
94 | USER_write(disk, tt, preserve, force)␊ |
95 | ␉disk_t *disk;␊ |
96 | ␉mbr_t *tt; /* Template MBR to write */␊ |
97 | ␉int preserve; /* Preserve partition table and just write boot code */␊ |
98 | ␉int force; /* Don't ask any questions */␊ |
99 | {␊ |
100 | ␉int fd, yn;␊ |
101 | ␉char *msgp = "\nDo you wish to write new MBR?";␊ |
102 | ␉char *msgk = "\nDo you wish to write new MBR and partition table?";␊ |
103 | ␊ |
104 | ␉/* Write sector 0 */␊ |
105 | ␉if (force) {␊ |
106 | ␉ yn = 1;␊ |
107 | ␉} else {␊ |
108 | ␉ printf("\a\n"␊ |
109 | ␉␉ "\t-----------------------------------------------------\n"␊ |
110 | ␉␉ "\t------ ATTENTION - UPDATING MASTER BOOT RECORD ------\n"␊ |
111 | ␉␉ "\t-----------------------------------------------------\n");␊ |
112 | ␉ if (preserve)␊ |
113 | ␉ yn = ask_yn(msgp, 0);␊ |
114 | ␉ else␊ |
115 | ␉ yn = ask_yn(msgk, 0);␊ |
116 | ␉}␊ |
117 | ␊ |
118 | ␉if (yn) {␊ |
119 | ␉ if (preserve) {␊ |
120 | ␉ int shared;␊ |
121 | ␉ /* Only write the first one, if there's more than one in an extended partition chain */␊ |
122 | ␉ /* Since we're updating boot code, we don't require exclusive access */␊ |
123 | ␉ fd = DISK_openshared(disk->name, O_RDWR, &shared);␊ |
124 | ␉ MBR_make(tt);␊ |
125 | ␉ MBR_write(disk, fd, tt);␊ |
126 | ␉ DISK_close(fd);␊ |
127 | ␉ } else {␊ |
128 | ␉ MBR_write_all(disk, tt);␊ |
129 | ␉ }␊ |
130 | ␉} else {␊ |
131 | ␉ printf("MBR is unchanged\n");␊ |
132 | ␉}␊ |
133 | ␊ |
134 | ␉return (0);␊ |
135 | }␊ |
136 | ␊ |
137 | ␊ |
138 | int␊ |
139 | USER_modify(disk, tt, offset, reloff)␊ |
140 | ␉disk_t *disk;␊ |
141 | ␉mbr_t *tt;␊ |
142 | ␉off_t offset;␊ |
143 | ␉off_t reloff;␊ |
144 | {␊ |
145 | ␉static int editlevel;␊ |
146 | ␉mbr_t *mbr;␊ |
147 | ␉cmd_t cmd;␊ |
148 | ␉int i, st, fd;␊ |
149 | ␉int modified = 0;␉␊ |
150 | ␊ |
151 | ␉/* One level deeper */␊ |
152 | ␉editlevel += 1;␊ |
153 | ␊ |
154 | ␉/* Set up command table pointer */␊ |
155 | ␉cmd.table = cmd_table;␊ |
156 | ␊ |
157 | ␉/* Read MBR & partition */␊ |
158 | ␉mbr = MBR_alloc(NULL);␊ |
159 | ␉fd = DISK_open(disk->name, O_RDONLY);␊ |
160 | ␉MBR_read(disk, fd, offset, mbr);␊ |
161 | ␉DISK_close(fd);␊ |
162 | ␊ |
163 | ␉/* Parse the sucker */␊ |
164 | ␉MBR_parse(disk, offset, reloff, mbr);␊ |
165 | ␊ |
166 | ␉if (mbr->signature != MBR_SIGNATURE) {␊ |
167 | ␉ int yn = ask_yn("The signature for this MBR is invalid.\nWould you like to initialize the partition table?", 1);␊ |
168 | ␉ if (yn) {␊ |
169 | ␉ strcpy(cmd.cmd, "erase");␊ |
170 | ␉ cmd.args[0] = '\0';␊ |
171 | ␉ st = Xerase(&cmd, disk, mbr, tt, offset);␊ |
172 | ␉ modified = 1;␊ |
173 | ␉ }␊ |
174 | ␉}␊ |
175 | ␊ |
176 | ␉printf("Enter 'help' for information\n");␊ |
177 | ␊ |
178 | ␉/* Edit cycle */␊ |
179 | ␉do {␊ |
180 | again:␊ |
181 | ␉␉printf("fdisk:%c%d> ", (modified)?'*':' ', editlevel);␊ |
182 | ␉␉fflush(stdout);␊ |
183 | ␉␉ask_cmd(&cmd);␊ |
184 | ␊ |
185 | ␉␉if (cmd.cmd[0] == '\0')␊ |
186 | ␉␉␉goto again;␊ |
187 | ␉␉for (i = 0; cmd_table[i].cmd != NULL; i++)␊ |
188 | ␉␉␉if (strstr(cmd_table[i].cmd, cmd.cmd)==cmd_table[i].cmd)␊ |
189 | ␉␉␉␉break;␊ |
190 | ␊ |
191 | ␉␉/* Quick hack to put in '?' == 'help' */␊ |
192 | ␉␉if (!strcmp(cmd.cmd, "?"))␊ |
193 | ␉␉␉i = 0;␊ |
194 | ␊ |
195 | ␉␉/* Check for valid command */␊ |
196 | ␉␉if (cmd_table[i].cmd == NULL) {␊ |
197 | ␉␉␉printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd);␊ |
198 | ␉␉␉continue;␊ |
199 | ␉␉} else␊ |
200 | ␉␉␉strcpy(cmd.cmd, cmd_table[i].cmd);␊ |
201 | ␊ |
202 | ␉␉/* Call function */␊ |
203 | ␉␉st = cmd_table[i].fcn(&cmd, disk, mbr, tt, offset);␊ |
204 | ␊ |
205 | ␉␉/* Update status */␊ |
206 | ␉␉if (st == CMD_EXIT)␊ |
207 | ␉␉␉break;␊ |
208 | ␉␉if (st == CMD_SAVE)␊ |
209 | ␉␉␉break;␊ |
210 | ␉␉if (st == CMD_CLEAN)␊ |
211 | ␉␉␉modified = 0;␊ |
212 | ␉␉if (st == CMD_DIRTY)␊ |
213 | ␉␉␉modified = 1;␊ |
214 | ␉} while (1);␊ |
215 | ␊ |
216 | ␉/* Write out MBR */␊ |
217 | ␉if (modified) {␊ |
218 | ␉␉if (st == CMD_SAVE) {␊ |
219 | ␉␉ ␉int shared = 0;␊ |
220 | ␉␉␉printf("Writing current MBR to disk.\n");␊ |
221 | ␉␉␉fd = DISK_openshared(disk->name, O_RDWR, &shared);␊ |
222 | ␉␉␉if(shared) {␊ |
223 | ␉␉␉ if(!ask_yn("Device could not be accessed exclusively.\nA reboot will be needed for changes to take effect. OK?", 0)) {␊ |
224 | ␉␉␉ close(fd);␊ |
225 | ␉␉␉ goto again;␊ |
226 | ␉␉␉ }␊ |
227 | ␉␉␉}␊ |
228 | ␊ |
229 | ␉␉␉MBR_make(mbr);␊ |
230 | ␉␉␉MBR_write(disk, fd, mbr);␊ |
231 | ␉␉␉close(fd);␊ |
232 | ␉␉} else {␊ |
233 | ␉ int yn = ask_yn("MBR was modified; really quit without saving?", 0);␊ |
234 | ␉␉␉if (yn) {␊ |
235 | ␉␉␉␉printf("Aborting changes to current MBR.\n");␊ |
236 | ␉␉␉} else {␊ |
237 | ␉␉␉␉goto again;␊ |
238 | ␉␉␉}␊ |
239 | ␉␉}␊ |
240 | ␉}␊ |
241 | ␊ |
242 | ␉/* One level less */␊ |
243 | ␉editlevel -= 1;␊ |
244 | ␊ |
245 | ␉MBR_free(mbr);␊ |
246 | ␉␊ |
247 | ␉return (0);␊ |
248 | }␊ |
249 | ␊ |
250 | int␊ |
251 | USER_print_disk(disk, do_dump)␊ |
252 | ␉disk_t *disk;␊ |
253 | ␉int do_dump;␊ |
254 | {␊ |
255 | ␉int fd, offset, firstoff;␊ |
256 | ␉mbr_t *mbr;␊ |
257 | ␊ |
258 | ␉fd = DISK_open(disk->name, O_RDONLY);␊ |
259 | ␉offset = firstoff = 0;␊ |
260 | ␊ |
261 | ␉if (!do_dump)␊ |
262 | ␉ DISK_printmetrics(disk);␊ |
263 | ␊ |
264 | ␉mbr = MBR_read_all(disk);␊ |
265 | ␉if (do_dump)␊ |
266 | ␉ MBR_dump_all(mbr);␊ |
267 | ␉else␊ |
268 | ␉ MBR_print_all(mbr);␊ |
269 | ␉MBR_free(mbr);␊ |
270 | ␊ |
271 | ␉return (DISK_close(fd));␊ |
272 | }␊ |
273 | ␊ |
274 | ␊ |
275 | ␊ |
276 |