nrelease - fix/improve livecd
[dragonfly.git] / usr.sbin / installer / dfuibe_installer / flow.c
CommitLineData
337ad0df
DH
1/*
2 * Copyright (c)2004 The DragonFly Project. All rights reserved.
21c1c48a 3 *
337ad0df
DH
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
21c1c48a 7 *
337ad0df
DH
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
21c1c48a 10 *
337ad0df
DH
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.
21c1c48a 15 *
337ad0df
DH
16 * Neither the name of the DragonFly Project nor the names of its
17 * contributors may be used to endorse or promote products derived
21c1c48a
SW
18 * from this software without specific prior written permission.
19 *
337ad0df
DH
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
21c1c48a 31 * OF THE POSSIBILITY OF SUCH DAMAGE.
337ad0df
DH
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>
a07abcb9 43#include <unistd.h>
337ad0df
DH
44#include <string.h>
45
46#ifdef ENABLE_NLS
47#include <libintl.h>
48#include <locale.h>
bc3d4063 49#include "libdfui/lang.h"
337ad0df
DH
50#define _(String) gettext (String)
51extern int _nl_msg_cat_cntr;
52#else
53#define _(String) (String)
54#endif
55
bc3d4063
SW
56#include "libaura/mem.h"
57#include "libaura/dict.h"
58#include "libaura/fspred.h"
337ad0df 59
bc3d4063 60#include "libdfui/dfui.h"
337ad0df 61#ifdef DEBUG
bc3d4063 62#include "libdfui/dump.h"
337ad0df 63#endif
bc3d4063 64#include "libdfui/system.h"
337ad0df 65
bc3d4063
SW
66#include "libinstaller/commands.h"
67#include "libinstaller/confed.h"
68#include "libinstaller/diskutil.h"
69#include "libinstaller/functions.h"
bc3d4063 70#include "libinstaller/uiutil.h"
337ad0df
DH
71
72#include "flow.h"
73#include "fn.h"
74#include "pathnames.h"
75
76/*** GLOBALS ***/
77
78void (*state)(struct i_fn_args *) = NULL;
79int do_reboot;
14825f9d
SW
80int use_hammer; /* 0=UFS 1=HAMMER 2=HAMMER2 */
81int use_uefi;
82int during_install;
337ad0df
DH
83
84/*** STATES ***/
85
86/*
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.)
94 *
95 * Installer States:
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
106 */
107
108#ifdef ENABLE_NLS
21c1c48a 109void
337ad0df
DH
110state_lang_menu(struct i_fn_args *a)
111{
112 struct dfui_form *f;
113 struct dfui_response *r;
114 int done = 0;
115 char *id;
116 int cancelled = 0;
117
118 while (!done) {
119 f = dfui_form_create(
120 "main_menu",
121 _("Select Language"),
122 _("Please select the language you wish you use."),
123 "",
124
125 "p", "role", "menu",
126
f4fbc037
MD
127 "a", "default", "English",
128 "English Standard Default", "",
337ad0df
DH
129 "a", "ru", "Russian",
130 "Russian KOI8-R", "",
131 NULL
132 );
133
134 if (!dfui_be_present(a->c, f, &r))
135 abort_backend();
136
137 id = aura_strdup(dfui_response_get_action_id(r));
138
139 if (strcmp(id, "default") == 0) {
140 state = state_welcome;
141 return;
142 } else {
143 state = state_welcome;
144 done = 1;
145 }
146
147 dfui_form_free(f);
148 dfui_response_free(r);
149 }
150
151 /* set keymap, scrnmap, fonts */
152 if (!set_lang_syscons(id))
153 return;
154
155 /* set envars */
156 if (!set_lang_envars(id))
157 return;
158
159 dfui_be_set_global_setting(a->c, "lang", id, &cancelled);
160
161 /* XXX if (!cancelled) ... ? */
162
163 /* let gettext know about changes */
164 ++_nl_msg_cat_cntr;
165}
166#endif
167
168/*
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.
172 */
173void
174state_welcome(struct i_fn_args *a)
175{
176 struct dfui_form *f;
337ad0df
DH
177 struct dfui_response *r;
178 char msg_buf[2][1024];
179
180 snprintf(msg_buf[0], sizeof(msg_buf[0]),
181 _("Welcome to %s"), OPERATING_SYSTEM_NAME);
182
183 snprintf(msg_buf[1], sizeof(msg_buf[1]),
184 _("Welcome to the %s Live CD."
21c1c48a 185 "\n\n"
337ad0df
DH
186 "%s is an efficient and elegant BSD "
187 "Unix-derived operating system. For more information, see %s"
188 "\n\n"
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."
194 "\n\n"
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."
198 ""),
199 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_URL,
200 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
201
c4d6eff4 202 if ((a->flags & I_BOOTED_LIVECD) == 0) {
337ad0df
DH
203 state = state_welcome_system;
204 return;
205 }
206
207 f = dfui_form_create(
208 "welcome",
209 msg_buf[0],
210
211 msg_buf[1],
212
213 "",
214
215 "p", "special", "dfinstaller_welcome",
216
217 NULL
218 );
219
c4d6eff4 220 if (a->flags & I_UPGRADE_TOOGLE) {
337ad0df
DH
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"),
226 msg_buf[0], ""));
227 } else {
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],
235 msg_buf[1], ""));
236 }
237
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"),
243 msg_buf[0], ""));
244
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"), ""));
248
666e46d7 249 dfui_form_action_add(f, "exit",
337ad0df
DH
250 dfui_info_new(_("Exit to Live CD"),
251 _("Exit this program to a login prompt with access to the LiveCD"), ""));
252
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)"), ""));
256
257 dfui_form_action_add(f, "configure_netboot",
258 dfui_info_new(_("Setup NetBoot Install Services"),
259 _("Setup machine as remote installation server"), ""));
260
261 if (!dfui_be_present(a->c, f, &r))
262 abort_backend();
263
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) {
275 state = NULL;
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;
280 }
281
282 dfui_form_free(f);
283 dfui_response_free(r);
284}
285
286/*
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
289 * system.
290 */
291void
292state_welcome_system(struct i_fn_args *a)
293{
294 struct dfui_form *f;
295 struct dfui_response *r;
296 char msg_buf[2][1024];
297
298 snprintf(msg_buf[0], sizeof(msg_buf[0]),
299 _("Configure this %s System"), OPERATING_SYSTEM_NAME);
21c1c48a 300
337ad0df
DH
301 snprintf(msg_buf[1], sizeof(msg_buf[1]),
302 _("Thank you for choosing %s."
303 "\n\n"
304 "For up-to-date news and information on %s, "
305 "make sure to check out"
306 "\n\n"
21c1c48a 307 "%s"
337ad0df
DH
308 "\n\n"
309 "You can use this automated application to assist "
310 "you in setting up this %s system."
311 ""),
312 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME,
313 OPERATING_SYSTEM_URL, OPERATING_SYSTEM_NAME);
314
315
316 f = dfui_form_create(
317 "welcome",
318 msg_buf[0],
319
320 msg_buf[1],
321
322 "",
323
324 "p", "special", "dfinstaller_welcome",
325
326 NULL
327 );
328
329 snprintf(msg_buf[0], sizeof(msg_buf[0]),
330 _("Configure this %s system"), OPERATING_SYSTEM_NAME);
331
332 dfui_form_action_add(f, "environment",
333 dfui_info_new(_("Configure this System"),
334 msg_buf[0], ""));
335
21c1c48a 336 dfui_form_action_add(f, "utilities",
337ad0df
DH
337 dfui_info_new(_("Utilities"),
338 _("Utilities to work with and diagnose disks and other subsystems"), ""));
339
340 dfui_form_action_add(f, "exit",
341 dfui_info_new(_("Exit Installer"),
342 _("Exit this program and return to the system"), ""));
343
344 if (!dfui_be_present(a->c, f, &r))
345 abort_backend();
346
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) {
352 state = NULL;
353 } else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0) {
354 state = state_reboot;
355 }
356
357 dfui_form_free(f);
358 dfui_response_free(r);
359}
360
361void
362state_configure_menu(struct i_fn_args *a)
363{
364 struct dfui_form *f = NULL;
365 struct dfui_response *r = NULL;
366 struct commands *cmds;
367 int done = 0;
368 char msg_buf[2][1024];
369
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."));
374 }
375
376 a->short_desc = _("Select the disk containing the installation.");
377 a->cancel_desc = _("Return to Welcome Menu");
378 fn_select_disk(a);
379 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
380 state = state_welcome;
381 return;
382 }
383
384 a->short_desc = _("Select the primary partition containing the installation.");
385 a->cancel_desc = _("Return to Welcome Menu");
386 fn_select_slice(a);
387
388 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
389 state = state_welcome;
390 return;
391 }
392 }
393
394 a->cfg_root = "mnt";
de58c8bc
MS
395
396 if (during_install == 0) {
397 switch (dfui_be_present_dialog(a->c, _("Select file system"),
a4911276 398 _("HAMMER2|HAMMER1|UFS|Return to Welcome Menu"),
de58c8bc
MS
399 _("Please select the file system installed on the disk.\n\n")))
400 {
401 case 1:
344ec808 402 /* HAMMER2 (first menu item is the default) */
e90c1ebb
MD
403 use_hammer = 2;
404 break;
a4911276
MD
405 case 2:
406 /* HAMMER1 */
407 use_hammer = 1;
408 break;
e90c1ebb 409 case 3:
de58c8bc
MS
410 /* UFS */
411 use_hammer = 0;
412 break;
e90c1ebb 413 case 4:
de58c8bc
MS
414 state = state_welcome;
415 return;
416 /* NOTREACHED */
417 break;
418 default:
419 abort_backend();
420 break;
421 }
422 }
423
337ad0df
DH
424 if (!mount_target_system(a)) {
425 inform(a->c, _("Target system could not be mounted."));
426 state = state_welcome;
427 return;
428 }
429
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);
434
435 while (!done) {
436 f = dfui_form_create(
437 "configure_menu",
438 _("Configure an Installed System"),
439 msg_buf[0],
440 "",
441 "p", "role", "menu",
442
443 "a", "set_timezone",
444 _("Select timezone"),
445 _("Set the Time Zone of your physical location"), "",
446 "a", "set_datetime",
447 _("Set date and time"),
448 _("Set the Time and Date of your machine"), "",
449
38e23cc2
SW
450 "a", "set_kbdmap",
451 _("Set keyboard map"),
452 _("Set what kind of keyboard layout you have"), "",
337ad0df
DH
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"), "",
337ad0df
DH
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"), "",
462 /*
463 "a", "select_services", "Select Services",
464 "Enable/Disable system services (servers, daemons, etc.)", "",
465 */
337ad0df
DH
466 "a", "set_vidfont",
467 _("Set console font"),
468 _("Set how the characters on your video console look"), "",
469 "a", "set_scrnmap",
470 _("Set screen map"),
471 _("Set how characters are translated before console display"), "",
337ad0df
DH
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);
337ad0df
DH
488 } else if (strcmp(dfui_response_get_action_id(r), "assign_ip") == 0) {
489 fn_assign_ip(a);
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) {
495 fn_set_kbdmap(a);
496 } else if (strcmp(dfui_response_get_action_id(r), "set_vidfont") == 0) {
497 fn_set_vidfont(a);
498 } else if (strcmp(dfui_response_get_action_id(r), "set_scrnmap") == 0) {
499 fn_set_scrnmap(a);
500 } else if (strcmp(dfui_response_get_action_id(r), "set_timezone") == 0) {
501 fn_set_timezone(a);
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;
506 done = 1;
507 }
508
509 dfui_form_free(f);
510 dfui_response_free(r);
511 }
512
513 /*
514 * Before unmounting the system, write out any changes to rc.conf.
515 */
516 config_vars_write(rc_conf, CONFIG_TYPE_SH,
517 "%s%setc/rc.conf", a->os_root, a->cfg_root);
518
519 /*
520 * Clear out configuration variable table in memory.
521 */
522 config_vars_free(rc_conf);
523 rc_conf = config_vars_new();
524
525 /*
fa419eae 526 * Finally, unmount the system we mounted on /mnt and remove mappings.
337ad0df
DH
527 */
528 cmds = commands_new();
529 unmount_all_under(a, cmds, "%smnt", a->os_root);
530 commands_execute(a, cmds);
531 commands_free(cmds);
fa419eae
SW
532
533 if (remove_all_mappings(a) == NULL)
534 inform(a->c, _("Warning: mappings could not be removed."));
337ad0df
DH
535}
536
21c1c48a 537void
337ad0df
DH
538state_utilities_menu(struct i_fn_args *a)
539{
540 struct dfui_form *f;
541 struct dfui_response *r;
542
543 if (!survey_storage(a)) {
544 inform(a->c, _("Errors occurred while probing "
545 "the system for its storage capabilities."));
546 }
547
548 f = dfui_form_create(
549 "utilities_menu",
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."),
555 "",
556 "p", "role", "menu",
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"), "",
565 "a", "reboot",
566 _("Reboot this Computer"), "", "",
567 "a", "cancel",
568 _("Return to Welcome Menu"), "", "",
569 "p", "accelerator", "ESC",
570 NULL
571 );
572
573 if (!dfui_be_present(a->c, f, &r))
574 abort_backend();
575
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)
583 state = NULL;
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;
588
589 dfui_form_free(f);
590 dfui_response_free(r);
591}
592
21c1c48a 593void
337ad0df
DH
594state_environment_menu(struct i_fn_args *a)
595{
596 struct dfui_form *f;
597 struct dfui_response *r;
598 int done = 0;
599 char msg_buf[2][1024];
600
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);
611
612 while (!done) {
613 f = dfui_form_create(
614 "environment_menu",
615 _("Live CD Environment Menu"),
616 msg_buf[0],
617 "",
618 "p", "role", "menu",
619
620 "a", "set_timezone",
621 _("Select timezone"),
622 _("Set the Time Zone of your physical location"), "",
623 "a", "set_datetime",
624 _("Set date and time"),
625 _("Set the Time and Date of your machine"), "",
626
627 "a", "set_kbdmap",
628 _("Set keyboard map"),
629 _("Set what kind of keyboard layout you have"), "",
630 "a", "set_vidfont",
631 _("Set console font"),
632 _("Set how the characters on your video console look"), "",
633 "a", "set_scrnmap",
634 _("Set screen map"),
635 _("Set how characters are translated before console display"), "",
636
637 "a", "assign_hostname_domain",
638 _("Configure hostname and domain"),
639 _("Configure the hostname and domain for this system"), "",
640 "a", "assign_ip",
641 _("Configure network interfaces"),
642 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "",
643
644 "a", "cancel",
645 _("Return to Utilities Menu"), "", "",
646 "p", "accelerator", "ESC",
647
648 NULL
649 );
650
651 if (!dfui_be_present(a->c, f, &r))
652 abort_backend();
653
654 /* Set up a */
655 a->cfg_root = "";
656 if (strcmp(dfui_response_get_action_id(r), "set_kbdmap") == 0) {
657 fn_set_kbdmap(a);
658 } else if (strcmp(dfui_response_get_action_id(r), "set_vidfont") == 0) {
659 fn_set_vidfont(a);
660 } else if (strcmp(dfui_response_get_action_id(r), "set_scrnmap") == 0) {
661 fn_set_scrnmap(a);
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) {
665 fn_assign_ip(a);
666 } else if (strcmp(dfui_response_get_action_id(r), "set_timezone") == 0) {
667 fn_set_timezone(a);
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;
672 done = 1;
673 }
674
675 dfui_form_free(f);
676 dfui_response_free(r);
677 }
678}
679
21c1c48a 680void
337ad0df
DH
681state_diagnostics_menu(struct i_fn_args *a)
682{
683 struct dfui_form *f;
684 struct dfui_action *k;
685 struct dfui_response *r;
686 int done = 0;
687
688 while (!done) {
689 f = dfui_form_create(
690 "utilities_menu",
691 _("Live CD Diagnostics Menu"),
692 _("These functions can help you diagnose this system."),
693 "",
694 "p", "role", "menu",
21c1c48a 695
337ad0df
DH
696 "a", "show_dmesg",
697 _("Display system startup messages"),
698 _("Display system startup messages (dmesg)"), "",
699 "a", "pciconf",
700 _("Display PCI devices"),
701 _("Display PCI devices (pciconf)"), "",
04bf803f 702 "a", "natacontrol",
337ad0df 703 _("Display ATA devices"),
04bf803f 704 _("Display ATA devices (natacontrol)"), "",
337ad0df
DH
705 NULL
706 );
707
337ad0df
DH
708 k = dfui_form_action_add(f, "cancel",
709 dfui_info_new(_("Return to Utilities Menu"), "", ""));
710 dfui_action_property_set(k, "accelerator", "ESC");
711
712 if (!dfui_be_present(a->c, f, &r))
713 abort_backend();
714
715 /* XXX set up a */
716 if (strcmp(dfui_response_get_action_id(r), "show_dmesg") == 0) {
717 fn_show_dmesg(a);
718 } else if (strcmp(dfui_response_get_action_id(r), "pciconf") == 0) {
719 fn_show_pciconf(a);
04bf803f
TN
720 } else if (strcmp(dfui_response_get_action_id(r), "natacontrol") == 0) {
721 fn_show_natacontrol(a);
337ad0df
DH
722 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
723 state = state_utilities_menu;
724 done = 1;
725 }
726
727 dfui_form_free(f);
728 dfui_response_free(r);
729 }
730}
731
21c1c48a 732void
337ad0df
DH
733state_diskutil_menu(struct i_fn_args *a)
734{
735 struct dfui_form *f;
736 struct dfui_action *k;
737 struct dfui_response *r;
738 int done = 0;
739
740 while (!done) {
741 f = dfui_form_create(
742 "utilities_menu",
743 _("Disk Utilities Menu"),
744 _("These functions let you manipulate the storage devices "
745 "attached to this computer."),
746 "",
747
748 "p", "role", "menu",
749
750 "a", "format_hdd",
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"), "", "",
760 NULL
761 );
762
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"),
766 "",
767 ""));
768 }
769
770 k = dfui_form_action_add(f, "cancel",
771 dfui_info_new(_("Return to Utilities Menu"), "", ""));
772 dfui_action_property_set(k, "accelerator", "ESC");
773
774 if (!dfui_be_present(a->c, f, &r))
775 abort_backend();
776
777 /* XXX set up a */
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);
7b1aa074
SW
781 if (use_uefi)
782 fn_format_disk_uefi(a);
783 else
784 fn_format_disk_mbr(a);
337ad0df
DH
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");
e75c9034 793 fn_install_bootblocks(a, NULL);
337ad0df
DH
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;
800 done = 1;
801 }
802
803 dfui_form_free(f);
804 dfui_response_free(r);
805 }
806}
807
808/** INSTALLER STATES **/
809
810/*
811 * state_begin_upgrade: Ask the user where the freebsd
812 * 4.X install is and make sure its safe to proceed.
813 *
814 */
21c1c48a 815void
337ad0df
DH
816state_begin_upgrade(struct i_fn_args *a)
817{
818 //struct dfui_form *f = NULL;
819 //struct dfui_response *r = NULL;
820 //int done = 0;
821
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."));
826 }
827
828 a->short_desc = _("Select the disk containing the installation that you would like to upgrade.");
829 a->cancel_desc = _("Return to Welcome Menu");
830 fn_select_disk(a);
831 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
832 state = state_welcome;
833 return;
834 }
835
836 a->short_desc = _("Select the primary partition containing the installation you would like to upgrade.");
837 a->cancel_desc = _("Return to Welcome Menu");
838 fn_select_slice(a);
839
840 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
841 state = state_welcome;
842 return;
843 }
844 }
845
846 a->cfg_root = "mnt";
847 if (!mount_target_system(a)) {
848 inform(a->c, _("Target system could not be mounted."));
849 state = state_welcome;
850 return;
851 }
852}
853
854/*
855 * state_begin_install: Briefly describe the install process
856 * to the user, and let them proceed (or not.)
857 */
858void
859state_begin_install(struct i_fn_args *a)
860{
861 struct dfui_form *f;
862 struct dfui_response *r;
863 char msg_buf[3][1024];
864
865 snprintf(msg_buf[0], sizeof(msg_buf[0]),
32b7c413 866 _("This application will install %s"
337ad0df
DH
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 ."
875 "\n\n"
876 "NOTE! As with any installation process, YOU ARE "
877 "STRONGLY ENCOURAGED TO BACK UP ANY IMPORTANT DATA ON THIS "
878 "COMPUTER BEFORE PROCEEDING!"
879 ""),
880 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME,
881 OPERATING_SYSTEM_NAME);
882
883 snprintf(msg_buf[1], sizeof(msg_buf[1]),
884 _("Some situations in which you might not wish to use this "
885 "installer are:\n\n"
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."
891 ""),
892 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
893
894 snprintf(msg_buf[2], sizeof(msg_buf[2]),
895 _("Install %s"), OPERATING_SYSTEM_NAME);
896
897 f = dfui_form_create(
898 "begin_install",
899 _("Begin Installation"),
900 msg_buf[0],
901
902 msg_buf[1],
903 "p", "special", "dfinstaller_begin_install",
904 "p", "minimum_width", "76",
905
906 "a", "proceed", msg_buf[2],
907 "", "",
908 "a", "cancel", _("Return to Welcome Menu"),
909 "", "",
910 "p", "accelerator", "ESC",
911 "a", "livecd", _("Exit to Live CD"),
912 "", "",
913 NULL
914 );
915
916 if (!dfui_be_present(a->c, f, &r))
917 abort_backend();
918
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."));
923 }
7b1aa074 924 state = state_ask_uefi;
337ad0df
DH
925 } else if (strcmp(dfui_response_get_action_id(r), "livecd") == 0) {
926 state = NULL;
927 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
928 state = state_welcome;
929 }
930
931 dfui_form_free(f);
932 dfui_response_free(r);
933}
934
7b1aa074
SW
935/*
936 * state_ask_uefi: ask the user if they want a UEFI installation
937 */
938void
939state_ask_uefi(struct i_fn_args *a)
940{
941 use_uefi = 0;
942
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))
947 {
948 case 1:
949 /* UEFI */
950 use_uefi = 1;
951 break;
952 case 2:
953 /* MBR */
954 break;
955 case 3:
956 state = state_begin_install;
957 return;
958 /* NOTREACHED */
959 break;
960 default:
961 abort_backend();
962 break;
963 }
964 state = state_select_disk;
965}
966
337ad0df
DH
967/*
968 * state_select_disk: ask the user on which physical disk they wish
969 * to install DragonFly.
970 */
971void
972state_select_disk(struct i_fn_args *a)
973{
974 struct disk *d;
975 int num_disks = 0;
976 char msg_buf[1][1024];
977
978 for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d))
979 num_disks++;
980
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;
990 return;
991 }
992
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");
998 fn_select_disk(a);
999 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
1000 state = state_begin_install;
1001 } else {
1002#if 0
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);
1008 }
1009#endif
1010 state = state_format_disk;
1011 }
1012}
1013
971d1cca
MS
1014void
1015state_ask_fs(struct i_fn_args *a)
1016{
1017 use_hammer = 0;
1018
1019 switch (dfui_be_present_dialog(a->c, _("Select file system"),
a4911276 1020 _("Use HAMMER2|Use HAMMER1|Use UFS|Return to Select Disk"),
dcea93a0 1021 _("Please select the file system you want to use with %s.\n\n"
a4911276
MD
1022 "HAMMER2 is the recommended %s file system. "
1023 "HAMMER1 is the previous %s file system. "
e90c1ebb
MD
1024 "UFS is the traditional BSD file system."),
1025 OPERATING_SYSTEM_NAME,
971d1cca
MS
1026 OPERATING_SYSTEM_NAME,
1027 OPERATING_SYSTEM_NAME))
1028 {
1029 case 1:
344ec808 1030 /* HAMMER2 (first menu item is the default) */
a4911276 1031 use_hammer = 2;
971d1cca
MS
1032 break;
1033 case 2:
344ec808 1034 /* HAMMER1 */
a4911276 1035 use_hammer = 1;
971d1cca
MS
1036 break;
1037 case 3:
e90c1ebb
MD
1038 /* UFS */
1039 break;
1040 case 4:
971d1cca
MS
1041 state = state_select_disk;
1042 return;
1043 /* NOTREACHED */
1044 break;
1045 default:
1046 abort_backend();
1047 break;
1048 }
1049 state = state_create_subpartitions;
1050}
1051
337ad0df
DH
1052/*
1053 * state_format_disk: ask the user if they wish to format the disk they
1054 * selected.
1055 */
1056void
1057state_format_disk(struct i_fn_args *a)
1058{
7b1aa074
SW
1059
1060 if (use_uefi) {
1061 fn_format_disk_uefi(a);
1062 if (a->result)
1063 state = state_ask_fs;
1064 else
d6f87aaf 1065 state = state_select_disk;
7b1aa074
SW
1066 return;
1067 }
1068
1069 /* XXX Using part of the disk is only supported for MBR installs */
337ad0df
DH
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)))) {
1075 case 1:
1076 /* Entire Disk */
1077 if (measure_activated_swap_from_disk(a, storage_get_selected_disk(a->s)) > 0) {
9687cd27
SW
1078 if (swapoff_all(a) == NULL) {
1079 inform(a->c, _("Warning: swap could not be turned off."));
337ad0df
DH
1080 state = state_select_disk;
1081 return;
337ad0df
DH
1082 }
1083 }
1084
7b1aa074 1085 fn_format_disk_mbr(a);
337ad0df 1086 if (a->result)
971d1cca 1087 state = state_ask_fs;
337ad0df
DH
1088 else
1089 state = state_format_disk;
1090 break;
1091 case 2:
1092 /* Part of Disk */
1093 state = state_select_slice;
1094 break;
1095 case 3:
1096 /* Return */
1097 state = state_select_disk;
1098 break;
1099 default:
1100 abort_backend();
1101 break;
1102 }
1103}
1104
1105/*
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
1109 * it, too.
1110 */
1111void
1112state_select_slice(struct i_fn_args *a)
1113{
1114 char msg_buf[1][1024];
1115
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);
21c1c48a 1127
337ad0df
DH
1128 a->short_desc = msg_buf[0];
1129 a->cancel_desc = _("Return to Select Disk");
1130 fn_select_slice(a);
1131 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
1132 state = state_select_disk;
1133 } else {
1134 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s),
1135 storage_get_selected_slice(a->s)) > 0) {
9687cd27
SW
1136 if (swapoff_all(a) == NULL) {
1137 inform(a->c, _("Warning: swap could not be turned off."));
337ad0df
DH
1138 state = state_select_slice;
1139 return;
337ad0df
DH
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)));
971d1cca 1168 state = state_ask_fs;
337ad0df
DH
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 */
1181void
1182state_create_subpartitions(struct i_fn_args *a)
1183{
a2f6293f 1184 struct commands *cmds;
337ad0df
DH
1185
1186 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s),
1187 storage_get_selected_slice(a->s)) > 0) {
9687cd27
SW
1188 if (swapoff_all(a) == NULL) {
1189 inform(a->c, _("Warning: swap could not be turned off."));
337ad0df
DH
1190 state = disk_get_formatted(storage_get_selected_disk(a->s)) ?
1191 state_select_disk : state_select_slice;
1192 return;
337ad0df
DH
1193 }
1194 }
1195
a2f6293f
SW
1196 cmds = commands_new();
1197
1198 /*
1199 * Auto-disklabel the slice.
1200 * NB: one cannot use "/dev/adXsY" here -
1201 * it must be in the form "adXsY".
1202 */
1203 command_add(cmds, "%s%s -W %s",
1204 a->os_root, cmd_name(a, "DISKLABEL64"),
f59b7dfa 1205 slice_get_device_name(storage_get_selected_slice(a->s)));
a2f6293f
SW
1206 command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
1207 a->os_root, cmd_name(a, "DD"),
f59b7dfa 1208 slice_get_device_name(storage_get_selected_slice(a->s)));
0a319615 1209 command_add(cmds, "%s%s -B -r -w %s",
a2f6293f 1210 a->os_root, cmd_name(a, "DISKLABEL64"),
f59b7dfa 1211 slice_get_device_name(storage_get_selected_slice(a->s)));
a2f6293f
SW
1212 commands_execute(a, cmds);
1213 commands_free(cmds);
1214
a07abcb9
MD
1215 /*
1216 * Create subpartitions and filesystems
1217 */
e90c1ebb
MD
1218 switch(use_hammer) {
1219 case 1:
1220 fn_create_subpartitions_hammer(FS_HAMMER, a);
1221 break;
1222 case 2:
1223 fn_create_subpartitions_hammer(FS_HAMMER2, a);
1224 break;
1225 default:
a2f6293f 1226 fn_create_subpartitions_ufs(a);
e90c1ebb
MD
1227 break;
1228 }
a2f6293f 1229
337ad0df
DH
1230 if (a->result) {
1231 state = state_install_os;
1232 } else {
1233 state = disk_get_formatted(storage_get_selected_disk(a->s)) ?
1234 state_select_disk : state_select_slice;
1235 }
1236}
1237
1238/*
1239 * state_install_os: actually put DragonFly on the disk.
1240 */
1241void
1242state_install_os(struct i_fn_args *a)
1243{
1244 struct dfui_form *f;
1245 struct dfui_response *r;
1246 char msg_buf[1][1024];
1247
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);
1256
1257 f = dfui_form_create(
1258 "install_os",
1259 _("Install OS"),
1260 msg_buf[0],
1261
1262 "",
1263
1264 "p", "role", "confirm",
1265 "p", "special", "dfinstaller_install_os",
1266
1267 "a", "ok", _("Begin Installing Files"), "", "",
1268 "a", "cancel", _("Return to Create Subpartitions"), "", "",
1269 "p", "accelerator", "ESC",
1270
1271 NULL
1272 );
1273
1274 if (!dfui_be_present(a->c, f, &r))
1275 abort_backend();
1276
1277 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1278 state = state_create_subpartitions;
1279 } else {
1280 fn_install_os(a);
7b1aa074
SW
1281 if (a->result) {
1282 if (use_uefi)
1283 state = state_finish_install;
1284 else
1285 state = state_install_bootstrap;
1286 }
337ad0df
DH
1287 }
1288
1289 dfui_form_free(f);
1290 dfui_response_free(r);
1291}
1292
1293/*
1294 * state_install_bootstrap: put boot0 bootblocks on selected disks.
1295 */
1296void
1297state_install_bootstrap(struct i_fn_args *a)
1298{
1299 char msg_buf[1][1024];
1300
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);
1309
1310 a->short_desc = msg_buf[0];
1311 a->cancel_desc = _("Skip this Step");
e75c9034
SW
1312 fn_install_bootblocks(a,
1313 disk_get_device_name(storage_get_selected_disk(a->s)));
337ad0df
DH
1314 state = state_finish_install;
1315}
1316
1317/*
1318 * Finish up the install.
1319 */
1320void
1321state_finish_install(struct i_fn_args *a)
1322{
1323 char msg_buf[1][1024];
de58c8bc 1324 during_install = 1;
337ad0df
DH
1325
1326 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1327 "%s is Installed!",
1328 OPERATING_SYSTEM_NAME);
1329
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)) {
1339 case 1:
1340 state = state_configure_menu;
1341 break;
1342 case 2:
1343 state = state_reboot;
1344 break;
1345 case 3:
1346 state = state_welcome;
1347 break;
1348 default:
1349 abort_backend();
1350 }
1351}
1352
1353/*
1354 * state_reboot: reboot the machine.
1355 */
1356void
1357state_reboot(struct i_fn_args *a)
1358{
1359 struct dfui_form *f;
1360 struct dfui_response *r;
1361
1362 f = dfui_form_create(
1363 "reboot",
1364 _("Reboot"),
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."),
1369
1370 "",
1371
1372 "p", "role", "confirm",
1373
1374 "a", "ok", _("Reboot"), "", "",
1375 "a", "cancel", _("Return to Welcome Menu"), "", "",
1376 "p", "accelerator", "ESC",
1377 NULL
1378 );
1379
1380 if (!dfui_be_present(a->c, f, &r))
1381 abort_backend();
1382
1383 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1384 state = state_welcome;
1385 } else {
1386 do_reboot = 1;
1387 state = NULL;
1388 }
1389
1390 dfui_form_free(f);
1391 dfui_response_free(r);
1392}
1393
1394/*
1395 *
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.
1400 *
1401 */
21c1c48a 1402void
337ad0df
DH
1403state_setup_remote_installation_server(struct i_fn_args *a)
1404{
1405 FILE *p;
1406 struct commands *cmds;
1407 struct dfui_form *f;
1408 struct dfui_action *k;
1409 struct dfui_response *r;
1410 char *word;
1411 char interface[256];
1412 char line[256];
1413
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?"))) {
1421 case 1:
1422 /*
1423 * Get interface list.
1424 */
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';
1429 pclose(p);
1430
1431 f = dfui_form_create(
1432 "assign_ip",
1433 _("Setup NetBoot Installation Environment"),
1434 _("Please select which interface you would like to configure:"),
1435 "",
1436 "p", "role", "menu",
1437 NULL
1438 );
1439
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, " ");
1446 }
1447
1448 k = dfui_form_action_add(f, "cancel",
1449 dfui_info_new("Cancel", "", ""));
1450 dfui_action_property_set(k, "accelerator", "ESC");
1451
1452 if (!dfui_be_present(a->c, f, &r))
6e278935 1453 abort_backend();
337ad0df
DH
1454
1455 strlcpy(interface, dfui_response_get_action_id(r), 256);
1456
1457 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1458 dfui_form_free(f);
1459 dfui_response_free(r);
1460 return;
1461 }
1462
21c1c48a 1463 /*
337ad0df
DH
1464 *
1465 * Issues the necessary commands to setup the remote boot environment
1466 *
1467 */
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);
51871435
SW
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"));
337ad0df
DH
1493
1494 if (commands_execute(a, cmds)) {
1495 inform(a->c, _("NetBoot installation services are now started."));
1496 } else {
6b882c34 1497 inform(a->c, _("A failure occurred while provisioning the NetBoot environment. Please check the logs."));
337ad0df
DH
1498 }
1499
1500 commands_free(cmds);
1501 dfui_form_free(f);
1502 dfui_response_free(r);
1503
1504 break;
21c1c48a 1505 case 2:
337ad0df
DH
1506
1507 break;
21c1c48a 1508
87c7a7cf 1509 }
337ad0df
DH
1510
1511 state = state_welcome;
1512
1513}
1514
1515/*** MAIN ***/
1516
1517int
1518flow(int transport, char *rendezvous, char *os_root,
c4d6eff4 1519 int flags __unused)
337ad0df
DH
1520{
1521 struct i_fn_args *a;
1522
1523 rc_conf = config_vars_new();
1524
1525 if ((a = i_fn_args_new(os_root, DEFAULT_INSTALLER_TEMP,
4d4ae2fa
AHJ
1526 DEFAULT_CMDNAMES_FILE, transport,
1527 rendezvous)) == NULL) {
337ad0df
DH
1528 return(0);
1529 }
1530
1531 /*
1532 * XXX We can't handle this yet.
1533 *
c4d6eff4
AHJ
1534 a->flags |= I_BOOTED_LIVECD;
1535 a->flags |= I_UPGRADE_TOOGLE;
337ad0df 1536 */
c4d6eff4 1537 a->flags |= I_BOOTED_LIVECD;
337ad0df
DH
1538
1539 /*
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.
1545 */
1546#ifdef ENABLE_NLS
1547 state = state_lang_menu;
1548#else
1549 state = state_welcome;
1550#endif
1551 for (; state != NULL; )
1552 state(a);
1553
1554 config_vars_free(rc_conf);
1555
1556 i_fn_args_free(a);
1557
1558 return(do_reboot);
1559}