Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Trunk/i386/util/fdisk/cmd.c

1/*
2 * Copyright (c) 2002-2005 Apple Computer, Inc. All rights reserved.
3 *
4 *
5 * This file contains Original Code and/or Modifications of Original Code
6 * as defined in and that are subject to the Apple Public Source License
7 * Version 2.0 (the 'License'). You may not use this file except in
8 * compliance with the License. Please obtain a copy of the License at
9 * http://www.opensource.apple.com/apsl/ and read it before using this
10 * file.
11 *
12 * The Original Code and all software distributed under the License are
13 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
17 * Please see the License for the specific language governing rights and
18 * limitations under the License.
19 *
20 * Copyright (c) 1997 Tobias Weingartner
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * This product includes software developed by Tobias Weingartner.
34 * 4. The name of the author may not be used to endorse or promote products
35 * derived from this software without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
38 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 */
48
49#include <stdio.h>
50#include <ctype.h>
51#include <memory.h>
52#include <stdlib.h>
53#include <unistd.h>
54#include <signal.h>
55#include <sys/fcntl.h>
56#include "disk.h"
57#include "misc.h"
58#include "user.h"
59#include "part.h"
60#include "cmd.h"
61#include "auto.h"
62
63#define MAX(a, b) ((a) >= (b) ? (a) : (b))
64
65int
66Xerase(cmd, disk, mbr, tt, offset)
67cmd_t *cmd;
68disk_t *disk;
69mbr_t *mbr;
70mbr_t *tt;
71int offset;
72{
73 bzero(mbr->part, sizeof(mbr->part));
74mbr->signature = MBR_SIGNATURE;
75return (CMD_DIRTY);
76}
77
78int
79Xreinit(cmd, disk, mbr, tt, offset)
80cmd_t *cmd;
81disk_t *disk;
82mbr_t *mbr;
83mbr_t *tt;
84int offset;
85{
86/* Copy template MBR */
87MBR_make(tt);
88MBR_parse(disk, offset, 0, mbr);
89
90MBR_init(disk, mbr);
91
92/* Tell em we did something */
93printf("In memory copy is initialized to:\n");
94printf("Offset: %d\t", offset);
95MBR_print(mbr);
96printf("Use 'write' to update disk.\n");
97
98return (CMD_DIRTY);
99}
100
101int
102Xauto(cmd, disk, mbr, tt, offset)
103cmd_t *cmd;
104disk_t *disk;
105mbr_t *mbr;
106mbr_t *tt;
107int offset;
108{
109if (cmd->args[0] == '\0') {
110 printf("usage: auto <style>\n");
111 printf(" where style is one of:\n");
112 AUTO_print_styles(stdout);
113 return (CMD_CONT);
114}
115
116 if (AUTO_init(disk, cmd->args, mbr) != AUTO_OK) {
117 return (CMD_CONT);
118}
119MBR_make(mbr);
120return (CMD_DIRTY);
121}
122
123int
124Xdisk(cmd, disk, mbr, tt, offset)
125cmd_t *cmd;
126disk_t *disk;
127mbr_t *mbr;
128mbr_t *tt;
129int offset;
130{
131int maxcyl = 1024;
132int maxhead = 256;
133int maxsec = 63;
134
135/* Print out disk info */
136DISK_printmetrics(disk);
137
138#if defined (__powerpc__) || defined (__mips__)
139maxcyl = 9999999;
140maxhead = 9999999;
141maxsec = 9999999;
142#endif
143
144/* Ask for new info */
145if (ask_yn("Change disk geometry?", 0)) {
146disk->real->cylinders = ask_num("BIOS Cylinders", ASK_DEC,
147 disk->real->cylinders, 1, maxcyl, NULL);
148disk->real->heads = ask_num("BIOS Heads", ASK_DEC,
149 disk->real->heads, 1, maxhead, NULL);
150disk->real->sectors = ask_num("BIOS Sectors", ASK_DEC,
151 disk->real->sectors, 1, maxsec, NULL);
152
153disk->real->size = disk->real->cylinders * disk->real->heads
154* disk->real->sectors;
155}
156
157return (CMD_CONT);
158}
159
160int
161Xedit(cmd, disk, mbr, tt, offset)
162cmd_t *cmd;
163disk_t *disk;
164mbr_t *mbr;
165mbr_t *tt;
166int offset;
167{
168int pn, num, ret;
169prt_t *pp;
170
171ret = CMD_CONT;
172
173if (!isdigit(cmd->args[0])) {
174printf("Invalid argument: %s <partition number>\n", cmd->cmd);
175return (ret);
176}
177pn = atoi(cmd->args) - 1;
178
179if (pn < 0 || pn > 3) {
180printf("Invalid partition number.\n");
181return (ret);
182}
183
184/* Print out current table entry */
185pp = &mbr->part[pn];
186PRT_print(0, NULL);
187PRT_print(pn, pp);
188
189#defineEDIT(p, f, v, n, m, h)\
190if ((num = ask_num(p, f, v, n, m, h)) != v)\
191ret = CMD_DIRTY;\
192v = num;
193
194/* Ask for partition type */
195EDIT("Partition id ('0' to disable) ", ASK_HEX, pp->id, 0, 0xFF, PRT_printall);
196
197/* Unused, so just zero out */
198if (pp->id == DOSPTYP_UNUSED) {
199memset(pp, 0, sizeof(*pp));
200printf("Partition %d is disabled.\n", pn + 1);
201return (ret);
202}
203
204/* Change table entry */
205if (ask_yn("Do you wish to edit in CHS mode?", 0)) {
206int maxcyl, maxhead, maxsect;
207
208/* Shorter */
209maxcyl = disk->real->cylinders - 1;
210maxhead = disk->real->heads - 1;
211maxsect = disk->real->sectors;
212
213/* Get data */
214EDIT("BIOS Starting cylinder", ASK_DEC, pp->scyl, 0, maxcyl, NULL);
215EDIT("BIOS Starting head", ASK_DEC, pp->shead, 0, maxhead, NULL);
216EDIT("BIOS Starting sector", ASK_DEC, pp->ssect, 1, maxsect, NULL);
217EDIT("BIOS Ending cylinder", ASK_DEC, pp->ecyl, 0, maxcyl, NULL);
218EDIT("BIOS Ending head", ASK_DEC, pp->ehead, 0, maxhead, NULL);
219EDIT("BIOS Ending sector", ASK_DEC, pp->esect, 1, maxsect, NULL);
220/* Fix up off/size values */
221PRT_fix_BN(disk, pp, pn);
222/* Fix up CHS values for LBA */
223PRT_fix_CHS(disk, pp, pn);
224} else {
225u_int m;
226
227if (pn == 0) {
228pp->bs = 63 + offset;
229} else {
230if (mbr->part[pn-1].id != 0) {
231pp->bs = mbr->part[pn-1].bs + mbr->part[pn-1].ns;
232}
233}
234/* Get data */
235EDIT("Partition offset", ASK_DEC, pp->bs, 0,
236 disk->real->size, NULL);
237m = MAX(pp->ns, disk->real->size - pp->bs);
238if ( m > disk->real->size - pp->bs) {
239/* dont have default value extend beyond end of disk */
240m = disk->real->size - pp->bs;
241}
242pp->ns = m;
243EDIT("Partition size", ASK_DEC, pp->ns, 1,
244 m, NULL);
245
246/* Fix up CHS values */
247PRT_fix_CHS(disk, pp, pn);
248}
249#undef EDIT
250return (ret);
251}
252
253int
254Xsetpid(cmd, disk, mbr, tt, offset)
255cmd_t *cmd;
256disk_t *disk;
257mbr_t *mbr;
258mbr_t *tt;
259int offset;
260{
261int pn, num, ret;
262prt_t *pp;
263
264ret = CMD_CONT;
265
266if (!isdigit(cmd->args[0])) {
267printf("Invalid argument: %s <partition number>\n", cmd->cmd);
268return (ret);
269}
270pn = atoi(cmd->args) - 1;
271
272if (pn < 0 || pn > 3) {
273printf("Invalid partition number.\n");
274return (ret);
275}
276
277/* Print out current table entry */
278pp = &mbr->part[pn];
279PRT_print(0, NULL);
280PRT_print(pn, pp);
281
282#defineEDIT(p, f, v, n, m, h)\
283if ((num = ask_num(p, f, v, n, m, h)) != v)\
284ret = CMD_DIRTY;\
285v = num;
286
287/* Ask for partition type */
288EDIT("Partition id ('0' to disable) ", ASK_HEX, pp->id, 0, 0xFF, PRT_printall);
289
290#undef EDIT
291return (ret);
292}
293int
294Xselect(cmd, disk, mbr, tt, offset)
295cmd_t *cmd;
296disk_t *disk;
297mbr_t *mbr;
298mbr_t *tt;
299int offset;
300{
301static int firstoff = 0;
302int off;
303int pn;
304
305if (!isdigit(cmd->args[0])) {
306printf("Invalid argument: %s <partition number>\n", cmd->cmd);
307return (CMD_CONT);
308}
309
310pn = atoi(cmd->args) - 1;
311if (pn < 0 || pn > 3) {
312printf("Invalid partition number.\n");
313return (CMD_CONT);
314}
315
316off = mbr->part[pn].bs;
317
318/* Sanity checks */
319if ((mbr->part[pn].id != DOSPTYP_EXTEND) &&
320 (mbr->part[pn].id != DOSPTYP_EXTENDL)) {
321printf("Partition %d is not an extended partition.\n", pn + 1);
322return (CMD_CONT);
323}
324
325if (firstoff == 0)
326firstoff = off;
327
328if (!off) {
329printf("Loop to offset 0! Not selected.\n");
330return (CMD_CONT);
331} else {
332printf("Selected extended partition %d\n", pn + 1);
333printf("New MBR at offset %d.\n", off);
334}
335
336/* Recursion is beautifull! */
337USER_modify(disk, tt, off, firstoff);
338return (CMD_CONT);
339}
340
341int
342Xprint(cmd, disk, mbr, tt, offset)
343cmd_t *cmd;
344disk_t *disk;
345mbr_t *mbr;
346mbr_t *tt;
347int offset;
348{
349
350DISK_printmetrics(disk);
351printf("Offset: %d\t", offset);
352MBR_print(mbr);
353
354return (CMD_CONT);
355}
356
357int
358Xwrite(cmd, disk, mbr, tt, offset)
359cmd_t *cmd;
360disk_t *disk;
361mbr_t *mbr;
362mbr_t *tt;
363int offset;
364{
365int fd;
366int shared = 0;
367
368fd = DISK_openshared(disk->name, O_RDWR, &shared);
369if(shared) {
370 if(!ask_yn("Device could not be accessed exclusively.\nA reboot will be needed for changes to take effect. OK?", 0)) {
371 close(fd);
372 printf("MBR unchanged\n");
373 return (CMD_CONT);
374 }
375}
376
377printf("Writing MBR at offset %d.\n", offset);
378
379MBR_make(mbr);
380MBR_write(disk, fd, mbr);
381close(fd);
382return (CMD_CLEAN);
383}
384
385int
386Xquit(cmd, disk, r, tt, offset)
387cmd_t *cmd;
388disk_t *disk;
389mbr_t *r;
390mbr_t *tt;
391int offset;
392{
393
394/* Nothing to do here */
395return (CMD_SAVE);
396}
397
398int
399Xabort(cmd, disk, mbr, tt, offset)
400cmd_t *cmd;
401disk_t *disk;
402mbr_t *mbr;
403mbr_t *tt;
404int offset;
405{
406exit(0);
407
408/* NOTREACHED */
409return (CMD_CONT);
410}
411
412
413int
414Xexit(cmd, disk, mbr, tt, offset)
415cmd_t *cmd;
416disk_t *disk;
417mbr_t *mbr;
418mbr_t *tt;
419int offset;
420{
421
422/* Nothing to do here */
423return (CMD_EXIT);
424}
425
426int
427Xhelp(cmd, disk, mbr, tt, offset)
428cmd_t *cmd;
429disk_t *disk;
430mbr_t *mbr;
431mbr_t *tt;
432int offset;
433{
434cmd_table_t *cmd_table = cmd->table;
435int i;
436
437/* Hmm, print out cmd_table here... */
438for (i = 0; cmd_table[i].cmd != NULL; i++)
439printf("\t%s\t\t%s\n", cmd_table[i].cmd, cmd_table[i].help);
440return (CMD_CONT);
441}
442
443int
444Xupdate(cmd, disk, mbr, tt, offset)
445cmd_t *cmd;
446disk_t *disk;
447mbr_t *mbr;
448mbr_t *tt;
449int offset;
450{
451extern char *mbr_binary;
452/* Update code */
453memcpy(mbr->code, mbr_binary, MBR_CODE_SIZE);
454printf("Machine code updated.\n");
455return (CMD_DIRTY);
456}
457
458int
459Xflag(cmd, disk, mbr, tt, offset)
460cmd_t *cmd;
461disk_t *disk;
462mbr_t *mbr;
463mbr_t *tt;
464int offset;
465{
466int i, pn = -1;
467
468/* Parse partition table entry number */
469if (!isdigit(cmd->args[0])) {
470printf("Invalid argument: %s <partition number>\n", cmd->cmd);
471return (CMD_CONT);
472}
473pn = atoi(cmd->args) - 1;
474
475if (pn < 0 || pn > 3) {
476printf("Invalid partition number.\n");
477return (CMD_CONT);
478}
479
480/* Set active flag */
481for (i = 0; i < 4; i++) {
482if (i == pn)
483mbr->part[i].flag = DOSACTIVE;
484else
485mbr->part[i].flag = 0x00;
486}
487
488printf("Partition %d marked active.\n", pn + 1);
489return (CMD_DIRTY);
490}
491
492int
493Xmanual(cmd, disk, mbr, tt, offset)
494cmd_t *cmd;
495disk_t *disk;
496mbr_t *mbr;
497mbr_t *tt;
498int offset;
499{
500system("man 8 fdisk");
501return (CMD_CONT);
502}
503

Archive Download this file

Revision: 2045