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