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