2 * Copyright (c)2004 The DragonFly Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
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
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.
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.
36 * Workflow logic for installer.
37 * $Id: flow.c,v 1.67 2005/04/08 08:09:23 cpressey Exp $
48 #include "libdfui/lang.h"
49 #define _(String) gettext (String)
50 extern int _nl_msg_cat_cntr;
52 #define _(String) (String)
55 #include "libaura/mem.h"
56 #include "libaura/dict.h"
57 #include "libaura/fspred.h"
59 #include "libdfui/dfui.h"
61 #include "libdfui/dump.h"
63 #include "libdfui/system.h"
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"
74 #include "pathnames.h"
78 void (*state)(struct i_fn_args *) = NULL;
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.)
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
107 state_lang_menu(struct i_fn_args *a)
110 struct dfui_response *r;
116 f = dfui_form_create(
118 _("Select Language"),
119 _("Please select the language you wish you use."),
124 "a", "default", "English",
125 "English Standard Default", "",
126 "a", "ru", "Russian",
127 "Russian KOI8-R", "",
131 if (!dfui_be_present(a->c, f, &r))
134 id = aura_strdup(dfui_response_get_action_id(r));
136 if (strcmp(id, "default") == 0) {
137 state = state_welcome;
140 state = state_welcome;
145 dfui_response_free(r);
148 /* set keymap, scrnmap, fonts */
149 if (!set_lang_syscons(id))
153 if (!set_lang_envars(id))
156 dfui_be_set_global_setting(a->c, "lang", id, &cancelled);
158 /* XXX if (!cancelled) ... ? */
160 /* let gettext know about changes */
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.
171 state_welcome(struct i_fn_args *a)
174 struct dfui_response *r;
175 char msg_buf[2][1024];
177 snprintf(msg_buf[0], sizeof(msg_buf[0]),
178 _("Welcome to %s"), OPERATING_SYSTEM_NAME);
180 snprintf(msg_buf[1], sizeof(msg_buf[1]),
181 _("Welcome to the %s Live CD."
183 "%s is an efficient and elegant BSD "
184 "Unix-derived operating system. For more information, see %s"
186 "From this CD, you can boot into %s ``live'' "
187 "(without installing it) to evaluate it, to install it "
188 "manually, or to troubleshoot problems with an "
189 "existing installation, using either a command prompt "
190 "or menu-driven utilities."
192 "Also, you can use this automated application to assist "
193 "you in installing %s on this computer and "
194 "configuring it once it is installed."
196 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_URL,
197 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
199 if (!a->booted_from_livecd) {
200 state = state_welcome_system;
204 f = dfui_form_create(
212 "p", "special", "dfinstaller_welcome",
217 if (a->upgrade_menu_toggle) {
218 snprintf(msg_buf[0], sizeof(msg_buf[0]),
219 _("Upgrade a FreeBSD 4.X system to %s"),
220 OPERATING_SYSTEM_NAME);
221 dfui_form_action_add(f, "upgrade",
222 dfui_info_new(_("Upgrade"),
225 snprintf(msg_buf[0], sizeof(msg_buf[0]),
226 _("Install %s"), OPERATING_SYSTEM_NAME);
227 snprintf(msg_buf[1], sizeof(msg_buf[1]),
228 _("Install %s on a HDD or HDD partition on this computer"),
229 OPERATING_SYSTEM_NAME);
230 dfui_form_action_add(f, "install",
231 dfui_info_new(msg_buf[0],
235 snprintf(msg_buf[0], sizeof(msg_buf[0]),
236 _("Configure a %s system once it has been installed on HDD"),
237 OPERATING_SYSTEM_NAME);
238 dfui_form_action_add(f, "configure",
239 dfui_info_new(_("Configure an Installed System"),
242 dfui_form_action_add(f, "utilities",
243 dfui_info_new(_("Live CD Utilities"),
244 _("Utilities to work with disks, diagnostics, and the LiveCD Environment"), ""));
246 dfui_form_action_add(f, "exit",
247 dfui_info_new(_("Exit to Live CD"),
248 _("Exit this program to a login prompt with access to the LiveCD"), ""));
250 dfui_form_action_add(f, "reboot",
251 dfui_info_new(_("Reboot this Computer"),
252 _("Reboot this computer (e.g. to boot into a newly installed system)"), ""));
254 dfui_form_action_add(f, "configure_netboot",
255 dfui_info_new(_("Setup NetBoot Install Services"),
256 _("Setup machine as remote installation server"), ""));
258 if (!dfui_be_present(a->c, f, &r))
261 if (strcmp(dfui_response_get_action_id(r), "install") == 0) {
262 state = state_begin_install;
263 } else if (strcmp(dfui_response_get_action_id(r), "upgrade") == 0) {
264 state = state_begin_upgrade;
265 } else if (strcmp(dfui_response_get_action_id(r), "configure") == 0) {
266 storage_set_selected_disk(a->s, NULL);
267 storage_set_selected_slice(a->s, NULL);
268 state = state_configure_menu;
269 } else if (strcmp(dfui_response_get_action_id(r), "utilities") == 0) {
270 state = state_utilities_menu;
271 } else if (strcmp(dfui_response_get_action_id(r), "exit") == 0) {
273 } else if (strcmp(dfui_response_get_action_id(r), "configure_netboot") == 0) {
274 state = state_setup_remote_installation_server;
275 } else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0) {
276 state = state_reboot;
280 dfui_response_free(r);
284 * state_welcome_system: the start state of the installer state machine,
285 * when run from the installed system. Allow the user to configure the
289 state_welcome_system(struct i_fn_args *a)
292 struct dfui_response *r;
293 char msg_buf[2][1024];
295 snprintf(msg_buf[0], sizeof(msg_buf[0]),
296 _("Configure this %s System"), OPERATING_SYSTEM_NAME);
298 snprintf(msg_buf[1], sizeof(msg_buf[1]),
299 _("Thank you for choosing %s."
301 "For up-to-date news and information on %s, "
302 "make sure to check out"
306 "You can use this automated application to assist "
307 "you in setting up this %s system."
309 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME,
310 OPERATING_SYSTEM_URL, OPERATING_SYSTEM_NAME);
313 f = dfui_form_create(
321 "p", "special", "dfinstaller_welcome",
326 snprintf(msg_buf[0], sizeof(msg_buf[0]),
327 _("Configure this %s system"), OPERATING_SYSTEM_NAME);
329 dfui_form_action_add(f, "environment",
330 dfui_info_new(_("Configure this System"),
333 dfui_form_action_add(f, "utilities",
334 dfui_info_new(_("Utilities"),
335 _("Utilities to work with and diagnose disks and other subsystems"), ""));
337 dfui_form_action_add(f, "exit",
338 dfui_info_new(_("Exit Installer"),
339 _("Exit this program and return to the system"), ""));
341 if (!dfui_be_present(a->c, f, &r))
344 if (strcmp(dfui_response_get_action_id(r), "environment") == 0) {
345 state = state_environment_menu;
346 } else if (strcmp(dfui_response_get_action_id(r), "utilities") == 0) {
347 state = state_utilities_menu;
348 } else if (strcmp(dfui_response_get_action_id(r), "exit") == 0) {
350 } else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0) {
351 state = state_reboot;
355 dfui_response_free(r);
359 state_configure_menu(struct i_fn_args *a)
361 struct dfui_form *f = NULL;
362 struct dfui_response *r = NULL;
363 struct commands *cmds;
365 char msg_buf[2][1024];
367 if (storage_get_selected_disk(a->s) == NULL || storage_get_selected_slice(a->s) == NULL) {
368 if (!survey_storage(a)) {
369 inform(a->c, _("Errors occurred while probing "
370 "the system for its storage capabilities."));
373 a->short_desc = _("Select the disk containing the installation.");
374 a->cancel_desc = _("Return to Welcome Menu");
376 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
377 state = state_welcome;
381 a->short_desc = _("Select the primary partition containing the installation.");
382 a->cancel_desc = _("Return to Welcome Menu");
385 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
386 state = state_welcome;
393 if (during_install == 0) {
394 switch (dfui_be_present_dialog(a->c, _("Select file system"),
395 _("HAMMER|UFS|Return to Welcome Menu"),
396 _("Please select the file system installed on the disk.\n\n")))
407 state = state_welcome;
417 if (!mount_target_system(a)) {
418 inform(a->c, _("Target system could not be mounted."));
419 state = state_welcome;
423 snprintf(msg_buf[0], sizeof(msg_buf[0]),
424 _("The options on this menu allow you to configure a "
425 "%s system after it has already been "
426 "installed."), OPERATING_SYSTEM_NAME);
429 f = dfui_form_create(
431 _("Configure an Installed System"),
437 _("Select timezone"),
438 _("Set the Time Zone of your physical location"), "",
440 _("Set date and time"),
441 _("Set the Time and Date of your machine"), "",
444 _("Set keyboard map"),
445 _("Set what kind of keyboard layout you have"), "",
446 "a", "root_passwd", _("Set root password"),
447 _("Set the password that the root (superuser) account will use"), "",
448 "a", "add_user", _("Add a user"),
449 _("Add a user to the system"), "",
450 "a", "assign_ip", _("Configure network interfaces"),
451 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "",
452 "a", "assign_hostname_domain",
453 _("Configure hostname and domain"),
454 _("Configure the hostname and domain for this system"), "",
456 "a", "select_services", "Select Services",
457 "Enable/Disable system services (servers, daemons, etc.)", "",
460 _("Set console font"),
461 _("Set how the characters on your video console look"), "",
464 _("Set how characters are translated before console display"), "",
466 "a", "install_pkgs", _("Install extra software packages"),
467 _("Install third-party software packages from the LiveCD"), "",
469 "a", "remove_pkgs", _("Remove software packages"),
470 _("Remove third-party software packages from the installed system"), "",
472 "a", "cancel", _("Return to Welcome Menu"), "", "",
473 "p", "accelerator", "ESC",
478 if (!dfui_be_present(a->c, f, &r))
482 a->cfg_root = "mnt/";
483 if (strcmp(dfui_response_get_action_id(r), "root_passwd") == 0) {
485 } else if (strcmp(dfui_response_get_action_id(r), "add_user") == 0) {
487 } else if (strcmp(dfui_response_get_action_id(r), "install_pkgs") == 0) {
488 fn_install_packages(a);
489 } else if (strcmp(dfui_response_get_action_id(r), "remove_pkgs") == 0) {
490 fn_remove_packages(a);
491 } else if (strcmp(dfui_response_get_action_id(r), "assign_ip") == 0) {
493 } else if (strcmp(dfui_response_get_action_id(r), "assign_hostname_domain") == 0) {
494 fn_assign_hostname_domain(a);
495 } else if (strcmp(dfui_response_get_action_id(r), "select_services") == 0) {
496 fn_select_services(a);
497 } else if (strcmp(dfui_response_get_action_id(r), "set_kbdmap") == 0) {
499 } else if (strcmp(dfui_response_get_action_id(r), "set_vidfont") == 0) {
501 } else if (strcmp(dfui_response_get_action_id(r), "set_scrnmap") == 0) {
503 } else if (strcmp(dfui_response_get_action_id(r), "set_timezone") == 0) {
505 } else if (strcmp(dfui_response_get_action_id(r), "set_datetime") == 0) {
506 fn_assign_datetime(a);
507 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
508 state = state_welcome;
513 dfui_response_free(r);
517 * Before unmounting the system, write out any changes to rc.conf.
519 config_vars_write(rc_conf, CONFIG_TYPE_SH,
520 "%s%setc/rc.conf", a->os_root, a->cfg_root);
523 * Clear out configuration variable table in memory.
525 config_vars_free(rc_conf);
526 rc_conf = config_vars_new();
529 * Finally, unmount the system we mounted on /mnt and remove mappings.
531 cmds = commands_new();
532 unmount_all_under(a, cmds, "%smnt", a->os_root);
533 commands_execute(a, cmds);
536 if (remove_all_mappings(a) == NULL)
537 inform(a->c, _("Warning: mappings could not be removed."));
541 state_utilities_menu(struct i_fn_args *a)
544 struct dfui_response *r;
546 if (!survey_storage(a)) {
547 inform(a->c, _("Errors occurred while probing "
548 "the system for its storage capabilities."));
551 f = dfui_form_create(
553 _("Live CD Utilities Menu"),
554 _("On these submenus you will find utilities to help "
555 "you set up your Live CD environment, diagnose "
556 "and analyse this system, and work with "
557 "the devices attached to this computer."),
560 "a", "environment", _("LiveCD Environment"),
561 _("Configure the LiveCD Environment"), "",
562 "a", "diagnostics", _("System Diagnostics"),
563 _("Probe and display detailed information about this system"), "",
564 "a", "diskutil", _("Disk Utilities"),
565 _("Format and check hard drives and floppy disks"), "",
566 "a", "livecd", _("Exit to Live CD"),
567 _("Exit this program to a login prompt with access to the LiveCD"), "",
569 _("Reboot this Computer"), "", "",
571 _("Return to Welcome Menu"), "", "",
572 "p", "accelerator", "ESC",
576 if (!dfui_be_present(a->c, f, &r))
579 if (strcmp(dfui_response_get_action_id(r), "environment") == 0)
580 state = state_environment_menu;
581 else if (strcmp(dfui_response_get_action_id(r), "diagnostics") == 0)
582 state = state_diagnostics_menu;
583 else if (strcmp(dfui_response_get_action_id(r), "diskutil") == 0)
584 state = state_diskutil_menu;
585 else if (strcmp(dfui_response_get_action_id(r), "livecd") == 0)
587 else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0)
588 state = state_reboot;
589 else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0)
590 state = state_welcome;
593 dfui_response_free(r);
597 state_environment_menu(struct i_fn_args *a)
600 struct dfui_response *r;
602 char msg_buf[2][1024];
604 snprintf(msg_buf[0], sizeof(msg_buf[0]),
605 _("On this menu you will find utilities to help you "
606 "set up your Live CD environment.\n\nNote "
607 "that these functions affect only the LiveCD "
608 "environment you are currently using, and they will "
609 "not affect any system that may be installed on "
610 "this computer UNLESS you subsequently choose to "
611 "install %s from this environment, in which "
612 "case they will be copied to the newly installed "
613 "system."), OPERATING_SYSTEM_NAME);
616 f = dfui_form_create(
618 _("Live CD Environment Menu"),
624 _("Select timezone"),
625 _("Set the Time Zone of your physical location"), "",
627 _("Set date and time"),
628 _("Set the Time and Date of your machine"), "",
631 _("Set keyboard map"),
632 _("Set what kind of keyboard layout you have"), "",
634 _("Set console font"),
635 _("Set how the characters on your video console look"), "",
638 _("Set how characters are translated before console display"), "",
640 "a", "assign_hostname_domain",
641 _("Configure hostname and domain"),
642 _("Configure the hostname and domain for this system"), "",
644 _("Configure network interfaces"),
645 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "",
648 _("Return to Utilities Menu"), "", "",
649 "p", "accelerator", "ESC",
654 if (!dfui_be_present(a->c, f, &r))
659 if (strcmp(dfui_response_get_action_id(r), "set_kbdmap") == 0) {
661 } else if (strcmp(dfui_response_get_action_id(r), "set_vidfont") == 0) {
663 } else if (strcmp(dfui_response_get_action_id(r), "set_scrnmap") == 0) {
665 } else if (strcmp(dfui_response_get_action_id(r), "assign_hostname_domain") == 0) {
666 fn_assign_hostname_domain(a);
667 } else if (strcmp(dfui_response_get_action_id(r), "assign_ip") == 0) {
669 } else if (strcmp(dfui_response_get_action_id(r), "set_timezone") == 0) {
671 } else if (strcmp(dfui_response_get_action_id(r), "set_datetime") == 0) {
672 fn_assign_datetime(a);
673 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
674 state = state_utilities_menu;
679 dfui_response_free(r);
684 state_diagnostics_menu(struct i_fn_args *a)
687 struct dfui_action *k;
688 struct dfui_response *r;
692 f = dfui_form_create(
694 _("Live CD Diagnostics Menu"),
695 _("These functions can help you diagnose this system."),
700 _("Display system startup messages"),
701 _("Display system startup messages (dmesg)"), "",
703 _("Display PCI devices"),
704 _("Display PCI devices (pciconf)"), "",
706 _("Display Plug'n'Play ISA devices"),
707 _("Display Plug'n'Play ISA devices (pnpinfo)"), "",
709 _("Display ATA devices"),
710 _("Display ATA devices (natacontrol)"), "",
714 k = dfui_form_action_add(f, "cancel",
715 dfui_info_new(_("Return to Utilities Menu"), "", ""));
716 dfui_action_property_set(k, "accelerator", "ESC");
718 if (!dfui_be_present(a->c, f, &r))
722 if (strcmp(dfui_response_get_action_id(r), "show_dmesg") == 0) {
724 } else if (strcmp(dfui_response_get_action_id(r), "pciconf") == 0) {
726 } else if (strcmp(dfui_response_get_action_id(r), "pnpinfo") == 0) {
728 } else if (strcmp(dfui_response_get_action_id(r), "natacontrol") == 0) {
729 fn_show_natacontrol(a);
730 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
731 state = state_utilities_menu;
736 dfui_response_free(r);
741 state_diskutil_menu(struct i_fn_args *a)
744 struct dfui_action *k;
745 struct dfui_response *r;
749 f = dfui_form_create(
751 _("Disk Utilities Menu"),
752 _("These functions let you manipulate the storage devices "
753 "attached to this computer."),
759 _("Format a hard disk drive"), "", "",
760 "a", "wipe_start_of_disk",
761 _("Wipe out the start of a disk"), "", "",
762 "a", "wipe_start_of_slice",
763 _("Wipe out the start of a primary partition"), "", "",
764 "a", "install_bootblocks",
765 _("Install bootblocks on disks"), "", "",
766 "a", "format_msdos_floppy",
767 _("Format an MSDOS floppy"), "", "",
771 if (is_file("%sboot/cdboot.flp.bz2", a->os_root)) {
772 dfui_form_action_add(f, "create_cdboot_floppy",
773 dfui_info_new(_("Create a CDBoot floppy"),
778 k = dfui_form_action_add(f, "cancel",
779 dfui_info_new(_("Return to Utilities Menu"), "", ""));
780 dfui_action_property_set(k, "accelerator", "ESC");
782 if (!dfui_be_present(a->c, f, &r))
786 if (strcmp(dfui_response_get_action_id(r), "format_hdd") == 0) {
787 storage_set_selected_disk(a->s, NULL);
788 storage_set_selected_slice(a->s, NULL);
790 } else if (strcmp(dfui_response_get_action_id(r), "wipe_start_of_disk") == 0) {
791 fn_wipe_start_of_disk(a);
792 } else if (strcmp(dfui_response_get_action_id(r), "wipe_start_of_slice") == 0) {
793 fn_wipe_start_of_slice(a);
794 } else if (strcmp(dfui_response_get_action_id(r), "install_bootblocks") == 0) {
795 a->short_desc = _("Select the disks on which "
796 "you wish to install bootblocks.");
797 a->cancel_desc = _("Return to Utilities Menu");
798 fn_install_bootblocks(a, NULL);
799 } else if (strcmp(dfui_response_get_action_id(r), "format_msdos_floppy") == 0) {
800 fn_format_msdos_floppy(a);
801 } else if (strcmp(dfui_response_get_action_id(r), "create_cdboot_floppy") == 0) {
802 fn_create_cdboot_floppy(a);
803 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
804 state = state_utilities_menu;
809 dfui_response_free(r);
813 /** INSTALLER STATES **/
816 * state_begin_upgrade: Ask the user where the freebsd
817 * 4.X install is and make sure its safe to proceed.
821 state_begin_upgrade(struct i_fn_args *a)
823 //struct dfui_form *f = NULL;
824 //struct dfui_response *r = NULL;
827 if (storage_get_selected_disk(a->s) == NULL || storage_get_selected_slice(a->s) == NULL) {
828 if (!survey_storage(a)) {
829 inform(a->c, _("Errors occurred while probing "
830 "the system for its storage capabilities."));
833 a->short_desc = _("Select the disk containing the installation that you would like to upgrade.");
834 a->cancel_desc = _("Return to Welcome Menu");
836 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
837 state = state_welcome;
841 a->short_desc = _("Select the primary partition containing the installation you would like to upgrade.");
842 a->cancel_desc = _("Return to Welcome Menu");
845 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
846 state = state_welcome;
852 if (!mount_target_system(a)) {
853 inform(a->c, _("Target system could not be mounted."));
854 state = state_welcome;
860 * state_begin_install: Briefly describe the install process
861 * to the user, and let them proceed (or not.)
864 state_begin_install(struct i_fn_args *a)
867 struct dfui_response *r;
868 char msg_buf[3][1024];
870 snprintf(msg_buf[0], sizeof(msg_buf[0]),
871 _("This application will install %s"
872 " on one of the hard disk drives attached to this computer. "
873 "It has been designed to make it easy to install "
874 "%s in the typical case. "
875 "If you have special requirements that are not addressed "
876 "by this installer, or if you have problems using it, you "
877 "are welcome to install %s manually. "
878 "To do so select Exit to Live CD, login as root, and follow "
879 "the instructions given in the file /README ."
881 "NOTE! As with any installation process, YOU ARE "
882 "STRONGLY ENCOURAGED TO BACK UP ANY IMPORTANT DATA ON THIS "
883 "COMPUTER BEFORE PROCEEDING!"
885 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME,
886 OPERATING_SYSTEM_NAME);
888 snprintf(msg_buf[1], sizeof(msg_buf[1]),
889 _("Some situations in which you might not wish to use this "
891 "- you want to install %s onto a "
892 "logical/extended partition;\n"
893 "- you want to install %s "
894 "onto a ``dangerously dedicated'' disk; or\n"
895 "- you want full and utter control over the install process."
897 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
899 snprintf(msg_buf[2], sizeof(msg_buf[2]),
900 _("Install %s"), OPERATING_SYSTEM_NAME);
902 f = dfui_form_create(
904 _("Begin Installation"),
908 "p", "special", "dfinstaller_begin_install",
909 "p", "minimum_width", "76",
911 "a", "proceed", msg_buf[2],
913 "a", "cancel", _("Return to Welcome Menu"),
915 "p", "accelerator", "ESC",
916 "a", "livecd", _("Exit to Live CD"),
921 if (!dfui_be_present(a->c, f, &r))
924 if (strcmp(dfui_response_get_action_id(r), "proceed") == 0) {
925 if (!survey_storage(a)) {
926 inform(a->c, _("Errors occurred while probing "
927 "the system for its storage capabilities."));
929 state = state_select_disk;
930 } else if (strcmp(dfui_response_get_action_id(r), "livecd") == 0) {
932 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
933 state = state_welcome;
937 dfui_response_free(r);
941 * state_select_disk: ask the user on which physical disk they wish
942 * to install DragonFly.
945 state_select_disk(struct i_fn_args *a)
949 char msg_buf[1][1024];
951 for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d))
954 if (num_disks == 0) {
955 inform(a->c, _("The installer could not find any disks suitable "
956 "for installation (IDE or SCSI) attached to this "
957 "computer. If you wish to install %s"
958 " on an unorthodox storage device, you will have to "
959 "exit to a LiveCD command prompt and install it "
960 "manually, using the file /README as a guide."),
961 OPERATING_SYSTEM_NAME);
962 state = state_welcome;
966 snprintf(msg_buf[0], sizeof(msg_buf[0]),
967 _("Select a disk on which to install %s"),
968 OPERATING_SYSTEM_NAME);
969 a->short_desc = msg_buf[0];
970 a->cancel_desc = _("Return to Begin Installation");
972 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
973 state = state_begin_install;
976 if (disk_get_capacity(storage_get_selected_disk(a->s)) < DISK_MIN) {
977 inform(a->c, _("WARNING: you should have a disk "
978 "at least %dM in size, or "
979 "you may encounter problems trying to "
980 "install %s."), DISK_MIN, OPERATING_SYSTEM_NAME);
983 state = state_format_disk;
988 state_ask_fs(struct i_fn_args *a)
992 switch (dfui_be_present_dialog(a->c, _("Select file system"),
993 _("Use HAMMER|Use UFS|Return to Select Disk"),
994 _("Please select the file system you want to use with %s.\n\n"
995 "HAMMER is the new %s file system. UFS is the traditional BSD file system."),
996 OPERATING_SYSTEM_NAME,
997 OPERATING_SYSTEM_NAME))
1007 state = state_select_disk;
1015 state = state_create_subpartitions;
1019 * state_format_disk: ask the user if they wish to format the disk they
1023 state_format_disk(struct i_fn_args *a)
1025 switch (dfui_be_present_dialog(a->c, _("How Much Disk?"),
1026 _("Use Entire Disk|Use Part of Disk|Return to Select Disk"),
1027 _("Select how much of this disk you want to use for %s.\n\n%s"),
1028 OPERATING_SYSTEM_NAME,
1029 disk_get_desc(storage_get_selected_disk(a->s)))) {
1032 if (measure_activated_swap_from_disk(a, storage_get_selected_disk(a->s)) > 0) {
1033 if (swapoff_all(a) == NULL) {
1034 inform(a->c, _("Warning: swap could not be turned off."));
1035 state = state_select_disk;
1042 state = state_ask_fs;
1044 state = state_format_disk;
1048 state = state_select_slice;
1052 state = state_select_disk;
1061 * state_select_slice: ask the user which slice they wish to install
1062 * DragonFly on. In order to avoid confusing them, refer to it as
1063 * a primary partition, but tell them what BSD has traditionally called
1067 state_select_slice(struct i_fn_args *a)
1069 char msg_buf[1][1024];
1071 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1072 _("Select the existing primary partition (also "
1073 "known as a `slice' in the BSD tradition) on "
1074 "which to install %s.\n\n"
1075 "Note that if you do not have any existing "
1076 "primary partitions on this disk, you must "
1077 "first create some. This installer does not "
1078 "currently have the ability to do this, so "
1079 "you will have to exit and run fdisk (in "
1080 "DOS or *BSD) or parted (in Linux) to do so."),
1081 OPERATING_SYSTEM_NAME);
1083 a->short_desc = msg_buf[0];
1084 a->cancel_desc = _("Return to Select Disk");
1086 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
1087 state = state_select_disk;
1089 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s),
1090 storage_get_selected_slice(a->s)) > 0) {
1091 if (swapoff_all(a) == NULL) {
1092 inform(a->c, _("Warning: swap could not be turned off."));
1093 state = state_select_slice;
1098 if (slice_get_capacity(storage_get_selected_slice(a->s)) < DISK_MIN) {
1099 inform(a->c, _("WARNING: you should have a primary "
1100 "partition at least %dM in size, or "
1101 "you may encounter problems trying to "
1102 "install %s."), DISK_MIN, OPERATING_SYSTEM_NAME);
1105 if (confirm_dangerous_action(a->c,
1106 _("WARNING! ALL data in primary partition #%d,\n\n%s\n\non the "
1107 "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you "
1108 "ABSOLUTELY SURE you wish to take this action? This is "
1109 "your LAST CHANCE to cancel!"),
1110 slice_get_number(storage_get_selected_slice(a->s)),
1111 slice_get_desc(storage_get_selected_slice(a->s)),
1112 disk_get_desc(storage_get_selected_disk(a->s)))) {
1113 if (!format_slice(a)) {
1114 inform(a->c, _("Primary partition #%d was "
1115 "not correctly formatted, and may "
1116 "now be in an inconsistent state. "
1117 "We recommend re-formatting it "
1118 "before proceeding."),
1119 slice_get_number(storage_get_selected_slice(a->s)));
1121 inform(a->c, _("Primary partition #%d was formatted."),
1122 slice_get_number(storage_get_selected_slice(a->s)));
1123 state = state_ask_fs;
1126 inform(a->c, _("Action cancelled - no primary partitions were formatted."));
1127 state = state_select_slice;
1133 * state_create_subpartitions: let the user specify what subpartitions they
1134 * want on the disk, how large each should be, and where it should be mounted.
1137 state_create_subpartitions(struct i_fn_args *a)
1139 struct commands *cmds;
1141 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s),
1142 storage_get_selected_slice(a->s)) > 0) {
1143 if (swapoff_all(a) == NULL) {
1144 inform(a->c, _("Warning: swap could not be turned off."));
1145 state = disk_get_formatted(storage_get_selected_disk(a->s)) ?
1146 state_select_disk : state_select_slice;
1151 cmds = commands_new();
1154 * Auto-disklabel the slice.
1155 * NB: one cannot use "/dev/adXsY" here -
1156 * it must be in the form "adXsY".
1158 command_add(cmds, "%s%s -W %s",
1159 a->os_root, cmd_name(a, "DISKLABEL64"),
1160 slice_get_device_name(storage_get_selected_slice(a->s)));
1161 command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
1162 a->os_root, cmd_name(a, "DD"),
1163 slice_get_device_name(storage_get_selected_slice(a->s)));
1164 command_add(cmds, "%s%s -B -r -w %s auto",
1165 a->os_root, cmd_name(a, "DISKLABEL64"),
1166 slice_get_device_name(storage_get_selected_slice(a->s)));
1167 commands_execute(a, cmds);
1168 commands_free(cmds);
1171 fn_create_subpartitions_hammer(a);
1173 fn_create_subpartitions_ufs(a);
1176 state = state_install_os;
1178 state = disk_get_formatted(storage_get_selected_disk(a->s)) ?
1179 state_select_disk : state_select_slice;
1184 * state_install_os: actually put DragonFly on the disk.
1187 state_install_os(struct i_fn_args *a)
1189 struct dfui_form *f;
1190 struct dfui_response *r;
1191 char msg_buf[1][1024];
1193 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1194 _("Everything is now ready to install the actual files which "
1195 "comprise the %s operating system "
1196 "on the selected partition of the selected disk.\n\n"
1197 "Note that this process will take quite a while to finish. "
1198 "You may wish to take a break now and come back to the "
1199 "computer in a short while."),
1200 OPERATING_SYSTEM_NAME);
1202 f = dfui_form_create(
1209 "p", "role", "confirm",
1210 "p", "special", "dfinstaller_install_os",
1212 "a", "ok", _("Begin Installing Files"), "", "",
1213 "a", "cancel", _("Return to Create Subpartitions"), "", "",
1214 "p", "accelerator", "ESC",
1219 if (!dfui_be_present(a->c, f, &r))
1222 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1223 state = state_create_subpartitions;
1227 state = state_install_bootstrap;
1231 dfui_response_free(r);
1235 * state_install_bootstrap: put boot0 bootblocks on selected disks.
1238 state_install_bootstrap(struct i_fn_args *a)
1240 char msg_buf[1][1024];
1242 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1243 _("You may now wish to install bootblocks on one or more disks. "
1244 "If you already have a boot manager installed, you can skip "
1245 "this step (but you may have to configure your boot manager "
1246 "separately.) If you installed %s on a disk other "
1247 "than your first disk, you will need to put the bootblock "
1248 "on at least your first disk and the %s disk."),
1249 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
1251 a->short_desc = msg_buf[0];
1252 a->cancel_desc = _("Skip this Step");
1253 fn_install_bootblocks(a,
1254 disk_get_device_name(storage_get_selected_disk(a->s)));
1255 state = state_finish_install;
1259 * Finish up the install.
1262 state_finish_install(struct i_fn_args *a)
1264 char msg_buf[1][1024];
1267 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1269 OPERATING_SYSTEM_NAME);
1271 switch (dfui_be_present_dialog(a->c, msg_buf[0],
1272 _("Configure this System|Reboot|Return to Welcome Menu"),
1273 _("Congratulations!\n\n"
1274 "%s has successfully been installed on "
1275 "this computer. You may now proceed to configure "
1276 "the installation. Alternately, you may wish to "
1277 "reboot the computer and boot into the installed "
1278 "system to confirm that it works."),
1279 OPERATING_SYSTEM_NAME)) {
1281 state = state_configure_menu;
1284 state = state_reboot;
1287 state = state_welcome;
1295 * state_reboot: reboot the machine.
1298 state_reboot(struct i_fn_args *a)
1300 struct dfui_form *f;
1301 struct dfui_response *r;
1303 f = dfui_form_create(
1306 _("This machine is about to be shut down. "
1307 "After the machine has reached its shutdown state, "
1308 "you may remove the CD from the CD-ROM drive tray "
1309 "and press Enter to reboot from the HDD."),
1313 "p", "role", "confirm",
1315 "a", "ok", _("Reboot"), "", "",
1316 "a", "cancel", _("Return to Welcome Menu"), "", "",
1317 "p", "accelerator", "ESC",
1321 if (!dfui_be_present(a->c, f, &r))
1324 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1325 state = state_welcome;
1332 dfui_response_free(r);
1337 * state_setup_remote_installation_server:
1338 * Setup a remote boot installation environment where a machine
1339 * can boot via DHCP/TFTP/NFS and have a running environment
1340 * where the installer can setup the machine.
1344 state_setup_remote_installation_server(struct i_fn_args *a)
1347 struct commands *cmds;
1348 struct dfui_form *f;
1349 struct dfui_action *k;
1350 struct dfui_response *r;
1352 char interface[256];
1355 switch (dfui_be_present_dialog(a->c, _("Enable Netboot Installation Services?"),
1356 _("Enable NetBoot Installation Services|No thanks"),
1357 _("NetBoot Installation Services allows this machine to become "
1358 "a Installation Server that will allow the clients to boot over the network "
1359 "via PXE and start the Installation Environment."
1360 "\n\n*NOTE!* This will assign the IP Address of 10.1.0.1/24 to the selected interface."
1361 "\n\nWould you like to provision this machine to serve up the LiveCD/Installer?"))) {
1364 * Get interface list.
1366 p = popen("/sbin/ifconfig -l", "r");
1367 /* XXX it's possible (though extremely unlikely) this will fail. */
1368 while (fgets(line, 255, p) != NULL)
1369 line[strlen(line) - 1] = '\0';
1372 f = dfui_form_create(
1374 _("Setup NetBoot Installation Environment"),
1375 _("Please select which interface you would like to configure:"),
1377 "p", "role", "menu",
1381 /* Loop through array. */
1382 word = strtok(line, " \t");
1383 while (word != NULL) {
1384 dfui_form_action_add(f, word,
1385 dfui_info_new(word, "", ""));
1386 word = strtok(NULL, " ");
1389 k = dfui_form_action_add(f, "cancel",
1390 dfui_info_new("Cancel", "", ""));
1391 dfui_action_property_set(k, "accelerator", "ESC");
1393 if (!dfui_be_present(a->c, f, &r))
1396 strlcpy(interface, dfui_response_get_action_id(r), 256);
1398 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1400 dfui_response_free(r);
1406 * Issues the necessary commands to setup the remote boot environment
1409 cmds = commands_new();
1410 command_add(cmds, "%s%s %s 10.1.0.1 netmask 255.255.255.0",
1411 a->os_root, cmd_name(a, "IFCONFIG"), interface);
1412 command_add(cmds, "%s%s -p %stftpdroot",
1413 a->os_root, cmd_name(a, "MKDIR"), a->tmp);
1414 command_add(cmds, "%s%s %sboot/pxeboot %stftpdroot",
1415 a->os_root, cmd_name(a, "CP"), a->os_root, a->tmp);
1416 command_add(cmds, "%s%s %s -ro -alldirs -maproot=root: -network 10.1.0.0 -mask 255.255.255.0 >> %setc/exports",
1417 a->os_root, cmd_name(a, "ECHO"), a->os_root, a->os_root);
1418 command_add(cmds, "%s%s tftp dgram udp wait root %s%s tftpd -l -s %stftpdroot >> %setc/inetd.conf",
1419 a->os_root, cmd_name(a, "ECHO"),
1420 a->os_root, cmd_name(a, "TFTPD"),
1421 a->tmp, a->os_root);
1422 command_add(cmds, "%s%s",
1423 a->os_root, cmd_name(a, "INETD"));
1424 command_add(cmds, "%s%s %svar/db/dhcpd.leases",
1425 a->os_root, cmd_name(a, "TOUCH"), a->os_root);
1426 command_add(cmds, "%s%s -cf /etc/dhcpd.conf >%sdev/null 2>&1",
1427 a->os_root, cmd_name(a, "DHCPD"), a->os_root);
1428 command_add(cmds, "%s%s >%sdev/null 2>&1",
1429 a->os_root, cmd_name(a, "RPCBIND"), a->os_root);
1430 command_add(cmds, "%s%s -ln >%sdev/null 2>&1",
1431 a->os_root, cmd_name(a, "MOUNTD"), a->os_root);
1432 command_add(cmds, "%s%s -u -t -n 6 >%sdev/null 2>&1",
1433 a->os_root, cmd_name(a, "NFSD"), a->os_root);
1435 if (commands_execute(a, cmds)) {
1436 inform(a->c, _("NetBoot installation services are now started."));
1438 inform(a->c, _("A failure occurred while provisioning the NetBoot environment. Please check the logs."));
1441 commands_free(cmds);
1443 dfui_response_free(r);
1452 state = state_welcome;
1459 flow(int transport, char *rendezvous, char *os_root,
1460 int booted_from_livecd __unused, int upgrade_menu_toggle __unused)
1462 struct i_fn_args *a;
1464 rc_conf = config_vars_new();
1466 if ((a = i_fn_args_new(os_root, DEFAULT_INSTALLER_TEMP,
1467 transport, rendezvous)) == NULL) {
1472 * XXX We can't handle this yet.
1474 a->booted_from_livecd = booted_from_livecd;
1475 a->upgrade_menu_toggle = upgrade_menu_toggle;
1477 a->booted_from_livecd = 1;
1478 a->upgrade_menu_toggle = 0;
1481 * Execute the state machine here. The global function pointer
1482 * variable `state' points to the next state_* function to execute.
1483 * Before it exits, this function should set `state' to the next
1484 * state to make a transition to, or NULL to indicate that the
1485 * state machine is finished.
1488 state = state_lang_menu;
1490 state = state_welcome;
1492 for (; state != NULL; )
1495 config_vars_free(rc_conf);