Commit | Line | Data |
---|---|---|
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) |
51 | extern 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 | ||
78 | void (*state)(struct i_fn_args *) = NULL; | |
79 | int do_reboot; | |
14825f9d SW |
80 | int use_hammer; /* 0=UFS 1=HAMMER 2=HAMMER2 */ |
81 | int use_uefi; | |
82 | int 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 | 109 | void |
337ad0df DH |
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 | ||
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 | */ | |
173 | void | |
174 | state_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 | */ | |
291 | void | |
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); | |
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 | ||
361 | void | |
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"; | |
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 | 537 | void |
337ad0df DH |
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 | ||
21c1c48a | 593 | void |
337ad0df DH |
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 | ||
21c1c48a | 680 | void |
337ad0df DH |
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", | |
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 | 732 | void |
337ad0df DH |
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); | |
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 | 815 | void |
337ad0df DH |
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 | |
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]), | |
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 | */ | |
938 | void | |
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 | ||
337ad0df DH |
967 | /* |
968 | * state_select_disk: ask the user on which physical disk they wish | |
969 | * to install DragonFly. | |
970 | */ | |
971 | void | |
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 | ||
971d1cca MS |
1014 | void |
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"), | |
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 | */ | |
1056 | void | |
1057 | state_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 | */ | |
1111 | void | |
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); | |
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 | */ | |
1181 | void | |
1182 | state_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 | */ | |
1241 | void | |
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); | |
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 | */ | |
1296 | void | |
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"); | |
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 | */ | |
1320 | void | |
1321 | state_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 | */ | |
1356 | void | |
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 | */ | |
21c1c48a | 1402 | void |
337ad0df DH |
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)) | |
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 | ||
1517 | int | |
1518 | flow(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 | } |