diff options
author | Gilles Chehade <gilles@poolp.org> | 2012-11-15 19:53:54 +0100 |
---|---|---|
committer | Gilles Chehade <gilles@poolp.org> | 2012-11-15 19:53:54 +0100 |
commit | b08a98cf23f4acba7e16764420f2804ffb19755c (patch) | |
tree | 82aca37919b611057b413aa9662aebfe10578bd5 | |
parent | tweak syntax slightly to provide simpler semantic for backend/paths (diff) | |
download | OpenSMTPD-b08a98cf23f4acba7e16764420f2804ffb19755c.tar.xz OpenSMTPD-b08a98cf23f4acba7e16764420f2804ffb19755c.zip |
- rework the table API:
* allow lookup() to return an error status
* allow lookup() to *not* allocate if we just want to check
- adapt the static and db table backends to the new API
- adapt every caller to the new API
- introduce table_getpwnam, the first K_USERINFO capable backend
-rw-r--r-- | smtpd/aliases.c | 46 | ||||
-rw-r--r-- | smtpd/lka.c | 19 | ||||
-rw-r--r-- | smtpd/makemap/Makefile | 2 | ||||
-rw-r--r-- | smtpd/ruleset.c | 2 | ||||
-rw-r--r-- | smtpd/smtpd.h | 4 | ||||
-rw-r--r-- | smtpd/smtpd/Makefile | 1 | ||||
-rw-r--r-- | smtpd/table.c | 17 | ||||
-rw-r--r-- | smtpd/table_db.c | 116 | ||||
-rw-r--r-- | smtpd/table_getpwnam.c | 129 | ||||
-rw-r--r-- | smtpd/table_static.c | 130 |
10 files changed, 310 insertions, 156 deletions
diff --git a/smtpd/aliases.c b/smtpd/aliases.c index 1fc2dc8c..94da92f0 100644 --- a/smtpd/aliases.c +++ b/smtpd/aliases.c @@ -44,15 +44,16 @@ static int alias_is_include(struct expandnode *, const char *, size_t); int aliases_get(objid_t id, struct expand *expand, const char *username) { - struct table_alias *table_alias; - struct expandnode *xn; - char buf[MAX_LOCALPART_SIZE]; - size_t nbaliases; + struct table_alias *table_alias = NULL; + struct expandnode *xn; + char buf[MAX_LOCALPART_SIZE]; + size_t nbaliases; + int ret; xlowercase(buf, username, sizeof(buf)); - table_alias = table_lookup(id, buf, K_ALIAS); - if (table_alias == NULL) - return (errno ? -1 : 0); + ret = table_lookup(id, buf, K_ALIAS, (void **)&table_alias); + if (ret <= 0) + return ret; /* foreach node in table_alias expandtree, we merge */ nbaliases = 0; @@ -76,26 +77,28 @@ int aliases_virtual_get(objid_t id, struct expand *expand, const struct mailaddr *maddr) { - struct table_virtual *table_virtual; + struct table_virtual *table_virtual = NULL; struct expandnode *xn; char buf[MAX_LINE_SIZE]; char *pbuf = buf; int nbaliases; + int ret; if (! bsnprintf(buf, sizeof(buf), "%s@%s", maddr->user, maddr->domain)) return 0; xlowercase(buf, buf, sizeof(buf)); + + ret = table_lookup(id, buf, K_VIRTUAL, (void **)&table_virtual); + if (ret < 0) + return (-1); - table_virtual = table_lookup(id, buf, K_VIRTUAL); - if (table_virtual == NULL) { - if (errno) - return (-1); + if (ret == 0) { pbuf = strchr(buf, '@'); - table_virtual = table_lookup(id, pbuf, K_VIRTUAL); + ret = table_lookup(id, pbuf, K_VIRTUAL, (void **)&table_virtual); } - if (table_virtual == NULL) - return (errno ? -1 : 0); + if (ret <= 0) + return ret; /* foreach node in table_virtual expand, we merge */ nbaliases = 0; @@ -118,19 +121,16 @@ aliases_virtual_get(objid_t id, struct expand *expand, int aliases_vdomain_exists(objid_t id, const char *hostname) { - struct table_virtual *table_virtual; - char buf[MAXHOSTNAMELEN]; + char buf[MAXHOSTNAMELEN]; + int ret; xlowercase(buf, hostname, sizeof(buf)); - table_virtual = table_lookup(id, buf, K_VIRTUAL); - if (table_virtual == NULL) - return (errno ? -1 : 0); + ret = table_lookup(id, buf, K_VIRTUAL, NULL); + if (ret <= 0) + return ret; /* XXX - for now the table API always allocate */ log_debug("debug: aliases_vdomain_exist: '%s' exists", hostname); - expand_free(&table_virtual->expand); - free(table_virtual); - return 1; } diff --git a/smtpd/lka.c b/smtpd/lka.c index d148b61b..0998f86e 100644 --- a/smtpd/lka.c +++ b/smtpd/lka.c @@ -59,6 +59,7 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) struct table *table; struct table *tp; void *tmp; + int ret; if (imsg->hdr.type == IMSG_DNS_HOST || imsg->hdr.type == IMSG_DNS_MX || imsg->hdr.type == IMSG_DNS_PTR) { @@ -102,7 +103,7 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) if (iev->proc == PROC_MTA) { switch (imsg->hdr.type) { case IMSG_LKA_SECRET: { - struct table_credentials *table_credentials; + struct table_credentials *table_credentials = NULL; secret = imsg->data; table = table_findbyname(secret->tablename); @@ -113,12 +114,18 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) -1, secret, sizeof *secret); return; } - table_credentials = table_lookup(table->t_id, secret->host, - K_CREDENTIALS); - log_debug("debug: lka: %s credentials lookup (%d)", secret->host, - table_credentials != NULL); + + ret = table_lookup(table->t_id, secret->host, K_CREDENTIALS, + (void **)&table_credentials); + + log_debug("debug: lka: %s credentials lookup (%d)", + secret->host, ret); + secret->secret[0] = '\0'; - if (table_credentials == NULL) + if (ret == -1) + log_warnx("warn: error with %s credentials", + secret->host); + else if (ret == 0) log_warnx("warn: %s credentials not found", secret->host); else if (lka_encode_credentials(secret->secret, diff --git a/smtpd/makemap/Makefile b/smtpd/makemap/Makefile index 004ec739..ff5cca0e 100644 --- a/smtpd/makemap/Makefile +++ b/smtpd/makemap/Makefile @@ -18,7 +18,7 @@ CFLAGS+= -Wsign-compare -Wbounded CFLAGS+= -DNO_IO SRCS= parse.y makemap.c aliases.c expand.c log.c util.c table.c \ - table_static.c table_db.c tree.c + table_static.c table_db.c table_getpwnam.c tree.c DPADD+= ${LIBUTIL} ${LIBCRYPTO} LDADD+= -lutil -lcrypto diff --git a/smtpd/ruleset.c b/smtpd/ruleset.c index 23f99245..5fcd53ef 100644 --- a/smtpd/ruleset.c +++ b/smtpd/ruleset.c @@ -83,7 +83,7 @@ ruleset_match(const struct envelope *evp) } } else if (table_lookup(table->t_id, maddr->domain, - K_VIRTUAL) != NULL) { + K_VIRTUAL, NULL) > 0) { return (r); } else if (errno) { errno = EAGAIN; diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h index f01d9e63..682a87cc 100644 --- a/smtpd/smtpd.h +++ b/smtpd/smtpd.h @@ -298,7 +298,7 @@ struct table_backend { void *(*open)(struct table *); int (*update)(struct table *, const char *); void (*close)(void *); - void *(*lookup)(void *, const char *, enum table_service); + int (*lookup)(void *, const char *, enum table_service, void **); int (*compare)(void *, const char *, enum table_service, int (*)(const char *, const char *)); }; @@ -1165,7 +1165,7 @@ void *table_open(struct table *); void table_update(struct table *); void table_close(struct table *, void *); int table_config_parser(struct table *, const char *); -void *table_lookup(objid_t, const char *, enum table_service); +int table_lookup(objid_t, const char *, enum table_service, void **); int table_compare(objid_t, const char *, enum table_service, int (*)(const char *, const char *)); struct table *table_find(objid_t); diff --git a/smtpd/smtpd/Makefile b/smtpd/smtpd/Makefile index ad53a54d..13fe166c 100644 --- a/smtpd/smtpd/Makefile +++ b/smtpd/smtpd/Makefile @@ -22,6 +22,7 @@ SRCS+= delivery_maildir.c SRCS+= delivery_mbox.c SRCS+= delivery_mda.c SRCS+= table_db.c +SRCS+= table_getpwnam.c SRCS+= table_static.c SRCS+= queue_fsqueue.c SRCS+= queue_ram.c diff --git a/smtpd/table.c b/smtpd/table.c index f54e2379..5f01a147 100644 --- a/smtpd/table.c +++ b/smtpd/table.c @@ -38,6 +38,7 @@ struct table_backend *table_backend_lookup(const char *); extern struct table_backend table_backend_static; extern struct table_backend table_backend_db; +extern struct table_backend table_backend_getpwnam; static objid_t last_table_id = 0; @@ -48,6 +49,8 @@ table_backend_lookup(const char *backend) return &table_backend_static; if (!strcmp(backend, "db")) return &table_backend_db; + if (!strcmp(backend, "getpwnam")) + return &table_backend_getpwnam; return NULL; } @@ -75,30 +78,28 @@ table_find(objid_t id) return (t); } -void * -table_lookup(objid_t id, const char *key, enum table_service kind) +int +table_lookup(objid_t id, const char *key, enum table_service kind, void **retp) { void *hdl = NULL; - char *ret = NULL; struct table *table; struct table_backend *backend = NULL; + int ret; table = table_find(id); if (table == NULL) { errno = EINVAL; - return NULL; + return -1; } backend = table_backend_lookup(table->t_src); hdl = backend->open(table); if (hdl == NULL) { log_warn("warn: table_lookup: can't open %s", table->t_config); - if (errno == 0) - errno = ENOTSUP; - return NULL; + return -1; } - ret = backend->lookup(hdl, key, kind); + ret = backend->lookup(hdl, key, kind, retp); backend->close(hdl); errno = 0; diff --git a/smtpd/table_db.c b/smtpd/table_db.c index 1b4c18fe..44822401 100644 --- a/smtpd/table_db.c +++ b/smtpd/table_db.c @@ -40,17 +40,17 @@ static int table_db_config(struct table *, const char *); static int table_db_update(struct table *, const char *); static void *table_db_open(struct table *); -static void *table_db_lookup(void *, const char *, enum table_service); +static int table_db_lookup(void *, const char *, enum table_service, void **); static int table_db_compare(void *, const char *, enum table_service, int (*)(const char *, const char *)); static void table_db_close(void *); static char *table_db_get_entry(void *, const char *, size_t *); -static void *table_db_credentials(const char *, char *, size_t); -static void *table_db_alias(const char *, char *, size_t); -static void *table_db_virtual(const char *, char *, size_t); -static void *table_db_netaddr(const char *, char *, size_t); +static int table_db_credentials(const char *, char *, size_t, void **); +static int table_db_alias(const char *, char *, size_t, void **); +static int table_db_virtual(const char *, char *, size_t, void **); +static int table_db_netaddr(const char *, char *, size_t, void **); struct table_backend table_backend_db = { K_ALIAS|K_VIRTUAL|K_CREDENTIALS|K_NETADDR, @@ -62,7 +62,6 @@ struct table_backend table_backend_db = { table_db_compare }; - static int table_db_config(struct table *table, const char *config) { @@ -89,33 +88,33 @@ table_db_close(void *hdl) db->close(db); } -static void * -table_db_lookup(void *hdl, const char *key, enum table_service kind) +static int +table_db_lookup(void *hdl, const char *key, enum table_service kind, void **retp) { char *line; size_t len; - void *ret; + int ret; line = table_db_get_entry(hdl, key, &len); if (line == NULL) - return NULL; + return 0; ret = 0; switch (kind) { case K_ALIAS: - ret = table_db_alias(key, line, len); + ret = table_db_alias(key, line, len, retp); break; case K_CREDENTIALS: - ret = table_db_credentials(key, line, len); + ret = table_db_credentials(key, line, len, retp); break; case K_VIRTUAL: - ret = table_db_virtual(key, line, len); + ret = table_db_virtual(key, line, len, retp); break; case K_NETADDR: - ret = table_db_netaddr(key, line, len); + ret = table_db_netaddr(key, line, len, retp); break; default: @@ -174,53 +173,52 @@ table_db_get_entry(void *hdl, const char *key, size_t *len) return xmemdup(dbv.data, dbv.size, "table_db_get_entry"); } -static void * -table_db_credentials(const char *key, char *line, size_t len) +static int +table_db_credentials(const char *key, char *line, size_t len, void **retp) { - struct table_credentials *table_credentials = NULL; + struct table_credentials *credentials = NULL; char *p; /* credentials are stored as user:password */ if (len < 3) - return NULL; + return -1; /* too big to fit in a smtp session line */ if (len >= MAX_LINE_SIZE) - return NULL; + return -1; p = strchr(line, ':'); if (p == NULL) - return NULL; + return -1; if (p == line || p == line + len - 1) - return NULL; + return -1; *p++ = '\0'; - table_credentials = xcalloc(1, sizeof *table_credentials, + credentials = xcalloc(1, sizeof *credentials, "table_db_credentials"); - - if (strlcpy(table_credentials->username, line, - sizeof(table_credentials->username)) >= - sizeof(table_credentials->username)) + if (strlcpy(credentials->username, line, sizeof(credentials->username)) + >= sizeof(credentials->username)) goto err; - if (strlcpy(table_credentials->password, p, - sizeof(table_credentials->password)) >= - sizeof(table_credentials->password)) + if (strlcpy(credentials->password, p, sizeof(credentials->password)) + >= sizeof(credentials->password)) goto err; - return table_credentials; + *retp = credentials; + return 1; err: - free(table_credentials); - return NULL; + *retp = NULL; + free(credentials); + return -1; } -static void * -table_db_alias(const char *key, char *line, size_t len) +static int +table_db_alias(const char *key, char *line, size_t len, void **retp) { - char *subrcpt; - char *endp; + char *subrcpt; + char *endp; struct table_alias *table_alias = NULL; struct expandnode xn; @@ -244,29 +242,32 @@ table_db_alias(const char *key, char *line, size_t len) expand_insert(&table_alias->expand, &xn); table_alias->nbnodes++; } - - return table_alias; + *retp = table_alias; + return 1; error: + *retp = NULL; expand_free(&table_alias->expand); free(table_alias); - return NULL; + return -1; } -static void * -table_db_virtual(const char *key, char *line, size_t len) +static int +table_db_virtual(const char *key, char *line, size_t len, void **retp) { - char *subrcpt; - char *endp; + char *subrcpt; + char *endp; struct table_virtual *table_virtual = NULL; struct expandnode xn; - table_virtual = xcalloc(1, sizeof *table_virtual, "table_db_virtual"); - /* domain key, discard value */ - if (strchr(key, '@') == NULL) - return table_virtual; + if (strchr(key, '@') == NULL) { + *retp = NULL; + return 1; + } + table_virtual = xcalloc(1, sizeof *table_virtual, + "table_db_virtual"); while ((subrcpt = strsep(&line, ",")) != NULL) { /* subrcpt: strip initial whitespace. */ while (isspace((int)*subrcpt)) @@ -286,28 +287,33 @@ table_db_virtual(const char *key, char *line, size_t len) table_virtual->nbnodes++; } - return table_virtual; + *retp = table_virtual; + return 1; error: + *retp = NULL; expand_free(&table_virtual->expand); free(table_virtual); - return NULL; + return 0; } -static void * -table_db_netaddr(const char *key, char *line, size_t len) +static int +table_db_netaddr(const char *key, char *line, size_t len, void **retp) { struct table_netaddr *table_netaddr = NULL; table_netaddr = xcalloc(1, sizeof *table_netaddr, "table_db_netaddr"); - + if (! text_to_netaddr(&table_netaddr->netaddr, line)) - goto error; + goto error; - return table_netaddr; + *retp = table_netaddr; + return 1; error: + *retp = NULL; free(table_netaddr); - return NULL; + return 0; } + diff --git a/smtpd/table_getpwnam.c b/smtpd/table_getpwnam.c new file mode 100644 index 00000000..10277f25 --- /dev/null +++ b/smtpd/table_getpwnam.c @@ -0,0 +1,129 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2012 Gilles Chehade <gilles@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/tree.h> +#include <sys/param.h> +#include <sys/socket.h> + +#include <ctype.h> +#include <err.h> +#include <event.h> +#include <fcntl.h> +#include <imsg.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "smtpd.h" +#include "log.h" + + +/* getpwnam(3) backend */ +static int table_getpwnam_config(struct table *, const char *); +static int table_getpwnam_update(struct table *, const char *); +static void *table_getpwnam_open(struct table *); +static int table_getpwnam_lookup(void *, const char *, enum table_service, void **); + +static int table_getpwnam_compare(void *, const char *, enum table_service, + int (*)(const char *, const char *)); +static void table_getpwnam_close(void *); + +struct table_backend table_backend_getpwnam = { + K_USERINFO, + table_getpwnam_config, + table_getpwnam_open, + table_getpwnam_update, + table_getpwnam_close, + table_getpwnam_lookup, + table_getpwnam_compare +}; + + +static int +table_getpwnam_config(struct table *table, const char *config) +{ + if (config) + return 0; + return 1; +} + +static int +table_getpwnam_update(struct table *table, const char *config) +{ + return 1; +} + +static void * +table_getpwnam_open(struct table *table) +{ + return table; +} + +static void +table_getpwnam_close(void *hdl) +{ + return; +} + +static int +table_getpwnam_lookup(void *hdl, const char *key, enum table_service kind, void **ret) +{ + struct table_userinfo *userinfo; + struct passwd *pw; + size_t s; + + if (kind != K_USERINFO) + return -1; + + pw = getpwnam(key); + if (pw == NULL) + return 0; + + if (ret == NULL) + return 1; + + userinfo = xcalloc(1, sizeof *userinfo, "table_getpwnam_lookup"); + userinfo->uid = pw->pw_uid; + userinfo->gid = pw->pw_gid; + s = strlcpy(userinfo->username, pw->pw_name, sizeof(userinfo->username)); + if (s >= sizeof(userinfo->username)) + goto error; + s = strlcpy(userinfo->password, pw->pw_passwd, sizeof(userinfo->password)); + if (s >= sizeof(userinfo->password)) + goto error; + s = strlcpy(userinfo->directory, pw->pw_passwd, sizeof(userinfo->directory)); + if (s >= sizeof(userinfo->directory)) + goto error; + + *ret = userinfo; + return 1; + +error: + free(userinfo); + return -1; +} + +static int +table_getpwnam_compare(void *hdl, const char *key, enum table_service kind, + int (*func)(const char *, const char *)) +{ + return 0; +} diff --git a/smtpd/table_static.c b/smtpd/table_static.c index 236864e7..26f80c22 100644 --- a/smtpd/table_static.c +++ b/smtpd/table_static.c @@ -39,15 +39,15 @@ static int table_static_config(struct table *, const char *); static int table_static_update(struct table *, const char *); static void *table_static_open(struct table *); -static void *table_static_lookup(void *, const char *, enum table_service); +static int table_static_lookup(void *, const char *, enum table_service, void **); static int table_static_compare(void *, const char *, enum table_service, int (*)(const char *, const char *)); static void table_static_close(void *); -static void *table_static_credentials(const char *, char *, size_t); -static void *table_static_alias(const char *, char *, size_t); -static void *table_static_virtual(const char *, char *, size_t); -static void *table_static_netaddr(const char *, char *, size_t); +static int table_static_credentials(const char *, char *, size_t, void **); +static int table_static_alias(const char *, char *, size_t, void **); +static int table_static_virtual(const char *, char *, size_t, void **); +static int table_static_netaddr(const char *, char *, size_t, void **); struct table_backend table_backend_static = { K_ALIAS|K_VIRTUAL|K_CREDENTIALS|K_NETADDR, @@ -118,49 +118,53 @@ table_static_close(void *hdl) return; } -static void * -table_static_lookup(void *hdl, const char *key, enum table_service kind) +static int +table_static_lookup(void *hdl, const char *key, enum table_service kind, void **retp) { struct table *m = hdl; struct mapel *me = NULL; char *line; - void *ret; size_t len; + int ret; line = NULL; - TAILQ_FOREACH(me, &m->t_contents, me_entry) { - if (strcmp(key, me->me_key) == 0) { - if (me->me_val == NULL) - return NULL; - line = strdup(me->me_val); - break; - } + TAILQ_FOREACH(me, &m->t_contents, me_entry) + if (strcmp(key, me->me_key) == 0) { + line = me->me_val; + break; + } + + if (retp == NULL) + return me ? 1 : 0; + + if (me == NULL) { + *retp = NULL; + return 0; } - if (line == NULL) - return NULL; + if ((line = strdup(line)) == NULL) + return -1; len = strlen(line); switch (kind) { case K_ALIAS: - ret = table_static_alias(key, line, len); + ret = table_static_alias(key, line, len, retp); break; case K_CREDENTIALS: - ret = table_static_credentials(key, line, len); + ret = table_static_credentials(key, line, len, retp); break; case K_VIRTUAL: - ret = table_static_virtual(key, line, len); + ret = table_static_virtual(key, line, len, retp); break; case K_NETADDR: - ret = table_static_netaddr(key, line, len); + ret = table_static_netaddr(key, line, len, retp); break; default: - ret = NULL; - break; + ret = -1; } free(line); @@ -186,50 +190,49 @@ table_static_compare(void *hdl, const char *key, enum table_service kind, return ret; } -static void * -table_static_credentials(const char *key, char *line, size_t len) +static int +table_static_credentials(const char *key, char *line, size_t len, void **retp) { - struct table_credentials *table_credentials = NULL; + struct table_credentials *credentials = NULL; char *p; /* credentials are stored as user:password */ if (len < 3) - return NULL; + return -1; /* too big to fit in a smtp session line */ if (len >= MAX_LINE_SIZE) - return NULL; + return -1; p = strchr(line, ':'); if (p == NULL) - return NULL; + return -1; if (p == line || p == line + len - 1) - return NULL; + return -1; *p++ = '\0'; - table_credentials = xcalloc(1, sizeof *table_credentials, + credentials = xcalloc(1, sizeof *credentials, "table_static_credentials"); - - if (strlcpy(table_credentials->username, line, - sizeof(table_credentials->username)) >= - sizeof(table_credentials->username)) + if (strlcpy(credentials->username, line, sizeof(credentials->username)) + >= sizeof(credentials->username)) goto err; - if (strlcpy(table_credentials->password, p, - sizeof(table_credentials->password)) >= - sizeof(table_credentials->password)) + if (strlcpy(credentials->password, p, sizeof(credentials->password)) + >= sizeof(credentials->password)) goto err; - return table_credentials; + *retp = credentials; + return 1; err: - free(table_credentials); - return NULL; + *retp = NULL; + free(credentials); + return -1; } -static void * -table_static_alias(const char *key, char *line, size_t len) +static int +table_static_alias(const char *key, char *line, size_t len, void **retp) { char *subrcpt; char *endp; @@ -256,29 +259,32 @@ table_static_alias(const char *key, char *line, size_t len) expand_insert(&table_alias->expand, &xn); table_alias->nbnodes++; } - - return table_alias; + *retp = table_alias; + return 1; error: + *retp = NULL; expand_free(&table_alias->expand); free(table_alias); - return NULL; + return -1; } -static void * -table_static_virtual(const char *key, char *line, size_t len) +static int +table_static_virtual(const char *key, char *line, size_t len, void **retp) { char *subrcpt; char *endp; struct table_virtual *table_virtual = NULL; struct expandnode xn; - table_virtual = xcalloc(1, sizeof *table_virtual, "table_static_virtual"); - /* domain key, discard value */ - if (strchr(key, '@') == NULL) - return table_virtual; + if (strchr(key, '@') == NULL) { + *retp = NULL; + return 1; + } + table_virtual = xcalloc(1, sizeof *table_virtual, + "table_static_virtual"); while ((subrcpt = strsep(&line, ",")) != NULL) { /* subrcpt: strip initial whitespace. */ while (isspace((int)*subrcpt)) @@ -298,28 +304,32 @@ table_static_virtual(const char *key, char *line, size_t len) table_virtual->nbnodes++; } - return table_virtual; + *retp = table_virtual; + return 1; error: + *retp = NULL; expand_free(&table_virtual->expand); free(table_virtual); - return NULL; + return 0; } -static void * -table_static_netaddr(const char *key, char *line, size_t len) +static int +table_static_netaddr(const char *key, char *line, size_t len, void **retp) { struct table_netaddr *table_netaddr = NULL; table_netaddr = xcalloc(1, sizeof *table_netaddr, "table_static_netaddr"); - + if (! text_to_netaddr(&table_netaddr->netaddr, line)) - goto error; + goto error; - return table_netaddr; + *retp = table_netaddr; + return 1; error: + *retp = NULL; free(table_netaddr); - return NULL; + return 0; } |