Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Jul 2003 13:50:41 -0400
From:      Tom Rhodes <trhodes@FreeBSD.org>
To:        FreeBSD-audit@FreeBSD.org
Subject:   [Review request] Patch to sysinstall(8) to give users multiple MTA selections.
Message-ID:  <20030703135041.5d3e9a4a.trhodes@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
Greetings,

Please find and review the accompanying patch which gives users the
ability to select different MTAs during initial system installation.

The only added MTAs are exim and postfix as, to my knowledge, we are
not permitted to package qmail due to the license.  Along with this,
I'm sure that FreeBSD will only continue to support sendmail(8) as
the standard MTA, however, I felt this would supress some mailing list
discussions which seem to arise every now and again.

FWIW: jhb approved this patch.  Some members of re thought it was a
'neat' idea.  And best of all, it builds and seems to function fine!

I plan to commit this on Monday.  Thanks!

--
Tom Rhodes


diff -ru sysinstall/config.c sysinstall.new/config.c
--- sysinstall/config.c	Mon Jun  2 19:44:03 2003
+++ sysinstall.new/config.c	Thu Jul  3 13:34:38 2003
@@ -373,23 +373,60 @@
     return DITEM_SUCCESS;
 }
 
+/*
+ * Write out rc.conf
+ *
+ * rc.conf is sorted if running as init and the needed utilities are
+ * present
+ *
+ * If rc.conf is sorted, all variables in rc.conf which conflict with
+ * the variables in the environment are removed from the original
+ * rc.conf
+ */
 void
 configRC_conf(void)
 {
-    FILE *rcSite;
+    char line[256];
+    FILE *rcSite, *rcOld;
     Variable *v;
     int write_header;
     time_t t_loc;
     char *cp;
     static int did_marker = 0;
+    int do_sort;
+    int do_merge;
     time_t tp;
 
     configTtys();
     write_header = !file_readable("/etc/rc.conf");
-    rcSite = fopen("/etc/rc.conf", "a");
-    if (!rcSite)
+    do_sort = RunningAsInit && file_readable("/usr/bin/sort") &&
+	file_readable("/usr/bin/uniq");
+    do_merge = do_sort && file_readable("/etc/rc.conf");
+
+    if(do_merge) {
+	rcSite = fopen("/etc/rc.conf.new", "w");
+    } else
+	rcSite = fopen("/etc/rc.conf", "a");
+    if (rcSite == NULL) {
+	msgError("Error opening new rc.conf for writing: %s (%u)", strerror(errno), errno);
 	return;
-    if (write_header) {
+    }
+
+    if (do_merge) {
+	/* "Copy" the old rc.conf */
+	rcOld = fopen("/etc/rc.conf", "r");
+	if(!rcOld) {
+	    msgError("Error opening rc.conf for reading: %s (%u)", strerror(errno), errno);
+	    return;
+	}
+	while(fgets(line, sizeof(line), rcOld)) {
+	    if(line[0] == '#' || variable_check2(line) != 0)
+		fprintf(rcSite, "%s", line);
+	    else /* XXX Only for debugging : */
+		fprintf(rcSite, "#Sysinstall disabled: %s", line);
+	}
+	fclose(rcOld);
+    } else {
 	fprintf(rcSite, "# This file now contains just the overrides from /etc/defaults/rc.conf.\n");
 	fprintf(rcSite, "# Please make all changes to this file, not to /etc/defaults/rc.conf.\n\n");
 	fprintf(rcSite, "# Enable network daemons for user convenience.\n");
@@ -411,10 +448,19 @@
 	}
     }
     fclose(rcSite);
+
+    if(do_merge) {
+	if(rename("/etc/rc.conf.new", "/etc/rc.conf") != 0) {
+	    msgError("Error renaming temporary rc.conf: %s (%u)", strerror(errno), errno);
+	    return;
+	}
+    }
+
     /* Tidy up the resulting file if it's late enough in the installation
 	for sort and uniq to be available */
-    if (RunningAsInit && file_readable("/usr/bin/sort") && file_readable("/usr/bin/uniq"))
+    if (do_sort) {
 	(void)vsystem("sort /etc/rc.conf | uniq > /etc/rc.conf.new && mv /etc/rc.conf.new /etc/rc.conf");
+    }
 }
 
 int
@@ -1091,3 +1137,134 @@
     return DITEM_SUCCESS;
 } 
 #endif
+
+int
+configMTAPostfix(dialogMenuItem *self)
+{
+    int ret;
+    FILE *perconf;
+
+    ret = package_add("postfix");
+
+    if(DITEM_STATUS(ret) == DITEM_FAILURE) {
+	msgConfirm("An error occurred while adding the postfix package\n"
+		   "Please change installation media and try again.");
+	return ret;
+    }
+
+    variable_set2(VAR_SENDMAIL_ENABLE, "YES", 1);
+    variable_set2("sendmail_flags", "-bd", 1);
+    variable_set2("sendmail_outbound_enable", "NO", 1);
+    variable_set2("sendmail_submit_enable", "NO", 1);
+    variable_set2("sendmail_msp_queue_enable", "NO", 1);
+
+    perconf = fopen("/etc/periodic.conf", "a");
+    if (perconf == NULL) {
+	msgConfirm("Unable to open /etc/periodic.conf.\n"
+		   "The daily cleanup scripts might generate errors when\n"
+		   "trying to run some sendmail only cleanup scripts.\n"
+		   "Please consult the documentation for the postfix port on how to\n"
+		   "fix this.");
+
+	/* Not really a serious problem, so we return success */
+	return DITEM_SUCCESS;
+    }
+
+    fprintf(perconf, "# --- Generated by sysinstall ---\n");
+    fprintf(perconf, "daily_clean_hoststat_enable=\"NO\"\n");
+    fprintf(perconf, "daily_status_mail_rejects_enable=\"NO\"\n");
+    fprintf(perconf, "daily_status_include_submit_mailq=\"NO\"\n");
+    fprintf(perconf, "daily_submit_queuerun=\"NO\"\n");
+    fclose(perconf);
+
+    msgConfirm("Postfix is now installed and enabled as the default MTA.\n"
+	       "Please check that the configuration works as expected.\n"
+	       "See the Postfix documentation for more information.\n"
+	       "The documentation can be found in /usr/local/share/doc/postfix/\n"
+	       "or on the Postfix website at http://www.postfix.org/.");
+
+    return DITEM_SUCCESS;
+}
+
+int
+configMTAExim(dialogMenuItem *self)
+{
+    int ret;
+    FILE *perconf, *mailerconf, *newsyslogconf;
+
+    ret = package_add("exim");
+
+    if(DITEM_STATUS(ret) == DITEM_FAILURE) {
+	msgConfirm("An error occurred while adding the exim package\n"
+		   "Please change installation media and try again.");
+	return ret;
+    }
+
+    variable_set2(VAR_SENDMAIL_ENABLE, "NONE", 1);
+
+    if(file_readable("/usr/local/etc/exim/configure.default") &&
+	!file_readable("/usr/local/etc/exim/configure")) {
+	if(vsystem("cp /usr/local/etc/exim/configure.default /usr/local/etc/exim/configure"))
+	    msgConfirm("An error occurred while coping the exim configuration file.\n"
+		       "Please check, if exim is working after you have completed this\n"
+		       "installation.\n");
+    }
+
+    /* Update periodic.conf */
+    perconf = fopen("/etc/periodic.conf", "a");
+    if (perconf == NULL) {
+	/* Not really a serious problem, so we do not abort */
+	msgConfirm("Unable to open /etc/periodic.conf.\n"
+		   "The daily cleanup scripts might generate errors when\n"
+		   "trying to run some sendmail only cleanup scripts.\n"
+		   "Please consult the documentation for the postfix port on how to\n"
+		   "fix this.");
+    } else {
+	fprintf(perconf, "# --- Generated by sysinstall ---\n");
+	fprintf(perconf, "daily_status_include_submit_mailq=\"NO\"\n");
+	fclose(perconf);
+    }
+
+    /* Update mailer.conf */
+    vsystem("mv -f /etc/mail/mailer.conf /etc/mail/mailer.conf.old");
+    mailerconf = fopen("/etc/mail/mailer.conf", "w");
+    if (mailerconf == NULL) {
+	/* Not really a serious problem, so we do not abort */
+	msgConfirm("Unable to open /etc/mailer.conf.\n"
+		   "Some programs which use the sendmail wrappers may not work.\n"
+		   "Please consult the documentation for the exim port on how\n"
+		   "to fix this.");
+    } else {
+	fprintf(mailerconf, "# --- Generated by sysinstall ---\n");
+	fprintf(mailerconf, "# Execute exim instead of sendmail\n");
+	fprintf(mailerconf, "#\n");
+	fprintf(mailerconf, "sendmail	/usr/local/sbin/exim\n");
+	fprintf(mailerconf, "send-mail	/usr/local/sbin/exim\n");
+	fprintf(mailerconf, "mailq		/usr/local/sbin/exim -bp\n");
+	fprintf(mailerconf, "newaliases	/usr/bin/true\n");
+	fclose(mailerconf);
+    }
+
+    /* Make newsyslog rotate exim logfiles */
+    newsyslogconf = fopen("/etc/newsyslog.conf", "a");
+    if (newsyslogconf == NULL) {
+	/* Not really a serious problem, so we do not abort */
+	msgConfirm("Unable to open /etc/newsyslog.conf.\n"
+		   "The exim logfiles will not be rotated.\n"
+		   "Please consult the documentation for the exim port on how to\n"
+		   "rotate the logfiles.");
+    } else {
+	fprintf(newsyslogconf, "# --- Generated by sysinstall ---\n");
+	fprintf(newsyslogconf, "/var/log/exim/mainlog	mailnull:mail	640  7	   *	@T00  Z\n");
+	fprintf(newsyslogconf, "/var/log/exim/rejectlog	mailnull:mail	640  7	   *	@T00  Z\n");
+	fclose(newsyslogconf);
+    }
+
+    msgConfirm("Exim is now installed and enabled as the default MTA.\n"
+	       "Please check that the configuration works as expected.\n"
+	       "See the Exim documentation for more information.\n"
+	       "The documentation can be found in /usr/local/share/doc/exim/\n"
+	       "or on the Exim website at http://www.exim.org/.");
+
+    return DITEM_SUCCESS;
+}
diff -ru sysinstall/menus.c sysinstall.new/menus.c
--- sysinstall/menus.c	Mon Jun  2 19:56:05 2003
+++ sysinstall.new/menus.c	Thu Jul  3 13:34:38 2003
@@ -1606,6 +1606,8 @@
 	dmenuVarCheck,	dmenuToggleVariable, NULL, "gateway_enable=YES" },
       { " inetd",	"This machine wants to run the inet daemon",
 	dmenuVarCheck,	configInetd, NULL, "inetd_enable=YES" },
+      { " Mail",	"This machine wants to run a Mail Transfer Agent",
+	NULL,		dmenuSubmenu, NULL, &MenuMTA },
       { " NFS client",	"This machine will be an NFS client",
 	dmenuVarCheck,	dmenuToggleVariable, NULL, "nfs_client_enable=YES" },
       { " NFS server",	"This machine will be an NFS server",
@@ -1624,8 +1626,6 @@
 	dmenuVarCheck,	configRouter, NULL, "router_enable=YES" },
       { " Rwhod",	"This machine wants to run the rwho daemon",
 	dmenuVarCheck,	dmenuToggleVariable, NULL, "rwhod_enable=YES" },
-      { " Sendmail",	"This machine wants to run the sendmail daemon",
-	NULL,		dmenuSubmenu, NULL, &MenuSendmail },
       { " Sshd",	"This machine wants to run the ssh daemon",
 	dmenuVarCheck,	dmenuToggleVariable, NULL, "sshd_enable=YES" },
       { " TCP Extensions", "Allow RFC1323 and RFC1644 TCP extensions?",
@@ -1633,25 +1633,31 @@
       { NULL } },
 };
 
-DMenu MenuSendmail = {
+DMenu MenuMTA = {
     DMENU_NORMAL_TYPE | DMENU_SELECTION_RETURNS,
-    "Sendmail Invocation Selection",
-    "There are three options for invoking sendmail at startup.\n"
-    "Please select Yes if you want to use sendmail as your mail transfer\n"
-    "agent.  Selecting No disables sendmail's network socket for incoming\n"
-    "email, but still enables sendmail for local and outbound mail.\n"
-    "None disables sendmail completely at startup and disables inbound,\n"
-    "outbound, and local mail.  See /etc/mail/README for more\n"
-    "information.\n",
+    "Mail Transfer Agent Selection",
+    "You can choose which Mail Transfer Agent (MTA) you wish to install and run.\n"
+    "Selecting Sendmail local disables sendmail's network socket for\n"
+    "incoming mail, but still enables sendmail for local and outbound mail.\n"
+    "The Postfix option will install the popular Postfix MTA from the ports\n"
+    "collection.  The Exim option will install the Exim MTA from the ports\n"
+    "collection."
+    "To return to the previous menu, select Exit",
     NULL,
     NULL,
     {
-      { " Yes",		"Start sendmail",
+      { "Sendmail",		"Use sendmail",
 	dmenuVarCheck, dmenuSetVariable, NULL, "sendmail_enable=YES" },
-      { " No",		"Start sendmail, but don't listen from network",
+      { " Sendmail local",	"Use sendmail, but do not listen on the network",
 	dmenuVarCheck, dmenuSetVariable, NULL, "sendmail_enable=NO" },
-      { " None",	"Don't start any sendmail processes",
+      { "Postfix",		"Use the Postfix MTA",
+	NULL, configMTAPostfix, NULL, NULL },
+      { "Exim",			"Use the Exim MTA",
+	NULL, configMTAExim, NULL, NULL },
+      { "None",			"Do not start an MTA",
 	dmenuVarCheck, dmenuSetVariable, NULL, "sendmail_enable=NONE" },
+      { "X Exit",		"Exit this menu (returning to previous)",
+        checkTrue, dmenuExit, NULL, NULL, '<', '<', '<' },
       { NULL } },
 };
 
diff -ru sysinstall/sysinstall.h sysinstall.new/sysinstall.h
--- sysinstall/sysinstall.h	Mon Jun  2 19:44:04 2003
+++ sysinstall.new/sysinstall.h	Thu Jul  3 13:34:38 2003
@@ -187,6 +187,7 @@
 #define VAR_ROUTER			"router"
 #define VAR_ROUTER_ENABLE		"router_enable"
 #define VAR_ROUTERFLAGS			"router_flags"
+#define VAR_SENDMAIL_ENABLE		"sendmail_enable"
 #define VAR_SERIAL_SPEED		"serialSpeed"
 #define VAR_SLOW_ETHER			"slowEthernetCard"
 #define VAR_SWAP_SIZE			"swapSize"
@@ -459,7 +460,7 @@
 extern DMenu            MenuSysconsTtys;        /* System console terminal type menu            */
 #endif
 extern DMenu		MenuNetworking;		/* Network configuration menu			*/
-extern DMenu		MenuSendmail;		/* Sendmail configuration menu			*/
+extern DMenu		MenuMTA;		/* MTA selection menu				*/
 extern DMenu		MenuInstallCustom;	/* Custom Installation menu			*/
 extern DMenu		MenuDistributions;	/* Distribution menu				*/
 extern DMenu		MenuDiskDevices;	/* Disk type devices				*/
@@ -526,6 +527,8 @@
 extern int	configPCNFSD(dialogMenuItem *self);
 extern int	configInetd(dialogMenuItem *self);
 extern int	configNFSServer(dialogMenuItem *self);
+extern int	configMTAPostfix(dialogMenuItem *self);
+extern int	configMTAExim(dialogMenuItem *self);
 extern int	configRpcBind(dialogMenuItem *self);
 extern int	configWriteRC_conf(dialogMenuItem *self);
 extern int	configSecurityProfile(dialogMenuItem *self);
@@ -856,6 +859,7 @@
 extern void	variable_unset(char *var);
 extern char	*variable_get_value(char *var, char *prompt, int dirty);
 extern int 	variable_check(char *data);
+extern int 	variable_check2(char *data);
 extern int	dump_variables(dialogMenuItem *self);
 extern void	free_variables(void);
 extern void     pvariable_set(char *var);
diff -ru sysinstall/variable.c sysinstall.new/variable.c
--- sysinstall/variable.c	Thu Oct 31 21:05:05 2002
+++ sysinstall.new/variable.c	Thu Jul  3 13:34:38 2003
@@ -174,14 +174,25 @@
 }
 
 /* Check if value passed in data (in the form "variable=value") is
-   equal to value of variable stored in env */
+ * valid, and it's status compared to the value of variable stored in
+ * env
+ *
+ * Possible return values :
+ * -3: Invalid line, the data string is NOT set as an env variable
+ * -2: Invalid line, the data string is set as an env variable
+ * -1: Invalid line
+ *  0: Valid line, is NOT equal to env version
+ *  1: Valid line, is equal to env version
+ *  2: Valid line, value empty - e.g. foo=""
+ *  3: Valid line, does not exist in env
+*/
 int
-variable_check(char *data)
+variable_check2(char *data)
 {
     char *cp, *cp2, *cp3, tmp[256];
 
-    if (!data)
-	return FALSE;
+    if (data == NULL)
+	return -1;
     SAFE_STRCPY(tmp, data);
     if ((cp = index(tmp, '=')) != NULL) {
         *(cp++) = '\0';
@@ -193,18 +204,37 @@
 	else if ((cp3 = index(cp, ',')) != NULL)
 	    *cp3 = '\0';
         cp2 = variable_get(tmp);
-        if (cp2) {
-	    if (!*cp)
-		return TRUE;
+        if (cp2 != NULL) {
+	    if (*cp == NULL)
+		return 2;
 	    else
-        	return !strcmp(cp, cp2);
+		return strcmp(cp, cp2) == 0 ? 1 : 0;
 	}
         else
-            return FALSE;
+	    return 3;
     }
     else
-        return variable_get(tmp) ? TRUE : FALSE;
+	return variable_get(tmp) != NULL ? -2 : -3;
 } 
+
+/* Check if the value passed in data (in the form "variable=value") is
+   equal to the value of variable stored in env */
+int
+variable_check(char *data)
+{
+    int ret;
+    ret = variable_check2(data);
+
+    switch(ret) {
+    case -2:
+    case 1:
+    case 2:
+	return TRUE;
+	/* NOT REACHED */
+    default:
+	return FALSE;
+    }
+}
 
 int
 dump_variables(dialogMenuItem *unused)


Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030703135041.5d3e9a4a.trhodes>