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