2 * The new sysinstall program.
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
10 * Jordan Hubbard. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * verbatim and that no modifications are made prior to this
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include "sysinstall.h"
38 #include <sys/disklabel.h>
40 #include <sys/errno.h>
41 #include <sys/ioctl.h>
42 #include <sys/fcntl.h>
43 #include <sys/param.h>
46 #include <sys/mount.h>
51 static Chunk *chunk_list[MAX_CHUNKS];
53 static int rootdev_is_od;
57 chunk_compare(Chunk *c1, Chunk *c2)
65 else if (!c1->private_data && !c2->private_data)
67 else if (c1->private_data && !c2->private_data)
69 else if (!c1->private_data && c2->private_data)
72 return strcmp(((PartInfo *)(c1->private_data))->mountpoint, ((PartInfo *)(c2->private_data))->mountpoint);
80 for (i = 0; i < nchunks; i++) {
81 for (j = 0; j < nchunks; j++) {
82 if (chunk_compare(chunk_list[j], chunk_list[j + 1]) > 0) {
83 Chunk *tmp = chunk_list[j];
85 chunk_list[j] = chunk_list[j + 1];
86 chunk_list[j + 1] = tmp;
93 check_rootdev(Chunk **list, int n)
99 for (i = 0; i < n; i++) {
101 if (c->type == part && (c->flags & CHUNK_IS_ROOT)
102 && strncmp(c->disk->name, "od", 2) == 0)
114 mount_point(Chunk *c1)
116 if (c1->type == part && c1->subtype == FS_SWAP)
118 else if (c1->type == part || c1->type == fat || c1->type == efi)
119 return ((PartInfo *)c1->private_data)->mountpoint;
126 if (c1->type == fat || c1->type == efi)
128 else if (c1->type == part) {
129 if (c1->subtype != FS_SWAP)
138 fstype_short(Chunk *c1)
140 if (c1->type == part) {
141 if (c1->subtype != FS_SWAP) {
142 if (rootdev_is_od == 0 && strncmp(c1->name, "od", 2) == 0)
150 else if (c1->type == fat) {
151 if (strncmp(c1->name, "od", 2) == 0)
156 else if (c1->type == efi)
165 if (c1->type == part && c1->subtype != FS_SWAP) {
166 if (rootdev_is_od == 0 && strncmp(c1->name, "od", 2) == 0)
168 else if (c1->flags & CHUNK_IS_ROOT)
177 configFstab(dialogMenuItem *self)
185 if (!RunningAsInit) {
186 if (file_readable("/etc/fstab"))
187 return DITEM_SUCCESS;
189 msgConfirm("Attempting to rebuild your /etc/fstab file. Warning: If you had\n"
190 "any CD devices in use before running sysinstall then they may NOT\n"
191 "be found by this run!");
195 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
197 msgConfirm("No disks found!");
198 return DITEM_FAILURE;
201 /* Record all the chunks */
203 for (i = 0; devs[i]; i++) {
204 if (!devs[i]->enabled)
206 disk = (Disk *)devs[i]->private;
208 msgFatal("No chunk list found for %s!", disk->name);
209 for (c1 = disk->chunks->part; c1; c1 = c1->next) {
211 if (c1->type == apple) {
213 if (c1->type == freebsd) {
215 for (c2 = c1->part; c2; c2 = c2->next) {
216 if (c2->type == part && (c2->subtype == FS_SWAP || c2->private_data))
217 chunk_list[nchunks++] = c2;
220 else if (((c1->type == fat || c1->type == efi || c1->type == part) &&
221 c1->private_data) || (c1->type == part && c1->subtype == FS_SWAP))
222 chunk_list[nchunks++] = c1;
225 chunk_list[nchunks] = 0;
228 fstab = fopen("/etc/fstab", "w");
230 msgConfirm("Unable to create a new /etc/fstab file! Manual intervention\n"
231 "will be required.");
232 return DITEM_FAILURE;
235 check_rootdev(chunk_list, nchunks);
237 /* Go for the burn */
238 msgDebug("Generating /etc/fstab file\n");
239 fprintf(fstab, "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#\n");
240 for (i = 0; i < nchunks; i++)
241 fprintf(fstab, "/dev/%s\t\t%s\t\t%s\t%s\t\t%d\t%d\n", name_of(chunk_list[i]), mount_point(chunk_list[i]),
242 fstype(chunk_list[i]), fstype_short(chunk_list[i]), seq_num(chunk_list[i]), seq_num(chunk_list[i]));
244 /* Now look for the CDROMs */
245 devs = deviceFind(NULL, DEVICE_TYPE_CDROM);
246 cnt = deviceCount(devs);
248 /* Write out the CDROM entries */
249 for (i = 0; i < cnt; i++) {
252 sprintf(cdname, "/cdrom%s", i ? itoa(i) : "");
254 msgConfirm("Unable to make mount point for: %s", cdname);
256 fprintf(fstab, "/dev/%s\t\t%s\t\tcd9660\tro,noauto\t0\t0\n", devs[i]->name, cdname);
261 msgDebug("Wrote out /etc/fstab file\n");
262 return DITEM_SUCCESS;
265 /* Do the work of sucking in a config file.
266 * config is the filename to read in.
267 * lines is a fixed (max) sized array of char*
268 * returns number of lines read. line contents
269 * are malloc'd and must be freed by the caller.
272 readConfig(char *config, char **lines, int max)
278 fp = fopen(config, "r");
283 /* Read in the entire file */
284 for (i = 0; i < max; i++) {
285 if (!fgets(line, sizeof line, fp))
287 lines[nlines++] = strdup(line);
291 msgDebug("readConfig: Read %d lines from %s.\n", nlines, config);
295 #define MAX_LINES 2000 /* Some big number we're not likely to ever reach - I'm being really lazy here, I know */
298 readConfigFile(char *config, int marked)
300 char *lines[MAX_LINES], *cp, *cp2;
303 nlines = readConfig(config, lines, MAX_LINES);
307 for (i = 0; i < nlines; i++) {
308 /* Skip the comments & non-variable settings */
309 if (lines[i][0] == '#' || !(cp = index(lines[i], '='))) {
315 if ((cp2 = index(cp, '"')) || (cp2 = index(cp, '\047'))) {
317 cp2 = index(cp, *cp2);
319 /* If valid quotes, use it */
322 /* If we have a legit value, set it */
324 variable_set2(lines[i], cp, marked);
330 /* Load the environment from rc.conf file(s) */
332 configEnvironmentRC_conf(void)
338 { "/etc/defaults/rc.conf", 0 },
339 { "/etc/rc.conf", 0 },
340 { "/etc/rc.conf.local", 0 },
345 for (i = 0; configs[i].fname; i++) {
346 if (file_readable(configs[i].fname))
347 readConfigFile(configs[i].fname, configs[i].marked);
351 /* Load the environment from a resolv.conf file */
353 configEnvironmentResolv(char *config)
355 char *lines[MAX_LINES];
358 nlines = readConfig(config, lines, MAX_LINES);
361 for (i = 0; i < nlines; i++) {
362 Boolean name_set = variable_get(VAR_NAMESERVER) ? 1 : 0;
364 if (!strncmp(lines[i], "domain", 6) && !variable_get(VAR_DOMAINNAME))
365 variable_set2(VAR_DOMAINNAME, string_skipwhite(string_prune(lines[i] + 6)), 0);
366 else if (!name_set && !strncmp(lines[i], "nameserver", 10)) {
367 /* Only take the first nameserver setting - we're lame */
368 variable_set2(VAR_NAMESERVER, string_skipwhite(string_prune(lines[i] + 10)), 0);
374 /* Version of below for dispatch routines */
376 configRC(dialogMenuItem *unused)
379 return DITEM_SUCCESS;
385 * rc.conf is sorted if running as init and the needed utilities are
388 * If rc.conf is sorted, all variables in rc.conf which conflict with
389 * the variables in the environment are removed from the original
396 FILE *rcSite, *rcOld;
401 static int did_marker = 0;
407 write_header = !file_readable("/etc/rc.conf");
408 do_sort = RunningAsInit && file_readable("/usr/bin/sort") &&
409 file_readable("/usr/bin/uniq");
410 do_merge = do_sort && file_readable("/etc/rc.conf");
413 rcSite = fopen("/etc/rc.conf.new", "w");
415 rcSite = fopen("/etc/rc.conf", "a");
416 if (rcSite == NULL) {
417 msgError("Error opening new rc.conf for writing: %s (%u)", strerror(errno), errno);
422 /* "Copy" the old rc.conf */
423 rcOld = fopen("/etc/rc.conf", "r");
425 msgError("Error opening rc.conf for reading: %s (%u)", strerror(errno), errno);
428 while(fgets(line, sizeof(line), rcOld)) {
429 if(line[0] == '#' || variable_check2(line) != 0)
430 fprintf(rcSite, "%s", line);
432 fprintf(rcSite, "#REMOVED: %s", line);
435 } else if (write_header) {
436 fprintf(rcSite, "# This file now contains just the overrides from /etc/defaults/rc.conf.\n");
437 fprintf(rcSite, "# Please make all changes to this file, not to /etc/defaults/rc.conf.\n\n");
438 fprintf(rcSite, "# Enable network daemons for user convenience.\n");
439 if ((t_loc = time(NULL)) != -1 && (cp = ctime(&t_loc)))
440 fprintf(rcSite, "# Created: %s", cp);
443 /* Now do variable substitutions */
444 for (v = VarHead; v; v = v->next) {
448 fprintf(rcSite, "# -- sysinstall generated deltas -- # "
452 fprintf(rcSite, "%s=\"%s\"\n", v->name, v->value);
459 if(rename("/etc/rc.conf.new", "/etc/rc.conf") != 0) {
460 msgError("Error renaming temporary rc.conf: %s (%u)", strerror(errno), errno);
465 /* Tidy up the resulting file if it's late enough in the installation
466 for sort and uniq to be available */
468 (void)vsystem("sort /etc/rc.conf | uniq > /etc/rc.conf.new && mv /etc/rc.conf.new /etc/rc.conf");
473 configSaver(dialogMenuItem *self)
475 variable_set((char *)self->data, 1);
476 if (!variable_get(VAR_BLANKTIME))
477 variable_set2(VAR_BLANKTIME, "300", 1);
478 return DITEM_SUCCESS;
482 configSaverTimeout(dialogMenuItem *self)
484 return (variable_get_value(VAR_BLANKTIME,
485 "Enter time-out period in seconds for screen saver", 1) ?
486 DITEM_SUCCESS : DITEM_FAILURE);
490 configNTP(dialogMenuItem *self)
494 status = variable_get_value(VAR_NTPDATE_FLAGS,
495 "Enter the name of an NTP server", 1)
496 ? DITEM_SUCCESS : DITEM_FAILURE;
497 if (status == DITEM_SUCCESS) {
498 static char tmp[255];
500 snprintf(tmp, sizeof(tmp), "ntpdate_enable=YES,ntpdate_flags=%s",
501 variable_get(VAR_NTPDATE_FLAGS));
503 dmenuSetVariables(self);
509 configUsers(dialogMenuItem *self)
511 WINDOW *w = savescr();
513 dialog_clear_norefresh();
514 dmenuOpenSimple(&MenuUsermgmt, FALSE);
516 return DITEM_SUCCESS;
521 configLinux(dialogMenuItem *self)
523 WINDOW *w = savescr();
526 dialog_clear_norefresh();
527 variable_set2(VAR_LINUX_ENABLE, "YES", 1);
528 Mkdir("/compat/linux");
529 msgNotify("Installing Linux compatibility library...");
530 i = package_add("linux_base-8");
538 configOSF1(dialogMenuItem *self)
541 variable_set2(VAR_OSF1_ENABLE, "YES", 1);
542 Mkdir("/compat/osf1");
543 return DITEM_SUCCESS;
548 configSecurelevel(dialogMenuItem *self)
550 WINDOW *w = savescr();
552 dialog_clear_norefresh();
553 dmenuOpenSimple(&MenuSecurelevel, FALSE);
555 return DITEM_SUCCESS;
559 configSecurelevelDisabled(dialogMenuItem *self)
562 variable_set2("kern_securelevel_enable", "NO", 1);
563 return DITEM_SUCCESS;
567 configSecurelevelSecure(dialogMenuItem *self)
570 variable_set2("kern_securelevel_enable", "YES", 1);
571 variable_set2("kern_securelevel", "1", 1);
572 return DITEM_SUCCESS;
576 configSecurelevelHighlySecure(dialogMenuItem *self)
579 variable_set2("kern_securelevel_enable", "YES", 1);
580 variable_set2("kern_securelevel", "2", 1);
581 return DITEM_SUCCESS;
585 configSecurelevelNetworkSecure(dialogMenuItem *self)
588 variable_set2("kern_securelevel_enable", "YES", 1);
589 variable_set2("kern_securelevel", "3", 1);
590 return DITEM_SUCCESS;
594 configSecurity(dialogMenuItem *self)
596 WINDOW *w = savescr();
598 dialog_clear_norefresh();
599 dmenuOpenSimple(&MenuSecurity, FALSE);
601 return DITEM_SUCCESS;
605 write_root_xprofile(char *str)
610 static char *flist[] = { /* take care of both xdm and startx */
613 "/usr/share/skel/dot.xinitrc",
614 "/usr/share/skel/dot.xsession",
619 for (cp = flist; *cp; cp++) {
620 fp = fopen(*cp, "w");
622 fwrite(str, 1, len, fp);
623 fchmod(fileno(fp), 0755);
632 char tmp[FILENAME_MAX];
634 snprintf(tmp, sizeof tmp, "/usr/X11R6/bin/%s", fname);
635 if (file_executable(tmp))
637 snprintf(tmp, sizeof tmp, "/usr/local/bin/%s", fname);
638 return file_executable(tmp);
642 configResolv(dialogMenuItem *ditem)
645 char *cp, *c6p, *dp, *hp;
647 cp = variable_get(VAR_NAMESERVER);
651 fp = fopen("/etc/resolv.conf", "w");
653 return DITEM_FAILURE;
654 if (variable_get(VAR_DOMAINNAME))
655 fprintf(fp, "domain\t%s\n", variable_get(VAR_DOMAINNAME));
656 fprintf(fp, "nameserver\t%s\n", cp);
659 msgDebug("Wrote out /etc/resolv.conf\n");
662 dp = variable_get(VAR_DOMAINNAME);
663 cp = variable_get(VAR_IPADDR);
664 c6p = variable_get(VAR_IPV6ADDR);
665 hp = variable_get(VAR_HOSTNAME);
666 /* Tack ourselves into /etc/hosts */
667 fp = fopen("/etc/hosts", "w");
669 return DITEM_FAILURE;
670 /* Add an entry for localhost */
672 fprintf(fp, "::1\t\t\tlocalhost.%s localhost\n", dp);
673 fprintf(fp, "127.0.0.1\t\tlocalhost.%s localhost\n", dp);
675 fprintf(fp, "::1\t\t\tlocalhost\n");
676 fprintf(fp, "127.0.0.1\t\tlocalhost\n");
678 /* Now the host entries, if applicable */
679 if (((cp && cp[0] != '0') || (c6p && c6p[0] != '0')) && hp) {
685 SAFE_STRCPY(cp2, hp);
686 *(index(cp2, '.')) = '\0';
688 if (c6p && c6p[0] != '0') {
689 fprintf(fp, "%s\t%s %s\n", c6p, hp, cp2);
690 fprintf(fp, "%s\t%s.\n", c6p, hp);
692 if (cp && cp[0] != '0') {
693 fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2);
694 fprintf(fp, "%s\t\t%s.\n", cp, hp);
699 msgDebug("Wrote out /etc/hosts\n");
700 return DITEM_SUCCESS;
704 configRouter(dialogMenuItem *self)
708 ret = variable_get_value(VAR_ROUTER,
709 "Please specify the router you wish to use. Routed is\n"
710 "provided with the stock system and gated is provided\n"
711 "as an optional package which this installation system\n"
712 "will attempt to load if you select gated. Any other\n"
713 "choice of routing daemon will be assumed to be something\n"
714 "the user intends to install themselves before rebooting\n"
715 "the system. If you don't want any routing daemon, choose NO", 1)
716 ? DITEM_SUCCESS : DITEM_FAILURE;
718 if (ret == DITEM_SUCCESS) {
719 char *cp = variable_get(VAR_ROUTER);
721 if (cp && strcmp(cp, "NO")) {
722 variable_set2(VAR_ROUTER_ENABLE, "YES", 1);
723 if (!strcmp(cp, "gated")) {
724 if (package_add("gated") != DITEM_SUCCESS) {
725 msgConfirm("Unable to load gated package. Falling back to no router.");
726 variable_unset(VAR_ROUTER);
727 variable_unset(VAR_ROUTERFLAGS);
728 variable_set2(VAR_ROUTER_ENABLE, "NO", 1);
733 /* Now get the flags, if they chose a router */
734 ret = variable_get_value(VAR_ROUTERFLAGS,
735 "Please Specify the routing daemon flags; if you're running routed\n"
736 "then -q is the right choice for nodes and -s for gateway hosts.\n", 1)
737 ? DITEM_SUCCESS : DITEM_FAILURE;
738 if (ret != DITEM_SUCCESS)
739 variable_unset(VAR_ROUTERFLAGS);
744 variable_set2(VAR_ROUTER_ENABLE, "NO", 1);
745 variable_unset(VAR_ROUTERFLAGS);
746 variable_unset(VAR_ROUTER);
750 variable_set2(VAR_ROUTER_ENABLE, "NO", 1);
751 variable_unset(VAR_ROUTERFLAGS);
752 variable_unset(VAR_ROUTER);
757 /* Shared between us and index_initialize() */
758 extern PkgNode Top, Plist;
761 configPackages(dialogMenuItem *self)
763 int i, restoreflag = 0;
766 /* Did we get an INDEX? */
767 i = index_initialize("packages/INDEX");
768 if (DITEM_STATUS(i) == DITEM_FAILURE)
772 int ret, pos, scroll;
774 /* Bring up the packages menu */
776 index_menu(&Top, &Top, &Plist, &pos, &scroll);
778 if (Plist.kids && Plist.kids->name) {
779 /* Now show the packing list menu */
781 ret = index_menu(&Plist, &Plist, NULL, &pos, &scroll);
782 if (ret & DITEM_LEAVE_MENU)
784 else if (DITEM_STATUS(ret) != DITEM_FAILURE) {
787 for (tmp = Plist.kids; tmp && tmp->name; tmp = tmp->next)
788 (void)index_extract(mediaDevice, &Top, tmp, FALSE);
793 msgConfirm("No packages were selected for extraction.");
799 PkgNodePtr tmp2 = tmp->next;
804 index_init(NULL, &Plist);
805 return DITEM_SUCCESS | (restoreflag ? DITEM_RESTORE : 0);
808 /* Load pcnfsd package */
810 configPCNFSD(dialogMenuItem *self)
814 ret = package_add("pcnfsd");
815 if (DITEM_STATUS(ret) == DITEM_SUCCESS) {
816 variable_set2(VAR_PCNFSD, "YES", 0);
817 variable_set2("mountd_flags", "-n", 1);
823 configInetd(dialogMenuItem *self)
827 WINDOW *w = savescr();
829 if (msgYesNo("The Internet Super Server (inetd) allows a number of simple Internet\n"
830 "services to be enabled, including finger, ftp, and telnetd. Enabling\n"
831 "these services may increase risk of security problems by increasing\n"
832 "the exposure of your system.\n\n"
833 "With this in mind, do you wish to enable inetd?\n")) {
834 variable_set2("inetd_enable", "NO", 1);
836 /* If inetd is enabled, we'll need an inetd.conf */
837 variable_set2("inetd_enable", "YES", 1);
838 if (!msgYesNo("inetd(8) relies on its configuration file, /etc/inetd.conf, to determine\n"
839 "which of its Internet services will be available. The default FreeBSD\n"
840 "inetd.conf(5) leaves all services disabled by default, so they must be\n"
841 "specifically enabled in the configuration file before they will\n"
842 "function, even once inetd(8) is enabled. Note that services for\n"
843 "IPv6 must be separately enabled from IPv4 services.\n\n"
844 "Select [Yes] now to invoke an editor on /etc/inetd.conf, or [No] to\n"
845 "use the current settings.\n")) {
846 sprintf(cmd, "%s /etc/inetd.conf", variable_get(VAR_EDITOR));
852 return DITEM_SUCCESS;
856 configNFSServer(dialogMenuItem *self)
861 /* If we're an NFS server, we need an exports file */
862 if (!file_readable("/etc/exports")) {
863 WINDOW *w = savescr();
865 if (file_readable("/etc/exports.disabled"))
866 vsystem("mv /etc/exports.disabled /etc/exports");
868 dialog_clear_norefresh();
869 msgConfirm("Operating as an NFS server means that you must first configure\n"
870 "an /etc/exports file to indicate which hosts are allowed certain\n"
871 "kinds of access to your local file systems.\n"
872 "Press [ENTER] now to invoke an editor on /etc/exports\n");
873 vsystem("echo '#The following examples export /usr to 3 machines named after ducks,' > /etc/exports");
874 vsystem("echo '#/usr/src and /usr/ports read-only to machines named after trouble makers' >> /etc/exports");
875 vsystem("echo '#/home and all directories under it to machines named after dead rock stars' >> /etc/exports");
876 vsystem("echo '#and, /a to a network of privileged machines allowed to write on it as root.' >> /etc/exports");
877 vsystem("echo '#/usr huey louie dewie' >> /etc/exports");
878 vsystem("echo '#/usr/src /usr/obj -ro calvin hobbes' >> /etc/exports");
879 vsystem("echo '#/home -alldirs janice jimmy frank' >> /etc/exports");
880 vsystem("echo '#/a -maproot=0 -network 10.0.1.0 -mask 255.255.248.0' >> /etc/exports");
881 vsystem("echo '#' >> /etc/exports");
882 vsystem("echo '# You should replace these lines with your actual exported filesystems.' >> /etc/exports");
883 vsystem("echo \"# Note that BSD's export syntax is 'host-centric' vs. Sun's 'FS-centric' one.\" >> /etc/exports");
884 vsystem("echo >> /etc/exports");
885 sprintf(cmd, "%s /etc/exports", variable_get(VAR_EDITOR));
889 variable_set2(VAR_NFS_SERVER, "YES", 1);
890 retval = configRpcBind(NULL);
893 else if (variable_get(VAR_NFS_SERVER)) { /* We want to turn it off again? */
894 vsystem("mv -f /etc/exports /etc/exports.disabled");
895 variable_unset(VAR_NFS_SERVER);
897 return DITEM_SUCCESS | retval;
901 * Extend the standard dmenuToggleVariable() method to also check and set
902 * the rpcbind variable if needed.
905 configRpcBind(dialogMenuItem *self)
911 retval = dmenuToggleVariable(self);
912 if (strcmp(variable_get(self->data), "YES") != 0)
916 if (doupdate && strcmp(variable_get(VAR_RPCBIND_ENABLE), "YES") != 0) {
917 variable_set2(VAR_RPCBIND_ENABLE, "YES", 1);
918 retval |= DITEM_REDRAW;
925 configEtcTtys(dialogMenuItem *self)
929 WINDOW *w = savescr();
931 /* Simply prompt for confirmation, then edit away. */
932 if (msgYesNo("Configuration of system TTYs requires editing the /etc/ttys file.\n"
933 "Typical configuration activities might include enabling getty(8)\n"
934 "on the first serial port to allow login via serial console after\n"
935 "reboot, or to enable xdm. The default ttys file enables normal\n"
936 "virtual consoles, and most sites will not need to perform manual\n"
938 "To load /etc/ttys in the editor, select [Yes], otherwise, [No].")) {
941 sprintf(cmd, "%s /etc/ttys", variable_get(VAR_EDITOR));
947 return DITEM_SUCCESS;
952 checkLoaderACPI(void)
956 if (kenv(KENV_GET, "loader.acpi_disabled_by_user", &val[0], 4) <= 0) {
960 if (strtol(&val[0], NULL, 10) <= 0) {
968 configLoaderACPI(int disable)
972 ldconf = fopen("/boot/loader.conf", "a");
973 if (ldconf == NULL) {
974 msgConfirm("Unable to open /boot/loader.conf. Please consult the\n"
975 "FreeBSD Handbook for instructions on disabling ACPI");
976 return DITEM_FAILURE;
979 fprintf(ldconf, "# --- Generated by sysinstall ---\n");
980 fprintf(ldconf, "hint.acpi.0.disabled=%d\n", disable);
983 return DITEM_SUCCESS;
988 configMTAPostfix(dialogMenuItem *self)
993 if(setenv("POSTFIX_DEFAULT_MTA", "YES", 1) != 0)
994 msgError("Error setting the enviroment variable POSTFIX_DEFAULT_MTA: %s (%u)",
995 strerror(errno), errno);
997 ret = package_add("postfix-2.2");
998 unsetenv("POSTFIX_DEFAULT_MTA");
1000 if(DITEM_STATUS(ret) == DITEM_FAILURE) {
1001 msgConfirm("An error occurred while adding the postfix package\n"
1002 "Please change installation media and try again.");
1006 variable_set2(VAR_SENDMAIL_ENABLE, "YES", 1);
1007 variable_set2("sendmail_flags", "-bd", 1);
1008 variable_set2("sendmail_outbound_enable", "NO", 1);
1009 variable_set2("sendmail_submit_enable", "NO", 1);
1010 variable_set2("sendmail_msp_queue_enable", "NO", 1);
1012 perconf = fopen("/etc/periodic.conf", "a");
1013 if (perconf == NULL) {
1014 msgConfirm("Unable to open /etc/periodic.conf.\n"
1015 "The daily cleanup scripts might generate errors when\n"
1016 "trying to run some sendmail only cleanup scripts.\n"
1017 "Please consult the documentation for the postfix port on how to\n"
1020 /* Not really a serious problem, so we return success */
1021 return DITEM_SUCCESS;
1024 fprintf(perconf, "# --- Generated by sysinstall ---\n");
1025 fprintf(perconf, "daily_clean_hoststat_enable=\"NO\"\n");
1026 fprintf(perconf, "daily_status_mail_rejects_enable=\"NO\"\n");
1027 fprintf(perconf, "daily_status_include_submit_mailq=\"NO\"\n");
1028 fprintf(perconf, "daily_submit_queuerun=\"NO\"\n");
1031 msgConfirm("Postfix is now installed and enabled as the default MTA.\n"
1032 "Please check that the configuration works as expected.\n"
1033 "See the Postfix documentation for more information.\n"
1034 "The documentation can be found in /usr/local/share/doc/postfix/\n"
1035 "or on the Postfix website at http://www.postfix.org/.");
1037 return DITEM_SUCCESS;
1041 configMTAExim(dialogMenuItem *self)
1044 FILE *perconf, *mailerconf, *newsyslogconf;
1046 ret = package_add("exim");
1048 if(DITEM_STATUS(ret) == DITEM_FAILURE) {
1049 msgConfirm("An error occurred while adding the exim package\n"
1050 "Please change installation media and try again.");
1054 variable_set2(VAR_SENDMAIL_ENABLE, "NONE", 1);
1055 variable_set2("exim_enable", "YES", 1);
1057 /* Update periodic.conf */
1058 perconf = fopen("/etc/periodic.conf", "a");
1059 if (perconf == NULL) {
1060 /* Not really a serious problem, so we do not abort */
1061 msgConfirm("Unable to open /etc/periodic.conf.\n"
1062 "The daily cleanup scripts might generate errors when\n"
1063 "trying to run some sendmail only cleanup scripts.\n"
1064 "Please consult the documentation for the exim port on how to\n"
1067 fprintf(perconf, "# --- Generated by sysinstall ---\n");
1068 fprintf(perconf, "daily_clean_hoststat_enable=\"NO\"\n");
1069 fprintf(perconf, "daily_status_include_submit_mailq=\"NO\"\n");
1070 fprintf(perconf, "daily_status_mail_rejects_enable=\"NO\"\n");
1071 fprintf(perconf, "daily_submit_queuerun=\"NO\"\n");
1075 /* Update mailer.conf */
1076 vsystem("mv -f /etc/mail/mailer.conf /etc/mail/mailer.conf.old");
1077 mailerconf = fopen("/etc/mail/mailer.conf", "w");
1078 if (mailerconf == NULL) {
1079 /* Not really a serious problem, so we do not abort */
1080 msgConfirm("Unable to open /etc/mailer.conf.\n"
1081 "Some programs which use the sendmail wrappers may not work.\n"
1082 "Please consult the documentation for the exim port on how\n"
1083 "to correct this.");
1085 fprintf(mailerconf, "# --- Generated by sysinstall ---\n");
1086 fprintf(mailerconf, "# Execute exim instead of sendmail\n");
1087 fprintf(mailerconf, "#\n");
1088 fprintf(mailerconf, "sendmail /usr/local/sbin/exim\n");
1089 fprintf(mailerconf, "send-mail /usr/local/sbin/exim\n");
1090 fprintf(mailerconf, "mailq /usr/local/sbin/exim\n");
1091 fprintf(mailerconf, "newaliases /usr/local/sbin/exim\n");
1092 fprintf(mailerconf, "hoststat /usr/bin/true\n");
1093 fprintf(mailerconf, "purgestat /usr/bin/true\n");
1097 /* Make newsyslog rotate exim logfiles */
1098 newsyslogconf = fopen("/etc/newsyslog.conf", "a");
1099 if (newsyslogconf == NULL) {
1100 /* Not really a serious problem, so we do not abort */
1101 msgConfirm("Unable to open /etc/newsyslog.conf.\n"
1102 "The exim logfiles will not be rotated.\n"
1103 "Please consult the documentation for the exim port on how to\n"
1104 "rotate the logfiles.");
1106 fprintf(newsyslogconf, "# --- Generated by sysinstall ---\n");
1107 fprintf(newsyslogconf, "/var/log/exim/mainlog mailnull:mail 640 7 * @T00 ZN\n");
1108 fprintf(newsyslogconf, "/var/log/exim/rejectlog mailnull:mail 640 7 * @T00 ZN\n");
1109 fclose(newsyslogconf);
1112 msgConfirm("Exim is now installed and enabled as the default MTA.\n"
1113 "Please check that the configuration works as expected.\n"
1114 "See the Exim documentation for more information.\n"
1115 "The documentation can be found in /usr/local/share/doc/exim/\n"
1116 "or on the Exim website at http://www.exim.org/.");
1118 return DITEM_SUCCESS;