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