1 /* 2 * Copyright (c)2004 The DragonFly Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * Neither the name of the DragonFly Project nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 * OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * 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/types.h> 43 44 #include <ctype.h> 45 #include <dirent.h> 46 #include <libgen.h> 47 #include <stdarg.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <time.h> 52 53 #ifdef ENABLE_NLS 54 #include <libintl.h> 55 #define _(String) gettext (String) 56 #else 57 #define _(String) (String) 58 #endif 59 60 #include "libaura/mem.h" 61 #include "libaura/dict.h" 62 #include "libaura/fspred.h" 63 64 #include "libdfui/dfui.h" 65 #include "libdfui/system.h" 66 67 #include "libinstaller/commands.h" 68 #include "libinstaller/confed.h" 69 #include "libinstaller/diskutil.h" 70 #include "libinstaller/functions.h" 71 #include "libinstaller/package.h" 72 #include "libinstaller/uiutil.h" 73 74 #include "fn.h" 75 #include "flow.h" 76 #include "pathnames.h" 77 78 static const char *yes_to_y(const char *); 79 static char *convert_tmpfs_options(char *); 80 81 /** CONFIGURE FUNCTIONS **/ 82 83 #define PW_NOT_ALLOWED ":;,`~!@#$%^&*()+={}[]\\|/?<>'\" " 84 #define GECOS_NOT_ALLOWED ":,\\\"" 85 #define FILENAME_NOT_ALLOWED ":;`~!#$^&*()={}[]\\|?<>'\" " 86 #define MEMBERSHIPS_NOT_ALLOWED ":;`~!@#$%^&*()+={}[]\\|/?<>'\" " 87 88 void 89 fn_add_user(struct i_fn_args *a) 90 { 91 struct dfui_dataset *ds, *new_ds; 92 struct dfui_form *f; 93 struct dfui_response *r; 94 struct commands *cmds; 95 struct command *cmd; 96 const char *username, *home, *passwd_1, *passwd_2, *gecos; 97 const char *shell, *uid, *group, *groups; 98 int done = 0; 99 100 f = dfui_form_create( 101 "add_user", 102 _("Add user"), 103 _("Here you can add a user to an installed system.\n\n" 104 "You can leave the Home Directory, User ID, and Login Group " 105 "fields empty if you want these items to be automatically " 106 "allocated by the system.\n\n" 107 "Note: this user's password will appear in the install log. " 108 "If this is a problem, please add the user manually after " 109 "rebooting into the installed system instead."), 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 /* Passwords don't match; tell the user. */ 181 inform(a->c, _("The passwords do not match.")); 182 done = 0; 183 } else if (!assert_clean(a->c, _("Username"), username, PW_NOT_ALLOWED) || 184 !assert_clean(a->c, _("Real Name"), gecos, GECOS_NOT_ALLOWED) || 185 !assert_clean(a->c, _("Password"), passwd_1, PW_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, PW_NOT_ALLOWED) || 189 !assert_clean(a->c, _("Login Group"), group, PW_NOT_ALLOWED) || 190 !assert_clean(a->c, _("Group Memberships"), groups, MEMBERSHIPS_NOT_ALLOWED)) { 191 done = 0; 192 } else if (!is_program("%s%s", a->os_root, shell) && 193 strcmp(shell, "/nonexistent") != 0) { 194 inform(a->c, _("Chosen shell does not exist on the system.")); 195 done = 0; 196 } else { 197 cmds = commands_new(); 198 199 command_add(cmds, "%s%s %smnt/ /%s useradd " 200 "'%s' %s%s %s%s -c \"%s\" %s%s -s %s %s%s %s", 201 a->os_root, cmd_name(a, "CHROOT"), 202 a->os_root, cmd_name(a, "PW"), 203 username, 204 strlen(uid) == 0 ? "" : "-u ", uid, 205 strlen(group) == 0 ? "" : "-g ", group, 206 gecos, 207 strlen(home) == 0 ? "" : "-d ", home, 208 shell, 209 strlen(groups) == 0 ? "" : "-G ", groups, 210 (strlen(home) == 0 || !is_dir(home)) ? 211 "-m -k /usr/share/skel" : ""); 212 213 cmd = command_add(cmds, "%s%s '%s' | " 214 "%s%s %smnt/ /%s usermod '%s' -h 0", 215 a->os_root, cmd_name(a, "ECHO"), 216 passwd_1, 217 a->os_root, cmd_name(a, "CHROOT"), 218 a->os_root, cmd_name(a, "PW"), 219 username); 220 command_set_desc(cmd, _("Setting password...")); 221 222 if (commands_execute(a, cmds)) { 223 inform(a->c, _("User `%s' was added."), username); 224 done = 1; 225 } else { 226 inform(a->c, _("User was not successfully added.")); 227 done = 0; 228 } 229 230 commands_free(cmds); 231 } 232 233 dfui_response_free(r); 234 } 235 236 dfui_form_free(f); 237 } 238 239 void 240 fn_root_passwd(struct i_fn_args *a) 241 { 242 struct dfui_dataset *ds, *new_ds; 243 struct dfui_form *f; 244 struct dfui_response *r; 245 struct commands *cmds; 246 struct command *cmd; 247 const char *root_passwd_1, *root_passwd_2; 248 int done = 0; 249 250 f = dfui_form_create( 251 "root_passwd", 252 _("Set Root Password"), 253 _("Here you can set the super-user (root) password.\n\n" 254 "Note: root's new password will appear in the install log. " 255 "If this is a problem, please set root's password manually " 256 "after rebooting into the installed system instead."), 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), "ok") == 0) { 283 new_ds = dfui_dataset_dup(dfui_response_dataset_get_first(r)); 284 dfui_form_datasets_free(f); 285 dfui_form_dataset_add(f, new_ds); 286 287 /* 288 * Fetch form field values. 289 */ 290 291 root_passwd_1 = dfui_dataset_get_value(new_ds, "root_passwd_1"); 292 root_passwd_2 = dfui_dataset_get_value(new_ds, "root_passwd_2"); 293 294 if (!assert_clean(a->c, _("Root password"), root_passwd_1, PW_NOT_ALLOWED)) { 295 done = 0; 296 } else if (strlen(root_passwd_1) == 0 && strlen(root_passwd_2) == 0) { 297 done = 0; 298 } else if (strcmp(root_passwd_1, root_passwd_2) == 0) { 299 /* 300 * Passwords match, so set the root password. 301 */ 302 cmds = commands_new(); 303 cmd = command_add(cmds, "%s%s '%s' | " 304 "%s%s %smnt/ /%s usermod root -h 0", 305 a->os_root, cmd_name(a, "ECHO"), 306 root_passwd_1, 307 a->os_root, cmd_name(a, "CHROOT"), 308 a->os_root, cmd_name(a, "PW")); 309 command_set_desc(cmd, _("Setting password...")); 310 if (commands_execute(a, cmds)) { 311 inform(a->c, _("The root password has been changed.")); 312 done = 1; 313 } else { 314 inform(a->c, _("An error occurred when " 315 "setting the root password.")); 316 done = 0; 317 } 318 commands_free(cmds); 319 } else { 320 /* 321 * Passwords don't match - tell the user, let them try again. 322 */ 323 inform(a->c, _("The passwords do not match.")); 324 done = 0; 325 } 326 } else { 327 /* 328 * Cancelled by user 329 */ 330 done = 1; 331 } 332 333 dfui_response_free(r); 334 } 335 336 dfui_form_free(f); 337 } 338 339 void 340 fn_install_packages(struct i_fn_args *a) 341 { 342 FILE *pipe; 343 struct commands *cmds; 344 struct dfui_celldata *cd; 345 struct dfui_dataset *ds; 346 struct dfui_field *fi; 347 struct dfui_form *f; 348 struct dfui_response *r; 349 char command[256]; 350 char pkg_name[256]; 351 char msg_buf[1][1024]; 352 struct aura_dict *seen; 353 354 snprintf(msg_buf[0], sizeof(msg_buf[0]), 355 _("Select optional software packages that you want " 356 "installed on this system. This form lists only the " 357 "software packages installed on the LiveCD; thousands " 358 "more are available via the internet once %s " 359 "is installed."), 360 OPERATING_SYSTEM_NAME); 361 362 f = dfui_form_create( 363 "install_packages", 364 _("Install Packages"), 365 msg_buf[0], 366 "", 367 368 "p", "special", "dfinstaller_install_packages", 369 370 NULL 371 ); 372 373 ds = dfui_dataset_new(); 374 snprintf(command, 256, "ls %svar/db/pkg", a->os_root); 375 if ((pipe = popen(command, "r")) != NULL) { 376 while (fgets(pkg_name, 255, pipe) != NULL) { 377 while (strlen(pkg_name) > 0 && 378 isspace(pkg_name[strlen(pkg_name) - 1])) { 379 pkg_name[strlen(pkg_name) - 1] = '\0'; 380 } 381 fi = dfui_form_field_add(f, pkg_name, 382 dfui_info_new(pkg_name, "", "")); 383 dfui_field_property_set(fi, "control", "checkbox"); 384 dfui_dataset_celldata_add(ds, 385 pkg_name, "Y"); 386 } 387 pclose(pipe); 388 } 389 dfui_form_dataset_add(f, ds); 390 391 dfui_form_action_add(f, "ok", 392 dfui_info_new(_("Accept and Install"), "", "")); 393 dfui_form_action_add(f, "cancel", 394 dfui_info_new(_("Return to Configure Menu"), "", "")); 395 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 cmds = commands_new(); 401 seen = aura_dict_new(23, AURA_DICT_HASH); 402 403 cd = dfui_dataset_celldata_get_first(dfui_response_dataset_get_first(r)); 404 405 while (cd != NULL) { 406 strlcpy(pkg_name, dfui_celldata_get_field_id(cd), 256); 407 if (!strcasecmp(dfui_celldata_get_value(cd), "Y")) { 408 if (!pkg_copy(a, cmds, pkg_name, seen)) { 409 inform(a->c, _("Couldn't install package `%s'."), pkg_name); 410 break; 411 } 412 } 413 cd = dfui_celldata_get_next(cd); 414 } 415 416 if (!commands_execute(a, cmds)) { 417 inform(a->c, _("Packages were not fully installed.")); 418 } else { 419 inform(a->c, _("Packages were successfully installed!")); 420 } 421 422 aura_dict_free(seen); 423 commands_free(cmds); 424 } 425 426 dfui_form_free(f); 427 dfui_response_free(r); 428 } 429 430 void 431 fn_remove_packages(struct i_fn_args *a) 432 { 433 FILE *pipe; 434 struct commands *cmds; 435 struct dfui_celldata *cd; 436 struct dfui_dataset *ds; 437 struct dfui_field *fi; 438 struct dfui_form *f; 439 struct dfui_response *r; 440 char command[256]; 441 char pkg_name[256]; 442 struct aura_dict *seen; 443 444 f = dfui_form_create( 445 "remove_packages", 446 _("Remove Packages"), 447 _("Select the installed software packages that you want " 448 "removed from this system."), 449 "", 450 451 "p", "special", "dfinstaller_remove_packages", 452 453 NULL 454 ); 455 456 ds = dfui_dataset_new(); 457 snprintf(command, 256, "ls %smnt/var/db/pkg", a->os_root); 458 if ((pipe = popen(command, "r")) != NULL) { 459 while (fgets(pkg_name, 255, pipe)) { 460 pkg_name[strlen(pkg_name) - 1] = '\0'; 461 fi = dfui_form_field_add(f, pkg_name, 462 dfui_info_new(pkg_name, "", "")); 463 dfui_field_property_set(fi, "control", "checkbox"); 464 dfui_dataset_celldata_add(ds, 465 pkg_name, "N"); 466 } 467 pclose(pipe); 468 } 469 dfui_form_dataset_add(f, ds); 470 471 dfui_form_action_add(f, "ok", 472 dfui_info_new(_("Accept and Remove"), "", "")); 473 dfui_form_action_add(f, "cancel", 474 dfui_info_new(_("Return to Configure Menu"), "", "")); 475 476 if (!dfui_be_present(a->c, f, &r)) 477 abort_backend(); 478 479 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 480 cmds = commands_new(); 481 seen = aura_dict_new(23, AURA_DICT_HASH); 482 483 cd = dfui_dataset_celldata_get_first(dfui_response_dataset_get_first(r)); 484 485 while (cd != NULL) { 486 strlcpy(pkg_name, dfui_celldata_get_field_id(cd), 256); 487 if (!strcasecmp(dfui_celldata_get_value(cd), "Y")) { 488 if (!pkg_remove(a, cmds, pkg_name, seen)) { 489 inform(a->c, _("Couldn't remove package `%s'."), pkg_name); 490 break; 491 } 492 } 493 cd = dfui_celldata_get_next(cd); 494 } 495 496 if (!commands_execute(a, cmds)) { 497 inform(a->c, _("Packages were not fully removed.")); 498 } else { 499 inform(a->c, _("Packages were successfully removed.")); 500 } 501 502 aura_dict_free(seen); 503 commands_free(cmds); 504 } 505 506 dfui_form_free(f); 507 dfui_response_free(r); 508 } 509 510 /** LIVECD UTILITIES FUNCTIONS **/ 511 512 /* 513 * String returned by this function must be deallocated by the caller. 514 */ 515 char * 516 fn_select_file(const char *title, const char *desc, const char *help, const char *cancel, 517 const char *dir, const char *ext, const struct i_fn_args *a) 518 { 519 DIR *d; 520 struct dfui_form *f; 521 struct dfui_action *k; 522 struct dfui_response *r; 523 struct dirent *de; 524 char *s; 525 struct aura_dict *dict; 526 char *rk; 527 size_t rk_len; 528 529 f = dfui_form_create( 530 "select_file", 531 title, desc, help, 532 "p", "role", "menu", 533 NULL 534 ); 535 536 dict = aura_dict_new(1, AURA_DICT_SORTED_LIST); 537 d = opendir(dir); 538 while ((de = readdir(d)) != NULL) { 539 if (strcmp(de->d_name, ".") == 0 || 540 strcmp(de->d_name, "..") == 0 || 541 strstr(de->d_name, ext) == NULL) 542 continue; 543 aura_dict_store(dict, de->d_name, strlen(de->d_name) + 1, "", 1); 544 } 545 closedir(d); 546 547 aura_dict_rewind(dict); 548 while (!aura_dict_eof(dict)) { 549 aura_dict_get_current_key(dict, (void **)&rk, &rk_len), 550 dfui_form_action_add(f, rk, 551 dfui_info_new(rk, "", "")); 552 aura_dict_next(dict); 553 } 554 aura_dict_free(dict); 555 556 k = dfui_form_action_add(f, "cancel", 557 dfui_info_new(cancel, "", "")); 558 dfui_action_property_set(k, "accelerator", "ESC"); 559 560 if (!dfui_be_present(a->c, f, &r)) 561 abort_backend(); 562 563 s = aura_strdup(dfui_response_get_action_id(r)); 564 565 dfui_form_free(f); 566 dfui_response_free(r); 567 568 return(s); 569 } 570 571 void 572 fn_set_kbdmap(struct i_fn_args *a) 573 { 574 struct commands *cmds; 575 char *s; 576 char filename[256], keymapname[256]; 577 578 s = fn_select_file(_("Select Keyboard Map"), 579 _("Select a keyboard map appropriate to your keyboard layout."), 580 "", _("Return to Utilities Menu"), "/usr/share/syscons/keymaps", 581 ".kbd", a); 582 583 if (strcmp(s, "cancel") != 0) { 584 cmds = commands_new(); 585 command_add(cmds, "%s%s -l " 586 "/usr/share/syscons/keymaps/%s < /dev/ttyv0", 587 a->os_root, cmd_name(a, "KBDCONTROL"), 588 s); 589 if (commands_execute(a, cmds)) { 590 snprintf(filename, 256, "/usr/share/syscons/keymaps/%s", s); 591 snprintf(keymapname, 256, filename_noext(basename(filename))); 592 config_var_set(rc_conf, "keymap", keymapname); 593 } else { 594 inform(a->c, _("Keyboard map not successfully set.")); 595 } 596 commands_free(cmds); 597 } 598 599 free(s); 600 } 601 602 void 603 fn_set_vidfont(struct i_fn_args *a) 604 { 605 struct commands *cmds; 606 char *s; 607 char filename[256], variable[256], fontname[256]; 608 int by = 0; 609 610 611 s = fn_select_file(_("Select Console Font"), 612 _("Select a font appropriate to your video monitor and language."), 613 "", _("Return to Utilities Menu"), "/usr/share/syscons/fonts", 614 ".fnt", a); 615 616 if (strcmp(s, "cancel") != 0) { 617 cmds = commands_new(); 618 command_add(cmds, "%s%s -f " 619 "/usr/share/syscons/fonts/%s < /dev/ttyv0", 620 a->os_root, cmd_name(a, "VIDCONTROL"), 621 s); 622 if (commands_execute(a, cmds)) { 623 if (strstr(s, "8x16") != NULL) 624 by = 16; 625 else if (strstr(s, "8x14") != NULL) 626 by = 14; 627 else 628 by = 8; 629 630 snprintf(variable, 256, "font8x%d", by); 631 snprintf(filename, 256, "/usr/share/syscons/fonts/%s", s); 632 snprintf(fontname, 256, filename_noext(basename(filename))); 633 config_var_set(rc_conf, variable, fontname); 634 635 } else { 636 inform(a->c, _("Video font not successfully set.")); 637 } 638 commands_free(cmds); 639 } 640 641 free(s); 642 } 643 644 void 645 fn_set_scrnmap(struct i_fn_args *a) 646 { 647 struct commands *cmds; 648 char *s; 649 char filename[256], scrnmapname[256]; 650 651 s = fn_select_file(_("Select Screen Map"), 652 _("Select a mapping for translating characters as they appear " 653 "on your video console screen."), 654 "", _("Return to Utilities Menu"), "/usr/share/syscons/scrnmaps", 655 ".scm", a); 656 657 if (strcmp(s, "cancel") != 0) { 658 cmds = commands_new(); 659 command_add(cmds, "%s%s -l " 660 "/usr/share/syscons/scrnmaps/%s < /dev/ttyv0", 661 a->os_root, cmd_name(a, "VIDCONTROL"), 662 s); 663 if (commands_execute(a, cmds)) { 664 snprintf(filename, 256, "/usr/share/syscons/scrnmaps/%s", s); 665 snprintf(scrnmapname, 256, filename_noext(basename(filename))); 666 config_var_set(rc_conf, "scrnmap", scrnmapname); 667 } else { 668 inform(a->c, _("Video font not successfully set.")); 669 } 670 commands_free(cmds); 671 } 672 free(s); 673 } 674 675 void 676 fn_set_timezone(struct i_fn_args *a) 677 { 678 struct commands *cmds; 679 char *s = NULL; 680 char current_path[256], selection[256], temp[256]; 681 int found_file = 0; 682 683 cmds = commands_new(); 684 685 switch (dfui_be_present_dialog(a->c, _("Local or UTC (Greenwich Mean Time) clock"), 686 _("Yes|No"), 687 _("Is this machine's CMOS clock set to UTC?\n"), 688 _("If it is set to local time, or you don't know, please choose NO here!"))) { 689 case 1: 690 cmds = commands_new(); 691 command_add(cmds, "%s%s %s%setc/wall_cmos_clock", 692 a->os_root, cmd_name(a, "TOUCH"), 693 a->os_root, a->cfg_root); 694 commands_execute(a, cmds); 695 } 696 697 snprintf(current_path, 256, "%s%susr/share/zoneinfo", 698 a->os_root, a->cfg_root); 699 while (!found_file) { 700 if (s != NULL) 701 free(s); 702 s = fn_select_file(_("Select Time Zone"), 703 _("Select a Time Zone appropriate to your physical location."), 704 "", _("Return to Utilities Menu"), current_path, 705 "", a); 706 if (is_dir("%s/%s", current_path, s)) { 707 snprintf(temp, 256, "%s/%s", current_path, s); 708 strlcpy(current_path, temp, 256); 709 } else { 710 if (is_file("%s/%s", current_path, s)) { 711 snprintf(selection, 256, "%s/%s", current_path, s); 712 found_file = 1; 713 } 714 if (strcmp(s, "cancel") == 0) { 715 strlcpy(selection, "cancel", 256); 716 found_file = 1; 717 } 718 } 719 } 720 free(s); 721 722 if (strcmp(selection, "cancel") != 0) { 723 command_add(cmds, "%s%s %s %s%setc/localtime", 724 a->os_root, cmd_name(a, "CP"), 725 selection, 726 a->os_root, a->cfg_root); 727 if (commands_execute(a, cmds)) 728 inform(a->c, _("The Time Zone has been set to %s."), selection); 729 } 730 commands_free(cmds); 731 } 732 733 void 734 fn_assign_datetime(struct i_fn_args *a) 735 { 736 struct commands *cmds; 737 struct dfui_dataset *ds, *new_ds; 738 struct dfui_form *f; 739 struct dfui_response *r; 740 struct tm *tp; 741 char temp[256]; 742 int year, month, dayofmonth, hour, minutes; 743 int valid = 1; 744 time_t now; 745 746 now = time(NULL); 747 tp = localtime(&now); 748 749 f = dfui_form_create( 750 "set_datetime", 751 _("Set Time/Date"), 752 _("Enter the current time and date."), 753 "", 754 755 "f", "year", _("Enter year"), 756 _("Enter the current year (e.g. `2004')"), "", 757 "f", "month", _("Month"), 758 _("Enter the current month (e.g. `07')"), "", 759 "f", "dayofmonth", "dayofmonth", 760 _("Enter the current day of month (e.g. `30')"), "", 761 "f", "hour", "hour", 762 _("Enter the current hour (e.g. `07')"), "", 763 "f", "minutes", "minutes", 764 _("Enter the current minutes (e.g. `59')"), "", 765 766 "a", "ok", _("OK"), "", "", 767 "a", "cancel", _("Cancel"), "", "", 768 "p", "accelerator", "ESC", 769 770 NULL 771 ); 772 773 ds = dfui_dataset_new(); 774 snprintf(temp, 256, "%i", (tp->tm_year+1900)); 775 dfui_dataset_celldata_add(ds, "year", temp); 776 snprintf(temp, 256, "%i", (tp->tm_mon+1)); 777 dfui_dataset_celldata_add(ds, "month", temp); 778 snprintf(temp, 256, "%i", tp->tm_mday); 779 dfui_dataset_celldata_add(ds, "dayofmonth", temp); 780 snprintf(temp, 256, "%i", tp->tm_hour); 781 dfui_dataset_celldata_add(ds, "hour", temp); 782 snprintf(temp, 256, "%i", tp->tm_min); 783 dfui_dataset_celldata_add(ds, "minutes", temp); 784 dfui_form_dataset_add(f, ds); 785 786 if (!dfui_be_present(a->c, f, &r)) 787 abort_backend(); 788 789 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 790 new_ds = dfui_response_dataset_get_first(r); 791 792 if ((year = atoi(dfui_dataset_get_value(new_ds, "year"))) <= 0) 793 valid = 0; 794 month = atoi(dfui_dataset_get_value(new_ds, "month")); 795 if (month < 1 || month > 12) 796 valid = 0; 797 dayofmonth = atoi(dfui_dataset_get_value(new_ds, "dayofmonth")); 798 if (dayofmonth < 1 || dayofmonth > 31) 799 valid = 0; 800 hour = atoi(dfui_dataset_get_value(new_ds, "hour")); 801 if (hour < 0 || hour > 23) 802 valid = 0; 803 minutes = atoi(dfui_dataset_get_value(new_ds, "minutes")); 804 if (minutes < 0 || minutes > 59) 805 valid = 0; 806 807 if (valid) { 808 cmds = commands_new(); 809 command_add(cmds, "%s%s -n %04d%02d%02d%02d%02d", 810 a->os_root, cmd_name(a, "DATE"), 811 year, month, dayofmonth, hour, minutes); 812 if (commands_execute(a, cmds)) { 813 inform(a->c, _("The date and time have been set.")); 814 } 815 commands_free(cmds); 816 } else { 817 inform(a->c, _("Please enter numbers within acceptable ranges " 818 "for year, month, day of month, hour, and minute.")); 819 } 820 } 821 } 822 823 void 824 fn_assign_hostname_domain(struct i_fn_args *a) 825 { 826 struct dfui_form *f; 827 struct dfui_response *r; 828 struct dfui_dataset *ds, *new_ds; 829 struct config_vars *resolv_conf; 830 const char *domain, *hostname; 831 char *fqdn; 832 833 f = dfui_form_create( 834 "set_hostname_domain", 835 _("Set Hostname/Domain"), 836 _("Please enter this machine's hostname and domain name."), 837 "", 838 839 "f", "hostname", _("Hostname"), 840 _("Enter the Hostname (e.g. `machine')"), "", 841 "f", "domain", _("Domain"), 842 _("Enter the Domain Name (e.g. `network.lan')"), "", 843 844 "a", "ok", _("OK"), "", "", 845 "a", "cancel", _("Cancel"), "", "", 846 "p", "accelerator", "ESC", 847 848 NULL 849 ); 850 851 ds = dfui_dataset_new(); 852 dfui_dataset_celldata_add(ds, "hostname", ""); 853 dfui_dataset_celldata_add(ds, "domain", ""); 854 dfui_form_dataset_add(f, ds); 855 856 if (!dfui_be_present(a->c, f, &r)) 857 abort_backend(); 858 859 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 860 new_ds = dfui_response_dataset_get_first(r); 861 862 hostname = dfui_dataset_get_value(new_ds, "hostname"); 863 domain = dfui_dataset_get_value(new_ds, "domain"); 864 asprintf(&fqdn, "%s.%s", hostname, domain); 865 866 resolv_conf = config_vars_new(); 867 868 config_var_set(rc_conf, "hostname", fqdn); 869 config_var_set(resolv_conf, "search", domain); 870 config_vars_write(resolv_conf, CONFIG_TYPE_RESOLV, 871 "%s%setc/resolv.conf", "/", a->cfg_root); 872 873 config_vars_free(resolv_conf); 874 875 free(fqdn); 876 } 877 878 dfui_form_free(f); 879 dfui_response_free(r); 880 } 881 882 void 883 fn_assign_ip(struct i_fn_args *a) 884 { 885 FILE *p; 886 struct commands *cmds; 887 struct command *cmd; 888 struct config_vars *resolv_conf; 889 struct dfui_dataset *ds, *new_ds; 890 struct dfui_form *f; 891 struct dfui_action *k; 892 struct dfui_response *r; 893 const char *domain, *hostname; 894 const char *interface_ip, *interface_netmask, *defaultrouter, *dns_resolver; 895 char *string, *string1; 896 char *word; 897 char interface[256]; 898 char line[256]; 899 int write_config = 0; 900 901 /* 902 * Get interface list. 903 */ 904 p = popen("/sbin/ifconfig -l", "r"); 905 /* XXX it's possible (though extremely unlikely) this will fail. */ 906 while (fgets(line, 255, p) != NULL) 907 line[strlen(line) - 1] = '\0'; 908 909 pclose(p); 910 911 f = dfui_form_create( 912 "assign_ip", 913 _("Assign IP Address"), 914 _("Please select which interface you would like to configure:"), 915 "", 916 "p", "role", "menu", 917 NULL 918 ); 919 920 /* Loop through array. */ 921 word = strtok(line, " \t"); 922 while (word != NULL) { 923 dfui_form_action_add(f, word, 924 dfui_info_new(word, "", "")); 925 word = strtok(NULL, " "); 926 } 927 928 k = dfui_form_action_add(f, "cancel", 929 dfui_info_new("Cancel", "", "")); 930 dfui_action_property_set(k, "accelerator", "ESC"); 931 932 if (!dfui_be_present(a->c, f, &r)) 933 abort_backend(); 934 935 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 936 dfui_form_free(f); 937 dfui_response_free(r); 938 return; 939 } 940 941 strlcpy(interface, dfui_response_get_action_id(r), 256); 942 943 resolv_conf = config_vars_new(); 944 945 switch (dfui_be_present_dialog(a->c, _("Use DHCP?"), 946 _("Use DHCP|Configure Manually"), 947 _("DHCP allows the interface to automatically obtain " 948 "an IP address from a nearby DHCP server.\n\n" 949 "Would you like to enable DHCP for %s?"), interface)) { 950 case 1: 951 asprintf(&string, "ifconfig_%s", interface); 952 953 cmds = commands_new(); 954 cmd = command_add(cmds, "%s%s dhclient", 955 a->os_root, cmd_name(a, "KILLALL")); 956 command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE); 957 command_add(cmds, "%s%s %s", 958 a->os_root, cmd_name(a, "DHCLIENT"), 959 interface); 960 if (commands_execute(a, cmds)) { 961 /* XXX sleep(3); */ 962 show_ifconfig(a->c, interface); 963 write_config = 1; 964 } else { 965 switch (dfui_be_present_dialog(a->c, _("DHCP Failure"), 966 _("Yes|No"), 967 _("Warning: could not enable dhclient for %s.\n\n" 968 "Write the corresponding settings to rc.conf " 969 "anyway?"), interface)) { 970 case 1: 971 write_config = 1; 972 break; 973 case 2: 974 write_config = 0; 975 break; 976 default: 977 abort_backend(); 978 } 979 } 980 commands_free(cmds); 981 config_var_set(rc_conf, string, "DHCP"); 982 free(string); 983 break; 984 case 2: 985 dfui_form_free(f); 986 dfui_response_free(r); 987 f = dfui_form_create( 988 "assign_ip", 989 _("Assign IP Address"), 990 _("Configuring Interface:"), 991 "", 992 993 "f", "interface_ip", _("IP Address"), 994 _("Enter the IP Address you would like to use"), "", 995 "f", "interface_netmask", _("Netmask"), 996 _("Enter the netmask of the IP address"), "", 997 "f", "defaultrouter", _("Default Router"), 998 _("Enter the IP address of the default router"), "", 999 "f", "dns_resolver", _("Primary DNS Server"), 1000 _("Enter the IP address of primary DNS Server"), "", 1001 "f", "hostname", _("Hostname"), 1002 _("Enter the Hostname"), "", 1003 "f", "domain", _("Domain"), 1004 _("Enter the Domain Name"), "", 1005 1006 "a", "ok", _("Configure Interface"), 1007 "", "", 1008 "a", "cancel", _("Return to Utilities Menu"), 1009 "", "", 1010 "p", "accelerator", "ESC", 1011 1012 NULL 1013 ); 1014 1015 ds = dfui_dataset_new(); 1016 dfui_dataset_celldata_add(ds, "interface_netmask", ""); 1017 dfui_dataset_celldata_add(ds, "defaultrouter", ""); 1018 dfui_dataset_celldata_add(ds, "dns_resolver", ""); 1019 dfui_dataset_celldata_add(ds, "hostname", ""); 1020 dfui_dataset_celldata_add(ds, "domain", ""); 1021 dfui_dataset_celldata_add(ds, "interface_ip", ""); 1022 dfui_form_dataset_add(f, ds); 1023 1024 if (!dfui_be_present(a->c, f, &r)) 1025 abort_backend(); 1026 1027 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 1028 new_ds = dfui_response_dataset_get_first(r); 1029 1030 interface_ip = dfui_dataset_get_value(new_ds, "interface_ip"); 1031 interface_netmask = dfui_dataset_get_value(new_ds, "interface_netmask"); 1032 defaultrouter = dfui_dataset_get_value(new_ds, "defaultrouter"); 1033 dns_resolver = dfui_dataset_get_value(new_ds, "dns_resolver"); 1034 hostname = dfui_dataset_get_value(new_ds, "hostname"); 1035 domain = dfui_dataset_get_value(new_ds, "domain"); 1036 1037 asprintf(&string, "ifconfig_%s", interface); 1038 asprintf(&string1, "inet %s netmask %s", 1039 interface_ip, interface_netmask); 1040 1041 cmds = commands_new(); 1042 command_add(cmds, "%s%s %s %s netmask %s", 1043 a->os_root, cmd_name(a, "IFCONFIG"), 1044 interface, interface_ip, interface_netmask); 1045 command_add(cmds, "%s%s add default %s", 1046 a->os_root, cmd_name(a, "ROUTE"), 1047 defaultrouter); 1048 1049 if (commands_execute(a, cmds)) { 1050 /* XXX sleep(3); */ 1051 show_ifconfig(a->c, interface); 1052 write_config = 1; 1053 } else { 1054 switch (dfui_be_present_dialog(a->c, 1055 _("ifconfig Failure"), 1056 _("Yes|No"), 1057 _("Warning: could not assign IP address " 1058 "or default gateway.\n\n" 1059 "Write the corresponding settings to " 1060 "rc.conf anyway?"))) { 1061 case 1: 1062 write_config = 1; 1063 break; 1064 case 2: 1065 write_config = 0; 1066 break; 1067 default: 1068 abort_backend(); 1069 } 1070 } 1071 commands_free(cmds); 1072 1073 config_var_set(rc_conf, string, string1); 1074 config_var_set(rc_conf, "defaultrouter", defaultrouter); 1075 1076 free(string); 1077 free(string1); 1078 1079 asprintf(&string, "%s.%s", hostname, domain); 1080 config_var_set(rc_conf, "hostname", string); 1081 free(string); 1082 1083 config_var_set(resolv_conf, "search", domain); 1084 config_var_set(resolv_conf, "nameserver", dns_resolver); 1085 } 1086 break; 1087 default: 1088 abort_backend(); 1089 } 1090 1091 if (write_config) { 1092 /* 1093 * Save out changes to /etc/rc.conf and /etc/resolv.conf. 1094 */ 1095 config_vars_write(resolv_conf, CONFIG_TYPE_RESOLV, 1096 "%s%setc/resolv.conf", a->os_root, a->cfg_root); 1097 } 1098 1099 config_vars_free(resolv_conf); 1100 1101 dfui_form_free(f); 1102 dfui_response_free(r); 1103 } 1104 1105 static const char * 1106 yes_to_y(const char *value) 1107 { 1108 return(strcasecmp(value, "YES") == 0 ? "Y" : "N"); 1109 } 1110 1111 void 1112 fn_select_services(struct i_fn_args *a) 1113 { 1114 struct dfui_dataset *ds; 1115 struct dfui_form *f; 1116 struct dfui_response *r; 1117 1118 if (!config_vars_read(a, rc_conf, CONFIG_TYPE_SH, "%setc/rc.conf", a->cfg_root)) { 1119 inform(a->c, _("Couldn't read %s%setc/rc.conf."), 1120 a->os_root, a->cfg_root); 1121 a->result = 0; 1122 return; 1123 } 1124 1125 f = dfui_form_create( 1126 "select_services", 1127 _("Select Services"), 1128 _("Please select which services you would like started at boot time."), 1129 "", 1130 1131 "f", "syslogd", "syslogd", 1132 _("System Logging Daemon"), "", 1133 "p", "control", "checkbox", 1134 "f", "inetd", "inetd", 1135 _("Internet Super-Server"), "", 1136 "p", "control", "checkbox", 1137 "f", "named", "named", 1138 _("BIND Name Server"), "", 1139 "p", "control", "checkbox", 1140 "f", "ntpd", "ntpd", 1141 _("Network Time Protocol Daemon"), "", 1142 "p", "control", "checkbox", 1143 "f", "sshd", "sshd", 1144 _("Secure Shell Daemon"), "", 1145 "p", "control", "checkbox", 1146 1147 "a", "ok", _("Enable/Disable Services"), 1148 "", "", 1149 "a", "cancel", _("Return to Utilities Menu"), 1150 "", "", 1151 "p", "accelerator", "ESC", 1152 1153 NULL 1154 ); 1155 1156 ds = dfui_dataset_new(); 1157 dfui_dataset_celldata_add(ds, "syslogd", 1158 yes_to_y(config_var_get(rc_conf, "syslogd_enable"))); 1159 dfui_dataset_celldata_add(ds, "inetd", 1160 yes_to_y(config_var_get(rc_conf, "inetd_enable"))); 1161 dfui_dataset_celldata_add(ds, "named", 1162 yes_to_y(config_var_get(rc_conf, "named_enable"))); 1163 dfui_dataset_celldata_add(ds, "ntpd", 1164 yes_to_y(config_var_get(rc_conf, "ntpd_enable"))); 1165 dfui_dataset_celldata_add(ds, "sshd", 1166 yes_to_y(config_var_get(rc_conf, "sshd_enable"))); 1167 dfui_form_dataset_add(f, ds); 1168 1169 if (!dfui_be_present(a->c, f, &r)) 1170 abort_backend(); 1171 1172 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 1173 dfui_form_free(f); 1174 dfui_response_free(r); 1175 return; 1176 } 1177 1178 dfui_form_free(f); 1179 dfui_response_free(r); 1180 } 1181 1182 /*** NON-fn_ FUNCTIONS ***/ 1183 1184 /* 1185 * Caller is responsible for deallocation. 1186 */ 1187 static char * 1188 convert_tmpfs_options(char *line) 1189 { 1190 char *result, *word; 1191 int i; 1192 1193 result = malloc(256); 1194 result[0] = '\0'; 1195 1196 for (; (word = strsep(&line, ",")) != NULL; ) { 1197 if (word[0] == '-') { 1198 /* 1199 * Don't bother trying to honour the -C 1200 * option, since we can't copy files from 1201 * the right place anyway. 1202 */ 1203 if (strcmp(word, "-C") != 0) { 1204 for (i = 0; word[i] != '\0'; i++) { 1205 if (word[i] == '=') 1206 word[i] = ' '; 1207 } 1208 strlcat(result, word, 256); 1209 strlcat(result, " ", 256); 1210 } 1211 } 1212 } 1213 1214 return(result); 1215 } 1216 1217 /* 1218 * Uses ss->selected_{disk,slice} as the target system. 1219 */ 1220 int 1221 mount_target_system(struct i_fn_args *a) 1222 { 1223 FILE *fstab; 1224 struct commands *cmds; 1225 struct subpartition *a_subpart; 1226 char device[256], mtpt[256], fstype[256], options[256]; 1227 char *filename, line[256]; 1228 const char *try_mtpt[5] = {"/var", "/tmp", "/usr", "/home", NULL}; 1229 char *word, *cvtoptions; 1230 int i; 1231 1232 /* 1233 * Mount subpartitions from this installation if they are 1234 * not already mounted. Tricky, as we need to honour the 1235 * installation's loader.conf and fstab. 1236 */ 1237 cmds = commands_new(); 1238 1239 /* 1240 * First, unmount anything already mounted on /mnt. 1241 */ 1242 unmount_all_under(a, cmds, "%smnt", a->os_root); 1243 1244 /* 1245 * Reset and clear out subpartitions so that system 1246 * can make a "dummy" subpart. 1247 */ 1248 subpartitions_free(storage_get_selected_slice(a->s)); 1249 1250 /* 1251 * Create a temporary dummy subpartition - that we 1252 * assume exists 1253 */ 1254 1255 a_subpart = subpartition_new(storage_get_selected_slice(a->s), 1256 "/dummy", 0, 0, 0, 0, 0); 1257 1258 /* 1259 * Mount the target's / and read its /etc/fstab. 1260 */ 1261 if (use_hammer == 0) { 1262 command_add(cmds, "%s%s %sdev/%s %s%s", 1263 a->os_root, cmd_name(a, "MOUNT"), 1264 a->os_root, 1265 subpartition_get_device_name(a_subpart), 1266 a->os_root, a->cfg_root); 1267 } else { 1268 command_add(cmds, "%s%s %sdev/%s %sboot", 1269 a->os_root, cmd_name(a, "MOUNT"), 1270 a->os_root, 1271 subpartition_get_device_name(a_subpart), 1272 a->os_root, a->cfg_root); 1273 command_add(cmds, 1274 "%s%s %sdev/`%s%s \"^vfs\\.root\\.mountfrom\" %sboot/loader.conf |" 1275 "%s%s -Fhammer: '{print $2;}' |" 1276 "%s%s 's/\"//'` %s%s", 1277 a->os_root, cmd_name(a, "MOUNT_HAMMER"), 1278 a->os_root, 1279 a->os_root, cmd_name(a, "GREP"), 1280 a->os_root, 1281 a->os_root, cmd_name(a, "AWK"), 1282 a->os_root, cmd_name(a, "SED"), 1283 a->os_root, a->cfg_root); 1284 command_add(cmds, "%s%s %sboot", 1285 a->os_root, cmd_name(a, "UMOUNT"), 1286 a->os_root, a->cfg_root); 1287 } 1288 if (!commands_execute(a, cmds)) { 1289 commands_free(cmds); 1290 return(0); 1291 } 1292 commands_free(cmds); 1293 1294 /* 1295 * Get rid of the dummy subpartition. 1296 */ 1297 subpartitions_free(storage_get_selected_slice(a->s)); 1298 1299 asprintf(&filename, "%s%s/etc/fstab", a->os_root, a->cfg_root); 1300 fstab = fopen(filename, "r"); 1301 free(filename); 1302 if (fstab == NULL) { 1303 inform(a->c, _("Filesystem table on installed system could not be read.")); 1304 cmds = commands_new(); 1305 command_add(cmds, "%s%s %s%s", 1306 a->os_root, cmd_name(a, "UMOUNT"), 1307 a->os_root, a->cfg_root); 1308 if (!commands_execute(a, cmds)) { 1309 inform(a->c, _("Warning: Installed system was not properly unmounted.")); 1310 } 1311 commands_free(cmds); 1312 return(0); 1313 } 1314 1315 cmds = commands_new(); 1316 1317 while (fgets(line, 256, fstab) != NULL) { 1318 /* 1319 * Parse the fstab line. 1320 */ 1321 if (first_non_space_char_is(line, '#')) 1322 continue; 1323 if ((word = strtok(line, " \t")) == NULL) 1324 continue; 1325 strlcpy(device, word, 256); 1326 if ((word = strtok(NULL, " \t")) == NULL) 1327 continue; 1328 strlcpy(mtpt, word, 256); 1329 if ((word = strtok(NULL, " \t")) == NULL) 1330 continue; 1331 strlcpy(fstype, word, 256); 1332 if ((word = strtok(NULL, " \t")) == NULL) 1333 continue; 1334 strlcpy(options, word, 256); 1335 1336 /* 1337 * Now, if the mountpoint has /usr, /var, /tmp, or /home 1338 * as a prefix, mount it under a->cfg_root. 1339 */ 1340 for (i = 0; try_mtpt[i] != NULL; i++) { 1341 if (strstr(mtpt, try_mtpt[i]) == mtpt) { 1342 /* 1343 * Don't mount it if it's optional. 1344 */ 1345 if (strstr(options, "noauto") != NULL) 1346 continue; 1347 1348 /* 1349 * Don't mount it if device doesn't start 1350 * with /dev/ or /pfs and it isn't 'tmpfs'. 1351 */ 1352 if (strstr(device, "/dev/") != NULL && 1353 strstr(device, "/pfs/") != NULL && 1354 strcmp(device, "tmpfs") != 0) 1355 continue; 1356 1357 /* 1358 * If the device is 'tmpfs', mount_tmpfs it instead. 1359 */ 1360 if (strcmp(device, "tmpfs") == 0) { 1361 cvtoptions = convert_tmpfs_options(options); 1362 command_add(cmds, 1363 "%s%s %s tmpfs %s%s%s", 1364 a->os_root, cmd_name(a, "MOUNT_TMPFS"), 1365 cvtoptions, a->os_root, a->cfg_root, mtpt); 1366 free(cvtoptions); 1367 } else { 1368 if (use_hammer == 0) { 1369 command_add(cmds, 1370 "%s%s -o %s %s%s %s%s%s", 1371 a->os_root, cmd_name(a, "MOUNT"), 1372 options, 1373 a->os_root, device, a->os_root, 1374 a->cfg_root, mtpt); 1375 } else { 1376 command_add(cmds, 1377 "%s%s -o %s %s%s%s %s%s%s", 1378 a->os_root, cmd_name(a, "MOUNT_NULL"), 1379 options, 1380 a->os_root, a->cfg_root, device, a->os_root, 1381 a->cfg_root, mtpt); 1382 } 1383 } 1384 } 1385 } 1386 } 1387 fclose(fstab); 1388 1389 if (!commands_execute(a, cmds)) { 1390 commands_free(cmds); 1391 return(0); 1392 } 1393 commands_free(cmds); 1394 1395 return(1); 1396 } 1397