xref: /dragonfly/usr.sbin/installer/dfuibe_installer/fn_configure.c (revision f8608e0dd91dfc478afd77c212f3932730907da1)
1 /*
2  * Copyright (c)2004,2015 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  * fn_configure.c
36  * Configuration functions for installer.
37  * This includes both Configure the LiveCD Environment, and
38  * Configure an Installed System (there is considerable overlap.)
39  * $Id: fn_configure.c,v 1.82 2005/03/25 05:24:00 cpressey Exp $
40  */
41 
42 #include <sys/stat.h>
43 #include <sys/types.h>
44 
45 #include <ctype.h>
46 #include <dirent.h>
47 #include <fcntl.h>
48 #include <libgen.h>
49 #include <stdarg.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <time.h>
54 #include <unistd.h>
55 
56 #ifdef ENABLE_NLS
57 #include <libintl.h>
58 #define _(String) gettext (String)
59 #else
60 #define _(String) (String)
61 #endif
62 
63 #include "libaura/mem.h"
64 #include "libaura/dict.h"
65 #include "libaura/fspred.h"
66 
67 #include "libdfui/dfui.h"
68 #include "libdfui/system.h"
69 
70 #include "libinstaller/commands.h"
71 #include "libinstaller/confed.h"
72 #include "libinstaller/diskutil.h"
73 #include "libinstaller/functions.h"
74 #include "libinstaller/uiutil.h"
75 
76 #include "fn.h"
77 #include "flow.h"
78 #include "pathnames.h"
79 
80 struct config_vars  *rc_conf;
81 
82 static const char   *yes_to_y(const char *);
83 
84 /** CONFIGURE FUNCTIONS **/
85 
86 #define   GECOS_NOT_ALLOWED   ":,\\\""
87 #define   FILENAME_NOT_ALLOWED          ":;`~!#$^&*()={}[]\\|?<>'\" "
88 #define   MEMBERSHIPS_NOT_ALLOWED       ":;`~!@#$%^&*()+={}[]\\|/?<>'\" "
89 #define   USERNAME_NOT_ALLOWED          (MEMBERSHIPS_NOT_ALLOWED ",")
90 
91 void
fn_add_user(struct i_fn_args * a)92 fn_add_user(struct i_fn_args *a)
93 {
94           struct dfui_dataset *ds, *new_ds;
95           struct dfui_form *f;
96           struct dfui_response *r;
97           struct commands *cmds;
98           struct command *cmd;
99           const char *username, *home, *passwd_1, *passwd_2, *gecos;
100           const char *shell, *uid, *group, *groups;
101           const char *passwd_env = "passwd";
102           int done = 0;
103 
104           f = dfui_form_create(
105               "add_user",
106               _("Add user"),
107               _("Here you can add a user to an installed system.\n\n"
108               "You can leave the Home Directory, User ID, and Login Group "
109               "fields empty if you want these items to be automatically "
110               "allocated by the system."),
111               "",
112               "f", "username", _("Username"),
113               _("Enter the username the user will log in as"), "",
114               "f", "gecos", _("Real Name"),
115               _("Enter the real name (or GECOS field) of this user"), "",
116               "f", "passwd_1", _("Password"),
117               _("Enter the user's password (will not be displayed)"), "",
118               "p", "obscured", "true",
119               "f", "passwd_2", _("Password (Again)"),
120               _("Re-enter the user's password to confirm"), "",
121               "p", "obscured", "true",
122               "f", "shell", _("Shell"),
123               _("Enter the full path to the user's shell program"), "",
124               "f", "home", _("Home Directory"),
125               _("Enter the full path to the user's home directory, or leave blank"), "",
126               "f", "uid", _("User ID"),
127               _("Enter this account's numeric user id, or leave blank"), "",
128               "f", "group", _("Login Group"),
129               _("Enter the primary group for this account, or leave blank"), "",
130               "f", "groups", _("Other Group Memberships"),
131               _("Enter a comma-separated list of other groups "
132               "that this user should belong to"), "",
133               "a", "ok", _("Accept and Add"), "", "",
134               "a", "cancel", _("Return to Configure Menu"), "", "",
135               "p", "accelerator", "ESC",
136               NULL
137           );
138 
139           ds = dfui_dataset_new();
140           dfui_dataset_celldata_add(ds, "username", "");
141           dfui_dataset_celldata_add(ds, "gecos", "");
142           dfui_dataset_celldata_add(ds, "passwd_1", "");
143           dfui_dataset_celldata_add(ds, "passwd_2", "");
144           dfui_dataset_celldata_add(ds, "shell", "/bin/tcsh");
145           dfui_dataset_celldata_add(ds, "home", "");
146           dfui_dataset_celldata_add(ds, "uid", "");
147           dfui_dataset_celldata_add(ds, "group", "");
148           dfui_dataset_celldata_add(ds, "groups", "");
149           dfui_form_dataset_add(f, ds);
150 
151           while (!done) {
152                     if (!dfui_be_present(a->c, f, &r))
153                               abort_backend();
154 
155                     if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
156                               done = 1;
157                               dfui_response_free(r);
158                               break;
159                     }
160 
161                     new_ds = dfui_dataset_dup(dfui_response_dataset_get_first(r));
162                     dfui_form_datasets_free(f);
163                     dfui_form_dataset_add(f, new_ds);
164 
165                     /* Fetch form field values. */
166 
167                     username = dfui_dataset_get_value(new_ds, "username");
168                     home = dfui_dataset_get_value(new_ds, "home");
169                     gecos = dfui_dataset_get_value(new_ds, "gecos");
170                     shell = dfui_dataset_get_value(new_ds, "shell");
171                     passwd_1 = dfui_dataset_get_value(new_ds, "passwd_1");
172                     passwd_2 = dfui_dataset_get_value(new_ds, "passwd_2");
173                     uid = dfui_dataset_get_value(new_ds, "uid");
174                     group = dfui_dataset_get_value(new_ds, "group");
175                     groups = dfui_dataset_get_value(new_ds, "groups");
176 
177                     if (strlen(username) == 0) {
178                               inform(a->c, _("You must enter a username."));
179                               done = 0;
180                     } else if (strcmp(passwd_1, passwd_2) != 0) {
181                               inform(a->c, _("The passwords do not match."));
182                               done = 0;
183                     } else if (!assert_clean(a->c, _("Username"), username, USERNAME_NOT_ALLOWED) ||
184                         !assert_clean(a->c, _("Real Name"), gecos, GECOS_NOT_ALLOWED) ||
185                         !assert_clean(a->c, _("Shell"), shell, FILENAME_NOT_ALLOWED) ||
186                         !assert_clean(a->c, _("Home Directory"), home, FILENAME_NOT_ALLOWED) ||
187                         !assert_clean(a->c, _("User ID"), uid, USERNAME_NOT_ALLOWED) ||
188                         !assert_clean(a->c, _("Login Group"), group, USERNAME_NOT_ALLOWED) ||
189                         !assert_clean(a->c, _("Group Memberships"), groups, MEMBERSHIPS_NOT_ALLOWED)) {
190                               done = 0;
191                     } else if (setenv(passwd_env, passwd_1, 1) != 0) {
192                               inform(a->c, _("setenv() failed."));
193                               done = 0;
194                     } else if (!is_program("%s%s", a->os_root, shell) &&
195                         strcmp(shell, "/nonexistent") != 0) {
196                               inform(a->c, _("Chosen shell does not exist on the system."));
197                               done = 0;
198                     } else {
199                               cmds = commands_new();
200 
201                               command_add(cmds, "%s%s %smnt/ /%s useradd "
202                                   "'%s' %s%s %s%s -c \"%s\" %s%s -s %s %s%s %s",
203                                   a->os_root, cmd_name(a, "CHROOT"),
204                                   a->os_root, cmd_name(a, "PW"),
205                                   username,
206                                   strlen(uid) == 0 ? "" : "-u ", uid,
207                                   strlen(group) == 0 ? "" : "-g ", group,
208                                   gecos,
209                                   strlen(home) == 0 ? "" : "-d ", home,
210                                   shell,
211                                   strlen(groups) == 0 ? "" : "-G ", groups,
212                                   (strlen(home) == 0 || !is_dir("%s", home)) ?
213                                   "-m -k /usr/share/skel" : "");
214 
215                               cmd = command_add(cmds, "%s%s \"$%s\" | "
216                                   "%s%s %smnt/ /%s usermod '%s' -h 0",
217                                   a->os_root, cmd_name(a, "ECHO"),
218                                   passwd_env,
219                                   a->os_root, cmd_name(a, "CHROOT"),
220                                   a->os_root, cmd_name(a, "PW"),
221                                   username);
222                               command_set_desc(cmd, _("Setting password..."));
223 
224                               if (commands_execute(a, cmds)) {
225                                         inform(a->c, _("User `%s' was added."), username);
226                                         done = 1;
227                               } else {
228                                         inform(a->c, _("User was not successfully added."));
229                                         done = 0;
230                               }
231 
232                               unsetenv(passwd_env);
233                               commands_free(cmds);
234                     }
235 
236                     dfui_response_free(r);
237           }
238 
239           dfui_form_free(f);
240 }
241 
242 void
fn_root_passwd(struct i_fn_args * a)243 fn_root_passwd(struct i_fn_args *a)
244 {
245           struct dfui_dataset *ds, *new_ds;
246           struct dfui_form *f;
247           struct dfui_response *r;
248           struct commands *cmds;
249           struct command *cmd;
250           const char *root_passwd_1, *root_passwd_2;
251           const char *passwd_env = "passwd";
252           int done = 0;
253 
254           f = dfui_form_create(
255               "root_passwd",
256               _("Set Root Password"),
257               _("Here you can set the super-user (root) password."),
258               "",
259 
260               "f", "root_passwd_1", _("Root password"),
261               _("Enter the root password you would like to use"), "",
262               "p", "obscured", "true",
263               "f", "root_passwd_2", _("Root password again"),
264               _("Enter the root password again to confirm"), "",
265               "p", "obscured", "true",
266 
267               "a", "ok", _("Accept and Set Password"), "", "",
268               "a", "cancel", _("Return to Configure Menu"), "", "",
269               "p", "accelerator", "ESC",
270 
271               NULL
272           );
273 
274           ds = dfui_dataset_new();
275           dfui_dataset_celldata_add(ds, "root_passwd_1", "");
276           dfui_dataset_celldata_add(ds, "root_passwd_2", "");
277           dfui_form_dataset_add(f, ds);
278 
279           while (!done) {
280                     if (!dfui_be_present(a->c, f, &r))
281                               abort_backend();
282 
283                     if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
284                               done = 1;
285                               dfui_response_free(r);
286                               break;
287                     }
288 
289                     new_ds = dfui_dataset_dup(dfui_response_dataset_get_first(r));
290                     dfui_form_datasets_free(f);
291                     dfui_form_dataset_add(f, new_ds);
292 
293                     root_passwd_1 = dfui_dataset_get_value(new_ds, "root_passwd_1");
294                     root_passwd_2 = dfui_dataset_get_value(new_ds, "root_passwd_2");
295 
296                     if (strlen(root_passwd_1) == 0) {
297                               inform(a->c, _("You must enter a password."));
298                               done = 0;
299                     } else if (strcmp(root_passwd_1, root_passwd_2) != 0) {
300                               inform(a->c, _("The passwords do not match."));
301                               done = 0;
302                     } else if (setenv(passwd_env, root_passwd_1, 1) != 0) {
303                               inform(a->c, _("setenv() failed."));
304                               done = 0;
305                     } else {
306                               cmds = commands_new();
307                               cmd = command_add(cmds, "%s%s \"$%s\" | "
308                                   "%s%s %smnt/ /%s usermod root -h 0",
309                                   a->os_root, cmd_name(a, "ECHO"),
310                                   passwd_env,
311                                   a->os_root, cmd_name(a, "CHROOT"),
312                                   a->os_root, cmd_name(a, "PW"));
313                               command_set_desc(cmd, _("Setting password..."));
314                               if (commands_execute(a, cmds)) {
315                                         inform(a->c, _("The root password has been changed."));
316                                         done = 1;
317                               } else {
318                                         inform(a->c, _("An error occurred when "
319                                             "setting the root password."));
320                                         done = 0;
321                               }
322                               unsetenv(passwd_env);
323                               commands_free(cmds);
324                     }
325 
326                     dfui_response_free(r);
327           }
328 
329           dfui_form_free(f);
330 }
331 
332 void
fn_get_passphrase(struct i_fn_args * a,int confirm)333 fn_get_passphrase(struct i_fn_args *a, int confirm)
334 {
335           struct dfui_dataset *ds, *new_ds;
336           struct dfui_form *f;
337           struct dfui_response *r;
338           const char *passphrase_1, *passphrase_2;
339           int fd;
340           int done = 0;
341 
342           if (confirm) {
343                     f = dfui_form_create(
344                         "crypt_passphrase",
345                         _("Set Passphrase for Encryption"),
346                         _("Please specify the passphrase to be used for the encrypted "
347                               "filesystems.\n\n"
348                               "Please note that in the LiveCD environment the keymap is "
349                               "set to \"US ISO\". "
350                               "If you prefer a different keymap for entering the passphrase "
351                               "here, you will need to set it manually using kbdcontrol(1)."),
352                         "",
353 
354                         "f", "passphrase_1", _("Passphrase"),
355                         _("Enter the passphrase you would like to use for encryption"), "",
356                         "p", "obscured", "true",
357                         "f", "passphrase_2", _("Passphrase again"),
358                         _("Enter the passphrase again to confirm"), "",
359                         "p", "obscured", "true",
360 
361                         "a", "ok", _("Accept and Set Passphrase"), "", "",
362                         "p", "accelerator", "ESC",
363 
364                         NULL
365                     );
366           } else {
367                     f = dfui_form_create(
368                         "crypt_passphrase",
369                         _("Specify Decryption Passphrase"),
370                         _("Please enter the passphrase to decrypt and mount the "
371                               "filesystems.\n\n"
372                               "Please note that in the LiveCD environment the keymap is "
373                               "set to \"US ISO\". "
374                               "If you prefer a different keymap for entering the passphrase "
375                               "here, you will need to set it manually using kbdcontrol(1)."),
376                         "",
377 
378                         "f", "passphrase_1", _("Passphrase"),
379                         _("Enter the passphrase"), "",
380                         "p", "obscured", "true",
381 
382                         "a", "ok", _("OK"), "", "",
383                         "p", "accelerator", "ESC",
384 
385                         NULL
386                     );
387           }
388 
389           ds = dfui_dataset_new();
390           dfui_dataset_celldata_add(ds, "passphrase_1", "");
391           if (confirm)
392                     dfui_dataset_celldata_add(ds, "passphrase_2", "");
393           dfui_form_dataset_add(f, ds);
394 
395           while (!done) {
396                     if (!dfui_be_present(a->c, f, &r))
397                               abort_backend();
398 
399                     if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
400                               new_ds = dfui_dataset_dup(dfui_response_dataset_get_first(r));
401                               dfui_form_datasets_free(f);
402                               dfui_form_dataset_add(f, new_ds);
403 
404                               /*
405                                * Fetch form field values.
406                                */
407 
408                               passphrase_1 = dfui_dataset_get_value(new_ds, "passphrase_1");
409                               passphrase_2 = passphrase_1;
410                               if (confirm)
411                                         passphrase_2 = dfui_dataset_get_value(new_ds, "passphrase_2");
412 
413                               if (strlen(passphrase_1) == 0 && strlen(passphrase_2) == 0) {
414                                         done = 0;
415                               } else if (strcmp(passphrase_1, passphrase_2) == 0) {
416                                         /*
417                                          * Passphrases match, write it out.
418                                          */
419                                         fd = open("/tmp/t1", O_RDWR | O_CREAT | O_TRUNC,
420                                             S_IRUSR);
421                                         if (fd != -1) {
422                                                   write(fd, passphrase_1, strlen(passphrase_1));
423                                                   close(fd);
424                                                   done = 1;
425                                         } else {
426                                                   inform(a->c, _("write() error"));
427                                                   done = 0;
428                                         }
429                               } else {
430                                         /*
431                                          * Passphrases don't match, tell the user,
432                                          * let them try again.
433                                          */
434                                         inform(a->c, _("The passphrases do not match."));
435                                         done = 0;
436                               }
437                     }
438 
439                     dfui_response_free(r);
440           }
441 
442           dfui_form_free(f);
443 }
444 
445 /** LIVECD UTILITIES FUNCTIONS **/
446 
447 /*
448  * String returned by this function must be deallocated by the caller.
449  */
450 char *
fn_select_file(const char * title,const char * desc,const char * help,const char * cancel,const char * dir,const char * ext,const struct i_fn_args * a)451 fn_select_file(const char *title, const char *desc, const char *help, const char *cancel,
452                  const char *dir, const char *ext, const struct i_fn_args *a)
453 {
454           DIR *d;
455           struct dfui_form *f;
456           struct dfui_action *k;
457           struct dfui_response *r;
458           struct dirent *de;
459           char *s;
460           struct aura_dict *dict;
461           char *rk;
462           size_t rk_len;
463 
464           f = dfui_form_create(
465               "select_file",
466               title, desc, help,
467               "p", "role", "menu",
468               NULL
469           );
470 
471           dict = aura_dict_new(1, AURA_DICT_SORTED_LIST);
472           d = opendir(dir);
473           while ((de = readdir(d)) != NULL) {
474                     if (strcmp(de->d_name, ".") == 0 ||
475                         strcmp(de->d_name, "..") == 0 ||
476                         strstr(de->d_name, ext) == NULL)
477                               continue;
478                     aura_dict_store(dict, de->d_name, strlen(de->d_name) + 1, "", 1);
479           }
480           closedir(d);
481 
482           aura_dict_rewind(dict);
483           while (!aura_dict_eof(dict)) {
484                     aura_dict_get_current_key(dict, (void **)&rk, &rk_len),
485                     dfui_form_action_add(f, rk,
486                         dfui_info_new(rk, "", ""));
487                     aura_dict_next(dict);
488           }
489           aura_dict_free(dict);
490 
491           k = dfui_form_action_add(f, "cancel",
492               dfui_info_new(cancel, "", ""));
493           dfui_action_property_set(k, "accelerator", "ESC");
494 
495           if (!dfui_be_present(a->c, f, &r))
496                     abort_backend();
497 
498           s = aura_strdup(dfui_response_get_action_id(r));
499 
500           dfui_form_free(f);
501           dfui_response_free(r);
502 
503           return(s);
504 }
505 
506 void
fn_set_kbdmap(struct i_fn_args * a)507 fn_set_kbdmap(struct i_fn_args *a)
508 {
509           struct commands *cmds;
510           char *s;
511           char filename[256], keymapname[256];
512 
513           s = fn_select_file(_("Select Keyboard Map"),
514               _("Select a keyboard map appropriate to your keyboard layout."),
515               "", _("Return to Utilities Menu"), "/usr/share/syscons/keymaps",
516               ".kbd", a);
517 
518           if (strcmp(s, "cancel") != 0) {
519                     cmds = commands_new();
520                     command_add(cmds, "%s%s -l "
521                         "/usr/share/syscons/keymaps/%s < /dev/ttyv0",
522                         a->os_root, cmd_name(a, "KBDCONTROL"),
523                         s);
524                     if (commands_execute(a, cmds)) {
525                               snprintf(filename, 256, "/usr/share/syscons/keymaps/%s", s);
526                               snprintf(keymapname, 256, "%s", filename_noext(basename(filename)));
527                               config_var_set(rc_conf, "keymap", keymapname);
528                     } else {
529                               inform(a->c, _("Keyboard map not successfully set."));
530                     }
531                     commands_free(cmds);
532           }
533 
534           free(s);
535 }
536 
537 void
fn_set_vidfont(struct i_fn_args * a)538 fn_set_vidfont(struct i_fn_args *a)
539 {
540           struct commands *cmds;
541           char *s;
542           char filename[256], variable[256], fontname[256];
543           int by = 0;
544 
545 
546           s = fn_select_file(_("Select Console Font"),
547               _("Select a font appropriate to your video monitor and language."),
548               "", _("Return to Utilities Menu"), "/usr/share/syscons/fonts",
549               ".fnt", a);
550 
551           if (strcmp(s, "cancel") != 0) {
552                     cmds = commands_new();
553                     command_add(cmds, "%s%s -f "
554                         "/usr/share/syscons/fonts/%s < /dev/ttyv0",
555                         a->os_root, cmd_name(a, "VIDCONTROL"),
556                         s);
557                     if (commands_execute(a, cmds)) {
558                               if (strstr(s, "8x16") != NULL)
559                                         by = 16;
560                               else if (strstr(s, "8x14") != NULL)
561                                         by = 14;
562                               else
563                                         by = 8;
564 
565                               snprintf(variable, 256, "font8x%d", by);
566                               snprintf(filename, 256, "/usr/share/syscons/fonts/%s", s);
567                               snprintf(fontname, 256, "%s", filename_noext(basename(filename)));
568                               config_var_set(rc_conf, variable, fontname);
569 
570                     } else {
571                               inform(a->c, _("Video font not successfully set."));
572                     }
573                     commands_free(cmds);
574           }
575 
576           free(s);
577 }
578 
579 void
fn_set_scrnmap(struct i_fn_args * a)580 fn_set_scrnmap(struct i_fn_args *a)
581 {
582           struct commands *cmds;
583           char *s;
584           char filename[256], scrnmapname[256];
585 
586           s = fn_select_file(_("Select Screen Map"),
587               _("Select a mapping for translating characters as they appear "
588               "on your video console screen."),
589               "", _("Return to Utilities Menu"), "/usr/share/syscons/scrnmaps",
590               ".scm", a);
591 
592           if (strcmp(s, "cancel") != 0) {
593                     cmds = commands_new();
594                     command_add(cmds, "%s%s -l "
595                         "/usr/share/syscons/scrnmaps/%s < /dev/ttyv0",
596                         a->os_root, cmd_name(a, "VIDCONTROL"),
597                         s);
598                     if (commands_execute(a, cmds)) {
599                               snprintf(filename, 256, "/usr/share/syscons/scrnmaps/%s", s);
600                               snprintf(scrnmapname, 256, "%s", filename_noext(basename(filename)));
601                               config_var_set(rc_conf, "scrnmap", scrnmapname);
602                     } else {
603                               inform(a->c, _("Video font not successfully set."));
604                     }
605                     commands_free(cmds);
606           }
607           free(s);
608 }
609 
610 void
fn_set_timezone(struct i_fn_args * a)611 fn_set_timezone(struct i_fn_args *a)
612 {
613           struct commands *cmds;
614           char *s = NULL;
615           char current_path[256], selection[256], temp[256];
616           int found_file = 0;
617           int result;
618 
619           result = dfui_be_present_dialog(a->c, _("Local or UTC (Greenwich Mean Time) clock"),
620               _("Yes|No"),
621             _("Is this machine's CMOS clock set to UTC?\n\n"
622               "If it is set to local time, or you don't know, please choose NO here!"));
623           if (result < 1)
624                     abort_backend();
625 
626           cmds = commands_new();
627           switch (result) {
628                     case 1:
629                               command_add(cmds, "%s%s -f %s%setc/wall_cmos_clock",
630                                   a->os_root, cmd_name(a, "RM"),
631                                   a->os_root, a->cfg_root);
632                               break;
633                     case 2:
634                               command_add(cmds, "%s%s %s%setc/wall_cmos_clock",
635                                   a->os_root, cmd_name(a, "TOUCH"),
636                                   a->os_root, a->cfg_root);
637                               break;
638           }
639           commands_execute(a, cmds);
640 
641           snprintf(current_path, 256, "%s%susr/share/zoneinfo",
642               a->os_root, a->cfg_root);
643           while (!found_file) {
644                     if (s != NULL)
645                               free(s);
646                     s = fn_select_file(_("Select Time Zone"),
647                         _("Select a Time Zone appropriate to your physical location."),
648                         "", _("Return to Utilities Menu"), current_path,
649                         "", a);
650                     if (is_dir("%s/%s", current_path, s)) {
651                               snprintf(temp, 256, "%s/%s", current_path, s);
652                               strlcpy(current_path, temp, 256);
653                     } else {
654                               if (is_file("%s/%s", current_path, s)) {
655                                         snprintf(selection, 256, "%s/%s", current_path, s);
656                                         found_file = 1;
657                               }
658                               if (strcmp(s, "cancel") == 0) {
659                                         strlcpy(selection, "cancel", 256);
660                                         found_file = 1;
661                               }
662                     }
663           }
664           free(s);
665 
666           if (strcmp(selection, "cancel") != 0) {
667                     command_add(cmds, "%s%s %s %s%setc/localtime",
668                         a->os_root, cmd_name(a, "CP"),
669                         selection,
670                         a->os_root, a->cfg_root);
671                     if (commands_execute(a, cmds)) {
672                               inform(a->c, _("The Time Zone has been set to %s."), selection);
673                               setenv("TZ", selection, 1);
674                               tzset();
675                     }
676           }
677           commands_free(cmds);
678 }
679 
680 void
fn_assign_datetime(struct i_fn_args * a)681 fn_assign_datetime(struct i_fn_args *a)
682 {
683           struct commands *cmds;
684           struct dfui_dataset *ds, *new_ds;
685           struct dfui_form *f;
686           struct dfui_response *r;
687           struct tm *tp;
688           char temp[256];
689           int year, month, dayofmonth, hour, minutes;
690           int valid = 1;
691           time_t now;
692 
693           now = time(NULL);
694           tp = localtime(&now);
695 
696           f = dfui_form_create(
697               "set_datetime",
698               _("Set Time/Date"),
699               _("Enter the date-time in your timezone."),
700               "",
701 
702               "f", "year", _("Enter year"),
703               _("Enter the current year (e.g. `2004')"), "",
704               "f", "month", _("Month"),
705               _("Enter the current month (e.g. `07')"), "",
706               "f", "dayofmonth", "dayofmonth",
707               _("Enter the current day of month (e.g. `30')"), "",
708               "f", "hour", "hour",
709               _("Enter the current hour (e.g. `07')"), "",
710               "f", "minutes", "minutes",
711               _("Enter the current minutes (e.g. `59')"), "",
712 
713               "a", "ok", _("OK"), "", "",
714               "a", "cancel", _("Cancel"), "", "",
715               "p", "accelerator", "ESC",
716 
717               NULL
718           );
719 
720           ds = dfui_dataset_new();
721           snprintf(temp, 256, "%i", (tp->tm_year+1900));
722           dfui_dataset_celldata_add(ds, "year", temp);
723           snprintf(temp, 256, "%i", (tp->tm_mon+1));
724           dfui_dataset_celldata_add(ds, "month", temp);
725           snprintf(temp, 256, "%i", tp->tm_mday);
726           dfui_dataset_celldata_add(ds, "dayofmonth", temp);
727           snprintf(temp, 256, "%i", tp->tm_hour);
728           dfui_dataset_celldata_add(ds, "hour", temp);
729           snprintf(temp, 256, "%i", tp->tm_min);
730           dfui_dataset_celldata_add(ds, "minutes", temp);
731           dfui_form_dataset_add(f, ds);
732 
733           if (!dfui_be_present(a->c, f, &r))
734                     abort_backend();
735 
736           if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
737                     new_ds = dfui_response_dataset_get_first(r);
738 
739                     if ((year = atoi(dfui_dataset_get_value(new_ds, "year"))) <= 0)
740                               valid = 0;
741                     month = atoi(dfui_dataset_get_value(new_ds, "month"));
742                     if (month < 1 || month > 12)
743                               valid = 0;
744                     dayofmonth = atoi(dfui_dataset_get_value(new_ds, "dayofmonth"));
745                     if (dayofmonth < 1 || dayofmonth > 31)
746                               valid = 0;
747                     hour = atoi(dfui_dataset_get_value(new_ds, "hour"));
748                     if (hour < 0 || hour > 23)
749                               valid = 0;
750                     minutes = atoi(dfui_dataset_get_value(new_ds, "minutes"));
751                     if (minutes < 0 || minutes > 59)
752                               valid = 0;
753 
754                     if (valid) {
755                               cmds = commands_new();
756                               command_add(cmds, "%s%s -n %04d%02d%02d%02d%02d",
757                                   a->os_root, cmd_name(a, "DATE"),
758                                   year, month, dayofmonth, hour, minutes);
759                               if (commands_execute(a, cmds)) {
760                                         inform(a->c, _("The date and time have been set."));
761                               }
762                               commands_free(cmds);
763                     } else {
764                               inform(a->c, _("Please enter numbers within acceptable ranges "
765                                         "for year, month, day of month, hour, and minute."));
766                     }
767           }
768 }
769 
770 void
fn_assign_hostname_domain(struct i_fn_args * a)771 fn_assign_hostname_domain(struct i_fn_args *a)
772 {
773           struct dfui_form *f;
774           struct dfui_response *r;
775           struct dfui_dataset *ds, *new_ds;
776           struct config_vars *resolv_conf;
777           const char *domain, *hostname;
778           char *fqdn;
779 
780           f = dfui_form_create(
781               "set_hostname_domain",
782               _("Set Hostname/Domain"),
783               _("Please enter this machine's hostname and domain name."),
784               "",
785 
786               "f", "hostname", _("Hostname"),
787               _("Enter the Hostname (e.g. `machine')"), "",
788               "f", "domain", _("Domain"),
789               _("Enter the Domain Name (e.g. `network.lan')"), "",
790 
791               "a", "ok", _("OK"), "", "",
792               "a", "cancel", _("Cancel"), "", "",
793               "p", "accelerator", "ESC",
794 
795               NULL
796           );
797 
798           ds = dfui_dataset_new();
799           dfui_dataset_celldata_add(ds, "hostname", "");
800           dfui_dataset_celldata_add(ds, "domain", "");
801           dfui_form_dataset_add(f, ds);
802 
803           if (!dfui_be_present(a->c, f, &r))
804                     abort_backend();
805 
806           if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
807                     new_ds = dfui_response_dataset_get_first(r);
808 
809                     hostname = dfui_dataset_get_value(new_ds, "hostname");
810                     domain = dfui_dataset_get_value(new_ds, "domain");
811                     if (strlen(domain) == 0)
812                               asprintf(&fqdn, "%s", hostname);
813                     else
814                               asprintf(&fqdn, "%s.%s", hostname, domain);
815 
816                     resolv_conf = config_vars_new();
817 
818                     config_var_set(rc_conf, "hostname", fqdn);
819                     config_var_set(resolv_conf, "search", domain);
820                     config_vars_write(resolv_conf, CONFIG_TYPE_RESOLV,
821                         "%s%setc/resolv.conf", a->os_root, a->cfg_root);
822 
823                     config_vars_free(resolv_conf);
824 
825                     free(fqdn);
826           }
827 
828           dfui_form_free(f);
829           dfui_response_free(r);
830 }
831 
832 void
fn_assign_ip(struct i_fn_args * a)833 fn_assign_ip(struct i_fn_args *a)
834 {
835           FILE *p;
836           struct commands *cmds;
837           struct command *cmd;
838           struct config_vars *resolv_conf;
839           struct dfui_dataset *ds, *new_ds;
840           struct dfui_form *f;
841           struct dfui_action *k;
842           struct dfui_response *r;
843           const char *domain, *hostname;
844           const char *interface_ip, *interface_netmask, *defaultrouter, *dns_resolver;
845           char *string, *string1;
846           char *word;
847           char interface[256];
848           char line[256];
849           int write_config = 0;
850 
851           /*
852            * Get interface list.
853            */
854           p = popen("/sbin/ifconfig -l", "r");
855           /* XXX it's possible (though extremely unlikely) this will fail. */
856           while (fgets(line, 255, p) != NULL)
857                     line[strlen(line) - 1] = '\0';
858 
859           pclose(p);
860 
861           f = dfui_form_create(
862               "assign_ip",
863               _("Assign IP Address"),
864               _("Please select which interface you would like to configure:"),
865               "",
866               "p",  "role", "menu",
867               NULL
868           );
869 
870           /* Loop through array. */
871           word = strtok(line, " \t");
872           while (word != NULL) {
873                     dfui_form_action_add(f, word,
874                         dfui_info_new(word, "", ""));
875                     word = strtok(NULL, " ");
876           }
877 
878           k = dfui_form_action_add(f, "cancel",
879               dfui_info_new("Cancel", "", ""));
880           dfui_action_property_set(k, "accelerator", "ESC");
881 
882           if (!dfui_be_present(a->c, f, &r))
883                     abort_backend();
884 
885           if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
886                     dfui_form_free(f);
887                     dfui_response_free(r);
888                     return;
889           }
890 
891           strlcpy(interface, dfui_response_get_action_id(r), 256);
892 
893           resolv_conf = config_vars_new();
894 
895           switch (dfui_be_present_dialog(a->c, _("Use DHCP?"),
896               _("Use DHCP|Configure Manually"),
897               _("DHCP allows the interface to automatically obtain "
898               "an IP address from a nearby DHCP server.\n\n"
899               "Would you like to enable DHCP for %s?"), interface)) {
900           case 1:
901                     asprintf(&string, "ifconfig_%s", interface);
902 
903                     cmds = commands_new();
904                     cmd = command_add(cmds, "%s%s dhclient",
905                         a->os_root, cmd_name(a, "KILLALL"));
906                     command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE);
907                     command_add(cmds, "%s%s %s",
908                         a->os_root, cmd_name(a, "DHCLIENT"),
909                         interface);
910                     if (commands_execute(a, cmds)) {
911                               /* XXX sleep(3); */
912                               show_ifconfig(a->c, interface);
913                               write_config = 1;
914                     } else {
915                               switch (dfui_be_present_dialog(a->c, _("DHCP Failure"),
916                                   _("Yes|No"),
917                                   _("Warning: could not enable dhclient for %s.\n\n"
918                                     "Write the corresponding settings to rc.conf "
919                                     "anyway?"), interface)) {
920                               case 1:
921                                         write_config = 1;
922                                         break;
923                               case 2:
924                                         write_config = 0;
925                                         break;
926                               default:
927                                         abort_backend();
928                               }
929                     }
930                     commands_free(cmds);
931                     config_var_set(rc_conf, string, "DHCP");
932                     free(string);
933                     break;
934           case 2:
935                     dfui_form_free(f);
936                     dfui_response_free(r);
937                     f = dfui_form_create(
938                         "assign_ip",
939                         _("Assign IP Address"),
940                         _("Configuring Interface:"),
941                         "",
942 
943                         "f", "interface_ip", _("IP Address"),
944                         _("Enter the IP Address you would like to use"), "",
945                         "f", "interface_netmask", _("Netmask"),
946                         _("Enter the netmask of the IP address"), "",
947                         "f", "defaultrouter", _("Default Router"),
948                         _("Enter the IP address of the default router"), "",
949                         "f", "dns_resolver", _("Primary DNS Server"),
950                         _("Enter the IP address of primary DNS Server"), "",
951                         "f", "hostname", _("Hostname"),
952                         _("Enter the Hostname"), "",
953                         "f", "domain", _("Domain"),
954                         _("Enter the Domain Name"), "",
955 
956                         "a", "ok", _("Configure Interface"),
957                         "", "",
958                         "a", "cancel", _("Return to Utilities Menu"),
959                         "", "",
960                         "p", "accelerator", "ESC",
961 
962                         NULL
963                     );
964 
965                     ds = dfui_dataset_new();
966                     dfui_dataset_celldata_add(ds, "interface_netmask", "");
967                     dfui_dataset_celldata_add(ds, "defaultrouter", "");
968                     dfui_dataset_celldata_add(ds, "dns_resolver", "");
969                     dfui_dataset_celldata_add(ds, "hostname", "");
970                     dfui_dataset_celldata_add(ds, "domain", "");
971                     dfui_dataset_celldata_add(ds, "interface_ip", "");
972                     dfui_form_dataset_add(f, ds);
973 
974                     if (!dfui_be_present(a->c, f, &r))
975                               abort_backend();
976 
977                     if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
978                               new_ds = dfui_response_dataset_get_first(r);
979 
980                               interface_ip = dfui_dataset_get_value(
981                                                             new_ds, "interface_ip");
982                               interface_netmask = dfui_dataset_get_value(
983                                                             new_ds, "interface_netmask");
984                               defaultrouter = dfui_dataset_get_value(
985                                                             new_ds, "defaultrouter");
986                               dns_resolver = dfui_dataset_get_value(
987                                                             new_ds, "dns_resolver");
988                               hostname = dfui_dataset_get_value(
989                                                             new_ds, "hostname");
990                               domain = dfui_dataset_get_value(
991                                                             new_ds, "domain");
992 
993                               asprintf(&string, "ifconfig_%s", interface);
994                               asprintf(&string1, "inet %s netmask %s",
995                                   interface_ip, interface_netmask);
996 
997                               cmds = commands_new();
998                               command_add(cmds, "%s%s %s %s netmask %s",
999                                   a->os_root, cmd_name(a, "IFCONFIG"),
1000                                   interface, interface_ip, interface_netmask);
1001                               command_add(cmds, "%s%s add default %s",
1002                                   a->os_root, cmd_name(a, "ROUTE"),
1003                                   defaultrouter);
1004 
1005                               if (commands_execute(a, cmds)) {
1006                                         /* XXX sleep(3); */
1007                                         show_ifconfig(a->c, interface);
1008                                         write_config = 1;
1009                               } else {
1010                                         switch (dfui_be_present_dialog(a->c,
1011                                             _("ifconfig Failure"),
1012                                             _("Yes|No"),
1013                                             _("Warning: could not assign IP address "
1014                                               "or default gateway.\n\n"
1015                                               "Write the corresponding settings to "
1016                                               "rc.conf anyway?"))) {
1017                                         case 1:
1018                                                   write_config = 1;
1019                                                   break;
1020                                         case 2:
1021                                                   write_config = 0;
1022                                                   break;
1023                                         default:
1024                                                   abort_backend();
1025                                         }
1026                               }
1027                               commands_free(cmds);
1028 
1029                               config_var_set(rc_conf, string, string1);
1030                               config_var_set(rc_conf, "defaultrouter", defaultrouter);
1031 
1032                               free(string);
1033                               free(string1);
1034 
1035                               asprintf(&string, "%s.%s", hostname, domain);
1036                               config_var_set(rc_conf, "hostname", string);
1037                               free(string);
1038 
1039                               config_var_set(resolv_conf, "search", domain);
1040                               config_var_set(resolv_conf, "nameserver", dns_resolver);
1041                     }
1042                     break;
1043           default:
1044                     abort_backend();
1045           }
1046 
1047           if (write_config) {
1048                     /*
1049                      * Save out changes to /etc/rc.conf and /etc/resolv.conf.
1050                      */
1051                     config_vars_write(resolv_conf, CONFIG_TYPE_RESOLV,
1052                         "%s%setc/resolv.conf", a->os_root, a->cfg_root);
1053           }
1054 
1055           config_vars_free(resolv_conf);
1056 
1057           dfui_form_free(f);
1058           dfui_response_free(r);
1059 }
1060 
1061 static const char *
yes_to_y(const char * value)1062 yes_to_y(const char *value)
1063 {
1064           return(strcasecmp(value, "YES") == 0 ? "Y" : "N");
1065 }
1066 
1067 void
fn_select_services(struct i_fn_args * a)1068 fn_select_services(struct i_fn_args *a)
1069 {
1070           struct dfui_dataset *ds;
1071           struct dfui_form *f;
1072           struct dfui_response *r;
1073 
1074           if (!config_vars_read(a, rc_conf, CONFIG_TYPE_SH, "%s%setc/rc.conf",
1075                     a->os_root, a->cfg_root)) {
1076                     inform(a->c, _("Couldn't read %s%setc/rc.conf."),
1077                         a->os_root, a->cfg_root);
1078                     a->result = 0;
1079                     return;
1080           }
1081 
1082           f = dfui_form_create(
1083               "select_services",
1084               _("Select Services"),
1085               _("Please select which services you would like "
1086                 "started at boot time."),
1087               "",
1088 
1089               "f", "syslogd", "syslogd",
1090                     _("System Logging Daemon"), "",
1091                     "p", "control", "checkbox",
1092               "f", "inetd", "inetd",
1093                     _("Internet Super-Server"), "",
1094                     "p", "control", "checkbox",
1095               "f", "named", "named",
1096                     _("BIND Name Server"), "",
1097                     "p", "control", "checkbox",
1098               "f", "ntpd", "ntpd",
1099                     _("Network Time Protocol Daemon"), "",
1100                     "p", "control", "checkbox",
1101               "f", "sshd", "sshd",
1102                     _("Secure Shell Daemon"), "",
1103                     "p", "control", "checkbox",
1104 
1105               "a", "ok", _("Enable/Disable Services"),
1106                   "", "",
1107               "a", "cancel", _("Return to Utilities Menu"),
1108                     "", "",
1109                   "p", "accelerator", "ESC",
1110 
1111               NULL
1112           );
1113 
1114           ds = dfui_dataset_new();
1115           dfui_dataset_celldata_add(ds, "syslogd",
1116               yes_to_y(config_var_get(rc_conf, "syslogd_enable")));
1117           dfui_dataset_celldata_add(ds, "inetd",
1118               yes_to_y(config_var_get(rc_conf, "inetd_enable")));
1119           dfui_dataset_celldata_add(ds, "named",
1120               yes_to_y(config_var_get(rc_conf, "named_enable")));
1121           dfui_dataset_celldata_add(ds, "ntpd",
1122               yes_to_y(config_var_get(rc_conf, "ntpd_enable")));
1123           dfui_dataset_celldata_add(ds, "sshd",
1124               yes_to_y(config_var_get(rc_conf, "sshd_enable")));
1125           dfui_form_dataset_add(f, ds);
1126 
1127           if (!dfui_be_present(a->c, f, &r))
1128                     abort_backend();
1129 
1130           if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1131                     dfui_form_free(f);
1132                     dfui_response_free(r);
1133                     return;
1134           }
1135 
1136           dfui_form_free(f);
1137           dfui_response_free(r);
1138 }
1139 
1140 /*** NON-fn_ FUNCTIONS ***/
1141 
1142 /*
1143  * Uses ss->selected_{disk,slice} as the target system.
1144  *
1145  * XXX We now assume that the root mount has enough of the topology
1146  *     to handle any configuration actions.
1147  */
1148 int
mount_target_system(struct i_fn_args * a)1149 mount_target_system(struct i_fn_args *a)
1150 {
1151           FILE *crypttab, *fstab;
1152           struct commands *cmds;
1153           struct command *cmd;
1154           struct subpartition *a_subpart;
1155           struct subpartition *d_subpart;
1156           char name[256], device[256];
1157           char *filename, line[256];
1158           char *word;
1159 
1160           /*
1161            * Mount subpartitions from this installation if they are
1162            * not already mounted.  Tricky, as we need to honour the
1163            * installation's loader.conf and fstab.
1164            */
1165           cmds = commands_new();
1166 
1167           /*
1168            * First, unmount anything already mounted on /mnt.
1169            */
1170           unmount_all_under(a, cmds, "%smnt", a->os_root);
1171 
1172           /*
1173            * Reset and clear out subpartitions so that system
1174            * can make a "dummy" subpart.
1175            */
1176           subpartitions_free(storage_get_selected_slice(a->s));
1177 
1178           /*
1179            * Create a temporary dummy subpartition - that we
1180            * assume exists
1181            */
1182           a_subpart = subpartition_new_ufs(storage_get_selected_slice(a->s),
1183                                                    "/dummy", 0, 0, 0, 0, 0, 0);
1184           subpartition_new_ufs(storage_get_selected_slice(a->s),
1185                                                    "swap", 0, 0, 0, 0, 0, 0);
1186           d_subpart = subpartition_new_ufs(storage_get_selected_slice(a->s),
1187                                                    "/dummy", 0, 0, 0, 0, 0, 0);
1188 
1189           /*
1190            * Mount the target's / and read its /etc/fstab.
1191            *
1192            * XXX NEEDS TO BE REWRITTEN XXX
1193            */
1194           {
1195                     command_add(cmds, "%s%s /dev/%s %sboot",
1196                         a->os_root, cmd_name(a, "MOUNT"),
1197                         subpartition_get_device_name(a_subpart),
1198                         a->os_root);
1199                     cmd = command_add(cmds,
1200                         "%s%s -f %st2;"
1201                         "%s%s \"^vfs\\.root\\.realroot=\" %sboot/loader.conf >%st2",
1202                         a->os_root, cmd_name(a, "RM"), a->tmp,
1203                         a->os_root, cmd_name(a, "GREP"),
1204                         a->os_root, a->tmp);
1205                     command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE);
1206           }
1207           if (!commands_execute(a, cmds)) {
1208                     commands_free(cmds);
1209                     return(0);
1210           }
1211           commands_free(cmds);
1212           cmds = commands_new();
1213 
1214           /*
1215            * XXX NEEDS TO BE REWRITTEN XXX
1216            */
1217           {
1218                     struct stat sb = { .st_size = 0 };
1219                     const char *fsname;
1220                     const char *mountid;
1221 
1222                     switch (use_hammer) {
1223                     case 1:
1224                               fsname = "hammer";
1225                               mountid = "MOUNT_HAMMER";
1226                               break;
1227                     case 2:
1228                               fsname = "hammer2";
1229                               mountid = "MOUNT_HAMMER2";
1230                               break;
1231                     case 0:
1232                     default:
1233                               fsname = "ufs";
1234                               mountid = "MOUNT";
1235                               break;
1236                     }
1237 
1238                     stat("/tmp/t2", &sb);
1239                     if (sb.st_size > 0) {
1240                               command_add(cmds, "%s%s %sboot",
1241                                   a->os_root, cmd_name(a, "UMOUNT"),
1242                                   a->os_root);
1243                               fn_get_passphrase(a, 0);
1244                               command_add(cmds,
1245                                   "%s%s -d /tmp/t1 luksOpen /dev/`%s%s \"^vfs\\.root\\.realroot=\" %st2 |"
1246                                   "%s%s -F%s: '{print $2;}' |"
1247                                   "%s%s -F: '{print $1;}'` %s",
1248                                   a->os_root, cmd_name(a, "CRYPTSETUP"),
1249                                   a->os_root, cmd_name(a, "GREP"),
1250                                   a->tmp,
1251                                   a->os_root, cmd_name(a, "AWK"),
1252                                   fsname,
1253                                   a->os_root, cmd_name(a, "AWK"),
1254                                   subpartition_get_mapper_name(d_subpart, -1));
1255                               command_add(cmds,
1256                                   "%s%s %s %s%s",
1257                                   a->os_root,
1258                                   cmd_name(a, mountid),
1259                                   subpartition_get_mapper_name(d_subpart, 1),
1260                                   a->os_root, a->cfg_root);
1261                     } else {
1262                               command_add(cmds,
1263                                   "%s%s /dev/`%s%s \"^vfs\\.root\\.mountfrom\" %sboot/loader.conf |"
1264                                   "%s%s -F%s: '{print $2;}' |"
1265                                   "%s%s 's/\"//'` %s%s",
1266                                   a->os_root,
1267                                   cmd_name(a, mountid),
1268                                   a->os_root, cmd_name(a, "GREP"),
1269                                   a->os_root,
1270                                   a->os_root, cmd_name(a, "AWK"),
1271                                   fsname,
1272                                   a->os_root, cmd_name(a, "SED"),
1273                                   a->os_root, a->cfg_root);
1274                               command_add(cmds, "%s%s %sboot",
1275                                   a->os_root, cmd_name(a, "UMOUNT"),
1276                                   a->os_root);
1277                     }
1278           }
1279           if (!commands_execute(a, cmds)) {
1280                     commands_free(cmds);
1281                     unlink("/tmp/t1");
1282                     return(0);
1283           }
1284           commands_free(cmds);
1285           cmds = commands_new();
1286 
1287           /*
1288            * Get rid of the dummy subpartition.
1289            */
1290           subpartitions_free(storage_get_selected_slice(a->s));
1291 
1292           /*
1293            * See if an /etc/crypttab exists.
1294            *
1295            * Scan and open the related mappings (currently not used since
1296            * we removed the additional mounts from the fstab scan, but we
1297            * might put those back in at a future date so leave this in for
1298            * now).
1299            */
1300           asprintf(&filename, "%s%s/etc/crypttab", a->os_root, a->cfg_root);
1301           crypttab = fopen(filename, "r");
1302           free(filename);
1303           if (crypttab != NULL) {
1304                     while (fgets(line, 256, crypttab) != NULL) {
1305                               /*
1306                                * Parse the crypttab line.
1307                                */
1308                               if (first_non_space_char_is(line, '#'))
1309                                         continue;
1310                               if ((word = strtok(line, " \t")) == NULL)
1311                                         continue;
1312                               strlcpy(name, word, 256);
1313 
1314                               /* don't mount encrypted swap */
1315                               if (strcmp(name, "swap") == 0)
1316                                         continue;
1317                               /* encrypted root already mounted */
1318                               if (strcmp(name, subpartition_get_mapper_name(d_subpart, -1)) == 0)
1319                                         continue;
1320 
1321                               if ((word = strtok(NULL, " \t")) == NULL)
1322                                         continue;
1323                               strlcpy(device, word, 256);
1324 
1325                               command_add(cmds,
1326                                   "%s%s -d /tmp/t1 luksOpen %s %s",
1327                                   a->os_root, cmd_name(a, "CRYPTSETUP"),
1328                                   device, name);
1329 
1330                               continue;
1331                     }
1332                     fclose(crypttab);
1333           }
1334           if (!commands_execute(a, cmds)) {
1335                     commands_free(cmds);
1336                     unlink("/tmp/t1");
1337                     return(0);
1338           }
1339           commands_free(cmds);
1340           unlink("/tmp/t1");
1341 
1342           /*
1343            * (current we do not mount the other partitions, everything needed
1344            *  for system configuration should be on the already-mounted root).
1345            */
1346           asprintf(&filename, "%s%s/etc/fstab", a->os_root, a->cfg_root);
1347           fstab = fopen(filename, "r");
1348           free(filename);
1349           if (fstab == NULL) {
1350                     inform(a->c, _("Filesystem table on installed system could not be read."));
1351                     cmds = commands_new();
1352                     command_add(cmds, "%s%s %s%s",
1353                         a->os_root, cmd_name(a, "UMOUNT"),
1354                         a->os_root, a->cfg_root);
1355                     if (!commands_execute(a, cmds)) {
1356                               inform(a->c, _("Warning: Installed system was not properly unmounted."));
1357                     }
1358                     commands_free(cmds);
1359                     return(0);
1360           }
1361           fclose(fstab);
1362 
1363           return 1;
1364 }
1365