Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/util/fdisk/user.c

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 */
72static 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
93int
94USER_write(disk, tt, preserve, force)
95disk_t *disk;
96mbr_t *tt; /* Template MBR to write */
97int preserve; /* Preserve partition table and just write boot code */
98int force; /* Don't ask any questions */
99{
100int fd, yn;
101char *msgp = "\nDo you wish to write new MBR?";
102char *msgk = "\nDo you wish to write new MBR and partition table?";
103
104/* Write sector 0 */
105if (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
118if (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
134return (0);
135}
136
137
138int
139USER_modify(disk, tt, offset, reloff)
140disk_t *disk;
141mbr_t *tt;
142off_t offset;
143off_t reloff;
144{
145static int editlevel;
146mbr_t *mbr;
147cmd_t cmd;
148int i, st, fd;
149int modified = 0;
150
151/* One level deeper */
152editlevel += 1;
153
154/* Set up command table pointer */
155cmd.table = cmd_table;
156
157/* Read MBR & partition */
158mbr = MBR_alloc(NULL);
159fd = DISK_open(disk->name, O_RDONLY);
160MBR_read(disk, fd, offset, mbr);
161DISK_close(fd);
162
163/* Parse the sucker */
164MBR_parse(disk, offset, reloff, mbr);
165
166if (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
176printf("Enter 'help' for information\n");
177
178/* Edit cycle */
179do {
180again:
181printf("fdisk:%c%d> ", (modified)?'*':' ', editlevel);
182fflush(stdout);
183ask_cmd(&cmd);
184
185if (cmd.cmd[0] == '\0')
186goto again;
187for (i = 0; cmd_table[i].cmd != NULL; i++)
188if (strstr(cmd_table[i].cmd, cmd.cmd)==cmd_table[i].cmd)
189break;
190
191/* Quick hack to put in '?' == 'help' */
192if (!strcmp(cmd.cmd, "?"))
193i = 0;
194
195/* Check for valid command */
196if (cmd_table[i].cmd == NULL) {
197printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd);
198continue;
199} else
200strcpy(cmd.cmd, cmd_table[i].cmd);
201
202/* Call function */
203st = cmd_table[i].fcn(&cmd, disk, mbr, tt, offset);
204
205/* Update status */
206if (st == CMD_EXIT)
207break;
208if (st == CMD_SAVE)
209break;
210if (st == CMD_CLEAN)
211modified = 0;
212if (st == CMD_DIRTY)
213modified = 1;
214} while (1);
215
216/* Write out MBR */
217if (modified) {
218if (st == CMD_SAVE) {
219 int shared = 0;
220printf("Writing current MBR to disk.\n");
221fd = DISK_openshared(disk->name, O_RDWR, &shared);
222if(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
229MBR_make(mbr);
230MBR_write(disk, fd, mbr);
231close(fd);
232} else {
233 int yn = ask_yn("MBR was modified; really quit without saving?", 0);
234if (yn) {
235printf("Aborting changes to current MBR.\n");
236} else {
237goto again;
238}
239}
240}
241
242/* One level less */
243editlevel -= 1;
244
245MBR_free(mbr);
246
247return (0);
248}
249
250int
251USER_print_disk(disk, do_dump)
252disk_t *disk;
253int do_dump;
254{
255int fd, offset, firstoff;
256mbr_t *mbr;
257
258fd = DISK_open(disk->name, O_RDONLY);
259offset = firstoff = 0;
260
261if (!do_dump)
262 DISK_printmetrics(disk);
263
264mbr = MBR_read_all(disk);
265if (do_dump)
266 MBR_dump_all(mbr);
267else
268 MBR_print_all(mbr);
269MBR_free(mbr);
270
271return (DISK_close(fd));
272}
273
274
275
276

Archive Download this file

Revision: 920