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 <sys/diskmbr.h> 41 42 #include <stdlib.h> 43 #include <unistd.h> 44 #include <string.h> 45 46 #ifdef ENABLE_NLS 47 #include <libintl.h> 48 #define _(String) gettext (String) 49 #else 50 #define _(String) (String) 51 #endif 52 53 #include "libaura/mem.h" 54 #include "libaura/fspred.h" 55 56 #include "libdfui/dfui.h" 57 #include "libdfui/system.h" 58 59 #include "libinstaller/commands.h" 60 #include "libinstaller/diskutil.h" 61 #include "libinstaller/functions.h" 62 #include "libinstaller/uiutil.h" 63 64 #include "fn.h" 65 #include "pathnames.h" 66 67 /*** DISK-RELATED FUNCTIONS ***/ 68 69 /* 70 * Ask the user which physical disk they want. 71 * Changes ss->selected_disk if successful. 72 */ 73 void 74 fn_select_disk(struct i_fn_args *a) 75 { 76 struct dfui_form *f; 77 struct dfui_action *k; 78 struct dfui_response *r; 79 struct disk *d; 80 81 f = dfui_form_create( 82 "select_disk", 83 _("Select Disk"), 84 a->short_desc, 85 "", 86 87 "p", "role", "menu", 88 "p", "special", "dfinstaller_select_disk", 89 90 NULL 91 ); 92 93 for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) { 94 dfui_form_action_add(f, disk_get_device_name(d), 95 dfui_info_new(disk_get_desc(d), "", "")); 96 } 97 98 k = dfui_form_action_add(f, "cancel", 99 dfui_info_new(a->cancel_desc, "", "")); 100 dfui_action_property_set(k, "accelerator", "ESC"); 101 102 if (!dfui_be_present(a->c, f, &r)) 103 abort_backend(); 104 105 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 106 a->result = 0; 107 } else { 108 d = disk_find(a->s, dfui_response_get_action_id(r)); 109 if (d == NULL) { 110 inform(a->c, _("Internal error - response from frontend " 111 "should be a valid device name.")); 112 a->result = 0; 113 } else { 114 storage_set_selected_disk(a->s, d); 115 a->result = 1; 116 } 117 } 118 119 dfui_form_free(f); 120 dfui_response_free(r); 121 } 122 123 /* 124 * Ask the user which slice on a the selected disk they want. 125 * Changes ss->selected_slice. 126 */ 127 void 128 fn_select_slice(struct i_fn_args *a) 129 { 130 struct dfui_form *f; 131 struct dfui_action *k; 132 struct dfui_response *r; 133 struct slice *s; 134 char string[16]; 135 136 f = dfui_form_create( 137 "select_slice", 138 _("Select Primary Partition"), 139 a->short_desc, 140 "", 141 142 "p", "role", "menu", 143 "p", "special", "dfinstaller_select_slice", 144 145 NULL 146 ); 147 148 for (s = disk_slice_first(storage_get_selected_disk(a->s)); 149 s != NULL; s = slice_next(s)) { 150 snprintf(string, 16, "%d", slice_get_number(s)); 151 dfui_form_action_add(f, string, 152 dfui_info_new(slice_get_desc(s), "", "")); 153 } 154 155 k = dfui_form_action_add(f, "cancel", 156 dfui_info_new(a->cancel_desc, "", "")); 157 dfui_action_property_set(k, "accelerator", "ESC"); 158 159 if (!dfui_be_present(a->c, f, &r)) 160 abort_backend(); 161 162 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 163 a->result = 0; 164 } else { 165 s = slice_find(storage_get_selected_disk(a->s), 166 atoi(dfui_response_get_action_id(r))); 167 if (s == NULL) { 168 inform(a->c, _("Internal error - response from frontend " 169 "should be a valid slice number.")); 170 a->result = 0; 171 } else { 172 storage_set_selected_slice(a->s, s); 173 a->result = 1; 174 } 175 } 176 177 dfui_form_free(f); 178 dfui_response_free(r); 179 } 180 181 /* 182 * If ss->selected_disk == NULL, user will be asked for which disk. 183 * Returns 1 if disk was formatted, 0 if it wasn't. 184 * If it was, ss->selected_disk and ss->selected_slice are set to it. 185 */ 186 void 187 fn_format_disk_mbr(struct i_fn_args *a) 188 { 189 struct commands *cmds; 190 char *selected_disk_string; 191 192 if (storage_get_selected_disk(a->s) == NULL) { 193 a->short_desc = _("Select a disk to format."); 194 a->cancel_desc = _("Return to Utilities Menu"); 195 fn_select_disk(a); 196 if (!a->result || storage_get_selected_disk(a->s) == NULL) { 197 a->result = 0; 198 return; 199 } 200 } 201 202 if (confirm_dangerous_action(a->c, 203 _("WARNING! ALL data in ALL partitions on the disk\n\n" 204 "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY " 205 "SURE you wish to take this action? This is your " 206 "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) { 207 cmds = commands_new(); 208 209 command_add(cmds, 210 "%s%s if=/dev/zero of=/dev/%s bs=32k count=16", 211 a->os_root, cmd_name(a, "DD"), 212 disk_get_device_name(storage_get_selected_disk(a->s))); 213 command_add(cmds, "%s%s -BI %s", 214 a->os_root, cmd_name(a, "FDISK"), 215 disk_get_device_name(storage_get_selected_disk(a->s))); 216 217 if (!commands_execute(a, cmds)) { 218 inform(a->c, _("The disk\n\n%s\n\nwas " 219 "not correctly formatted, and may " 220 "now be in an inconsistent state. " 221 "We recommend re-formatting it " 222 "before attempting to install " 223 "%s on it."), 224 disk_get_desc(storage_get_selected_disk(a->s)), 225 OPERATING_SYSTEM_NAME); 226 commands_free(cmds); 227 a->result = 0; 228 return; 229 } 230 commands_free(cmds); 231 232 /* 233 * Since one of the disks has now changed, we must 234 * refresh our view of them and re-select the disk 235 * since the selected_disk pointer will be invalidated. 236 */ 237 selected_disk_string = aura_strdup( 238 disk_get_device_name(storage_get_selected_disk(a->s))); 239 if (!survey_storage(a)) { 240 inform(a->c, _("Errors occurred while probing " 241 "the system for its storage capabilities.")); 242 } 243 storage_set_selected_disk(a->s, disk_find(a->s, selected_disk_string)); 244 free(selected_disk_string); 245 246 /* 247 * Note that we formatted this disk and that we want 248 * to use the first (and only) slice of it. 249 */ 250 disk_set_formatted(storage_get_selected_disk(a->s), 1); 251 storage_set_selected_slice(a->s, disk_slice_first(storage_get_selected_disk(a->s))); 252 253 if (!format_slice(a)) { 254 inform(a->c, _("The sole primary partition of " 255 "the disk\n\n%s\n\nwas " 256 "not correctly formatted, and may " 257 "now be in an inconsistent state. " 258 "We recommend re-formatting the " 259 "disk before attempting to install " 260 "%s on it."), 261 disk_get_desc(storage_get_selected_disk(a->s)), 262 OPERATING_SYSTEM_NAME); 263 a->result = 0; 264 return; 265 } 266 inform(a->c, _("The disk\n\n%s\n\nwas formatted."), 267 disk_get_desc(storage_get_selected_disk(a->s))); 268 a->result = 1; 269 } else { 270 inform(a->c, _("Action cancelled - no disks were formatted.")); 271 a->result = 0; 272 } 273 } 274 275 void 276 fn_format_disk_uefi(struct i_fn_args *a) 277 { 278 struct commands *cmds; 279 char *selected_disk_string; 280 281 if (storage_get_selected_disk(a->s) == NULL) { 282 a->short_desc = _("Select a disk to format."); 283 a->cancel_desc = _("Return to Utilities Menu"); 284 fn_select_disk(a); 285 if (!a->result || storage_get_selected_disk(a->s) == NULL) { 286 a->result = 0; 287 return; 288 } 289 } 290 291 if (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 298 command_add(cmds, 299 "%s%s if=/dev/zero of=/dev/%s bs=32k count=16", 300 a->os_root, cmd_name(a, "DD"), 301 disk_get_device_name(storage_get_selected_disk(a->s))); 302 command_add(cmds, "%s%s destroy %s", 303 a->os_root, cmd_name(a, "GPT"), 304 disk_get_device_name(storage_get_selected_disk(a->s))); 305 command_add(cmds, "%s%s create -f %s", 306 a->os_root, cmd_name(a, "GPT"), 307 disk_get_device_name(storage_get_selected_disk(a->s))); 308 command_add(cmds, "%s%s add -i 0 -s 262144 -t efi %s", 309 a->os_root, cmd_name(a, "GPT"), 310 disk_get_device_name(storage_get_selected_disk(a->s))); 311 command_add(cmds, "%s%s add -i 1 -t dragonfly %s", 312 a->os_root, cmd_name(a, "GPT"), 313 disk_get_device_name(storage_get_selected_disk(a->s))); 314 command_add(cmds, "%s%s -F 32 -c 2 -L EFI -m 0xf8 %ss0", 315 a->os_root, cmd_name(a, "NEWFS_MSDOS"), 316 disk_get_device_name(storage_get_selected_disk(a->s))); 317 command_add(cmds, "%s%s /dev/%ss0 %smnt", 318 a->os_root, cmd_name(a, "MOUNT_MSDOS"), 319 disk_get_device_name(storage_get_selected_disk(a->s)), 320 a->os_root); 321 command_add(cmds, "%s%s -p %smnt/EFI/BOOT", 322 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 323 command_add(cmds, 324 "%s%s %s/boot/boot1.efi %smnt/EFI/BOOT/BOOTX64.EFI", 325 a->os_root, cmd_name(a, "CP"), 326 a->os_root, a->os_root); 327 command_add(cmds, "%s%s %smnt", 328 a->os_root, cmd_name(a, "UMOUNT"), a->os_root); 329 330 if (!commands_execute(a, cmds)) { 331 inform(a->c, _("The disk\n\n%s\n\nwas " 332 "not correctly formatted, and may " 333 "now be in an inconsistent state. " 334 "We recommend re-formatting it " 335 "before attempting to install " 336 "%s on it."), 337 disk_get_desc(storage_get_selected_disk(a->s)), 338 OPERATING_SYSTEM_NAME); 339 commands_free(cmds); 340 a->result = 0; 341 return; 342 } 343 commands_free(cmds); 344 345 /* 346 * Since one of the disks has now changed, we must 347 * refresh our view of them and re-select the disk 348 * since the selected_disk pointer will be invalidated. 349 */ 350 selected_disk_string = aura_strdup( 351 disk_get_device_name(storage_get_selected_disk(a->s))); 352 if (!survey_storage(a)) { 353 inform(a->c, _("Errors occurred while probing " 354 "the system for its storage capabilities.")); 355 } 356 storage_set_selected_disk(a->s, 357 disk_find(a->s, selected_disk_string)); 358 free(selected_disk_string); 359 360 /* 361 * Note that we formatted this disk and that we want 362 * to use the first (and only) slice of it. 363 */ 364 disk_set_formatted(storage_get_selected_disk(a->s), 1); 365 storage_set_selected_slice(a->s, 366 disk_slice_first(storage_get_selected_disk(a->s))); 367 368 inform(a->c, _("The disk\n\n%s\n\nwas formatted."), 369 disk_get_desc(storage_get_selected_disk(a->s))); 370 a->result = 1; 371 } else { 372 inform(a->c, _("Action cancelled - no disks were formatted.")); 373 a->result = 0; 374 } 375 } 376 377 /* 378 * Wipes the start of the selected disk. 379 */ 380 void 381 fn_wipe_start_of_disk(struct i_fn_args *a) 382 { 383 struct commands *cmds; 384 385 a->short_desc = _("If you are having problems formatting a disk, " 386 "it may be because of junk that has accumulated " 387 "in the boot block and the partition table. " 388 "A cure for this is to wipe out everything on " 389 "the first few sectors of the disk. However, this " 390 "is a rather drastic action to take, so it is not " 391 "recommended unless you are otherwise " 392 "encountering problems."); 393 a->cancel_desc = _("Return to Utilities Menu"); 394 fn_select_disk(a); 395 if (!a->result) 396 return; 397 398 /* XXX check to make sure no slices on this disk are mounted first? */ 399 if (storage_get_selected_disk(a->s) != NULL && confirm_dangerous_action(a->c, 400 _("WARNING! ALL data in ALL partitions on the disk\n\n" 401 "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY " 402 "SURE you wish to take this action? This is your " 403 "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) { 404 cmds = commands_new(); 405 command_add(cmds, 406 "%s%s if=/dev/zero of=/dev/%s bs=32k count=16", 407 a->os_root, cmd_name(a, "DD"), 408 disk_get_device_name(storage_get_selected_disk(a->s))); 409 if (commands_execute(a, cmds)) { 410 inform(a->c, _("Start of disk was successfully wiped.")); 411 } else { 412 inform(a->c, _("Some errors occurred. " 413 "Start of disk was not successfully wiped.")); 414 } 415 commands_free(cmds); 416 } 417 } 418 419 /* 420 * Wipes the start of the selected slice. 421 */ 422 void 423 fn_wipe_start_of_slice(struct i_fn_args *a) 424 { 425 struct commands *cmds; 426 427 a->short_desc = 428 _("If you are having problems formatting a primary partition, " 429 "it may be because of junk that has accumulated in the " 430 "partition's `disklabel'. A cure for this is to wipe out " 431 "everything on the first few sectors of the primary partition. " 432 "However, this is a rather drastic action to take, so it is not " 433 "recommended unless you are otherwise encountering problems."); 434 a->cancel_desc = _("Return to Utilities Menu"); 435 fn_select_slice(a); 436 if (!a->result) 437 return; 438 439 if (confirm_dangerous_action(a->c, 440 _("WARNING! ALL data in primary partition #%d,\n\n%s\n\non the " 441 "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you " 442 "ABSOLUTELY SURE you wish to take this action? This is " 443 "your LAST CHANCE to cancel!"), 444 slice_get_number(storage_get_selected_slice(a->s)), 445 slice_get_desc(storage_get_selected_slice(a->s)), 446 disk_get_desc(storage_get_selected_disk(a->s)))) { 447 /* XXX check to make sure this slice is not mounted first */ 448 cmds = commands_new(); 449 command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16", 450 a->os_root, cmd_name(a, "DD"), 451 slice_get_device_name(storage_get_selected_slice(a->s))); 452 if (commands_execute(a, cmds)) { 453 inform(a->c, _("Start of primary partition was successfully wiped.")); 454 } else { 455 inform(a->c, _("Some errors occurred. " 456 "Start of primary partition was not successfully wiped.")); 457 } 458 commands_free(cmds); 459 } 460 } 461 462 static void 463 ask_to_wipe_boot_sector(struct i_fn_args *a, struct commands *fcmds) 464 { 465 struct commands *cmds; 466 struct command *cmd; 467 char *disk; 468 469 for (cmd = command_get_first(fcmds); cmd != NULL; 470 cmd = command_get_next(cmd)) { 471 disk = command_get_tag(cmd); 472 if (disk != NULL && 473 command_get_result(cmd) > 0 && 474 command_get_result(cmd) < 256) { 475 switch (dfui_be_present_dialog(a->c, 476 _("Bootblock Install Failed"), 477 _("Re-Initialize Bootblock|Cancel"), 478 _("Warning: bootblocks were not successfully " 479 "installed on the disk `%s'. This may be " 480 "because the disk is new and not yet " 481 "formatted. If this is the case, it might " 482 "help to re-initialize the boot sector, " 483 "then try installing the bootblock again. " 484 "Note that this should not affect the " 485 "partition table of the disk."), 486 disk)) { 487 case 1: 488 cmds = commands_new(); 489 command_add(cmds, 490 "%s%s | %s%s -B /dev/%s", 491 a->os_root, cmd_name(a, "YES"), 492 a->os_root, cmd_name(a, "FDISK"), 493 disk); 494 if (commands_execute(a, cmds)) { 495 inform(a->c, _("Boot sector successfully initialized.")); 496 } else { 497 inform(a->c, _("Some errors occurred. " 498 "Boot sector was not successfully initialized.")); 499 } 500 commands_free(cmds); 501 break; 502 default: 503 break; 504 } 505 } 506 } 507 } 508 509 void 510 fn_install_bootblocks(struct i_fn_args *a, const char *device) 511 { 512 struct dfui_form *f; 513 struct dfui_response *r; 514 struct dfui_dataset *ds; 515 struct disk *d; 516 struct commands *cmds; 517 struct command *cmd; 518 char disk[64], boot0cfg[32], packet[32]; 519 char msg_buf[1][1024]; 520 521 snprintf(msg_buf[0], sizeof(msg_buf[0]), 522 "'Packet Mode' refers to using newer BIOS calls to boot " 523 "from a partition of the disk. It is generally not " 524 "required unless:\n\n" 525 "- your BIOS does not support legacy mode; or\n" 526 "- your %s primary partition resides on a " 527 "cylinder of the disk beyond cylinder 1024; or\n" 528 "- you just can't get it to boot without it.", 529 OPERATING_SYSTEM_NAME); 530 531 f = dfui_form_create( 532 "install_bootstrap", 533 _("Install Bootblock(s)"), 534 a->short_desc, 535 536 msg_buf[0], 537 538 "p", "special", "dfinstaller_install_bootstrap", 539 540 "f", "disk", _("Disk Drive"), 541 _("The disk on which you wish to install a bootblock"), "", 542 "p", "editable", "false", 543 "f", "boot0cfg", _("Install Bootblock?"), 544 _("Install a bootblock on this disk"), "", 545 "p", "control", "checkbox", 546 "f", "packet", _("Packet Mode?"), 547 _("Select this to use 'packet mode' to boot the disk"), "", 548 "p", "control", "checkbox", 549 550 "a", "ok", _("Accept and Install Bootblocks"), "", "", 551 "a", "cancel", a->cancel_desc, "", "", 552 "p", "accelerator", "ESC", 553 554 NULL 555 ); 556 557 dfui_form_set_multiple(f, 1); 558 559 if (device != NULL) { 560 ds = dfui_dataset_new(); 561 dfui_dataset_celldata_add(ds, "disk", device); 562 dfui_dataset_celldata_add(ds, "boot0cfg", "Y"); 563 dfui_dataset_celldata_add(ds, "packet", "Y"); 564 dfui_form_dataset_add(f, ds); 565 } else { 566 for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) { 567 ds = dfui_dataset_new(); 568 dfui_dataset_celldata_add(ds, "disk", 569 disk_get_device_name(d)); 570 dfui_dataset_celldata_add(ds, "boot0cfg", "Y"); 571 dfui_dataset_celldata_add(ds, "packet", "Y"); 572 dfui_form_dataset_add(f, ds); 573 } 574 } 575 576 if (!dfui_be_present(a->c, f, &r)) 577 abort_backend(); 578 579 a->result = 0; 580 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 581 cmds = commands_new(); 582 583 for (ds = dfui_response_dataset_get_first(r); ds != NULL; 584 ds = dfui_dataset_get_next(ds)) { 585 strlcpy(disk, dfui_dataset_get_value(ds, "disk"), 64); 586 strlcpy(boot0cfg, dfui_dataset_get_value(ds, "boot0cfg"), 32); 587 strlcpy(packet, dfui_dataset_get_value(ds, "packet"), 32); 588 589 if (strcasecmp(boot0cfg, "Y") == 0) { 590 cmd = command_add(cmds, "%s%s -B -o %spacket %s", 591 a->os_root, cmd_name(a, "BOOT0CFG"), 592 strcasecmp(packet, "Y") == 0 ? "" : "no", 593 disk); 594 command_set_failure_mode(cmd, COMMAND_FAILURE_WARN); 595 command_set_tag(cmd, "%s", disk); 596 cmd = command_add(cmds, "%s%s -v %s", 597 a->os_root, cmd_name(a, "BOOT0CFG"), 598 disk); 599 command_set_failure_mode(cmd, COMMAND_FAILURE_WARN); 600 command_set_tag(cmd, "%s", disk); 601 } 602 } 603 604 if (!commands_execute(a, cmds)) { 605 ask_to_wipe_boot_sector(a, cmds); 606 } else { 607 inform(a->c, _("Bootblocks were successfully installed!")); 608 a->result = 1; 609 } 610 commands_free(cmds); 611 } 612 613 dfui_form_free(f); 614 dfui_response_free(r); 615 } 616 617 void 618 fn_format_msdos_floppy(struct i_fn_args *a) 619 { 620 struct commands *cmds; 621 622 switch (dfui_be_present_dialog(a->c, _("Format MSDOS Floppy"), 623 _("Format Floppy|Return to Utilities Menu"), 624 _("Please insert the floppy to be formatted " 625 "in unit 0 (``drive A:'')."))) { 626 case 1: 627 cmds = commands_new(); 628 command_add(cmds, "%s%s -y -f 1440 /dev/fd0", 629 a->os_root, cmd_name(a, "FDFORMAT")); 630 command_add(cmds, "%s%s -f 1440 fd0", 631 a->os_root, cmd_name(a, "NEWFS_MSDOS")); 632 if (commands_execute(a, cmds)) 633 inform(a->c, _("Floppy successfully formatted!")); 634 else 635 inform(a->c, _("Floppy was not successfully formatted.")); 636 break; 637 case 2: 638 return; 639 default: 640 abort_backend(); 641 } 642 } 643 644 void 645 fn_create_cdboot_floppy(struct i_fn_args *a) 646 { 647 struct commands *cmds; 648 char msg_buf[1][1024]; 649 650 snprintf(msg_buf[0], sizeof(msg_buf[0]), 651 "%s cannot be installed from a floppy; " 652 "it must be installed from a booted CD-ROM. " 653 "However, many older systems do not support booting " 654 "from a CD-ROM. For these systems, a boot disk can be " 655 "created. This boot disk contains the Smart Boot " 656 "Manager program, which can boot a CD-ROM even " 657 "on systems with BIOSes which do not support booting " 658 "from the CD-ROM.\n\n" 659 "Smart Boot Manager is not a part of %s; " 660 "the Smart Boot Manager project can be found here:\n\n" 661 "http://btmgr.sourceforge.net/\n\n" 662 "To create a CDBoot floppy, insert a blank floppy " 663 "in unit 0 (``drive A:'') before proceeding." 664 "", 665 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME); 666 667 switch (dfui_be_present_dialog(a->c, _("Create CDBoot Floppy"), 668 _("Create CDBoot Floppy|Return to Utilities Menu"), 669 "%s", msg_buf[0])) { 670 case 1: 671 cmds = commands_new(); 672 command_add(cmds, "%s%s -c %sboot/cdboot.flp.bz2 | " 673 "%s%s of=/dev/fd0 bs=32k", 674 a->os_root, cmd_name(a, "BUNZIP2"), 675 a->os_root, 676 a->os_root, cmd_name(a, "DD")); 677 if (commands_execute(a, cmds)) 678 inform(a->c, _("CDBoot floppy successfully created!")); 679 else 680 inform(a->c, _("CDBoot floppy was not successfully created.")); 681 break; 682 case 2: 683 return; 684 default: 685 abort_backend(); 686 } 687 } 688 689 /**** NON-fn_ FUNCTIONS ***/ 690 691 int 692 format_slice(struct i_fn_args *a) 693 { 694 struct commands *cmds; 695 struct command *cmd; 696 int result; 697 int cyl, hd, sec; 698 699 cmds = commands_new(); 700 701 /* 702 * The information in a->s NEEDS to be accurate here! 703 * Presumably we just did a survey_storage() recently. 704 * XXX should we do another one here anyway just to be paranoid? 705 */ 706 707 /* 708 * Make sure the survey did get disk info correctly or fail 709 */ 710 if ((storage_get_selected_disk(a->s) == NULL) || 711 (storage_get_selected_slice(a->s) == NULL)) 712 return 0; 713 714 /* 715 * Set the slice's sysid to 108. 716 */ 717 disk_get_geometry(storage_get_selected_disk(a->s), &cyl, &hd, &sec); 718 command_add(cmds, "%s%s 'g c%d h%d s%d' >%snew.fdisk", 719 a->os_root, cmd_name(a, "ECHO"), 720 cyl, hd, sec, 721 a->tmp); 722 command_add(cmds, "%s%s 'p %d %d %lu %lu' >>%snew.fdisk", 723 a->os_root, cmd_name(a, "ECHO"), 724 slice_get_number(storage_get_selected_slice(a->s)), 725 DOSPTYP_DFLYBSD, 726 slice_get_start(storage_get_selected_slice(a->s)), 727 slice_get_size(storage_get_selected_slice(a->s)), 728 a->tmp); 729 if (slice_get_flags(storage_get_selected_slice(a->s)) & 0x80) { 730 command_add(cmds, "%s%s 'a %d' >>%snew.fdisk", 731 a->os_root, cmd_name(a, "ECHO"), 732 slice_get_number(storage_get_selected_slice(a->s)), 733 a->tmp); 734 } 735 736 command_add(cmds, "%s%s %snew.fdisk", 737 a->os_root, cmd_name(a, "CAT"), a->tmp); 738 temp_file_add(a, "new.fdisk"); 739 740 /* 741 * Execute the fdisk script. 742 */ 743 cmd = command_add(cmds, "%s%s -v -f %snew.fdisk %s", 744 a->os_root, cmd_name(a, "FDISK"), a->tmp, 745 disk_get_device_name(storage_get_selected_disk(a->s))); 746 if (slice_get_size(storage_get_selected_slice(a->s)) == 0xFFFFFFFFU) 747 command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE); 748 749 /* 750 * If there is an old 'virgin' disklabel hanging around 751 * in the temp dir, get rid of it. This won't happen 752 * from a real CD, but might happen with '-o' installs. 753 */ 754 command_add(cmds, "%s%s -f %sinstall.disklabel.%s", 755 a->os_root, cmd_name(a, "RM"), 756 a->tmp, 757 slice_get_device_name(storage_get_selected_slice(a->s))); 758 759 result = commands_execute(a, cmds); 760 761 commands_free(cmds); 762 763 return(result); 764 } 765