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 <unistd.h>
44 #include <string.h>
45
46 #ifdef ENABLE_NLS
47 #include <libintl.h>
48 #include <locale.h>
49 #include "libdfui/lang.h"
50 #define _(String) gettext (String)
51 extern int _nl_msg_cat_cntr;
52 #else
53 #define _(String) (String)
54 #endif
55
56 #include "libaura/mem.h"
57 #include "libaura/dict.h"
58 #include "libaura/fspred.h"
59
60 #include "libdfui/dfui.h"
61 #ifdef DEBUG
62 #include "libdfui/dump.h"
63 #endif
64 #include "libdfui/system.h"
65
66 #include "libinstaller/commands.h"
67 #include "libinstaller/confed.h"
68 #include "libinstaller/diskutil.h"
69 #include "libinstaller/functions.h"
70 #include "libinstaller/uiutil.h"
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 int use_hammer; /* 0=UFS 1=HAMMER 2=HAMMER2 */
81 int use_uefi;
82 int during_install;
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
109 void
state_lang_menu(struct i_fn_args * a)110 state_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
127 "a", "default", "English",
128 "English Standard Default", "",
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 */
173 void
state_welcome(struct i_fn_args * a)174 state_welcome(struct i_fn_args *a)
175 {
176 struct dfui_form *f;
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."
185 "\n\n"
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
202 if ((a->flags & I_BOOTED_LIVECD) == 0) {
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
220 if (a->flags & I_UPGRADE_TOOGLE) {
221 snprintf(msg_buf[0], sizeof(msg_buf[0]),
222 _("Upgrade a FreeBSD 4.X system to %s"),
223 OPERATING_SYSTEM_NAME);
224 dfui_form_action_add(f, "upgrade",
225 dfui_info_new(_("Upgrade"),
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
249 dfui_form_action_add(f, "exit",
250 dfui_info_new(_("Exit to Live CD"),
251 _("Exit this program to a login prompt with access to the LiveCD"), ""));
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 */
291 void
state_welcome_system(struct i_fn_args * a)292 state_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);
300
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"
307 "%s"
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
336 dfui_form_action_add(f, "utilities",
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
361 void
state_configure_menu(struct i_fn_args * a)362 state_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";
395
396 if (during_install == 0) {
397 switch (dfui_be_present_dialog(a->c, _("Select file system"),
398 _("HAMMER2|HAMMER1|UFS|Return to Welcome Menu"),
399 _("Please select the file system installed on the disk.\n\n")))
400 {
401 case 1:
402 /* HAMMER2 (first menu item is the default) */
403 use_hammer = 2;
404 break;
405 case 2:
406 /* HAMMER1 */
407 use_hammer = 1;
408 break;
409 case 3:
410 /* UFS */
411 use_hammer = 0;
412 break;
413 case 4:
414 state = state_welcome;
415 return;
416 /* NOTREACHED */
417 break;
418 default:
419 abort_backend();
420 break;
421 }
422 }
423
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
450 "a", "set_kbdmap",
451 _("Set keyboard map"),
452 _("Set what kind of keyboard layout you have"), "",
453 "a", "root_passwd", _("Set root password"),
454 _("Set the password that the root (superuser) account will use"), "",
455 "a", "add_user", _("Add a user"),
456 _("Add a user to the system"), "",
457 "a", "assign_ip", _("Configure network interfaces"),
458 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "",
459 "a", "assign_hostname_domain",
460 _("Configure hostname and domain"),
461 _("Configure the hostname and domain for this system"), "",
462 /*
463 "a", "select_services", "Select Services",
464 "Enable/Disable system services (servers, daemons, etc.)", "",
465 */
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"), "",
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), "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 /*
526 * Finally, unmount the system we mounted on /mnt and remove mappings.
527 */
528 cmds = commands_new();
529 unmount_all_under(a, cmds, "%smnt", a->os_root);
530 commands_execute(a, cmds);
531 commands_free(cmds);
532
533 if (remove_all_mappings(a) == NULL)
534 inform(a->c, _("Warning: mappings could not be removed."));
535 }
536
537 void
state_utilities_menu(struct i_fn_args * a)538 state_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
593 void
state_environment_menu(struct i_fn_args * a)594 state_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
680 void
state_diagnostics_menu(struct i_fn_args * a)681 state_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",
695
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)"), "",
702 "a", "natacontrol",
703 _("Display ATA devices"),
704 _("Display ATA devices (natacontrol)"), "",
705 NULL
706 );
707
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);
720 } else if (strcmp(dfui_response_get_action_id(r), "natacontrol") == 0) {
721 fn_show_natacontrol(a);
722 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
723 state = state_utilities_menu;
724 done = 1;
725 }
726
727 dfui_form_free(f);
728 dfui_response_free(r);
729 }
730 }
731
732 void
state_diskutil_menu(struct i_fn_args * a)733 state_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);
781 if (use_uefi)
782 fn_format_disk_uefi(a);
783 else
784 fn_format_disk_mbr(a);
785 } else if (strcmp(dfui_response_get_action_id(r), "wipe_start_of_disk") == 0) {
786 fn_wipe_start_of_disk(a);
787 } else if (strcmp(dfui_response_get_action_id(r), "wipe_start_of_slice") == 0) {
788 fn_wipe_start_of_slice(a);
789 } else if (strcmp(dfui_response_get_action_id(r), "install_bootblocks") == 0) {
790 a->short_desc = _("Select the disks on which "
791 "you wish to install bootblocks.");
792 a->cancel_desc = _("Return to Utilities Menu");
793 fn_install_bootblocks(a, NULL);
794 } else if (strcmp(dfui_response_get_action_id(r), "format_msdos_floppy") == 0) {
795 fn_format_msdos_floppy(a);
796 } else if (strcmp(dfui_response_get_action_id(r), "create_cdboot_floppy") == 0) {
797 fn_create_cdboot_floppy(a);
798 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
799 state = state_utilities_menu;
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 */
815 void
state_begin_upgrade(struct i_fn_args * a)816 state_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 */
858 void
state_begin_install(struct i_fn_args * a)859 state_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]),
866 _("This application will install %s"
867 " on one of the hard disk drives attached to this computer. "
868 "It has been designed to make it easy to install "
869 "%s in the typical case. "
870 "If you have special requirements that are not addressed "
871 "by this installer, or if you have problems using it, you "
872 "are welcome to install %s manually. "
873 "To do so select Exit to Live CD, login as root, and follow "
874 "the instructions given in the file /README ."
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 }
924 state = state_ask_uefi;
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
935 /*
936 * state_ask_uefi: ask the user if they want a UEFI installation
937 */
938 void
state_ask_uefi(struct i_fn_args * a)939 state_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
967 /*
968 * state_select_disk: ask the user on which physical disk they wish
969 * to install DragonFly.
970 */
971 void
state_select_disk(struct i_fn_args * a)972 state_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
1014 void
state_ask_fs(struct i_fn_args * a)1015 state_ask_fs(struct i_fn_args *a)
1016 {
1017 use_hammer = 0;
1018
1019 switch (dfui_be_present_dialog(a->c, _("Select file system"),
1020 _("Use HAMMER2|Use HAMMER1|Use UFS|Return to Select Disk"),
1021 _("Please select the file system you want to use with %s.\n\n"
1022 "HAMMER2 is the recommended %s file system. "
1023 "HAMMER1 is the previous %s file system. "
1024 "UFS is the traditional BSD file system."),
1025 OPERATING_SYSTEM_NAME,
1026 OPERATING_SYSTEM_NAME,
1027 OPERATING_SYSTEM_NAME))
1028 {
1029 case 1:
1030 /* HAMMER2 (first menu item is the default) */
1031 use_hammer = 2;
1032 break;
1033 case 2:
1034 /* HAMMER1 */
1035 use_hammer = 1;
1036 break;
1037 case 3:
1038 /* UFS */
1039 break;
1040 case 4:
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
1052 /*
1053 * state_format_disk: ask the user if they wish to format the disk they
1054 * selected.
1055 */
1056 void
state_format_disk(struct i_fn_args * a)1057 state_format_disk(struct i_fn_args *a)
1058 {
1059
1060 if (use_uefi) {
1061 fn_format_disk_uefi(a);
1062 if (a->result)
1063 state = state_ask_fs;
1064 else
1065 state = state_select_disk;
1066 return;
1067 }
1068
1069 /* XXX Using part of the disk is only supported for MBR installs */
1070 switch (dfui_be_present_dialog(a->c, _("How Much Disk?"),
1071 _("Use Entire Disk|Use Part of Disk|Return to Select Disk"),
1072 _("Select how much of this disk you want to use for %s.\n\n%s"),
1073 OPERATING_SYSTEM_NAME,
1074 disk_get_desc(storage_get_selected_disk(a->s)))) {
1075 case 1:
1076 /* Entire Disk */
1077 if (measure_activated_swap_from_disk(a, storage_get_selected_disk(a->s)) > 0) {
1078 if (swapoff_all(a) == NULL) {
1079 inform(a->c, _("Warning: swap could not be turned off."));
1080 state = state_select_disk;
1081 return;
1082 }
1083 }
1084
1085 fn_format_disk_mbr(a);
1086 if (a->result)
1087 state = state_ask_fs;
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 */
1111 void
state_select_slice(struct i_fn_args * a)1112 state_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);
1127
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) {
1136 if (swapoff_all(a) == NULL) {
1137 inform(a->c, _("Warning: swap could not be turned off."));
1138 state = state_select_slice;
1139 return;
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
state_create_subpartitions(struct i_fn_args * a)1182 state_create_subpartitions(struct i_fn_args *a)
1183 {
1184 struct commands *cmds;
1185
1186 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s),
1187 storage_get_selected_slice(a->s)) > 0) {
1188 if (swapoff_all(a) == NULL) {
1189 inform(a->c, _("Warning: swap could not be turned off."));
1190 state = disk_get_formatted(storage_get_selected_disk(a->s)) ?
1191 state_select_disk : state_select_slice;
1192 return;
1193 }
1194 }
1195
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"),
1205 slice_get_device_name(storage_get_selected_slice(a->s)));
1206 command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
1207 a->os_root, cmd_name(a, "DD"),
1208 slice_get_device_name(storage_get_selected_slice(a->s)));
1209 command_add(cmds, "%s%s -B -r -w %s",
1210 a->os_root, cmd_name(a, "DISKLABEL64"),
1211 slice_get_device_name(storage_get_selected_slice(a->s)));
1212 commands_execute(a, cmds);
1213 commands_free(cmds);
1214
1215 /*
1216 * Create subpartitions and filesystems
1217 */
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:
1226 fn_create_subpartitions_ufs(a);
1227 break;
1228 }
1229
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 */
1241 void
state_install_os(struct i_fn_args * a)1242 state_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);
1281 if (a->result) {
1282 if (use_uefi)
1283 state = state_finish_install;
1284 else
1285 state = state_install_bootstrap;
1286 }
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 */
1296 void
state_install_bootstrap(struct i_fn_args * a)1297 state_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");
1312 fn_install_bootblocks(a,
1313 disk_get_device_name(storage_get_selected_disk(a->s)));
1314 state = state_finish_install;
1315 }
1316
1317 /*
1318 * Finish up the install.
1319 */
1320 void
state_finish_install(struct i_fn_args * a)1321 state_finish_install(struct i_fn_args *a)
1322 {
1323 char msg_buf[1][1024];
1324 during_install = 1;
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 */
1356 void
state_reboot(struct i_fn_args * a)1357 state_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 */
1402 void
state_setup_remote_installation_server(struct i_fn_args * a)1403 state_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))
1453 abort_backend();
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
1463 /*
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);
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"));
1493
1494 if (commands_execute(a, cmds)) {
1495 inform(a->c, _("NetBoot installation services are now started."));
1496 } else {
1497 inform(a->c, _("A failure occurred while provisioning the NetBoot environment. Please check the logs."));
1498 }
1499
1500 commands_free(cmds);
1501 dfui_form_free(f);
1502 dfui_response_free(r);
1503
1504 break;
1505 case 2:
1506
1507 break;
1508
1509 }
1510
1511 state = state_welcome;
1512
1513 }
1514
1515 /*** MAIN ***/
1516
1517 int
flow(int transport,char * rendezvous,char * os_root,int flags __unused)1518 flow(int transport, char *rendezvous, char *os_root,
1519 int flags __unused)
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,
1526 DEFAULT_CMDNAMES_FILE, transport,
1527 rendezvous)) == NULL) {
1528 return(0);
1529 }
1530
1531 /*
1532 * XXX We can't handle this yet.
1533 *
1534 a->flags |= I_BOOTED_LIVECD;
1535 a->flags |= I_UPGRADE_TOOGLE;
1536 */
1537 a->flags |= I_BOOTED_LIVECD;
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 }
1560