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_swap_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_cvsup_sources(struct i_fn_args *a) 341 { 342 struct commands *cmds; 343 344 inform(a->c, _("The system has issued a cvsup command in the background.\n\nPlease tail /tmp/cvsupdate.log if you wish to follow the progress.")); 345 346 // TODO: This needs a lot more work. 347 348 cmds = commands_new(); 349 command_add(cmds, "%s%s -h cvsup.dragonflybsd.com -b /usr " 350 "/usr/share/examples/cvsup/DragonFly-supfile >/tmp/cvsupdate.log", 351 a->os_root, cmd_name(a, "CVSUP")); 352 if (!commands_execute(a, cmds)) 353 inform(a->c, _("Warning: could not launch cvsup")); 354 355 commands_free(cmds); 356 } 357 358 void 359 fn_install_packages(struct i_fn_args *a) 360 { 361 FILE *pipe; 362 struct commands *cmds; 363 struct dfui_celldata *cd; 364 struct dfui_dataset *ds; 365 struct dfui_field *fi; 366 struct dfui_form *f; 367 struct dfui_response *r; 368 char command[256]; 369 char pkg_name[256]; 370 char msg_buf[1][1024]; 371 struct aura_dict *seen; 372 373 snprintf(msg_buf[0], sizeof(msg_buf[0]), 374 _("Select optional software packages that you want " 375 "installed on this system. This form lists only the " 376 "software packages installed on the LiveCD; thousands " 377 "more are available via the internet once %s " 378 "is installed."), 379 OPERATING_SYSTEM_NAME); 380 381 f = dfui_form_create( 382 "install_packages", 383 _("Install Packages"), 384 msg_buf[0], 385 "", 386 387 "p", "special", "dfinstaller_install_packages", 388 389 NULL 390 ); 391 392 ds = dfui_dataset_new(); 393 snprintf(command, 256, "ls %svar/db/pkg", a->os_root); 394 if ((pipe = popen(command, "r")) != NULL) { 395 while (fgets(pkg_name, 255, pipe) != NULL) { 396 while (strlen(pkg_name) > 0 && 397 isspace(pkg_name[strlen(pkg_name) - 1])) { 398 pkg_name[strlen(pkg_name) - 1] = '\0'; 399 } 400 fi = dfui_form_field_add(f, pkg_name, 401 dfui_info_new(pkg_name, "", "")); 402 dfui_field_property_set(fi, "control", "checkbox"); 403 dfui_dataset_celldata_add(ds, 404 pkg_name, "Y"); 405 } 406 pclose(pipe); 407 } 408 dfui_form_dataset_add(f, ds); 409 410 dfui_form_action_add(f, "ok", 411 dfui_info_new(_("Accept and Install"), "", "")); 412 dfui_form_action_add(f, "cancel", 413 dfui_info_new(_("Return to Configure Menu"), "", "")); 414 415 if (!dfui_be_present(a->c, f, &r)) 416 abort_backend(); 417 418 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 419 cmds = commands_new(); 420 seen = aura_dict_new(23, AURA_DICT_HASH); 421 422 cd = dfui_dataset_celldata_get_first(dfui_response_dataset_get_first(r)); 423 424 while (cd != NULL) { 425 strlcpy(pkg_name, dfui_celldata_get_field_id(cd), 256); 426 if (!strcasecmp(dfui_celldata_get_value(cd), "Y")) { 427 if (!pkg_copy(a, cmds, pkg_name, seen)) { 428 inform(a->c, _("Couldn't install package `%s'."), pkg_name); 429 break; 430 } 431 } 432 cd = dfui_celldata_get_next(cd); 433 } 434 435 if (!commands_execute(a, cmds)) { 436 inform(a->c, _("Packages were not fully installed.")); 437 } else { 438 inform(a->c, _("Packages were successfully installed!")); 439 } 440 441 aura_dict_free(seen); 442 commands_free(cmds); 443 } 444 445 dfui_form_free(f); 446 dfui_response_free(r); 447 } 448 449 void 450 fn_remove_packages(struct i_fn_args *a) 451 { 452 FILE *pipe; 453 struct commands *cmds; 454 struct dfui_celldata *cd; 455 struct dfui_dataset *ds; 456 struct dfui_field *fi; 457 struct dfui_form *f; 458 struct dfui_response *r; 459 char command[256]; 460 char pkg_name[256]; 461 struct aura_dict *seen; 462 463 f = dfui_form_create( 464 "remove_packages", 465 _("Remove Packages"), 466 _("Select the installed software packages that you want " 467 "removed from this system."), 468 "", 469 470 "p", "special", "dfinstaller_remove_packages", 471 472 NULL 473 ); 474 475 ds = dfui_dataset_new(); 476 snprintf(command, 256, "ls %smnt/var/db/pkg", a->os_root); 477 if ((pipe = popen(command, "r")) != NULL) { 478 while (fgets(pkg_name, 255, pipe)) { 479 pkg_name[strlen(pkg_name) - 1] = '\0'; 480 fi = dfui_form_field_add(f, pkg_name, 481 dfui_info_new(pkg_name, "", "")); 482 dfui_field_property_set(fi, "control", "checkbox"); 483 dfui_dataset_celldata_add(ds, 484 pkg_name, "N"); 485 } 486 pclose(pipe); 487 } 488 dfui_form_dataset_add(f, ds); 489 490 dfui_form_action_add(f, "ok", 491 dfui_info_new(_("Accept and Remove"), "", "")); 492 dfui_form_action_add(f, "cancel", 493 dfui_info_new(_("Return to Configure Menu"), "", "")); 494 495 if (!dfui_be_present(a->c, f, &r)) 496 abort_backend(); 497 498 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 499 cmds = commands_new(); 500 seen = aura_dict_new(23, AURA_DICT_HASH); 501 502 cd = dfui_dataset_celldata_get_first(dfui_response_dataset_get_first(r)); 503 504 while (cd != NULL) { 505 strlcpy(pkg_name, dfui_celldata_get_field_id(cd), 256); 506 if (!strcasecmp(dfui_celldata_get_value(cd), "Y")) { 507 if (!pkg_remove(a, cmds, pkg_name, seen)) { 508 inform(a->c, _("Couldn't remove package `%s'."), pkg_name); 509 break; 510 } 511 } 512 cd = dfui_celldata_get_next(cd); 513 } 514 515 if (!commands_execute(a, cmds)) { 516 inform(a->c, _("Packages were not fully removed.")); 517 } else { 518 inform(a->c, _("Packages were successfully removed.")); 519 } 520 521 aura_dict_free(seen); 522 commands_free(cmds); 523 } 524 525 dfui_form_free(f); 526 dfui_response_free(r); 527 } 528 529 /** LIVECD UTILITIES FUNCTIONS **/ 530 531 /* 532 * String returned by this function must be deallocated by the caller. 533 */ 534 char * 535 fn_select_file(const char *title, const char *desc, const char *help, const char *cancel, 536 const char *dir, const char *ext, const struct i_fn_args *a) 537 { 538 DIR *d; 539 struct dfui_form *f; 540 struct dfui_action *k; 541 struct dfui_response *r; 542 struct dirent *de; 543 char *s; 544 struct aura_dict *dict; 545 char *rk; 546 size_t rk_len; 547 548 f = dfui_form_create( 549 "select_file", 550 title, desc, help, 551 "p", "role", "menu", 552 NULL 553 ); 554 555 dict = aura_dict_new(1, AURA_DICT_SORTED_LIST); 556 d = opendir(dir); 557 while ((de = readdir(d)) != NULL) { 558 if (strcmp(de->d_name, ".") == 0 || 559 strcmp(de->d_name, "..") == 0 || 560 strstr(de->d_name, ext) == NULL) 561 continue; 562 aura_dict_store(dict, de->d_name, strlen(de->d_name) + 1, "", 1); 563 } 564 closedir(d); 565 566 aura_dict_rewind(dict); 567 while (!aura_dict_eof(dict)) { 568 aura_dict_get_current_key(dict, (void **)&rk, &rk_len), 569 dfui_form_action_add(f, rk, 570 dfui_info_new(rk, "", "")); 571 aura_dict_next(dict); 572 } 573 aura_dict_free(dict); 574 575 k = dfui_form_action_add(f, "cancel", 576 dfui_info_new(cancel, "", "")); 577 dfui_action_property_set(k, "accelerator", "ESC"); 578 579 if (!dfui_be_present(a->c, f, &r)) 580 abort_backend(); 581 582 s = aura_strdup(dfui_response_get_action_id(r)); 583 584 dfui_form_free(f); 585 dfui_response_free(r); 586 587 return(s); 588 } 589 590 void 591 fn_set_kbdmap(struct i_fn_args *a) 592 { 593 struct commands *cmds; 594 char *s; 595 char filename[256], keymapname[256]; 596 597 s = fn_select_file(_("Select Keyboard Map"), 598 _("Select a keyboard map appropriate to your keyboard layout."), 599 "", _("Return to Utilities Menu"), "/usr/share/syscons/keymaps", 600 ".kbd", a); 601 602 if (strcmp(s, "cancel") != 0) { 603 cmds = commands_new(); 604 command_add(cmds, "%s%s -l " 605 "/usr/share/syscons/keymaps/%s < /dev/ttyv0", 606 a->os_root, cmd_name(a, "KBDCONTROL"), 607 s); 608 if (commands_execute(a, cmds)) { 609 snprintf(filename, 256, "/usr/share/syscons/keymaps/%s", s); 610 snprintf(keymapname, 256, filename_noext(basename(filename))); 611 config_var_set(rc_conf, "keymap", keymapname); 612 } else { 613 inform(a->c, _("Keyboard map not successfully set.")); 614 } 615 commands_free(cmds); 616 } 617 618 free(s); 619 } 620 621 void 622 fn_set_vidfont(struct i_fn_args *a) 623 { 624 struct commands *cmds; 625 char *s; 626 char filename[256], variable[256], fontname[256]; 627 int by = 0; 628 629 630 s = fn_select_file(_("Select Console Font"), 631 _("Select a font appropriate to your video monitor and language."), 632 "", _("Return to Utilities Menu"), "/usr/share/syscons/fonts", 633 ".fnt", a); 634 635 if (strcmp(s, "cancel") != 0) { 636 cmds = commands_new(); 637 command_add(cmds, "%s%s -f " 638 "/usr/share/syscons/fonts/%s < /dev/ttyv0", 639 a->os_root, cmd_name(a, "VIDCONTROL"), 640 s); 641 if (commands_execute(a, cmds)) { 642 if (strstr(s, "8x16") != NULL) 643 by = 16; 644 else if (strstr(s, "8x14") != NULL) 645 by = 14; 646 else 647 by = 8; 648 649 snprintf(variable, 256, "font8x%d", by); 650 snprintf(filename, 256, "/usr/share/syscons/fonts/%s", s); 651 snprintf(fontname, 256, filename_noext(basename(filename))); 652 config_var_set(rc_conf, variable, fontname); 653 654 } else { 655 inform(a->c, _("Video font not successfully set.")); 656 } 657 commands_free(cmds); 658 } 659 660 free(s); 661 } 662 663 void 664 fn_set_scrnmap(struct i_fn_args *a) 665 { 666 struct commands *cmds; 667 char *s; 668 char filename[256], scrnmapname[256]; 669 670 s = fn_select_file(_("Select Screen Map"), 671 _("Select a mapping for translating characters as they appear " 672 "on your video console screen."), 673 "", _("Return to Utilities Menu"), "/usr/share/syscons/scrnmaps", 674 ".scm", a); 675 676 if (strcmp(s, "cancel") != 0) { 677 cmds = commands_new(); 678 command_add(cmds, "%s%s -l " 679 "/usr/share/syscons/scrnmaps/%s < /dev/ttyv0", 680 a->os_root, cmd_name(a, "VIDCONTROL"), 681 s); 682 if (commands_execute(a, cmds)) { 683 snprintf(filename, 256, "/usr/share/syscons/scrnmaps/%s", s); 684 snprintf(scrnmapname, 256, filename_noext(basename(filename))); 685 config_var_set(rc_conf, "scrnmap", scrnmapname); 686 } else { 687 inform(a->c, _("Video font not successfully set.")); 688 } 689 commands_free(cmds); 690 } 691 free(s); 692 } 693 694 void 695 fn_set_timezone(struct i_fn_args *a) 696 { 697 struct commands *cmds; 698 char *s = NULL; 699 char current_path[256], selection[256], temp[256]; 700 int found_file = 0; 701 702 cmds = commands_new(); 703 704 switch (dfui_be_present_dialog(a->c, _("Local or UTC (Greenwich Mean Time) clock"), 705 _("Yes|No"), 706 _("Is this machine's CMOS clock set to UTC?\n"), 707 _("If it is set to local time, or you don't know, please choose NO here!"))) { 708 case 1: 709 cmds = commands_new(); 710 command_add(cmds, "%s%s %s%setc/wall_cmos_clock", 711 a->os_root, cmd_name(a, "TOUCH"), 712 a->os_root, a->cfg_root); 713 commands_execute(a, cmds); 714 } 715 716 snprintf(current_path, 256, "%s%susr/share/zoneinfo", 717 a->os_root, a->cfg_root); 718 while (!found_file) { 719 if (s != NULL) 720 free(s); 721 s = fn_select_file(_("Select Time Zone"), 722 _("Select a Time Zone appropriate to your physical location."), 723 "", _("Return to Utilities Menu"), current_path, 724 "", a); 725 if (is_dir("%s/%s", current_path, s)) { 726 snprintf(temp, 256, "%s/%s", current_path, s); 727 strlcpy(current_path, temp, 256); 728 } else { 729 if (is_file("%s/%s", current_path, s)) { 730 snprintf(selection, 256, "%s/%s", current_path, s); 731 found_file = 1; 732 } 733 if (strcmp(s, "cancel") == 0) { 734 strlcpy(selection, "cancel", 256); 735 found_file = 1; 736 } 737 } 738 } 739 free(s); 740 741 if (strcmp(selection, "cancel") != 0) { 742 command_add(cmds, "%s%s %s %s%setc/localtime", 743 a->os_root, cmd_name(a, "CP"), 744 selection, 745 a->os_root, a->cfg_root); 746 if (commands_execute(a, cmds)) 747 inform(a->c, _("The Time Zone has been set to %s."), selection); 748 } 749 commands_free(cmds); 750 } 751 752 void 753 fn_assign_datetime(struct i_fn_args *a) 754 { 755 struct commands *cmds; 756 struct dfui_dataset *ds, *new_ds; 757 struct dfui_form *f; 758 struct dfui_response *r; 759 struct tm *tp; 760 char temp[256]; 761 int year, month, dayofmonth, hour, minutes; 762 int valid = 1; 763 time_t now; 764 765 now = time(NULL); 766 tp = localtime(&now); 767 768 f = dfui_form_create( 769 "set_datetime", 770 _("Set Time/Date"), 771 _("Enter the current time and date."), 772 "", 773 774 "f", "year", _("Enter year"), 775 _("Enter the current year (e.g. `2004')"), "", 776 "f", "month", _("Month"), 777 _("Enter the current month (e.g. `07')"), "", 778 "f", "dayofmonth", "dayofmonth", 779 _("Enter the current day of month (e.g. `30')"), "", 780 "f", "hour", "hour", 781 _("Enter the current hour (e.g. `07')"), "", 782 "f", "minutes", "minutes", 783 _("Enter the current minutes (e.g. `59')"), "", 784 785 "a", "ok", _("OK"), "", "", 786 "a", "cancel", _("Cancel"), "", "", 787 "p", "accelerator", "ESC", 788 789 NULL 790 ); 791 792 ds = dfui_dataset_new(); 793 snprintf(temp, 256, "%i", (tp->tm_year+1900)); 794 dfui_dataset_celldata_add(ds, "year", temp); 795 snprintf(temp, 256, "%i", (tp->tm_mon+1)); 796 dfui_dataset_celldata_add(ds, "month", temp); 797 snprintf(temp, 256, "%i", tp->tm_mday); 798 dfui_dataset_celldata_add(ds, "dayofmonth", temp); 799 snprintf(temp, 256, "%i", tp->tm_hour); 800 dfui_dataset_celldata_add(ds, "hour", temp); 801 snprintf(temp, 256, "%i", tp->tm_min); 802 dfui_dataset_celldata_add(ds, "minutes", temp); 803 dfui_form_dataset_add(f, ds); 804 805 if (!dfui_be_present(a->c, f, &r)) 806 abort_backend(); 807 808 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 809 new_ds = dfui_response_dataset_get_first(r); 810 811 if ((year = atoi(dfui_dataset_get_value(new_ds, "year"))) <= 0) 812 valid = 0; 813 month = atoi(dfui_dataset_get_value(new_ds, "month")); 814 if (month < 1 || month > 12) 815 valid = 0; 816 dayofmonth = atoi(dfui_dataset_get_value(new_ds, "dayofmonth")); 817 if (dayofmonth < 1 || dayofmonth > 31) 818 valid = 0; 819 hour = atoi(dfui_dataset_get_value(new_ds, "hour")); 820 if (hour < 0 || hour > 23) 821 valid = 0; 822 minutes = atoi(dfui_dataset_get_value(new_ds, "minutes")); 823 if (minutes < 0 || minutes > 59) 824 valid = 0; 825 826 if (valid) { 827 cmds = commands_new(); 828 command_add(cmds, "%s%s -n %04d%02d%02d%02d%02d", 829 a->os_root, cmd_name(a, "DATE"), 830 year, month, dayofmonth, hour, minutes); 831 if (commands_execute(a, cmds)) { 832 inform(a->c, _("The date and time have been set.")); 833 } 834 commands_free(cmds); 835 } else { 836 inform(a->c, _("Please enter numbers within acceptable ranges " 837 "for year, month, day of month, hour, and minute.")); 838 } 839 } 840 } 841 842 void 843 fn_assign_hostname_domain(struct i_fn_args *a) 844 { 845 struct dfui_form *f; 846 struct dfui_response *r; 847 struct dfui_dataset *ds, *new_ds; 848 struct config_vars *resolv_conf; 849 const char *domain, *hostname; 850 char *fqdn; 851 852 f = dfui_form_create( 853 "set_hostname_domain", 854 _("Set Hostname/Domain"), 855 _("Please enter this machine's hostname and domain name."), 856 "", 857 858 "f", "hostname", _("Hostname"), 859 _("Enter the Hostname (e.g. `machine')"), "", 860 "f", "domain", _("Domain"), 861 _("Enter the Domain Name (e.g. `network.lan')"), "", 862 863 "a", "ok", _("OK"), "", "", 864 "a", "cancel", _("Cancel"), "", "", 865 "p", "accelerator", "ESC", 866 867 NULL 868 ); 869 870 ds = dfui_dataset_new(); 871 dfui_dataset_celldata_add(ds, "hostname", ""); 872 dfui_dataset_celldata_add(ds, "domain", ""); 873 dfui_form_dataset_add(f, ds); 874 875 if (!dfui_be_present(a->c, f, &r)) 876 abort_backend(); 877 878 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 879 new_ds = dfui_response_dataset_get_first(r); 880 881 hostname = dfui_dataset_get_value(new_ds, "hostname"); 882 domain = dfui_dataset_get_value(new_ds, "domain"); 883 asprintf(&fqdn, "%s.%s", hostname, domain); 884 885 resolv_conf = config_vars_new(); 886 887 config_var_set(rc_conf, "hostname", fqdn); 888 config_var_set(resolv_conf, "search", domain); 889 config_vars_write(resolv_conf, CONFIG_TYPE_RESOLV, 890 "%s%setc/resolv.conf", "/", a->cfg_root); 891 892 config_vars_free(resolv_conf); 893 894 free(fqdn); 895 } 896 897 dfui_form_free(f); 898 dfui_response_free(r); 899 } 900 901 void 902 fn_assign_ip(struct i_fn_args *a) 903 { 904 FILE *p; 905 struct commands *cmds; 906 struct command *cmd; 907 struct config_vars *resolv_conf; 908 struct dfui_dataset *ds, *new_ds; 909 struct dfui_form *f; 910 struct dfui_action *k; 911 struct dfui_response *r; 912 const char *domain, *hostname; 913 const char *interface_ip, *interface_netmask, *defaultrouter, *dns_resolver; 914 char *string, *string1; 915 char *word; 916 char interface[256]; 917 char line[256]; 918 int write_config = 0; 919 920 /* 921 * Get interface list. 922 */ 923 p = popen("/sbin/ifconfig -l", "r"); 924 /* XXX it's possible (though extremely unlikely) this will fail. */ 925 while (fgets(line, 255, p) != NULL) 926 line[strlen(line) - 1] = '\0'; 927 928 pclose(p); 929 930 f = dfui_form_create( 931 "assign_ip", 932 _("Assign IP Address"), 933 _("Please select which interface you would like to configure:"), 934 "", 935 "p", "role", "menu", 936 NULL 937 ); 938 939 /* Loop through array. */ 940 word = strtok(line, " \t"); 941 while (word != NULL) { 942 dfui_form_action_add(f, word, 943 dfui_info_new(word, "", "")); 944 word = strtok(NULL, " "); 945 } 946 947 k = dfui_form_action_add(f, "cancel", 948 dfui_info_new("Cancel", "", "")); 949 dfui_action_property_set(k, "accelerator", "ESC"); 950 951 if (!dfui_be_present(a->c, f, &r)) 952 abort_backend(); 953 954 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 955 dfui_form_free(f); 956 dfui_response_free(r); 957 return; 958 } 959 960 strlcpy(interface, dfui_response_get_action_id(r), 256); 961 962 resolv_conf = config_vars_new(); 963 964 switch (dfui_be_present_dialog(a->c, _("Use DHCP?"), 965 _("Use DHCP|Configure Manually"), 966 _("DHCP allows the interface to automatically obtain " 967 "an IP address from a nearby DHCP server.\n\n" 968 "Would you like to enable DHCP for this interface?"))) { 969 case 1: 970 cmds = commands_new(); 971 cmd = command_add(cmds, "%s%s dhclient", 972 a->os_root, cmd_name(a, "KILLALL")); 973 command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE); 974 command_add(cmds, "%s%s %s", 975 a->os_root, cmd_name(a, "DHCLIENT"), 976 interface); 977 asprintf(&string, "ifconfig_%s", interface); 978 if (commands_execute(a, cmds)) { 979 /* XXX sleep(3); */ 980 show_ifconfig(a->c, interface); 981 write_config = 1; 982 } else { 983 switch (dfui_be_present_dialog(a->c, _("DHCP Failure"), 984 _("Yes|No"), 985 _("Warning: could not enable dhclient for %s.\n\n" 986 "Write the corresponding settings to rc.conf " 987 "anyway?"), interface)) { 988 case 1: 989 write_config = 1; 990 break; 991 case 2: 992 write_config = 0; 993 break; 994 default: 995 abort_backend(); 996 } 997 } 998 commands_free(cmds); 999 config_var_set(rc_conf, string, "DHCP"); 1000 free(string); 1001 break; 1002 case 2: 1003 dfui_form_free(f); 1004 dfui_response_free(r); 1005 f = dfui_form_create( 1006 "assign_ip", 1007 _("Assign IP Address"), 1008 _("Configuring Interface:"), 1009 "", 1010 1011 "f", "interface_ip", _("IP Address"), 1012 _("Enter the IP Address you would like to use"), "", 1013 "f", "interface_netmask", _("Netmask"), 1014 _("Enter the netmask of the IP address"), "", 1015 "f", "defaultrouter", _("Default Router"), 1016 _("Enter the IP address of the default router"), "", 1017 "f", "dns_resolver", _("Primary DNS Server"), 1018 _("Enter the IP address of primary DNS Server"), "", 1019 "f", "hostname", _("Hostname"), 1020 _("Enter the Hostname"), "", 1021 "f", "domain", _("Domain"), 1022 _("Enter the Domain Name"), "", 1023 1024 "a", "ok", _("Configure Interface"), 1025 "", "", 1026 "a", "cancel", _("Return to Utilities Menu"), 1027 "", "", 1028 "p", "accelerator", "ESC", 1029 1030 NULL 1031 ); 1032 1033 ds = dfui_dataset_new(); 1034 dfui_dataset_celldata_add(ds, "interface_netmask", ""); 1035 dfui_dataset_celldata_add(ds, "defaultrouter", ""); 1036 dfui_dataset_celldata_add(ds, "dns_resolver", ""); 1037 dfui_dataset_celldata_add(ds, "hostname", ""); 1038 dfui_dataset_celldata_add(ds, "domain", ""); 1039 dfui_dataset_celldata_add(ds, "interface_ip", ""); 1040 dfui_form_dataset_add(f, ds); 1041 1042 if (!dfui_be_present(a->c, f, &r)) 1043 abort_backend(); 1044 1045 if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 1046 new_ds = dfui_response_dataset_get_first(r); 1047 1048 interface_ip = dfui_dataset_get_value(new_ds, "interface_ip"); 1049 interface_netmask = dfui_dataset_get_value(new_ds, "interface_netmask"); 1050 defaultrouter = dfui_dataset_get_value(new_ds, "defaultrouter"); 1051 dns_resolver = dfui_dataset_get_value(new_ds, "dns_resolver"); 1052 hostname = dfui_dataset_get_value(new_ds, "hostname"); 1053 domain = dfui_dataset_get_value(new_ds, "domain"); 1054 1055 cmds = commands_new(); 1056 command_add(cmds, "%s%s %s %s netmask %s", 1057 a->os_root, cmd_name(a, "IFCONFIG"), 1058 interface, interface_ip, interface_netmask); 1059 command_add(cmds, "%s%s add default %s", 1060 a->os_root, cmd_name(a, "ROUTE"), 1061 defaultrouter); 1062 1063 if (commands_execute(a, cmds)) { 1064 /* XXX sleep(3); */ 1065 show_ifconfig(a->c, interface); 1066 write_config = 1; 1067 } else { 1068 switch (dfui_be_present_dialog(a->c, 1069 _("ifconfig Failure"), 1070 _("Yes|No"), 1071 _("Warning: could not assign IP address " 1072 "or default gateway.\n\n" 1073 "Write the corresponding settings to " 1074 "rc.conf anyway?"))) { 1075 case 1: 1076 write_config = 1; 1077 break; 1078 case 2: 1079 write_config = 0; 1080 break; 1081 default: 1082 abort_backend(); 1083 } 1084 } 1085 commands_free(cmds); 1086 1087 asprintf(&string, "ifconfig_%s", interface); 1088 asprintf(&string1, "inet %s netmask %s", 1089 interface_ip, interface_netmask); 1090 1091 config_var_set(rc_conf, string, string1); 1092 config_var_set(rc_conf, "defaultrouter", defaultrouter); 1093 1094 free(string); 1095 free(string1); 1096 1097 asprintf(&string, "%s.%s", hostname, domain); 1098 config_var_set(rc_conf, "hostname", string); 1099 free(string); 1100 1101 config_var_set(resolv_conf, "search", domain); 1102 config_var_set(resolv_conf, "nameserver", dns_resolver); 1103 } 1104 break; 1105 default: 1106 abort_backend(); 1107 } 1108 1109 if (write_config) { 1110 /* 1111 * Save out changes to /etc/rc.conf and /etc/resolv.conf. 1112 */ 1113 config_vars_write(resolv_conf, CONFIG_TYPE_RESOLV, 1114 "%s%setc/resolv.conf", a->os_root, a->cfg_root); 1115 } 1116 1117 config_vars_free(resolv_conf); 1118 1119 dfui_form_free(f); 1120 dfui_response_free(r); 1121 } 1122 1123 static const char * 1124 yes_to_y(const char *value) 1125 { 1126 return(strcasecmp(value, "YES") == 0 ? "Y" : "N"); 1127 } 1128 1129 void 1130 fn_select_services(struct i_fn_args *a) 1131 { 1132 struct dfui_dataset *ds; 1133 struct dfui_form *f; 1134 struct dfui_response *r; 1135 1136 if (!config_vars_read(a, rc_conf, CONFIG_TYPE_SH, "%setc/rc.conf", a->cfg_root)) { 1137 inform(a->c, _("Couldn't read %s%setc/rc.conf."), 1138 a->os_root, a->cfg_root); 1139 a->result = 0; 1140 return; 1141 } 1142 1143 f = dfui_form_create( 1144 "select_services", 1145 _("Select Services"), 1146 _("Please select which services you would like started at boot time."), 1147 "", 1148 1149 "f", "syslogd", "syslogd", 1150 _("System Logging Daemon"), "", 1151 "p", "control", "checkbox", 1152 "f", "inetd", "inetd", 1153 _("Internet Super-Server"), "", 1154 "p", "control", "checkbox", 1155 "f", "named", "named", 1156 _("BIND Name Server"), "", 1157 "p", "control", "checkbox", 1158 "f", "ntpd", "ntpd", 1159 _("Network Time Protocol Daemon"), "", 1160 "p", "control", "checkbox", 1161 "f", "sshd", "sshd", 1162 _("Secure Shell Daemon"), "", 1163 "p", "control", "checkbox", 1164 1165 "a", "ok", _("Enable/Disable Services"), 1166 "", "", 1167 "a", "cancel", _("Return to Utilities Menu"), 1168 "", "", 1169 "p", "accelerator", "ESC", 1170 1171 NULL 1172 ); 1173 1174 ds = dfui_dataset_new(); 1175 dfui_dataset_celldata_add(ds, "syslogd", 1176 yes_to_y(config_var_get(rc_conf, "syslogd_enable"))); 1177 dfui_dataset_celldata_add(ds, "inetd", 1178 yes_to_y(config_var_get(rc_conf, "inetd_enable"))); 1179 dfui_dataset_celldata_add(ds, "named", 1180 yes_to_y(config_var_get(rc_conf, "named_enable"))); 1181 dfui_dataset_celldata_add(ds, "ntpd", 1182 yes_to_y(config_var_get(rc_conf, "ntpd_enable"))); 1183 dfui_dataset_celldata_add(ds, "sshd", 1184 yes_to_y(config_var_get(rc_conf, "sshd_enable"))); 1185 dfui_form_dataset_add(f, ds); 1186 1187 if (!dfui_be_present(a->c, f, &r)) 1188 abort_backend(); 1189 1190 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 1191 dfui_form_free(f); 1192 dfui_response_free(r); 1193 return; 1194 } 1195 1196 dfui_form_free(f); 1197 dfui_response_free(r); 1198 } 1199 1200 /*** NON-fn_ FUnCTIONS ***/ 1201 1202 /* 1203 * Caller is responsible for deallocation. 1204 */ 1205 static char * 1206 convert_swap_options(char *line) 1207 { 1208 char *result, *word; 1209 int i; 1210 1211 result = malloc(256); 1212 result[0] = '\0'; 1213 1214 for (; (word = strsep(&line, ",")) != NULL; ) { 1215 if (word[0] == '-') { 1216 /* 1217 * Don't bother trying to honour the -C 1218 * option, since we can't copy files from 1219 * the right place anyway. 1220 */ 1221 if (strcmp(word, "-C") != 0) { 1222 for (i = 0; word[i] != '\0'; i++) { 1223 if (word[i] == '=') 1224 word[i] = ' '; 1225 } 1226 strlcat(result, word, 256); 1227 strlcat(result, " ", 256); 1228 } 1229 } 1230 } 1231 1232 return(result); 1233 } 1234 1235 /* 1236 * Uses ss->selected_{disk,slice} as the target system. 1237 */ 1238 int 1239 mount_target_system(struct i_fn_args *a) 1240 { 1241 FILE *fstab; 1242 struct commands *cmds; 1243 struct subpartition *a_subpart; 1244 char device[256], mtpt[256], fstype[256], options[256]; 1245 char *filename, line[256]; 1246 const char *try_mtpt[5] = {"/var", "/tmp", "/usr", "/home", NULL}; 1247 char *word, *cvtoptions; 1248 int i; 1249 1250 /* 1251 * Mount subpartitions from this installation if they are 1252 * not already mounted. Tricky, as we need to honour the 1253 * installation's loader.conf and fstab. 1254 */ 1255 cmds = commands_new(); 1256 1257 /* 1258 * First, unmount anything already mounted on /mnt. 1259 */ 1260 unmount_all_under(a, cmds, "%smnt", a->os_root); 1261 1262 /* 1263 * Reset and clear out subpartitions so that system 1264 * can make a "dummy" subpart. 1265 */ 1266 subpartitions_free(storage_get_selected_slice(a->s)); 1267 1268 /* 1269 * Create a temporary dummy subpartition - that we 1270 * assume exists 1271 */ 1272 1273 a_subpart = subpartition_new(storage_get_selected_slice(a->s), 1274 "/dummy", 0, 0, 0, 0, 0); 1275 1276 /* 1277 * Mount the target's / and read its /etc/fstab. 1278 */ 1279 if (use_hammer == 0) { 1280 command_add(cmds, "%s%s %sdev/%s %s%s", 1281 a->os_root, cmd_name(a, "MOUNT"), 1282 a->os_root, 1283 subpartition_get_device_name(a_subpart), 1284 a->os_root, a->cfg_root); 1285 } else { 1286 command_add(cmds, "%s%s %sdev/%s %sboot", 1287 a->os_root, cmd_name(a, "MOUNT"), 1288 a->os_root, 1289 subpartition_get_device_name(a_subpart), 1290 a->os_root, a->cfg_root); 1291 command_add(cmds, 1292 "%s%s %sdev/`%s%s \"^vfs\\.root\\.mountfrom\" %sboot/loader.conf |" 1293 "%s%s -Fhammer: '{print $2;}' |" 1294 "%s%s 's/\"//'` %s%s", 1295 a->os_root, cmd_name(a, "MOUNT_HAMMER"), 1296 a->os_root, 1297 a->os_root, cmd_name(a, "GREP"), 1298 a->os_root, 1299 a->os_root, cmd_name(a, "AWK"), 1300 a->os_root, cmd_name(a, "SED"), 1301 a->os_root, a->cfg_root); 1302 command_add(cmds, "%s%s %sboot", 1303 a->os_root, cmd_name(a, "UMOUNT"), 1304 a->os_root, a->cfg_root); 1305 } 1306 if (!commands_execute(a, cmds)) { 1307 commands_free(cmds); 1308 return(0); 1309 } 1310 commands_free(cmds); 1311 1312 /* 1313 * Get rid of the dummy subpartition. 1314 */ 1315 subpartitions_free(storage_get_selected_slice(a->s)); 1316 1317 asprintf(&filename, "%s%s/etc/fstab", a->os_root, a->cfg_root); 1318 fstab = fopen(filename, "r"); 1319 free(filename); 1320 if (fstab == NULL) { 1321 inform(a->c, _("Filesystem table on installed system could not be read.")); 1322 cmds = commands_new(); 1323 command_add(cmds, "%s%s %s%s", 1324 a->os_root, cmd_name(a, "UMOUNT"), 1325 a->os_root, a->cfg_root); 1326 if (!commands_execute(a, cmds)) { 1327 inform(a->c, _("Warning: Installed system was not properly unmounted.")); 1328 } 1329 commands_free(cmds); 1330 return(0); 1331 } 1332 1333 cmds = commands_new(); 1334 1335 while (fgets(line, 256, fstab) != NULL) { 1336 /* 1337 * Parse the fstab line. 1338 */ 1339 if (first_non_space_char_is(line, '#')) 1340 continue; 1341 if ((word = strtok(line, " \t")) == NULL) 1342 continue; 1343 strlcpy(device, word, 256); 1344 if ((word = strtok(NULL, " \t")) == NULL) 1345 continue; 1346 strlcpy(mtpt, word, 256); 1347 if ((word = strtok(NULL, " \t")) == NULL) 1348 continue; 1349 strlcpy(fstype, word, 256); 1350 if ((word = strtok(NULL, " \t")) == NULL) 1351 continue; 1352 strlcpy(options, word, 256); 1353 1354 /* 1355 * Now, if the mountpoint has /usr, /var, /tmp, or /home 1356 * as a prefix, mount it under a->cfg_root. 1357 */ 1358 for (i = 0; try_mtpt[i] != NULL; i++) { 1359 if (strstr(mtpt, try_mtpt[i]) == mtpt) { 1360 /* 1361 * Don't mount it if it's optional. 1362 */ 1363 if (strstr(options, "noauto") != NULL) 1364 continue; 1365 1366 /* 1367 * Don't mount it if device doesn't start 1368 * with /dev/ or /pfs and it isn't 'swap'. 1369 */ 1370 if (strstr(device, "/dev/") != NULL && 1371 strstr(device, "/pfs/") != NULL && 1372 strcmp(device, "swap") != 0) 1373 continue; 1374 1375 /* 1376 * If the device is 'swap', mount_mfs it instead. 1377 */ 1378 if (strcmp(device, "swap") == 0) { 1379 cvtoptions = convert_swap_options(options); 1380 command_add(cmds, 1381 "%s%s %s swap %s%s%s", 1382 a->os_root, cmd_name(a, "MOUNT_MFS"), 1383 cvtoptions, a->os_root, a->cfg_root, mtpt); 1384 free(cvtoptions); 1385 } else { 1386 if (use_hammer == 0) { 1387 command_add(cmds, 1388 "%s%s -o %s %s%s %s%s%s", 1389 a->os_root, cmd_name(a, "MOUNT"), 1390 options, 1391 a->os_root, device, a->os_root, 1392 a->cfg_root, mtpt); 1393 } else { 1394 command_add(cmds, 1395 "%s%s -o %s %s%s%s %s%s%s", 1396 a->os_root, cmd_name(a, "MOUNT_NULL"), 1397 options, 1398 a->os_root, a->cfg_root, device, a->os_root, 1399 a->cfg_root, mtpt); 1400 } 1401 } 1402 } 1403 } 1404 } 1405 fclose(fstab); 1406 1407 if (!commands_execute(a, cmds)) { 1408 commands_free(cmds); 1409 return(0); 1410 } 1411 commands_free(cmds); 1412 1413 return(1); 1414 } 1415