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