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