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