Chameleon

Chameleon Svn Source Tree

Root/tags/2.3/i386/util/fdisk/user.c

Source at commit 2862 created 7 years 25 days ago.
By ifabio, Tag 2.3 release, bump svn to 2.4
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 = CMD_EXIT, 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);
159if (!mbr) errx(1, "out of memory");
160fd = DISK_open(disk->name, O_RDONLY);
161if (fd == -1)
162err(1, "Could not open %s", disk->name);
163MBR_read(disk, fd, offset, mbr);
164DISK_close(fd);
165
166/* Parse the sucker */
167MBR_parse(disk, offset, reloff, mbr);
168
169if (mbr->signature != MBR_SIGNATURE) {
170 int yn = ask_yn("The signature for this MBR is invalid.\nWould you like to initialize the partition table?", 1);
171 if (yn) {
172 strlcpy(cmd.cmd, "erase", sizeof(cmd.cmd));
173 cmd.args[0] = '\0';
174 Xerase(&cmd, disk, mbr, tt, offset);
175 modified = 1;
176 }
177}
178
179printf("Enter 'help' for information\n");
180
181/* Edit cycle */
182do {
183again:
184printf("fdisk:%c%d> ", (modified)?'*':' ', editlevel);
185fflush(stdout);
186ask_cmd(&cmd);
187
188if (cmd.cmd[0] == '\0')
189goto again;
190for (i = 0; cmd_table[i].cmd != NULL; i++)
191if (strstr(cmd_table[i].cmd, cmd.cmd)==cmd_table[i].cmd)
192break;
193
194/* Quick hack to put in '?' == 'help' */
195if (!strncmp(cmd.cmd, "?", sizeof("?")))
196i = 0;
197
198/* Check for valid command */
199if (cmd_table[i].cmd == NULL) {
200printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd);
201continue;
202} else
203strlcpy(cmd.cmd, cmd_table[i].cmd, sizeof(cmd.cmd));
204
205/* Call function */
206st = cmd_table[i].fcn(&cmd, disk, mbr, tt, offset);
207
208/* Update status */
209if (st == CMD_EXIT)
210break;
211if (st == CMD_SAVE)
212break;
213if (st == CMD_CLEAN)
214modified = 0;
215if (st == CMD_DIRTY)
216modified = 1;
217} while (1);
218
219/* Write out MBR */
220if (modified) {
221if (st == CMD_SAVE) {
222 int shared = 0;
223printf("Writing current MBR to disk.\n");
224fd = DISK_openshared(disk->name, O_RDWR, &shared);
225if(shared) {
226 if(!ask_yn("Device could not be accessed exclusively.\nA reboot will be needed for changes to take effect. OK?", 0)) {
227 close(fd);
228 goto again;
229 }
230}
231
232MBR_make(mbr);
233MBR_write(disk, fd, mbr);
234close(fd);
235} else {
236 int yn = ask_yn("MBR was modified; really quit without saving?", 0);
237if (yn) {
238printf("Aborting changes to current MBR.\n");
239} else {
240goto again;
241}
242}
243}
244
245/* One level less */
246editlevel -= 1;
247
248MBR_free(mbr);
249
250return (0);
251}
252
253int
254USER_print_disk(disk, do_dump)
255disk_t *disk;
256int do_dump;
257{
258int fd /*, offset, firstoff*/;
259mbr_t *mbr;
260
261fd = DISK_open(disk->name, O_RDONLY);
262if (fd == -1)
263err(1, "Could not open %s", disk->name);
264/*offset = firstoff = 0;*/
265
266if (!do_dump)
267 DISK_printmetrics(disk);
268
269mbr = MBR_read_all(disk);
270if (do_dump)
271 MBR_dump_all(mbr);
272else
273 MBR_print_all(mbr);
274MBR_free(mbr);
275
276return (DISK_close(fd));
277}
278
279
280
281

Archive Download this file

Revision: 2862