aboutsummaryrefslogtreecommitdiff
path: root/gacopyz/gacopyz.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-02-10 14:08:36 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-02-10 14:08:36 +0000
commita1871918823166cac9f0c12164ba27cb3b1f0c2c (patch)
tree7260d118aa5af6a8f006f9b2dac6cabde782db8c /gacopyz/gacopyz.c
parent455b645247bdc0f01239b2352a9d8f07f446024f (diff)
downloadmailfromd-a1871918823166cac9f0c12164ba27cb3b1f0c2c.tar.gz
mailfromd-a1871918823166cac9f0c12164ba27cb3b1f0c2c.tar.bz2
Merged HEAD from branches/gmach
git-svn-id: file:///svnroot/mailfromd/trunk@1612 7a8a7f39-df28-0410-adc6-e0d955640f24
Diffstat (limited to 'gacopyz/gacopyz.c')
-rw-r--r--gacopyz/gacopyz.c629
1 files changed, 364 insertions, 265 deletions
diff --git a/gacopyz/gacopyz.c b/gacopyz/gacopyz.c
index 4f066615..3cf919bd 100644
--- a/gacopyz/gacopyz.c
+++ b/gacopyz/gacopyz.c
@@ -1,5 +1,5 @@
/* This file is part of gacopyz.
- Copyright (C) 2006, 2007 Sergey Poznyakoff
+ Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff
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
@@ -16,13 +16,17 @@
#include <gacopyz_priv.h>
-#define TRACE(conn,cmd,size,buf) do { \
- gacopyz_log(conn, SMI_LOG_DEBUG, \
- _("send header: size=%lu, cmd=%c"),\
- size, cmd); \
- gacopyz_logdump(conn, SMI_LOG_DEBUG, \
- _("send data"), buf, size); \
-} while (0)
+#define TRACE(ctx,cmd,size,buf) do { \
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_DEBUG)) { \
+ gacopyz_log(SMI_LOG_DEBUG, _("send header: size=%lu, cmd=%c"),\
+ size, cmd); \
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_PROTO)) \
+ gacopyz_logdump(SMI_LOG_PROTO, \
+ _("send data"), buf, size); \
+ else \
+ gacopyz_log(SMI_LOG_DEBUG, _("send data")); \
+ } \
+ } while (0)
int
gacopyz_init(gacopyz_conn_t *pconn, struct smfiDesc *desc)
@@ -34,7 +38,7 @@ gacopyz_init(gacopyz_conn_t *pconn, struct smfiDesc *desc)
name = desc->xxfi_name ? desc->xxfi_name : "Unknown";
len = strlen(name);
if (desc->xxfi_version != SMFI_VERSION) {
- gacopyz_logmsg(SMI_LOG_ERR,
+ gacopyz_log(SMI_LOG_ERR,
_("smfi_register: %s: version mismatch; "
"application %d != implementation %d"),
name, desc->xxfi_version, SMFI_VERSION);
@@ -44,7 +48,7 @@ gacopyz_init(gacopyz_conn_t *pconn, struct smfiDesc *desc)
conn = malloc(sizeof(*conn) + len + 1);
if (!conn) {
- gacopyz_logmsg(SMI_LOG_ERR,
+ gacopyz_log(SMI_LOG_ERR,
"smfi_register: %s: %s", name,
strerror(errno));
return MI_FAILURE;
@@ -54,9 +58,10 @@ gacopyz_init(gacopyz_conn_t *pconn, struct smfiDesc *desc)
conn->sd = -1;
conn->master_timeout.tv_usec = 0;
conn->master_timeout.tv_sec = 5;
- conn->ctx_timeout.tv_usec = 0;
- conn->ctx_timeout.tv_sec = GACOPYZ_TIMEOUT;
- conn->logmask = SMI_DEFAULT_LOG_MASK;
+ conn->desc.ctx_timeout.tv_usec = 0;
+ conn->desc.ctx_timeout.tv_sec = GACOPYZ_TIMEOUT;
+ if (!conn->desc.logmask)
+ conn->desc.logmask = SMI_DEFAULT_LOG_MASK;
conn->desc = *desc;
conn->desc.xxfi_name = (char*)(conn + 1);
strcpy(conn->desc.xxfi_name, name);
@@ -73,42 +78,71 @@ gacopyz_free(gacopyz_conn_t conn)
}
}
+static int
+copy_part(const char *cstr, const char *p, char **pbuf)
+{
+ size_t len = p - cstr;
+ char *buf = malloc(len + 1);
+ if (!buf) {
+ free(buf);
+ return MI_FAILURE;
+ }
+ memcpy(buf, cstr, len);
+ buf[len] = 0;
+ *pbuf = buf;
+ return 0;
+}
+
+
+static int
+parse_url(const char *proto, const char *cstr, char **pport, char **ppath)
+{
+ const char *p = strchr (cstr, ':');
+
+ if (!p) {
+ *pport = NULL;
+ *ppath = strdup(cstr);
+ return *ppath == NULL ? MI_FAILURE : 0;
+ } else if (copy_part(cstr, p, ppath))
+ return MI_FAILURE;
+ else
+ cstr = p + 1;
+ *pport = strdup(cstr);
+ return *pport == NULL ? MI_FAILURE : 0;
+}
+
int
-gacopyz_parse_connection(const char *cstr,
+gacopyz_parse_connection(const char *cstr,
char **pproto, char **pport, char **ppath)
{
const char *p;
- size_t len;
p = strchr(cstr, ':');
if (!p)
*pproto = NULL;
else {
- len = p - cstr;
- *pproto = malloc(len + 1);
- if (!*pproto)
+ char *proto;
+ if (copy_part(cstr, p, &proto))
return MI_FAILURE;
- memcpy(*pproto, cstr, len);
- (*pproto)[len] = 0;
-
cstr = p + 1;
+ if (cstr[0] == '/' && cstr[1] == '/') {
+ int rc = parse_url(proto, cstr + 2, pport, ppath);
+ if (rc)
+ free(proto);
+ else
+ *pproto = proto;
+ return rc;
+ }
+ *pproto = proto;
}
p = strchr(cstr, '@');
if (!p)
*pport = NULL;
- else {
- len = p - cstr;
- *pport = malloc(len + 1);
- if (!*pport) {
- free(*pproto);
- return MI_FAILURE;
- }
- memcpy(*pport, cstr, len);
- (*pport)[len] = 0;
-
+ else if (copy_part(cstr, p, pport))
+ return MI_FAILURE;
+ else
cstr = p + 1;
- }
*ppath = strdup(cstr);
if (!*ppath) {
@@ -127,9 +161,9 @@ parse_connection(gacopyz_conn_t conn,
char **pproto, char **pport, char **ppath)
{
int rc = gacopyz_parse_connection(cstr, pproto, pport, ppath);
- if (rc)
- gacopyz_log(conn, SMI_LOG_ERR,
- "parse_connection: %s", strerror(ENOMEM));
+ if (rc && GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ "parse_connection: %s", strerror(ENOMEM));
return rc;
}
@@ -138,10 +172,12 @@ static void
cleanup_unix_socket(gacopyz_conn_t conn, void *data)
{
if (unlink(data) && errno != ENOENT)
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: %s: cannot unlink: %s"),
- conn->desc.xxfi_name, (char*)data,
- strerror(errno));
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: %s: cannot unlink: %s"),
+ conn->desc.xxfi_name, (char*)data,
+ strerror(errno));
+
free(data);
}
@@ -164,7 +200,8 @@ do_connect(gacopyz_conn_t conn,
struct stat st;
if (port) {
- gacopyz_log(conn, SMI_LOG_ERR,
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
_("%s: invalid connection type: %s; "
"port is meaningless for UNIX sockets"),
conn->desc.xxfi_name, cstr);
@@ -173,9 +210,10 @@ do_connect(gacopyz_conn_t conn,
if (strlen(path) > sizeof addr.s_un.sun_path) {
errno = EINVAL;
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: %s: UNIX socket name too long"),
- conn->desc.xxfi_name, path);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: %s: UNIX socket name too long"),
+ conn->desc.xxfi_name, path);
return -1;
}
@@ -188,22 +226,26 @@ do_connect(gacopyz_conn_t conn,
conn->cleanup = cleanup_unix_socket;
conn->cleanup_data = strdup(path);
} else {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: %s: cannot stat socket: %s"),
- conn->desc.xxfi_name, path,
- strerror(errno));
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: %s: cannot stat socket: %s"),
+ conn->desc.xxfi_name, path,
+ strerror(errno));
return -1;
}
} else {
/* FIXME: Check permissions? */
if (!S_ISSOCK(st.st_mode)) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: %s: not a socket"),
- conn->desc.xxfi_name, path);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: %s: not a socket"),
+ conn->desc.xxfi_name,
+ path);
return -1;
}
if (rmsocket && unlink(path)) {
- gacopyz_log(conn, SMI_LOG_ERR,
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
_("%s: %s: cannot unlink: %s"),
conn->desc.xxfi_name, path,
strerror(errno));
@@ -220,30 +262,35 @@ do_connect(gacopyz_conn_t conn,
socklen = sizeof(addr.s_in);
if (!port) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: invalid connection type: %s; "
- "missing port number"),
- conn->desc.xxfi_name, cstr);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: invalid connection type: %s; "
+ "missing port number"),
+ conn->desc.xxfi_name, cstr);
return -1;
}
num = pnum = strtol(port, &p, 0);
if (*p == 0) {
if (num != pnum) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: invalid connection type: %s; "
- "bad port number"),
- conn->desc.xxfi_name, cstr);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: invalid connection type: "
+ "%s; bad port number"),
+ conn->desc.xxfi_name,
+ cstr);
return -1;
}
pnum = htons(pnum);
} else {
struct servent *sp = getservbyname(port, "tcp");
if (!sp) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: invalid connection type: %s; "
- "unknown port name"),
- conn->desc.xxfi_name, cstr);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: invalid connection type: "
+ "%s; unknown port name"),
+ conn->desc.xxfi_name,
+ cstr);
return -1;
}
pnum = sp->s_port;
@@ -254,9 +301,11 @@ do_connect(gacopyz_conn_t conn,
else {
struct hostent *hp = gethostbyname(path);
if (!hp) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: Unknown host name %s"),
- conn->desc.xxfi_name, path);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: Unknown host name %s"),
+ conn->desc.xxfi_name,
+ path);
return -1;
}
addr.sa.sa_family = hp->h_addrtype;
@@ -267,33 +316,38 @@ do_connect(gacopyz_conn_t conn,
break;
default:
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: invalid connection type: %s; "
- "unsupported address family"),
- conn->desc.xxfi_name, cstr);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: invalid connection type: "
+ "%s; unsupported address family"),
+ conn->desc.xxfi_name,
+ cstr);
return -1;
}
}
} else {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: unsupported protocol: %s"),
- conn->desc.xxfi_name, proto);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: unsupported protocol: %s"),
+ conn->desc.xxfi_name, proto);
return -1;
}
fd = socket(addr.sa.sa_family, SOCK_STREAM, 0);
if (fd == -1) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: Unable to create new socket: %s"),
- conn->desc.xxfi_name, strerror(errno));
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: Unable to create new socket: %s"),
+ conn->desc.xxfi_name, strerror(errno));
return -1;
}
if ((flags = fcntl(fd, F_GETFD, 0)) == -1 ||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: Cannot set close-on-exec: %s"),
- conn->desc.xxfi_name, strerror(errno));
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: Cannot set close-on-exec: %s"),
+ conn->desc.xxfi_name, strerror(errno));
close(fd);
return -1;
}
@@ -301,25 +355,30 @@ do_connect(gacopyz_conn_t conn,
if (addr.sa.sa_family != PF_UNIX
&& setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &yes,
sizeof(yes)) == -1) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: set reuseaddr failed (%s)"),
- conn->desc.xxfi_name, strerror(errno));
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: set reuseaddr failed (%s)"),
+ conn->desc.xxfi_name, strerror(errno));
close(fd);
return -1;
}
if (bind(fd, &addr.sa, socklen) < 0) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: Cannot bind to port %s: %s"),
- conn->desc.xxfi_name, cstr, strerror(errno));
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: Cannot bind to port %s: %s"),
+ conn->desc.xxfi_name, cstr,
+ strerror(errno));
close(fd);
return -1;
}
if (listen(fd, backlog)) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("%s: Cannot listen on port %s: %s"),
- conn->desc.xxfi_name, cstr, strerror(errno));
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: Cannot listen on port %s: %s"),
+ conn->desc.xxfi_name, cstr,
+ strerror(errno));
close(fd);
return -1;
}
@@ -336,15 +395,16 @@ gacopyz_open(gacopyz_conn_t conn, const char *cstr, int backlog, int rmsocket)
char *path;
if (!conn) {
- gacopyz_logmsg(SMI_LOG_ERR,
+ gacopyz_log(SMI_LOG_ERR,
_("Empty or missing socket information"));
errno = EINVAL;
return MI_FAILURE;
}
- gacopyz_log(conn, SMI_LOG_DEBUG,
- _("%s: opening listen socket on %s"),
- conn->desc.xxfi_name, cstr);
+ if (GACOPYZ_CONN_LOG_MATCH(conn, SMI_LOG_DEBUG))
+ gacopyz_log(SMI_LOG_DEBUG,
+ _("%s: opening listen socket on %s"),
+ conn->desc.xxfi_name, cstr);
if (parse_connection(conn, cstr, &proto, &port, &path)) {
errno = ENOENT;
return MI_FAILURE;
@@ -364,7 +424,7 @@ gacopyz_get_logmask(gacopyz_conn_t conn, int *mask)
{
if (!conn || !mask)
return MI_FAILURE;
- *mask = conn->logmask;
+ *mask = conn->desc.logmask;
return MI_SUCCESS;
}
@@ -373,7 +433,7 @@ gacopyz_set_logmask(gacopyz_conn_t conn, int mask)
{
if (!conn)
return MI_FAILURE;
- conn->logmask = mask;
+ conn->desc.logmask = mask;
return MI_SUCCESS;
}
@@ -434,7 +494,7 @@ gacopyz_set_ctx_timeout(gacopyz_conn_t conn, struct timeval *timeout)
{
if (!conn)
return MI_FAILURE;
- conn->ctx_timeout = *timeout;
+ conn->desc.ctx_timeout = *timeout;
return MI_SUCCESS;
}
@@ -443,7 +503,7 @@ gacopyz_get_ctx_timeout(gacopyz_conn_t conn, struct timeval *timeout)
{
if (!conn)
return MI_FAILURE;
- *timeout = conn->ctx_timeout;
+ *timeout = conn->desc.ctx_timeout;
return MI_SUCCESS;
}
@@ -478,14 +538,14 @@ ctx_read(SMFICTX *ctx, char *buf, size_t size)
FD_SET(ctx->sd, &rset);
FD_SET(ctx->sd, &xset);
- to = ctx->conn->ctx_timeout;
+ to = ctx->desc->ctx_timeout;
res = select(ctx->sd + 1, &rset, NULL, &xset, &to);
if (res == 0) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR,
- _("%s: connection timed out"),
- "ctx_read");
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: connection timed out"),
+ "ctx_read");
errno = ETIMEDOUT;
rc = MI_FAILURE;
break;
@@ -496,10 +556,10 @@ ctx_read(SMFICTX *ctx, char *buf, size_t size)
break;
} else if (rc > 0) {
if (FD_ISSET(ctx->sd, &xset)) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR,
- _("%s: exception on control fd"),
- "ctx_read");
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: exception on control fd"),
+ "ctx_read");
rc = MI_FAILURE;
break;
}
@@ -508,18 +568,18 @@ ctx_read(SMFICTX *ctx, char *buf, size_t size)
res = read(ctx->sd, buf, size);
if (res == -1) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR,
- _("%s: read failed: %s"),
- "ctx_read",
- strerror(errno));
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: read failed: %s"),
+ "ctx_read",
+ strerror(errno));
rc = MI_FAILURE;
break;
} else if (res == 0) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR,
- _("%s: end of file"),
- "ctx_read");
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: end of file"),
+ "ctx_read");
rc = MI_FAILURE;
break;
}
@@ -546,14 +606,14 @@ ctx_write(SMFICTX *ctx, char *buf, size_t size)
FD_SET(ctx->sd, &wset);
FD_SET(ctx->sd, &xset);
- to = ctx->conn->ctx_timeout;
+ to = ctx->desc->ctx_timeout;
res = select(ctx->sd + 1, NULL, &wset, &xset, &to);
if (res == 0) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR,
- _("%s: connection timed out"),
- "ctx_write");
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: connection timed out"),
+ "ctx_write");
errno = ETIMEDOUT;
rc = MI_FAILURE;
break;
@@ -564,8 +624,8 @@ ctx_write(SMFICTX *ctx, char *buf, size_t size)
break;
} else if (rc > 0) {
if (FD_ISSET(ctx->sd, &xset)) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR,
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
_("%s: exception on control fd"),
"ctx_write");
rc = MI_FAILURE;
@@ -576,18 +636,18 @@ ctx_write(SMFICTX *ctx, char *buf, size_t size)
res = write(ctx->sd, buf, size);
if (res == -1) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR,
- _("%s: write failed: %s"),
- "ctx_write",
- strerror(errno));
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: write failed: %s"),
+ "ctx_write",
+ strerror(errno));
rc = MI_FAILURE;
break;
} else if (res == 0) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR,
- _("%s: wrote 0 bytes"),
- "ctx_write");
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: wrote 0 bytes"),
+ "ctx_write");
rc = MI_FAILURE;
break;
}
@@ -622,24 +682,28 @@ get_command(SMFICTX *ctx, unsigned char *cmd, size_t *pcount,
if (size + 1 > *psize) {
char *p = realloc(*pbuf, size + 1);
if (!p) {
- gacopyz_log(ctx->conn,
- SMI_LOG_ERR, "%s", strerror(errno));
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR, "%s",
+ strerror(errno));
return MI_FAILURE;
}
*pbuf = p;
*psize = size + 1;
}
- gacopyz_log(ctx->conn, SMI_LOG_DEBUG,
- _("read header: size=%lu, cmd=%c"),
- size, header.hdr.cmd);
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_DEBUG))
+ gacopyz_log(SMI_LOG_DEBUG,
+ _("read header: size=%lu, cmd=%c"),
+ size, header.hdr.cmd);
if ((rc = ctx_read(ctx, *pbuf, size)) != MI_SUCCESS)
return rc;
(*pbuf)[size] = 0;
- gacopyz_logdump(ctx->conn, SMI_LOG_DEBUG,
- _("read data"), *pbuf, size);
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_PROTO))
+ gacopyz_logdump(SMI_LOG_PROTO, _("read data"), *pbuf, size);
+ else if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_DEBUG))
+ gacopyz_log(SMI_LOG_DEBUG, _("read data"));
*pcount = size;
*cmd = header.hdr.cmd;
return MI_SUCCESS;
@@ -682,8 +746,8 @@ send_reply(SMFICTX *ctx, unsigned char cmd)
case SMFIC_OPTNEG:
{
gacopyz_uint32_t v[3];
- v[0] = htonl(ctx->conn->desc.xxfi_version);
- v[1] = htonl(ctx->conn->desc.xxfi_flags);
+ v[0] = htonl(ctx->desc->xxfi_version);
+ v[1] = htonl(ctx->desc->xxfi_flags);
v[2] = htonl(ctx->flags);
buf = (char*) v;
bufsize = sizeof v;
@@ -694,7 +758,7 @@ send_reply(SMFICTX *ctx, unsigned char cmd)
break;
}
- TRACE(ctx->conn, cmd, bufsize, buf);
+ TRACE(ctx, cmd, bufsize, buf);
header.hdr.size = htonl(bufsize + 1);
header.hdr.cmd = cmd;
@@ -789,8 +853,8 @@ convert_sfsistat(sfsistat stat)
static state_ret_type
shan_abort(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_abort)
- ctx->conn->desc.xxfi_abort(ctx);
+ if (ctx->desc->xxfi_abort)
+ ctx->desc->xxfi_abort(ctx);
return sret_noreply;
}
@@ -855,11 +919,11 @@ shan_macro(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_body(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_body) {
+ if (ctx->desc->xxfi_body) {
*cmd = convert_sfsistat(
- ctx->conn->desc.xxfi_body(ctx,
- arg->string.ptr,
- arg->string.len));
+ ctx->desc->xxfi_body(ctx,
+ arg->string.ptr,
+ arg->string.len));
} else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -875,7 +939,7 @@ shan_connect(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
unsigned short port = 0;
*cmd = SMFIR_CONTINUE;
- if (!ctx->conn->desc.xxfi_connect)
+ if (!ctx->desc->xxfi_connect)
return sret_reply;
memset(&sockaddr, 0, sizeof sockaddr);
@@ -894,11 +958,12 @@ shan_connect(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
switch (family) {
case SMFIA_UNIX:
if (len >= sizeof sockaddr.sunix.sun_path) {
- gacopyz_log(ctx->conn, SMI_LOG_ERR,
- "%s: shan_connect: %s: %lu",
- ctx->conn->desc.xxfi_name,
- _("path too long"),
- (unsigned long) len);
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ "%s: shan_connect: %s: %lu",
+ ctx->desc->xxfi_name,
+ _("path too long"),
+ (unsigned long) len);
return sret_abort;
}
strcpy(sockaddr.sunix.sun_path, s);
@@ -908,10 +973,11 @@ shan_connect(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
case SMFIA_INET:
if (inet_aton(s,
(struct in_addr *) &sockaddr.sin.sin_addr) != 1) {
- gacopyz_log(ctx->conn, SMI_LOG_ERR,
- _("%s: shan_connect: inet_aton(%s) failed"),
- ctx->conn->desc.xxfi_name,
- s);
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: shan_connect: inet_aton(%s) failed"),
+ ctx->desc->xxfi_name,
+ s);
return sret_abort;
}
sockaddr.sa.sa_family = AF_INET;
@@ -920,35 +986,36 @@ shan_connect(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
case SMFIA_INET6:
default:
- gacopyz_log(ctx->conn, SMI_LOG_ERR,
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
_("%s: shan_connect: unknown family %d"),
- ctx->conn->desc.xxfi_name,
- family);
+ ctx->desc->xxfi_name,
+ family);
return sret_abort;
}
}
*cmd = convert_sfsistat(
- ctx->conn->desc.xxfi_connect(ctx,
- arg->strings[0],
- family != SMFIA_UNKNOWN ?
- &sockaddr : NULL));
+ ctx->desc->xxfi_connect(ctx,
+ arg->strings[0],
+ family != SMFIA_UNKNOWN ?
+ &sockaddr : NULL));
return sret_reply;
}
static state_ret_type
shan_endm(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (arg->string.len && ctx->conn->desc.xxfi_body) {
- sfsistat r = ctx->conn->desc.xxfi_body(ctx,
- arg->string.ptr,
- arg->string.len);
+ if (arg->string.len && ctx->desc->xxfi_body) {
+ sfsistat r = ctx->desc->xxfi_body(ctx,
+ arg->string.ptr,
+ arg->string.len);
if (r != SMFIS_CONTINUE
&& send_reply(ctx, convert_sfsistat(r) != MI_SUCCESS))
return sret_abort;
}
- if (ctx->conn->desc.xxfi_eom)
- *cmd = convert_sfsistat(ctx->conn->desc.xxfi_eom(ctx));
+ if (ctx->desc->xxfi_eom)
+ *cmd = convert_sfsistat(ctx->desc->xxfi_eom(ctx));
else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -957,9 +1024,9 @@ shan_endm(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_helo(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_helo)
+ if (ctx->desc->xxfi_helo)
*cmd = convert_sfsistat(
- ctx->conn->desc.xxfi_helo(ctx, arg->string.ptr));
+ ctx->desc->xxfi_helo(ctx, arg->string.ptr));
else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -968,11 +1035,11 @@ shan_helo(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_header(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_header)
+ if (ctx->desc->xxfi_header)
*cmd = convert_sfsistat(
- ctx->conn->desc.xxfi_header(ctx,
- arg->strings[0],
- arg->strings[1]));
+ ctx->desc->xxfi_header(ctx,
+ arg->strings[0],
+ arg->strings[1]));
else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -981,9 +1048,9 @@ shan_header(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_mail(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_envfrom) {
+ if (ctx->desc->xxfi_envfrom) {
*cmd = convert_sfsistat(
- ctx->conn->desc.xxfi_envfrom(ctx, arg->argv.v));
+ ctx->desc->xxfi_envfrom(ctx, arg->argv.v));
} else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -994,24 +1061,27 @@ shan_optneg(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
gacopyz_uint32_t val;
- if (arg->ints[0] < ctx->conn->desc.xxfi_version) {
- gacopyz_log(ctx->conn, SMI_LOG_ERR,
+ if (arg->ints[0] < ctx->desc->xxfi_version) {
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
_("%s: shan_optneg: version mismatch; "
"MTA: %ld < milter: %d"),
- ctx->conn->desc.xxfi_name,
- arg->ints[0], ctx->conn->desc.xxfi_version);
+ ctx->desc->xxfi_name,
+ arg->ints[0],
+ ctx->desc->xxfi_version);
return sret_abort;
}
val = arg->ints[1];
if (!val)
val = SMFI_V1_ACTS;
- if ((val & ctx->conn->desc.xxfi_flags) != ctx->conn->desc.xxfi_flags) {
- gacopyz_log(ctx->conn, SMI_LOG_ERR,
- _("%s: shan_optneg: flags %#x do not match "
- "actions requirements %#x"),
- ctx->conn->desc.xxfi_name, val,
- ctx->conn->desc.xxfi_flags);
+ if ((val & ctx->desc->xxfi_flags) != ctx->desc->xxfi_flags) {
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
+ _("%s: shan_optneg: flags %#x do not match "
+ "actions requirements %#x"),
+ ctx->desc->xxfi_name, val,
+ ctx->desc->xxfi_flags);
return sret_abort;
}
@@ -1019,11 +1089,12 @@ shan_optneg(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
if (!val)
val = SMFI_V1_PROT;
if ((val & ctx->flags) != ctx->flags) {
- gacopyz_log(ctx->conn, SMI_LOG_ERR,
+ if (GACOPYZ_CTX_LOG_MATCH(ctx, SMI_LOG_ERR))
+ gacopyz_log(SMI_LOG_ERR,
_("%s: shan_optneg: flags %#x do not match "
"protocol requirement %#x"),
- ctx->conn->desc.xxfi_name, val,
- ctx->flags);
+ ctx->desc->xxfi_name, val,
+ ctx->flags);
return sret_abort;
}
*cmd = SMFIC_OPTNEG;
@@ -1033,8 +1104,8 @@ shan_optneg(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_eoh(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_eoh)
- *cmd = convert_sfsistat(ctx->conn->desc.xxfi_eoh(ctx));
+ if (ctx->desc->xxfi_eoh)
+ *cmd = convert_sfsistat(ctx->desc->xxfi_eoh(ctx));
else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -1049,8 +1120,8 @@ shan_quit(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_data(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_data)
- *cmd = convert_sfsistat(ctx->conn->desc.xxfi_data(ctx));
+ if (ctx->desc->xxfi_data)
+ *cmd = convert_sfsistat(ctx->desc->xxfi_data(ctx));
else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -1059,9 +1130,9 @@ shan_data(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_rcpt(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_envrcpt) {
+ if (ctx->desc->xxfi_envrcpt) {
*cmd = convert_sfsistat(
- ctx->conn->desc.xxfi_envrcpt(ctx, arg->argv.v));
+ ctx->desc->xxfi_envrcpt(ctx, arg->argv.v));
} else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -1070,9 +1141,9 @@ shan_rcpt(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_unkn(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- if (ctx->conn->desc.xxfi_unknown) {
+ if (ctx->desc->xxfi_unknown) {
*cmd = convert_sfsistat(
- ctx->conn->desc.xxfi_unknown(ctx, arg->string.ptr));
+ ctx->desc->xxfi_unknown(ctx, arg->string.ptr));
} else
*cmd = SMFIR_CONTINUE;
return sret_reply;
@@ -1213,7 +1284,7 @@ arg_free(union state_arg *arg, enum state_arg_type type)
#define STATE_NAME(st) ((st == st_none) ? "st_none" : state_name[st])
int
-gacopyz_context_loop(gacopyz_conn_t conn, int fd)
+gacopyz_context_loop(int fd, struct smfiDesc *desc)
{
int rc;
char *buffer = NULL;
@@ -1221,26 +1292,29 @@ gacopyz_context_loop(gacopyz_conn_t conn, int fd)
size_t size;
unsigned char cmd;
SMFICTX ctx;
- int allow_unkn = conn->desc.xxfi_unknown != NULL;
+ int allow_unkn = desc->xxfi_unknown != NULL;
enum state state = st_init;
int stop = 0;
+ if (desc->xxfi_start)
+ desc->xxfi_start();
+
memset(&ctx, 0, sizeof ctx);
- ctx.conn = conn;
+ ctx.desc = desc;
ctx.sd = fd;
- if (!conn->desc.xxfi_connect)
+ if (!desc->xxfi_connect)
ctx.flags |= SMFIP_NOCONNECT;
- if (!conn->desc.xxfi_helo)
+ if (!desc->xxfi_helo)
ctx.flags |= SMFIP_NOHELO;
- if (!conn->desc.xxfi_envfrom)
+ if (!desc->xxfi_envfrom)
ctx.flags |= SMFIP_NOMAIL;
- if (!conn->desc.xxfi_envrcpt)
+ if (!desc->xxfi_envrcpt)
ctx.flags |= SMFIP_NORCPT;
- if (!conn->desc.xxfi_header)
+ if (!desc->xxfi_header)
ctx.flags |= SMFIP_NOHDRS;
- if (!conn->desc.xxfi_eoh)
+ if (!desc->xxfi_eoh)
ctx.flags |= SMFIP_NOEOH;
- if (!conn->desc.xxfi_body)
+ if (!desc->xxfi_body)
ctx.flags |= SMFIP_NOBODY;
/* Fix up the transition table */
@@ -1251,8 +1325,9 @@ gacopyz_context_loop(gacopyz_conn_t conn, int fd)
transtab[st_hdrs][st_skip] = !!(ctx.flags & SMFIP_NOHDRS);
transtab[st_eohs][st_skip] = !!(ctx.flags & SMFIP_NOEOH);
transtab[st_body][st_skip] = !!(ctx.flags & SMFIP_NOBODY);
-
- gacopyz_log(conn, SMI_LOG_DEBUG, _("Begin context loop"));
+
+ if (GACOPYZ_DESC_LOG_MATCH(desc, SMI_LOG_DEBUG))
+ gacopyz_log(SMI_LOG_DEBUG, _("Begin context loop"));
while (!stop
&& (rc = get_command(&ctx, &cmd, &size, &buffer, &bufsize))
@@ -1263,12 +1338,14 @@ gacopyz_context_loop(gacopyz_conn_t conn, int fd)
struct state_disp *sd = find_disp(cmd, allow_unkn);
if (sd == NULL) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("Unknown command: %c"),
- cmd);
- gacopyz_logdump(conn, SMI_LOG_ERR,
- _("buffer"),
- buffer, size);
+ if (GACOPYZ_DESC_LOG_MATCH(desc, SMI_LOG_ERR)) {
+ gacopyz_log(SMI_LOG_ERR,
+ _("Unknown command: %c"),
+ cmd);
+ gacopyz_logdump(SMI_LOG_ERR,
+ _("buffer"),
+ buffer, size);
+ }
rc = MI_FAILURE;
break;
}
@@ -1277,13 +1354,15 @@ gacopyz_context_loop(gacopyz_conn_t conn, int fd)
stop = sd->flags & CT_END;
if (next_state != st_none && !trans_ok(state, next_state)) {
- gacopyz_log(conn, SMI_LOG_DEBUG,
- _("Transition from state %s to %s is "
- "prohibited"),
- STATE_NAME(state),
- STATE_NAME(next_state));
- if (ST_IN_MAIL(state) && ctx.conn->desc.xxfi_abort)
- ctx.conn->desc.xxfi_abort(&ctx);
+ if (GACOPYZ_DESC_LOG_MATCH(desc, SMI_LOG_DEBUG))
+ gacopyz_log(SMI_LOG_DEBUG,
+ _("Transition from state %s to %s is "
+ "prohibited"),
+ STATE_NAME(state),
+ STATE_NAME(next_state));
+
+ if (ST_IN_MAIL(state) && desc->xxfi_abort)
+ desc->xxfi_abort(&ctx);
/* Retry starting from HELO */
state = st_helo;
@@ -1297,11 +1376,13 @@ gacopyz_context_loop(gacopyz_conn_t conn, int fd)
}
if (parse_state_arg(&arg, sd->arg_type, buffer, size)) {
- gacopyz_log(conn, SMI_LOG_ERR,
- _("Argument parsing failed"));
- gacopyz_logdump(conn, SMI_LOG_ERR,
- _("buffer"),
- buffer, size);
+ if (GACOPYZ_DESC_LOG_MATCH(desc, SMI_LOG_ERR)) {
+ gacopyz_log(SMI_LOG_ERR,
+ _("Argument parsing failed"));
+ gacopyz_logdump(SMI_LOG_ERR,
+ _("buffer"),
+ buffer, size);
+ }
rc = MI_FAILURE;
break;
}
@@ -1329,15 +1410,17 @@ gacopyz_context_loop(gacopyz_conn_t conn, int fd)
break;
case sret_fail:
- gacopyz_log(conn, SMI_LOG_DEBUG,
- _("%s handler returned failure"),
- sd->name);
+ if (GACOPYZ_DESC_LOG_MATCH(desc, SMI_LOG_DEBUG))
+ gacopyz_log(SMI_LOG_DEBUG,
+ _("%s handler returned failure"),
+ sd->name);
break;
case sret_abort:
- gacopyz_log(conn, SMI_LOG_DEBUG,
- _("%s handler returned abort"),
- sd->name);
+ if (GACOPYZ_DESC_LOG_MATCH(desc, SMI_LOG_DEBUG))
+ gacopyz_log(SMI_LOG_DEBUG,
+ _("%s handler returned abort"),
+ sd->name);
rc = MI_FAILURE;
}
@@ -1345,18 +1428,23 @@ gacopyz_context_loop(gacopyz_conn_t conn, int fd)
break;
}
- ga