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 configCountry(dialogMenuItem *self)
511 int choice, scroll, curr, max;
513 WINDOW *w = savescr();
515 dialog_clear_norefresh();
516 dmenuSetDefaultItem(&MenuCountry, NULL, NULL,
517 VAR_COUNTRY "=" DEFAULT_COUNTRY, &choice, &scroll, &curr, &max);
518 dmenuOpen(&MenuCountry, &choice, &scroll, &curr, &max, FALSE);
520 return DITEM_SUCCESS;
524 configUsers(dialogMenuItem *self)
526 WINDOW *w = savescr();
528 dialog_clear_norefresh();
529 dmenuOpenSimple(&MenuUsermgmt, FALSE);
531 return DITEM_SUCCESS;
536 configLinux(dialogMenuItem *self)
538 WINDOW *w = savescr();
541 dialog_clear_norefresh();
542 variable_set2(VAR_LINUX_ENABLE, "YES", 1);
543 Mkdir("/compat/linux");
544 msgNotify("Installing Linux compatibility library...");
545 i = package_add("linux_base-fc");
553 configOSF1(dialogMenuItem *self)
556 variable_set2(VAR_OSF1_ENABLE, "YES", 1);
557 Mkdir("/compat/osf1");
558 return DITEM_SUCCESS;
563 configSecurelevel(dialogMenuItem *self)
565 WINDOW *w = savescr();
567 dialog_clear_norefresh();
568 dmenuOpenSimple(&MenuSecurelevel, FALSE);
570 return DITEM_SUCCESS;
574 configSecurelevelDisabled(dialogMenuItem *self)
577 variable_set2("kern_securelevel_enable", "NO", 1);
578 return DITEM_SUCCESS;
582 configSecurelevelSecure(dialogMenuItem *self)
585 variable_set2("kern_securelevel_enable", "YES", 1);
586 variable_set2("kern_securelevel", "1", 1);
587 return DITEM_SUCCESS;
591 configSecurelevelHighlySecure(dialogMenuItem *self)
594 variable_set2("kern_securelevel_enable", "YES", 1);
595 variable_set2("kern_securelevel", "2", 1);
596 return DITEM_SUCCESS;
600 configSecurelevelNetworkSecure(dialogMenuItem *self)
603 variable_set2("kern_securelevel_enable", "YES", 1);
604 variable_set2("kern_securelevel", "3", 1);
605 return DITEM_SUCCESS;
609 configSecurity(dialogMenuItem *self)
611 WINDOW *w = savescr();
613 dialog_clear_norefresh();
614 dmenuOpenSimple(&MenuSecurity, FALSE);
616 return DITEM_SUCCESS;
620 write_root_xprofile(char *str)
625 static char *flist[] = { /* take care of both xdm and startx */
628 "/usr/share/skel/dot.xinitrc",
629 "/usr/share/skel/dot.xsession",
634 for (cp = flist; *cp; cp++) {
635 fp = fopen(*cp, "w");
637 fwrite(str, 1, len, fp);
638 fchmod(fileno(fp), 0755);
647 char tmp[FILENAME_MAX];
649 snprintf(tmp, sizeof tmp, "/usr/X11R6/bin/%s", fname);
650 if (file_executable(tmp))
652 snprintf(tmp, sizeof tmp, "/usr/local/bin/%s", fname);
653 return file_executable(tmp);
657 configResolv(dialogMenuItem *ditem)
660 char *cp, *c6p, *dp, *hp;
662 cp = variable_get(VAR_NAMESERVER);
666 fp = fopen("/etc/resolv.conf", "w");
668 return DITEM_FAILURE;
669 if (variable_get(VAR_DOMAINNAME))
670 fprintf(fp, "domain\t%s\n", variable_get(VAR_DOMAINNAME));
671 fprintf(fp, "nameserver\t%s\n", cp);
674 msgDebug("Wrote out /etc/resolv.conf\n");
677 dp = variable_get(VAR_DOMAINNAME);
678 cp = variable_get(VAR_IPADDR);
679 c6p = variable_get(VAR_IPV6ADDR);
680 hp = variable_get(VAR_HOSTNAME);
681 /* Tack ourselves into /etc/hosts */
682 fp = fopen("/etc/hosts", "w");
684 return DITEM_FAILURE;
685 /* Add an entry for localhost */
687 fprintf(fp, "::1\t\t\tlocalhost.%s localhost\n", dp);
688 fprintf(fp, "127.0.0.1\t\tlocalhost.%s localhost\n", dp);
690 fprintf(fp, "::1\t\t\tlocalhost\n");
691 fprintf(fp, "127.0.0.1\t\tlocalhost\n");
693 /* Now the host entries, if applicable */
694 if (((cp && cp[0] != '0') || (c6p && c6p[0] != '0')) && hp) {
700 SAFE_STRCPY(cp2, hp);
701 *(index(cp2, '.')) = '\0';
703 if (c6p && c6p[0] != '0') {
704 fprintf(fp, "%s\t%s %s\n", c6p, hp, cp2);
705 fprintf(fp, "%s\t%s.\n", c6p, hp);
707 if (cp && cp[0] != '0') {
708 fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2);
709 fprintf(fp, "%s\t\t%s.\n", cp, hp);
714 msgDebug("Wrote out /etc/hosts\n");
715 return DITEM_SUCCESS;
719 configRouter(dialogMenuItem *self)
723 ret = variable_get_value(VAR_ROUTER,
724 "Please specify the router you wish to use. Routed is\n"
725 "provided with the stock system and gated is provided\n"
726 "as an optional package which this installation system\n"
727 "will attempt to load if you select gated. Any other\n"
728 "choice of routing daemon will be assumed to be something\n"
729 "the user intends to install themselves before rebooting\n"
730 "the system. If you don't want any routing daemon, choose NO", 1)
731 ? DITEM_SUCCESS : DITEM_FAILURE;
733 if (ret == DITEM_SUCCESS) {
734 char *cp = variable_get(VAR_ROUTER);
736 if (cp && strcmp(cp, "NO")) {
737 variable_set2(VAR_ROUTER_ENABLE, "YES", 1);
738 if (!strcmp(cp, "gated")) {
739 if (package_add("gated") != DITEM_SUCCESS) {
740 msgConfirm("Unable to load gated package. Falling back to no router.");
741 variable_unset(VAR_ROUTER);
742 variable_unset(VAR_ROUTERFLAGS);
743 variable_set2(VAR_ROUTER_ENABLE, "NO", 1);
748 /* Now get the flags, if they chose a router */
749 ret = variable_get_value(VAR_ROUTERFLAGS,
750 "Please Specify the routing daemon flags; if you're running routed\n"
751 "then -q is the right choice for nodes and -s for gateway hosts.\n", 1)
752 ? DITEM_SUCCESS : DITEM_FAILURE;
753 if (ret != DITEM_SUCCESS)
754 variable_unset(VAR_ROUTERFLAGS);
759 variable_set2(VAR_ROUTER_ENABLE, "NO", 1);
760 variable_unset(VAR_ROUTERFLAGS);
761 variable_unset(VAR_ROUTER);
765 variable_set2(VAR_ROUTER_ENABLE, "NO", 1);
766 variable_unset(VAR_ROUTERFLAGS);
767 variable_unset(VAR_ROUTER);
772 /* Shared between us and index_initialize() */
773 extern PkgNode Top, Plist;
776 configPackages(dialogMenuItem *self)
778 int i, restoreflag = 0;
781 /* Did we get an INDEX? */
782 i = index_initialize("packages/INDEX");
783 if (DITEM_STATUS(i) == DITEM_FAILURE)
787 int ret, pos, scroll;
789 /* Bring up the packages menu */
791 index_menu(&Top, &Top, &Plist, &pos, &scroll);
793 if (Plist.kids && Plist.kids->name) {
794 /* Now show the packing list menu */
796 ret = index_menu(&Plist, &Plist, NULL, &pos, &scroll);
797 if (ret & DITEM_LEAVE_MENU)
799 else if (DITEM_STATUS(ret) != DITEM_FAILURE) {
802 for (tmp = Plist.kids; tmp && tmp->name; tmp = tmp->next)
803 (void)index_extract(mediaDevice, &Top, tmp, FALSE);
808 msgConfirm("No packages were selected for extraction.");
814 PkgNodePtr tmp2 = tmp->next;
819 index_init(NULL, &Plist);
820 return DITEM_SUCCESS | (restoreflag ? DITEM_RESTORE : 0);
823 /* Load pcnfsd package */
825 configPCNFSD(dialogMenuItem *self)
829 ret = package_add("pcnfsd");
830 if (DITEM_STATUS(ret) == DITEM_SUCCESS) {
831 variable_set2(VAR_PCNFSD, "YES", 0);
832 variable_set2("mountd_flags", "-n", 1);
838 configInetd(dialogMenuItem *self)
842 WINDOW *w = savescr();
844 if (msgYesNo("The Internet Super Server (inetd) allows a number of simple Internet\n"
845 "services to be enabled, including finger, ftp, and telnetd. Enabling\n"
846 "these services may increase risk of security problems by increasing\n"
847 "the exposure of your system.\n\n"
848 "With this in mind, do you wish to enable inetd?\n")) {
849 variable_set2("inetd_enable", "NO", 1);
851 /* If inetd is enabled, we'll need an inetd.conf */
852 variable_set2("inetd_enable", "YES", 1);
853 if (!msgYesNo("inetd(8) relies on its configuration file, /etc/inetd.conf, to determine\n"
854 "which of its Internet services will be available. The default FreeBSD\n"
855 "inetd.conf(5) leaves all services disabled by default, so they must be\n"
856 "specifically enabled in the configuration file before they will\n"
857 "function, even once inetd(8) is enabled. Note that services for\n"
858 "IPv6 must be separately enabled from IPv4 services.\n\n"
859 "Select [Yes] now to invoke an editor on /etc/inetd.conf, or [No] to\n"
860 "use the current settings.\n")) {
861 sprintf(cmd, "%s /etc/inetd.conf", variable_get(VAR_EDITOR));
867 return DITEM_SUCCESS;
871 configNFSServer(dialogMenuItem *self)
876 /* If we're an NFS server, we need an exports file */
877 if (!file_readable("/etc/exports")) {
878 WINDOW *w = savescr();
880 if (file_readable("/etc/exports.disabled"))
881 vsystem("mv /etc/exports.disabled /etc/exports");
883 dialog_clear_norefresh();
884 msgConfirm("Operating as an NFS server means that you must first configure\n"
885 "an /etc/exports file to indicate which hosts are allowed certain\n"
886 "kinds of access to your local file systems.\n"
887 "Press [ENTER] now to invoke an editor on /etc/exports\n");
888 vsystem("echo '#The following examples export /usr to 3 machines named after ducks,' > /etc/exports");
889 vsystem("echo '#/usr/src and /usr/ports read-only to machines named after trouble makers' >> /etc/exports");
890 vsystem("echo '#/home and all directories under it to machines named after dead rock stars' >> /etc/exports");
891 vsystem("echo '#and, /a to a network of privileged machines allowed to write on it as root.' >> /etc/exports");
892 vsystem("echo '#/usr huey louie dewie' >> /etc/exports");
893 vsystem("echo '#/usr/src /usr/obj -ro calvin hobbes' >> /etc/exports");
894 vsystem("echo '#/home -alldirs janice jimmy frank' >> /etc/exports");
895 vsystem("echo '#/a -maproot=0 -network 10.0.1.0 -mask 255.255.248.0' >> /etc/exports");
896 vsystem("echo '#' >> /etc/exports");
897 vsystem("echo '# You should replace these lines with your actual exported filesystems.' >> /etc/exports");
898 vsystem("echo \"# Note that BSD's export syntax is 'host-centric' vs. Sun's 'FS-centric' one.\" >> /etc/exports");
899 vsystem("echo >> /etc/exports");
900 sprintf(cmd, "%s /etc/exports", variable_get(VAR_EDITOR));
904 variable_set2(VAR_NFS_SERVER, "YES", 1);
905 retval = configRpcBind(NULL);
908 else if (variable_get(VAR_NFS_SERVER)) { /* We want to turn it off again? */
909 vsystem("mv -f /etc/exports /etc/exports.disabled");
910 variable_unset(VAR_NFS_SERVER);
912 return DITEM_SUCCESS | retval;
916 * Extend the standard dmenuToggleVariable() method to also check and set
917 * the rpcbind variable if needed.
920 configRpcBind(dialogMenuItem *self)
926 retval = dmenuToggleVariable(self);
927 if (strcmp(variable_get(self->data), "YES") != 0)
931 if (doupdate && strcmp(variable_get(VAR_RPCBIND_ENABLE), "YES") != 0) {
932 variable_set2(VAR_RPCBIND_ENABLE, "YES", 1);
933 retval |= DITEM_REDRAW;
940 configEtcTtys(dialogMenuItem *self)
944 WINDOW *w = savescr();
946 /* Simply prompt for confirmation, then edit away. */
947 if (msgYesNo("Configuration of system TTYs requires editing the /etc/ttys file.\n"
948 "Typical configuration activities might include enabling getty(8)\n"
949 "on the first serial port to allow login via serial console after\n"
950 "reboot, or to enable xdm. The default ttys file enables normal\n"
951 "virtual consoles, and most sites will not need to perform manual\n"
953 "To load /etc/ttys in the editor, select [Yes], otherwise, [No].")) {
956 sprintf(cmd, "%s /etc/ttys", variable_get(VAR_EDITOR));
962 return DITEM_SUCCESS;
967 checkLoaderACPI(void)
971 if (kenv(KENV_GET, "loader.acpi_disabled_by_user", &val[0], 4) <= 0) {
975 if (strtol(&val[0], NULL, 10) <= 0) {
983 configLoaderACPI(int disable)
987 ldconf = fopen("/boot/loader.conf", "a");
988 if (ldconf == NULL) {
989 msgConfirm("Unable to open /boot/loader.conf. Please consult the\n"
990 "FreeBSD Handbook for instructions on disabling ACPI");
991 return DITEM_FAILURE;
994 fprintf(ldconf, "# --- Generated by sysinstall ---\n");
995 fprintf(ldconf, "hint.acpi.0.disabled=%d\n", disable);
998 return DITEM_SUCCESS;
1003 configMTAPostfix(dialogMenuItem *self)
1008 if(setenv("POSTFIX_DEFAULT_MTA", "YES", 1) != 0)
1009 msgError("Error setting the enviroment variable POSTFIX_DEFAULT_MTA: %s (%u)",
1010 strerror(errno), errno);
1012 ret = package_add("postfix-2.4");
1013 unsetenv("POSTFIX_DEFAULT_MTA");
1015 if(DITEM_STATUS(ret) == DITEM_FAILURE) {
1016 msgConfirm("An error occurred while adding the postfix package\n"
1017 "Please change installation media and try again.");
1021 variable_set2(VAR_SENDMAIL_ENABLE, "YES", 1);
1022 variable_set2("sendmail_flags", "-bd", 1);
1023 variable_set2("sendmail_outbound_enable", "NO", 1);
1024 variable_set2("sendmail_submit_enable", "NO", 1);
1025 variable_set2("sendmail_msp_queue_enable", "NO", 1);
1027 perconf = fopen("/etc/periodic.conf", "a");
1028 if (perconf == NULL) {
1029 msgConfirm("Unable to open /etc/periodic.conf.\n"
1030 "The daily cleanup scripts might generate errors when\n"
1031 "trying to run some sendmail only cleanup scripts.\n"
1032 "Please consult the documentation for the postfix port on how to\n"
1035 /* Not really a serious problem, so we return success */
1036 return DITEM_SUCCESS;
1039 fprintf(perconf, "# --- Generated by sysinstall ---\n");
1040 fprintf(perconf, "daily_clean_hoststat_enable=\"NO\"\n");
1041 fprintf(perconf, "daily_status_mail_rejects_enable=\"NO\"\n");
1042 fprintf(perconf, "daily_status_include_submit_mailq=\"NO\"\n");
1043 fprintf(perconf, "daily_submit_queuerun=\"NO\"\n");
1046 msgConfirm("Postfix is now installed and enabled as the default MTA.\n"
1047 "Please check that the configuration works as expected.\n"
1048 "See the Postfix documentation for more information.\n"
1049 "The documentation can be found in /usr/local/share/doc/postfix/\n"
1050 "or on the Postfix website at http://www.postfix.org/.");
1052 return DITEM_SUCCESS;
1056 configMTAExim(dialogMenuItem *self)
1059 FILE *perconf, *mailerconf, *newsyslogconf;
1061 ret = package_add("exim");
1063 if(DITEM_STATUS(ret) == DITEM_FAILURE) {
1064 msgConfirm("An error occurred while adding the exim package\n"
1065 "Please change installation media and try again.");
1069 variable_set2(VAR_SENDMAIL_ENABLE, "NONE", 1);
1070 variable_set2("exim_enable", "YES", 1);
1072 /* Update periodic.conf */
1073 perconf = fopen("/etc/periodic.conf", "a");
1074 if (perconf == NULL) {
1075 /* Not really a serious problem, so we do not abort */
1076 msgConfirm("Unable to open /etc/periodic.conf.\n"
1077 "The daily cleanup scripts might generate errors when\n"
1078 "trying to run some sendmail only cleanup scripts.\n"
1079 "Please consult the documentation for the exim port on how to\n"
1082 fprintf(perconf, "# --- Generated by sysinstall ---\n");
1083 fprintf(perconf, "daily_clean_hoststat_enable=\"NO\"\n");
1084 fprintf(perconf, "daily_status_include_submit_mailq=\"NO\"\n");
1085 fprintf(perconf, "daily_status_mail_rejects_enable=\"NO\"\n");
1086 fprintf(perconf, "daily_submit_queuerun=\"NO\"\n");
1090 /* Update mailer.conf */
1091 vsystem("mv -f /etc/mail/mailer.conf /etc/mail/mailer.conf.old");
1092 mailerconf = fopen("/etc/mail/mailer.conf", "w");
1093 if (mailerconf == NULL) {
1094 /* Not really a serious problem, so we do not abort */
1095 msgConfirm("Unable to open /etc/mailer.conf.\n"
1096 "Some programs which use the sendmail wrappers may not work.\n"
1097 "Please consult the documentation for the exim port on how\n"
1098 "to correct this.");
1100 fprintf(mailerconf, "# --- Generated by sysinstall ---\n");
1101 fprintf(mailerconf, "# Execute exim instead of sendmail\n");
1102 fprintf(mailerconf, "#\n");
1103 fprintf(mailerconf, "sendmail /usr/local/sbin/exim\n");
1104 fprintf(mailerconf, "send-mail /usr/local/sbin/exim\n");
1105 fprintf(mailerconf, "mailq /usr/local/sbin/exim\n");
1106 fprintf(mailerconf, "newaliases /usr/local/sbin/exim\n");
1107 fprintf(mailerconf, "hoststat /usr/bin/true\n");
1108 fprintf(mailerconf, "purgestat /usr/bin/true\n");
1112 /* Make newsyslog rotate exim logfiles */
1113 newsyslogconf = fopen("/etc/newsyslog.conf", "a");
1114 if (newsyslogconf == NULL) {
1115 /* Not really a serious problem, so we do not abort */
1116 msgConfirm("Unable to open /etc/newsyslog.conf.\n"
1117 "The exim logfiles will not be rotated.\n"
1118 "Please consult the documentation for the exim port on how to\n"
1119 "rotate the logfiles.");
1121 fprintf(newsyslogconf, "# --- Generated by sysinstall ---\n");
1122 fprintf(newsyslogconf, "/var/log/exim/mainlog mailnull:mail 640 7 * @T00 ZN\n");
1123 fprintf(newsyslogconf, "/var/log/exim/rejectlog mailnull:mail 640 7 * @T00 ZN\n");
1124 fclose(newsyslogconf);
1127 msgConfirm("Exim is now installed and enabled as the default MTA.\n"
1128 "Please check that the configuration works as expected.\n"
1129 "See the Exim documentation for more information.\n"
1130 "The documentation can be found in /usr/local/share/doc/exim/\n"
1131 "or on the Exim website at http://www.exim.org/.");
1133 return DITEM_SUCCESS;