diff options
Diffstat (limited to 'gnu/usr.sbin/sendmail/libmilter')
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/Makefile | 8 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/README | 69 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/comm.c | 38 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/engine.c | 91 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/handler.c | 7 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/libmilter.h | 27 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/listener.c | 184 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/main.c | 72 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/signal.c | 11 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/sm_gethost.c | 43 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/libmilter/smfi.c | 49 |
11 files changed, 395 insertions, 204 deletions
diff --git a/gnu/usr.sbin/sendmail/libmilter/Makefile b/gnu/usr.sbin/sendmail/libmilter/Makefile index 01400cccf1c..3e5a650668c 100644 --- a/gnu/usr.sbin/sendmail/libmilter/Makefile +++ b/gnu/usr.sbin/sendmail/libmilter/Makefile @@ -1,7 +1,9 @@ -# $OpenBSD: Makefile,v 1.2 2000/04/02 19:48:31 millert Exp $ +# $OpenBSD: Makefile,v 1.3 2001/09/11 19:02:49 millert Exp $ -LIB= libmilter -SRCS= main.c engine.c listener.c handler.c comm.c smfi.c signal.c sm_gethost.c +LIB= milter +SRCS= main.c engine.c listener.c handler.c comm.c smfi.c signal.c \ + sm_gethost.c +CPPFLAGS+= -pthread # This is not a library that gets installed so only build the .a version # In the future we may wish to install it to ease the use of external filters. diff --git a/gnu/usr.sbin/sendmail/libmilter/README b/gnu/usr.sbin/sendmail/libmilter/README index aacaadfa5bf..fed06305d78 100644 --- a/gnu/usr.sbin/sendmail/libmilter/README +++ b/gnu/usr.sbin/sendmail/libmilter/README @@ -9,17 +9,11 @@ through reference to a sample filter which is attached at the end of this file. It is necessary to first build libmilter.a, which can be done by issuing the './Build' command in SRCDIR/libmilter . -NOTE: Both libmilter and the callouts in sendmail are marked as an FFR (For -Future Release). If you intend to use them in 8.11.X, you must compiled -both libmilter and sendmail with -D_FFR_MILTER defined. You can do this by -adding the following to your devtools/Site/site.config.m4 file: +NOTE: If you intend to use filters in sendmail, you must compile sendmail +with -DMILTER defined. You can do this by adding the following to +your devtools/Site/site.config.m4 file: - dnl Milter - 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. + APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER') +-------------------+ | BUILDING A FILTER | @@ -29,14 +23,14 @@ The following command presumes that the sample code from the end of this README is saved to a file named 'sample.c' and built in the local platform- specific build subdirectory (SRCDIR/obj.*/libmilter). - cc -I../../sendmail -I../../include -o sample sample.c libmilter.a ../libsmutil/libsmutil.a -pthread + cc -I../../sendmail -I../../include -o sample sample.c libmilter.a ../libsm/libsm.a -pthread 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'. Depending on your OS you may need a library instead -of the option -pthread, e.g., -lpthread. +-lsocket -lnsl'. Depending on your operating system 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 @@ -83,7 +77,7 @@ Finally, you can override the default timeouts used by sendmail when talking to the filters using the T= equate. There are four fields inside of the T= equate: -Letter Meaning +Letter Meaning C Timeout for connecting to a filter (if 0, use system timeout) S Timeout for sending information from the MTA to a filter R Timeout for reading reply from the filter @@ -94,7 +88,7 @@ Note the separator between each is a ';' as a ',' already separates equates and therefore can't separate timeouts. The default values (if not set in the config) are: -T=C:0m;S:10s;R:10s;E:5m +T=C:5m;S:10s;R:10s;E:5m where 's' is seconds and 'm' is minutes. @@ -182,6 +176,30 @@ the logging level of sendmail can be raised with the LogLevel option. See the sendmail(8) manual page for more information. ++--------------+ +| REQUIREMENTS | ++--------------+ + +libmilter requires pthread support in the operating system. Moreover, it +requires that the library functions it uses are thread safe; which is true +for the operating systems libmilter has been developed and tested on. On +some operating systems this requires special compile time options (e.g., +not just -pthread). libmilter is currently known to work on (modulo problems +in the pthread support of some specific versions): + +FreeBSD 3.x, 4.x +SunOS 5.x (x >= 5) +AIX 4.3.x +HP UX 11.x +Linux (recent versions/distributions) + +libmilter is currently not supported on: + +IRIX 6.x +Ultrix + +Feedback about problems (and possible fixes) is welcome. + +--------------------------+ | SOURCE FOR SAMPLE FILTER | +--------------------------+ @@ -201,14 +219,11 @@ below to verify the functions are thread safe. #include "libmilter/mfapi.h" +#ifndef true typedef int bool; - -#ifndef FALSE -# define FALSE 0 -#endif /* ! FALSE*/ -#ifndef TRUE -# define TRUE 1 -#endif /* ! TRUE*/ +# define false 0 +# define true 1 +#endif /* ! true */ struct mlfiPriv { @@ -295,7 +310,7 @@ mlfi_body(ctx, bodyp, bodylen) if (fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp) <= 0) { /* write failed */ - (void) mlfi_cleanup(ctx, FALSE); + (void) mlfi_cleanup(ctx, false); return SMFIS_TEMPFAIL; } @@ -307,7 +322,7 @@ sfsistat mlfi_eom(ctx) SMFICTX *ctx; { - return mlfi_cleanup(ctx, TRUE); + return mlfi_cleanup(ctx, true); } sfsistat @@ -321,7 +336,7 @@ sfsistat mlfi_abort(ctx) SMFICTX *ctx; { - return mlfi_cleanup(ctx, FALSE); + return mlfi_cleanup(ctx, false); } sfsistat @@ -349,7 +364,7 @@ mlfi_cleanup(ctx, ok) { /* add a header to the message announcing our presence */ if (gethostname(host, sizeof host) < 0) - strlcpy(host, "localhost", sizeof host); + snprintf(host, sizeof host, "localhost"); p = strrchr(priv->mlfi_fname, '/'); if (p == NULL) p = priv->mlfi_fname; @@ -426,4 +441,4 @@ main(argc, argv) /* eof */ -$Revision: 1.7 $, Last updated $Date: 2001/08/01 01:01:40 $ +$Revision: 1.8 $, Last updated $Date: 2001/09/11 19:02:49 $ diff --git a/gnu/usr.sbin/sendmail/libmilter/comm.c b/gnu/usr.sbin/sendmail/libmilter/comm.c index 692ec2e84a4..4d8baaa9dd3 100644 --- a/gnu/usr.sbin/sendmail/libmilter/comm.c +++ b/gnu/usr.sbin/sendmail/libmilter/comm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,17 +8,16 @@ * */ -#ifndef lint -static char id[] = "@(#)$Sendmail: comm.c,v 8.30.4.6 2000/10/05 22:44:01 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: comm.c,v 8.43 2001/07/20 20:33:07 ca Exp $") -#if _FFR_MILTER #include "libmilter.h" +#include <sm/errstring.h> -#define FD_Z FD_ZERO(&readset); \ - FD_SET((u_int) sd, &readset); \ - FD_ZERO(&excset); \ - FD_SET((u_int) sd, &excset) +#define FD_Z FD_ZERO(&readset); \ + FD_SET((unsigned int) sd, &readset); \ + FD_ZERO(&excset); \ + FD_SET((unsigned int) sd, &excset) /* ** MI_RD_CMD -- read a command @@ -77,7 +76,7 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) { smi_log(SMI_LOG_ERR, "%s, mi_rd_cmd: read returned %d: %s", - name, len, strerror(errno)); + name, len, sm_errstring(errno)); *cmd = SMFIC_RECVERR; return NULL; } @@ -100,7 +99,7 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) { smi_log(SMI_LOG_ERR, "%s: mi_rd_cmd: select returned %d: %s", - name, ret, strerror(errno)); + name, ret, sm_errstring(errno)); *cmd = SMFIC_RECVERR; return NULL; } @@ -116,7 +115,11 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) *cmd = SMFIC_TOOBIG; return NULL; } +#if _FFR_ADD_NULL + buf = malloc(expl + 1); +#else /* _FFR_ADD_NULL */ buf = malloc(expl); +#endif /* _FFR_ADD_NULL */ if (buf == NULL) { *cmd = SMFIC_MALLOC; @@ -137,7 +140,7 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) { smi_log(SMI_LOG_ERR, "%s: mi_rd_cmd: read returned %d: %s", - name, len, strerror(errno)); + name, len, sm_errstring(errno)); ret = -1; break; } @@ -156,6 +159,10 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) if (len >= expl - i) { *rlen = expl; +#if _FFR_ADD_NULL + /* makes life simpler for common string routines */ + buf[expl] = '\0'; +#endif /* _FFR_ADD_NULL */ return buf; } i += len; @@ -175,7 +182,7 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) { smi_log(SMI_LOG_ERR, "%s: mi_rd_cmd: select returned %d: %s", - name, ret, strerror(save_errno)); + name, ret, sm_errstring(save_errno)); *cmd = SMFIC_RECVERR; return NULL; } @@ -222,7 +229,7 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) do { FD_ZERO(&wrtset); - FD_SET((u_int) sd, &wrtset); + FD_SET((unsigned int) sd, &wrtset); if ((ret = select(sd + 1, NULL, &wrtset, NULL, timeout)) == 0) return MI_FAILURE; } while (ret < 0 && errno == EINTR); @@ -248,7 +255,7 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) do { FD_ZERO(&wrtset); - FD_SET((u_int) sd, &wrtset); + FD_SET((unsigned int) sd, &wrtset); if ((ret = select(sd + 1, NULL, &wrtset, NULL, timeout)) == 0) return MI_FAILURE; } while (ret < 0 && errno == EINTR); @@ -264,4 +271,3 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) } return MI_SUCCESS; } -#endif /* _FFR_MILTER */ diff --git a/gnu/usr.sbin/sendmail/libmilter/engine.c b/gnu/usr.sbin/sendmail/libmilter/engine.c index 3ecbe6944f0..4b8cb008644 100644 --- a/gnu/usr.sbin/sendmail/libmilter/engine.c +++ b/gnu/usr.sbin/sendmail/libmilter/engine.c @@ -8,13 +8,10 @@ * */ -#ifndef lint -static char id[] = "@(#)$Sendmail: engine.c,v 8.67.4.17 2001/01/22 19:00:16 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: engine.c,v 8.94 2001/08/14 12:49:45 ca Exp $") -#if _FFR_MILTER #include "libmilter.h" -#include "sendmail/useful.h" #if NETINET || NETINET6 # include <arpa/inet.h> @@ -118,13 +115,16 @@ static int dec_arg2 __P((char *, size_t, char **, char **)); ** is set in the NX_* value ** this function is coded in trans_ok(), see below. */ + #define MASK(x) (0x0001 << (x)) /* generate a bit "mask" for a state */ #define NX_INIT (MASK(ST_OPTS)) #define NX_OPTS (MASK(ST_CONN)) #define NX_CONN (MASK(ST_HELO) | MASK(ST_MAIL)) #define NX_HELO (MASK(ST_HELO) | MASK(ST_MAIL)) #define NX_MAIL (MASK(ST_RCPT) | MASK(ST_ABRT)) -#define NX_RCPT (MASK(ST_HDRS) | MASK(ST_EOHS) | MASK(ST_RCPT) | MASK(ST_ABRT)) +#define NX_RCPT (MASK(ST_HDRS) | MASK(ST_EOHS) | \ + MASK(ST_BODY) | MASK(ST_ENDM) | \ + MASK(ST_RCPT) | MASK(ST_ABRT)) #define NX_HDRS (MASK(ST_EOHS) | MASK(ST_HDRS) | MASK(ST_ABRT)) #define NX_EOHS (MASK(ST_BODY) | MASK(ST_ENDM) | MASK(ST_ABRT)) #define NX_BODY (MASK(ST_ENDM) | MASK(ST_BODY) | MASK(ST_ABRT)) @@ -217,7 +217,7 @@ mi_engine(ctx) if (mi_stop() == MILTER_ABRT) { if (ctx->ctx_dbg > 3) - dprintf("[%d] milter_abort\n", + sm_dprintf("[%d] milter_abort\n", (int) ctx->ctx_id); ret = MI_FAILURE; break; @@ -227,7 +227,7 @@ mi_engine(ctx) cmd < SMFIC_VALIDCMD) { if (ctx->ctx_dbg > 5) - dprintf("[%d] mi_engine: mi_rd_cmd error (%x)\n", + sm_dprintf("[%d] mi_engine: mi_rd_cmd error (%x)\n", (int) ctx->ctx_id, (int) cmd); /* @@ -240,7 +240,7 @@ mi_engine(ctx) break; } if (ctx->ctx_dbg > 4) - dprintf("[%d] got cmd '%c' len %d\n", + sm_dprintf("[%d] got cmd '%c' len %d\n", (int) ctx->ctx_id, cmd, len); for (i = 0; i < ncmds; i++) { @@ -251,7 +251,7 @@ mi_engine(ctx) { /* unknown command */ if (ctx->ctx_dbg > 1) - dprintf("[%d] cmd '%c' unknown\n", + sm_dprintf("[%d] cmd '%c' unknown\n", (int) ctx->ctx_id, cmd); ret = MI_FAILURE; break; @@ -260,7 +260,7 @@ mi_engine(ctx) { /* stop for now */ if (ctx->ctx_dbg > 1) - dprintf("[%d] cmd '%c' not impl\n", + sm_dprintf("[%d] cmd '%c' not impl\n", (int) ctx->ctx_id, cmd); ret = MI_FAILURE; break; @@ -269,14 +269,14 @@ mi_engine(ctx) /* is new state ok? */ newstate = cmds[i].cm_next; if (ctx->ctx_dbg > 5) - dprintf("[%d] cur %x new %x nextmask %x\n", + sm_dprintf("[%d] cur %x new %x nextmask %x\n", (int) ctx->ctx_id, curstate, newstate, next_states[curstate]); if (newstate != ST_NONE && !trans_ok(curstate, newstate)) { if (ctx->ctx_dbg > 1) - dprintf("[%d] abort: cur %d (%x) new %d (%x) next %x\n", + sm_dprintf("[%d] abort: cur %d (%x) new %d (%x) next %x\n", (int) ctx->ctx_id, curstate, MASK(curstate), newstate, MASK(newstate), @@ -337,7 +337,7 @@ mi_engine(ctx) else if (r == _SMFIS_ABORT) { if (ctx->ctx_dbg > 5) - dprintf("[%d] function returned abort\n", + sm_dprintf("[%d] function returned abort\n", (int) ctx->ctx_id); ret = MI_FAILURE; break; @@ -560,7 +560,7 @@ st_connectinfo(g) size_t l; size_t i; char *s, family; - u_short port = 0; + unsigned short port = 0; _SOCK_ADDR sockaddr; sfsistat (*fi_connect) __P((SMFICTX *, char *, _SOCK_ADDR *)); @@ -617,11 +617,11 @@ st_connectinfo(g) # if NETINET6 if (family == SMFIA_INET6) { - if (inet_pton(AF_INET6, s + i, - &sockaddr.sin6.sin6_addr) != 1) + if (mi_inet_pton(AF_INET6, s + i, + &sockaddr.sin6.sin6_addr) != 1) { smi_log(SMI_LOG_ERR, - "%s: connect[%d]: inet_pton failed", + "%s: connect[%d]: mi_inet_pton failed", g->a_ctx->ctx_smfi->xxfi_name, (int) g->a_ctx->ctx_id); return _SMFIS_ABORT; @@ -635,7 +635,7 @@ st_connectinfo(g) # if NETUNIX if (family == SMFIA_UNIX) { - if (strlcpy(sockaddr.sunix.sun_path, s + i, + if (sm_strlcpy(sockaddr.sunix.sun_path, s + i, sizeof sockaddr.sunix.sun_path) >= sizeof sockaddr.sunix.sun_path) { @@ -734,21 +734,21 @@ st_header(g) return _SMFIS_ABORT; } -#define ARGV_FCT(lf, rf, idx) \ - char **argv; \ - sfsistat (*lf) __P((SMFICTX *, char **)); \ - int r; \ - \ - if (g == NULL) \ - return _SMFIS_ABORT; \ - mi_clr_macros(g->a_ctx, g->a_idx + 1); \ - if (g->a_ctx->ctx_smfi == NULL || \ - (lf = g->a_ctx->ctx_smfi->rf) == NULL) \ - return SMFIS_CONTINUE; \ +#define ARGV_FCT(lf, rf, idx) \ + char **argv; \ + sfsistat (*lf) __P((SMFICTX *, char **)); \ + int r; \ + \ + if (g == NULL) \ + return _SMFIS_ABORT; \ + mi_clr_macros(g->a_ctx, g->a_idx + 1); \ + if (g->a_ctx->ctx_smfi == NULL || \ + (lf = g->a_ctx->ctx_smfi->rf) == NULL) \ + return SMFIS_CONTINUE; \ if ((argv = dec_argv(g->a_buf, g->a_len)) == NULL) \ - return _SMFIS_ABORT; \ - r = (*lf)(g->a_ctx, argv); \ - free(argv); \ + return _SMFIS_ABORT; \ + r = (*lf)(g->a_ctx, argv); \ + free(argv); \ return r; /* @@ -863,13 +863,14 @@ static int st_bodychunk(g) genarg *g; { - sfsistat (*fi_body) __P((SMFICTX *, u_char *, size_t)); + sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); if (g == NULL) return _SMFIS_ABORT; if (g->a_ctx->ctx_smfi != NULL && (fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL) - return (*fi_body)(g->a_ctx, (u_char *)g->a_buf, g->a_len); + return (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf, + g->a_len); return SMFIS_CONTINUE; } /* @@ -890,7 +891,7 @@ st_bodyend(g) genarg *g; { sfsistat r; - sfsistat (*fi_body) __P((SMFICTX *, u_char *, size_t)); + sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); sfsistat (*fi_eom) __P((SMFICTX *)); if (g == NULL) @@ -907,7 +908,8 @@ st_bodyend(g) timeout.tv_sec = g->a_ctx->ctx_timeout; timeout.tv_usec = 0; sd = g->a_ctx->ctx_sd; - r = (*fi_body)(g->a_ctx, (u_char *)g->a_buf, g->a_len); + r = (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf, + g->a_len); if (r != SMFIS_CONTINUE && sendreply(r, sd, &timeout, g->a_ctx) != MI_SUCCESS) return _SMFIS_ABORT; @@ -963,13 +965,14 @@ trans_ok(old, new) { /* is this state transition allowed? */ if ((MASK(new) & next_states[s]) != 0) - return TRUE; + return true; /* ** no: try next state; ** this works since the relevant states are ordered ** strict sequentially */ + n = s + 1; /* @@ -977,12 +980,13 @@ trans_ok(old, new) ** see fix_stm() which sets this bit for those ** states which the filter program is not interested in */ + if (bitset(NX_SKIP, next_states[n])) s = n; else - return FALSE; + return false; } while (s <= ST_LAST); - return FALSE; + return false; } /* ** FIX_STM -- add "skip" bits to the state transition table @@ -1001,7 +1005,7 @@ static void fix_stm(ctx) SMFICTX_PTR ctx; { - u_long fl; + unsigned long fl; if (ctx == NULL || ctx->ctx_smfi == NULL) return; @@ -1111,9 +1115,8 @@ mi_sendok(ctx, flag) int flag; { if (ctx == NULL || ctx->ctx_smfi == NULL) - return FALSE; + return false; if (flag != 0 && !bitset(flag, ctx->ctx_smfi->xxfi_flags)) - return FALSE; + return false; return ctx->ctx_state == ST_ENDM; } -#endif /* _FFR_MILTER */ diff --git a/gnu/usr.sbin/sendmail/libmilter/handler.c b/gnu/usr.sbin/sendmail/libmilter/handler.c index 3b5102fe031..f165befc2a2 100644 --- a/gnu/usr.sbin/sendmail/libmilter/handler.c +++ b/gnu/usr.sbin/sendmail/libmilter/handler.c @@ -8,11 +8,9 @@ * */ -#ifndef lint -static char id[] = "@(#)$Sendmail: handler.c,v 8.19.4.3 2000/12/29 19:45:39 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: handler.c,v 8.24 2000/12/29 19:45:55 gshapiro Exp $") -#if _FFR_MILTER #include "libmilter.h" @@ -64,4 +62,3 @@ mi_handle_session(ctx) ctx = NULL; return ret; } -#endif /* _FFR_MILTER */ diff --git a/gnu/usr.sbin/sendmail/libmilter/libmilter.h b/gnu/usr.sbin/sendmail/libmilter/libmilter.h index d826f972368..fe90c563e06 100644 --- a/gnu/usr.sbin/sendmail/libmilter/libmilter.h +++ b/gnu/usr.sbin/sendmail/libmilter/libmilter.h @@ -13,12 +13,13 @@ #ifndef _LIBMILTER_H # define _LIBMILTER_H 1 + +#include <sm/gen.h> + #ifdef _DEFINE # define EXTERN # define INIT(x) = x -# ifndef lint -static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3.6.16 2001/06/07 23:21:35 geir Exp $"; -# endif /* ! lint */ +SM_IDSTR(MilterlId, "@(#)$Sendmail: libmilter.h,v 8.26 2001/07/20 02:48:37 gshapiro Exp $") #else /* _DEFINE */ # define EXTERN extern # define INIT(x) @@ -31,11 +32,6 @@ static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3.6.16 2001/06/07 23:2 #include "libmilter/milter.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)) @@ -61,16 +57,19 @@ typedef pthread_mutex_t smutex_t; #define MI_TIMEOUT 7210 /* 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 */ +#ifndef MI_SOMAXCONN +# if SOMAXCONN > 20 +# define MI_SOMAXCONN SOMAXCONN +# else /* SOMAXCONN */ +# define MI_SOMAXCONN 20 +# endif /* SOMAXCONN */ +#endif /* ! MI_SOMAXCONN */ /* maximum number of repeated failures in mi_listener() */ #define MAX_FAILS_M 16 /* malloc() */ #define MAX_FAILS_T 16 /* thread creation */ #define MAX_FAILS_A 16 /* accept() */ +#define MAX_FAILS_S 16 /* select() */ /* internal "commands", i.e., error codes */ #define SMFIC_TIMEOUT ((char) 1) /* timeout */ @@ -84,6 +83,7 @@ typedef pthread_mutex_t smutex_t; /* hack */ #define smi_log syslog +#define sm_dprintf printf #define milter_ret int #define SMI_LOG_ERR LOG_ERR #define SMI_LOG_FATAL LOG_ERR @@ -106,6 +106,7 @@ 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 int mi_inet_pton __P((int, const char *, void *)); extern void mi_closener __P((void)); /* communication functions */ diff --git a/gnu/usr.sbin/sendmail/libmilter/listener.c b/gnu/usr.sbin/sendmail/libmilter/listener.c index f197ff01cbc..656c82ba6b6 100644 --- a/gnu/usr.sbin/sendmail/libmilter/listener.c +++ b/gnu/usr.sbin/sendmail/libmilter/listener.c @@ -8,21 +8,23 @@ * */ -#ifndef lint -static char id[] = "@(#)$Sendmail: listener.c,v 8.38.2.1.2.22 2001/05/16 17:15:58 ca Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: listener.c,v 8.72 2001/06/28 20:59:06 ca Exp $") -#if _FFR_MILTER /* ** listener.c -- threaded network listener */ #include "libmilter.h" +#include <sm/errstring.h> # if NETINET || NETINET6 # include <arpa/inet.h> # endif /* NETINET || NETINET6 */ + +static smutex_t L_Mutex; + /* ** MI_MILTEROPEN -- setup socket to listen on ** @@ -35,8 +37,15 @@ static char id[] = "@(#)$Sendmail: listener.c,v 8.38.2.1.2.22 2001/05/16 17:15:5 ** ** Returns: ** socket upon success, error code otherwise. +** +** Side effect: +** sets sockpath if UNIX socket. */ +#if NETUNIX +static char *sockpath = NULL; +#endif /* NETUNIX */ + static socket_t mi_milteropen(conn, backlog, socksize, family, name) char *conn; @@ -47,6 +56,7 @@ mi_milteropen(conn, backlog, socksize, family, name) { socket_t sock; int sockopt = 1; + size_t len = -1; char *p; char *colon; char *at; @@ -157,15 +167,16 @@ mi_milteropen(conn, backlog, socksize, family, name) # endif /* 0 */ at = colon; - if (strlcpy(addr.sunix.sun_path, colon, - sizeof addr.sunix.sun_path) >= - sizeof addr.sunix.sun_path) + len = strlen(colon) + 1; + if (len >= sizeof addr.sunix.sun_path) { errno = EINVAL; smi_log(SMI_LOG_ERR, "%s: UNIX socket name %s too long", name, colon); return INVALID_SOCKET; } + (void) sm_strlcpy(addr.sunix.sun_path, colon, + sizeof addr.sunix.sun_path); # if 0 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, S_IRUSR|S_IWUSR, NULL); @@ -179,7 +190,6 @@ mi_milteropen(conn, backlog, socksize, family, name) return INVALID_SOCKET; } # endif /* 0 */ - } #endif /* NETUNIX */ @@ -196,7 +206,7 @@ mi_milteropen(conn, backlog, socksize, family, name) # endif /* NETINET6 */ ) { - u_short port; + unsigned short port; /* Parse port@host */ at = strchr(colon, '@'); @@ -221,7 +231,7 @@ mi_milteropen(conn, backlog, socksize, family, name) *at = '\0'; if (isascii(*colon) && isdigit(*colon)) - port = htons((u_short) atoi(colon)); + port = htons((unsigned short) atoi(colon)); else { # ifdef NO_GETSERVBYNAME @@ -252,7 +262,7 @@ mi_milteropen(conn, backlog, socksize, family, name) end = strchr(at, ']'); if (end != NULL) { - bool found = FALSE; + bool found = false; # if NETINET unsigned long hid = INADDR_NONE; # endif /* NETINET */ @@ -263,23 +273,22 @@ mi_milteropen(conn, backlog, socksize, family, name) *end = '\0'; # if NETINET if (addr.sa.sa_family == AF_INET && - (hid = inet_addr(&at[1])) != - INADDR_NONE) + (hid = inet_addr(&at[1])) != INADDR_NONE) { addr.sin.sin_addr.s_addr = hid; addr.sin.sin_port = port; - found = TRUE; + found = true; } # endif /* NETINET */ # if NETINET6 (void) memset(&hid6, '\0', sizeof hid6); if (addr.sa.sa_family == AF_INET6 && - inet_pton(AF_INET6, &at[1], - &hid6.sin6_addr) == 1) + mi_inet_pton(AF_INET6, &at[1], + &hid6.sin6_addr) == 1) { addr.sin6.sin6_addr = hid6.sin6_addr; addr.sin6.sin6_port = port; - found = TRUE; + found = true; } # endif /* NETINET6 */ *end = ']'; @@ -338,9 +347,9 @@ mi_milteropen(conn, backlog, socksize, family, name) name, at, hp->h_addrtype); return INVALID_SOCKET; } -# if _FFR_FREEHOSTENT && NETINET6 +# if NETINET6 freehostent(hp); -# endif /* _FFR_FREEHOSTENT && NETINET6 */ +# endif /* NETINET6 */ } } else @@ -367,7 +376,7 @@ mi_milteropen(conn, backlog, socksize, family, name) { smi_log(SMI_LOG_ERR, "%s: Unable to create new socket: %s", - name, strerror(errno)); + name, sm_errstring(errno)); return INVALID_SOCKET; } @@ -375,7 +384,8 @@ mi_milteropen(conn, backlog, socksize, family, name) sizeof(sockopt)) == -1) { smi_log(SMI_LOG_ERR, - "%s: Unable to setsockopt: %s", name, strerror(errno)); + "%s: Unable to setsockopt: %s", name, + sm_errstring(errno)); (void) close(sock); return INVALID_SOCKET; } @@ -384,7 +394,7 @@ mi_milteropen(conn, backlog, socksize, family, name) { smi_log(SMI_LOG_ERR, "%s: Unable to bind to port %s: %s", - name, conn, strerror(errno)); + name, conn, sm_errstring(errno)); (void) close(sock); return INVALID_SOCKET; } @@ -392,10 +402,32 @@ mi_milteropen(conn, backlog, socksize, family, name) if (listen(sock, backlog) < 0) { smi_log(SMI_LOG_ERR, - "%s: listen call failed: %s", name, strerror(errno)); + "%s: listen call failed: %s", name, + sm_errstring(errno)); (void) close(sock); return INVALID_SOCKET; } + +#if NETUNIX + if (addr.sa.sa_family == AF_UNIX && len > 0) + { + /* + ** Set global variable sockpath so the UNIX socket can be + ** unlink()ed at exit. + */ + sockpath = (char *) malloc(len); + if (sockpath != NULL) + (void) sm_strlcpy(sockpath, colon, len); + else + { + smi_log(SMI_LOG_ERR, + "%s: can't malloc(%d) for sockpath: %s", + name, len, sm_errstring(errno)); + (void) close(sock); + return INVALID_SOCKET; + } + } +#endif /* NETUNIX */ *family = addr.sa.sa_family; return sock; } @@ -418,11 +450,12 @@ mi_thread_handle_wrapper(arg) static socket_t listenfd = INVALID_SOCKET; -static smutex_t L_Mutex; - /* ** MI_CLOSENER -- close listen socket ** +** NOTE: It is assumed that this function is called from a +** function that has a mutex lock (currently mi_stop_milters()). +** ** Parameters: ** none. ** @@ -436,8 +469,42 @@ mi_closener() (void) smutex_lock(&L_Mutex); if (ValidSocket(listenfd)) { +#if NETUNIX + bool removable = false; + struct stat sockinfo; + struct stat fileinfo; + + if (sockpath != NULL && + fstat(listenfd, &sockinfo) == 0 && + (S_ISFIFO(sockinfo.st_mode) +# ifdef S_ISSOCK + || !S_ISSOCK(sockinfo.st_mode) +# endif /* S_ISSOCK */ + )) + removable = true; +#endif /* NETUNIX */ + (void) close(listenfd); listenfd = INVALID_SOCKET; + +#if NETUNIX + /* XXX sleep() some time before doing this? */ + if (sockpath != NULL) + { + if (removable && + stat(sockpath, &fileinfo) == 0 && + fileinfo.st_dev == sockinfo.st_dev && + fileinfo.st_ino == sockinfo.st_ino && + (S_ISFIFO(fileinfo.st_mode) +# ifdef S_ISSOCK + || S_ISSOCK(fileinfo.st_mode) +# endif /* S_ISSOCK */ + )) + (void) unlink(sockpath); + free(sockpath); + sockpath = NULL; + } +#endif /* NETUNIX */ } (void) smutex_unlock(&L_Mutex); } @@ -460,7 +527,7 @@ mi_closener() ** MI_FAILURE -- Network initialization failed. */ -# if BROKEN_PTHREAD_SLEEP +#if BROKEN_PTHREAD_SLEEP /* ** Solaris 2.6, perhaps others, gets an internal threads library panic @@ -480,7 +547,7 @@ mi_closener() ** 0 */ -# define MI_SLEEP(s) \ +# define MI_SLEEP(s) \ { \ int rs = 0; \ struct timeval st; \ @@ -496,9 +563,9 @@ mi_closener() rs, errno); \ } \ } -# else /* BROKEN_PTHREAD_SLEEP */ -# define MI_SLEEP(s) sleep((s)) -# endif /* BROKEN_PTHREAD_SLEEP */ +#else /* BROKEN_PTHREAD_SLEEP */ +# define MI_SLEEP(s) sleep((s)) +#endif /* BROKEN_PTHREAD_SLEEP */ int mi_listener(conn, dbg, smfi, timeout, backlog) @@ -513,9 +580,10 @@ mi_listener(conn, dbg, smfi, timeout, backlog) int sockopt = 1; int r; int ret = MI_SUCCESS; - int mcnt = 0; - int tcnt = 0; - int acnt = 0; + int mcnt = 0; /* error count for malloc() failures */ + int tcnt = 0; /* error count for thread_create() failures */ + int acnt = 0; /* error count for accept() failures */ + int scnt = 0; /* error count for select() failures */ int save_errno = 0; sthread_t thread_id; _SOCK_ADDR cliaddr; @@ -564,8 +632,8 @@ mi_listener(conn, dbg, smfi, timeout, backlog) /* select on interface ports */ FD_ZERO(&readset); FD_ZERO(&excset); - FD_SET((u_int) listenfd, &readset); - FD_SET((u_int) listenfd, &excset); + FD_SET((unsigned int) listenfd, &readset); + FD_SET((unsigned int) listenfd, &excset); chktime.tv_sec = MI_CHK_TIME; chktime.tv_usec = 0; r = select(listenfd + 1, &readset, NULL, &excset, &chktime); @@ -580,16 +648,30 @@ mi_listener(conn, dbg, smfi, timeout, backlog) (void) smutex_unlock(&L_Mutex); if (save_errno == EINTR) continue; - ret = MI_FAILURE; - break; + scnt++; + smi_log(SMI_LOG_ERR, + "%s: select() failed (%s), %s", + smfi->xxfi_name, sm_errstring(save_errno), + scnt >= MAX_FAILS_S ? "abort" : "try again"); + MI_SLEEP(scnt); + if (scnt >= MAX_FAILS_S) + { + ret = MI_FAILURE; + break; + } + continue; } if (!FD_ISSET(listenfd, &readset)) { /* some error: just stop for now... */ ret = MI_FAILURE; (void) smutex_unlock(&L_Mutex); + smi_log(SMI_LOG_ERR, + "%s: select() returned exception for socket, abort", + smfi->xxfi_name); break; } + scnt = 0; /* reset error counter for select() */ memset(&cliaddr, '\0', sizeof cliaddr); connfd = accept(listenfd, (struct sockaddr *) &cliaddr, @@ -617,12 +699,13 @@ mi_listener(conn, dbg, smfi, timeout, backlog) if (!ValidSocket(connfd)) { - smi_log(SMI_LOG_ERR, - "%s: accept() returned invalid socket (%s)", - smfi->xxfi_name, strerror(save_errno)); if (save_errno == EINTR) continue; acnt++; + smi_log(SMI_LOG_ERR, + "%s: accept() returned invalid socket (%s), %s", + smfi->xxfi_name, sm_errstring(save_errno), + acnt >= MAX_FAILS_A ? "abort" : "try again"); MI_SLEEP(acnt); if (acnt >= MAX_FAILS_A) { @@ -631,20 +714,22 @@ mi_listener(conn, dbg, smfi, timeout, backlog) } continue; } + acnt = 0; /* reset error counter for accept() */ if (setsockopt(connfd, SOL_SOCKET, SO_KEEPALIVE, (void *) &sockopt, sizeof sockopt) < 0) { - smi_log(SMI_LOG_WARN, "%s: setsockopt() failed", - smfi->xxfi_name); + smi_log(SMI_LOG_WARN, "%s: setsockopt() failed (%s)", + smfi->xxfi_name, sm_errstring(errno)); /* XXX: continue? */ } if ((ctx = (SMFICTX_PTR) malloc(sizeof *ctx)) == NULL) { (void) close(connfd); - smi_log(SMI_LOG_ERR, "%s: malloc(ctx) failed", - smfi->xxfi_name); mcnt++; + smi_log(SMI_LOG_ERR, "%s: malloc(ctx) failed (%s), %s", + smfi->xxfi_name, sm_errstring(save_errno), + mcnt >= MAX_FAILS_M ? "abort" : "try again"); MI_SLEEP(mcnt); if (mcnt >= MAX_FAILS_M) { @@ -653,8 +738,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) } continue; } - mcnt = 0; - acnt = 0; + mcnt = 0; /* reset error counter for malloc() */ memset(ctx, '\0', sizeof *ctx); ctx->ctx_sd = connfd; ctx->ctx_dbg = dbg; @@ -685,10 +769,11 @@ mi_listener(conn, dbg, smfi, timeout, backlog) mi_thread_handle_wrapper, (void *) ctx)) != 0) { - smi_log(SMI_LOG_ERR, - "%s: thread_create() failed: %d", - smfi->xxfi_name, r); tcnt++; + smi_log(SMI_LOG_ERR, + "%s: thread_create() failed: %d, %s", + smfi->xxfi_name, r, + tcnt >= MAX_FAILS_T ? "abort" : "try again"); MI_SLEEP(tcnt); (void) close(connfd); free(ctx); @@ -708,4 +793,3 @@ mi_listener(conn, dbg, smfi, timeout, backlog) (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 521f149fca1..2fbe35334e3 100644 --- a/gnu/usr.sbin/sendmail/libmilter/main.c +++ b/gnu/usr.sbin/sendmail/libmilter/main.c @@ -8,11 +8,9 @@ * */ -#ifndef lint -static char id[] = "@(#)$Sendmail: main.c,v 8.34.4.11 2001/05/07 22:06:37 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: main.c,v 8.49 2001/04/21 01:18:16 ca Exp $") -#if _FFR_MILTER #define _DEFINE 1 #include "libmilter.h" #include <fcntl.h> @@ -51,7 +49,7 @@ smfi_register(smfilter) smfi->xxfi_name = (char *) malloc(len); if (smfi->xxfi_name == NULL) return MI_FAILURE; - (void) strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len); + (void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len); /* compare milter version with hard coded version */ if (smfi->xxfi_version != SMFI_VERSION) @@ -61,6 +59,9 @@ smfi_register(smfilter) "%s: smfi_register: version mismatch application: %d != milter: %d", smfi->xxfi_name, smfi->xxfi_version, (int) SMFI_VERSION); + + /* XXX how about smfi? */ + free(smfi->xxfi_name); return MI_FAILURE; } @@ -84,11 +85,26 @@ smfi_stop() return MI_SUCCESS; } +/* +** default values for some variables. +** Most of these can be changed with the functions below. +*/ + static int dbg = 0; static char *conn = NULL; static int timeout = MI_TIMEOUT; static int backlog= MI_SOMAXCONN; +/* +** SMFI_SETDBG -- set debug level. +** +** Parameters: +** odbg -- new debug level. +** +** Returns: +** MI_SUCCESS +*/ + int smfi_setdbg(odbg) int odbg; @@ -97,6 +113,16 @@ smfi_setdbg(odbg) return MI_SUCCESS; } +/* +** SMFI_SETTIMEOUT -- set timeout (for read/write). +** +** Parameters: +** otimeout -- new timeout. +** +** Returns: +** MI_SUCCESS +*/ + int smfi_settimeout(otimeout) int otimeout; @@ -105,6 +131,16 @@ smfi_settimeout(otimeout) return MI_SUCCESS; } +/* +** SMFI_SETCONN -- set connection information (socket description) +** +** Parameters: +** oconn -- new connection information. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + int smfi_setconn(oconn) char *oconn; @@ -116,11 +152,21 @@ smfi_setconn(oconn) l = strlen(oconn) + 1; if ((conn = (char *) malloc(l)) == NULL) return MI_FAILURE; - if (strlcpy(conn, oconn, l) >= l) + if (sm_strlcpy(conn, oconn, l) >= l) return MI_FAILURE; return MI_SUCCESS; } +/* +** SMFI_SETBACKLOG -- set backlog +** +** Parameters: +** odbg -- new backlog. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + int smfi_setbacklog(obacklog) int obacklog; @@ -131,12 +177,20 @@ smfi_setbacklog(obacklog) return MI_SUCCESS; } +/* +** SMFI_MAIN -- setup milter connnection and start listener. +** +** Parameters: +** none. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ int smfi_main() { - - signal(SIGPIPE, SIG_IGN); + (void) signal(SIGPIPE, SIG_IGN); if (conn == NULL) { smi_log(SMI_LOG_FATAL, "%s: missing connection information", @@ -153,11 +207,9 @@ smfi_main() return MI_FAILURE; } - /* Startup the listener */ if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS) return MI_FAILURE; 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 19a79be2560..b41f8f8fcb5 100644 --- a/gnu/usr.sbin/sendmail/libmilter/signal.c +++ b/gnu/usr.sbin/sendmail/libmilter/signal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,11 +8,9 @@ * */ -#ifndef lint -static char id[] = "@(#)$Sendmail: signal.c,v 8.10.4.8 2000/11/20 21:15:37 ca Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: signal.c,v 8.24 2001/01/24 00:27:35 ca Exp $") -#if _FFR_MILTER #include "libmilter.h" /* @@ -100,7 +98,7 @@ mi_signal_thread(name) sigaddset(&set, SIGINT); errs = 0; - while (TRUE) + while (true) { sig = 0; #ifdef SOLARIS @@ -212,4 +210,3 @@ mi_control_startup(name) } return MI_SUCCESS; } -#endif /* _FFR_MILTER */ diff --git a/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c b/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c index 57b102f236d..a0337b1f73b 100644 --- a/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c +++ b/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c @@ -8,11 +8,9 @@ * */ -#ifndef lint -static char id[] = "@(#)$Sendmail: sm_gethost.c,v 8.7.8.11 2001/07/21 00:10:23 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: sm_gethost.c,v 8.23 2001/07/21 00:05:06 gshapiro Exp $") -#if _FFR_MILTER #include <sendmail.h> #if NETINET || NETINET6 # include <arpa/inet.h> @@ -48,7 +46,7 @@ getipnodebyname(name, family, flags, err) int flags; int *err; { - bool resv6 = TRUE; + bool resv6 = true; struct hostent *h; if (family == AF_INET6) @@ -59,13 +57,12 @@ getipnodebyname(name, family, flags, err) } SM_SET_H_ERRNO(0); h = gethostbyname(name); - *err = h_errno; if (family == AF_INET6 && !resv6) _res.options &= ~RES_USE_INET6; + *err = h_errno; return h; } -# if _FFR_FREEHOSTENT void freehostent(h) struct hostent *h; @@ -77,7 +74,6 @@ freehostent(h) return; } -# endif /* _FFR_FREEHOSTENT */ #endif /* NEEDSGETIPNODE && NETINET6 */ struct hostent * @@ -117,4 +113,33 @@ mi_gethostbyname(name, family) #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */ return h; } -#endif /* _FFR_MILTER */ + +#if NETINET6 +/* +** MI_INET_PTON -- convert printed form to network address. +** +** Wrapper for inet_pton() which handles IPv6: labels. +** +** Parameters: +** family -- address family +** src -- string +** dst -- destination address structure +** +** Returns: +** 1 if the address was valid +** 0 if the address wasn't parseable +** -1 if error +*/ + +int +mi_inet_pton(family, src, dst) + int family; + const char *src; + void *dst; +{ + if (family == AF_INET6 && + strncasecmp(src, "IPv6:", 5) == 0) + src += 5; + return inet_pton(family, src, dst); +} +#endif /* NETINET6 */ diff --git a/gnu/usr.sbin/sendmail/libmilter/smfi.c b/gnu/usr.sbin/sendmail/libmilter/smfi.c index 5297524e5fd..82b3d4cf638 100644 --- a/gnu/usr.sbin/sendmail/libmilter/smfi.c +++ b/gnu/usr.sbin/sendmail/libmilter/smfi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,13 +8,10 @@ * */ -#ifndef lint -static char id[] = "@(#)$Sendmail: smfi.c,v 8.28.4.6 2000/06/28 23:48:56 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: smfi.c,v 8.42 2001/08/27 18:09:16 gshapiro Exp $") -#if _FFR_MILTER #include "libmilter.h" -#include "sendmail/useful.h" /* ** SMFI_ADDHEADER -- send a new header to the MTA @@ -181,13 +178,14 @@ smfi_delrcpt(ctx, rcpt) int smfi_replacebody(ctx, bodyp, bodylen) SMFICTX *ctx; - u_char *bodyp; + unsigned char *bodyp; int bodylen; { int len, off, r; struct timeval timeout; - if (bodyp == NULL && bodylen > 0) + if (bodylen < 0 || + (bodyp == NULL && bodylen > 0)) return MI_FAILURE; if (!mi_sendok(ctx, SMFIF_CHGBODY)) return MI_FAILURE; @@ -267,29 +265,41 @@ smfi_setreply(ctx, rcode, xcode, message) char *xcode; char *message; { - size_t len, l1, l2, l3; + size_t len; char *buf; if (rcode == NULL || ctx == NULL) return MI_FAILURE; - l1 = strlen(rcode) + 1; - if (l1 != 4) + + /* ### <sp> \0 */ + len = strlen(rcode) + 2; + if (len != 5) return MI_FAILURE; if ((rcode[0] != '4' && rcode[0] != '5') || !isascii(rcode[1]) || !isdigit(rcode[1]) || !isascii(rcode[2]) || !isdigit(rcode[2])) return MI_FAILURE; - l2 = xcode == NULL ? 1 : strlen(xcode) + 1; - if (xcode != NULL && !myisenhsc(xcode, '\0')) - return MI_FAILURE; - l3 = message == NULL ? 1 : strlen(message) + 1; - len = l1 + l2 + l3; + if (xcode != NULL) + len += strlen(xcode) + 1; + if (message != NULL) + len += strlen(message) + 1; buf = malloc(len); if (buf == NULL) return MI_FAILURE; /* oops */ - (void) snprintf(buf, len, "%s %s %s", rcode, - xcode == NULL ? "" : xcode, - message == NULL ? "" : message); + (void) sm_strlcpy(buf, rcode, len); + (void) sm_strlcat(buf, " ", len); + if (xcode != NULL) + { + if (!myisenhsc(xcode, '\0')) + return MI_FAILURE; + (void) sm_strlcat(buf, xcode, len); + } + if (message != NULL) + { + if (xcode != NULL) + (void) sm_strlcat(buf, " ", len); + (void) sm_strlcat(buf, message, len); + } if (ctx->ctx_reply != NULL) free(ctx->ctx_reply); ctx->ctx_reply = buf; @@ -397,4 +407,3 @@ smfi_getsymval(ctx, symname) } return NULL; } -#endif /* _FFR_MILTER */ |