summaryrefslogtreecommitdiff
path: root/gnu/usr.sbin/sendmail/libmilter
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2001-01-15 21:09:13 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2001-01-15 21:09:13 +0000
commit5062bcecfa81a7e0dd07894d6e93655a97239964 (patch)
treefd0e0dd2a71271dbe81c195cd9fbdd57fb7c20fb /gnu/usr.sbin/sendmail/libmilter
parent91deaea81040227b9ba537ff047f1f863f75fc31 (diff)
sendmail 8.11.2 with BSD Makefiles
Diffstat (limited to 'gnu/usr.sbin/sendmail/libmilter')
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/README63
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/comm.c62
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/engine.c160
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/handler.c17
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/libmilter.h40
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/listener.c150
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/main.c55
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/signal.c43
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/sm_gethost.c22
-rw-r--r--gnu/usr.sbin/sendmail/libmilter/smfi.c95
10 files changed, 496 insertions, 211 deletions
diff --git a/gnu/usr.sbin/sendmail/libmilter/README b/gnu/usr.sbin/sendmail/libmilter/README
index 621219fb044..59d8beca9e1 100644
--- a/gnu/usr.sbin/sendmail/libmilter/README
+++ b/gnu/usr.sbin/sendmail/libmilter/README
@@ -18,6 +18,9 @@ adding the following to your devtools/Site/site.config.m4 file:
APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_MILTER=1')
APPENDDEF(`conf_libmilter_ENVDEF', `-D_FFR_MILTER=1')
+You will also need to define _FFR_MILTER when building your .cf file using
+m4.
+
+-------------------+
| BUILDING A FILTER |
+-------------------+
@@ -32,7 +35,8 @@ It is recommended that you build your filters in a location outside of
the sendmail source tree. Modify the compiler include references (-I)
and the library locations accordingly. Also, some operating systems may
require additional libraries. For example, SunOS 5.X requires '-lresolv
--lsocket -lnsl'.
+-lsocket -lnsl'. Depending on your OS you may need a library instead
+of the option -pthread, e.g., -lpthread.
Filters must be thread-safe! Many operating systems now provide support for
POSIX threads in the standard C libraries. The compiler flag to link with
@@ -49,14 +53,14 @@ Filters are specified with a key letter ``X'' (for ``eXternal'').
For example:
- Xfilter1, S=unix:/var/run/f1.sock, F=R
+ Xfilter1, S=local:/var/run/f1.sock, F=R
Xfilter2, S=inet6:999@localhost, F=T, T=S:1s;R:1s;E:5m
Xfilter3, S=inet:3333@localhost
specifies three filters. Filters can be specified in your .mc file using
the following:
- INPUT_MAIL_FILTER(`filter1', `S=unix:/var/run/f1.sock, F=R')
+ INPUT_MAIL_FILTER(`filter1', `S=local:/var/run/f1.sock, F=R')
INPUT_MAIL_FILTER(`filter2', `S=inet6:999@localhost, F=T, T=S:1s;R:1s;E:5m')
INPUT_MAIL_FILTER(`filter3', `S=inet:3333@localhost')
@@ -67,6 +71,9 @@ IPv4 socket on port 3333 of localhost. The current flags (F=) are:
R Reject connection if filter unavailable
T Temporary fail connection if filter unavailable
+If neither F=R nor F=T is specified, the message is passed through sendmail
+as if the filter were not present.
+
Finally, you can override the default timeouts used by sendmail when
talking to the filters using the T= equate. There are three fields inside
of the T= equate:
@@ -84,13 +91,17 @@ T=S:10s;R:10s;E:5m
where 's' is seconds and 'm' is minutes.
-Actual sequencing is handled by the InputMailFilters option which is set
-automatically according to the order of the INPUT_MAIL_FILTER commands
-in your .mc file. Alternatively, you can reset it's value by setting
-confINPUT_MAIL_FILTERS in your .mc file. This options causes the three
-filters to be called in the same order they were specified. It allows
-for possible future filtering on output (although this is not intended
-for this release).
+Which filters are invoked and their sequencing is handled by the
+InputMailFilters option.
+
+ O InputMailFilters=filter1, filter2, filter3
+
+This is is set automatically according to the order of the
+INPUT_MAIL_FILTER commands in your .mc file. Alternatively, you can
+reset its value by setting confINPUT_MAIL_FILTERS in your .mc file.
+This options causes the three filters to be called in the same order
+they were specified. It allows for possible future filtering on output
+(although this is not intended for this release).
Also note that a filter can be defined without adding it to the input
filter list by using MAIL_FILTER() instead of INPUT_MAIL_FILTER() in your
@@ -99,7 +110,7 @@ filter list by using MAIL_FILTER() instead of INPUT_MAIL_FILTER() in your
To test sendmail with the sample filter, the following might be added (in
the appropriate locations) to your .mc file:
- INPUT_MAIL_FILTER(`sample', `S=unix:/var/run/f1.sock')
+ INPUT_MAIL_FILTER(`sample', `S=local:/var/run/f1.sock')
+------------------+
@@ -115,7 +126,7 @@ on which to create a listening socket for the filter. Maintaining
consistency with the suggested options for sendmail.cf, this would be the
UNIX domain socket located in /var/run/f1.sock.
- % ./sample -p unix:/var/run/f1.sock
+ % ./sample -p local:/var/run/f1.sock
If the sample filter returns immediately to a command line, there was either
an error with your command or a problem creating the specified socket.
@@ -130,7 +141,7 @@ connected via one of these options, the session can be continued through
the use of standard SMTP commands.
% sendmail -bs
-220 test.sendmail.com ESMTP Sendmail 8.10.0.Beta8/8.10.0.Beta8; Mon, 6 Dec 1999 19:34:23 -0800 (PST)
+220 test.sendmail.com ESMTP Sendmail 8.11.0/8.11.0; Tue, 10 Nov 1970 13:05:23 -0500 (EST)
HELO localhost
250 test.sendmail.com Hello testy@localhost, pleased to meet you
MAIL From:<testy>
@@ -167,10 +178,30 @@ See the sendmail(8) manual page for more information.
| SOURCE FOR SAMPLE FILTER |
+--------------------------+
+Note that the filter below may not be thread safe on some operating
+systems. You should check your system man pages for the functions used
+below to verify the functions are thread safe.
+
/* A trivial filter that logs all email to a file. */
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
#include "libmilter/mfapi.h"
+typedef int bool;
+
+#ifndef FALSE
+# define FALSE 0
+#endif /* ! FALSE*/
+#ifndef TRUE
+# define TRUE 1
+#endif /* ! TRUE*/
+
struct mlfiPriv
{
char *mlfi_fname;
@@ -336,7 +367,7 @@ struct smfiDesc smfilter =
{
"SampleFilter", /* filter name */
SMFI_VERSION, /* version code -- do not change */
- SMFIF_MODHDRS, /* flags */
+ SMFIF_ADDHDRS, /* flags */
NULL, /* connection info filter */
NULL, /* SMTP HELO command filter */
mlfi_envfrom, /* envelope sender filter */
@@ -355,7 +386,7 @@ main(argc, argv)
int argc;
char *argv[];
{
- char c;
+ int c;
const char *args = "p:";
/* Process command line options */
@@ -385,4 +416,4 @@ main(argc, argv)
/* eof */
-$Revision: 1.3 $, Last updated $Date: 2000/04/07 19:20:34 $
+$Revision: 1.4 $, Last updated $Date: 2001/01/15 21:09:02 $
diff --git a/gnu/usr.sbin/sendmail/libmilter/comm.c b/gnu/usr.sbin/sendmail/libmilter/comm.c
index 9e8702807ba..692ec2e84a4 100644
--- a/gnu/usr.sbin/sendmail/libmilter/comm.c
+++ b/gnu/usr.sbin/sendmail/libmilter/comm.c
@@ -9,24 +9,24 @@
*/
#ifndef lint
-static char id[] = "@(#)$Sendmail: comm.c,v 8.30 2000/02/11 00:12:29 ca Exp $";
+static char id[] = "@(#)$Sendmail: comm.c,v 8.30.4.6 2000/10/05 22:44:01 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
#include "libmilter.h"
#define FD_Z FD_ZERO(&readset); \
- FD_SET(fd, &readset); \
+ FD_SET((u_int) sd, &readset); \
FD_ZERO(&excset); \
- FD_SET(fd, &excset)
+ FD_SET((u_int) sd, &excset)
/*
** MI_RD_CMD -- read a command
**
** Parameters:
-** fd -- file descriptor
+** sd -- socket descriptor
** timeout -- maximum time to wait
-** cmd -- single character command read from fd
+** cmd -- single character command read from sd
** rlen -- pointer to length of result
** name -- name of milter
**
@@ -37,8 +37,8 @@ static char id[] = "@(#)$Sendmail: comm.c,v 8.30 2000/02/11 00:12:29 ca Exp $";
*/
char *
-mi_rd_cmd(fd, timeout, cmd, rlen, name)
- int fd;
+mi_rd_cmd(sd, timeout, cmd, rlen, name)
+ socket_t sd;
struct timeval *timeout;
char *cmd;
size_t *rlen;
@@ -55,23 +55,25 @@ mi_rd_cmd(fd, timeout, cmd, rlen, name)
*cmd = '\0';
*rlen = 0;
- if (fd >= FD_SETSIZE)
+
+ if (sd >= FD_SETSIZE)
{
smi_log(SMI_LOG_ERR, "%s: fd %d is larger than FD_SETSIZE %d",
- name, fd, FD_SETSIZE);
+ name, sd, FD_SETSIZE);
*cmd = SMFIC_SELECT;
return NULL;
}
+
FD_Z;
i = 0;
- while ((ret = select(fd + 1, &readset, NULL, &excset, timeout)) >= 1)
+ while ((ret = select(sd + 1, &readset, NULL, &excset, timeout)) >= 1)
{
- if (FD_ISSET(fd, &excset))
+ if (FD_ISSET(sd, &excset))
{
*cmd = SMFIC_SELECT;
return NULL;
}
- if ((len = read(fd, data + i, sizeof data - i)) < 0)
+ if ((len = MI_SOCK_READ(sd, data + i, sizeof data - i)) < 0)
{
smi_log(SMI_LOG_ERR,
"%s, mi_rd_cmd: read returned %d: %s",
@@ -84,7 +86,7 @@ mi_rd_cmd(fd, timeout, cmd, rlen, name)
*cmd = SMFIC_EOF;
return NULL;
}
- if (len >= sizeof data - i)
+ if (len >= (ssize_t) sizeof data - i)
break;
i += len;
FD_Z;
@@ -123,15 +125,15 @@ mi_rd_cmd(fd, timeout, cmd, rlen, name)
i = 0;
FD_Z;
- while ((ret = select(fd + 1, &readset, NULL, &excset, timeout)) == 1)
+ while ((ret = select(sd + 1, &readset, NULL, &excset, timeout)) == 1)
{
- if (FD_ISSET(fd, &excset))
+ if (FD_ISSET(sd, &excset))
{
*cmd = SMFIC_SELECT;
free(buf);
return NULL;
}
- if ((len = read(fd, buf + i, expl - i)) < 0)
+ if ((len = MI_SOCK_READ(sd, buf + i, expl - i)) < 0)
{
smi_log(SMI_LOG_ERR,
"%s: mi_rd_cmd: read returned %d: %s",
@@ -181,10 +183,10 @@ mi_rd_cmd(fd, timeout, cmd, rlen, name)
return NULL;
}
/*
-** MI_WR_CMD -- write a cmd to fd
+** MI_WR_CMD -- write a cmd to sd
**
** Parameters:
-** fd -- file descriptor
+** sd -- socket descriptor
** timeout -- maximum time to wait (currently unused)
** cmd -- single character command to write
** buf -- buffer with further data
@@ -195,8 +197,8 @@ mi_rd_cmd(fd, timeout, cmd, rlen, name)
*/
int
-mi_wr_cmd(fd, timeout, cmd, buf, len)
- int fd;
+mi_wr_cmd(sd, timeout, cmd, buf, len)
+ socket_t sd;
struct timeval *timeout;
int cmd;
char *buf;
@@ -217,17 +219,19 @@ mi_wr_cmd(fd, timeout, cmd, buf, len)
i = 0;
sl = MILTER_LEN_BYTES + 1;
- do {
+ do
+ {
FD_ZERO(&wrtset);
- FD_SET(fd, &wrtset);
- if ((ret = select(fd + 1, NULL, &wrtset, NULL, timeout)) == 0)
+ FD_SET((u_int) sd, &wrtset);
+ if ((ret = select(sd + 1, NULL, &wrtset, NULL, timeout)) == 0)
return MI_FAILURE;
} while (ret < 0 && errno == EINTR);
if (ret < 0)
return MI_FAILURE;
/* use writev() instead to send the whole stuff at once? */
- while ((l = write(fd, (void *) (data + i), sl - i)) < sl)
+ while ((l = MI_SOCK_WRITE(sd, (void *) (data + i),
+ sl - i)) < (ssize_t) sl)
{
if (l < 0)
return MI_FAILURE;
@@ -241,15 +245,17 @@ mi_wr_cmd(fd, timeout, cmd, buf, len)
return MI_SUCCESS;
i = 0;
sl = len;
- do {
+ do
+ {
FD_ZERO(&wrtset);
- FD_SET(fd, &wrtset);
- if ((ret = select(fd + 1, NULL, &wrtset, NULL, timeout)) == 0)
+ FD_SET((u_int) sd, &wrtset);
+ if ((ret = select(sd + 1, NULL, &wrtset, NULL, timeout)) == 0)
return MI_FAILURE;
} while (ret < 0 && errno == EINTR);
if (ret < 0)
return MI_FAILURE;
- while ((l = write(fd, (void *) (buf + i), sl - i)) < sl)
+ while ((l = MI_SOCK_WRITE(sd, (void *) (buf + i),
+ sl - i)) < (ssize_t) sl)
{
if (l < 0)
return MI_FAILURE;
diff --git a/gnu/usr.sbin/sendmail/libmilter/engine.c b/gnu/usr.sbin/sendmail/libmilter/engine.c
index e0f4b378270..6da335ef550 100644
--- a/gnu/usr.sbin/sendmail/libmilter/engine.c
+++ b/gnu/usr.sbin/sendmail/libmilter/engine.c
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Sendmail: engine.c,v 8.67 2000/03/27 05:04:16 ca Exp $";
+static char id[] = "@(#)$Sendmail: engine.c,v 8.67.4.15 2000/12/29 19:43:10 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -20,9 +20,6 @@ static char id[] = "@(#)$Sendmail: engine.c,v 8.67 2000/03/27 05:04:16 ca Exp $"
# include <arpa/inet.h>
#endif /* NETINET || NETINET6 */
-/* length of options: two 32bit integers */
-#define MILTER_OPTLEN 8
-
/* generic argument for functions in the command table */
struct arg_struct
{
@@ -87,7 +84,7 @@ static int st_sender __P((genarg *));
static int st_rcpt __P((genarg *));
static int st_eoh __P((genarg *));
static int st_quit __P((genarg *));
-static int sendreply __P((sfsistat, int, struct timeval *, SMFICTX_PTR));
+static int sendreply __P((sfsistat, socket_t, struct timeval *, SMFICTX_PTR));
static void fix_stm __P((SMFICTX_PTR));
static bool trans_ok __P((int, int));
static char **dec_argv __P((char *, size_t));
@@ -110,6 +107,9 @@ static int dec_arg2 __P((char *, size_t, char **, char **));
#define ST_LAST ST_ABRT
#define ST_SKIP 15 /* not a state but required for the state table */
+/* in a mail transaction? must be before eom according to spec. */
+#define ST_IN_MAIL(st) ((st) >= ST_MAIL && (st) < ST_ENDM)
+
/*
** set of next states
** each state (ST_*) corresponds to bit in an int value (1 << state)
@@ -187,11 +187,13 @@ mi_engine(ctx)
SMFICTX_PTR ctx;
{
size_t len;
- int i, fd;
+ int i;
+ socket_t sd;
int ret = MI_SUCCESS;
int ncmds = sizeof(cmds) / sizeof(cmdfct);
int curstate = ST_INIT;
int newstate;
+ bool call_abort;
sfsistat r;
char cmd;
char *buf = NULL;
@@ -199,13 +201,17 @@ mi_engine(ctx)
struct timeval timeout;
int (*f) __P((genarg *));
sfsistat (*fi_abort) __P((SMFICTX *));
+ sfsistat (*fi_close) __P((SMFICTX *));
arg.a_ctx = ctx;
- fd = ctx->ctx_fd;
+ sd = ctx->ctx_sd;
fi_abort = ctx->ctx_smfi->xxfi_abort;
mi_clr_macros(ctx, 0);
fix_stm(ctx);
- do {
+ do
+ {
+ /* call abort only if in a mail transaction */
+ call_abort = ST_IN_MAIL(curstate);
timeout.tv_sec = ctx->ctx_timeout;
timeout.tv_usec = 0;
if (mi_stop() == MILTER_ABRT)
@@ -216,12 +222,12 @@ mi_engine(ctx)
ret = MI_FAILURE;
break;
}
- if ((buf = mi_rd_cmd(fd, &timeout, &cmd, &len,
+ if ((buf = mi_rd_cmd(sd, &timeout, &cmd, &len,
ctx->ctx_smfi->xxfi_name)) == NULL &&
cmd < SMFIC_VALIDCMD)
{
if (ctx->ctx_dbg > 5)
- dprintf("[%d] error (%x)\n",
+ dprintf("[%d] mi_engine: mi_rd_cmd error (%x)\n",
(int) ctx->ctx_id, (int) cmd);
/*
@@ -275,7 +281,9 @@ mi_engine(ctx)
curstate, MASK(curstate),
newstate, MASK(newstate),
next_states[curstate]);
- if (fi_abort != NULL)
+
+ /* call abort only if in a mail transaction */
+ if (fi_abort != NULL && call_abort)
(void) (*fi_abort)(ctx);
/*
@@ -303,12 +311,13 @@ mi_engine(ctx)
free(buf);
buf = NULL;
}
- if (sendreply(r, fd, &timeout, ctx) != MI_SUCCESS)
+ if (sendreply(r, sd, &timeout, ctx) != MI_SUCCESS)
{
ret = MI_FAILURE;
break;
}
+ call_abort = ST_IN_MAIL(curstate);
if (r == SMFIS_ACCEPT)
{
/* accept mail, no further actions taken */
@@ -337,16 +346,14 @@ mi_engine(ctx)
if (ret != MI_SUCCESS)
{
- if (fi_abort != NULL)
+ /* call abort only if in a mail transaction */
+ if (fi_abort != NULL && call_abort)
(void) (*fi_abort)(ctx);
}
- else
- {
- sfsistat (*fi_close) __P((SMFICTX *));
- if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL)
- (void) (*fi_close)(ctx);
- }
+ /* close must always be called */
+ if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL)
+ (void) (*fi_close)(ctx);
if (buf != NULL)
free(buf);
mi_clr_macros(ctx, 0);
@@ -357,7 +364,7 @@ mi_engine(ctx)
**
** Parameters:
** r -- reply code
-** fd -- file descriptor
+** sd -- socket descriptor
** timeout_ptr -- (ptr to) timeout to use for sending
** ctx -- context structure
**
@@ -366,24 +373,24 @@ mi_engine(ctx)
*/
static int
-sendreply(r, fd, timeout_ptr, ctx)
+sendreply(r, sd, timeout_ptr, ctx)
sfsistat r;
- int fd;
+ socket_t sd;
struct timeval *timeout_ptr;
SMFICTX_PTR ctx;
{
int ret = MI_SUCCESS;
- switch(r)
+ switch (r)
{
case SMFIS_CONTINUE:
- ret = mi_wr_cmd(fd, timeout_ptr, SMFIR_CONTINUE, NULL, 0);
+ ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_CONTINUE, NULL, 0);
break;
case SMFIS_TEMPFAIL:
case SMFIS_REJECT:
if (ctx->ctx_reply != NULL)
{
- ret = mi_wr_cmd(fd, timeout_ptr, SMFIR_REPLYCODE,
+ ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_REPLYCODE,
ctx->ctx_reply,
strlen(ctx->ctx_reply) + 1);
free(ctx->ctx_reply);
@@ -391,15 +398,15 @@ sendreply(r, fd, timeout_ptr, ctx)
}
else
{
- ret = mi_wr_cmd(fd, timeout_ptr, r == SMFIS_REJECT ?
+ ret = mi_wr_cmd(sd, timeout_ptr, r == SMFIS_REJECT ?
SMFIR_REJECT : SMFIR_TEMPFAIL, NULL, 0);
}
break;
case SMFIS_DISCARD:
- ret = mi_wr_cmd(fd, timeout_ptr, SMFIR_DISCARD, NULL, 0);
+ ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_DISCARD, NULL, 0);
break;
case SMFIS_ACCEPT:
- ret = mi_wr_cmd(fd, timeout_ptr, SMFIR_ACCEPT, NULL, 0);
+ ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_ACCEPT, NULL, 0);
break;
case _SMFIS_OPTIONS:
{
@@ -411,7 +418,10 @@ sendreply(r, fd, timeout_ptr, ctx)
v = htonl(ctx->ctx_smfi->xxfi_flags);
(void) memcpy(&(buf[MILTER_LEN_BYTES]), (void *) &v,
MILTER_LEN_BYTES);
- ret = mi_wr_cmd(fd, timeout_ptr, SMFIC_OPTNEG, buf,
+ v = htonl(ctx->ctx_pflags);
+ (void) memcpy(&(buf[MILTER_LEN_BYTES * 2]), (void *) &v,
+ MILTER_LEN_BYTES);
+ ret = mi_wr_cmd(sd, timeout_ptr, SMFIC_OPTNEG, buf,
MILTER_OPTLEN);
}
break;
@@ -466,15 +476,17 @@ static int
st_optionneg(g)
genarg *g;
{
- mi_int32 i, version;
+ mi_int32 i, v;
if (g == NULL || g->a_ctx->ctx_smfi == NULL)
return SMFIS_CONTINUE;
mi_clr_macros(g->a_ctx, g->a_idx + 1);
- if (g->a_len != MILTER_OPTLEN)
+
+ /* check for minimum length */
+ if (g->a_len < MILTER_OPTLEN)
{
smi_log(SMI_LOG_ERR,
- "%s: st_optionneg[%d]: len mismatch %d != %d",
+ "%s: st_optionneg[%d]: len too short %d < %d",
g->a_ctx->ctx_smfi->xxfi_name,
(int) g->a_ctx->ctx_id, g->a_len,
MILTER_OPTLEN);
@@ -483,23 +495,51 @@ st_optionneg(g)
(void) memcpy((void *) &i, (void *) &(g->a_buf[0]),
MILTER_LEN_BYTES);
- version = ntohl(i);
- if (version != g->a_ctx->ctx_smfi->xxfi_version)
+ v = ntohl(i);
+ if (v < g->a_ctx->ctx_smfi->xxfi_version)
{
+ /* hard failure for now! */
smi_log(SMI_LOG_ERR,
- "%s: st_optionneg[%d]: version mismatch %d != %d",
+ "%s: st_optionneg[%d]: version mismatch MTA: %d < milter: %d",
g->a_ctx->ctx_smfi->xxfi_name,
- (int) g->a_ctx->ctx_id, (int) version,
+ (int) g->a_ctx->ctx_id, (int) v,
g->a_ctx->ctx_smfi->xxfi_version);
return _SMFIS_ABORT;
}
-#if 0
- /* flags are currently ignored */
(void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES]),
MILTER_LEN_BYTES);
- flags = ntohl(i);
-#endif /* 0 */
+ v = ntohl(i);
+
+ /* no flags? set to default value for V1 actions */
+ if (v == 0)
+ v = SMFI_V1_ACTS;
+ i = g->a_ctx->ctx_smfi->xxfi_flags;
+ if ((v & i) != i)
+ {
+ smi_log(SMI_LOG_ERR,
+ "%s: st_optionneg[%d]: 0x%x does not fulfill action requirements 0x%x",
+ g->a_ctx->ctx_smfi->xxfi_name,
+ (int) g->a_ctx->ctx_id, v, i);
+ return _SMFIS_ABORT;
+ }
+
+ (void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES * 2]),
+ MILTER_LEN_BYTES);
+ v = ntohl(i);
+
+ /* no flags? set to default value for V1 protocol */
+ if (v == 0)
+ v = SMFI_V1_PROT;
+ i = g->a_ctx->ctx_pflags;
+ if ((v & i) != i)
+ {
+ smi_log(SMI_LOG_ERR,
+ "%s: st_optionneg[%d]: 0x%x does not fulfill protocol requirements 0x%x",
+ g->a_ctx->ctx_smfi->xxfi_name,
+ (int) g->a_ctx->ctx_id, v, i);
+ return _SMFIS_ABORT;
+ }
return _SMFIS_OPTIONS;
}
@@ -518,9 +558,9 @@ st_connectinfo(g)
genarg *g;
{
size_t l;
- int i;
+ size_t i;
char *s, family;
- u_short port;
+ u_short port = 0;
_SOCK_ADDR sockaddr;
sfsistat (*fi_connect) __P((SMFICTX *, char *, _SOCK_ADDR *));
@@ -569,6 +609,8 @@ st_connectinfo(g)
return _SMFIS_ABORT;
}
sockaddr.sa.sa_family = AF_INET;
+ if (port > 0)
+ sockaddr.sin.sin_port = port;
}
else
# endif /* NETINET */
@@ -585,6 +627,8 @@ st_connectinfo(g)
return _SMFIS_ABORT;
}
sockaddr.sa.sa_family = AF_INET6;
+ if (port > 0)
+ sockaddr.sin6.sin6_port = port;
}
else
# endif /* NETINET6 */
@@ -763,7 +807,7 @@ st_macros(g)
return _SMFIS_FAIL;
if ((argv = dec_argv(g->a_buf + 1, g->a_len - 1)) == NULL)
return _SMFIS_FAIL;
- switch(g->a_buf[0])
+ switch (g->a_buf[0])
{
case SMFIC_CONNECT:
i = CI_CONN;
@@ -857,15 +901,15 @@ st_bodyend(g)
if ((fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL &&
g->a_len > 0)
{
- int fd;
+ socket_t sd;
struct timeval timeout;
timeout.tv_sec = g->a_ctx->ctx_timeout;
timeout.tv_usec = 0;
- fd = g->a_ctx->ctx_fd;
+ sd = g->a_ctx->ctx_sd;
r = (*fi_body)(g->a_ctx, (u_char *)g->a_buf, g->a_len);
if (r != SMFIS_CONTINUE &&
- sendreply(r, fd, &timeout, g->a_ctx) != MI_SUCCESS)
+ sendreply(r, sd, &timeout, g->a_ctx) != MI_SUCCESS)
return _SMFIS_ABORT;
}
}
@@ -915,7 +959,8 @@ trans_ok(old, new)
int s, n;
s = old;
- do {
+ do
+ {
/* is this state transition allowed? */
if ((MASK(new) & next_states[s]) != 0)
return TRUE;
@@ -960,21 +1005,20 @@ fix_stm(ctx)
if (ctx == NULL || ctx->ctx_smfi == NULL)
return;
- fl = ctx->ctx_smfi->xxfi_flags;
- if (bitset(SMFIF_NOCONNECT, fl))
+ fl = ctx->ctx_pflags;
+ if (bitset(SMFIP_NOCONNECT, fl))
next_states[ST_CONN] |= NX_SKIP;
- if (bitset(SMFIF_NOHELO, fl))
+ if (bitset(SMFIP_NOHELO, fl))
next_states[ST_HELO] |= NX_SKIP;
- if (bitset(SMFIF_NOMAIL, fl))
+ if (bitset(SMFIP_NOMAIL, fl))
next_states[ST_MAIL] |= NX_SKIP;
- if (bitset(SMFIF_NORCPT, fl))
+ if (bitset(SMFIP_NORCPT, fl))
next_states[ST_RCPT] |= NX_SKIP;
- if (bitset(SMFIF_NOHDRS, fl))
- {
+ if (bitset(SMFIP_NOHDRS, fl))
next_states[ST_HDRS] |= NX_SKIP;
+ if (bitset(SMFIP_NOEOH, fl))
next_states[ST_EOHS] |= NX_SKIP;
- }
- if (bitset(SMFIF_NOBODY, fl))
+ if (bitset(SMFIP_NOBODY, fl))
next_states[ST_BODY] |= NX_SKIP;
}
/*
@@ -1019,7 +1063,7 @@ dec_argv(buf, len)
/* overwrite last entry */
s[elem] = NULL;
- return (s);
+ return s;
}
/*
** DEC_ARG2 -- split a buffer into two strings
@@ -1040,7 +1084,7 @@ dec_arg2(buf, len, s1, s2)
char **s1;
char **s2;
{
- int i;
+ size_t i;
*s1 = buf;
for (i = 1; i < len && buf[i] != '\0'; i++)
diff --git a/gnu/usr.sbin/sendmail/libmilter/handler.c b/gnu/usr.sbin/sendmail/libmilter/handler.c
index 0a805b75752..3b5102fe031 100644
--- a/gnu/usr.sbin/sendmail/libmilter/handler.c
+++ b/gnu/usr.sbin/sendmail/libmilter/handler.c
@@ -9,14 +9,15 @@
*/
#ifndef lint
-static char id[] = "@(#)$Sendmail: handler.c,v 8.19 2000/02/11 00:12:29 ca Exp $";
+static char id[] = "@(#)$Sendmail: handler.c,v 8.19.4.3 2000/12/29 19:45:39 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
#include "libmilter.h"
+
/*
-** HANDLE_SESSION -- Handle a connected session in it's own context
+** HANDLE_SESSION -- Handle a connected session in its own context
**
** Parameters:
** ctx -- context structure
@@ -33,7 +34,7 @@ mi_handle_session(ctx)
if (ctx == NULL)
return MI_FAILURE;
- ctx->ctx_id = pthread_self();
+ ctx->ctx_id = (sthread_t) sthread_get_id();
/*
** detach so resources are free when the thread returns
@@ -42,10 +43,16 @@ mi_handle_session(ctx)
if (pthread_detach(ctx->ctx_id) != 0)
return MI_FAILURE;
ret = mi_engine(ctx);
- if (ctx->ctx_fd >= 0)
- (void) close(ctx->ctx_fd);
+ if (ValidSocket(ctx->ctx_sd))
+ {
+ (void) close(ctx->ctx_sd);
+ ctx->ctx_sd = INVALID_SOCKET;
+ }
if (ctx->ctx_reply != NULL)
+ {
free(ctx->ctx_reply);
+ ctx->ctx_reply = NULL;
+ }
if (ctx->ctx_privdata != NULL)
{
smi_log(SMI_LOG_WARN,
diff --git a/gnu/usr.sbin/sendmail/libmilter/libmilter.h b/gnu/usr.sbin/sendmail/libmilter/libmilter.h
index eaf581d760a..898edfc38bd 100644
--- a/gnu/usr.sbin/sendmail/libmilter/libmilter.h
+++ b/gnu/usr.sbin/sendmail/libmilter/libmilter.h
@@ -8,7 +8,7 @@
*/
/*
-** MILTER.H -- include file for mail filter library functions
+** LIBMILTER.H -- include file for mail filter library functions
*/
#ifndef _LIBMILTER_H
@@ -17,21 +17,40 @@
# define EXTERN
# define INIT(x) = x
# ifndef lint
-static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3 2000/02/26 01:32:13 gshapiro Exp $";
+static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3.6.10 2000/11/20 21:15:36 ca Exp $";
# endif /* ! lint */
#else /* _DEFINE */
# define EXTERN extern
# define INIT(x)
#endif /* _DEFINE */
+
+#define NOT_SENDMAIL 1
+#define _SOCK_ADDR union bigsockaddr
+#include "sendmail.h"
+
#include "libmilter/milter.h"
-#include "libmilter/mfapi.h"
#ifndef __P
# include "sendmail/cdefs.h"
#endif /* ! __P */
#include "sendmail/useful.h"
+# define ValidSocket(sd) ((sd) >= 0)
+# define INVALID_SOCKET -1
+# define MI_SOCK_READ(s, b, l) (read(s, b, l))
+# define MI_SOCK_WRITE(s, b, l) (write(s, b, l))
+
+# define thread_create(ptid,wr,arg) pthread_create(ptid, NULL, wr, arg)
+# define sthread_get_id() pthread_self()
+
+typedef pthread_mutex_t smutex_t;
+# define smutex_init(mp) (pthread_mutex_init(mp, NULL) == 0)
+# define smutex_destroy(mp) (pthread_mutex_destroy(mp) == 0)
+# define smutex_lock(mp) (pthread_mutex_lock(mp) == 0)
+# define smutex_unlock(mp) (pthread_mutex_unlock(mp) == 0)
+# define smutex_trylock(mp) (pthread_mutex_trylock(mp) == 0)
+
#include <sys/time.h>
/* version info */
@@ -42,6 +61,12 @@ static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3 2000/02/26 01:32:13
#define MI_TIMEOUT 1800 /* default timeout for read/write */
#define MI_CHK_TIME 5 /* checking whether to terminate */
+#if SOMAXCONN > 20
+# define MI_SOMAXCONN SOMAXCONN
+#else /* SOMAXCONN */
+# define MI_SOMAXCONN 20
+#endif /* SOMAXCONN */
+
/* maximum number of repeated failures in mi_listener() */
#define MAX_FAILS_M 16 /* malloc() */
#define MAX_FAILS_T 16 /* thread creation */
@@ -65,8 +90,6 @@ static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3 2000/02/26 01:32:13
#define SMI_LOG_INFO LOG_INFO
#define SMI_LOG_DEBUG LOG_DEBUG
-#define MI_INVALID_SOCKET (-1)
-
/* stop? */
#define MILTER_CONT 0
#define MILTER_STOP 1
@@ -75,17 +98,18 @@ static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3 2000/02/26 01:32:13
/* functions */
extern int mi_handle_session __P((SMFICTX_PTR));
extern int mi_engine __P((SMFICTX_PTR));
-extern int mi_listener __P((char *, int, smfiDesc_ptr, time_t));
+extern int mi_listener __P((char *, int, smfiDesc_ptr, time_t, int));
extern void mi_clr_macros __P((SMFICTX_PTR, int));
extern int mi_stop __P((void));
extern int mi_control_startup __P((char *));
extern void mi_stop_milters __P((int));
extern void mi_clean_signals __P((void));
extern struct hostent *mi_gethostbyname __P((char *, int));
+extern void mi_closener __P((void));
/* communication functions */
-extern char *mi_rd_cmd __P((int, struct timeval *, char *, size_t *, char *));
-extern int mi_wr_cmd __P((int, struct timeval *, int, char *, size_t));
+extern char *mi_rd_cmd __P((socket_t, struct timeval *, char *, size_t *, char *));
+extern int mi_wr_cmd __P((socket_t, struct timeval *, int, char *, size_t));
extern bool mi_sendok __P((SMFICTX_PTR, int));
#endif /* !_LIBMILTER_H */
diff --git a/gnu/usr.sbin/sendmail/libmilter/listener.c b/gnu/usr.sbin/sendmail/libmilter/listener.c
index 3ee18045a40..43a00e60a69 100644
--- a/gnu/usr.sbin/sendmail/libmilter/listener.c
+++ b/gnu/usr.sbin/sendmail/libmilter/listener.c
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Sendmail: listener.c,v 8.38 2000/02/11 00:12:30 ca Exp $";
+static char id[] = "@(#)$Sendmail: listener.c,v 8.38.2.1.2.18 2000/12/29 19:44:28 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -19,10 +19,10 @@ static char id[] = "@(#)$Sendmail: listener.c,v 8.38 2000/02/11 00:12:30 ca Exp
#include "libmilter.h"
-#if NETINET || NETINET6
-# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+# if NETINET || NETINET6
+# include <arpa/inet.h>
+# endif /* NETINET || NETINET6 */
/*
** MI_MILTEROPEN -- setup socket to listen on
**
@@ -35,26 +35,25 @@ static char id[] = "@(#)$Sendmail: listener.c,v 8.38 2000/02/11 00:12:30 ca Exp
** socket upon success, error code otherwise.
*/
-static int
+static socket_t
mi_milteropen(conn, backlog, socksize, name)
char *conn;
int backlog;
SOCKADDR_LEN_T *socksize;
char *name;
{
- int sock = 0;
+ socket_t sock;
int sockopt = 1;
char *p;
char *colon;
char *at;
- struct hostent *hp = NULL;
SOCKADDR addr;
if (conn == NULL || conn[0] == '\0')
{
smi_log(SMI_LOG_ERR, "%s: empty or missing socket information",
name);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
(void) memset(&addr, '\0', sizeof addr);
@@ -86,7 +85,7 @@ mi_milteropen(conn, backlog, socksize, name)
smi_log(SMI_LOG_ERR,
"%s: no valid socket protocols available",
name);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
# endif /* NETINET6 */
# endif /* NETINET */
#endif /* NETUNIX */
@@ -117,7 +116,7 @@ mi_milteropen(conn, backlog, socksize, name)
{
smi_log(SMI_LOG_ERR, "%s: unknown socket type %s",
name, p);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
*colon++ = ':';
}
@@ -141,7 +140,7 @@ mi_milteropen(conn, backlog, socksize, name)
# else /* NETINET6 */
smi_log(SMI_LOG_ERR, "%s: unknown socket type %s",
name, p);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
# endif /* NETINET6 */
# endif /* NETINET */
#endif /* NETUNIX */
@@ -162,7 +161,7 @@ mi_milteropen(conn, backlog, socksize, name)
errno = EINVAL;
smi_log(SMI_LOG_ERR, "%s: UNIX socket name %s too long",
name, colon);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
# if 0
errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff,
@@ -174,7 +173,7 @@ mi_milteropen(conn, backlog, socksize, name)
smi_log(SMI_LOG_ERR,
"%s: UNIX socket name %s unsafe",
name, colon);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
# endif /* 0 */
@@ -219,13 +218,13 @@ mi_milteropen(conn, backlog, socksize, name)
*at = '\0';
if (isascii(*colon) && isdigit(*colon))
- port = htons(atoi(colon));
+ port = htons((u_short) atoi(colon));
else
{
# ifdef NO_GETSERVBYNAME
smi_log(SMI_LOG_ERR, "%s: invalid port number %s",
name, colon);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
# else /* NO_GETSERVBYNAME */
register struct servent *sp;
@@ -235,7 +234,7 @@ mi_milteropen(conn, backlog, socksize, name)
smi_log(SMI_LOG_ERR,
"%s: unknown port name %s",
name, colon);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
port = sp->s_port;
# endif /* NO_GETSERVBYNAME */
@@ -286,7 +285,7 @@ mi_milteropen(conn, backlog, socksize, name)
smi_log(SMI_LOG_ERR,
"%s: Invalid numeric domain spec \"%s\"",
name, at);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
}
else
@@ -294,18 +293,20 @@ mi_milteropen(conn, backlog, socksize, name)
smi_log(SMI_LOG_ERR,
"%s: Invalid numeric domain spec \"%s\"",
name, at);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
}
else
{
+ struct hostent *hp = NULL;
+
hp = mi_gethostbyname(at, addr.sa.sa_family);
if (hp == NULL)
{
smi_log(SMI_LOG_ERR,
"%s: Unknown host name %s",
name, at);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
addr.sa.sa_family = hp->h_addrtype;
switch (hp->h_addrtype)
@@ -332,8 +333,11 @@ mi_milteropen(conn, backlog, socksize, name)
smi_log(SMI_LOG_ERR,
"%s: Unknown protocol for %s (%d)",
name, at, hp->h_addrtype);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
+# if _FFR_FREEHOSTENT && NETINET6
+ freehostent(hp);
+# endif /* _FFR_FREEHOSTENT && NETINET6 */
}
}
else
@@ -356,12 +360,12 @@ mi_milteropen(conn, backlog, socksize, name)
#endif /* NETINET || NETINET6 */
sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
- if (sock < 0)
+ if (!ValidSocket(sock))
{
smi_log(SMI_LOG_ERR,
"%s: Unable to create new socket: %s",
name, strerror(errno));
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt,
@@ -370,7 +374,7 @@ mi_milteropen(conn, backlog, socksize, name)
smi_log(SMI_LOG_ERR,
"%s: Unable to setsockopt: %s", name, strerror(errno));
(void) close(sock);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
if (bind(sock, &addr.sa, *socksize) < 0)
@@ -379,7 +383,7 @@ mi_milteropen(conn, backlog, socksize, name)
"%s: Unable to bind to port %s: %s",
name, conn, strerror(errno));
(void) close(sock);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
if (listen(sock, backlog) < 0)
@@ -387,7 +391,7 @@ mi_milteropen(conn, backlog, socksize, name)
smi_log(SMI_LOG_ERR,
"%s: listen call failed: %s", name, strerror(errno));
(void) close(sock);
- return MI_INVALID_SOCKET;
+ return INVALID_SOCKET;
}
return sock;
@@ -409,8 +413,34 @@ mi_thread_handle_wrapper(arg)
return (void *) mi_handle_session(arg);
}
+static socket_t listenfd = INVALID_SOCKET;
+
+static smutex_t L_Mutex;
+
+ /*
+** MI_CLOSENER -- close listen socket
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+*/
+
+void
+mi_closener()
+{
+ (void) smutex_lock(&L_Mutex);
+ if (ValidSocket(listenfd))
+ {
+ (void) close(listenfd);
+ listenfd = INVALID_SOCKET;
+ }
+ (void) smutex_unlock(&L_Mutex);
+}
+
/*
-** MI_MILTER_LISTENER -- Generic listener harness
+** MI_LISTENER -- Generic listener harness
**
** Open up listen port
** Wait for connections
@@ -428,23 +458,23 @@ mi_thread_handle_wrapper(arg)
*/
int
-mi_listener(conn, dbg, smfi, timeout)
+mi_listener(conn, dbg, smfi, timeout, backlog)
char *conn;
int dbg;
smfiDesc_ptr smfi;
time_t timeout;
+ int backlog;
{
- int connfd = -1;
- int listenfd = -1;
- int clilen;
+ socket_t connfd = INVALID_SOCKET;
int sockopt = 1;
int r;
int ret = MI_SUCCESS;
int cnt_m = 0;
int cnt_t = 0;
- pthread_t thread_id;
+ sthread_t thread_id;
_SOCK_ADDR cliaddr;
SOCKADDR_LEN_T socksize;
+ SOCKADDR_LEN_T clilen;
SMFICTX_PTR ctx;
fd_set readset, excset;
struct timeval chktime;
@@ -453,37 +483,56 @@ mi_listener(conn, dbg, smfi, timeout)
smi_log(SMI_LOG_DEBUG,
"%s: Opening listen socket on conn %s",
smfi->xxfi_name, conn);
- if ((listenfd = mi_milteropen(conn, SOMAXCONN, &socksize,
- smfi->xxfi_name)) < 0)
+ (void) smutex_init(&L_Mutex);
+ (void) smutex_lock(&L_Mutex);
+ listenfd = mi_milteropen(conn, backlog, &socksize, smfi->xxfi_name);
+ if (!ValidSocket(listenfd))
{
smi_log(SMI_LOG_FATAL,
"%s: Unable to create listening socket on conn %s",
smfi->xxfi_name, conn);
+ (void) smutex_unlock(&L_Mutex);
return MI_FAILURE;
}
clilen = socksize;
+
if (listenfd >= FD_SETSIZE)
{
smi_log(SMI_LOG_ERR, "%s: fd %d is larger than FD_SETSIZE %d",
smfi->xxfi_name, listenfd, FD_SETSIZE);
+ (void) smutex_unlock(&L_Mutex);
return MI_FAILURE;
}
+ (void) smutex_unlock(&L_Mutex);
while (mi_stop() == MILTER_CONT)
{
+ (void) smutex_lock(&L_Mutex);
+ if (!ValidSocket(listenfd))
+ {
+ (void) smutex_unlock(&L_Mutex);
+ break;
+ }
+
/* select on interface ports */
FD_ZERO(&readset);
- FD_SET(listenfd, &readset);
FD_ZERO(&excset);
- FD_SET(listenfd, &excset);
+ FD_SET((u_int) listenfd, &readset);
+ FD_SET((u_int) listenfd, &excset);
chktime.tv_sec = MI_CHK_TIME;
chktime.tv_usec = 0;
r = select(listenfd + 1, &readset, NULL, &excset, &chktime);
if (r == 0) /* timeout */
+ {
+ (void) smutex_unlock(&L_Mutex);
continue; /* just check mi_stop() */
+ }
if (r < 0)
{
- if (errno == EINTR)
+ int err = errno;
+
+ (void) smutex_unlock(&L_Mutex);
+ if (err == EINTR)
continue;
ret = MI_FAILURE;
break;
@@ -492,13 +541,15 @@ mi_listener(conn, dbg, smfi, timeout)
{
/* some error: just stop for now... */
ret = MI_FAILURE;
+ (void) smutex_unlock(&L_Mutex);
break;
}
connfd = accept(listenfd, (struct sockaddr *) &cliaddr,
&clilen);
+ (void) smutex_unlock(&L_Mutex);
- if (connfd < 0)
+ if (!ValidSocket(connfd))
{
smi_log(SMI_LOG_ERR,
"%s: accept() returned invalid socket",
@@ -528,7 +579,7 @@ mi_listener(conn, dbg, smfi, timeout)
}
cnt_m = 0;
memset(ctx, '\0', sizeof *ctx);
- ctx->ctx_fd = connfd;
+ ctx->ctx_sd = connfd;
ctx->ctx_dbg = dbg;
ctx->ctx_timeout = timeout;
ctx->ctx_smfi = smfi;
@@ -539,24 +590,26 @@ mi_listener(conn, dbg, smfi, timeout)
if (smfi->xxfi_close == NULL)
#endif /* 0 */
if (smfi->xxfi_connect == NULL)
- smfi->xxfi_flags |= SMFIF_NOCONNECT;
+ ctx->ctx_pflags |= SMFIP_NOCONNECT;
if (smfi->xxfi_helo == NULL)
- smfi->xxfi_flags |= SMFIF_NOHELO;
+ ctx->ctx_pflags |= SMFIP_NOHELO;
if (smfi->xxfi_envfrom == NULL)
- smfi->xxfi_flags |= SMFIF_NOMAIL;
+ ctx->ctx_pflags |= SMFIP_NOMAIL;
if (smfi->xxfi_envrcpt == NULL)
- smfi->xxfi_flags |= SMFIF_NORCPT;
+ ctx->ctx_pflags |= SMFIP_NORCPT;
if (smfi->xxfi_header == NULL)
- smfi->xxfi_flags |= SMFIF_NOHDRS;
+ ctx->ctx_pflags |= SMFIP_NOHDRS;
+ if (smfi->xxfi_eoh == NULL)
+ ctx->ctx_pflags |= SMFIP_NOEOH;
if (smfi->xxfi_body == NULL)
- smfi->xxfi_flags |= SMFIF_NOBODY;
+ ctx->ctx_pflags |= SMFIP_NOBODY;
- if ((r = pthread_create(&thread_id, NULL,
+ if ((r = thread_create(&thread_id,
mi_thread_handle_wrapper,
(void *) ctx)) != 0)
{
smi_log(SMI_LOG_ERR,
- "%s: pthread_create() failed: %d",
+ "%s: thread_create() failed: %d",
smfi->xxfi_name, r);
sleep(++cnt_t);
(void) close(connfd);
@@ -572,8 +625,9 @@ mi_listener(conn, dbg, smfi, timeout)
}
if (ret != MI_SUCCESS)
mi_stop_milters(MILTER_ABRT);
- if (listenfd >= 0)
- (void) close(listenfd);
+ else
+ mi_closener();
+ (void) smutex_destroy(&L_Mutex);
return ret;
}
#endif /* _FFR_MILTER */
diff --git a/gnu/usr.sbin/sendmail/libmilter/main.c b/gnu/usr.sbin/sendmail/libmilter/main.c
index cf0bbcd2831..873eddafeff 100644
--- a/gnu/usr.sbin/sendmail/libmilter/main.c
+++ b/gnu/usr.sbin/sendmail/libmilter/main.c
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Sendmail: main.c,v 8.34 2000/02/11 02:43:45 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: main.c,v 8.34.4.9 2000/09/09 02:23:03 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -18,6 +18,7 @@ static char id[] = "@(#)$Sendmail: main.c,v 8.34 2000/02/11 02:43:45 gshapiro Ex
#include <fcntl.h>
#include <sys/stat.h>
+
static smfiDesc_ptr smfi = NULL;
/*
@@ -42,7 +43,7 @@ smfi_register(smfilter)
if (smfi == NULL)
return MI_FAILURE;
}
- (void)memcpy(smfi, &smfilter, sizeof *smfi);
+ (void) memcpy(smfi, &smfilter, sizeof *smfi);
if (smfilter.xxfi_name == NULL)
smfilter.xxfi_name = "Unknown";
@@ -51,12 +52,42 @@ smfi_register(smfilter)
if (smfi->xxfi_name == NULL)
return MI_FAILURE;
(void) strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len);
+
+ /* compare milter version with hard coded version */
+ if (smfi->xxfi_version != SMFI_VERSION)
+ {
+ /* hard failure for now! */
+ smi_log(SMI_LOG_ERR,
+ "%s: smfi_register: version mismatch application: %d != milter: %d",
+ smfi->xxfi_name, smfi->xxfi_version,
+ (int) SMFI_VERSION);
+ return MI_FAILURE;
+ }
+
+ return MI_SUCCESS;
+}
+
+ /*
+** SMFI_STOP -- stop milter
+**
+** Parameters:
+** none.
+**
+** Returns:
+** success.
+*/
+
+int
+smfi_stop()
+{
+ mi_stop_milters(MILTER_STOP);
return MI_SUCCESS;
}
static int dbg = 0;
static char *conn = NULL;
static int timeout = MI_TIMEOUT;
+static int backlog= MI_SOMAXCONN;
int
smfi_setdbg(odbg)
@@ -91,6 +122,16 @@ smfi_setconn(oconn)
}
int
+smfi_setbacklog(obacklog)
+ int obacklog;
+{
+ if (obacklog <= 0)
+ return MI_FAILURE;
+ backlog = obacklog;
+ return MI_SUCCESS;
+}
+
+int
smfi_main()
{
signal(SIGPIPE, SIG_IGN);
@@ -98,7 +139,7 @@ smfi_main()
{
smi_log(SMI_LOG_FATAL, "%s: missing connection information",
smfi->xxfi_name);
- exit(EX_DATAERR);
+ return MI_FAILURE;
}
(void) atexit(mi_clean_signals);
@@ -107,13 +148,13 @@ smfi_main()
smi_log(SMI_LOG_FATAL,
"%s: Couldn't start signal thread",
smfi->xxfi_name);
- exit(EX_OSERR);
+ return MI_FAILURE;
}
/* Startup the listener */
- if (mi_listener(conn, dbg, smfi, timeout) != MI_SUCCESS)
- return(MI_FAILURE);
+ if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
+ return MI_FAILURE;
- return(MI_SUCCESS);
+ return MI_SUCCESS;
}
#endif /* _FFR_MILTER */
diff --git a/gnu/usr.sbin/sendmail/libmilter/signal.c b/gnu/usr.sbin/sendmail/libmilter/signal.c
index 00ddd9fdcd4..19a79be2560 100644
--- a/gnu/usr.sbin/sendmail/libmilter/signal.c
+++ b/gnu/usr.sbin/sendmail/libmilter/signal.c
@@ -9,29 +9,21 @@
*/
#ifndef lint
-static char id[] = "@(#)$Sendmail: signal.c,v 8.10 2000/02/26 01:32:14 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: signal.c,v 8.10.4.8 2000/11/20 21:15:37 ca Exp $";
#endif /* ! lint */
#if _FFR_MILTER
#include "libmilter.h"
/*
-** thread to handle signals
+** thread to handle signals
*/
-typedef pthread_mutex_t smutex_t;
-#define smutex_init(mp) (pthread_mutex_init(mp, NULL) == 0)
-#define smutex_destroy(mp) (pthread_mutex_destroy(mp) == 0)
-#define smutex_lock(mp) (pthread_mutex_lock(mp) == 0)
-#define smutex_unlock(mp) (pthread_mutex_unlock(mp) == 0)
-#define smutex_trylock(mp) (pthread_mutex_trylock(mp) == 0)
-
static smutex_t M_Mutex;
static int MilterStop = MILTER_CONT;
-
-/*
+ /*
** MI_STOP -- return value of MilterStop
**
** Parameters:
@@ -44,11 +36,9 @@ static int MilterStop = MILTER_CONT;
int
mi_stop()
{
- return(MilterStop);
+ return MilterStop;
}
-
-
-/*
+ /*
** MI_STOP_MILTERS -- set value of MilterStop
**
** Parameters:
@@ -65,10 +55,12 @@ mi_stop_milters(v)
(void) smutex_lock(&M_Mutex);
if (MilterStop < v)
MilterStop = v;
+
+ /* close listen socket */
+ mi_closener();
(void) smutex_unlock(&M_Mutex);
}
-
-/*
+ /*
** MI_CLEAN_SIGNALS -- clean up signal handler thread
**
** Parameters:
@@ -83,9 +75,8 @@ mi_clean_signals()
{
(void) smutex_destroy(&M_Mutex);
}
-
-/*
-** MI -- thread to deal with signals
+ /*
+** MI_SIGNAL_THREAD -- thread to deal with signals
**
** Parameters:
** name -- name of milter
@@ -147,8 +138,7 @@ mi_signal_thread(name)
}
}
}
-
-/*
+ /*
** MI_SPAWN_SIGNAL_THREAD -- spawn thread to handle signals
**
** Parameters:
@@ -162,8 +152,8 @@ static int
mi_spawn_signal_thread(name)
char *name;
{
+ sthread_t tid;
sigset_t set;
- pthread_t tid;
/* Mask HUP and KILL signals */
sigemptyset(&set);
@@ -177,8 +167,8 @@ mi_spawn_signal_thread(name)
"%s: Couldn't mask HUP and KILL signals", name);
return MI_FAILURE;
}
- if (pthread_create(&tid, NULL, mi_signal_thread, (void *)name)
- != MI_SUCCESS)
+ if (thread_create(&tid, mi_signal_thread,
+ (void *)name) != MI_SUCCESS)
{
smi_log(SMI_LOG_ERR,
"%s: Couldn't start signal thread", name);
@@ -186,8 +176,7 @@ mi_spawn_signal_thread(name)
}
return MI_SUCCESS;
}
-
-/*
+ /*
** MI_CONTROL_STARTUP -- startup for thread to handle signals
**
** Parameters:
diff --git a/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c b/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c
index 9ee76a5f76e..b7de9775e08 100644
--- a/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c
+++ b/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Sendmail: sm_gethost.c,v 8.7 2000/01/20 21:51:52 geir Exp $";
+static char id[] = "@(#)$Sendmail: sm_gethost.c,v 8.7.8.4 2000/12/19 04:26:33 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -39,7 +39,7 @@ static char id[] = "@(#)$Sendmail: sm_gethost.c,v 8.7 2000/01/20 21:51:52 geir E
# endif /* ! AI_ALL */
static struct hostent *
-mi_getipnodebyname(name, family, flags, err)
+getipnodebyname(name, family, flags, err)
char *name;
int family;
int flags;
@@ -61,6 +61,20 @@ mi_getipnodebyname(name, family, flags, err)
_res.options &= ~RES_USE_INET6;
return h;
}
+
+# if _FFR_FREEHOSTENT
+void
+freehostent(h)
+ struct hostent *h;
+{
+ /*
+ ** Stub routine -- if they don't have getipnodeby*(),
+ ** they probably don't have the free routine either.
+ */
+
+ return;
+}
+# endif /* _FFR_FREEHOSTENT */
#endif /* NEEDSGETIPNODE && NETINET6 && __RES < 19990909 */
struct hostent *
@@ -87,7 +101,7 @@ mi_gethostbyname(name, family)
# endif /* NETINET6 */
# if NETINET6
- h = mi_getipnodebyname(name, family, AI_V4MAPPED|AI_ALL, &err);
+ h = getipnodebyname(name, family, AI_V4MAPPED|AI_ALL, &err);
h_errno = err;
# else /* NETINET6 */
h = gethostbyname(name);
diff --git a/gnu/usr.sbin/sendmail/libmilter/smfi.c b/gnu/usr.sbin/sendmail/libmilter/smfi.c
index 5496e35318a..5297524e5fd 100644
--- a/gnu/usr.sbin/sendmail/libmilter/smfi.c
+++ b/gnu/usr.sbin/sendmail/libmilter/smfi.c
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Sendmail: smfi.c,v 8.28 2000/02/26 01:32:15 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: smfi.c,v 8.28.4.6 2000/06/28 23:48:56 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -40,9 +40,9 @@ smfi_addheader(ctx, headerf, headerv)
char *buf;
struct timeval timeout;
- if (headerf == NULL || headerv == NULL)
+ if (headerf == NULL || *headerf == '\0' || headerv == NULL)
return MI_FAILURE;
- if (!mi_sendok(ctx, SMFIF_MODHDRS))
+ if (!mi_sendok(ctx, SMFIF_ADDHDRS))
return MI_FAILURE;
timeout.tv_sec = ctx->ctx_timeout;
timeout.tv_usec = 0;
@@ -54,7 +54,59 @@ smfi_addheader(ctx, headerf, headerv)
return MI_FAILURE;
(void) memcpy(buf, headerf, l1 + 1);
(void) memcpy(buf + l1 + 1, headerv, l2 + 1);
- r = mi_wr_cmd(ctx->ctx_fd, &timeout, SMFIR_ADDHEADER, buf, len);
+ r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_ADDHEADER, buf, len);
+ free(buf);
+ return r;
+}
+
+/*
+** SMFI_CHGHEADER -- send a changed header to the MTA
+**
+** Parameters:
+** ctx -- Opaque context structure
+** headerf -- Header field name
+** hdridx -- Header index value
+** headerv -- Header field value
+**
+** Returns:
+** MI_SUCCESS/MI_FAILURE
+*/
+
+int
+smfi_chgheader(ctx, headerf, hdridx, headerv)
+ SMFICTX *ctx;
+ char *headerf;
+ mi_int32 hdridx;
+ char *headerv;
+{
+ /* do we want to copy the stuff or have a special mi_wr_cmd call? */
+ size_t len, l1, l2;
+ int r;
+ mi_int32 v;
+ char *buf;
+ struct timeval timeout;
+
+ if (headerf == NULL || *headerf == '\0')
+ return MI_FAILURE;
+ if (hdridx < 0)
+ return MI_FAILURE;
+ if (!mi_sendok(ctx, SMFIF_CHGHDRS))
+ return MI_FAILURE;
+ timeout.tv_sec = ctx->ctx_timeout;
+ timeout.tv_usec = 0;
+ if (headerv == NULL)
+ headerv = "";
+ l1 = strlen(headerf);
+ l2 = strlen(headerv);
+ len = l1 + l2 + 2 + MILTER_LEN_BYTES;
+ buf = malloc(len);
+ if (buf == NULL)
+ return MI_FAILURE;
+ v = htonl(hdridx);
+ (void) memcpy(&(buf[0]), (void *) &v, MILTER_LEN_BYTES);
+ (void) memcpy(buf + MILTER_LEN_BYTES, headerf, l1 + 1);
+ (void) memcpy(buf + MILTER_LEN_BYTES + l1 + 1, headerv, l2 + 1);
+ r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_CHGHEADER, buf, len);
free(buf);
return r;
}
@@ -77,14 +129,14 @@ smfi_addrcpt(ctx, rcpt)
size_t len;
struct timeval timeout;
- if (rcpt == NULL)
+ if (rcpt == NULL || *rcpt == '\0')
return MI_FAILURE;
if (!mi_sendok(ctx, SMFIF_ADDRCPT))
return MI_FAILURE;
timeout.tv_sec = ctx->ctx_timeout;
timeout.tv_usec = 0;
len = strlen(rcpt) + 1;
- return mi_wr_cmd(ctx->ctx_fd, &timeout, SMFIR_ADDRCPT, rcpt, len);
+ return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_ADDRCPT, rcpt, len);
}
/*
** SMFI_DELRCPT -- send a recipient to be removed to the MTA
@@ -105,14 +157,14 @@ smfi_delrcpt(ctx, rcpt)
size_t len;
struct timeval timeout;
- if (rcpt == NULL)
+ if (rcpt == NULL || *rcpt == '\0')
return MI_FAILURE;
if (!mi_sendok(ctx, SMFIF_DELRCPT))
return MI_FAILURE;
timeout.tv_sec = ctx->ctx_timeout;
timeout.tv_usec = 0;
len = strlen(rcpt) + 1;
- return mi_wr_cmd(ctx->ctx_fd, &timeout, SMFIR_DELRCPT, rcpt, len);
+ return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_DELRCPT, rcpt, len);
}
/*
** SMFI_REPLACEBODY -- send a body chunk to the MTA
@@ -137,7 +189,7 @@ smfi_replacebody(ctx, bodyp, bodylen)
if (bodyp == NULL && bodylen > 0)
return MI_FAILURE;
- if (!mi_sendok(ctx, SMFIF_MODBODY))
+ if (!mi_sendok(ctx, SMFIF_CHGBODY))
return MI_FAILURE;
timeout.tv_sec = ctx->ctx_timeout;
timeout.tv_usec = 0;
@@ -148,7 +200,7 @@ smfi_replacebody(ctx, bodyp, bodylen)
{
len = (bodylen >= MILTER_CHUNK_SIZE) ? MILTER_CHUNK_SIZE :
bodylen;
- if ((r = mi_wr_cmd(ctx->ctx_fd, &timeout, SMFIR_REPLBODY,
+ if ((r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_REPLBODY,
(char *) (bodyp + off), len)) != MI_SUCCESS)
return r;
off += len;
@@ -302,10 +354,29 @@ smfi_getsymval(ctx, symname)
{
int i;
char **s;
+ char one[2];
+ char braces[4];
if (ctx == NULL || symname == NULL || *symname == '\0')
return NULL;
+ if (strlen(symname) == 3 && symname[0] == '{' && symname[2] == '}')
+ {
+ one[0] = symname[1];
+ one[1] = '\0';
+ }
+ else
+ one[0] = '\0';
+ if (strlen(symname) == 1)
+ {
+ braces[0] = '{';
+ braces[1] = *symname;
+ braces[2] = '}';
+ braces[3] = '\0';
+ }
+ else
+ braces[0] = '\0';
+
/* search backwards through the macro array */
for (i = MAX_MACROS_ENTRIES - 1 ; i >= 0; --i)
{
@@ -316,6 +387,10 @@ smfi_getsymval(ctx, symname)
{
if (strcmp(*s, symname) == 0)
return *++s;
+ if (one[0] != '\0' && strcmp(*s, one) == 0)
+ return *++s;
+ if (braces[0] != '\0' && strcmp(*s, braces) == 0)
+ return *++s;
++s; /* skip over macro value */
++s; /* points to next macro name */
}