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