]> git.cameronkatri.com Git - apple_cmds.git/blob - diskdev_cmds/fdisk.tproj/cmd.c
setup.sh: Use iOS ~12 XNU version
[apple_cmds.git] / diskdev_cmds / fdisk.tproj / cmd.c
1 /*
2 * Copyright (c) 2002-2005 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 <stdio.h>
56 #include <ctype.h>
57 #include <memory.h>
58 #include <stdlib.h>
59 #include <unistd.h>
60 #include <signal.h>
61 #include <sys/fcntl.h>
62 #include "disk.h"
63 #include "misc.h"
64 #include "user.h"
65 #include "part.h"
66 #include "cmd.h"
67 #include "auto.h"
68 #define MAX(a, b) ((a) >= (b) ? (a) : (b))
69
70 int
71 Xerase(cmd, disk, mbr, tt, offset)
72 cmd_t *cmd;
73 disk_t *disk;
74 mbr_t *mbr;
75 mbr_t *tt;
76 int offset;
77 {
78 bzero(mbr->part, sizeof(mbr->part));
79 mbr->signature = MBR_SIGNATURE;
80 return (CMD_DIRTY);
81 }
82
83 int
84 Xreinit(cmd, disk, mbr, tt, offset)
85 cmd_t *cmd;
86 disk_t *disk;
87 mbr_t *mbr;
88 mbr_t *tt;
89 int offset;
90 {
91 /* Copy template MBR */
92 MBR_make(tt);
93 MBR_parse(disk, offset, 0, mbr);
94
95 MBR_init(disk, mbr);
96
97 /* Tell em we did something */
98 printf("In memory copy is initialized to:\n");
99 printf("Offset: %d\t", offset);
100 MBR_print(mbr);
101 printf("Use 'write' to update disk.\n");
102
103 return (CMD_DIRTY);
104 }
105
106 int
107 Xauto(cmd, disk, mbr, tt, offset)
108 cmd_t *cmd;
109 disk_t *disk;
110 mbr_t *mbr;
111 mbr_t *tt;
112 int offset;
113 {
114 if (cmd->args[0] == '\0') {
115 printf("usage: auto <style>\n");
116 printf(" where style is one of:\n");
117 AUTO_print_styles(stdout);
118 return (CMD_CONT);
119 }
120
121 if (AUTO_init(disk, cmd->args, mbr) != AUTO_OK) {
122 return (CMD_CONT);
123 }
124 MBR_make(mbr);
125 return (CMD_DIRTY);
126 }
127
128 int
129 Xdisk(cmd, disk, mbr, tt, offset)
130 cmd_t *cmd;
131 disk_t *disk;
132 mbr_t *mbr;
133 mbr_t *tt;
134 int offset;
135 {
136 int maxcyl = 1024;
137 int maxhead = 256;
138 int maxsec = 63;
139
140 /* Print out disk info */
141 DISK_printmetrics(disk);
142
143 #if defined (__powerpc__) || defined (__mips__)
144 maxcyl = 9999999;
145 maxhead = 9999999;
146 maxsec = 9999999;
147 #endif
148
149 /* Ask for new info */
150 if (ask_yn("Change disk geometry?", 0)) {
151 disk->real->cylinders = ask_num("BIOS Cylinders", ASK_DEC,
152 disk->real->cylinders, 1, maxcyl, NULL);
153 disk->real->heads = ask_num("BIOS Heads", ASK_DEC,
154 disk->real->heads, 1, maxhead, NULL);
155 disk->real->sectors = ask_num("BIOS Sectors", ASK_DEC,
156 disk->real->sectors, 1, maxsec, NULL);
157
158 disk->real->size = disk->real->cylinders * disk->real->heads
159 * disk->real->sectors;
160 }
161
162 return (CMD_CONT);
163 }
164
165 int
166 Xedit(cmd, disk, mbr, tt, offset)
167 cmd_t *cmd;
168 disk_t *disk;
169 mbr_t *mbr;
170 mbr_t *tt;
171 int offset;
172 {
173 int pn, num, ret;
174 prt_t *pp;
175
176 ret = CMD_CONT;
177
178 if (!isdigit(cmd->args[0])) {
179 printf("Invalid argument: %s <partition number>\n", cmd->cmd);
180 return (ret);
181 }
182 pn = atoi(cmd->args) - 1;
183
184 if (pn < 0 || pn > 3) {
185 printf("Invalid partition number.\n");
186 return (ret);
187 }
188
189 /* Print out current table entry */
190 pp = &mbr->part[pn];
191 PRT_print(0, NULL);
192 PRT_print(pn, pp);
193
194 #define EDIT(p, f, v, n, m, h) \
195 if ((num = ask_num(p, f, v, n, m, h)) != v) \
196 ret = CMD_DIRTY; \
197 v = num;
198
199 /* Ask for partition type */
200 EDIT("Partition id ('0' to disable) ", ASK_HEX, pp->id, 0, 0xFF, PRT_printall);
201
202 /* Unused, so just zero out */
203 if (pp->id == DOSPTYP_UNUSED) {
204 memset(pp, 0, sizeof(*pp));
205 printf("Partition %d is disabled.\n", pn + 1);
206 return (ret);
207 }
208
209 /* Change table entry */
210 if (ask_yn("Do you wish to edit in CHS mode?", 0)) {
211 int maxcyl, maxhead, maxsect;
212
213 /* Shorter */
214 maxcyl = disk->real->cylinders - 1;
215 maxhead = disk->real->heads - 1;
216 maxsect = disk->real->sectors;
217
218 /* Get data */
219 EDIT("BIOS Starting cylinder", ASK_DEC, pp->scyl, 0, maxcyl, NULL);
220 EDIT("BIOS Starting head", ASK_DEC, pp->shead, 0, maxhead, NULL);
221 EDIT("BIOS Starting sector", ASK_DEC, pp->ssect, 1, maxsect, NULL);
222 EDIT("BIOS Ending cylinder", ASK_DEC, pp->ecyl, 0, maxcyl, NULL);
223 EDIT("BIOS Ending head", ASK_DEC, pp->ehead, 0, maxhead, NULL);
224 EDIT("BIOS Ending sector", ASK_DEC, pp->esect, 1, maxsect, NULL);
225 /* Fix up off/size values */
226 PRT_fix_BN(disk, pp, pn);
227 /* Fix up CHS values for LBA */
228 PRT_fix_CHS(disk, pp, pn);
229 } else {
230 u_int m;
231
232 if (pn == 0) {
233 pp->bs = 63 + offset;
234 } else {
235 if (mbr->part[pn-1].id != 0) {
236 pp->bs = mbr->part[pn-1].bs + mbr->part[pn-1].ns;
237 }
238 }
239 /* Get data */
240 EDIT("Partition offset", ASK_DEC, pp->bs, 0,
241 disk->real->size, NULL);
242 m = MAX(pp->ns, disk->real->size - pp->bs);
243 if ( m > disk->real->size - pp->bs) {
244 /* dont have default value extend beyond end of disk */
245 m = disk->real->size - pp->bs;
246 }
247 pp->ns = m;
248 EDIT("Partition size", ASK_DEC, pp->ns, 1,
249 m, NULL);
250
251 /* Fix up CHS values */
252 PRT_fix_CHS(disk, pp, pn);
253 }
254 #undef EDIT
255 return (ret);
256 }
257
258 int
259 Xsetpid(cmd, disk, mbr, tt, offset)
260 cmd_t *cmd;
261 disk_t *disk;
262 mbr_t *mbr;
263 mbr_t *tt;
264 int offset;
265 {
266 int pn, num, ret;
267 prt_t *pp;
268
269 ret = CMD_CONT;
270
271 if (!isdigit(cmd->args[0])) {
272 printf("Invalid argument: %s <partition number>\n", cmd->cmd);
273 return (ret);
274 }
275 pn = atoi(cmd->args) - 1;
276
277 if (pn < 0 || pn > 3) {
278 printf("Invalid partition number.\n");
279 return (ret);
280 }
281
282 /* Print out current table entry */
283 pp = &mbr->part[pn];
284 PRT_print(0, NULL);
285 PRT_print(pn, pp);
286
287 #define EDIT(p, f, v, n, m, h) \
288 if ((num = ask_num(p, f, v, n, m, h)) != v) \
289 ret = CMD_DIRTY; \
290 v = num;
291
292 /* Ask for partition type */
293 EDIT("Partition id ('0' to disable) ", ASK_HEX, pp->id, 0, 0xFF, PRT_printall);
294
295 #undef EDIT
296 return (ret);
297 }
298 int
299 Xselect(cmd, disk, mbr, tt, offset)
300 cmd_t *cmd;
301 disk_t *disk;
302 mbr_t *mbr;
303 mbr_t *tt;
304 int offset;
305 {
306 static int firstoff = 0;
307 int off;
308 int pn;
309
310 if (!isdigit(cmd->args[0])) {
311 printf("Invalid argument: %s <partition number>\n", cmd->cmd);
312 return (CMD_CONT);
313 }
314
315 pn = atoi(cmd->args) - 1;
316 if (pn < 0 || pn > 3) {
317 printf("Invalid partition number.\n");
318 return (CMD_CONT);
319 }
320
321 off = mbr->part[pn].bs;
322
323 /* Sanity checks */
324 if ((mbr->part[pn].id != DOSPTYP_EXTEND) &&
325 (mbr->part[pn].id != DOSPTYP_EXTENDL)) {
326 printf("Partition %d is not an extended partition.\n", pn + 1);
327 return (CMD_CONT);
328 }
329
330 if (firstoff == 0)
331 firstoff = off;
332
333 if (!off) {
334 printf("Loop to offset 0! Not selected.\n");
335 return (CMD_CONT);
336 } else {
337 printf("Selected extended partition %d\n", pn + 1);
338 printf("New MBR at offset %d.\n", off);
339 }
340
341 /* Recursion is beautifull! */
342 USER_modify(disk, tt, off, firstoff);
343 return (CMD_CONT);
344 }
345
346 int
347 Xprint(cmd, disk, mbr, tt, offset)
348 cmd_t *cmd;
349 disk_t *disk;
350 mbr_t *mbr;
351 mbr_t *tt;
352 int offset;
353 {
354
355 DISK_printmetrics(disk);
356 printf("Offset: %d\t", offset);
357 MBR_print(mbr);
358
359 return (CMD_CONT);
360 }
361
362 int
363 Xwrite(cmd, disk, mbr, tt, offset)
364 cmd_t *cmd;
365 disk_t *disk;
366 mbr_t *mbr;
367 mbr_t *tt;
368 int offset;
369 {
370 int fd;
371 int shared = 0;
372
373 fd = DISK_openshared(disk->name, O_RDWR, &shared);
374 if(shared) {
375 if(!ask_yn("Device could not be accessed exclusively.\nA reboot will be needed for changes to take effect. OK?", 0)) {
376 close(fd);
377 printf("MBR unchanged\n");
378 return (CMD_CONT);
379 }
380 }
381
382 printf("Writing MBR at offset %d.\n", offset);
383
384 MBR_make(mbr);
385 MBR_write(disk, fd, mbr);
386 close(fd);
387 return (CMD_CLEAN);
388 }
389
390 int
391 Xquit(cmd, disk, r, tt, offset)
392 cmd_t *cmd;
393 disk_t *disk;
394 mbr_t *r;
395 mbr_t *tt;
396 int offset;
397 {
398
399 /* Nothing to do here */
400 return (CMD_SAVE);
401 }
402
403 int
404 Xabort(cmd, disk, mbr, tt, offset)
405 cmd_t *cmd;
406 disk_t *disk;
407 mbr_t *mbr;
408 mbr_t *tt;
409 int offset;
410 {
411 exit(0);
412
413 /* NOTREACHED */
414 return (CMD_CONT);
415 }
416
417
418 int
419 Xexit(cmd, disk, mbr, tt, offset)
420 cmd_t *cmd;
421 disk_t *disk;
422 mbr_t *mbr;
423 mbr_t *tt;
424 int offset;
425 {
426
427 /* Nothing to do here */
428 return (CMD_EXIT);
429 }
430
431 int
432 Xhelp(cmd, disk, mbr, tt, offset)
433 cmd_t *cmd;
434 disk_t *disk;
435 mbr_t *mbr;
436 mbr_t *tt;
437 int offset;
438 {
439 cmd_table_t *cmd_table = cmd->table;
440 int i;
441
442 /* Hmm, print out cmd_table here... */
443 for (i = 0; cmd_table[i].cmd != NULL; i++)
444 printf("\t%s\t\t%s\n", cmd_table[i].cmd, cmd_table[i].help);
445 return (CMD_CONT);
446 }
447
448 int
449 Xupdate(cmd, disk, mbr, tt, offset)
450 cmd_t *cmd;
451 disk_t *disk;
452 mbr_t *mbr;
453 mbr_t *tt;
454 int offset;
455 {
456 extern char *mbr_binary;
457 /* Update code */
458 memcpy(mbr->code, mbr_binary, MBR_CODE_SIZE);
459 printf("Machine code updated.\n");
460 return (CMD_DIRTY);
461 }
462
463 int
464 Xflag(cmd, disk, mbr, tt, offset)
465 cmd_t *cmd;
466 disk_t *disk;
467 mbr_t *mbr;
468 mbr_t *tt;
469 int offset;
470 {
471 int i, pn = -1;
472
473 /* Parse partition table entry number */
474 if (!isdigit(cmd->args[0])) {
475 printf("Invalid argument: %s <partition number>\n", cmd->cmd);
476 return (CMD_CONT);
477 }
478 pn = atoi(cmd->args) - 1;
479
480 if (pn < 0 || pn > 3) {
481 printf("Invalid partition number.\n");
482 return (CMD_CONT);
483 }
484
485 /* Set active flag */
486 for (i = 0; i < 4; i++) {
487 if (i == pn)
488 mbr->part[i].flag = DOSACTIVE;
489 else
490 mbr->part[i].flag = 0x00;
491 }
492
493 printf("Partition %d marked active.\n", pn + 1);
494 return (CMD_DIRTY);
495 }
496
497 int
498 Xmanual(cmd, disk, mbr, tt, offset)
499 cmd_t *cmd;
500 disk_t *disk;
501 mbr_t *mbr;
502 mbr_t *tt;
503 int offset;
504 {
505 system("man 8 fdisk");
506 return (CMD_CONT);
507 }