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 $
49 #include "libdfui/lang.h"
50 #define _(String) gettext (String)
51 extern int _nl_msg_cat_cntr
;
53 #define _(String) (String)
56 #include "libaura/mem.h"
57 #include "libaura/dict.h"
58 #include "libaura/fspred.h"
60 #include "libdfui/dfui.h"
62 #include "libdfui/dump.h"
64 #include "libdfui/system.h"
66 #include "libinstaller/commands.h"
67 #include "libinstaller/confed.h"
68 #include "libinstaller/diskutil.h"
69 #include "libinstaller/functions.h"
70 #include "libinstaller/uiutil.h"
74 #include "pathnames.h"
78 void (*state
)(struct i_fn_args
*) = NULL
;
80 int use_hammer
; /* 0=UFS 1=HAMMER 2=HAMMER2 */
87 * The installer works like a big state machine. Each major form is
88 * a state. When the user has filled out the form satisfactorily,
89 * and selects "OK", there is a transition to the next state, in a
90 * mostly-linear order towards the final, "successfully installed"
91 * state. The user may also "Cancel", which generally causes a
92 * transition to the previous state (but may also take them back to
93 * the very first state in some cases.)
96 * - Select localization optional
97 * - Welcome to DragonFly required
98 * - Begin Installation required
99 * - Select Disk required
100 * - Format Disk optional dd, fdisk
101 * - Select Partition required dd, disklabel
102 * - Create Subpartitions required disklabel, newfs
103 * - Install DragonFly required swapon, mkdir, mount, cpdup
104 * - Install Bootstrap optional boot0cfg
105 * - Reboot optional reboot
110 state_lang_menu(struct i_fn_args
*a
)
113 struct dfui_response
*r
;
119 f
= dfui_form_create(
121 _("Select Language"),
122 _("Please select the language you wish you use."),
127 "a", "default", "English",
128 "English Standard Default", "",
129 "a", "ru", "Russian",
130 "Russian KOI8-R", "",
134 if (!dfui_be_present(a
->c
, f
, &r
))
137 id
= aura_strdup(dfui_response_get_action_id(r
));
139 if (strcmp(id
, "default") == 0) {
140 state
= state_welcome
;
143 state
= state_welcome
;
148 dfui_response_free(r
);
151 /* set keymap, scrnmap, fonts */
152 if (!set_lang_syscons(id
))
156 if (!set_lang_envars(id
))
159 dfui_be_set_global_setting(a
->c
, "lang", id
, &cancelled
);
161 /* XXX if (!cancelled) ... ? */
163 /* let gettext know about changes */
169 * state_welcome_livecd: the start state of the installer state machine,
170 * when run from the Live CD. Briefly describe DragonFly to the user,
171 * and present them with a set of reasonable options of how to proceed.
174 state_welcome(struct i_fn_args
*a
)
177 struct dfui_response
*r
;
178 char msg_buf
[2][1024];
180 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
181 _("Welcome to %s"), OPERATING_SYSTEM_NAME
);
183 snprintf(msg_buf
[1], sizeof(msg_buf
[1]),
184 _("Welcome to the %s Live CD."
186 "%s is an efficient and elegant BSD "
187 "Unix-derived operating system. For more information, see %s"
189 "From this CD, you can boot into %s ``live'' "
190 "(without installing it) to evaluate it, to install it "
191 "manually, or to troubleshoot problems with an "
192 "existing installation, using either a command prompt "
193 "or menu-driven utilities."
195 "Also, you can use this automated application to assist "
196 "you in installing %s on this computer and "
197 "configuring it once it is installed."
199 OPERATING_SYSTEM_NAME
, OPERATING_SYSTEM_NAME
, OPERATING_SYSTEM_URL
,
200 OPERATING_SYSTEM_NAME
, OPERATING_SYSTEM_NAME
);
202 if ((a
->flags
& I_BOOTED_LIVECD
) == 0) {
203 state
= state_welcome_system
;
207 f
= dfui_form_create(
215 "p", "special", "dfinstaller_welcome",
220 if (a
->flags
& I_UPGRADE_TOOGLE
) {
221 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
222 _("Upgrade a FreeBSD 4.X system to %s"),
223 OPERATING_SYSTEM_NAME
);
224 dfui_form_action_add(f
, "upgrade",
225 dfui_info_new(_("Upgrade"),
228 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
229 _("Install %s"), OPERATING_SYSTEM_NAME
);
230 snprintf(msg_buf
[1], sizeof(msg_buf
[1]),
231 _("Install %s on a HDD or HDD partition on this computer"),
232 OPERATING_SYSTEM_NAME
);
233 dfui_form_action_add(f
, "install",
234 dfui_info_new(msg_buf
[0],
238 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
239 _("Configure a %s system once it has been installed on HDD"),
240 OPERATING_SYSTEM_NAME
);
241 dfui_form_action_add(f
, "configure",
242 dfui_info_new(_("Configure an Installed System"),
245 dfui_form_action_add(f
, "utilities",
246 dfui_info_new(_("Live CD Utilities"),
247 _("Utilities to work with disks, diagnostics, and the LiveCD Environment"), ""));
249 dfui_form_action_add(f
, "exit",
250 dfui_info_new(_("Exit to Live CD"),
251 _("Exit this program to a login prompt with access to the LiveCD"), ""));
253 dfui_form_action_add(f
, "reboot",
254 dfui_info_new(_("Reboot this Computer"),
255 _("Reboot this computer (e.g. to boot into a newly installed system)"), ""));
257 dfui_form_action_add(f
, "configure_netboot",
258 dfui_info_new(_("Setup NetBoot Install Services"),
259 _("Setup machine as remote installation server"), ""));
261 if (!dfui_be_present(a
->c
, f
, &r
))
264 if (strcmp(dfui_response_get_action_id(r
), "install") == 0) {
265 state
= state_begin_install
;
266 } else if (strcmp(dfui_response_get_action_id(r
), "upgrade") == 0) {
267 state
= state_begin_upgrade
;
268 } else if (strcmp(dfui_response_get_action_id(r
), "configure") == 0) {
269 storage_set_selected_disk(a
->s
, NULL
);
270 storage_set_selected_slice(a
->s
, NULL
);
271 state
= state_configure_menu
;
272 } else if (strcmp(dfui_response_get_action_id(r
), "utilities") == 0) {
273 state
= state_utilities_menu
;
274 } else if (strcmp(dfui_response_get_action_id(r
), "exit") == 0) {
276 } else if (strcmp(dfui_response_get_action_id(r
), "configure_netboot") == 0) {
277 state
= state_setup_remote_installation_server
;
278 } else if (strcmp(dfui_response_get_action_id(r
), "reboot") == 0) {
279 state
= state_reboot
;
283 dfui_response_free(r
);
287 * state_welcome_system: the start state of the installer state machine,
288 * when run from the installed system. Allow the user to configure the
292 state_welcome_system(struct i_fn_args
*a
)
295 struct dfui_response
*r
;
296 char msg_buf
[2][1024];
298 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
299 _("Configure this %s System"), OPERATING_SYSTEM_NAME
);
301 snprintf(msg_buf
[1], sizeof(msg_buf
[1]),
302 _("Thank you for choosing %s."
304 "For up-to-date news and information on %s, "
305 "make sure to check out"
309 "You can use this automated application to assist "
310 "you in setting up this %s system."
312 OPERATING_SYSTEM_NAME
, OPERATING_SYSTEM_NAME
,
313 OPERATING_SYSTEM_URL
, OPERATING_SYSTEM_NAME
);
316 f
= dfui_form_create(
324 "p", "special", "dfinstaller_welcome",
329 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
330 _("Configure this %s system"), OPERATING_SYSTEM_NAME
);
332 dfui_form_action_add(f
, "environment",
333 dfui_info_new(_("Configure this System"),
336 dfui_form_action_add(f
, "utilities",
337 dfui_info_new(_("Utilities"),
338 _("Utilities to work with and diagnose disks and other subsystems"), ""));
340 dfui_form_action_add(f
, "exit",
341 dfui_info_new(_("Exit Installer"),
342 _("Exit this program and return to the system"), ""));
344 if (!dfui_be_present(a
->c
, f
, &r
))
347 if (strcmp(dfui_response_get_action_id(r
), "environment") == 0) {
348 state
= state_environment_menu
;
349 } else if (strcmp(dfui_response_get_action_id(r
), "utilities") == 0) {
350 state
= state_utilities_menu
;
351 } else if (strcmp(dfui_response_get_action_id(r
), "exit") == 0) {
353 } else if (strcmp(dfui_response_get_action_id(r
), "reboot") == 0) {
354 state
= state_reboot
;
358 dfui_response_free(r
);
362 state_configure_menu(struct i_fn_args
*a
)
364 struct dfui_form
*f
= NULL
;
365 struct dfui_response
*r
= NULL
;
366 struct commands
*cmds
;
368 char msg_buf
[2][1024];
370 if (storage_get_selected_disk(a
->s
) == NULL
|| storage_get_selected_slice(a
->s
) == NULL
) {
371 if (!survey_storage(a
)) {
372 inform(a
->c
, _("Errors occurred while probing "
373 "the system for its storage capabilities."));
376 a
->short_desc
= _("Select the disk containing the installation.");
377 a
->cancel_desc
= _("Return to Welcome Menu");
379 if (!a
->result
|| storage_get_selected_disk(a
->s
) == NULL
) {
380 state
= state_welcome
;
384 a
->short_desc
= _("Select the primary partition containing the installation.");
385 a
->cancel_desc
= _("Return to Welcome Menu");
388 if (!a
->result
|| storage_get_selected_slice(a
->s
) == NULL
) {
389 state
= state_welcome
;
396 if (during_install
== 0) {
397 switch (dfui_be_present_dialog(a
->c
, _("Select file system"),
398 _("HAMMER2|HAMMER1|UFS|Return to Welcome Menu"),
399 _("Please select the file system installed on the disk.\n\n")))
402 /* HAMMER2 (first menu item is the default) */
414 state
= state_welcome
;
424 if (!mount_target_system(a
)) {
425 inform(a
->c
, _("Target system could not be mounted."));
426 state
= state_welcome
;
430 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
431 _("The options on this menu allow you to configure a "
432 "%s system after it has already been "
433 "installed."), OPERATING_SYSTEM_NAME
);
436 f
= dfui_form_create(
438 _("Configure an Installed System"),
444 _("Select timezone"),
445 _("Set the Time Zone of your physical location"), "",
447 _("Set date and time"),
448 _("Set the Time and Date of your machine"), "",
451 _("Set keyboard map"),
452 _("Set what kind of keyboard layout you have"), "",
453 "a", "root_passwd", _("Set root password"),
454 _("Set the password that the root (superuser) account will use"), "",
455 "a", "add_user", _("Add a user"),
456 _("Add a user to the system"), "",
457 "a", "assign_ip", _("Configure network interfaces"),
458 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "",
459 "a", "assign_hostname_domain",
460 _("Configure hostname and domain"),
461 _("Configure the hostname and domain for this system"), "",
463 "a", "select_services", "Select Services",
464 "Enable/Disable system services (servers, daemons, etc.)", "",
467 _("Set console font"),
468 _("Set how the characters on your video console look"), "",
471 _("Set how characters are translated before console display"), "",
473 "a", "cancel", _("Return to Welcome Menu"), "", "",
474 "p", "accelerator", "ESC",
479 if (!dfui_be_present(a
->c
, f
, &r
))
483 a
->cfg_root
= "mnt/";
484 if (strcmp(dfui_response_get_action_id(r
), "root_passwd") == 0) {
486 } else if (strcmp(dfui_response_get_action_id(r
), "add_user") == 0) {
488 } else if (strcmp(dfui_response_get_action_id(r
), "assign_ip") == 0) {
490 } else if (strcmp(dfui_response_get_action_id(r
), "assign_hostname_domain") == 0) {
491 fn_assign_hostname_domain(a
);
492 } else if (strcmp(dfui_response_get_action_id(r
), "select_services") == 0) {
493 fn_select_services(a
);
494 } else if (strcmp(dfui_response_get_action_id(r
), "set_kbdmap") == 0) {
496 } else if (strcmp(dfui_response_get_action_id(r
), "set_vidfont") == 0) {
498 } else if (strcmp(dfui_response_get_action_id(r
), "set_scrnmap") == 0) {
500 } else if (strcmp(dfui_response_get_action_id(r
), "set_timezone") == 0) {
502 } else if (strcmp(dfui_response_get_action_id(r
), "set_datetime") == 0) {
503 fn_assign_datetime(a
);
504 } else if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0) {
505 state
= state_welcome
;
510 dfui_response_free(r
);
514 * Before unmounting the system, write out any changes to rc.conf.
516 config_vars_write(rc_conf
, CONFIG_TYPE_SH
,
517 "%s%setc/rc.conf", a
->os_root
, a
->cfg_root
);
520 * Clear out configuration variable table in memory.
522 config_vars_free(rc_conf
);
523 rc_conf
= config_vars_new();
526 * Finally, unmount the system we mounted on /mnt and remove mappings.
528 cmds
= commands_new();
529 unmount_all_under(a
, cmds
, "%smnt", a
->os_root
);
530 commands_execute(a
, cmds
);
533 if (remove_all_mappings(a
) == NULL
)
534 inform(a
->c
, _("Warning: mappings could not be removed."));
538 state_utilities_menu(struct i_fn_args
*a
)
541 struct dfui_response
*r
;
543 if (!survey_storage(a
)) {
544 inform(a
->c
, _("Errors occurred while probing "
545 "the system for its storage capabilities."));
548 f
= dfui_form_create(
550 _("Live CD Utilities Menu"),
551 _("On these submenus you will find utilities to help "
552 "you set up your Live CD environment, diagnose "
553 "and analyse this system, and work with "
554 "the devices attached to this computer."),
557 "a", "environment", _("LiveCD Environment"),
558 _("Configure the LiveCD Environment"), "",
559 "a", "diagnostics", _("System Diagnostics"),
560 _("Probe and display detailed information about this system"), "",
561 "a", "diskutil", _("Disk Utilities"),
562 _("Format and check hard drives and floppy disks"), "",
563 "a", "livecd", _("Exit to Live CD"),
564 _("Exit this program to a login prompt with access to the LiveCD"), "",
566 _("Reboot this Computer"), "", "",
568 _("Return to Welcome Menu"), "", "",
569 "p", "accelerator", "ESC",
573 if (!dfui_be_present(a
->c
, f
, &r
))
576 if (strcmp(dfui_response_get_action_id(r
), "environment") == 0)
577 state
= state_environment_menu
;
578 else if (strcmp(dfui_response_get_action_id(r
), "diagnostics") == 0)
579 state
= state_diagnostics_menu
;
580 else if (strcmp(dfui_response_get_action_id(r
), "diskutil") == 0)
581 state
= state_diskutil_menu
;
582 else if (strcmp(dfui_response_get_action_id(r
), "livecd") == 0)
584 else if (strcmp(dfui_response_get_action_id(r
), "reboot") == 0)
585 state
= state_reboot
;
586 else if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0)
587 state
= state_welcome
;
590 dfui_response_free(r
);
594 state_environment_menu(struct i_fn_args
*a
)
597 struct dfui_response
*r
;
599 char msg_buf
[2][1024];
601 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
602 _("On this menu you will find utilities to help you "
603 "set up your Live CD environment.\n\nNote "
604 "that these functions affect only the LiveCD "
605 "environment you are currently using, and they will "
606 "not affect any system that may be installed on "
607 "this computer UNLESS you subsequently choose to "
608 "install %s from this environment, in which "
609 "case they will be copied to the newly installed "
610 "system."), OPERATING_SYSTEM_NAME
);
613 f
= dfui_form_create(
615 _("Live CD Environment Menu"),
621 _("Select timezone"),
622 _("Set the Time Zone of your physical location"), "",
624 _("Set date and time"),
625 _("Set the Time and Date of your machine"), "",
628 _("Set keyboard map"),
629 _("Set what kind of keyboard layout you have"), "",
631 _("Set console font"),
632 _("Set how the characters on your video console look"), "",
635 _("Set how characters are translated before console display"), "",
637 "a", "assign_hostname_domain",
638 _("Configure hostname and domain"),
639 _("Configure the hostname and domain for this system"), "",
641 _("Configure network interfaces"),
642 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "",
645 _("Return to Utilities Menu"), "", "",
646 "p", "accelerator", "ESC",
651 if (!dfui_be_present(a
->c
, f
, &r
))
656 if (strcmp(dfui_response_get_action_id(r
), "set_kbdmap") == 0) {
658 } else if (strcmp(dfui_response_get_action_id(r
), "set_vidfont") == 0) {
660 } else if (strcmp(dfui_response_get_action_id(r
), "set_scrnmap") == 0) {
662 } else if (strcmp(dfui_response_get_action_id(r
), "assign_hostname_domain") == 0) {
663 fn_assign_hostname_domain(a
);
664 } else if (strcmp(dfui_response_get_action_id(r
), "assign_ip") == 0) {
666 } else if (strcmp(dfui_response_get_action_id(r
), "set_timezone") == 0) {
668 } else if (strcmp(dfui_response_get_action_id(r
), "set_datetime") == 0) {
669 fn_assign_datetime(a
);
670 } else if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0) {
671 state
= state_utilities_menu
;
676 dfui_response_free(r
);
681 state_diagnostics_menu(struct i_fn_args
*a
)
684 struct dfui_action
*k
;
685 struct dfui_response
*r
;
689 f
= dfui_form_create(
691 _("Live CD Diagnostics Menu"),
692 _("These functions can help you diagnose this system."),
697 _("Display system startup messages"),
698 _("Display system startup messages (dmesg)"), "",
700 _("Display PCI devices"),
701 _("Display PCI devices (pciconf)"), "",
703 _("Display ATA devices"),
704 _("Display ATA devices (natacontrol)"), "",
708 k
= dfui_form_action_add(f
, "cancel",
709 dfui_info_new(_("Return to Utilities Menu"), "", ""));
710 dfui_action_property_set(k
, "accelerator", "ESC");
712 if (!dfui_be_present(a
->c
, f
, &r
))
716 if (strcmp(dfui_response_get_action_id(r
), "show_dmesg") == 0) {
718 } else if (strcmp(dfui_response_get_action_id(r
), "pciconf") == 0) {
720 } else if (strcmp(dfui_response_get_action_id(r
), "natacontrol") == 0) {
721 fn_show_natacontrol(a
);
722 } else if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0) {
723 state
= state_utilities_menu
;
728 dfui_response_free(r
);
733 state_diskutil_menu(struct i_fn_args
*a
)
736 struct dfui_action
*k
;
737 struct dfui_response
*r
;
741 f
= dfui_form_create(
743 _("Disk Utilities Menu"),
744 _("These functions let you manipulate the storage devices "
745 "attached to this computer."),
751 _("Format a hard disk drive"), "", "",
752 "a", "wipe_start_of_disk",
753 _("Wipe out the start of a disk"), "", "",
754 "a", "wipe_start_of_slice",
755 _("Wipe out the start of a primary partition"), "", "",
756 "a", "install_bootblocks",
757 _("Install bootblocks on disks"), "", "",
758 "a", "format_msdos_floppy",
759 _("Format an MSDOS floppy"), "", "",
763 if (is_file("%sboot/cdboot.flp.bz2", a
->os_root
)) {
764 dfui_form_action_add(f
, "create_cdboot_floppy",
765 dfui_info_new(_("Create a CDBoot floppy"),
770 k
= dfui_form_action_add(f
, "cancel",
771 dfui_info_new(_("Return to Utilities Menu"), "", ""));
772 dfui_action_property_set(k
, "accelerator", "ESC");
774 if (!dfui_be_present(a
->c
, f
, &r
))
778 if (strcmp(dfui_response_get_action_id(r
), "format_hdd") == 0) {
779 storage_set_selected_disk(a
->s
, NULL
);
780 storage_set_selected_slice(a
->s
, NULL
);
782 fn_format_disk_uefi(a
);
784 fn_format_disk_mbr(a
);
785 } else if (strcmp(dfui_response_get_action_id(r
), "wipe_start_of_disk") == 0) {
786 fn_wipe_start_of_disk(a
);
787 } else if (strcmp(dfui_response_get_action_id(r
), "wipe_start_of_slice") == 0) {
788 fn_wipe_start_of_slice(a
);
789 } else if (strcmp(dfui_response_get_action_id(r
), "install_bootblocks") == 0) {
790 a
->short_desc
= _("Select the disks on which "
791 "you wish to install bootblocks.");
792 a
->cancel_desc
= _("Return to Utilities Menu");
793 fn_install_bootblocks(a
, NULL
);
794 } else if (strcmp(dfui_response_get_action_id(r
), "format_msdos_floppy") == 0) {
795 fn_format_msdos_floppy(a
);
796 } else if (strcmp(dfui_response_get_action_id(r
), "create_cdboot_floppy") == 0) {
797 fn_create_cdboot_floppy(a
);
798 } else if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0) {
799 state
= state_utilities_menu
;
804 dfui_response_free(r
);
808 /** INSTALLER STATES **/
811 * state_begin_upgrade: Ask the user where the freebsd
812 * 4.X install is and make sure its safe to proceed.
816 state_begin_upgrade(struct i_fn_args
*a
)
818 //struct dfui_form *f = NULL;
819 //struct dfui_response *r = NULL;
822 if (storage_get_selected_disk(a
->s
) == NULL
|| storage_get_selected_slice(a
->s
) == NULL
) {
823 if (!survey_storage(a
)) {
824 inform(a
->c
, _("Errors occurred while probing "
825 "the system for its storage capabilities."));
828 a
->short_desc
= _("Select the disk containing the installation that you would like to upgrade.");
829 a
->cancel_desc
= _("Return to Welcome Menu");
831 if (!a
->result
|| storage_get_selected_disk(a
->s
) == NULL
) {
832 state
= state_welcome
;
836 a
->short_desc
= _("Select the primary partition containing the installation you would like to upgrade.");
837 a
->cancel_desc
= _("Return to Welcome Menu");
840 if (!a
->result
|| storage_get_selected_slice(a
->s
) == NULL
) {
841 state
= state_welcome
;
847 if (!mount_target_system(a
)) {
848 inform(a
->c
, _("Target system could not be mounted."));
849 state
= state_welcome
;
855 * state_begin_install: Briefly describe the install process
856 * to the user, and let them proceed (or not.)
859 state_begin_install(struct i_fn_args
*a
)
862 struct dfui_response
*r
;
863 char msg_buf
[3][1024];
865 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
866 _("This application will install %s"
867 " on one of the hard disk drives attached to this computer. "
868 "It has been designed to make it easy to install "
869 "%s in the typical case. "
870 "If you have special requirements that are not addressed "
871 "by this installer, or if you have problems using it, you "
872 "are welcome to install %s manually. "
873 "To do so select Exit to Live CD, login as root, and follow "
874 "the instructions given in the file /README ."
876 "NOTE! As with any installation process, YOU ARE "
877 "STRONGLY ENCOURAGED TO BACK UP ANY IMPORTANT DATA ON THIS "
878 "COMPUTER BEFORE PROCEEDING!"
880 OPERATING_SYSTEM_NAME
, OPERATING_SYSTEM_NAME
,
881 OPERATING_SYSTEM_NAME
);
883 snprintf(msg_buf
[1], sizeof(msg_buf
[1]),
884 _("Some situations in which you might not wish to use this "
886 "- you want to install %s onto a "
887 "logical/extended partition;\n"
888 "- you want to install %s "
889 "onto a ``dangerously dedicated'' disk; or\n"
890 "- you want full and utter control over the install process."
892 OPERATING_SYSTEM_NAME
, OPERATING_SYSTEM_NAME
);
894 snprintf(msg_buf
[2], sizeof(msg_buf
[2]),
895 _("Install %s"), OPERATING_SYSTEM_NAME
);
897 f
= dfui_form_create(
899 _("Begin Installation"),
903 "p", "special", "dfinstaller_begin_install",
904 "p", "minimum_width", "76",
906 "a", "proceed", msg_buf
[2],
908 "a", "cancel", _("Return to Welcome Menu"),
910 "p", "accelerator", "ESC",
911 "a", "livecd", _("Exit to Live CD"),
916 if (!dfui_be_present(a
->c
, f
, &r
))
919 if (strcmp(dfui_response_get_action_id(r
), "proceed") == 0) {
920 if (!survey_storage(a
)) {
921 inform(a
->c
, _("Errors occurred while probing "
922 "the system for its storage capabilities."));
924 state
= state_ask_uefi
;
925 } else if (strcmp(dfui_response_get_action_id(r
), "livecd") == 0) {
927 } else if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0) {
928 state
= state_welcome
;
932 dfui_response_free(r
);
936 * state_ask_uefi: ask the user if they want a UEFI installation
939 state_ask_uefi(struct i_fn_args
*a
)
943 switch (dfui_be_present_dialog(a
->c
, _("UEFI or legacy BIOS?"),
944 _("UEFI|Legacy BIOS|Return to Begin Installation"),
945 _("Do you wish to set up %s for a UEFI or legacy BIOS system?"),
946 OPERATING_SYSTEM_NAME
))
956 state
= state_begin_install
;
964 state
= state_select_disk
;
968 * state_select_disk: ask the user on which physical disk they wish
969 * to install DragonFly.
972 state_select_disk(struct i_fn_args
*a
)
976 char msg_buf
[1][1024];
978 for (d
= storage_disk_first(a
->s
); d
!= NULL
; d
= disk_next(d
))
981 if (num_disks
== 0) {
982 inform(a
->c
, _("The installer could not find any disks suitable "
983 "for installation (IDE or SCSI) attached to this "
984 "computer. If you wish to install %s"
985 " on an unorthodox storage device, you will have to "
986 "exit to a LiveCD command prompt and install it "
987 "manually, using the file /README as a guide."),
988 OPERATING_SYSTEM_NAME
);
989 state
= state_welcome
;
993 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
994 _("Select a disk on which to install %s"),
995 OPERATING_SYSTEM_NAME
);
996 a
->short_desc
= msg_buf
[0];
997 a
->cancel_desc
= _("Return to Begin Installation");
999 if (!a
->result
|| storage_get_selected_disk(a
->s
) == NULL
) {
1000 state
= state_begin_install
;
1003 if (disk_get_capacity(storage_get_selected_disk(a
->s
)) < DISK_MIN
) {
1004 inform(a
->c
, _("WARNING: you should have a disk "
1005 "at least %dM in size, or "
1006 "you may encounter problems trying to "
1007 "install %s."), DISK_MIN
, OPERATING_SYSTEM_NAME
);
1010 state
= state_format_disk
;
1015 state_ask_fs(struct i_fn_args
*a
)
1019 switch (dfui_be_present_dialog(a
->c
, _("Select file system"),
1020 _("Use HAMMER2|Use HAMMER1|Use UFS|Return to Select Disk"),
1021 _("Please select the file system you want to use with %s.\n\n"
1022 "HAMMER2 is the recommended %s file system. "
1023 "HAMMER1 is the previous %s file system. "
1024 "UFS is the traditional BSD file system."),
1025 OPERATING_SYSTEM_NAME
,
1026 OPERATING_SYSTEM_NAME
,
1027 OPERATING_SYSTEM_NAME
))
1030 /* HAMMER2 (first menu item is the default) */
1041 state
= state_select_disk
;
1049 state
= state_create_subpartitions
;
1053 * state_format_disk: ask the user if they wish to format the disk they
1057 state_format_disk(struct i_fn_args
*a
)
1061 fn_format_disk_uefi(a
);
1063 state
= state_ask_fs
;
1065 state
= state_select_disk
;
1069 /* XXX Using part of the disk is only supported for MBR installs */
1070 switch (dfui_be_present_dialog(a
->c
, _("How Much Disk?"),
1071 _("Use Entire Disk|Use Part of Disk|Return to Select Disk"),
1072 _("Select how much of this disk you want to use for %s.\n\n%s"),
1073 OPERATING_SYSTEM_NAME
,
1074 disk_get_desc(storage_get_selected_disk(a
->s
)))) {
1077 if (measure_activated_swap_from_disk(a
, storage_get_selected_disk(a
->s
)) > 0) {
1078 if (swapoff_all(a
) == NULL
) {
1079 inform(a
->c
, _("Warning: swap could not be turned off."));
1080 state
= state_select_disk
;
1085 fn_format_disk_mbr(a
);
1087 state
= state_ask_fs
;
1089 state
= state_format_disk
;
1093 state
= state_select_slice
;
1097 state
= state_select_disk
;
1106 * state_select_slice: ask the user which slice they wish to install
1107 * DragonFly on. In order to avoid confusing them, refer to it as
1108 * a primary partition, but tell them what BSD has traditionally called
1112 state_select_slice(struct i_fn_args
*a
)
1114 char msg_buf
[1][1024];
1116 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
1117 _("Select the existing primary partition (also "
1118 "known as a `slice' in the BSD tradition) on "
1119 "which to install %s.\n\n"
1120 "Note that if you do not have any existing "
1121 "primary partitions on this disk, you must "
1122 "first create some. This installer does not "
1123 "currently have the ability to do this, so "
1124 "you will have to exit and run fdisk (in "
1125 "DOS or *BSD) or parted (in Linux) to do so."),
1126 OPERATING_SYSTEM_NAME
);
1128 a
->short_desc
= msg_buf
[0];
1129 a
->cancel_desc
= _("Return to Select Disk");
1131 if (!a
->result
|| storage_get_selected_slice(a
->s
) == NULL
) {
1132 state
= state_select_disk
;
1134 if (measure_activated_swap_from_slice(a
, storage_get_selected_disk(a
->s
),
1135 storage_get_selected_slice(a
->s
)) > 0) {
1136 if (swapoff_all(a
) == NULL
) {
1137 inform(a
->c
, _("Warning: swap could not be turned off."));
1138 state
= state_select_slice
;
1143 if (slice_get_capacity(storage_get_selected_slice(a
->s
)) < DISK_MIN
) {
1144 inform(a
->c
, _("WARNING: you should have a primary "
1145 "partition at least %dM in size, or "
1146 "you may encounter problems trying to "
1147 "install %s."), DISK_MIN
, OPERATING_SYSTEM_NAME
);
1150 if (confirm_dangerous_action(a
->c
,
1151 _("WARNING! ALL data in primary partition #%d,\n\n%s\n\non the "
1152 "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you "
1153 "ABSOLUTELY SURE you wish to take this action? This is "
1154 "your LAST CHANCE to cancel!"),
1155 slice_get_number(storage_get_selected_slice(a
->s
)),
1156 slice_get_desc(storage_get_selected_slice(a
->s
)),
1157 disk_get_desc(storage_get_selected_disk(a
->s
)))) {
1158 if (!format_slice(a
)) {
1159 inform(a
->c
, _("Primary partition #%d was "
1160 "not correctly formatted, and may "
1161 "now be in an inconsistent state. "
1162 "We recommend re-formatting it "
1163 "before proceeding."),
1164 slice_get_number(storage_get_selected_slice(a
->s
)));
1166 inform(a
->c
, _("Primary partition #%d was formatted."),
1167 slice_get_number(storage_get_selected_slice(a
->s
)));
1168 state
= state_ask_fs
;
1171 inform(a
->c
, _("Action cancelled - no primary partitions were formatted."));
1172 state
= state_select_slice
;
1178 * state_create_subpartitions: let the user specify what subpartitions they
1179 * want on the disk, how large each should be, and where it should be mounted.
1182 state_create_subpartitions(struct i_fn_args
*a
)
1184 struct commands
*cmds
;
1186 if (measure_activated_swap_from_slice(a
, storage_get_selected_disk(a
->s
),
1187 storage_get_selected_slice(a
->s
)) > 0) {
1188 if (swapoff_all(a
) == NULL
) {
1189 inform(a
->c
, _("Warning: swap could not be turned off."));
1190 state
= disk_get_formatted(storage_get_selected_disk(a
->s
)) ?
1191 state_select_disk
: state_select_slice
;
1196 cmds
= commands_new();
1199 * Auto-disklabel the slice.
1200 * NB: one cannot use "/dev/adXsY" here -
1201 * it must be in the form "adXsY".
1203 command_add(cmds
, "%s%s -W %s",
1204 a
->os_root
, cmd_name(a
, "DISKLABEL64"),
1205 slice_get_device_name(storage_get_selected_slice(a
->s
)));
1206 command_add(cmds
, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
1207 a
->os_root
, cmd_name(a
, "DD"),
1208 slice_get_device_name(storage_get_selected_slice(a
->s
)));
1209 command_add(cmds
, "%s%s -B -r -w %s",
1210 a
->os_root
, cmd_name(a
, "DISKLABEL64"),
1211 slice_get_device_name(storage_get_selected_slice(a
->s
)));
1212 commands_execute(a
, cmds
);
1213 commands_free(cmds
);
1216 * Create subpartitions and filesystems
1218 switch(use_hammer
) {
1220 fn_create_subpartitions_hammer(FS_HAMMER
, a
);
1223 fn_create_subpartitions_hammer(FS_HAMMER2
, a
);
1226 fn_create_subpartitions_ufs(a
);
1231 state
= state_install_os
;
1233 state
= disk_get_formatted(storage_get_selected_disk(a
->s
)) ?
1234 state_select_disk
: state_select_slice
;
1239 * state_install_os: actually put DragonFly on the disk.
1242 state_install_os(struct i_fn_args
*a
)
1244 struct dfui_form
*f
;
1245 struct dfui_response
*r
;
1246 char msg_buf
[1][1024];
1248 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
1249 _("Everything is now ready to install the actual files which "
1250 "comprise the %s operating system "
1251 "on the selected partition of the selected disk.\n\n"
1252 "Note that this process will take quite a while to finish. "
1253 "You may wish to take a break now and come back to the "
1254 "computer in a short while."),
1255 OPERATING_SYSTEM_NAME
);
1257 f
= dfui_form_create(
1264 "p", "role", "confirm",
1265 "p", "special", "dfinstaller_install_os",
1267 "a", "ok", _("Begin Installing Files"), "", "",
1268 "a", "cancel", _("Return to Create Subpartitions"), "", "",
1269 "p", "accelerator", "ESC",
1274 if (!dfui_be_present(a
->c
, f
, &r
))
1277 if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0) {
1278 state
= state_create_subpartitions
;
1283 state
= state_finish_install
;
1285 state
= state_install_bootstrap
;
1290 dfui_response_free(r
);
1294 * state_install_bootstrap: put boot0 bootblocks on selected disks.
1297 state_install_bootstrap(struct i_fn_args
*a
)
1299 char msg_buf
[1][1024];
1301 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
1302 _("You may now wish to install bootblocks on one or more disks. "
1303 "If you already have a boot manager installed, you can skip "
1304 "this step (but you may have to configure your boot manager "
1305 "separately.) If you installed %s on a disk other "
1306 "than your first disk, you will need to put the bootblock "
1307 "on at least your first disk and the %s disk."),
1308 OPERATING_SYSTEM_NAME
, OPERATING_SYSTEM_NAME
);
1310 a
->short_desc
= msg_buf
[0];
1311 a
->cancel_desc
= _("Skip this Step");
1312 fn_install_bootblocks(a
,
1313 disk_get_device_name(storage_get_selected_disk(a
->s
)));
1314 state
= state_finish_install
;
1318 * Finish up the install.
1321 state_finish_install(struct i_fn_args
*a
)
1323 char msg_buf
[1][1024];
1326 snprintf(msg_buf
[0], sizeof(msg_buf
[0]),
1328 OPERATING_SYSTEM_NAME
);
1330 switch (dfui_be_present_dialog(a
->c
, msg_buf
[0],
1331 _("Configure this System|Reboot|Return to Welcome Menu"),
1332 _("Congratulations!\n\n"
1333 "%s has successfully been installed on "
1334 "this computer. You may now proceed to configure "
1335 "the installation. Alternately, you may wish to "
1336 "reboot the computer and boot into the installed "
1337 "system to confirm that it works."),
1338 OPERATING_SYSTEM_NAME
)) {
1340 state
= state_configure_menu
;
1343 state
= state_reboot
;
1346 state
= state_welcome
;
1354 * state_reboot: reboot the machine.
1357 state_reboot(struct i_fn_args
*a
)
1359 struct dfui_form
*f
;
1360 struct dfui_response
*r
;
1362 f
= dfui_form_create(
1365 _("This machine is about to be shut down. "
1366 "After the machine has reached its shutdown state, "
1367 "you may remove the CD from the CD-ROM drive tray "
1368 "and press Enter to reboot from the HDD."),
1372 "p", "role", "confirm",
1374 "a", "ok", _("Reboot"), "", "",
1375 "a", "cancel", _("Return to Welcome Menu"), "", "",
1376 "p", "accelerator", "ESC",
1380 if (!dfui_be_present(a
->c
, f
, &r
))
1383 if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0) {
1384 state
= state_welcome
;
1391 dfui_response_free(r
);
1396 * state_setup_remote_installation_server:
1397 * Setup a remote boot installation environment where a machine
1398 * can boot via DHCP/TFTP/NFS and have a running environment
1399 * where the installer can setup the machine.
1403 state_setup_remote_installation_server(struct i_fn_args
*a
)
1406 struct commands
*cmds
;
1407 struct dfui_form
*f
;
1408 struct dfui_action
*k
;
1409 struct dfui_response
*r
;
1411 char interface
[256];
1414 switch (dfui_be_present_dialog(a
->c
, _("Enable Netboot Installation Services?"),
1415 _("Enable NetBoot Installation Services|No thanks"),
1416 _("NetBoot Installation Services allows this machine to become "
1417 "a Installation Server that will allow the clients to boot over the network "
1418 "via PXE and start the Installation Environment."
1419 "\n\n*NOTE!* This will assign the IP Address of 10.1.0.1/24 to the selected interface."
1420 "\n\nWould you like to provision this machine to serve up the LiveCD/Installer?"))) {
1423 * Get interface list.
1425 p
= popen("/sbin/ifconfig -l", "r");
1426 /* XXX it's possible (though extremely unlikely) this will fail. */
1427 while (fgets(line
, 255, p
) != NULL
)
1428 line
[strlen(line
) - 1] = '\0';
1431 f
= dfui_form_create(
1433 _("Setup NetBoot Installation Environment"),
1434 _("Please select which interface you would like to configure:"),
1436 "p", "role", "menu",
1440 /* Loop through array. */
1441 word
= strtok(line
, " \t");
1442 while (word
!= NULL
) {
1443 dfui_form_action_add(f
, word
,
1444 dfui_info_new(word
, "", ""));
1445 word
= strtok(NULL
, " ");
1448 k
= dfui_form_action_add(f
, "cancel",
1449 dfui_info_new("Cancel", "", ""));
1450 dfui_action_property_set(k
, "accelerator", "ESC");
1452 if (!dfui_be_present(a
->c
, f
, &r
))
1455 strlcpy(interface
, dfui_response_get_action_id(r
), 256);
1457 if (strcmp(dfui_response_get_action_id(r
), "cancel") == 0) {
1459 dfui_response_free(r
);
1465 * Issues the necessary commands to setup the remote boot environment
1468 cmds
= commands_new();
1469 command_add(cmds
, "%s%s %s 10.1.0.1 netmask 255.255.255.0",
1470 a
->os_root
, cmd_name(a
, "IFCONFIG"), interface
);
1471 command_add(cmds
, "%s%s -p %stftpdroot",
1472 a
->os_root
, cmd_name(a
, "MKDIR"), a
->tmp
);
1473 command_add(cmds
, "%s%s %sboot/pxeboot %stftpdroot",
1474 a
->os_root
, cmd_name(a
, "CP"), a
->os_root
, a
->tmp
);
1475 command_add(cmds
, "%s%s %s -ro -alldirs -maproot=root: -network 10.1.0.0 -mask 255.255.255.0 >> %setc/exports",
1476 a
->os_root
, cmd_name(a
, "ECHO"), a
->os_root
, a
->os_root
);
1477 command_add(cmds
, "%s%s tftp dgram udp wait root %s%s tftpd -l -s %stftpdroot >> %setc/inetd.conf",
1478 a
->os_root
, cmd_name(a
, "ECHO"),
1479 a
->os_root
, cmd_name(a
, "TFTPD"),
1480 a
->tmp
, a
->os_root
);
1481 command_add(cmds
, "%s%s",
1482 a
->os_root
, cmd_name(a
, "INETD"));
1483 command_add(cmds
, "%s%s %svar/db/dhcpd.leases",
1484 a
->os_root
, cmd_name(a
, "TOUCH"), a
->os_root
);
1485 command_add(cmds
, "%s%s -cf /etc/dhcpd.conf >/dev/null 2>&1",
1486 a
->os_root
, cmd_name(a
, "DHCPD"));
1487 command_add(cmds
, "%s%s >/dev/null 2>&1",
1488 a
->os_root
, cmd_name(a
, "RPCBIND"));
1489 command_add(cmds
, "%s%s -ln >/dev/null 2>&1",
1490 a
->os_root
, cmd_name(a
, "MOUNTD"));
1491 command_add(cmds
, "%s%s -u -t -n 6 >/dev/null 2>&1",
1492 a
->os_root
, cmd_name(a
, "NFSD"));
1494 if (commands_execute(a
, cmds
)) {
1495 inform(a
->c
, _("NetBoot installation services are now started."));
1497 inform(a
->c
, _("A failure occurred while provisioning the NetBoot environment. Please check the logs."));
1500 commands_free(cmds
);
1502 dfui_response_free(r
);
1511 state
= state_welcome
;
1518 flow(int transport
, char *rendezvous
, char *os_root
,
1521 struct i_fn_args
*a
;
1523 rc_conf
= config_vars_new();
1525 if ((a
= i_fn_args_new(os_root
, DEFAULT_INSTALLER_TEMP
,
1526 DEFAULT_CMDNAMES_FILE
, transport
,
1527 rendezvous
)) == NULL
) {
1532 * XXX We can't handle this yet.
1534 a->flags |= I_BOOTED_LIVECD;
1535 a->flags |= I_UPGRADE_TOOGLE;
1537 a
->flags
|= I_BOOTED_LIVECD
;
1540 * Execute the state machine here. The global function pointer
1541 * variable `state' points to the next state_* function to execute.
1542 * Before it exits, this function should set `state' to the next
1543 * state to make a transition to, or NULL to indicate that the
1544 * state machine is finished.
1547 state
= state_lang_menu
;
1549 state
= state_welcome
;
1551 for (; state
!= NULL
; )
1554 config_vars_free(rc_conf
);