As mailer and mailers structures and allow parsing of
a mailers section into those structures.

These structures will subsequently be freed as it is
not yet possible to use reference them in the configuration.

Signed-off-by: Simon Horman <ho...@verge.net.au>
---
 Makefile                |   2 +-
 include/types/mailers.h |  65 ++++++++++++++++++
 src/cfgparse.c          | 177 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/mailers.c           |  17 +++++
 4 files changed, 260 insertions(+), 1 deletion(-)
 create mode 100644 include/types/mailers.h
 create mode 100644 src/mailers.c

diff --git a/Makefile b/Makefile
index 4671759..4e3e166 100644
--- a/Makefile
+++ b/Makefile
@@ -664,7 +664,7 @@ OBJS = src/haproxy.o src/sessionhash.o src/base64.o 
src/protocol.o \
        src/session.o src/hdr_idx.o src/ev_select.o src/signal.o \
        src/acl.o src/sample.o src/memory.o src/freq_ctr.o src/auth.o \
        src/compression.o src/payload.o src/hash.o src/pattern.o src/map.o \
-       src/namespace.o
+       src/namespace.o src/mailers.o
 
 EBTREE_OBJS = $(EBTREE_DIR)/ebtree.o \
               $(EBTREE_DIR)/eb32tree.o $(EBTREE_DIR)/eb64tree.o \
diff --git a/include/types/mailers.h b/include/types/mailers.h
new file mode 100644
index 0000000..582bb94
--- /dev/null
+++ b/include/types/mailers.h
@@ -0,0 +1,65 @@
+/*
+ * include/types/mailer.h
+ * This file defines everything related to mailer.
+ *
+ * Copyright 2015 Horms Solutions Ltd., Simon Horman <ho...@verge.net.au>
+ *
+ * Based on include/types/peers.h
+ *
+ * Copyright 2010 EXCELIANCE, Emeric Brun <eb...@exceliance.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+ */
+
+#ifndef _TYPES_EMAIL_ALERT_H
+#define _TYPES_EMAIL_ALERT_H
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+struct mailer {
+       char *id;
+       struct mailers *mailers;
+       struct {
+               const char *file;       /* file where the section appears */
+               int line;               /* line where the section appears */
+       } conf;                         /* config information */
+       struct sockaddr_storage addr;   /* SMTP server address */
+       struct protocol *proto;         /* SMTP server address's protocol */
+       struct xprt_ops *xprt;          /* SMTP server socket operations at 
transport layer */
+       void *sock_init_arg;            /* socket operations's opaque init 
argument if needed */
+       struct mailer *next;            /* next mailer in the list */
+};
+
+
+struct mailers {
+       char *id;                       /* mailers section name */
+       struct mailer *mailer_list;     /* mailers in this mailers section */
+       struct {
+               const char *file;       /* file where the section appears */
+               int line;               /* line where the section appears */
+       } conf;                         /* config information */
+       struct mailers *next;           /* next mailers section */
+       int count;                      /* total number of mailers in this 
mailers section */
+       int users;                      /* number of users of this mailers 
section */
+};
+
+
+extern struct mailers *mailers;
+
+#endif /* _TYPES_EMAIL_ALERT_H */
+
diff --git a/src/cfgparse.c b/src/cfgparse.c
index c5f20a3..2db5ed1 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -48,6 +48,7 @@
 #include <types/global.h>
 #include <types/obj_type.h>
 #include <types/peers.h>
+#include <types/mailers.h>
 
 #include <proto/acl.h>
 #include <proto/auth.h>
@@ -1916,6 +1917,145 @@ out:
        return err_code;
 }
 
+
+/*
+ * Parse a line in a <listen>, <frontend>, <backend> or <ruleset> section.
+ * Returns the error code, 0 if OK, or any combination of :
+ *  - ERR_ABORT: must abort ASAP
+ *  - ERR_FATAL: we can continue parsing but not start the service
+ *  - ERR_WARN: a warning has been emitted
+ *  - ERR_ALERT: an alert has been emitted
+ * Only the two first ones can stop processing, the two others are just
+ * indicators.
+ */
+int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
+{
+       static struct mailers *curmailers = NULL;
+       struct mailer *newmailer = NULL;
+       const char *err;
+       int err_code = 0;
+       char *errmsg = NULL;
+
+       if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
+               if (!*args[1]) {
+                       Alert("parsing [%s:%d] : missing name for mailers 
section.\n", file, linenum);
+                       err_code |= ERR_ALERT | ERR_ABORT;
+                       goto out;
+               }
+
+               err = invalid_char(args[1]);
+               if (err) {
+                       Alert("parsing [%s:%d] : character '%c' is not 
permitted in '%s' name '%s'.\n",
+                             file, linenum, *err, args[0], args[1]);
+                       err_code |= ERR_ALERT | ERR_ABORT;
+                       goto out;
+               }
+
+               for (curmailers = mailers; curmailers != NULL; curmailers = 
curmailers->next) {
+                       /*
+                        * If there are two proxies with the same name only 
following
+                        * combinations are allowed:
+                        */
+                       if (strcmp(curmailers->id, args[1]) == 0) {
+                               Warning("Parsing [%s:%d]: mailers '%s' has same 
name as another mailers (declared at %s:%d).\n",
+                                       file, linenum, args[1], 
curmailers->conf.file, curmailers->conf.line);
+                               err_code |= ERR_WARN;
+                       }
+               }
+
+               if ((curmailers = (struct mailers *)calloc(1, sizeof(struct 
mailers))) == NULL) {
+                       Alert("parsing [%s:%d] : out of memory.\n", file, 
linenum);
+                       err_code |= ERR_ALERT | ERR_ABORT;
+                       goto out;
+               }
+
+               curmailers->next = mailers;
+               mailers = curmailers;
+               curmailers->conf.file = strdup(file);
+               curmailers->conf.line = linenum;
+               curmailers->id = strdup(args[1]);
+       }
+       else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
+               struct sockaddr_storage *sk;
+               int port1, port2;
+               struct protocol *proto;
+
+               if (!*args[2]) {
+                       Alert("parsing [%s:%d] : '%s' expects <name> and 
<addr>[:<port>] as arguments.\n",
+                             file, linenum, args[0]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
+               err = invalid_char(args[1]);
+               if (err) {
+                       Alert("parsing [%s:%d] : character '%c' is not 
permitted in server name '%s'.\n",
+                             file, linenum, *err, args[1]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
+               if ((newmailer = (struct mailer *)calloc(1, sizeof(struct 
mailer))) == NULL) {
+                       Alert("parsing [%s:%d] : out of memory.\n", file, 
linenum);
+                       err_code |= ERR_ALERT | ERR_ABORT;
+                       goto out;
+               }
+
+               /* the mailers are linked backwards first */
+               curmailers->count++;
+               newmailer->next = curmailers->mailer_list;
+               curmailers->mailer_list = newmailer;
+               newmailer->mailers = curmailers;
+               newmailer->conf.file = strdup(file);
+               newmailer->conf.line = linenum;
+
+               newmailer->id = strdup(args[1]);
+
+               sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL);
+               if (!sk) {
+                       Alert("parsing [%s:%d] : '%s %s' : %s\n", file, 
linenum, args[0], args[1], errmsg);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
+               proto = protocol_by_family(sk->ss_family);
+               if (!proto || !proto->connect) {
+                       Alert("parsing [%s:%d] : '%s %s' : connect() not 
supported for this address family.\n",
+                             file, linenum, args[0], args[1]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
+               if (port1 != port2) {
+                       Alert("parsing [%s:%d] : '%s %s' : port ranges and 
offsets are not allowed in '%s'\n",
+                             file, linenum, args[0], args[1], args[2]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
+               if (!port1) {
+                       Alert("parsing [%s:%d] : '%s %s' : missing or invalid 
port in '%s'\n",
+                             file, linenum, args[0], args[1], args[2]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
+               newmailer->addr = *sk;
+               newmailer->proto = proto;
+               newmailer->xprt  = &raw_sock;
+               newmailer->sock_init_arg = NULL;
+       } /* neither "mailer" nor "mailers" */
+       else if (*args[0] != 0) {
+               Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' 
section\n", file, linenum, args[0], cursection);
+               err_code |= ERR_ALERT | ERR_FATAL;
+               goto out;
+       }
+
+out:
+       free(errmsg);
+       return err_code;
+}
+
 int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
 {
        static struct proxy *curproxy = NULL;
@@ -5942,6 +6082,7 @@ int readcfgfile(const char *file)
            !cfg_register_section("global",   cfg_parse_global) ||
            !cfg_register_section("userlist", cfg_parse_users)  ||
            !cfg_register_section("peers",    cfg_parse_peers)  ||
+           !cfg_register_section("mailers",  cfg_parse_mailers) ||
            !cfg_register_section("namespace_list",    cfg_parse_netns))
                return -1;
 
@@ -7653,6 +7794,42 @@ out_uri_auth_compat:
                }
        }
 
+       if (mailers) {
+               struct mailers *curmailers = mailers, **last;
+               struct mailer *m, *mb;
+
+               /* Remove all mailers sections which don't have a valid 
listener.
+                * This can happen when a mailers section is never referenced.
+                */
+               last = &mailers;
+               while (*last) {
+                       curmailers = *last;
+                       if (curmailers->users) {
+                               last = &curmailers->next;
+                               continue;
+                       }
+
+                       Warning("Removing incomplete section 'mailers %s'.\n",
+                               curmailers->id);
+
+                       m = curmailers->mailer_list;
+                       while (m) {
+                               mb = m->next;
+                               free(m->id);
+                               free(m);
+                               m = mb;
+                       }
+
+                       /* Destroy and unlink this curmailers section.
+                        * Note: curmailers is backed up into *last.
+                        */
+                       free(curmailers->id);
+                       curmailers = curmailers->next;
+                       free(*last);
+                       *last = curmailers;
+               }
+       }
+
        pool2_hdr_idx = create_pool("hdr_idx",
                                    global.tune.max_http_hdr * sizeof(struct 
hdr_idx_elem),
                                    MEM_F_SHARED);
diff --git a/src/mailers.c b/src/mailers.c
new file mode 100644
index 0000000..4335453
--- /dev/null
+++ b/src/mailers.c
@@ -0,0 +1,17 @@
+/*
+ * Mailer management.
+ *
+ * Copyright 2015 Horms Solutions Ltd, Simon Horman <ho...@verge.net.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <types/mailers.h>
+
+struct mailers *mailers = NULL;
-- 
2.1.4


Reply via email to