1 /* 2 * Copyright (c)2004 The DragonFly Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * Neither the name of the DragonFly Project nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 * OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * fn_disk.c 36 * Disk functions for installer. 37 * $Id: fn_disk.c,v 1.40 2005/03/13 01:53:58 cpressey Exp $ 38 */ 39 40 #include <stdlib.h> 41 #include <string.h> 42 43 #ifdef ENABLE_NLS 44 #include <libintl.h> 45 #define _(String) gettext (String) 46 #else 47 #define _(String) (String) 48 #endif 49 50 #include "libaura/mem.h" 51 #include "libaura/fspred.h" 52 53 #include "libdfui/dfui.h" 54 #include "libdfui/system.h" 55 56 #include "libinstaller/commands.h" 57 #include "libinstaller/diskutil.h" 58 #include "libinstaller/functions.h" 59 #include "libinstaller/uiutil.h" 60 61 #include "fn.h" 62 #include "pathnames.h" 63 64 /*** DISK-RELATED FUNCTIONS ***/ 65 66 /* 67 * Ask the user which physical disk they want. 68 * Changes ss->selected_disk if successful. 69 */ 70 void 71 fn_select_disk(struct i_fn_args *a) 72 { 73 struct dfui_form *f; 74 struct dfui_action *k; 75 struct dfui_response *r; 76 struct disk *d; 77 78 f = dfui_form_create( 79 "select_disk", 80 _("Select Disk"), 81 a->short_desc, 82 "", 83 84 "p", "role", "menu", 85 "p", "special", "dfinstaller_select_disk", 86 87 NULL 88 ); 89 90 for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) { 91 dfui_form_action_add(f, disk_get_device_name(d), 92 dfui_info_new(disk_get_desc(d), "", "")); 93 } 94 95 k = dfui_form_action_add(f, "cancel", 96 dfui_info_new(a->cancel_desc, "", "")); 97 dfui_action_property_set(k, "accelerator", "ESC"); 98 99 if (!dfui_be_present(a->c, f, &r)) 100 abort_backend(); 101 102 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 103 a->result = 0; 104 } else { 105 d = disk_find(a->s, dfui_response_get_action_id(r)); 106 if (d == NULL) { 107 inform(a->c, _("Internal error - response from frontend " 108 "should be a valid device name.")); 109 a->result = 0; 110 } else { 111 storage_set_selected_disk(a->s, d); 112 a->result = 1; 113 } 114 } 115 116 dfui_form_free(f); 117 dfui_response_free(r); 118 } 119 120 /* 121 * Ask the user which slice on a the selected disk they want. 122 * Changes ss->selected_slice. 123 */ 124 void 125 fn_select_slice(struct i_fn_args *a) 126 { 127 struct dfui_form *f; 128 struct dfui_action *k; 129 struct dfui_response *r; 130 struct slice *s; 131 char string[16]; 132 133 f = dfui_form_create( 134 "select_slice", 135 _("Select Primary Partition"), 136 a->short_desc, 137 "", 138 139 "p", "role", "menu", 140 "p", "special", "dfinstaller_select_slice", 141 142 NULL 143 ); 144 145 for (s = disk_slice_first(storage_get_selected_disk(a->s)); 146 s != NULL; s = slice_next(s)) { 147 snprintf(string, 16, "%d", slice_get_number(s)); 148 dfui_form_action_add(f, string, 149 dfui_info_new(slice_get_desc(s), "", "")); 150 } 151 152 k = dfui_form_action_add(f, "cancel", 153 dfui_info_new(a->cancel_desc, "", "")); 154 dfui_action_property_set(k, "accelerator", "ESC"); 155 156 if (!dfui_be_present(a->c, f, &r)) 157 abort_backend(); 158 159 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 160 a->result = 0; 161 } else { 162 s = slice_find(storage_get_selected_disk(a->s), 163 atoi(dfui_response_get_action_id(r))); 164 if (s == NULL) { 165 inform(a->c, _("Internal error - response from frontend " 166 "should be a valid slice number.")); 167 a->result = 0; 168 } else { 169 storage_set_selected_slice(a->s, s); 170 a->result = 1; 171 } 172 } 173 174 dfui_form_free(f); 175 dfui_response_free(r); 176 } 177 178 /* 179 * If ss->selected_disk == NULL, user will be asked for which disk. 180 * Returns 1 if disk was formatted, 0 if it wasn't. 181 * If it was, ss->selected_disk and ss->selected_slice are set to it. 182 */ 183 void 184 fn_format_disk(struct i_fn_args *a) 185 { 186 struct commands *cmds; 187 char *selected_disk_string; 188 189 if (storage_get_selected_disk(a->s) == NULL) { 190 a->short_desc = _("Select a disk to format."); 191 a->cancel_desc = _("Return to Utilities Menu"); 192 fn_select_disk(a); 193 if (!a->result || storage_get_selected_disk(a->s) == NULL) { 194 a->result = 0; 195 return; 196 } 197 } 198 199 if (confirm_dangerous_action(a->c, 200 _("WARNING! ALL data in ALL partitions on the disk\n\n" 201 "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY " 202 "SURE you wish to take this action? This is your " 203 "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) { 204 cmds = commands_new(); 205 206 command_add(cmds, "%s%s -BI %s", 207 a->os_root, cmd_name(a, "FDISK"), 208 disk_get_device_name(storage_get_selected_disk(a->s))); 209 210 if (!commands_execute(a, cmds)) { 211 inform(a->c, _("The disk\n\n%s\n\nwas " 212 "not correctly formatted, and may " 213 "now be in an inconsistent state. " 214 "We recommend re-formatting it " 215 "before attempting to install " 216 "%s on it."), 217 disk_get_desc(storage_get_selected_disk(a->s)), 218 OPERATING_SYSTEM_NAME); 219 commands_free(cmds); 220 a->result = 0; 221 return; 222 } 223 commands_free(cmds); 224 225 /* 226 * Since one of the disks has now changed, we must 227 * refresh our view of them and re-select the disk 228 * since the selected_disk pointer will be invalidated. 229 */ 230 selected_disk_string = aura_strdup( 231 disk_get_device_name(storage_get_selected_disk(a->s))); 232 if (!survey_storage(a)) { 233 inform(a->c, _("Errors occurred while probing " 234 "the system for its storage capabilities.")); 235 } 236 storage_set_selected_disk(a->s, disk_find(a->s, selected_disk_string)); 237 free(selected_disk_string); 238 239 /* 240 * Note that we formatted this disk and that we want 241 * to use the first (and only) slice of it. 242 */ 243 disk_set_formatted(storage_get_selected_disk(a->s), 1); 244 storage_set_selected_slice(a->s, disk_slice_first(storage_get_selected_disk(a->s))); 245 246 if (!format_slice(a)) { 247 inform(a->c, _("The sole primary partition of " 248 "the disk\n\n%s\n\nwas " 249 "not correctly formatted, and may " 250 "now be in an inconsistent state. " 251 "We recommend re-formatting the " 252 "disk before attempting to install " 253 "%s on it."), 254 disk_get_desc(storage_get_selected_disk(a->s)), 255 OPERATING_SYSTEM_NAME); 256 a->result = 0; 257 return; 258 } 259 260 inform(a->c, _("The disk\n\n%s\n\nwas formatted."), 261 disk_get_desc(storage_get_selected_disk(a->s))); 262 a->result = 1; 263 } else { 264 inform(a->c, _("Action cancelled - no disks were formatted.")); 265 a->result = 0; 266 } 267 } 268 269 /* 270 * Wipes the start of the selected disk. 271 */ 272 void 273 fn_wipe_start_of_disk(struct i_fn_args *a) 274 { 275 struct commands *cmds; 276 277 a->short_desc = _("If you are having problems formatting a disk, " 278 "it may be because of junk that has accumulated " 279 "in the boot block and the partition table. " 280 "A cure for this is to wipe out everything on " 281 "the first few sectors of the disk. However, this " 282 "is a rather drastic action to take, so it is not " 283 "recommended unless you are otherwise " 284 "encountering problems."); 285 a->cancel_desc = _("Return to Utilities Menu"); 286 fn_select_disk(a); 287 if (!a->result) 288 return; 289 290 /* XXX check to make sure no slices on this disk are mounted first? */ 291 if (storage_get_selected_disk(a->s) != NULL && confirm_dangerous_action(a->c, 292 _("WARNING! ALL data in ALL partitions on the disk\n\n" 293 "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY " 294 "SURE you wish to take this action? This is your " 295 "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) { 296 cmds = commands_new(); 297 command_add(cmds, 298 "%s%s if=%sdev/zero of=%sdev/%s bs=32k count=16", 299 a->os_root, cmd_name(a, "DD"), 300 a->os_root, a->os_root, 301 disk_get_device_name(storage_get_selected_disk(a->s))); 302 if (commands_execute(a, cmds)) { 303 inform(a->c, _("Start of disk was successfully wiped.")); 304 } else { 305 inform(a->c, _("Some errors occurred. " 306 "Start of disk was not successfully wiped.")); 307 } 308 commands_free(cmds); 309 } 310 } 311 312 /* 313 * Wipes the start of the selected slice. 314 */ 315 void 316 fn_wipe_start_of_slice(struct i_fn_args *a) 317 { 318 struct commands *cmds; 319 320 a->short_desc = 321 _("If you are having problems formatting a primary partition, " 322 "it may be because of junk that has accumulated in the " 323 "partition's `disklabel'. A cure for this is to wipe out " 324 "everything on the first few sectors of the primary partition. " 325 "However, this is a rather drastic action to take, so it is not " 326 "recommended unless you are otherwise encountering problems."); 327 a->cancel_desc = _("Return to Utilities Menu"); 328 fn_select_slice(a); 329 if (!a->result) 330 return; 331 332 if (confirm_dangerous_action(a->c, 333 _("WARNING! ALL data in primary partition #%d,\n\n%s\n\non the " 334 "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you " 335 "ABSOLUTELY SURE you wish to take this action? This is " 336 "your LAST CHANCE to cancel!"), 337 slice_get_number(storage_get_selected_slice(a->s)), 338 slice_get_desc(storage_get_selected_slice(a->s)), 339 disk_get_desc(storage_get_selected_disk(a->s)))) { 340 /* XXX check to make sure this slice is not mounted first */ 341 cmds = commands_new(); 342 command_add(cmds, "%s%s if=%sdev/zero of=%sdev/%s bs=32k count=16", 343 a->os_root, cmd_name(a, "DD"), 344 a->os_root, a->os_root, 345 slice_get_device_name(storage_get_selected_slice(a->s))); 346 if (commands_execute(a, cmds)) { 347 inform(a->c, _("Start of primary partition was successfully wiped.")); 348 } else { 349 inform(a->c, _("Some errors occurred. " 350 "Start of primary partition was not successfully wiped.")); 351 } 352 commands_free(cmds); 353 } 354 } 355 356 static void 357 ask_to_wipe_boot_sector(struct i_fn_args *a, struct commands *fcmds) 358 { 359 struct commands *cmds; 360 struct command *cmd; 361 char *disk; 362 363 for (cmd = command_get_first(fcmds); cmd != NULL; 364 cmd = command_get_next(cmd)) { 365 disk = command_get_tag(cmd); 366 if (disk != NULL && 367 command_get_result(cmd) > 0 && 368 command_get_result(cmd) < 256) { 369 switch (dfui_be_present_dialog(a->c, 370 _("Bootblock Install Failed"), 371 _("Re-Initialize Bootblock|Cancel"), 372 _("Warning: bootblocks were not successfully " 373 "installed on the disk `%s'. This may be " 374 "because the disk is new and not yet " 375 "formatted. If this is the case, it might " 376 "help to re-initialize the boot sector, " 377 "then try installing the bootblock again. " 378 "Note that this should not affect the " 379 "partition table of the disk."), 380 disk, disk)) { 381 case 1: 382 cmds = commands_new(); 383 command_add(cmds, 384 "%s%s | %s%s -B %sdev/%s", 385 a->os_root, cmd_name(a, "YES"), 386 a->os_root, cmd_name(a, "FDISK"), 387 a->os_root, disk); 388 if (commands_execute(a, cmds)) { 389 inform(a->c, _("Boot sector successfully initialized.")); 390 } else { 391 inform(a->c, _("Some errors occurred. " 392 "Boot sector was not successfully initialized.")); 393 } 394 commands_free(cmds); 395 break; 396 default: 397 break; 398 } 399 } 400 } 401 } 402 403 void 404 fn_install_bootblocks(struct i_fn_args *a) 405 { 406 struct dfui_form *f; 407 struct dfui_response *r; 408 struct dfui_dataset *ds; 409 struct disk *d; 410 struct commands *cmds; 411 struct command *cmd; 412 char disk[64], boot0cfg[32], packet[32]; 413 char msg_buf[1][1024]; 414 415 snprintf(msg_buf[0], sizeof(msg_buf[0]), 416 "'Packet Mode' refers to using newer BIOS calls to boot " 417 "from a partition of the disk. It is generally not " 418 "required unless:\n\n" 419 "- your BIOS does not support legacy mode; or\n" 420 "- your %s primary partition resides on a " 421 "cylinder of the disk beyond cylinder 1024; or\n" 422 "- you just can't get it to boot without it.", 423 OPERATING_SYSTEM_NAME); 424 425 f = dfui_form_create( 426 "install_bootstrap", 427 _("Install Bootblock(s)"), 428 a->short_desc, 429 430 msg_buf[0], 431 432 "p", "special", "dfinstaller_install_bootstrap", 433 434 "f", "disk", _("Disk Drive"), 435 _("The disk on which you wish to install a bootblock"), "", 436 "p", "editable", "false", 437 "f", "boot0cfg", _("Install Bootblock?"), 438 _("Install a bootblock on this disk"), "", 439 "p", "control", "checkbox", 440 "f", "packet", _("Packet Mode?"), 441 _("Select this to use 'packet mode' to boot the disk"), "", 442 "p", "control", "checkbox", 443 444 "a", "ok", _("Accept and Install Bootblocks"), "", "", 445 "a", "cancel", a->cancel_desc, "", "", 446 "p", "accelerator", "ESC", 447 448 NULL 449 ); 450 451 dfui_form_set_multiple(f, 1); 452 453 for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) { 454 ds = dfui_dataset_new(); 455 /* XXX need to see how this is handled in OpenBSD/NetBSD */ 456 dfui_dataset_celldata_add(ds, "disk", disk_get_device_name(d)); 457 dfui_dataset_celldata_add(ds, "boot0cfg", "Y"); 458 dfui_dataset_celldata_add(ds, "packet", "Y"); 459 dfui_form_dataset_add(f, ds); 460 } 461 462 if (!dfui_be_present(a->c, f, &r)) 463 abort_backend(); 464 465 a->result = 0; 466 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 467 cmds = commands_new(); 468 469 for (ds = dfui_response_dataset_get_first(r); ds != NULL; 470 ds = dfui_dataset_get_next(ds)) { 471 strlcpy(disk, dfui_dataset_get_value(ds, "disk"), 64); 472 strlcpy(boot0cfg, dfui_dataset_get_value(ds, "boot0cfg"), 32); 473 strlcpy(packet, dfui_dataset_get_value(ds, "packet"), 32); 474 475 if (strcasecmp(boot0cfg, "Y") == 0) { 476 cmd = command_add(cmds, "%s%s -B -o %spacket %s", 477 a->os_root, cmd_name(a, "BOOT0CFG"), 478 strcasecmp(packet, "Y") == 0 ? "" : "no", 479 disk); 480 command_set_failure_mode(cmd, COMMAND_FAILURE_WARN); 481 command_set_tag(cmd, disk); 482 cmd = command_add(cmds, "%s%s -v %s", 483 a->os_root, cmd_name(a, "BOOT0CFG"), 484 disk); 485 command_set_failure_mode(cmd, COMMAND_FAILURE_WARN); 486 command_set_tag(cmd, disk); 487 } 488 } 489 490 if (!commands_execute(a, cmds)) { 491 ask_to_wipe_boot_sector(a, cmds); 492 } else { 493 inform(a->c, _("Bootblocks were successfully installed!")); 494 a->result = 1; 495 } 496 commands_free(cmds); 497 } 498 499 dfui_form_free(f); 500 dfui_response_free(r); 501 } 502 503 void 504 fn_format_msdos_floppy(struct i_fn_args *a) 505 { 506 struct commands *cmds; 507 508 switch (dfui_be_present_dialog(a->c, _("Format MSDOS Floppy"), 509 _("Format Floppy|Return to Utilities Menu"), 510 _("Please insert the floppy to be formatted " 511 "in unit 0 (``drive A:'')."))) { 512 case 1: 513 cmds = commands_new(); 514 command_add(cmds, "%s%s -y -f 1440 /dev/fd0", 515 a->os_root, cmd_name(a, "FDFORMAT")); 516 command_add(cmds, "%s%s -f 1440 fd0", 517 a->os_root, cmd_name(a, "NEWFS_MSDOS")); 518 if (commands_execute(a, cmds)) 519 inform(a->c, _("Floppy successfully formatted!")); 520 else 521 inform(a->c, _("Floppy was not successfully formatted.")); 522 break; 523 case 2: 524 return; 525 default: 526 abort_backend(); 527 } 528 } 529 530 void 531 fn_create_cdboot_floppy(struct i_fn_args *a) 532 { 533 struct commands *cmds; 534 char msg_buf[1][1024]; 535 536 snprintf(msg_buf[0], sizeof(msg_buf[0]), 537 "%s cannot be installed from a floppy; " 538 "it must be installed from a booted CD-ROM. " 539 "However, many older systems do not support booting " 540 "from a CD-ROM. For these systems, a boot disk can be " 541 "created. This boot disk contains the Smart Boot " 542 "Manager program, which can boot a CD-ROM even " 543 "on systems with BIOSes which do not support booting " 544 "from the CD-ROM.\n\n" 545 "Smart Boot Manager is not a part of %s; " 546 "the Smart Boot Manager project can be found here:\n\n" 547 "http://btmgr.sourceforge.net/\n\n" 548 "To create a CDBoot floppy, insert a blank floppy " 549 "in unit 0 (``drive A:'') before proceeding." 550 "", 551 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME); 552 553 switch (dfui_be_present_dialog(a->c, _("Create CDBoot Floppy"), 554 _("Create CDBoot Floppy|Return to Utilities Menu"), 555 msg_buf[0])) { 556 case 1: 557 cmds = commands_new(); 558 command_add(cmds, "%s%s -c %sboot/cdboot.flp.bz2 | " 559 "%s%s of=%sdev/fd0 bs=32k", 560 a->os_root, cmd_name(a, "BUNZIP2"), 561 a->os_root, 562 a->os_root, cmd_name(a, "DD"), 563 a->os_root); 564 if (commands_execute(a, cmds)) 565 inform(a->c, _("CDBoot floppy successfully created!")); 566 else 567 inform(a->c, _("CDBoot floppy was not successfully created.")); 568 break; 569 case 2: 570 return; 571 default: 572 abort_backend(); 573 } 574 } 575 576 void 577 fn_create_memtest86_floppy(struct i_fn_args *a) 578 { 579 struct commands *cmds; 580 581 switch (dfui_be_present_dialog(a->c, _("Create memtest86 Floppy"), 582 "Create memtest86 Floppy|Return to Utilities Menu", 583 "While this installer allows you to test memory " 584 "on-line, the fact that the installer and operating " 585 "system are already loaded means that the memory " 586 "test has certain limits. For a more thorough " 587 "memory test, you can create a floppy containing " 588 "the memtest86 program, which boots up independently " 589 "of any operating system, allowing it access to " 590 "almost the entire memory of the computer for testing.\n\n" 591 "memtest86 is not a part of %s; " 592 "the memtest86 project can be found here:\n\n" 593 "http://www.memtest86.com/\n\n" 594 "To create a memtest86 floppy, insert a blank floppy " 595 "in unit 0 (``drive A:'') before proceeding." 596 "", OPERATING_SYSTEM_NAME)) { 597 case 1: 598 cmds = commands_new(); 599 command_add(cmds, "%s%s -c %sboot/memtest86.flp.bz2 | " 600 "%s%s of=%sdev/fd0 bs=32k", 601 a->os_root, cmd_name(a, "BUNZIP2"), 602 a->os_root, 603 a->os_root, cmd_name(a, "DD"), 604 a->os_root); 605 if (commands_execute(a, cmds)) 606 inform(a->c, _("memtest86 floppy successfully created!")); 607 else 608 inform(a->c, _("memtest86 floppy was not successfully created.")); 609 break; 610 case 2: 611 return; 612 default: 613 abort_backend(); 614 } 615 } 616 617 /**** NON-fn_ FUNCTIONS ***/ 618 619 int 620 format_slice(struct i_fn_args *a) 621 { 622 struct commands *cmds; 623 int result; 624 int cyl, hd, sec; 625 626 cmds = commands_new(); 627 628 /* 629 * The information in a->s NEEDS to be accurate here! 630 * Presumably we just did a survey_storage() recently. 631 * XXX should we do another one here anyway just to be paranoid? 632 */ 633 634 /* 635 * Set the slice's sysid to 165. 636 */ 637 disk_get_geometry(storage_get_selected_disk(a->s), &cyl, &hd, &sec); 638 command_add(cmds, "%s%s 'g c%d h%d s%d' >%snew.fdisk", 639 a->os_root, cmd_name(a, "ECHO"), 640 cyl, hd, sec, 641 a->tmp); 642 command_add(cmds, "%s%s 'p %d %d %lu %lu' >>%snew.fdisk", 643 a->os_root, cmd_name(a, "ECHO"), 644 slice_get_number(storage_get_selected_slice(a->s)), 645 165, 646 slice_get_start(storage_get_selected_slice(a->s)), 647 slice_get_size(storage_get_selected_slice(a->s)), 648 a->tmp); 649 if (slice_get_flags(storage_get_selected_slice(a->s)) & 0x80) { 650 command_add(cmds, "%s%s 'a %d' >>%snew.fdisk", 651 a->os_root, cmd_name(a, "ECHO"), 652 slice_get_number(storage_get_selected_slice(a->s)), 653 a->tmp); 654 } 655 656 command_add(cmds, "%s%s %snew.fdisk", 657 a->os_root, cmd_name(a, "CAT"), a->tmp); 658 temp_file_add(a, "new.fdisk"); 659 660 /* 661 * Execute the fdisk script. 662 */ 663 command_add(cmds, "%s%s -v -f %snew.fdisk %s", 664 a->os_root, cmd_name(a, "FDISK"), a->tmp, 665 disk_get_device_name(storage_get_selected_disk(a->s))); 666 667 /* 668 * If there is an old 'virgin' disklabel hanging around 669 * in the temp dir, get rid of it. This won't happen 670 * from a real CD, but might happen with '-o' installs. 671 */ 672 command_add(cmds, "%s%s -f %sinstall.disklabel.%s", 673 a->os_root, cmd_name(a, "RM"), 674 a->tmp, 675 slice_get_device_name(storage_get_selected_slice(a->s))); 676 677 result = commands_execute(a, cmds); 678 679 commands_free(cmds); 680 681 return(result); 682 } 683