MEDIUM: Allow configuration of email alerts

This currently does nothing beyond parsing the configuration
and storing in the proxy as there is no implementation of email alerts.

Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/include/types/mailers.h b/include/types/mailers.h
index 582bb94..07374a7 100644
--- a/include/types/mailers.h
+++ b/include/types/mailers.h
@@ -23,8 +23,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef _TYPES_EMAIL_ALERT_H
-#define _TYPES_EMAIL_ALERT_H
+#ifndef _TYPES_MAILERS_H
+#define _TYPES_MAILERS_H
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -61,5 +61,5 @@
 
 extern struct mailers *mailers;
 
-#endif /* _TYPES_EMAIL_ALERT_H */
+#endif /* _TYPES_MAILERS_H */
 
diff --git a/include/types/proxy.h b/include/types/proxy.h
index d67fe88..72d1024 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -380,6 +380,16 @@
 	} conf;					/* config information */
 	void *parent;				/* parent of the proxy when applicable */
 	struct comp *comp;			/* http compression */
+
+	struct {
+		union {
+			struct mailers *m;	/* Mailer to send email alerts via */
+			char *name;
+		} mailers;
+		char *from;			/* Address to send email allerts from */
+		char *to;			/* Address(es) to send email allerts to */
+		char *myhostname;		/* Identity to use in HELO command sent to mailer */
+	} email_alert;
 };
 
 struct switching_rule {
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 2db5ed1..de94074 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2056,6 +2056,18 @@
 	return err_code;
 }
 
+static void free_email_alert(struct proxy *p)
+{
+	free(p->email_alert.mailers.name);
+	p->email_alert.mailers.name = NULL;
+	free(p->email_alert.from);
+	p->email_alert.from = NULL;
+	free(p->email_alert.to);
+	p->email_alert.to = NULL;
+	free(p->email_alert.myhostname);
+	p->email_alert.myhostname = NULL;
+}
+
 int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
 {
 	static struct proxy *curproxy = NULL;
@@ -2352,6 +2364,15 @@
 		if (defproxy.check_command)
 			curproxy->check_command = strdup(defproxy.check_command);
 
+		if (defproxy.email_alert.mailers.name)
+			curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
+		if (defproxy.email_alert.from)
+			curproxy->email_alert.from = strdup(defproxy.email_alert.from);
+		if (defproxy.email_alert.to)
+			curproxy->email_alert.to = strdup(defproxy.email_alert.to);
+		if (defproxy.email_alert.myhostname)
+			curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
+
 		goto out;
 	}
 	else if (!strcmp(args[0], "defaults")) {  /* use this one to assign default values */
@@ -2393,6 +2414,7 @@
 		free(defproxy.conf.lfs_file);
 		free(defproxy.conf.uif_file);
 		free(defproxy.log_tag);
+		free_email_alert(&defproxy);
 
 		for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
 			chunk_destroy(&defproxy.errmsg[rc]);
@@ -2870,6 +2892,61 @@
 			err_code |= ERR_ALERT | ERR_FATAL;
 		}
 	}/* end else if (!strcmp(args[0], "cookie"))  */
+	else if (!strcmp(args[0], "email-alert")) {
+		if (*(args[1]) == 0) {
+			Alert("parsing [%s:%d] : missing argument after '%s'.\n",
+			      file, linenum, args[0]);
+			err_code |= ERR_ALERT | ERR_FATAL;
+			goto out;
+                }
+
+		if (!strcmp(args[1], "from")) {
+			if (*(args[1]) == 0) {
+				Alert("parsing [%s:%d] : missing argument after '%s'.\n",
+				      file, linenum, args[1]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+			}
+			free(curproxy->email_alert.from);
+			curproxy->email_alert.from = strdup(args[2]);
+		}
+		else if (!strcmp(args[1], "mailers")) {
+			if (*(args[1]) == 0) {
+				Alert("parsing [%s:%d] : missing argument after '%s'.\n",
+				      file, linenum, args[1]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+			}
+			free(curproxy->email_alert.mailers.name);
+			curproxy->email_alert.mailers.name = strdup(args[2]);
+		}
+		else if (!strcmp(args[1], "myhostname")) {
+			if (*(args[1]) == 0) {
+				Alert("parsing [%s:%d] : missing argument after '%s'.\n",
+				      file, linenum, args[1]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+			}
+			free(curproxy->email_alert.myhostname);
+			curproxy->email_alert.myhostname = strdup(args[2]);
+		}
+		else if (!strcmp(args[1], "to")) {
+			if (*(args[1]) == 0) {
+				Alert("parsing [%s:%d] : missing argument after '%s'.\n",
+				      file, linenum, args[1]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+			}
+			free(curproxy->email_alert.to);
+			curproxy->email_alert.to = strdup(args[2]);
+		}
+		else {
+			Alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
+			      file, linenum, args[1]);
+			err_code |= ERR_ALERT | ERR_FATAL;
+			goto out;
+		}
+	}/* end else if (!strcmp(args[0], "email-alert"))  */
 	else if (!strcmp(args[0], "external-check")) {
 		if (*(args[1]) == 0) {
 			Alert("parsing [%s:%d] : missing argument after '%s'.\n",
@@ -6530,6 +6607,17 @@
 			}
 		}
 
+		if (
+		    (curproxy->email_alert.mailers.name || curproxy->email_alert.from || curproxy->email_alert.myhostname || curproxy->email_alert.to) &&
+		    !(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
+			Warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
+				"'email-alert from', 'email-alert mailer', 'email-alert hostname' or 'email-alert to' requrires each of"
+				"'email-alert from', 'email-alert mailer' and 'email-alert to'  to be present).\n",
+				proxy_type_str(curproxy), curproxy->id);
+			err_code |= ERR_WARN;
+			free_email_alert(curproxy);
+		}
+
 		if (curproxy->check_command) {
 			int clear = 0;
 			if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
@@ -6893,6 +6981,27 @@
 			}
 		}
 
+
+		if (curproxy->email_alert.mailers.name) {
+			struct mailers *curmailers = mailers;
+
+			for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
+				if (strcmp(curmailers->id, curproxy->email_alert.mailers.name) == 0) {
+					free(curproxy->email_alert.mailers.name);
+					curproxy->email_alert.mailers.m = curmailers;
+					curmailers->users++;
+					break;
+				}
+			}
+
+			if (!curmailers) {
+				Alert("Proxy '%s': unable to find mailers '%s'.\n",
+				      curproxy->id, curproxy->email_alert.mailers.name);
+				free_email_alert(curproxy);
+				cfgerr++;
+			}
+		}
+
 		if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
 		    !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
 		    (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {