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 * flow.c 36 * Workflow logic for installer. 37 * $Id: flow.c,v 1.67 2005/04/08 08:09:23 cpressey Exp $ 38 */ 39 40 #include <stdarg.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <unistd.h> 44 #include <string.h> 45 46 #ifdef ENABLE_NLS 47 #include <libintl.h> 48 #include <locale.h> 49 #include "libdfui/lang.h" 50 #define _(String) gettext (String) 51 extern int _nl_msg_cat_cntr; 52 #else 53 #define _(String) (String) 54 #endif 55 56 #include "libaura/mem.h" 57 #include "libaura/dict.h" 58 #include "libaura/fspred.h" 59 60 #include "libdfui/dfui.h" 61 #ifdef DEBUG 62 #include "libdfui/dump.h" 63 #endif 64 #include "libdfui/system.h" 65 66 #include "libinstaller/commands.h" 67 #include "libinstaller/confed.h" 68 #include "libinstaller/diskutil.h" 69 #include "libinstaller/functions.h" 70 #include "libinstaller/package.h" 71 #include "libinstaller/uiutil.h" 72 73 #include "flow.h" 74 #include "fn.h" 75 #include "pathnames.h" 76 77 /*** GLOBALS ***/ 78 79 void (*state)(struct i_fn_args *) = NULL; 80 int do_reboot; 81 int use_hammer; /* 0=UFS 1=HAMMER 2=HAMMER2 */ 82 int use_uefi; 83 int during_install; 84 85 /*** STATES ***/ 86 87 /* 88 * The installer works like a big state machine. Each major form is 89 * a state. When the user has filled out the form satisfactorily, 90 * and selects "OK", there is a transition to the next state, in a 91 * mostly-linear order towards the final, "successfully installed" 92 * state. The user may also "Cancel", which generally causes a 93 * transition to the previous state (but may also take them back to 94 * the very first state in some cases.) 95 * 96 * Installer States: 97 * - Select localization optional 98 * - Welcome to DragonFly required 99 * - Begin Installation required 100 * - Select Disk required 101 * - Format Disk optional dd, fdisk 102 * - Select Partition required dd, disklabel 103 * - Create Subpartitions required disklabel, newfs 104 * - Install DragonFly required swapon, mkdir, mount, cpdup 105 * - Install Bootstrap optional boot0cfg 106 * - Reboot optional reboot 107 */ 108 109 #ifdef ENABLE_NLS 110 void 111 state_lang_menu(struct i_fn_args *a) 112 { 113 struct dfui_form *f; 114 struct dfui_response *r; 115 int done = 0; 116 char *id; 117 int cancelled = 0; 118 119 while (!done) { 120 f = dfui_form_create( 121 "main_menu", 122 _("Select Language"), 123 _("Please select the language you wish you use."), 124 "", 125 126 "p", "role", "menu", 127 128 "a", "default", "English", 129 "English Standard Default", "", 130 "a", "ru", "Russian", 131 "Russian KOI8-R", "", 132 NULL 133 ); 134 135 if (!dfui_be_present(a->c, f, &r)) 136 abort_backend(); 137 138 id = aura_strdup(dfui_response_get_action_id(r)); 139 140 if (strcmp(id, "default") == 0) { 141 state = state_welcome; 142 return; 143 } else { 144 state = state_welcome; 145 done = 1; 146 } 147 148 dfui_form_free(f); 149 dfui_response_free(r); 150 } 151 152 /* set keymap, scrnmap, fonts */ 153 if (!set_lang_syscons(id)) 154 return; 155 156 /* set envars */ 157 if (!set_lang_envars(id)) 158 return; 159 160 dfui_be_set_global_setting(a->c, "lang", id, &cancelled); 161 162 /* XXX if (!cancelled) ... ? */ 163 164 /* let gettext know about changes */ 165 ++_nl_msg_cat_cntr; 166 } 167 #endif 168 169 /* 170 * state_welcome_livecd: the start state of the installer state machine, 171 * when run from the Live CD. Briefly describe DragonFly to the user, 172 * and present them with a set of reasonable options of how to proceed. 173 */ 174 void 175 state_welcome(struct i_fn_args *a) 176 { 177 struct dfui_form *f; 178 struct dfui_response *r; 179 char msg_buf[2][1024]; 180 181 snprintf(msg_buf[0], sizeof(msg_buf[0]), 182 _("Welcome to %s"), OPERATING_SYSTEM_NAME); 183 184 snprintf(msg_buf[1], sizeof(msg_buf[1]), 185 _("Welcome to the %s Live CD." 186 "\n\n" 187 "%s is an efficient and elegant BSD " 188 "Unix-derived operating system. For more information, see %s" 189 "\n\n" 190 "From this CD, you can boot into %s ``live'' " 191 "(without installing it) to evaluate it, to install it " 192 "manually, or to troubleshoot problems with an " 193 "existing installation, using either a command prompt " 194 "or menu-driven utilities." 195 "\n\n" 196 "Also, you can use this automated application to assist " 197 "you in installing %s on this computer and " 198 "configuring it once it is installed." 199 ""), 200 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_URL, 201 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME); 202 203 if ((a->flags & I_BOOTED_LIVECD) == 0) { 204 state = state_welcome_system; 205 return; 206 } 207 208 f = dfui_form_create( 209 "welcome", 210 msg_buf[0], 211 212 msg_buf[1], 213 214 "", 215 216 "p", "special", "dfinstaller_welcome", 217 218 NULL 219 ); 220 221 if (a->flags & I_UPGRADE_TOOGLE) { 222 snprintf(msg_buf[0], sizeof(msg_buf[0]), 223 _("Upgrade a FreeBSD 4.X system to %s"), 224 OPERATING_SYSTEM_NAME); 225 dfui_form_action_add(f, "upgrade", 226 dfui_info_new(_("Upgrade"), 227 msg_buf[0], "")); 228 } else { 229 snprintf(msg_buf[0], sizeof(msg_buf[0]), 230 _("Install %s"), OPERATING_SYSTEM_NAME); 231 snprintf(msg_buf[1], sizeof(msg_buf[1]), 232 _("Install %s on a HDD or HDD partition on this computer"), 233 OPERATING_SYSTEM_NAME); 234 dfui_form_action_add(f, "install", 235 dfui_info_new(msg_buf[0], 236 msg_buf[1], "")); 237 } 238 239 snprintf(msg_buf[0], sizeof(msg_buf[0]), 240 _("Configure a %s system once it has been installed on HDD"), 241 OPERATING_SYSTEM_NAME); 242 dfui_form_action_add(f, "configure", 243 dfui_info_new(_("Configure an Installed System"), 244 msg_buf[0], "")); 245 246 dfui_form_action_add(f, "utilities", 247 dfui_info_new(_("Live CD Utilities"), 248 _("Utilities to work with disks, diagnostics, and the LiveCD Environment"), "")); 249 250 dfui_form_action_add(f, "exit", 251 dfui_info_new(_("Exit to Live CD"), 252 _("Exit this program to a login prompt with access to the LiveCD"), "")); 253 254 dfui_form_action_add(f, "reboot", 255 dfui_info_new(_("Reboot this Computer"), 256 _("Reboot this computer (e.g. to boot into a newly installed system)"), "")); 257 258 dfui_form_action_add(f, "configure_netboot", 259 dfui_info_new(_("Setup NetBoot Install Services"), 260 _("Setup machine as remote installation server"), "")); 261 262 if (!dfui_be_present(a->c, f, &r)) 263 abort_backend(); 264 265 if (strcmp(dfui_response_get_action_id(r), "install") == 0) { 266 state = state_begin_install; 267 } else if (strcmp(dfui_response_get_action_id(r), "upgrade") == 0) { 268 state = state_begin_upgrade; 269 } else if (strcmp(dfui_response_get_action_id(r), "configure") == 0) { 270 storage_set_selected_disk(a->s, NULL); 271 storage_set_selected_slice(a->s, NULL); 272 state = state_configure_menu; 273 } else if (strcmp(dfui_response_get_action_id(r), "utilities") == 0) { 274 state = state_utilities_menu; 275 } else if (strcmp(dfui_response_get_action_id(r), "exit") == 0) { 276 state = NULL; 277 } else if (strcmp(dfui_response_get_action_id(r), "configure_netboot") == 0) { 278 state = state_setup_remote_installation_server; 279 } else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0) { 280 state = state_reboot; 281 } 282 283 dfui_form_free(f); 284 dfui_response_free(r); 285 } 286 287 /* 288 * state_welcome_system: the start state of the installer state machine, 289 * when run from the installed system. Allow the user to configure the 290 * system. 291 */ 292 void 293 state_welcome_system(struct i_fn_args *a) 294 { 295 struct dfui_form *f; 296 struct dfui_response *r; 297 char msg_buf[2][1024]; 298 299 snprintf(msg_buf[0], sizeof(msg_buf[0]), 300 _("Configure this %s System"), OPERATING_SYSTEM_NAME); 301 302 snprintf(msg_buf[1], sizeof(msg_buf[1]), 303 _("Thank you for choosing %s." 304 "\n\n" 305 "For up-to-date news and information on %s, " 306 "make sure to check out" 307 "\n\n" 308 "%s" 309 "\n\n" 310 "You can use this automated application to assist " 311 "you in setting up this %s system." 312 ""), 313 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME, 314 OPERATING_SYSTEM_URL, OPERATING_SYSTEM_NAME); 315 316 317 f = dfui_form_create( 318 "welcome", 319 msg_buf[0], 320 321 msg_buf[1], 322 323 "", 324 325 "p", "special", "dfinstaller_welcome", 326 327 NULL 328 ); 329 330 snprintf(msg_buf[0], sizeof(msg_buf[0]), 331 _("Configure this %s system"), OPERATING_SYSTEM_NAME); 332 333 dfui_form_action_add(f, "environment", 334 dfui_info_new(_("Configure this System"), 335 msg_buf[0], "")); 336 337 dfui_form_action_add(f, "utilities", 338 dfui_info_new(_("Utilities"), 339 _("Utilities to work with and diagnose disks and other subsystems"), "")); 340 341 dfui_form_action_add(f, "exit", 342 dfui_info_new(_("Exit Installer"), 343 _("Exit this program and return to the system"), "")); 344 345 if (!dfui_be_present(a->c, f, &r)) 346 abort_backend(); 347 348 if (strcmp(dfui_response_get_action_id(r), "environment") == 0) { 349 state = state_environment_menu; 350 } else if (strcmp(dfui_response_get_action_id(r), "utilities") == 0) { 351 state = state_utilities_menu; 352 } else if (strcmp(dfui_response_get_action_id(r), "exit") == 0) { 353 state = NULL; 354 } else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0) { 355 state = state_reboot; 356 } 357 358 dfui_form_free(f); 359 dfui_response_free(r); 360 } 361 362 void 363 state_configure_menu(struct i_fn_args *a) 364 { 365 struct dfui_form *f = NULL; 366 struct dfui_response *r = NULL; 367 struct commands *cmds; 368 int done = 0; 369 char msg_buf[2][1024]; 370 371 if (storage_get_selected_disk(a->s) == NULL || storage_get_selected_slice(a->s) == NULL) { 372 if (!survey_storage(a)) { 373 inform(a->c, _("Errors occurred while probing " 374 "the system for its storage capabilities.")); 375 } 376 377 a->short_desc = _("Select the disk containing the installation."); 378 a->cancel_desc = _("Return to Welcome Menu"); 379 fn_select_disk(a); 380 if (!a->result || storage_get_selected_disk(a->s) == NULL) { 381 state = state_welcome; 382 return; 383 } 384 385 a->short_desc = _("Select the primary partition containing the installation."); 386 a->cancel_desc = _("Return to Welcome Menu"); 387 fn_select_slice(a); 388 389 if (!a->result || storage_get_selected_slice(a->s) == NULL) { 390 state = state_welcome; 391 return; 392 } 393 } 394 395 a->cfg_root = "mnt"; 396 397 if (during_install == 0) { 398 switch (dfui_be_present_dialog(a->c, _("Select file system"), 399 _("HAMMER2|HAMMER1|UFS|Return to Welcome Menu"), 400 _("Please select the file system installed on the disk.\n\n"))) 401 { 402 case 1: 403 /* HAMMER2 (first menu item is the default) */ 404 use_hammer = 2; 405 break; 406 case 2: 407 /* HAMMER1 */ 408 use_hammer = 1; 409 break; 410 case 3: 411 /* UFS */ 412 use_hammer = 0; 413 break; 414 case 4: 415 state = state_welcome; 416 return; 417 /* NOTREACHED */ 418 break; 419 default: 420 abort_backend(); 421 break; 422 } 423 } 424 425 if (!mount_target_system(a)) { 426 inform(a->c, _("Target system could not be mounted.")); 427 state = state_welcome; 428 return; 429 } 430 431 snprintf(msg_buf[0], sizeof(msg_buf[0]), 432 _("The options on this menu allow you to configure a " 433 "%s system after it has already been " 434 "installed."), OPERATING_SYSTEM_NAME); 435 436 while (!done) { 437 f = dfui_form_create( 438 "configure_menu", 439 _("Configure an Installed System"), 440 msg_buf[0], 441 "", 442 "p", "role", "menu", 443 444 "a", "set_timezone", 445 _("Select timezone"), 446 _("Set the Time Zone of your physical location"), "", 447 "a", "set_datetime", 448 _("Set date and time"), 449 _("Set the Time and Date of your machine"), "", 450 451 "a", "set_kbdmap", 452 _("Set keyboard map"), 453 _("Set what kind of keyboard layout you have"), "", 454 "a", "root_passwd", _("Set root password"), 455 _("Set the password that the root (superuser) account will use"), "", 456 "a", "add_user", _("Add a user"), 457 _("Add a user to the system"), "", 458 "a", "assign_ip", _("Configure network interfaces"), 459 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "", 460 "a", "assign_hostname_domain", 461 _("Configure hostname and domain"), 462 _("Configure the hostname and domain for this system"), "", 463 /* 464 "a", "select_services", "Select Services", 465 "Enable/Disable system services (servers, daemons, etc.)", "", 466 */ 467 "a", "set_vidfont", 468 _("Set console font"), 469 _("Set how the characters on your video console look"), "", 470 "a", "set_scrnmap", 471 _("Set screen map"), 472 _("Set how characters are translated before console display"), "", 473 /* 474 "a", "install_pkgs", _("Install extra software packages"), 475 _("Install third-party software packages from the LiveCD"), "", 476 */ 477 "a", "remove_pkgs", _("Remove software packages"), 478 _("Remove third-party software packages from the installed system"), "", 479 480 "a", "cancel", _("Return to Welcome Menu"), "", "", 481 "p", "accelerator", "ESC", 482 483 NULL 484 ); 485 486 if (!dfui_be_present(a->c, f, &r)) 487 abort_backend(); 488 489 /* XXX set up a */ 490 a->cfg_root = "mnt/"; 491 if (strcmp(dfui_response_get_action_id(r), "root_passwd") == 0) { 492 fn_root_passwd(a); 493 } else if (strcmp(dfui_response_get_action_id(r), "add_user") == 0) { 494 fn_add_user(a); 495 } else if (strcmp(dfui_response_get_action_id(r), "install_pkgs") == 0) { 496 fn_install_packages(a); 497 } else if (strcmp(dfui_response_get_action_id(r), "remove_pkgs") == 0) { 498 fn_remove_packages(a); 499 } else if (strcmp(dfui_response_get_action_id(r), "assign_ip") == 0) { 500 fn_assign_ip(a); 501 } else if (strcmp(dfui_response_get_action_id(r), "assign_hostname_domain") == 0) { 502 fn_assign_hostname_domain(a); 503 } else if (strcmp(dfui_response_get_action_id(r), "select_services") == 0) { 504 fn_select_services(a); 505 } else if (strcmp(dfui_response_get_action_id(r), "set_kbdmap") == 0) { 506 fn_set_kbdmap(a); 507 } else if (strcmp(dfui_response_get_action_id(r), "set_vidfont") == 0) { 508 fn_set_vidfont(a); 509 } else if (strcmp(dfui_response_get_action_id(r), "set_scrnmap") == 0) { 510 fn_set_scrnmap(a); 511 } else if (strcmp(dfui_response_get_action_id(r), "set_timezone") == 0) { 512 fn_set_timezone(a); 513 } else if (strcmp(dfui_response_get_action_id(r), "set_datetime") == 0) { 514 fn_assign_datetime(a); 515 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 516 state = state_welcome; 517 done = 1; 518 } 519 520 dfui_form_free(f); 521 dfui_response_free(r); 522 } 523 524 /* 525 * Before unmounting the system, write out any changes to rc.conf. 526 */ 527 config_vars_write(rc_conf, CONFIG_TYPE_SH, 528 "%s%setc/rc.conf", a->os_root, a->cfg_root); 529 530 /* 531 * Clear out configuration variable table in memory. 532 */ 533 config_vars_free(rc_conf); 534 rc_conf = config_vars_new(); 535 536 /* 537 * Finally, unmount the system we mounted on /mnt and remove mappings. 538 */ 539 cmds = commands_new(); 540 unmount_all_under(a, cmds, "%smnt", a->os_root); 541 commands_execute(a, cmds); 542 commands_free(cmds); 543 544 if (remove_all_mappings(a) == NULL) 545 inform(a->c, _("Warning: mappings could not be removed.")); 546 } 547 548 void 549 state_utilities_menu(struct i_fn_args *a) 550 { 551 struct dfui_form *f; 552 struct dfui_response *r; 553 554 if (!survey_storage(a)) { 555 inform(a->c, _("Errors occurred while probing " 556 "the system for its storage capabilities.")); 557 } 558 559 f = dfui_form_create( 560 "utilities_menu", 561 _("Live CD Utilities Menu"), 562 _("On these submenus you will find utilities to help " 563 "you set up your Live CD environment, diagnose " 564 "and analyse this system, and work with " 565 "the devices attached to this computer."), 566 "", 567 "p", "role", "menu", 568 "a", "environment", _("LiveCD Environment"), 569 _("Configure the LiveCD Environment"), "", 570 "a", "diagnostics", _("System Diagnostics"), 571 _("Probe and display detailed information about this system"), "", 572 "a", "diskutil", _("Disk Utilities"), 573 _("Format and check hard drives and floppy disks"), "", 574 "a", "livecd", _("Exit to Live CD"), 575 _("Exit this program to a login prompt with access to the LiveCD"), "", 576 "a", "reboot", 577 _("Reboot this Computer"), "", "", 578 "a", "cancel", 579 _("Return to Welcome Menu"), "", "", 580 "p", "accelerator", "ESC", 581 NULL 582 ); 583 584 if (!dfui_be_present(a->c, f, &r)) 585 abort_backend(); 586 587 if (strcmp(dfui_response_get_action_id(r), "environment") == 0) 588 state = state_environment_menu; 589 else if (strcmp(dfui_response_get_action_id(r), "diagnostics") == 0) 590 state = state_diagnostics_menu; 591 else if (strcmp(dfui_response_get_action_id(r), "diskutil") == 0) 592 state = state_diskutil_menu; 593 else if (strcmp(dfui_response_get_action_id(r), "livecd") == 0) 594 state = NULL; 595 else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0) 596 state = state_reboot; 597 else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) 598 state = state_welcome; 599 600 dfui_form_free(f); 601 dfui_response_free(r); 602 } 603 604 void 605 state_environment_menu(struct i_fn_args *a) 606 { 607 struct dfui_form *f; 608 struct dfui_response *r; 609 int done = 0; 610 char msg_buf[2][1024]; 611 612 snprintf(msg_buf[0], sizeof(msg_buf[0]), 613 _("On this menu you will find utilities to help you " 614 "set up your Live CD environment.\n\nNote " 615 "that these functions affect only the LiveCD " 616 "environment you are currently using, and they will " 617 "not affect any system that may be installed on " 618 "this computer UNLESS you subsequently choose to " 619 "install %s from this environment, in which " 620 "case they will be copied to the newly installed " 621 "system."), OPERATING_SYSTEM_NAME); 622 623 while (!done) { 624 f = dfui_form_create( 625 "environment_menu", 626 _("Live CD Environment Menu"), 627 msg_buf[0], 628 "", 629 "p", "role", "menu", 630 631 "a", "set_timezone", 632 _("Select timezone"), 633 _("Set the Time Zone of your physical location"), "", 634 "a", "set_datetime", 635 _("Set date and time"), 636 _("Set the Time and Date of your machine"), "", 637 638 "a", "set_kbdmap", 639 _("Set keyboard map"), 640 _("Set what kind of keyboard layout you have"), "", 641 "a", "set_vidfont", 642 _("Set console font"), 643 _("Set how the characters on your video console look"), "", 644 "a", "set_scrnmap", 645 _("Set screen map"), 646 _("Set how characters are translated before console display"), "", 647 648 "a", "assign_hostname_domain", 649 _("Configure hostname and domain"), 650 _("Configure the hostname and domain for this system"), "", 651 "a", "assign_ip", 652 _("Configure network interfaces"), 653 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "", 654 655 "a", "cancel", 656 _("Return to Utilities Menu"), "", "", 657 "p", "accelerator", "ESC", 658 659 NULL 660 ); 661 662 if (!dfui_be_present(a->c, f, &r)) 663 abort_backend(); 664 665 /* Set up a */ 666 a->cfg_root = ""; 667 if (strcmp(dfui_response_get_action_id(r), "set_kbdmap") == 0) { 668 fn_set_kbdmap(a); 669 } else if (strcmp(dfui_response_get_action_id(r), "set_vidfont") == 0) { 670 fn_set_vidfont(a); 671 } else if (strcmp(dfui_response_get_action_id(r), "set_scrnmap") == 0) { 672 fn_set_scrnmap(a); 673 } else if (strcmp(dfui_response_get_action_id(r), "assign_hostname_domain") == 0) { 674 fn_assign_hostname_domain(a); 675 } else if (strcmp(dfui_response_get_action_id(r), "assign_ip") == 0) { 676 fn_assign_ip(a); 677 } else if (strcmp(dfui_response_get_action_id(r), "set_timezone") == 0) { 678 fn_set_timezone(a); 679 } else if (strcmp(dfui_response_get_action_id(r), "set_datetime") == 0) { 680 fn_assign_datetime(a); 681 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 682 state = state_utilities_menu; 683 done = 1; 684 } 685 686 dfui_form_free(f); 687 dfui_response_free(r); 688 } 689 } 690 691 void 692 state_diagnostics_menu(struct i_fn_args *a) 693 { 694 struct dfui_form *f; 695 struct dfui_action *k; 696 struct dfui_response *r; 697 int done = 0; 698 699 while (!done) { 700 f = dfui_form_create( 701 "utilities_menu", 702 _("Live CD Diagnostics Menu"), 703 _("These functions can help you diagnose this system."), 704 "", 705 "p", "role", "menu", 706 707 "a", "show_dmesg", 708 _("Display system startup messages"), 709 _("Display system startup messages (dmesg)"), "", 710 "a", "pciconf", 711 _("Display PCI devices"), 712 _("Display PCI devices (pciconf)"), "", 713 "a", "natacontrol", 714 _("Display ATA devices"), 715 _("Display ATA devices (natacontrol)"), "", 716 NULL 717 ); 718 719 k = dfui_form_action_add(f, "cancel", 720 dfui_info_new(_("Return to Utilities Menu"), "", "")); 721 dfui_action_property_set(k, "accelerator", "ESC"); 722 723 if (!dfui_be_present(a->c, f, &r)) 724 abort_backend(); 725 726 /* XXX set up a */ 727 if (strcmp(dfui_response_get_action_id(r), "show_dmesg") == 0) { 728 fn_show_dmesg(a); 729 } else if (strcmp(dfui_response_get_action_id(r), "pciconf") == 0) { 730 fn_show_pciconf(a); 731 } else if (strcmp(dfui_response_get_action_id(r), "natacontrol") == 0) { 732 fn_show_natacontrol(a); 733 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 734 state = state_utilities_menu; 735 done = 1; 736 } 737 738 dfui_form_free(f); 739 dfui_response_free(r); 740 } 741 } 742 743 void 744 state_diskutil_menu(struct i_fn_args *a) 745 { 746 struct dfui_form *f; 747 struct dfui_action *k; 748 struct dfui_response *r; 749 int done = 0; 750 751 while (!done) { 752 f = dfui_form_create( 753 "utilities_menu", 754 _("Disk Utilities Menu"), 755 _("These functions let you manipulate the storage devices " 756 "attached to this computer."), 757 "", 758 759 "p", "role", "menu", 760 761 "a", "format_hdd", 762 _("Format a hard disk drive"), "", "", 763 "a", "wipe_start_of_disk", 764 _("Wipe out the start of a disk"), "", "", 765 "a", "wipe_start_of_slice", 766 _("Wipe out the start of a primary partition"), "", "", 767 "a", "install_bootblocks", 768 _("Install bootblocks on disks"), "", "", 769 "a", "format_msdos_floppy", 770 _("Format an MSDOS floppy"), "", "", 771 NULL 772 ); 773 774 if (is_file("%sboot/cdboot.flp.bz2", a->os_root)) { 775 dfui_form_action_add(f, "create_cdboot_floppy", 776 dfui_info_new(_("Create a CDBoot floppy"), 777 "", 778 "")); 779 } 780 781 k = dfui_form_action_add(f, "cancel", 782 dfui_info_new(_("Return to Utilities Menu"), "", "")); 783 dfui_action_property_set(k, "accelerator", "ESC"); 784 785 if (!dfui_be_present(a->c, f, &r)) 786 abort_backend(); 787 788 /* XXX set up a */ 789 if (strcmp(dfui_response_get_action_id(r), "format_hdd") == 0) { 790 storage_set_selected_disk(a->s, NULL); 791 storage_set_selected_slice(a->s, NULL); 792 if (use_uefi) 793 fn_format_disk_uefi(a); 794 else 795 fn_format_disk_mbr(a); 796 } else if (strcmp(dfui_response_get_action_id(r), "wipe_start_of_disk") == 0) { 797 fn_wipe_start_of_disk(a); 798 } else if (strcmp(dfui_response_get_action_id(r), "wipe_start_of_slice") == 0) { 799 fn_wipe_start_of_slice(a); 800 } else if (strcmp(dfui_response_get_action_id(r), "install_bootblocks") == 0) { 801 a->short_desc = _("Select the disks on which " 802 "you wish to install bootblocks."); 803 a->cancel_desc = _("Return to Utilities Menu"); 804 fn_install_bootblocks(a, NULL); 805 } else if (strcmp(dfui_response_get_action_id(r), "format_msdos_floppy") == 0) { 806 fn_format_msdos_floppy(a); 807 } else if (strcmp(dfui_response_get_action_id(r), "create_cdboot_floppy") == 0) { 808 fn_create_cdboot_floppy(a); 809 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 810 state = state_utilities_menu; 811 done = 1; 812 } 813 814 dfui_form_free(f); 815 dfui_response_free(r); 816 } 817 } 818 819 /** INSTALLER STATES **/ 820 821 /* 822 * state_begin_upgrade: Ask the user where the freebsd 823 * 4.X install is and make sure its safe to proceed. 824 * 825 */ 826 void 827 state_begin_upgrade(struct i_fn_args *a) 828 { 829 //struct dfui_form *f = NULL; 830 //struct dfui_response *r = NULL; 831 //int done = 0; 832 833 if (storage_get_selected_disk(a->s) == NULL || storage_get_selected_slice(a->s) == NULL) { 834 if (!survey_storage(a)) { 835 inform(a->c, _("Errors occurred while probing " 836 "the system for its storage capabilities.")); 837 } 838 839 a->short_desc = _("Select the disk containing the installation that you would like to upgrade."); 840 a->cancel_desc = _("Return to Welcome Menu"); 841 fn_select_disk(a); 842 if (!a->result || storage_get_selected_disk(a->s) == NULL) { 843 state = state_welcome; 844 return; 845 } 846 847 a->short_desc = _("Select the primary partition containing the installation you would like to upgrade."); 848 a->cancel_desc = _("Return to Welcome Menu"); 849 fn_select_slice(a); 850 851 if (!a->result || storage_get_selected_slice(a->s) == NULL) { 852 state = state_welcome; 853 return; 854 } 855 } 856 857 a->cfg_root = "mnt"; 858 if (!mount_target_system(a)) { 859 inform(a->c, _("Target system could not be mounted.")); 860 state = state_welcome; 861 return; 862 } 863 } 864 865 /* 866 * state_begin_install: Briefly describe the install process 867 * to the user, and let them proceed (or not.) 868 */ 869 void 870 state_begin_install(struct i_fn_args *a) 871 { 872 struct dfui_form *f; 873 struct dfui_response *r; 874 char msg_buf[3][1024]; 875 876 snprintf(msg_buf[0], sizeof(msg_buf[0]), 877 _("This application will install %s" 878 " on one of the hard disk drives attached to this computer. " 879 "It has been designed to make it easy to install " 880 "%s in the typical case. " 881 "If you have special requirements that are not addressed " 882 "by this installer, or if you have problems using it, you " 883 "are welcome to install %s manually. " 884 "To do so select Exit to Live CD, login as root, and follow " 885 "the instructions given in the file /README ." 886 "\n\n" 887 "NOTE! As with any installation process, YOU ARE " 888 "STRONGLY ENCOURAGED TO BACK UP ANY IMPORTANT DATA ON THIS " 889 "COMPUTER BEFORE PROCEEDING!" 890 ""), 891 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME, 892 OPERATING_SYSTEM_NAME); 893 894 snprintf(msg_buf[1], sizeof(msg_buf[1]), 895 _("Some situations in which you might not wish to use this " 896 "installer are:\n\n" 897 "- you want to install %s onto a " 898 "logical/extended partition;\n" 899 "- you want to install %s " 900 "onto a ``dangerously dedicated'' disk; or\n" 901 "- you want full and utter control over the install process." 902 ""), 903 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME); 904 905 snprintf(msg_buf[2], sizeof(msg_buf[2]), 906 _("Install %s"), OPERATING_SYSTEM_NAME); 907 908 f = dfui_form_create( 909 "begin_install", 910 _("Begin Installation"), 911 msg_buf[0], 912 913 msg_buf[1], 914 "p", "special", "dfinstaller_begin_install", 915 "p", "minimum_width", "76", 916 917 "a", "proceed", msg_buf[2], 918 "", "", 919 "a", "cancel", _("Return to Welcome Menu"), 920 "", "", 921 "p", "accelerator", "ESC", 922 "a", "livecd", _("Exit to Live CD"), 923 "", "", 924 NULL 925 ); 926 927 if (!dfui_be_present(a->c, f, &r)) 928 abort_backend(); 929 930 if (strcmp(dfui_response_get_action_id(r), "proceed") == 0) { 931 if (!survey_storage(a)) { 932 inform(a->c, _("Errors occurred while probing " 933 "the system for its storage capabilities.")); 934 } 935 state = state_ask_uefi; 936 } else if (strcmp(dfui_response_get_action_id(r), "livecd") == 0) { 937 state = NULL; 938 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 939 state = state_welcome; 940 } 941 942 dfui_form_free(f); 943 dfui_response_free(r); 944 } 945 946 /* 947 * state_ask_uefi: ask the user if they want a UEFI installation 948 */ 949 void 950 state_ask_uefi(struct i_fn_args *a) 951 { 952 use_uefi = 0; 953 954 switch (dfui_be_present_dialog(a->c, _("UEFI or legacy BIOS?"), 955 _("UEFI|Legacy BIOS|Return to Begin Installation"), 956 _("Do you wish to set up %s for a UEFI or legacy BIOS system?"), 957 OPERATING_SYSTEM_NAME)) 958 { 959 case 1: 960 /* UEFI */ 961 use_uefi = 1; 962 break; 963 case 2: 964 /* MBR */ 965 break; 966 case 3: 967 state = state_begin_install; 968 return; 969 /* NOTREACHED */ 970 break; 971 default: 972 abort_backend(); 973 break; 974 } 975 state = state_select_disk; 976 } 977 978 /* 979 * state_select_disk: ask the user on which physical disk they wish 980 * to install DragonFly. 981 */ 982 void 983 state_select_disk(struct i_fn_args *a) 984 { 985 struct disk *d; 986 int num_disks = 0; 987 char msg_buf[1][1024]; 988 989 for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) 990 num_disks++; 991 992 if (num_disks == 0) { 993 inform(a->c, _("The installer could not find any disks suitable " 994 "for installation (IDE or SCSI) attached to this " 995 "computer. If you wish to install %s" 996 " on an unorthodox storage device, you will have to " 997 "exit to a LiveCD command prompt and install it " 998 "manually, using the file /README as a guide."), 999 OPERATING_SYSTEM_NAME); 1000 state = state_welcome; 1001 return; 1002 } 1003 1004 snprintf(msg_buf[0], sizeof(msg_buf[0]), 1005 _("Select a disk on which to install %s"), 1006 OPERATING_SYSTEM_NAME); 1007 a->short_desc = msg_buf[0]; 1008 a->cancel_desc = _("Return to Begin Installation"); 1009 fn_select_disk(a); 1010 if (!a->result || storage_get_selected_disk(a->s) == NULL) { 1011 state = state_begin_install; 1012 } else { 1013 #if 0 1014 if (disk_get_capacity(storage_get_selected_disk(a->s)) < DISK_MIN) { 1015 inform(a->c, _("WARNING: you should have a disk " 1016 "at least %dM in size, or " 1017 "you may encounter problems trying to " 1018 "install %s."), DISK_MIN, OPERATING_SYSTEM_NAME); 1019 } 1020 #endif 1021 state = state_format_disk; 1022 } 1023 } 1024 1025 void 1026 state_ask_fs(struct i_fn_args *a) 1027 { 1028 use_hammer = 0; 1029 1030 switch (dfui_be_present_dialog(a->c, _("Select file system"), 1031 _("Use HAMMER2|Use HAMMER1|Use UFS|Return to Select Disk"), 1032 _("Please select the file system you want to use with %s.\n\n" 1033 "HAMMER2 is the recommended %s file system. " 1034 "HAMMER1 is the previous %s file system. " 1035 "UFS is the traditional BSD file system."), 1036 OPERATING_SYSTEM_NAME, 1037 OPERATING_SYSTEM_NAME, 1038 OPERATING_SYSTEM_NAME)) 1039 { 1040 case 1: 1041 /* HAMMER2 (first menu item is the default) */ 1042 use_hammer = 2; 1043 break; 1044 case 2: 1045 /* HAMMER1 */ 1046 use_hammer = 1; 1047 break; 1048 case 3: 1049 /* UFS */ 1050 break; 1051 case 4: 1052 state = state_select_disk; 1053 return; 1054 /* NOTREACHED */ 1055 break; 1056 default: 1057 abort_backend(); 1058 break; 1059 } 1060 state = state_create_subpartitions; 1061 } 1062 1063 /* 1064 * state_format_disk: ask the user if they wish to format the disk they 1065 * selected. 1066 */ 1067 void 1068 state_format_disk(struct i_fn_args *a) 1069 { 1070 1071 if (use_uefi) { 1072 fn_format_disk_uefi(a); 1073 if (a->result) 1074 state = state_ask_fs; 1075 else 1076 state = state_select_disk; 1077 return; 1078 } 1079 1080 /* XXX Using part of the disk is only supported for MBR installs */ 1081 switch (dfui_be_present_dialog(a->c, _("How Much Disk?"), 1082 _("Use Entire Disk|Use Part of Disk|Return to Select Disk"), 1083 _("Select how much of this disk you want to use for %s.\n\n%s"), 1084 OPERATING_SYSTEM_NAME, 1085 disk_get_desc(storage_get_selected_disk(a->s)))) { 1086 case 1: 1087 /* Entire Disk */ 1088 if (measure_activated_swap_from_disk(a, storage_get_selected_disk(a->s)) > 0) { 1089 if (swapoff_all(a) == NULL) { 1090 inform(a->c, _("Warning: swap could not be turned off.")); 1091 state = state_select_disk; 1092 return; 1093 } 1094 } 1095 1096 fn_format_disk_mbr(a); 1097 if (a->result) 1098 state = state_ask_fs; 1099 else 1100 state = state_format_disk; 1101 break; 1102 case 2: 1103 /* Part of Disk */ 1104 state = state_select_slice; 1105 break; 1106 case 3: 1107 /* Return */ 1108 state = state_select_disk; 1109 break; 1110 default: 1111 abort_backend(); 1112 break; 1113 } 1114 } 1115 1116 /* 1117 * state_select_slice: ask the user which slice they wish to install 1118 * DragonFly on. In order to avoid confusing them, refer to it as 1119 * a primary partition, but tell them what BSD has traditionally called 1120 * it, too. 1121 */ 1122 void 1123 state_select_slice(struct i_fn_args *a) 1124 { 1125 char msg_buf[1][1024]; 1126 1127 snprintf(msg_buf[0], sizeof(msg_buf[0]), 1128 _("Select the existing primary partition (also " 1129 "known as a `slice' in the BSD tradition) on " 1130 "which to install %s.\n\n" 1131 "Note that if you do not have any existing " 1132 "primary partitions on this disk, you must " 1133 "first create some. This installer does not " 1134 "currently have the ability to do this, so " 1135 "you will have to exit and run fdisk (in " 1136 "DOS or *BSD) or parted (in Linux) to do so."), 1137 OPERATING_SYSTEM_NAME); 1138 1139 a->short_desc = msg_buf[0]; 1140 a->cancel_desc = _("Return to Select Disk"); 1141 fn_select_slice(a); 1142 if (!a->result || storage_get_selected_slice(a->s) == NULL) { 1143 state = state_select_disk; 1144 } else { 1145 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s), 1146 storage_get_selected_slice(a->s)) > 0) { 1147 if (swapoff_all(a) == NULL) { 1148 inform(a->c, _("Warning: swap could not be turned off.")); 1149 state = state_select_slice; 1150 return; 1151 } 1152 } 1153 1154 if (slice_get_capacity(storage_get_selected_slice(a->s)) < DISK_MIN) { 1155 inform(a->c, _("WARNING: you should have a primary " 1156 "partition at least %dM in size, or " 1157 "you may encounter problems trying to " 1158 "install %s."), DISK_MIN, OPERATING_SYSTEM_NAME); 1159 } 1160 1161 if (confirm_dangerous_action(a->c, 1162 _("WARNING! ALL data in primary partition #%d,\n\n%s\n\non the " 1163 "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you " 1164 "ABSOLUTELY SURE you wish to take this action? This is " 1165 "your LAST CHANCE to cancel!"), 1166 slice_get_number(storage_get_selected_slice(a->s)), 1167 slice_get_desc(storage_get_selected_slice(a->s)), 1168 disk_get_desc(storage_get_selected_disk(a->s)))) { 1169 if (!format_slice(a)) { 1170 inform(a->c, _("Primary partition #%d was " 1171 "not correctly formatted, and may " 1172 "now be in an inconsistent state. " 1173 "We recommend re-formatting it " 1174 "before proceeding."), 1175 slice_get_number(storage_get_selected_slice(a->s))); 1176 } else { 1177 inform(a->c, _("Primary partition #%d was formatted."), 1178 slice_get_number(storage_get_selected_slice(a->s))); 1179 state = state_ask_fs; 1180 } 1181 } else { 1182 inform(a->c, _("Action cancelled - no primary partitions were formatted.")); 1183 state = state_select_slice; 1184 } 1185 } 1186 } 1187 1188 /* 1189 * state_create_subpartitions: let the user specify what subpartitions they 1190 * want on the disk, how large each should be, and where it should be mounted. 1191 */ 1192 void 1193 state_create_subpartitions(struct i_fn_args *a) 1194 { 1195 struct commands *cmds; 1196 1197 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s), 1198 storage_get_selected_slice(a->s)) > 0) { 1199 if (swapoff_all(a) == NULL) { 1200 inform(a->c, _("Warning: swap could not be turned off.")); 1201 state = disk_get_formatted(storage_get_selected_disk(a->s)) ? 1202 state_select_disk : state_select_slice; 1203 return; 1204 } 1205 } 1206 1207 cmds = commands_new(); 1208 1209 /* 1210 * Auto-disklabel the slice. 1211 * NB: one cannot use "/dev/adXsY" here - 1212 * it must be in the form "adXsY". 1213 */ 1214 command_add(cmds, "%s%s -W %s", 1215 a->os_root, cmd_name(a, "DISKLABEL64"), 1216 slice_get_device_name(storage_get_selected_slice(a->s))); 1217 command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16", 1218 a->os_root, cmd_name(a, "DD"), 1219 slice_get_device_name(storage_get_selected_slice(a->s))); 1220 command_add(cmds, "%s%s -B -r -w %s", 1221 a->os_root, cmd_name(a, "DISKLABEL64"), 1222 slice_get_device_name(storage_get_selected_slice(a->s))); 1223 commands_execute(a, cmds); 1224 commands_free(cmds); 1225 1226 /* 1227 * Create subpartitions and filesystems 1228 */ 1229 switch(use_hammer) { 1230 case 1: 1231 fn_create_subpartitions_hammer(FS_HAMMER, a); 1232 break; 1233 case 2: 1234 fn_create_subpartitions_hammer(FS_HAMMER2, a); 1235 break; 1236 default: 1237 fn_create_subpartitions_ufs(a); 1238 break; 1239 } 1240 1241 if (a->result) { 1242 state = state_install_os; 1243 } else { 1244 state = disk_get_formatted(storage_get_selected_disk(a->s)) ? 1245 state_select_disk : state_select_slice; 1246 } 1247 } 1248 1249 /* 1250 * state_install_os: actually put DragonFly on the disk. 1251 */ 1252 void 1253 state_install_os(struct i_fn_args *a) 1254 { 1255 struct dfui_form *f; 1256 struct dfui_response *r; 1257 char msg_buf[1][1024]; 1258 1259 snprintf(msg_buf[0], sizeof(msg_buf[0]), 1260 _("Everything is now ready to install the actual files which " 1261 "comprise the %s operating system " 1262 "on the selected partition of the selected disk.\n\n" 1263 "Note that this process will take quite a while to finish. " 1264 "You may wish to take a break now and come back to the " 1265 "computer in a short while."), 1266 OPERATING_SYSTEM_NAME); 1267 1268 f = dfui_form_create( 1269 "install_os", 1270 _("Install OS"), 1271 msg_buf[0], 1272 1273 "", 1274 1275 "p", "role", "confirm", 1276 "p", "special", "dfinstaller_install_os", 1277 1278 "a", "ok", _("Begin Installing Files"), "", "", 1279 "a", "cancel", _("Return to Create Subpartitions"), "", "", 1280 "p", "accelerator", "ESC", 1281 1282 NULL 1283 ); 1284 1285 if (!dfui_be_present(a->c, f, &r)) 1286 abort_backend(); 1287 1288 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 1289 state = state_create_subpartitions; 1290 } else { 1291 fn_install_os(a); 1292 if (a->result) { 1293 if (use_uefi) 1294 state = state_finish_install; 1295 else 1296 state = state_install_bootstrap; 1297 } 1298 } 1299 1300 dfui_form_free(f); 1301 dfui_response_free(r); 1302 } 1303 1304 /* 1305 * state_install_bootstrap: put boot0 bootblocks on selected disks. 1306 */ 1307 void 1308 state_install_bootstrap(struct i_fn_args *a) 1309 { 1310 char msg_buf[1][1024]; 1311 1312 snprintf(msg_buf[0], sizeof(msg_buf[0]), 1313 _("You may now wish to install bootblocks on one or more disks. " 1314 "If you already have a boot manager installed, you can skip " 1315 "this step (but you may have to configure your boot manager " 1316 "separately.) If you installed %s on a disk other " 1317 "than your first disk, you will need to put the bootblock " 1318 "on at least your first disk and the %s disk."), 1319 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME); 1320 1321 a->short_desc = msg_buf[0]; 1322 a->cancel_desc = _("Skip this Step"); 1323 fn_install_bootblocks(a, 1324 disk_get_device_name(storage_get_selected_disk(a->s))); 1325 state = state_finish_install; 1326 } 1327 1328 /* 1329 * Finish up the install. 1330 */ 1331 void 1332 state_finish_install(struct i_fn_args *a) 1333 { 1334 char msg_buf[1][1024]; 1335 during_install = 1; 1336 1337 snprintf(msg_buf[0], sizeof(msg_buf[0]), 1338 "%s is Installed!", 1339 OPERATING_SYSTEM_NAME); 1340 1341 switch (dfui_be_present_dialog(a->c, msg_buf[0], 1342 _("Configure this System|Reboot|Return to Welcome Menu"), 1343 _("Congratulations!\n\n" 1344 "%s has successfully been installed on " 1345 "this computer. You may now proceed to configure " 1346 "the installation. Alternately, you may wish to " 1347 "reboot the computer and boot into the installed " 1348 "system to confirm that it works."), 1349 OPERATING_SYSTEM_NAME)) { 1350 case 1: 1351 state = state_configure_menu; 1352 break; 1353 case 2: 1354 state = state_reboot; 1355 break; 1356 case 3: 1357 state = state_welcome; 1358 break; 1359 default: 1360 abort_backend(); 1361 } 1362 } 1363 1364 /* 1365 * state_reboot: reboot the machine. 1366 */ 1367 void 1368 state_reboot(struct i_fn_args *a) 1369 { 1370 struct dfui_form *f; 1371 struct dfui_response *r; 1372 1373 f = dfui_form_create( 1374 "reboot", 1375 _("Reboot"), 1376 _("This machine is about to be shut down. " 1377 "After the machine has reached its shutdown state, " 1378 "you may remove the CD from the CD-ROM drive tray " 1379 "and press Enter to reboot from the HDD."), 1380 1381 "", 1382 1383 "p", "role", "confirm", 1384 1385 "a", "ok", _("Reboot"), "", "", 1386 "a", "cancel", _("Return to Welcome Menu"), "", "", 1387 "p", "accelerator", "ESC", 1388 NULL 1389 ); 1390 1391 if (!dfui_be_present(a->c, f, &r)) 1392 abort_backend(); 1393 1394 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 1395 state = state_welcome; 1396 } else { 1397 do_reboot = 1; 1398 state = NULL; 1399 } 1400 1401 dfui_form_free(f); 1402 dfui_response_free(r); 1403 } 1404 1405 /* 1406 * 1407 * state_setup_remote_installation_server: 1408 * Setup a remote boot installation environment where a machine 1409 * can boot via DHCP/TFTP/NFS and have a running environment 1410 * where the installer can setup the machine. 1411 * 1412 */ 1413 void 1414 state_setup_remote_installation_server(struct i_fn_args *a) 1415 { 1416 FILE *p; 1417 struct commands *cmds; 1418 struct dfui_form *f; 1419 struct dfui_action *k; 1420 struct dfui_response *r; 1421 char *word; 1422 char interface[256]; 1423 char line[256]; 1424 1425 switch (dfui_be_present_dialog(a->c, _("Enable Netboot Installation Services?"), 1426 _("Enable NetBoot Installation Services|No thanks"), 1427 _("NetBoot Installation Services allows this machine to become " 1428 "a Installation Server that will allow the clients to boot over the network " 1429 "via PXE and start the Installation Environment." 1430 "\n\n*NOTE!* This will assign the IP Address of 10.1.0.1/24 to the selected interface." 1431 "\n\nWould you like to provision this machine to serve up the LiveCD/Installer?"))) { 1432 case 1: 1433 /* 1434 * Get interface list. 1435 */ 1436 p = popen("/sbin/ifconfig -l", "r"); 1437 /* XXX it's possible (though extremely unlikely) this will fail. */ 1438 while (fgets(line, 255, p) != NULL) 1439 line[strlen(line) - 1] = '\0'; 1440 pclose(p); 1441 1442 f = dfui_form_create( 1443 "assign_ip", 1444 _("Setup NetBoot Installation Environment"), 1445 _("Please select which interface you would like to configure:"), 1446 "", 1447 "p", "role", "menu", 1448 NULL 1449 ); 1450 1451 /* Loop through array. */ 1452 word = strtok(line, " \t"); 1453 while (word != NULL) { 1454 dfui_form_action_add(f, word, 1455 dfui_info_new(word, "", "")); 1456 word = strtok(NULL, " "); 1457 } 1458 1459 k = dfui_form_action_add(f, "cancel", 1460 dfui_info_new("Cancel", "", "")); 1461 dfui_action_property_set(k, "accelerator", "ESC"); 1462 1463 if (!dfui_be_present(a->c, f, &r)) 1464 abort_backend(); 1465 1466 strlcpy(interface, dfui_response_get_action_id(r), 256); 1467 1468 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 1469 dfui_form_free(f); 1470 dfui_response_free(r); 1471 return; 1472 } 1473 1474 /* 1475 * 1476 * Issues the necessary commands to setup the remote boot environment 1477 * 1478 */ 1479 cmds = commands_new(); 1480 command_add(cmds, "%s%s %s 10.1.0.1 netmask 255.255.255.0", 1481 a->os_root, cmd_name(a, "IFCONFIG"), interface); 1482 command_add(cmds, "%s%s -p %stftpdroot", 1483 a->os_root, cmd_name(a, "MKDIR"), a->tmp); 1484 command_add(cmds, "%s%s %sboot/pxeboot %stftpdroot", 1485 a->os_root, cmd_name(a, "CP"), a->os_root, a->tmp); 1486 command_add(cmds, "%s%s %s -ro -alldirs -maproot=root: -network 10.1.0.0 -mask 255.255.255.0 >> %setc/exports", 1487 a->os_root, cmd_name(a, "ECHO"), a->os_root, a->os_root); 1488 command_add(cmds, "%s%s tftp dgram udp wait root %s%s tftpd -l -s %stftpdroot >> %setc/inetd.conf", 1489 a->os_root, cmd_name(a, "ECHO"), 1490 a->os_root, cmd_name(a, "TFTPD"), 1491 a->tmp, a->os_root); 1492 command_add(cmds, "%s%s", 1493 a->os_root, cmd_name(a, "INETD")); 1494 command_add(cmds, "%s%s %svar/db/dhcpd.leases", 1495 a->os_root, cmd_name(a, "TOUCH"), a->os_root); 1496 command_add(cmds, "%s%s -cf /etc/dhcpd.conf >/dev/null 2>&1", 1497 a->os_root, cmd_name(a, "DHCPD")); 1498 command_add(cmds, "%s%s >/dev/null 2>&1", 1499 a->os_root, cmd_name(a, "RPCBIND")); 1500 command_add(cmds, "%s%s -ln >/dev/null 2>&1", 1501 a->os_root, cmd_name(a, "MOUNTD")); 1502 command_add(cmds, "%s%s -u -t -n 6 >/dev/null 2>&1", 1503 a->os_root, cmd_name(a, "NFSD")); 1504 1505 if (commands_execute(a, cmds)) { 1506 inform(a->c, _("NetBoot installation services are now started.")); 1507 } else { 1508 inform(a->c, _("A failure occurred while provisioning the NetBoot environment. Please check the logs.")); 1509 } 1510 1511 commands_free(cmds); 1512 dfui_form_free(f); 1513 dfui_response_free(r); 1514 1515 break; 1516 case 2: 1517 1518 break; 1519 1520 } 1521 1522 state = state_welcome; 1523 1524 } 1525 1526 /*** MAIN ***/ 1527 1528 int 1529 flow(int transport, char *rendezvous, char *os_root, 1530 int flags __unused) 1531 { 1532 struct i_fn_args *a; 1533 1534 rc_conf = config_vars_new(); 1535 1536 if ((a = i_fn_args_new(os_root, DEFAULT_INSTALLER_TEMP, 1537 DEFAULT_CMDNAMES_FILE, transport, 1538 rendezvous)) == NULL) { 1539 return(0); 1540 } 1541 1542 /* 1543 * XXX We can't handle this yet. 1544 * 1545 a->flags |= I_BOOTED_LIVECD; 1546 a->flags |= I_UPGRADE_TOOGLE; 1547 */ 1548 a->flags |= I_BOOTED_LIVECD; 1549 1550 /* 1551 * Execute the state machine here. The global function pointer 1552 * variable `state' points to the next state_* function to execute. 1553 * Before it exits, this function should set `state' to the next 1554 * state to make a transition to, or NULL to indicate that the 1555 * state machine is finished. 1556 */ 1557 #ifdef ENABLE_NLS 1558 state = state_lang_menu; 1559 #else 1560 state = state_welcome; 1561 #endif 1562 for (; state != NULL; ) 1563 state(a); 1564 1565 config_vars_free(rc_conf); 1566 1567 i_fn_args_free(a); 1568 1569 return(do_reboot); 1570 } 1571