diff options
Diffstat (limited to 'contrib/sendmail/libmilter')
66 files changed, 0 insertions, 12371 deletions
diff --git a/contrib/sendmail/libmilter/Makefile b/contrib/sendmail/libmilter/Makefile deleted file mode 100644 index b5bfba4..0000000 --- a/contrib/sendmail/libmilter/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# $Id: Makefile,v 8.2 2006/05/23 21:55:55 ca Exp $ - -SHELL= /bin/sh -BUILD= ./Build -OPTIONS= $(CONFIG) $(FLAGS) - -all: FRC - $(SHELL) $(BUILD) $(OPTIONS) $@ -check: FRC - $(SHELL) $(BUILD) $(OPTIONS) $@ -clean: FRC - $(SHELL) $(BUILD) $(OPTIONS) $@ -install: FRC - $(SHELL) $(BUILD) $(OPTIONS) $@ - -fresh: FRC - $(SHELL) $(BUILD) $(OPTIONS) -c - -FRC: diff --git a/contrib/sendmail/libmilter/Makefile.m4 b/contrib/sendmail/libmilter/Makefile.m4 deleted file mode 100644 index 7902c2f..0000000 --- a/contrib/sendmail/libmilter/Makefile.m4 +++ /dev/null @@ -1,40 +0,0 @@ -dnl $Id: Makefile.m4,v 8.78 2007/02/05 19:21:29 ca Exp $ -include(confBUILDTOOLSDIR`/M4/switch.m4') - -dnl only required for compilation of EXTRAS -define(`confREQUIRE_SM_OS_H', `true') -define(`confMT', `true') - -# sendmail dir -SMSRCDIR=ifdef(`confSMSRCDIR', `confSMSRCDIR', `${SRCDIR}/sendmail') -PREPENDDEF(`confINCDIRS', `-I${SMSRCDIR} ') - -bldPRODUCT_START(`library', `libmilter') -define(`bldINSTALLABLE', `true') -define(`LIBMILTER_EXTRAS', `errstring.c strl.c') -APPENDDEF(`confENVDEF', `-DNOT_SENDMAIL -Dsm_snprintf=snprintf') -define(`bldSOURCES', `main.c engine.c listener.c worker.c handler.c comm.c smfi.c signal.c sm_gethost.c monitor.c LIBMILTER_EXTRAS ') -define(`confBEFORE', `LIBMILTER_EXTRAS') -bldPUSH_INSTALL_TARGET(`install-mfapi') -bldPRODUCT_END - -PUSHDIVERT(3) -errstring.c: - ${LN} ${LNOPTS} ${SRCDIR}/libsm/errstring.c . - -strl.c: - ${LN} ${LNOPTS} ${SRCDIR}/libsm/strl.c . -POPDIVERT - - -divert(bldTARGETS_SECTION) -# Install the API header files -MFAPI= ${SRCDIR}/inc`'lude/libmilter/mfapi.h -MFDEF= ${SRCDIR}/inc`'lude/libmilter/mfdef.h -install-mfapi: ${MFAPI} - if [ ! -d ${DESTDIR}${INCLUDEDIR}/libmilter ]; then mkdir -p ${DESTDIR}${INCLUDEDIR}/libmilter; else :; fi - ${INSTALL} -c -o ${INCOWN} -g ${INCGRP} -m ${INCMODE} ${MFAPI} ${DESTDIR}${INCLUDEDIR}/libmilter/mfapi.h - ${INSTALL} -c -o ${INCOWN} -g ${INCGRP} -m ${INCMODE} ${MFDEF} ${DESTDIR}${INCLUDEDIR}/libmilter/mfdef.h -divert(0) - -bldFINISH diff --git a/contrib/sendmail/libmilter/README b/contrib/sendmail/libmilter/README deleted file mode 100644 index e9c2cb1..0000000 --- a/contrib/sendmail/libmilter/README +++ /dev/null @@ -1,234 +0,0 @@ -This directory contains the source files for libmilter. - -The sendmail Mail Filter API (Milter) is designed to allow third-party -programs access to mail messages as they are being processed in order to -filter meta-information and content. - -This README file describes the steps needed to compile and run a filter, -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 . - -Starting with 8.13 sendmail is compiled by default with support for -the milter API. - -Note: if you want to write a milter in Java, then see -http://sendmail-jilter.sourceforge.net/ - -+----------------+ -| SECURITY HINTS | -+----------------+ - -Note: we strongly recommend not to run any milter as root. Libmilter -does not need root access to communicate with sendmail. It is a -good security practice to run a program only with root privileges -if really necessary. A milter should probably check first whether -it runs as root and refuse to start in that case. libmilter will -not unlink a socket when running as root. - -+----------------------+ -| CONFIGURATION MACROS | -+----------------------+ - -Libmilter uses a set of C preprocessor macros to specify platform specific -features of the C compiler and standard C libraries. - -SM_CONF_POLL - Set to 1 if poll(2) should be used instead of select(2). - -+-------------------+ -| BUILDING A FILTER | -+-------------------+ - -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../../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 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 -threading support differs according to the compiler and linker used. Check -the Makefile in your appropriate obj.*/libmilter build subdirectory if you -are unsure of the local flag used. - -Note that since filters use threads, it may be necessary to alter per -process limits in your filter. For example, you might look at using -setrlimit() to increase the number of open file descriptors if your filter -is going to be busy. - - -+----------------------------------------+ -| SPECIFYING FILTERS IN SENDMAIL CONFIGS | -+----------------------------------------+ - -Filters are specified with a key letter ``X'' (for ``eXternal''). - -For example: - - Xfilter1, S=local:/var/run/f1.sock, F=R - Xfilter2, S=inet6:999@localhost, F=T, T=C:10m;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=local:/var/run/f1.sock, F=R') - INPUT_MAIL_FILTER(`filter2', `S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m') - INPUT_MAIL_FILTER(`filter3', `S=inet:3333@localhost') - -The first attaches to a Unix-domain socket in the /var/run directory; the -second uses an IPv6 socket on port 999 of localhost, and the third uses an -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 - 4 Shut down connection if filter unavailable - (with a 421 temporary error). - -If none of these is specified, the message is passed through sendmail -in case of filter errors as if the failing filters were not present. - -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 - 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 - E Overall timeout between sending end-of-message to filter - and waiting for the final acknowledgment - -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:5m;S:10s;R:10s;E:5m - -where 's' is seconds and 'm' is minutes. - -Which filters are invoked and their sequencing is handled by the -InputMailFilters option. Note: if InputMailFilters is not defined no filters -will be used. - - 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 -.mc file. - -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=local:/var/run/f1.sock') - - -+------------------+ -| TESTING A FILTER | -+------------------+ - -Once you have compiled a filter, modified your .mc file and restarted -the sendmail process, you will want to test that the filter performs as -intended. - -The sample filter takes one argument -p, which indicates the local port -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 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. -Further logging can be captured through the syslogd daemon. Using the -'netstat -a' command can ensure that your filter process is listening on -the appropriate local socket. - -Email messages must be injected via SMTP to be filtered. There are two -simple means of doing this; either using the 'sendmail -bs' command, or -by telnetting to port 25 of the machine configured for milter. Once -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.14.0/8.14.0; Thu, 22 Jun 2006 13:05:23 -0500 (EST) -HELO localhost -250 test.sendmail.com Hello testy@localhost, pleased to meet you -MAIL From:<testy> -250 2.1.0 <testy>... Sender ok -RCPT To:<root> -250 2.1.5 <root>... Recipient ok -DATA -354 Enter mail, end with "." on a line by itself -From: testy@test.sendmail.com -To: root@test.sendmail.com -Subject: testing sample filter - -Sample body -. -250 2.0.0 dB73Zxi25236 Message accepted for delivery -QUIT -221 2.0.0 test.sendmail.com closing connection - -In the above example, the lines beginning with numbers are output by the -mail server, and those without are your input. If everything is working -properly, you will find a file in /tmp by the name of msg.XXXXXXXX (where -the Xs represent any combination of letters and numbers). This file should -contain the message body and headers from the test email entered above. - -If the sample filter did not log your test email, there are a number of -methods to narrow down the source of the problem. Check your system -logs written by syslogd and see if there are any pertinent lines. You -may need to reconfigure syslogd to capture all relevant data. Additionally, -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 | -+--------------------------+ - -Note that the filter example.c 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. - -$Revision: 8.42 $, Last updated $Date: 2006/06/29 17:10:16 $ diff --git a/contrib/sendmail/libmilter/comm.c b/contrib/sendmail/libmilter/comm.c deleted file mode 100644 index a7a44df..0000000 --- a/contrib/sendmail/libmilter/comm.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: comm.c,v 8.67 2006/11/02 17:54:44 ca Exp $") - -#include "libmilter.h" -#include <sm/errstring.h> -#include <sys/uio.h> - -static ssize_t retry_writev __P((socket_t, struct iovec *, int, struct timeval *)); -static size_t Maxdatasize = MILTER_MAX_DATA_SIZE; - -#if _FFR_MAXDATASIZE -/* -** SMFI_SETMAXDATASIZE -- set limit for milter data read/write. -** -** Parameters: -** sz -- new limit. -** -** Returns: -** old limit -*/ - -size_t -smfi_setmaxdatasize(sz) - size_t sz; -{ - size_t old; - - old = Maxdatasize; - Maxdatasize = sz; - return old; -} -#endif /* _FFR_MAXDATASIZE */ - -/* -** MI_RD_CMD -- read a command -** -** Parameters: -** sd -- socket descriptor -** timeout -- maximum time to wait -** cmd -- single character command read from sd -** rlen -- pointer to length of result -** name -- name of milter -** -** Returns: -** buffer with rest of command -** (malloc()ed here, should be free()d) -** hack: encode error in cmd -*/ - -char * -mi_rd_cmd(sd, timeout, cmd, rlen, name) - socket_t sd; - struct timeval *timeout; - char *cmd; - size_t *rlen; - char *name; -{ - ssize_t len; - mi_int32 expl; - ssize_t i; - FD_RD_VAR(rds, excs); - int ret; - int save_errno; - char *buf; - char data[MILTER_LEN_BYTES + 1]; - - *cmd = '\0'; - *rlen = 0; - - i = 0; - for (;;) - { - FD_RD_INIT(sd, rds, excs); - ret = FD_RD_READY(sd, rds, excs, timeout); - if (ret == 0) - break; - else if (ret < 0) - { - if (errno == EINTR) - continue; - break; - } - if (FD_IS_RD_EXC(sd, rds, excs)) - { - *cmd = SMFIC_SELECT; - return NULL; - } - - len = MI_SOCK_READ(sd, data + i, sizeof data - i); - if (MI_SOCK_READ_FAIL(len)) - { - smi_log(SMI_LOG_ERR, - "%s, mi_rd_cmd: read returned %d: %s", - name, (int) len, sm_errstring(errno)); - *cmd = SMFIC_RECVERR; - return NULL; - } - if (len == 0) - { - *cmd = SMFIC_EOF; - return NULL; - } - if (len >= (ssize_t) sizeof data - i) - break; - i += len; - } - if (ret == 0) - { - *cmd = SMFIC_TIMEOUT; - return NULL; - } - else if (ret < 0) - { - smi_log(SMI_LOG_ERR, - "%s: mi_rd_cmd: select returned %d: %s", - name, ret, sm_errstring(errno)); - *cmd = SMFIC_RECVERR; - return NULL; - } - - *cmd = data[MILTER_LEN_BYTES]; - data[MILTER_LEN_BYTES] = '\0'; - (void) memcpy((void *) &expl, (void *) &(data[0]), MILTER_LEN_BYTES); - expl = ntohl(expl) - 1; - if (expl <= 0) - return NULL; - if (expl > Maxdatasize) - { - *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; - return NULL; - } - - i = 0; - for (;;) - { - FD_RD_INIT(sd, rds, excs); - ret = FD_RD_READY(sd, rds, excs, timeout); - if (ret == 0) - break; - else if (ret < 0) - { - if (errno == EINTR) - continue; - break; - } - if (FD_IS_RD_EXC(sd, rds, excs)) - { - *cmd = SMFIC_SELECT; - free(buf); - return NULL; - } - len = MI_SOCK_READ(sd, buf + i, expl - i); - if (MI_SOCK_READ_FAIL(len)) - { - smi_log(SMI_LOG_ERR, - "%s: mi_rd_cmd: read returned %d: %s", - name, (int) len, sm_errstring(errno)); - ret = -1; - break; - } - if (len == 0) - { - *cmd = SMFIC_EOF; - free(buf); - return NULL; - } - if (len > expl - i) - { - *cmd = SMFIC_RECVERR; - free(buf); - return NULL; - } - 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; - } - - save_errno = errno; - free(buf); - - /* select returned 0 (timeout) or < 0 (error) */ - if (ret == 0) - { - *cmd = SMFIC_TIMEOUT; - return NULL; - } - if (ret < 0) - { - smi_log(SMI_LOG_ERR, - "%s: mi_rd_cmd: select returned %d: %s", - name, ret, sm_errstring(save_errno)); - *cmd = SMFIC_RECVERR; - return NULL; - } - *cmd = SMFIC_UNKNERR; - return NULL; -} - -/* -** RETRY_WRITEV -- Keep calling the writev() system call -** until all the data is written out or an error occurs. -** -** Parameters: -** fd -- socket descriptor -** iov -- io vector -** iovcnt -- number of elements in io vector -** must NOT exceed UIO_MAXIOV. -** timeout -- maximum time to wait -** -** Returns: -** success: number of bytes written -** otherwise: MI_FAILURE -*/ - -static ssize_t -retry_writev(fd, iov, iovcnt, timeout) - socket_t fd; - struct iovec *iov; - int iovcnt; - struct timeval *timeout; -{ - int i; - ssize_t n, written; - FD_WR_VAR(wrs); - - written = 0; - for (;;) - { - while (iovcnt > 0 && iov[0].iov_len == 0) - { - iov++; - iovcnt--; - } - if (iovcnt <= 0) - return written; - - /* - ** We don't care much about the timeout here, - ** it's very long anyway; correct solution would be - ** to take the time before the loop and reduce the - ** timeout after each invocation. - ** FD_SETSIZE is checked when socket is created. - */ - - FD_WR_INIT(fd, wrs); - i = FD_WR_READY(fd, wrs, timeout); - if (i == 0) - return MI_FAILURE; - if (i < 0) - { - if (errno == EINTR || errno == EAGAIN) - continue; - return MI_FAILURE; - } - n = writev(fd, iov, iovcnt); - if (n == -1) - { - if (errno == EINTR || errno == EAGAIN) - continue; - return MI_FAILURE; - } - - written += n; - for (i = 0; i < iovcnt; i++) - { - if (iov[i].iov_len > (unsigned int) n) - { - iov[i].iov_base = (char *)iov[i].iov_base + n; - iov[i].iov_len -= (unsigned int) n; - break; - } - n -= (int) iov[i].iov_len; - iov[i].iov_len = 0; - } - if (i == iovcnt) - return written; - } -} - -/* -** MI_WR_CMD -- write a cmd to sd -** -** Parameters: -** sd -- socket descriptor -** timeout -- maximum time to wait -** cmd -- single character command to write -** buf -- buffer with further data -** len -- length of buffer (without cmd!) -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -mi_wr_cmd(sd, timeout, cmd, buf, len) - socket_t sd; - struct timeval *timeout; - int cmd; - char *buf; - size_t len; -{ - size_t sl, i; - ssize_t l; - mi_int32 nl; - int iovcnt; - struct iovec iov[2]; - char data[MILTER_LEN_BYTES + 1]; - - if (len > Maxdatasize || (len > 0 && buf == NULL)) - return MI_FAILURE; - - nl = htonl(len + 1); /* add 1 for the cmd char */ - (void) memcpy(data, (void *) &nl, MILTER_LEN_BYTES); - data[MILTER_LEN_BYTES] = (char) cmd; - i = 0; - sl = MILTER_LEN_BYTES + 1; - - /* set up the vector for the size / command */ - iov[0].iov_base = (void *) data; - iov[0].iov_len = sl; - iovcnt = 1; - if (len >= 0 && buf != NULL) - { - iov[1].iov_base = (void *) buf; - iov[1].iov_len = len; - iovcnt = 2; - } - - l = retry_writev(sd, iov, iovcnt, timeout); - if (l == MI_FAILURE) - return MI_FAILURE; - return MI_SUCCESS; -} diff --git a/contrib/sendmail/libmilter/docs/api.html b/contrib/sendmail/libmilter/docs/api.html deleted file mode 100644 index 4214df4..0000000 --- a/contrib/sendmail/libmilter/docs/api.html +++ /dev/null @@ -1,320 +0,0 @@ -<HTML> -<HEAD><TITLE>Milter API</TITLE></HEAD> -<BODY> -<!-- -$Id: api.html,v 1.35 2006/11/30 23:09:23 ca Exp $ ---> -<H1>Milter API</H1> - -<H2>Contents</H2> -<UL> - <LI><A HREF="#LibraryControlFunctions">Library Control Functions</A> - <LI><A HREF="#DataAccessFunctions">Data Access Functions</A> - <LI><A HREF="#MessageModificationFunctions">Message Modification Functions</A> - <LI><A HREF="#Callbacks">Callbacks</A> - <LI><A HREF="#Miscellaneous">Miscellaneous</A> -</UL> - -<H2><A NAME="LibraryControlFunctions">Library Control Functions</A></H2> - -Before handing control to libmilter (by calling -<A HREF="smfi_main.html">smfi_main</A>), a filter may call the following -functions to set libmilter parameters. -In particular, the filter must call -<A HREF="smfi_register.html">smfi_register</A> to register its callbacks. -Each function will return either MI_SUCCESS or MI_FAILURE to -indicate the status of the operation. - -<P> -None of these functions communicate with the MTA. All alter the -library's state, some of which is communicated to the MTA inside -<A HREF="smfi_main.html">smfi_main</A>. - -<P> -<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH></TR> - -<TR><TD><A HREF="smfi_opensocket.html">smfi_opensocket</A></TD><TD>Try to create the interface socket.</TD></TR> - -<TR><TD><A HREF="smfi_register.html">smfi_register</A></TD><TD>Register a filter.</TD></TR> - -<TR><TD><A HREF="smfi_setconn.html">smfi_setconn</A></TD><TD>Specify socket to use.</TD></TR> - -<TR><TD><A HREF="smfi_settimeout.html">smfi_settimeout</A></TD><TD>Set timeout.</TD></TR> - -<TR><TD><A HREF="smfi_setbacklog.html">smfi_setbacklog</A></TD><TD>Define the incoming <CODE>listen(2)</CODE> queue size.</TD></TR> - -<TR><TD><A HREF="smfi_setdbg.html">smfi_setdbg</A></TD><TD>Set the milter library debugging (tracing) level.</TD></TR> - -<TR><TD><A HREF="smfi_stop.html">smfi_stop</A></TD><TD>Cause an orderly shutdown.</TD></TR> - -<TR><TD><A HREF="smfi_main.html">smfi_main</A></TD><TD>Hand control to libmilter.</TD></TR> - -</TABLE> - -<H2><A NAME="DataAccessFunctions">Data Access Functions</A></H2> - -The following functions may be called from within the filter-defined callbacks -to access information about the current connection or message. -<P> -<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR bgcolor="#dddddd"><TH>Function</TH><TH>Description</TH></TR> -<TR><TD><A HREF="smfi_getsymval.html">smfi_getsymval</A></TD><TD>Return the value -of a symbol.</TD></TR> - -<TR><TD><A HREF="smfi_getpriv.html">smfi_getpriv</A></TD><TD>Get the private data -pointer.</TD></TR> - -<TR><TD><A HREF="smfi_setpriv.html">smfi_setpriv</A></TD><TD>Set the private data -pointer.</TD></TR> - -<TR><TD><A HREF="smfi_setreply.html">smfi_setreply</A></TD><TD>Set the specific -reply code to be used.</TD></TR> - -<TR><TD><A HREF="smfi_setmlreply.html">smfi_setmlreply</A></TD><TD>Set the -specific multi-line reply to be used.</TD></TR> - -</TABLE> - -<H2><A NAME="MessageModificationFunctions">Message Modification Functions</A></H2> - -The following functions change a message's contents and attributes. -<EM>They may only be called in <A HREF="xxfi_eom.html">xxfi_eom</A></EM>. -All of these functions may invoke additional communication with the MTA. -They will return either MI_SUCCESS or MI_FAILURE to indicate the status of -the operation. - -<P> -A filter must have set the appropriate flag (listed below) in the -description passed to <A HREF="smfi_register.html">smfi_register</A> -to call any message modification function. Failure to do so will -cause the MTA to treat a call to the function as a failure of the -filter, terminating its connection. - -<P> -Note that the status returned indicates only whether or not the -filter's message was successfully sent to the MTA, not whether or not -the MTA performed the requested operation. For example, -<A HREF="smfi_addheader.html">smfi_addheader</A>, when called with an -illegal header name, will return MI_SUCCESS even though the MTA may -later refuse to add the illegal header. -<P> -<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH><TH>SMFIF_* flag</TR> -<TR><TD><A HREF="smfi_addheader.html">smfi_addheader</A></TD><TD>Add a header to -the message.</TD><TD>SMFIF_ADDHDRS</TD></TR> - -<TR><TD><A HREF="smfi_chgheader.html">smfi_chgheader</A></TD><TD>Change or delete a header.</TD><TD>SMFIF_CHGHDRS</TD></TR> - -<TR><TD><A HREF="smfi_insheader.html">smfi_insheader</A></TD><TD>Insert a -header into the message.</TD><TD>SMFIF_ADDHDRS</TD></TR> - -<TR><TD><A HREF="smfi_chgfrom.html">smfi_chgfrom</A></TD><TD>Change the -envelope sender address.</TD><TD>SMFIF_CHGFROM</TD></TR> - -<TR><TD><A HREF="smfi_addrcpt.html">smfi_addrcpt</A></TD><TD>Add a recipient to -the envelope.</TD><TD>SMFIF_ADDRCPT</TD></TR> - -<TR><TD><A HREF="smfi_addrcpt_par.html">smfi_addrcpt_par</A></TD><TD>Add -a recipient including ESMTP parameter to the envelope. -</TD><TD>SMFIF_ADDRCPT_PAR</TD></TR> - -<TR><TD><A HREF="smfi_delrcpt.html">smfi_delrcpt</A></TD><TD>Delete a recipient -from the envelope.</TD><TD>SMFIF_DELRCPT</TD></TR> - -<TR><TD><A HREF="smfi_replacebody.html">smfi_replacebody</A></TD><TD>Replace the -body of the message.</TD><TD>SMFIF_CHGBODY</TD></TR> - -</TABLE> - -<H2>Other Message Handling Functions</H2> - -The following functions provide special case handling instructions for -milter or the MTA, without altering the content or status of the message. -<EM>They too may only be called in <A HREF="xxfi_eom.html">xxfi_eom</A></EM>. -All of these functions may invoke additional communication with the MTA. -They will return either MI_SUCCESS or MI_FAILURE to indicate the status of -the operation. - -<P> -Note that the status returned indicates only whether or not the -filter's message was successfully sent to the MTA, not whether or not -the MTA performed the requested operation. - -<P> -<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH></TR> -<TR><TD><A HREF="smfi_progress.html">smfi_progress</A></TD><TD>Report operation in progress.</TD></TR> - -<TR><TD><A HREF="smfi_quarantine.html">smfi_quarantine</A></TD><TD>Quarantine a message.</TD></TR> - -</TABLE> - -<H2><A NAME="Callbacks">Callbacks</A></H2> - -The filter should implement one or more of the following callbacks, -which are registered via <A HREF="smfi_register.html">smfi_register</A>: - -<P> -<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH></TR> - -<TR><TD><A HREF="xxfi_connect.html">xxfi_connect</A></TD><TD>connection info</TD></TR> - -<TR><TD><A HREF="xxfi_helo.html">xxfi_helo</A></TD><TD>SMTP HELO/EHLO command</TD></TR> - -<TR><TD><A HREF="xxfi_envfrom.html">xxfi_envfrom</A></TD><TD>envelope sender</TD></TR> - -<TR><TD><A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A></TD><TD>envelope recipient</TD></TR> - -<TR><TD><A HREF="xxfi_data.html">xxfi_data</A></TD><TD>DATA command</TD></TR> - -<TR><TD><A HREF="xxfi_unknown.html">xxfi_unknown</A></TD><TD>Unknown SMTP command</TD></TR> - -<TR><TD><A HREF="xxfi_header.html">xxfi_header</A></TD><TD>header</TD></TR> - -<TR><TD><A HREF="xxfi_eoh.html">xxfi_eoh</A></TD><TD>end of header</TD></TR> - -<TR><TD><A HREF="xxfi_body.html">xxfi_body</A></TD><TD>body block</TD></TR> - -<TR><TD><A HREF="xxfi_eom.html">xxfi_eom</A></TD><TD>end of message</TD></TR> - -<TR><TD><A HREF="xxfi_abort.html">xxfi_abort</A></TD><TD>message aborted</TD></TR> - -<TR><TD><A HREF="xxfi_close.html">xxfi_close</A></TD><TD>connection cleanup</TD></TR> - -<TR><TD><A HREF="xxfi_negotiate.html">xxfi_negotiate</A></TD><TD>option negotiattion</TD></TR> - -</TABLE> - -<P> -The above callbacks should all return one of the following return values, -having the indicated meanings. Any return other than one of the below -values constitutes an error, and will cause sendmail to terminate its -connection to the offending filter. - -<P><A NAME="conn-spec">Milter</A> distinguishes between recipient-, -message-, and connection-oriented routines. Recipient-oriented -callbacks may affect the processing of a single message recipient; -message-oriented callbacks, a single message; connection-oriented -callbacks, an entire connection (during which multiple messages may be -delivered to multiple sets of recipients). -<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A> is recipient-oriented. -<A HREF="xxfi_connect.html">xxfi_connect</A>, -<A HREF="xxfi_helo.html">xxfi_helo</A> and -<A HREF="xxfi_close.html">xxfi_close</A> are connection-oriented. All -other callbacks are message-oriented. - -<P> -<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2> - <TR BGCOLOR="#dddddd"><TH>Return value</TH><TH>Description</TH></TR> - <TR VALIGN="TOP"> - <TD>SMFIS_CONTINUE</TD> - <TD>Continue processing the current connection, message, or recipient. - </TD> - </TR> - <TR VALIGN="TOP"> - <TD>SMFIS_REJECT</TD> - <TD>For a connection-oriented routine, reject this connection; call <A HREF="xxfi_close.html">xxfi_close</A>.<BR> - For a message-oriented routine (except - <A HREF="xxfi_eom.html">xxfi_eom</A> or - <A HREF="xxfi_abort.html">xxfi_abort</A>), reject this message.<BR> - For a recipient-oriented routine, reject the current recipient (but continue processing the current message). - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_DISCARD</TD> - <TD>For a message- or recipient-oriented routine, accept this message, but silently discard it.<BR> - SMFIS_DISCARD should not be returned by a connection-oriented routine. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_ACCEPT</TD> - <TD>For a connection-oriented routine, accept this connection without further filter processing; call <A HREF="xxfi_close.html">xxfi_close</A>.<BR> - For a message- or recipient-oriented routine, accept this message without further filtering.<BR> - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_TEMPFAIL</TD> - <TD>Return a temporary failure, i.e., the corresponding SMTP command will return an appropriate 4xx status code. - For a message-oriented routine (except <A HREF="xxfi_envfrom.html">xxfi_envfrom</A>), fail for this message. <BR> - For a connection-oriented routine, fail for this connection; call <A HREF="xxfi_close.html">xxfi_close</A>. <BR> - For a recipient-oriented routine, only fail for the current recipient; continue message processing. - </TD> - </TR> - - <TR valign="top"> - <TD><A NAME="SMFIS_SKIP">SMFIS_SKIP</A></TD> - <TD>Skip further callbacks of the same type in this transaction. - Currently this return value is only allowed in - <A HREF="xxfi_body.html">xxfi_body()</A>. - It can be used if a milter has received sufficiently many - body chunks to make a decision, but still wants to invoke - message modification functions that are only allowed to be called from - <A HREF="xxfi_eom.html">xxfi_eom()</A>. - Note: the milter <EM>must</EM> - <A HREF="xxfi_negotiate.html">negotiate</A> - this behavior with the MTA, i.e., it must check whether - the protocol action - <A HREF="xxfi_negotiate.html#SMFIP_SKIP"><CODE>SMFIP_SKIP</CODE></A> - is available and if so, the milter must request it. - </TD> - </TR> - - <TR valign="top"> - <TD><A NAME="SMFIS_NOREPLY">SMFIS_NOREPLY</A></TD> - <TD>Do not send a reply back to the MTA. - The milter <EM>must</EM> - <A HREF="xxfi_negotiate.html">negotiate</A> - this behavior with the MTA, i.e., it must check whether - the appropriate protocol action - <A HREF="xxfi_negotiate.html#SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A> - is available and if so, the milter must request it. - If you set the - <A HREF="xxfi_negotiate.html#SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A> - protocol action for a callback, that callback <EM>must</EM> - always reply with - SMFIS_NOREPLY. - Using any other reply code is a violation of the API. - If in some cases your callback may return another value - (e.g., due to some resource shortages), then you - <EM>must not</EM> set - <A HREF="xxfi_negotiate.html#SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A> - and you must use - SMFIS_CONTINUE as the default return code. - (Alternatively you can try to delay reporting the problem to - a later callback for which - <A HREF="xxfi_negotiate.html#SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A> - is not set.) - </TD> - </TR> - -</TABLE> - -<H2><A NAME="Miscellaneous">Miscellaneous</A></H2> - -<P> -<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH></TR> - -<TR><TD><A HREF="smfi_version.html">smfi_version</A></TD><TD>libmilter (runtime) version info</TD></TR> - -<TR><TD><A HREF="smfi_setsymlist.html">smfi_setsymlist</A></TD><TD> -Set the list of macros that the milter wants to receive from the MTA -for a protocol stage. -</TD></TR> - -</TABLE> - -<P> -<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Constant</TH><TH>Description</TH></TR> - -<TR><TD><A HREF="smfi_version.html">SMFI_VERSION</A></TD><TD>libmilter (compile time) version info</TD></TR> - -</TABLE> - - -<HR SIZE="1"> -<FONT SIZE="-1"> -Copyright (c) 2000, 2003, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/design.html b/contrib/sendmail/libmilter/docs/design.html deleted file mode 100644 index f2e5f11..0000000 --- a/contrib/sendmail/libmilter/docs/design.html +++ /dev/null @@ -1,147 +0,0 @@ -<HTML> -<HEAD> -<TITLE>Architecture</TITLE> -</HEAD> -<BODY> -<!-- -$Id: design.html,v 1.12 2006/08/08 20:55:57 ca Exp $ ---> - -<H1>Architecture</H1> - -<H2>Contents</H2> - -<UL> - <LI>Design Goals - <LI>Implementing Filtering Policies - <LI>MTA - Filter Communication -</UL> - -<H2>Goals</H2> - -The Sendmail Content Management API (Milter) provides an interface for -third-party software to validate and modify messages as they pass -through the mail transport system. Filters can process messages' -connection (IP) information, envelope protocol elements, message -headers, and/or message body contents, and modify a message's -recipients, headers, and body. The MTA configuration file specifies -which filters are to be applied, and in what order, allowing an -administrator to combine multiple independently-developed filters. - -<P> -We expect to see both vendor-supplied, configurable mail filtering -applications and a multiplicity of script-like filters designed by and -for MTA administrators. A certain degree of coding sophistication and -domain knowledge on the part of the filter provider is assumed. This -allows filters to exercise fine-grained control at the SMTP level. -However, as will be seen in the example, many filtering applications -can be written with relatively little protocol knowledge. - -<P> -Given these expectations, the API is designed to achieve the following -goals: - -<OL> - <LI>Safety/security. - Filter processes should not need to run as root - (of course, they can if required, but that is a local issue); - this will simplify coding - and limit the impact of security flaws in the filter program. -<P> - <LI>Reliability. - Coding failures in a Milter process that cause that process - to hang or core-dump - should not stop mail delivery. - Faced with such a failure, - sendmail should use a default mechanism, - either behaving as if the filter were not present - or as if a required resource were unavailable. - The latter failure mode will generally have sendmail return - a 4xx SMTP code (although in later phases of the SMTP protocol - it may cause the mail to be queued for later processing). -<P> - <LI>Simplicity. - The API should make implementation of a new filter - no more difficult than absolutely necessary. - Subgoals include: - <UL> - <LI>Encourage good thread practice - by defining thread-clean interfaces including local data hooks. - <LI>Provide all interfaces required - while avoiding unnecessary pedanticism. - </UL> -<P> - <LI>Performance. - Simple filters should not seriously impact overall MTA performance. -</OL> - -<H2>Implementing Filtering Policies</H2> - -Milter is designed to allow a server administrator to combine -third-party filters to implement a desired mail filtering policy. For -example, if a site wished to scan incoming mail for viruses on several -platforms, eliminate unsolicited commercial email, and append a mandated -footer to selected incoming messages, the administrator could configure -the MTA to filter messages first through a server based anti-virus -engine, then via a large-scale spam-catching service, and finally -append the desired footer if the message still met requisite criteria. -Any of these filters could be added or changed independently. - -<P> -Thus the site administrator, not the filter writer, controls the -overall mail filtering environment. In particular, he/she must decide -which filters are run, in what order they are run, and how they -communicate with the MTA. These parameters, as well as the -actions to be taken if a filter becomes unavailable, are selectable -during MTA configuration. <A href="installation.html">Further -details</A> are available later in this document. - -<H2>MTA - Filter communication</H2> - -Filters run as separate processes, outside of the sendmail address -space. The benefits of this are threefold: - -<OL> - <LI>The filter need not run with "root" permissions, thereby - avoiding a large family of potential security problems.</LI> - - <LI>Failures in a particular filter will not affect the MTA or - other filters.</LI> - - <LI>The filter can potentially have higher performance because of - the parallelism inherent in multiple processes.</LI> -</OL> - -<P> -Each filter may communicate with multiple MTAs at the same time over -local or remote connections, using multiple threads of execution. -<A HREF="#figure-1">Figure 1</A> illustrates a possible network of -communication channels between a site's filters, its MTAs, and other -MTAs on the network: -</P> -<DIV align="center"> -<A name="figure-1"><IMG src="figure1.jpg" ALT=""></A><BR> -<B>Figure 1: A set of MTA's interacting with a set of filters.</B> -</DIV> -<P> -The Milter library (libmilter) implements the communication protocol. -It accepts connections from various MTAs, passes the relevant data to -the filter through callbacks, then makes appropriate responses based -on return codes. A filter may also send data to the MTA as a result -of library calls. <A href="#figure-2">Figure 2</A> shows a single -filter process processing messages from two MTAs: -</P> -<DIV align="center"> -<IMG src="figure2.jpg" ALT=""><BR> -<B>Figure 2: A filter handling simultaneous requests from two MTA's.</B> -</DIV> -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/figure1.fig b/contrib/sendmail/libmilter/docs/figure1.fig deleted file mode 100644 index e0cbdc8..0000000 --- a/contrib/sendmail/libmilter/docs/figure1.fig +++ /dev/null @@ -1,56 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 975 225 5025 3375 -6 1500 1275 2700 2025 -2 2 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 5 - 1650 1425 2550 1425 2550 1875 1650 1875 1650 1425 -4 0 1 50 0 0 20 0.0000 4 195 645 1800 1725 MTA\001 --6 -6 1950 2625 3150 3375 -2 2 0 2 4 7 50 0 -1 0.000 0 0 7 0 0 5 - 2100 2775 3000 2775 3000 3225 2100 3225 2100 2775 -4 0 4 50 0 0 20 0.0000 4 195 645 2250 3075 MTA\001 --6 -6 1050 225 2250 975 -2 2 0 2 14 7 50 0 -1 0.000 0 0 7 0 0 5 - 1200 375 2100 375 2100 825 1200 825 1200 375 -4 0 14 50 0 0 20 0.0000 4 195 645 1350 675 MTA\001 --6 -2 1 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 2 - 2550 1575 3750 2625 -2 1 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 2 - 2550 1575 3750 1575 -2 1 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 2 - 2550 1575 3750 825 -2 1 0 2 4 7 50 0 -1 0.000 0 0 7 0 0 2 - 3000 2925 3750 2625 -2 1 0 2 14 7 50 0 -1 0.000 0 0 7 0 0 2 - 2100 525 3750 825 -2 1 0 2 14 7 50 0 -1 0.000 0 0 7 0 0 2 - 2100 525 3750 2625 -2 1 0 4 0 7 50 0 -1 0.000 0 0 7 0 0 2 - 1050 3075 2100 3075 -2 1 0 4 0 7 50 0 -1 0.000 0 0 7 0 0 2 - 1050 1725 1650 1725 -2 1 0 4 0 7 50 0 -1 0.000 0 0 7 0 0 2 - 1050 675 1200 675 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 3750 2475 4950 2475 4950 2925 3750 2925 3750 2475 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 3750 1425 4950 1425 4950 1875 3750 1875 3750 1425 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 3750 525 4950 525 4950 975 3750 975 3750 525 -4 0 0 50 0 1 20 0.0000 4 210 795 3900 2775 Filter 3\001 -4 0 0 50 0 1 20 0.0000 4 210 795 3900 1725 Filter 2\001 -4 0 0 50 0 1 20 0.0000 4 210 795 3900 825 Filter 1\001 --6 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 300 525 1050 525 1050 3225 300 3225 300 525 -4 0 0 50 0 2 24 1.5708 4 255 1950 825 2850 INTERNET\001 diff --git a/contrib/sendmail/libmilter/docs/figure1.jpg b/contrib/sendmail/libmilter/docs/figure1.jpg Binary files differdeleted file mode 100644 index 1a5f1de..0000000 --- a/contrib/sendmail/libmilter/docs/figure1.jpg +++ /dev/null diff --git a/contrib/sendmail/libmilter/docs/figure1.ps b/contrib/sendmail/libmilter/docs/figure1.ps deleted file mode 100644 index ae31760..0000000 --- a/contrib/sendmail/libmilter/docs/figure1.ps +++ /dev/null @@ -1,173 +0,0 @@ -%!PS-Adobe-2.0 -%%Title: figure1.fig -%%Creator: fig2dev Version 3.2.3 Patchlevel -%%CreationDate: Tue Jun 6 14:00:04 2000 -%%For: sean@host232.Sendmail.COM (Sean O'rourke,5400) -%%Orientation: Landscape -%%Pages: 1 -%%BoundingBox: 0 0 612 792 -%%BeginSetup -%%IncludeFeature: *PageSize Letter -%%EndSetup -%%Magnification: 1.0000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 792 moveto 0 0 lineto 612 0 lineto 612 792 lineto closepath clip newpath -198.0 238.0 translate - 90 rotate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -%%Page: 1 1 -10 setmiterlimit - 0.06000 0.06000 sc -%%Page: 1 1 -/Times-Bold ff 360.00 scf sf -825 2850 m -gs 1 -1 sc 90.0 rot (INTERNET) col0 sh gr -/Times-Roman ff 300.00 scf sf -1800 1725 m -gs 1 -1 sc (MTA) col1 sh gr -% Polyline -15.000 slw -n 2100 2775 m 3000 2775 l 3000 3225 l 2100 3225 l - cp gs col4 s gr -/Times-Roman ff 300.00 scf sf -2250 3075 m -gs 1 -1 sc (MTA) col4 sh gr -% Polyline -n 1200 375 m 2100 375 l 2100 825 l 1200 825 l - cp gs col14 s gr -/Times-Roman ff 300.00 scf sf -1350 675 m -gs 1 -1 sc (MTA) col14 sh gr -% Polyline -n 2550 1575 m - 3750 2625 l gs col1 s gr -% Polyline -n 2550 1575 m - 3750 1575 l gs col1 s gr -% Polyline -n 2550 1575 m - 3750 825 l gs col1 s gr -% Polyline -n 3000 2925 m - 3750 2625 l gs col4 s gr -% Polyline -n 2100 525 m - 3750 825 l gs col14 s gr -% Polyline -n 2100 525 m - 3750 2625 l gs col14 s gr -% Polyline -45.000 slw -n 1050 3075 m - 2100 3075 l gs col0 s gr -% Polyline -n 1050 1725 m - 1650 1725 l gs col0 s gr -% Polyline -n 1050 675 m - 1200 675 l gs col0 s gr -% Polyline -15.000 slw -n 3750 2475 m 4950 2475 l 4950 2925 l 3750 2925 l - cp gs col0 s gr -% Polyline -n 3750 1425 m 4950 1425 l 4950 1875 l 3750 1875 l - cp gs col0 s gr -% Polyline -n 3750 525 m 4950 525 l 4950 975 l 3750 975 l - cp gs col0 s gr -/Times-Italic ff 300.00 scf sf -3900 2775 m -gs 1 -1 sc (Filter 3) col0 sh gr -/Times-Italic ff 300.00 scf sf -3900 1725 m -gs 1 -1 sc (Filter 2) col0 sh gr -/Times-Italic ff 300.00 scf sf -3900 825 m -gs 1 -1 sc (Filter 1) col0 sh gr -% Polyline -7.500 slw -n 300 525 m 1050 525 l 1050 3225 l 300 3225 l - cp gs col0 s gr -% Polyline -15.000 slw -n 1650 1425 m 2550 1425 l 2550 1875 l 1650 1875 l - cp gs col1 s gr -$F2psEnd -rs -showpage diff --git a/contrib/sendmail/libmilter/docs/figure2.fig b/contrib/sendmail/libmilter/docs/figure2.fig deleted file mode 100644 index c93bfe3..0000000 --- a/contrib/sendmail/libmilter/docs/figure2.fig +++ /dev/null @@ -1,67 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -5 1 0 1 0 7 50 0 -1 0.000 0 0 1 0 2981.250 1200.000 2700 1050 3300 1200 2700 1350 - 1 1 1.00 60.00 120.00 -6 4200 900 6450 1350 -2 2 0 1 1 7 50 0 -1 0.000 0 0 7 0 0 5 - 4200 900 6450 900 6450 1350 4200 1350 4200 900 -4 0 1 50 0 0 16 0.0000 4 195 2040 4350 1200 xxfi_header callback\001 --6 -6 4200 2250 6450 2700 -2 2 0 1 4 7 50 0 -1 0.000 0 0 7 0 0 5 - 4200 2250 6450 2250 6450 2700 4200 2700 4200 2250 -4 0 4 50 0 0 16 0.0000 4 195 2040 4350 2550 xxfi_header callback\001 --6 -6 600 2100 1800 2850 -2 2 0 2 4 7 50 0 -1 0.000 0 0 7 0 0 5 - 750 2250 1650 2250 1650 2700 750 2700 750 2250 -4 0 4 50 0 0 20 0.0000 4 195 645 900 2550 MTA\001 --6 -6 600 750 1800 1500 -2 2 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 5 - 750 900 1650 900 1650 1350 750 1350 750 900 -4 0 1 50 0 0 20 0.0000 4 195 645 900 1200 MTA\001 --6 -2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 4200 1200 3600 1200 -2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3450 900 4050 900 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 2400 300 6600 300 6600 3300 2400 3300 2400 300 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 2550 750 3450 750 3450 2700 2550 2700 2550 750 -2 1 0 2 4 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3450 2700 4050 2700 -2 1 0 2 4 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 4200 2400 3600 2400 -2 1 0 2 4 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 1650 2700 2250 2700 -2 1 0 2 4 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 2400 2400 1800 2400 -2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 1650 900 2250 900 -2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 2400 1200 1800 1200 -4 0 0 50 0 0 20 0.0000 4 195 630 3900 600 Filter\001 -4 0 4 50 0 0 12 0.0000 4 180 1620 3450 3000 callback (arguments)\001 -4 0 4 50 0 0 12 0.0000 4 180 1575 3900 1950 optional library calls,\001 -4 0 4 50 0 0 12 0.0000 4 135 855 3900 2175 return code\001 -4 0 4 50 0 0 12 0.0000 4 135 780 1500 2100 responses\001 -4 0 0 50 0 0 16 0.0000 4 165 645 2700 2085 Milter\001 -4 0 0 50 0 0 16 0.0000 4 225 675 2700 2400 library\001 -4 0 4 50 0 0 12 0.0000 4 135 510 1500 3000 header\001 diff --git a/contrib/sendmail/libmilter/docs/figure2.jpg b/contrib/sendmail/libmilter/docs/figure2.jpg Binary files differdeleted file mode 100644 index 8b11485..0000000 --- a/contrib/sendmail/libmilter/docs/figure2.jpg +++ /dev/null diff --git a/contrib/sendmail/libmilter/docs/figure2.ps b/contrib/sendmail/libmilter/docs/figure2.ps deleted file mode 100644 index 861a193..0000000 --- a/contrib/sendmail/libmilter/docs/figure2.ps +++ /dev/null @@ -1,242 +0,0 @@ -%!PS-Adobe-2.0 -%%Title: figure2.fig -%%Creator: fig2dev Version 3.2.3 Patchlevel -%%CreationDate: Tue Jun 6 13:57:47 2000 -%%For: sean@host232.Sendmail.COM (Sean O'rourke,5400) -%%Orientation: Landscape -%%Pages: 1 -%%BoundingBox: 0 0 612 792 -%%BeginSetup -%%IncludeFeature: *PageSize Letter -%%EndSetup -%%Magnification: 1.5000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 792 moveto 0 0 lineto 612 0 lineto 612 792 lineto closepath clip newpath -144.0 65.5 translate - 90 rotate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -%%Page: 1 1 -10 setmiterlimit - 0.09000 0.09000 sc -%%Page: 1 1 -/Times-Roman ff 180.00 scf sf -1500 3000 m -gs 1 -1 sc (header) col4 sh gr -/Times-Roman ff 240.00 scf sf -4350 1200 m -gs 1 -1 sc (xxfi_header callback) col1 sh gr -% Polyline -7.500 slw -n 4200 2250 m 6450 2250 l 6450 2700 l 4200 2700 l - cp gs col4 s gr -/Times-Roman ff 240.00 scf sf -4350 2550 m -gs 1 -1 sc (xxfi_header callback) col4 sh gr -% Polyline -15.000 slw -n 750 2250 m 1650 2250 l 1650 2700 l 750 2700 l - cp gs col4 s gr -/Times-Roman ff 300.00 scf sf -900 2550 m -gs 1 -1 sc (MTA) col4 sh gr -% Polyline -n 750 900 m 1650 900 l 1650 1350 l 750 1350 l - cp gs col1 s gr -/Times-Roman ff 300.00 scf sf -900 1200 m -gs 1 -1 sc (MTA) col1 sh gr -% Arc -7.500 slw -gs clippath -2713 1319 m 2667 1357 l 2761 1475 l 2710 1363 l 2808 1437 l cp -eoclip -n 2981.2 1200.0 318.8 -151.9 151.9 arc -gs col0 s gr - gr - -% arrowhead -n 2808 1437 m 2710 1363 l 2761 1475 l 2808 1437 l cp gs 0.00 setgray ef gr col0 s -% Polyline -15.000 slw -gs clippath -3585 1140 m 3585 1260 l 3872 1260 l 3632 1200 l 3872 1140 l cp -eoclip -n 4200 1200 m - 3600 1200 l gs col1 s gr gr - -% arrowhead -n 3872 1140 m 3632 1200 l 3872 1260 l 3872 1140 l cp gs col1 1.00 shd ef gr col1 s -% Polyline -gs clippath -4065 960 m 4065 840 l 3778 840 l 4018 900 l 3778 960 l cp -eoclip -n 3450 900 m - 4050 900 l gs col1 s gr gr - -% arrowhead -n 3778 960 m 4018 900 l 3778 840 l 3778 960 l cp gs col1 1.00 shd ef gr col1 s -% Polyline -n 2400 300 m 6600 300 l 6600 3300 l 2400 3300 l - cp gs col0 s gr -% Polyline -7.500 slw -n 2550 750 m 3450 750 l 3450 2700 l 2550 2700 l - cp gs col0 s gr -% Polyline -15.000 slw -gs clippath -4065 2760 m 4065 2640 l 3778 2640 l 4018 2700 l 3778 2760 l cp -eoclip -n 3450 2700 m - 4050 2700 l gs col4 s gr gr - -% arrowhead -n 3778 2760 m 4018 2700 l 3778 2640 l 3778 2760 l cp gs col4 1.00 shd ef gr col4 s -% Polyline -gs clippath -3585 2340 m 3585 2460 l 3872 2460 l 3632 2400 l 3872 2340 l cp -eoclip -n 4200 2400 m - 3600 2400 l gs col4 s gr gr - -% arrowhead -n 3872 2340 m 3632 2400 l 3872 2460 l 3872 2340 l cp gs col4 1.00 shd ef gr col4 s -% Polyline -gs clippath -2265 2760 m 2265 2640 l 1978 2640 l 2218 2700 l 1978 2760 l cp -eoclip -n 1650 2700 m - 2250 2700 l gs col4 s gr gr - -% arrowhead -n 1978 2760 m 2218 2700 l 1978 2640 l 1978 2760 l cp gs col4 1.00 shd ef gr col4 s -% Polyline -gs clippath -1785 2340 m 1785 2460 l 2072 2460 l 1832 2400 l 2072 2340 l cp -eoclip -n 2400 2400 m - 1800 2400 l gs col4 s gr gr - -% arrowhead -n 2072 2340 m 1832 2400 l 2072 2460 l 2072 2340 l cp gs col4 1.00 shd ef gr col4 s -% Polyline -gs clippath -2265 960 m 2265 840 l 1978 840 l 2218 900 l 1978 960 l cp -eoclip -n 1650 900 m - 2250 900 l gs col1 s gr gr - -% arrowhead -n 1978 960 m 2218 900 l 1978 840 l 1978 960 l cp gs col1 1.00 shd ef gr col1 s -% Polyline -gs clippath -1785 1140 m 1785 1260 l 2072 1260 l 1832 1200 l 2072 1140 l cp -eoclip -n 2400 1200 m - 1800 1200 l gs col1 s gr gr - -% arrowhead -n 2072 1140 m 1832 1200 l 2072 1260 l 2072 1140 l cp gs col1 1.00 shd ef gr col1 s -/Times-Roman ff 300.00 scf sf -3900 600 m -gs 1 -1 sc (Filter) col0 sh gr -/Times-Roman ff 180.00 scf sf -3450 3000 m -gs 1 -1 sc (callback \(arguments\)) col4 sh gr -/Times-Roman ff 180.00 scf sf -3900 1950 m -gs 1 -1 sc (optional library calls,) col4 sh gr -/Times-Roman ff 180.00 scf sf -3900 2175 m -gs 1 -1 sc (return code) col4 sh gr -/Times-Roman ff 180.00 scf sf -1500 2100 m -gs 1 -1 sc (responses) col4 sh gr -/Times-Roman ff 240.00 scf sf -2700 2085 m -gs 1 -1 sc (Milter) col0 sh gr -/Times-Roman ff 240.00 scf sf -2700 2400 m -gs 1 -1 sc (library) col0 sh gr -% Polyline -7.500 slw -n 4200 900 m 6450 900 l 6450 1350 l 4200 1350 l - cp gs col1 s gr -$F2psEnd -rs -showpage diff --git a/contrib/sendmail/libmilter/docs/index.html b/contrib/sendmail/libmilter/docs/index.html deleted file mode 100644 index 517d2f6..0000000 --- a/contrib/sendmail/libmilter/docs/index.html +++ /dev/null @@ -1,92 +0,0 @@ -<HTML> -<HEAD> -<TITLE>Filtering Mail with Sendmail</TITLE> -</HEAD> -<BODY> -<!-- -$Id: index.html,v 1.13 2006/08/08 20:55:57 ca Exp $ ---> - -<H1>Filtering Mail with Sendmail</H1> - -<!-- -<P><B>Disclaimer</B>: -This preliminary API description is provided for review only. This -specification may change based on feedback from reviewers, and does -not bind Sendmail to offer this functionality in any release. ---> - -<H2>Introduction</H2> - -<P> -Sendmail's Content Management API (milter) provides third-party -programs to access mail messages as they are being processed by the -Mail Transfer Agent (MTA), allowing them to examine and modify message -content and meta-information. Filtering policies implemented by -Milter-conformant filters may then be centrally configured and -composed in an end-user's MTA configuration file. - -<P> -Possible uses for filters include spam rejection, virus -filtering, and content control. In general, Milter seeks to address -site-wide filtering concerns in a scalable way. Individual users' mail -filtering needs (e.g. sorting messages by subject) are left to -client-level programs such as <A href="http://www.procmail.org">Procmail</A>. - -<P> -This document is a technical introduction intended for those -interested in developing Milter filters. It includes: -<UL> -<LI>A description of Milter's design goals. - -<LI>An explanation of Milter application architecture, including -interactions between the support library and user code, and between -filters and the MTA. - -<LI>A specification of the C application programming interface. -<LI>An example of a simple Milter filter. -</UL> - -<H2>Contents</H2> - -<UL> -<LI><A href="design.html">Architecture</A> -<UL> - <LI>Design Goals - <LI>Implementing Filtering Policies - <LI>MTA - Filter communication -</UL> -<LI><A href="overview.html">Technical Overview</A> -<UL> - <LI>Initialization - <LI>Control flow - <LI>Multithreading - <LI>Resource Management - <LI>Signal Handling -</UL> -<LI><A href="api.html">API Documentation</A> -<UL> - <LI>Library Control Functions - <LI>Data Access Functions - <LI>Message Modification Functions - <LI>Callbacks -</UL> -<LI><A href="installation.html">Installation and Configuration</A> -<UL> - <LI>Compiling and Installing Your Filter - <LI>Configuring Sendmail -</UL> -<LI><A href="sample.html">A Sample Filter</A> -<!-- <LI><A href="other.html">Other Sources of Information</A> --> -</UL> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2001, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/installation.html b/contrib/sendmail/libmilter/docs/installation.html deleted file mode 100644 index 07142e9..0000000 --- a/contrib/sendmail/libmilter/docs/installation.html +++ /dev/null @@ -1,165 +0,0 @@ -<HTML> -<HEAD><TITLE>Installation and Configuration</TITLE> -</HEAD> -<BODY> -<!-- -$Id: installation.html,v 1.23 2006/08/31 17:16:03 ca Exp $ ---> -<H1>Installation</H1> -<H2>Contents</H2> -<UL> - <LI><A href="#compile">Compiling and Installing Your Filter</A> - <LI><A href="#config">Configuring Sendmail</A> -</UL> - -<H2><A name="compile">Compiling and Installing Your Filter</A></H2> - -To compile a filter, modify the Makefile provided with the sample program, or: -<UL> - <LI>Put the include and Sendmail directories in your include path - (e.g. -I/path/to/include -I/path/to/sendmail). - - <LI>Make sure libmilter.a is in your library path, and link your - application with it (e.g. "-lmilter"). - - <LI>Compile with pthreads, either by using -pthread for gcc, or - linking with a pthreads support library (-lpthread). -</UL> -Your compile command line will look like -<PRE> -cc -I/path/to/include -I/path/to/sendmail -c myfile.c -</PRE> -and your linking command line will look something like -<PRE> -cc -o myfilter [object-files] -L[library-location] -lmilter -pthread -</PRE> - -<H2><A name="config">Configuring Sendmail</A></H2> - -If you use a sendmail version older than 8.13 please see -the instructions for your version. -The default compilation options for sendmail enable support -for milters since 8.13. - -<P> -Next, you must add the desired filters to your sendmail configuration -(.mc) file. -Mail filters have three equates: -The required <CODE>S=</CODE> equate specifies the socket where -sendmail should look for the filter; the optional <CODE>F=</CODE> and -<CODE>T=</CODE> equates specify flags and timeouts, respectively. -All equates names, equate field names, and flag values are case sensitive. - -<P> -The current flags (<CODE>F=</CODE>) are: -<P> -<TABLE cellspacing="1" cellpadding=4 border=1> -<TR bgcolor="#dddddd" align=left valign=top> -<TH>Flag</TH> <TH align="center">Meaning</TH> -</TR> -<TR align="left" valign=top> -<TD>R</TD> <TD>Reject connection if filter unavailable</TD> -</TR> -<TR align="left" valign=top> -<TD>T</TD> <TD>Temporary fail connection if filter unavailable</TD> -</TR> -</TABLE> - -If a filter is unavailable or unresponsive and no flags have been -specified, the MTA will continue normal handling of the current -connection. -The MTA will try to contact the filter again on each new connection. - -<P> -There are three fields inside of the <CODE>T=</CODE> equate: S, R, and E. -Note the separator between each is a ";" (semicolon), as "," -(comma) already separates equates. -The value of each field is a decimal number followed by a single letter -designating the units ("s" for seconds, "m" for minutes). -The fields have the following meanings: -<P> -<TABLE cellspacing="1" cellpadding=4 border=1> -<TR bgcolor="#dddddd" align=left valign=top> -<TH>Flag</TH> <TH align="center">Meaning</TH> -</TR> -<TR align="left" valign=top> -<TD>C</TD> <TD>Timeout for connecting to a filter. If set to 0, the - system's <CODE>connect(2)</CODE> timeout will be used. - Default: 5m</TD> -</TR> -<TR align="left" valign=top> -<TD>S</TD> <TD>Timeout for sending information from the MTA to a - filter. Default: 10s</TD> -</TR> -<TR align="left" valign=top> -<TD>R</TD> <TD>Timeout for reading reply from the filter. Default: 10s</TD> -</TR> -<TR align="left" valign=top> -<TD>E</TD> <TD>Overall timeout between sending end-of-message to - filter and waiting for the final acknowledgment. Default: 5m</TD> -</TR> -</TABLE> - -<P> -The following sendmail.mc example specifies three filters. -The first two rendezvous on Unix-domain sockets in the /var/run directory; -the third uses an IP socket on port 999. -<PRE> - INPUT_MAIL_FILTER(`filter1', `S=unix:/var/run/f1.sock, F=R') - INPUT_MAIL_FILTER(`filter2', `S=unix:/var/run/f2.sock, F=T, T=S:1s;R:1s;E:5m') - INPUT_MAIL_FILTER(`filter3', `S=inet:999@localhost, T=C:2m') - - define(`confINPUT_MAIL_FILTERS', `filter2,filter1,filter3') -<HR width="30%"> - m4 ../m4/cf.m4 myconfig.mc > myconfig.cf -</PRE> -By default, the filters would be run in the order declared, -i.e. "filter1, filter2, filter3"; however, since -<CODE>confINPUT_MAIL_FILTERS</CODE> is defined, the filters will be -run "filter2, filter1, filter3". -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(). - -<P> -The above macros will result in the following lines being added to -your .cf file: -<PRE> - Xfilter1, S=unix:/var/run/f1.sock, F=R - Xfilter2, S=unix:/var/run/f2.sock, F=T, T=S:1s;R:1s;E:5m - Xfilter3, S=inet:999@localhost, T=C:2m - - O InputMailFilters=filter2,filter1,filter3 -</PRE> -<P> -Finally, the sendmail macros accessible via -<A HREF="smfi_getsymval.html">smfi_getsymval</A> can be configured by -defining the following m4 variables (or cf options): -<TABLE cellspacing="1" cellpadding=4 border=1> -<TR bgcolor="#dddddd" align=left valign=top> -<TH align="center">In .mc file</TH> <TH align="center">In .cf file</TH> -<TH align="center">Default Value</TH> -</TR> -<TR><TD>confMILTER_MACROS_CONNECT</TD><TD>Milter.macros.connect</TD> -<TD><CODE>j, _, {daemon_name}, {if_name}, {if_addr}</CODE></TD></TR> -<TR><TD>confMILTER_MACROS_HELO</TD><TD>Milter.macros.helo</TD> -<TD><CODE>{tls_version}, {cipher}, {cipher_bits}, {cert_subject}, -{cert_issuer}</CODE></TD></TR> -<TR><TD>confMILTER_MACROS_ENVFROM</TD><TD>Milter.macros.envfrom</TD> -<TD><CODE>i, {auth_type}, {auth_authen}, {auth_ssf}, {auth_author}, -{mail_mailer}, {mail_host}, {mail_addr}</CODE></TD></TR> -<TR><TD>confMILTER_MACROS_ENVRCPT</TD><TD>Milter.macros.envrcpt</TD> -<TD><CODE>{rcpt_mailer}, {rcpt_host}, {rcpt_addr}</CODE></TD></TR> -</TABLE> -For information about available macros and their meanings, please -consult the sendmail documentation. -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2003, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/other.html b/contrib/sendmail/libmilter/docs/other.html deleted file mode 100644 index c33b536..0000000 --- a/contrib/sendmail/libmilter/docs/other.html +++ /dev/null @@ -1,18 +0,0 @@ -<HTML> -<HEAD><TITLE>Other Resources</TITLE> -</HEAD> -<BODY> -<!-- -$Id: other.html,v 1.6 2006/08/08 20:55:57 ca Exp $ ---> -FAQ? Mailing list? More sample filters? -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/overview.html b/contrib/sendmail/libmilter/docs/overview.html deleted file mode 100644 index b7e80df..0000000 --- a/contrib/sendmail/libmilter/docs/overview.html +++ /dev/null @@ -1,215 +0,0 @@ -<HTML> -<HEAD> -<TITLE>Technical Overview</TITLE> -</HEAD> -<BODY> -<!-- -$Id: overview.html,v 1.19 2006/12/21 18:23:47 ca Exp $ ---> - -<H1>Technical Overview</H1> - -<H2>Contents</H2> - -<UL> - <LI><A HREF="#Initialization">Initialization</A> - <LI><A HREF="#ControlFlow">Control Flow</A> - <LI><A HREF="#Multithreading">Multithreading</A> - <LI><A HREF="#ResourceManagement">Resource Management</A> - <LI><A HREF="#SignalHandling">Signal Handling</A> -</UL> - -<H2><A NAME="Initialization">Initialization</A></H2> - -In addition to its own initialization, -libmilter expects a filter to initialize several parameters -before calling <A HREF="smfi_main.html">smfi_main</A>: -<UL> - <LI>The callbacks the filter wishes to be called, and the types of - message modification it intends to perform (required, see - <A HREF="smfi_register.html">smfi_register</A>). - - <LI>The socket address to be used when communicating with the MTA - (required, see <A HREF="smfi_setconn.html">smfi_setconn</A>). - - <LI>The number of seconds to wait for MTA connections before - timing out (optional, see - <A HREF="smfi_settimeout.html">smfi_settimeout</A>). -</UL> -<P> -If the filter fails to initialize libmilter, -or if one or more of the parameters it has passed are invalid, -a subsequent call to smfi_main will fail. - -<H2><A NAME="ControlFlow">Control Flow</A></H2> - -<P> -The following pseudocode describes the filtering process from the -perspective of a set of <CODE>N</CODE> MTA's, -each corresponding to a connection. -Callbacks are shown beside the processing stages in which they are invoked; -if no callbacks are defined for a particular stage, -that stage may be bypassed. -Though it is not shown, -processing may be aborted at any time during a message, -in which case the -<A HREF="xxfi_abort.html">xxfi_abort</A> callback is invoked and control -returns to <CODE>MESSAGE</CODE>. -<P> -<PRE> -For each of N connections -{ - For each filter - process connection/helo (<A HREF="xxfi_connect.html">xxfi_connect</A>, <A HREF="xxfi_helo.html">xxfi_helo</A>) -MESSAGE:For each message in this connection (sequentially) - { - For each filter - process sender (<A HREF="xxfi_envfrom.html">xxfi_envfrom</A>) - For each recipient - { - For each filter - process recipient (<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A>) - } - For each filter - { - process DATA (<A HREF="xxfi_data.html">xxfi_data</A>) - For each header - process header (<A HREF="xxfi_header.html">xxfi_header</A>) - process end of headers (<A HREF="xxfi_eoh.html">xxfi_eoh</A>) - For each body block - process this body block (<A HREF="xxfi_body.html">xxfi_body</A>) - process end of message (<A HREF="xxfi_eom.html">xxfi_eom</A>) - } - } - For each filter - process end of connection (<A HREF="xxfi_close.html">xxfi_close</A>) -} -</PRE> - -<P>Note: Filters are contacted in order defined in config file.</P> - -<P> -To write a filter, a vendor supplies callbacks to process relevant -parts of a message transaction. -The library then controls all sequencing, threading, -and protocol exchange with the MTA. -<A HREF="#figure-3">Figure 3</A> outlines control flow for a filter -process, showing where different callbacks are invoked. -</P> - -<DIV ALIGN="center"><A NAME="figure-3"></A> -<TABLE border=1 cellspacing=0 cellpadding=2 width="70%"> -<TR bgcolor="#dddddd"><TH>SMTP Commands</TH><TH>Milter Callbacks</TH></TR> -<TR><TD>(open SMTP connection)</TD><TD>xxfi_connect</TD></TR> -<TR><TD>HELO ...</TD><TD>xxfi_helo</TD></TR> -<TR><TD>MAIL From: ...</TD><TD>xxfi_envfrom</TD></TR> -<TR><TD>RCPT To: ...</TD><TD>xxfi_envrcpt</TD></TR> -<TR><TD>[more RCPTs]</TD><TD>[xxfi_envrcpt]</TD></TR> -<TR><TD>DATA</TD><TD>xxfi_data</TD></TR> -<TR><TD>Header: ...</TD><TD>xxfi_header</TD></TR> -<TR><TD>[more headers]</TD><TD>[xxfi_header]</TD></TR> -<TR><TD> </TD><TD>xxfi_eoh</TD></TR> -<TR><TD>body... </TD><TD>xxfi_body</TD></TR> -<TR><TD>[more body...]</TD><TD>[xxfi_body]</TD></TR> -<TR><TD>.</TD><TD>xxfi_eom</TD></TR> -<TR><TD>QUIT</TD><TD>xxfi_close</TD></TR> -<TR><TD>(close SMTP connection)</TD><TD> </TD></TR> -</TABLE> -<B>Figure 3: Milter callbacks related to an SMTP transaction.</B> -</DIV> - -<P> -Note that although only a single message is shown above, multiple -messages may be sent in a single connection. -Note also that a message or connection may be aborted by -either the remote host or the MTA -at any point during the SMTP transaction. -f this occurs during a message (between the MAIL command and the final "."), -the filter's -<A HREF="xxfi_abort.html">xxfi_abort</A> routine will be called. -<A HREF="xxfi_close.html">xxfi_close</A> is called any time the -connection closes. - -<H2><A NAME="Multithreading">Multithreading</A></H2> - -<P> -A single filter process may handle any number of connections -simultaneously. -All filtering callbacks must therefore be reentrant, -and use some appropriate external synchronization methods to access -global data. -Furthermore, since there is not a one-to-one correspondence -between threads and connections -(N connections mapped onto M threads, M <= N), -connection-specific data must be accessed -through the handles provided by the Milter library. -The programmer cannot rely on library-supplied thread-specific data blocks -(e.g., <CODE>pthread_getspecific(3)</CODE>) to store connection-specific data. -See the API documentation for -<A HREF="smfi_setpriv.html">smfi_setpriv</A> and -<A HREF="smfi_getpriv.html">smfi_getpriv</A> for details. - -<H2><A NAME="ResourceManagement">Resource Management</A></H2> - -Since filters are likely to be long-lived, -and to handle many connections, -proper deallocation of per-connection resources is important. -The lifetime of a connection is bracketed by calls to the -callbacks <A HREF="xxfi_connect.html">xxfi_connect</A> and -<A HREF="xxfi_close.html">xxfi_close</A>. -Therefore connection-specific -resources (accessed via <A HREF="smfi_getpriv.html">smfi_getpriv</A> -and <A HREF="smfi_setpriv.html">smfi_setpriv</A>) may be allocated in -<A HREF="xxfi_connect.html">xxfi_connect</A>, -and should be freed in -<A HREF="xxfi_close.html">xxfi_close</A>. -For further information see -the <A HREF="api.html#conn-msg">discussion</A> of message- versus -connection-oriented routines. -In particular, -note that there is only one connection-specific data pointer per connection. -<P> - -Each message is bracketed by calls to -<A HREF="xxfi_envfrom.html">xxfi_envfrom</A> and -<A HREF="xxfi_eom.html">xxfi_eom</A> (or -<A HREF="xxfi_abort.html">xxfi_abort</A>), -implying that message-specific resources can be allocated -and reclaimed in these routines. -Since the messages in a connection are processed sequentially by each filter, -there will be only one active message associated with a given -connection and filter (and connection-private data block). -These resources must still be accessed through -<A HREF="smfi_getpriv.html">smfi_getpriv</A> and -<A HREF="smfi_setpriv.html">smfi_setpriv</A>, -and must be reclaimed in -<A HREF="xxfi_abort.html">xxfi_abort</A>. - -<H2><A NAME="SignalHandling">Signal Handling</A></H2> - -libmilter takes care of signal handling, -the filters are not influenced directly by signals. -There are basically two types of signal handlers: - -<OL> -<LI><TT>Stop</TT>: no new connections from the MTA will be accepted, -but existing connections are allowed to continue. -<LI><TT>Abort</TT>: all filters will be stopped as soon as the next -communication with the MTA happens. -</OL> - -Filters are not terminated asynchronously -(except by signals that can't be caught). -In the case of <TT>Abort</TT> the -<A HREF="xxfi_abort.html">xxfi_abort</A> callback is invoked. - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2001, 2003, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/sample.html b/contrib/sendmail/libmilter/docs/sample.html deleted file mode 100644 index 48e25c5..0000000 --- a/contrib/sendmail/libmilter/docs/sample.html +++ /dev/null @@ -1,537 +0,0 @@ -<HTML> -<HEAD><TITLE>A Sample Filter</TITLE></HEAD> -<BODY> -<!-- -$Id: sample.html,v 1.22 2006/10/09 23:14:51 ca Exp $ ---> -<H1>A Sample Filter</H1> - -The following sample logs each message to a separate temporary file, -adds a recipient given with the -a flag, -and rejects a disallowed recipient address given with the -r flag. -It recognizes the following options: -<P> -<CENTER> -<TABLE border="1" cellpadding=2 cellspacing=1> -<TR><TD><CODE>-p port</CODE></TD><TD>The port through which the MTA will connect to the filter.</TD></TR> -<TR><TD><CODE>-t sec</CODE></TD><TD>The timeout value.</TD></TR> -<TR><TD><CODE>-r addr</CODE></TD><TD>A recipient to reject.</TD></TR> -<TR><TD><CODE>-a addr</CODE></TD><TD>A recipient to add.</TD></TR> -</TABLE> -</CENTER> -<HR> -<PRE> -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sysexits.h> -#include <unistd.h> - -#include "libmilter/mfapi.h" - -#ifndef bool -# define bool int -# define TRUE 1 -# define FALSE 0 -#endif /* ! bool */ - - -struct mlfiPriv -{ - char *mlfi_fname; - char *mlfi_connectfrom; - char *mlfi_helofrom; - FILE *mlfi_fp; -}; - -#define MLFIPRIV ((struct mlfiPriv *) <A href="smfi_getpriv.html">smfi_getpriv</A>(ctx)) - -extern sfsistat mlfi_cleanup(SMFICTX *, bool); - -/* recipients to add and reject (set with -a and -r options) */ -char *add = NULL; -char *reject = NULL; - -sfsistat -<A href="xxfi_connect.html">mlfi_connect</A>(ctx, hostname, hostaddr) - SMFICTX *ctx; - char *hostname; - _SOCK_ADDR *hostaddr; -{ - struct mlfiPriv *priv; - char *ident; - - /* allocate some private memory */ - priv = malloc(sizeof *priv); - if (priv == NULL) - { - /* can't accept this message right now */ - return SMFIS_TEMPFAIL; - } - memset(priv, '\0', sizeof *priv); - - /* save the private data */ - <A href="smfi_setpriv.html">smfi_setpriv</A>(ctx, priv); - - ident = <A href="smfi_getsymval.html">smfi_getsymval</A>(ctx, "_"); - if (ident == NULL) - ident = "???"; - if ((priv->mlfi_connectfrom = strdup(ident)) == NULL) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_helo.html">mlfi_helo</A>(ctx, helohost) - SMFICTX *ctx; - char *helohost; -{ - size_t len; - char *tls; - char *buf; - struct mlfiPriv *priv = MLFIPRIV; - - tls = <A href="smfi_getsymval.html">smfi_getsymval</A>(ctx, "{tls_version}"); - if (tls == NULL) - tls = "No TLS"; - if (helohost == NULL) - helohost = "???"; - len = strlen(tls) + strlen(helohost) + 3; - if ((buf = (char*) malloc(len)) == NULL) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - snprintf(buf, len, "%s, %s", helohost, tls); - if (priv->mlfi_helofrom != NULL) - free(priv->mlfi_helofrom); - priv->mlfi_helofrom = buf; - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_envfrom.html">mlfi_envfrom</A>(ctx, argv) - SMFICTX *ctx; - char **argv; -{ - int fd = -1; - int argc = 0; - struct mlfiPriv *priv = MLFIPRIV; - char *mailaddr = <A href="smfi_getsymval.html">smfi_getsymval</A>(ctx, "{mail_addr}"); - - /* open a file to store this message */ - if ((priv->mlfi_fname = strdup("/tmp/msg.XXXXXX")) == NULL) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - if ((fd = mkstemp(priv->mlfi_fname)) == -1) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - if ((priv->mlfi_fp = fdopen(fd, "w+")) == NULL) - { - (void) close(fd); - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - /* count the arguments */ - while (*argv++ != NULL) - ++argc; - - /* log the connection information we stored earlier: */ - if (fprintf(priv->mlfi_fp, "Connect from %s (%s)\n\n", - priv->mlfi_helofrom, priv->mlfi_connectfrom) == EOF) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - /* log the sender */ - if (fprintf(priv->mlfi_fp, "FROM %s (%d argument%s)\n", - mailaddr ? mailaddr : "???", argc, - (argc == 1) ? "" : "s") == EOF) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_envrcpt.html">mlfi_envrcpt</A>(ctx, argv) - SMFICTX *ctx; - char **argv; -{ - struct mlfiPriv *priv = MLFIPRIV; - char *rcptaddr = <A href="smfi_getsymval.html">smfi_getsymval</A>(ctx, "{rcpt_addr}"); - int argc = 0; - - /* count the arguments */ - while (*argv++ != NULL) - ++argc; - - /* log this recipient */ - if (reject != NULL && rcptaddr != NULL && - (strcasecmp(rcptaddr, reject) == 0)) - { - if (fprintf(priv->mlfi_fp, "RCPT %s -- REJECTED\n", - rcptaddr) == EOF) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - return SMFIS_REJECT; - } - if (fprintf(priv->mlfi_fp, "RCPT %s (%d argument%s)\n", - rcptaddr ? rcptaddr : "???", argc, - (argc == 1) ? "" : "s") == EOF) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_header.html">mlfi_header</A>(ctx, headerf, headerv) - SMFICTX *ctx; - char *headerf; - unsigned char *headerv; -{ - /* write the header to the log file */ - if (fprintf(MLFIPRIV->mlfi_fp, "%s: %s\n", headerf, headerv) == EOF) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_eoh.html">mlfi_eoh</A>(ctx) - SMFICTX *ctx; -{ - /* output the blank line between the header and the body */ - if (fprintf(MLFIPRIV->mlfi_fp, "\n") == EOF) - { - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_body.html">mlfi_body</A>(ctx, bodyp, bodylen) - SMFICTX *ctx; - unsigned char *bodyp; - size_t bodylen; -{ - struct mlfiPriv *priv = MLFIPRIV; - - /* output body block to log file */ - if (fwrite(bodyp, bodylen, 1, priv->mlfi_fp) != 1) - { - /* write failed */ - fprintf(stderr, "Couldn't write file %s: %s\n", - priv->mlfi_fname, strerror(errno)); - (void) mlfi_cleanup(ctx, FALSE); - return SMFIS_TEMPFAIL; - } - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_eom.html">mlfi_eom</A>(ctx) - SMFICTX *ctx; -{ - bool ok = TRUE; - - /* change recipients, if requested */ - if (add != NULL) - ok = (<A href="smfi_addrcpt.html">smfi_addrcpt</A>(ctx, add) == MI_SUCCESS); - return mlfi_cleanup(ctx, ok); -} - -sfsistat -<A href="xxfi_abort.html">mlfi_abort</A>(ctx) - SMFICTX *ctx; -{ - return mlfi_cleanup(ctx, FALSE); -} - -sfsistat -mlfi_cleanup(ctx, ok) - SMFICTX *ctx; - bool ok; -{ - sfsistat rstat = SMFIS_CONTINUE; - struct mlfiPriv *priv = MLFIPRIV; - char *p; - char host[512]; - char hbuf[1024]; - - if (priv == NULL) - return rstat; - - /* close the archive file */ - if (priv->mlfi_fp != NULL && fclose(priv->mlfi_fp) == EOF) - { - /* failed; we have to wait until later */ - fprintf(stderr, "Couldn't close archive file %s: %s\n", - priv->mlfi_fname, strerror(errno)); - rstat = SMFIS_TEMPFAIL; - (void) unlink(priv->mlfi_fname); - } - else if (ok) - { - /* add a header to the message announcing our presence */ - if (gethostname(host, sizeof host) < 0) - snprintf(host, sizeof host, "localhost"); - p = strrchr(priv->mlfi_fname, '/'); - if (p == NULL) - p = priv->mlfi_fname; - else - p++; - snprintf(hbuf, sizeof hbuf, "%s@%s", p, host); - if (<A href="smfi_addheader.html">smfi_addheader</A>(ctx, "X-Archived", hbuf) != MI_SUCCESS) - { - /* failed; we have to wait until later */ - fprintf(stderr, - "Couldn't add header: X-Archived: %s\n", - hbuf); - ok = FALSE; - rstat = SMFIS_TEMPFAIL; - (void) unlink(priv->mlfi_fname); - } - } - else - { - /* message was aborted -- delete the archive file */ - fprintf(stderr, "Message aborted. Removing %s\n", - priv->mlfi_fname); - rstat = SMFIS_TEMPFAIL; - (void) unlink(priv->mlfi_fname); - } - - /* release private memory */ - if (priv->mlfi_fname != NULL) - free(priv->mlfi_fname); - - /* return status */ - return rstat; -} - -sfsistat -<A href="xxfi_close.html">mlfi_close</A>(ctx) - SMFICTX *ctx; -{ - struct mlfiPriv *priv = MLFIPRIV; - - if (priv == NULL) - return SMFIS_CONTINUE; - if (priv->mlfi_connectfrom != NULL) - free(priv->mlfi_connectfrom); - if (priv->mlfi_helofrom != NULL) - free(priv->mlfi_helofrom); - free(priv); - <A href="smfi_setpriv.html">smfi_setpriv</A>(ctx, NULL); - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_unknown.html">mlfi_unknown</A>(ctx, cmd) - SMFICTX *ctx; - char *cmd; -{ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_data.html">mlfi_data</A>(ctx) - SMFICTX *ctx; -{ - return SMFIS_CONTINUE; -} - -sfsistat -<A href="xxfi_negotiate.html">mlfi_negotiate</A>(ctx, f0, f1, f2, f3, pf0, pf1, pf2, pf3) - SMFICTX *ctx; - unsigned long f0; - unsigned long f1; - unsigned long f2; - unsigned long f3; - unsigned long *pf0; - unsigned long *pf1; - unsigned long *pf2; - unsigned long *pf3; -{ - return SMFIS_ALL_OPTS; -} - -struct smfiDesc smfilter = -{ - "SampleFilter", /* filter name */ - SMFI_VERSION, /* version code -- do not change */ - SMFIF_ADDHDRS|SMFIF_ADDRCPT, - /* flags */ - <A href="xxfi_connect.html">mlfi_connect</A>, /* connection info filter */ - <A href="xxfi_helo.html">mlfi_helo</A>, /* SMTP HELO command filter */ - <A href="xxfi_envfrom.html">mlfi_envfrom</A>, /* envelope sender filter */ - <A href="xxfi_envrcpt.html">mlfi_envrcpt</A>, /* envelope recipient filter */ - <A href="xxfi_header.html">mlfi_header</A>, /* header filter */ - <A href="xxfi_eoh.html">mlfi_eoh</A>, /* end of header */ - <A href="xxfi_body.html">mlfi_body</A>, /* body block filter */ - <A href="xxfi_eom.html">mlfi_eom</A>, /* end of message */ - <A href="xxfi_abort.html">mlfi_abort</A>, /* message aborted */ - <A href="xxfi_close.html">mlfi_close</A>, /* connection cleanup */ - <A href="xxfi_unknown.html">mlfi_unknown</A>, /* unknown SMTP commands */ - <A href="xxfi_data.html">mlfi_data</A>, /* DATA command */ - <A href="xxfi_negotiate.html">mlfi_negotiate</A> /* Once, at the start of each SMTP connection */ -}; - -static void -usage(prog) - char *prog; -{ - fprintf(stderr, - "Usage: %s -p socket-addr [-t timeout] [-r reject-addr] [-a add-addr]\n", - prog); -} - -int -main(argc, argv) - int argc; - char **argv; -{ - bool setconn = FALSE; - int c; - const char *args = "p:t:r:a:h"; - extern char *optarg; - - /* Process command line options */ - while ((c = getopt(argc, argv, args)) != -1) - { - switch (c) - { - case 'p': - if (optarg == NULL || *optarg == '\0') - { - (void) fprintf(stderr, "Illegal conn: %s\n", - optarg); - exit(EX_USAGE); - } - if (<A href="smfi_setconn.html">smfi_setconn</A>(optarg) == MI_FAILURE) - { - (void) fprintf(stderr, - "smfi_setconn failed\n"); - exit(EX_SOFTWARE); - } - - /* - ** If we're using a local socket, make sure it - ** doesn't already exist. Don't ever run this - ** code as root!! - */ - - if (strncasecmp(optarg, "unix:", 5) == 0) - unlink(optarg + 5); - else if (strncasecmp(optarg, "local:", 6) == 0) - unlink(optarg + 6); - setconn = TRUE; - break; - - case 't': - if (optarg == NULL || *optarg == '\0') - { - (void) fprintf(stderr, "Illegal timeout: %s\n", - optarg); - exit(EX_USAGE); - } - if (<A href="smfi_settimeout.html">smfi_settimeout</A>(atoi(optarg)) == MI_FAILURE) - { - (void) fprintf(stderr, - "smfi_settimeout failed\n"); - exit(EX_SOFTWARE); - } - break; - - case 'r': - if (optarg == NULL) - { - (void) fprintf(stderr, - "Illegal reject rcpt: %s\n", - optarg); - exit(EX_USAGE); - } - reject = optarg; - break; - - case 'a': - if (optarg == NULL) - { - (void) fprintf(stderr, - "Illegal add rcpt: %s\n", - optarg); - exit(EX_USAGE); - } - add = optarg; - smfilter.xxfi_flags |= SMFIF_ADDRCPT; - break; - - case 'h': - default: - usage(argv[0]); - exit(EX_USAGE); - } - } - if (!setconn) - { - fprintf(stderr, "%s: Missing required -p argument\n", argv[0]); - usage(argv[0]); - exit(EX_USAGE); - } - if (<A href="smfi_register.html">smfi_register</A>(smfilter) == MI_FAILURE) - { - fprintf(stderr, "smfi_register failed\n"); - exit(EX_UNAVAILABLE); - } - return <A href="smfi_main.html">smfi_main</A>(); -} - -/* eof */ - -</PRE> -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2004, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_addheader.html b/contrib/sendmail/libmilter/docs/smfi_addheader.html deleted file mode 100644 index d068f9f..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_addheader.html +++ /dev/null @@ -1,126 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_addheader</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_addheader.html,v 1.19 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_addheader</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_addheader( - SMFICTX *ctx, - char *headerf, - char *headerv -); -</PRE> -Add a header to the current message. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Adds a header to the current message.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>headerf</TD> - <TD>The header name, a non-NULL, null-terminated string. - </TD></TR> - <TR valign="top"><TD>headerv</TD> - <TD>The header value to be added, a non-NULL, null-terminated string. - This may be the empty string. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_addheader returns MI_FAILURE if: -<UL><LI>headerf or headerv is NULL. - <LI>Adding headers in the current connection state is invalid. - <LI>Memory allocation fails. - <LI>A network error occurs. - <LI>SMFIF_ADDHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it returns MI_SUCCESS. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -<UL><LI>smfi_addheader does not change a message's existing headers. -To change a header's current value, use -<A HREF="smfi_chgheader.html">smfi_chgheader</A>. - <LI>A filter which calls smfi_addheader must have set the SMFIF_ADDHDRS - flag in the smfiDesc_str passed to - <A href="smfi_register.html">smfi_register</A>. - <LI>For smfi_addheader, filter order is important. - <B>Later filters will see the header changes made by earlier ones.</B> - <LI>Neither the name nor the value of the header is checked for - standards compliance. - However, each line of the header must be under 2048 characters - and should be under 998 characters. - If longer headers are needed, make them multi-line. - To make a multi-line header, - insert a line feed (ASCII 0x0a, or <TT>\n</TT> in C) - followed by at least one whitespace character - such as a space (ASCII 0x20) or tab (ASCII 0x09, or <TT>\t</TT> in C). - The line feed should NOT be preceded by a carriage return (ASCII 0x0d); - the MTA will add this automatically. - <B>It is the filter writer's responsibility to ensure that no standards - are violated.</B> - <LI>The MTA adds a leading space to an added header value. -</UL> -</TD> -</TR> - -<!----------- Example code ----------> -<TR> -<TH valign="top" align=left>EXAMPLE</TH> - -<TD> - <PRE> - int ret; - SMFICTX *ctx; - - ... - - ret = smfi_addheader(ctx, "Content-Type", - "multipart/mixed;\n\tboundary=\"foobar\""); - </PRE> -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2003, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_addrcpt.html b/contrib/sendmail/libmilter/docs/smfi_addrcpt.html deleted file mode 100644 index cf997e5..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_addrcpt.html +++ /dev/null @@ -1,83 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_addrcpt</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_addrcpt.html,v 1.11 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_addrcpt</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_addrcpt( - SMFICTX *ctx, - char *rcpt -); -</PRE> -Add a recipient for the current message. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Add a recipient to the message envelope.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>rcpt</TD> - <TD>The new recipient's address. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_addrcpt will fail and return MI_FAILURE if: -<UL><LI>rcpt is NULL. - <LI>Adding recipients in the current connection state is invalid. - <LI>A network error occurs. - <LI>SMFIF_ADDRCPT was not set when <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it will return MI_SUCCESS. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -A filter which calls smfi_addrcpt must have set the SMFIF_ADDRCPT flag -in the smfiDesc_str passed to -<A href="smfi_register.html">smfi_register</A>. -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_addrcpt_par.html b/contrib/sendmail/libmilter/docs/smfi_addrcpt_par.html deleted file mode 100644 index 776b02c..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_addrcpt_par.html +++ /dev/null @@ -1,88 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_addrcpt_par</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_addrcpt_par.html,v 1.4 2007/03/19 16:38:02 ca Exp $ ---> -<H1>smfi_addrcpt_par</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_addrcpt_par( - SMFICTX *ctx, - char *rcpt, - char *args -); -</PRE> -Add a recipient for the current message including ESMTP arguments. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Add a recipient to the message envelope.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>rcpt</TD> - <TD>The new recipient's address. - </TD></TR> - <TR valign="top"><TD>args</TD> - <TD>The new recipient's ESMTP parameters. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_addrcpt will fail and return MI_FAILURE if: -<UL><LI>rcpt is NULL. - <LI>Adding recipients in the current connection state is invalid. - <LI>A network error occurs. - <LI>SMFIF_ADDRCPT_PAR was not set when - <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it will return MI_SUCCESS. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -A filter which calls smfi_addrcpt must have set the SMFIF_ADDRCPT_PAR flag -in the smfiDesc_str passed to -<A href="smfi_register.html">smfi_register</A>. -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_chgfrom.html b/contrib/sendmail/libmilter/docs/smfi_chgfrom.html deleted file mode 100644 index e8249e0..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_chgfrom.html +++ /dev/null @@ -1,94 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_chgfrom</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_chgfrom.html,v 1.3 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_chgfrom</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_chgfrom( - SMFICTX *ctx, - const char *mail, - char *args -); -</PRE> -Change the envelope sender (MAIL From) of the current message. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Change the envelope sender (MAIL From) of the current message.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>mail</TD> - <TD>The new sender address. - </TD></TR> - <TR valign="top"><TD>args</TD> - <TD>ESMTP arguments. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_chgfrom will fail and return MI_FAILURE if: -<UL><LI>mail is NULL. - <LI>Changing the sender in the current connection state is invalid. - <LI>A network error occurs. - <LI>SMFIF_CHGFROM was not set when <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it will return MI_SUCCESS. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -A filter which calls smfi_chgfrom must have set the SMFIF_CHGFROM flag -in the smfiDesc_str passed to -<A href="smfi_register.html">smfi_register</A>. -<BR> -Even though all ESMTP arguments could be set via this call, -it does not make sense to do so for many of them, -e.g., SIZE and BODY. -Setting those may cause problems, proper care must be taken. -Moreover, there is no feedback from the MTA to the milter -whether the call was successful. -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_chgheader.html b/contrib/sendmail/libmilter/docs/smfi_chgheader.html deleted file mode 100644 index 0701a36..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_chgheader.html +++ /dev/null @@ -1,120 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_chgheader</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_chgheader.html,v 1.17 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_chgheader</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_chgheader( - SMFICTX *ctx, - char *headerf, - mi_int32 hdridx, - char *headerv -); -</PRE> -Change or delete a message header. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Changes a header's value for the current message.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>headerf</TD> - <TD>The header name, a non-NULL, null-terminated string. - </TD></TR> - <TR valign="top"><TD>hdridx</TD> - <TD>Header index value (1-based). A hdridx value of 1 will modify the first occurrence of a header named headerf. If hdridx is greater than the number of times headerf appears, a new copy of headerf will be added. - </TD></TR> - <TR valign="top"><TD>headerv</TD> - <TD>The new value of the given header. headerv == NULL implies that the header should be deleted. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD> -smfi_chgheader will return MI_FAILURE if -<UL><LI>headerf is NULL - <LI>Modifying headers in the current connection state is invalid. - <LI>Memory allocation fails. - <LI>A network error occurs. - <LI>SMFIF_CHGHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it returns MI_SUCCESS. -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -<UL><LI>While smfi_chgheader may be used to add new headers, it is more efficient and far safer to use <A href="smfi_addheader.html">smfi_addheader</A>. - <LI>A filter which calls smfi_chgheader must have set the SMFIF_CHGHDRS flag in the smfiDesc_str passed to <A href="smfi_register.html">smfi_register</A>. - <LI>For smfi_chgheader, filter order is important. <B>Later filters will see the header changes made by earlier ones.</B> - <LI>Neither the name nor the value of the header is checked for - standards compliance. However, each line of the header must be under - 2048 characters and should be under 998 characters. If longer headers - are needed, make them multi-line. To make a multi-line header, insert - a line feed (ASCII 0x0a, or <TT>\n</TT> in C) followed by at least - one whitespace character such as a space (ASCII 0x20) or tab (ASCII 0x09, - or <TT>\t</TT> in C). The line feed should NOT be preceded by a - carriage return (ASCII 0x0d); the MTA will add this automatically. - <B>It is the filter writer's responsibility to ensure that no standards - are violated.</B> -</UL> -</TD> -</TR> - -<!----------- Example code ----------> -<TR> -<TH valign="top" align=left>EXAMPLE</TH> - -<TD> - <PRE> - int ret; - SMFICTX *ctx; - - ... - - ret = smfi_chgheader(ctx, "Content-Type", 1, - "multipart/mixed;\n\tboundary=\"foobar\""); - </PRE> -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_delrcpt.html b/contrib/sendmail/libmilter/docs/smfi_delrcpt.html deleted file mode 100644 index c43dcd6..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_delrcpt.html +++ /dev/null @@ -1,82 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_delrcpt</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_delrcpt.html,v 1.11 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_delrcpt</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_delrcpt( - SMFICTX *ctx; - char *rcpt; -); -</PRE> -Remove a recipient from the current message's envelope. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>smfi_delrcpt removes the named recipient from the current message's envelope.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>rcpt</TD> - <TD>The recipient address to be removed, a non-NULL, null-terminated string. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_delrcpt will fail and return MI_FAILURE if: -<UL> - <LI>rcpt is NULL. - <LI>Deleting recipients in the current connection state is invalid. - <LI>A network error occurs. - <LI>SMFIF_DELRCPT was not set when <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it will return MI_SUCCESS -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -The addresses to be removed must match exactly. For example, an address and its expanded form do not match. -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_getpriv.html b/contrib/sendmail/libmilter/docs/smfi_getpriv.html deleted file mode 100644 index 9584b9e..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_getpriv.html +++ /dev/null @@ -1,62 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_getpriv</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_getpriv.html,v 1.9 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_getpriv</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -void* smfi_getpriv( - SMFICTX *ctx -); -</PRE> -Get the connection-specific data pointer for this connection. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_getpriv may be called in any of the xxfi_* callbacks.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>None.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_getpriv returns the private data pointer stored by a prior call to <A href="smfi_setpriv.html">smfi_setpriv</A>, or NULL if none has been set.</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_getsymval.html b/contrib/sendmail/libmilter/docs/smfi_getsymval.html deleted file mode 100644 index 671dbfa..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_getsymval.html +++ /dev/null @@ -1,105 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_getsymval</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_getsymval.html,v 1.15 2007/03/19 16:49:11 ca Exp $ ---> -<H1>smfi_getsymval</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -char* smfi_getsymval( - SMFICTX *ctx, - char *symname -); -</PRE> -Get the value of a sendmail macro. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_getsymval may be called from within any of the xxfi_* callbacks. Which macros are defined will depend on when it is called.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>None.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>The opaque context structure. - </TD></TR> - <TR valign="top"><TD>symname</TD> - <TD>The name of a sendmail macro. - Single letter macros can optionally be enclosed in braces ("{" and "}"), - longer macro names must be enclosed in braces, just as in a - <TT>sendmail.cf</TT> file. - <A href="#notes">See below</A> for default macros. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_getsymval returns the value of the given macro as a null-terminated string, or NULL if the macro is not defined.</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH><A name="notes">NOTES</A></TH> -<TD> -By default, the following macros are valid in the given contexts: - -<TABLE border="1" cellspacing=0> -<TR bgcolor="#dddddd"><TH>Sent With</TH><TH>Macros</TH></TR> -<TR><TD>xxfi_connect</TD> <TD>daemon_name, if_name, if_addr, j, _</TD></TR> -<TR><TD>xxfi_helo</TD> <TD>tls_version, cipher, cipher_bits, cert_subject, cert_issuer</TD></TR> -<TR><TD>xxfi_envfrom</TD> <TD>i, auth_type, auth_authen, auth_ssf, auth_author, - mail_mailer, mail_host, mail_addr</TD></TR> -<TR><TD>xxfi_envrcpt</TD> <TD>rcpt_mailer, rcpt_host, rcpt_addr</TD></TR> - -<TR><TD>xxfi_data</TD> <TD>(none)</TD></TR> -<TR><TD>xxfi_eoh</TD> <TD>(none)</TD></TR> -<TR><TD>xxfi_eom</TD> <TD>msg_id</TD></TR> -</TABLE> -<P> -All macros stay in effect from the point they are received -until the end of the connection for the first two sets, -the end of the message for the third (xxfi_envfrom) and last (xxfi_eom), -and just for each recipient for xxfi_envrcpt. -<P> -The macro list can be changed using the confMILTER_MACROS_* options in -sendmail.mc. -The scopes of such macros will be determined by when they are set by sendmail. -For descriptions of macros' values, -please see the -"Sendmail Installation and Operation Guide" -provided with your sendmail distribution. - -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2002-2003, 2007 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_insheader.html b/contrib/sendmail/libmilter/docs/smfi_insheader.html deleted file mode 100644 index a4ba77f..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_insheader.html +++ /dev/null @@ -1,145 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_insheader</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_insheader.html,v 1.9 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_insheader</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_insheader( - SMFICTX *ctx, - int hdridx, - char *headerf, - char *headerv -); -</PRE> -Prepend a header to the current message. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Prepends a header to the current message.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>hdridx</TD> - <TD>The location in the internal header list where this header should - be inserted; 0 makes it the topmost header, etc. - </TD></TR> - <TR valign="top"><TD>headerf</TD> - <TD>The header name, a non-NULL, null-terminated string. - </TD></TR> - <TR valign="top"><TD>headerv</TD> - <TD>The header value to be added, a non-NULL, null-terminated string. This may be the empty string. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_insheader returns MI_FAILURE if: -<UL><LI>headerf or headerv is NULL. - <LI>Adding headers in the current connection state is invalid. - <LI>Memory allocation fails. - <LI>A network error occurs. - <LI>SMFIF_ADDHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it returns MI_SUCCESS. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -<UL> - <LI>smfi_insheader does not change a message's existing headers. - To change a header's current value, use - <A HREF="smfi_chgheader.html">smfi_chgheader</A>. - <LI>A filter which calls smfi_insheader must have set the SMFIF_ADDHDRS - flag in the smfiDesc_str passed to - <A href="smfi_register.html">smfi_register</A>. - <LI>For smfi_insheader, filter order is important. - <B>Later filters will see the header changes made by earlier ones.</B> - <LI>A filter will receive <EM>only</EM> headers that have been sent - by the SMTP client and those header modifications by earlier filters. - It will <EM>not</EM> receive the headers that are inserted by sendmail - itself. - This makes the header insertion position highly dependent on - the headers that exist in the incoming message - and those that are configured to be added by sendmail. - For example, sendmail will always add a - <CODE>Received:</CODE> header to the beginning of the headers. - Setting <CODE>hdridx</CODE> to 0 will actually insert the header - before this <CODE>Received:</CODE> header. - However, later filters can be easily confused as they receive - the added header, but not the <CODE>Received:</CODE> header, - thus making it hard to insert a header at a fixed position. - <LI>If hdridx is a number larger than the number of headers in the message, - the header will simply be appended. - <LI>Neither the name nor the value of the header is checked for - standards compliance. - However, each line of the header must be under 2048 characters - and should be under 998 characters. - If longer headers are needed, make them multi-line. - To make a multi-line header, - insert a line feed (ASCII 0x0a, or <TT>\n</TT> in C) - followed by at least one whitespace character - such as a space (ASCII 0x20) or tab (ASCII 0x09, or <TT>\t</TT> in C). - The line feed should NOT be preceded by a carriage return (ASCII 0x0d); - the MTA will add this automatically. - <B>It is the filter writer's responsibility to ensure that no standards - are violated.</B> -</UL> -</TD> -</TR> - -<!----------- Example code ----------> -<TR> -<TH valign="top" align=left>EXAMPLE</TH> - -<TD> - <PRE> - int ret; - SMFICTX *ctx; - - ... - - ret = smfi_insheader(ctx, 0, "First", "See me?"); - </PRE> -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2004, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_main.html b/contrib/sendmail/libmilter/docs/smfi_main.html deleted file mode 100644 index a749386..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_main.html +++ /dev/null @@ -1,51 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_main</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_main.html,v 1.9 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_main</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_main( -); -</PRE> -Hand control to libmilter event loop. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_main is called after a filter's initialization is complete.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>smfi_main hands control to the Milter event loop.</TD> -</TR> -</TABLE> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_main will return MI_FAILURE if it fails to establish a connection. This may occur for any of a variety of reasons (e.g. invalid address passed to <A href="smfi_setconn.html">smfi_setconn</A>). The reason for the failure will be logged. Otherwise, smfi_main will return MI_SUCCESS.</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_opensocket.html b/contrib/sendmail/libmilter/docs/smfi_opensocket.html deleted file mode 100644 index 151af07..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_opensocket.html +++ /dev/null @@ -1,78 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_opensocket</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_opensocket.html,v 1.6 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_opensocket</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_opensocket( - bool rmsocket -); -</PRE> -Attempt to create the interface socket MTAs will use to connect to the -filter. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from program mainline, before calling -<TT>smfi_main()</TT>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>smfi_opensocket attempts to create the socket specified previously by -a call to <TT>smfi_setconn()</TT> which will be the interface between MTAs -and the filter. This allows the calling application to ensure that the -socket can be created. If this is not called, <TT>smfi_main()</TT> will -do so implicitly. </TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>rmsocket</TD> - <TD>A flag indicating whether or not the library should try to - remove any existing UNIX domain socket before trying to create - a new one. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_opensocket will fail and return MI_FAILURE if: -<UL> - <LI>The interface socket could not be created for any reason. - <LI><TT>rmsocket</TT> was <TT>true</TT>, and either the socket could - not be examined, or exists and could not be removed. - <LI><TT>smfi_setconn()</TT> has not been called. -</UL> -Otherwise, it will return MI_SUCCESS -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_progress.html b/contrib/sendmail/libmilter/docs/smfi_progress.html deleted file mode 100644 index 801bdf3..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_progress.html +++ /dev/null @@ -1,68 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_progress</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_progress.html,v 1.5 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_progress</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_progress( - SMFICTX *ctx; -); -</PRE> -Notify the MTA that an operation is still in progress. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>smfi_progress notifies the MTA that the filter is still working -on a message, causing the MTA to re-start its timeouts.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_progress will fail and return MI_FAILURE if: -<UL> - <LI>A network error occurs. -</UL> -Otherwise, it will return MI_SUCCESS -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_quarantine.html b/contrib/sendmail/libmilter/docs/smfi_quarantine.html deleted file mode 100644 index 656a480..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_quarantine.html +++ /dev/null @@ -1,73 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_quarantine</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_quarantine.html,v 1.5 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_quarantine</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_quarantine( - SMFICTX *ctx; - char *reason; -); -</PRE> -Quarantine the message using the given reason. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>smfi_quarantine quarantines the message using the given reason.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>reason</TD> - <TD>The quarantine reason, a non-NULL and non-empty null-terminated string. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_quarantine will fail and return MI_FAILURE if: -<UL> - <LI>reason is NULL or empty. - <LI>A network error occurs. - <LI>SMFIF_QUARANTINE was not set when <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it will return MI_SUCCESS -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2002-2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_register.html b/contrib/sendmail/libmilter/docs/smfi_register.html deleted file mode 100644 index 1a35918..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_register.html +++ /dev/null @@ -1,224 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_register</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_register.html,v 1.18 2006/12/20 18:37:11 ca Exp $ ---> -<H1>smfi_register</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_register( - smfiDesc descr -); -</PRE> -Register a set of filter callbacks. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=1> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_register must be called before smfi_main</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>smfi_register creates a filter using the information given in the -smfiDesc argument. -Multiple (successful) calls to smfi_register within a -single process are not allowed, -i.e., only one filter can be successfully registered. -Note, however, that the library may not check whether this restriction -is obeyed. -</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>descr</TD> - <TD> -A filter descriptor of type smfiDesc describing the filter's functions. -<A NAME="smfiDesc">The structure</A> has the following members: -<PRE> -struct smfiDesc -{ - char *xxfi_name; /* filter name */ - int xxfi_version; /* version code -- do not change */ - unsigned long xxfi_flags; /* <A href="#flags">flags</A> */ - - /* connection info filter */ - sfsistat (*<A href="xxfi_connect.html">xxfi_connect</A>)(SMFICTX *, char *, _SOCK_ADDR *); - /* SMTP HELO command filter */ - sfsistat (*<A href="xxfi_helo.html">xxfi_helo</A>)(SMFICTX *, char *); - /* envelope sender filter */ - sfsistat (*<A href="xxfi_envfrom.html">xxfi_envfrom</A>)(SMFICTX *, char **); - /* envelope recipient filter */ - sfsistat (*<A href="xxfi_envrcpt.html">xxfi_envrcpt</A>)(SMFICTX *, char **); - /* header filter */ - sfsistat (*<A href="xxfi_header.html">xxfi_header</A>)(SMFICTX *, char *, char *); - /* end of header */ - sfsistat (*<A href="xxfi_eoh.html">xxfi_eoh</A>)(SMFICTX *); - /* body block */ - sfsistat (*<A href="xxfi_body.html">xxfi_body</A>)(SMFICTX *, unsigned char *, size_t); - /* end of message */ - sfsistat (*<A href="xxfi_eom.html">xxfi_eom</A>)(SMFICTX *); - /* message aborted */ - sfsistat (*<A href="xxfi_abort.html">xxfi_abort</A>)(SMFICTX *); - /* connection cleanup */ - sfsistat (*<A href="xxfi_close.html">xxfi_close</A>)(SMFICTX *); - - /* any unrecognized or unimplemented command filter */ - sfsistat (*xxfi_unknown)(SMFICTX *, const char *); - - /* SMTP DATA command filter */ - sfsistat (*xxfi_data)(SMFICTX *); - - /* negotiation callback */ - sfsistat (*<A HREF="xxfi_negotiate.html">xxfi_negotiate</A>)(SMFICTX *, - unsigned long, unsigned long, unsigned long, unsigned long, - unsigned long *, unsigned long *, unsigned long *, unsigned long *); -}; -</PRE> - -A NULL value for any callback function indicates that the filter -does not wish to process the given type of information, -simply returning SMFIS_CONTINUE. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD> -smfi_register may return MI_FAILURE for any of the following reasons: -<UL> -<LI>memory allocation failed. -<LI>incompatible version or illegal flags value. -</UL> - -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> - -<A NAME="flags">The xxfi_flags</A> -field should contain the bitwise OR of zero or more of -the following values, describing the actions the filter may take: -<TABLE BORDER CELLPADDING="1" cellspacing=1> -<TR valign="top" bgcolor="#dddddd"><TH align="left">Flag</TH><TH align="center">Description</TH></TR> - <TR align="left" valign=top> - <TD> - SMFIF_ADDHDRS - </TD> - <TD> - This filter may <A HREF="smfi_addheader.html">add headers</A>. - </TD> - </TR> - <TR align="left" valign=top> - <TD> - SMFIF_CHGHDRS - </TD> - <TD> - This filter may - <A HREF="smfi_chgheader.html">change and/or delete headers</A>. - </TD> - </TR> - <TR align="left" valign=top> - <TD VALIGN="TOP"> - SMFIF_CHGBODY - </TD> - <TD> - This filter may - <A HREF="smfi_replacebody.html">replace the body</A> during filtering. - This may have significant performance impact - if other filters do body filtering after this filter. - </TD> - </TR> - <TR> - <TD VALIGN="TOP"> - SMFIF_ADDRCPT - </TD> - <TD> - This filter may - <A HREF="smfi_addrcpt.html">add recipients</A> - to the message. - </TD> - </TR> - <TR> - <TD VALIGN="TOP"> - SMFIF_ADDRCPT_PAR - </TD> - <TD> - This filter may - <A HREF="smfi_addrcpt_par.html">add recipients including ESMTP args</A>. - </TD> - </TR> - <TR> - <TD VALIGN="TOP"> - SMFIF_DELRCPT - </TD> - <TD> - This filter may - <A HREF="smfi_delrcpt.html">remove recipients</A> from the message. - </TD> - </TR> - <TR> - <TD VALIGN="TOP"> - SMFIF_QUARANTINE - </TD> - <TD> - This filter may - <A HREF="smfi_quarantine.html">quarantine</A> a message. - </TD> - </TR> - - <TR> - <TD VALIGN="TOP"> - SMFIF_CHGFROM - </TD> - <TD> - This filter may - <A HREF="smfi_chgfrom.html">change the envelope sender</A> (MAIL). - </TD> - </TR> - - <TR> - <TD VALIGN="TOP"> - SMFIF_SETSYMLIST - </TD> - <TD> - This filter can - <A HREF="smfi_setsymlist.html">send a set of symbols (macros)</A> - that it wants. - </TD> - </TR> - -</TABLE> - -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2001, 2003, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_replacebody.html b/contrib/sendmail/libmilter/docs/smfi_replacebody.html deleted file mode 100644 index bc8d5ac..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_replacebody.html +++ /dev/null @@ -1,93 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_replacebody</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_replacebody.html,v 1.15 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_replacebody</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_replacebody( - SMFICTX *ctx, - unsigned char *bodyp, - int bodylen -); -</PRE> -Replace message-body data. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>. smfi_replacebody may be called more than once.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>smfi_replacebody replaces the body of the current message. If called -more than once, subsequent calls result in data being appended to the new -body. -</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>bodyp</TD> - <TD>A pointer to the start of the new body data, which does not have to be null-terminated. If bodyp is NULL, it is treated as having length == 0. Body data should be in CR/LF form. - </TD></TR> - <TR valign="top"><TD>bodylen</TD> - <TD>The number of data bytes pointed to by bodyp. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_replacebody fails and returns MI_FAILURE if: -<UL> - <LI>bodyp == NULL and bodylen > 0. - <LI>Changing the body in the current connection state is invalid. - <LI>A network error occurs. - <LI>SMFIF_CHGBODY was not set when <A href="smfi_register.html">smfi_register</A> was called. -</UL> -Otherwise, it will return MI_SUCCESS. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -<UL> - <LI>Since the message body may be very large, setting SMFIF_CHGBODY may significantly affect filter performance. - <LI>If a filter sets SMFIF_CHGBODY but does not call smfi_replacebody, the original body remains unchanged. - <LI>For smfi_replacebody, filter order is important. <B>Later filters will see the new body contents created by earlier ones.</B> -</UL> -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_setbacklog.html b/contrib/sendmail/libmilter/docs/smfi_setbacklog.html deleted file mode 100644 index 8353cac..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_setbacklog.html +++ /dev/null @@ -1,64 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_setbacklog</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_setbacklog.html,v 1.6 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_setbacklog</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_setbacklog( - int obacklog -); -</PRE> -Set the filter's <CODE>listen(2)</CODE> backlog value. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_setbacklog should only be called before <A href="smfi_main.html">smfi_main</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Sets the incoming socket backlog used by <CODE>listen(2)</CODE>. -If smfi_setbacklog is not called, the operating system default is used.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>obacklog</TD> - <TD>The number of incoming connections to allow in the listen queue. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_setbacklog returns MI_FAILURE if obacklog is less than or equal -to zero.</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2002-2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_setconn.html b/contrib/sendmail/libmilter/docs/smfi_setconn.html deleted file mode 100644 index 70a510e..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_setconn.html +++ /dev/null @@ -1,93 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_setconn</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_setconn.html,v 1.17 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_setconn</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_setconn( - char *oconn; -); -</PRE> -Set the socket through which this filter should communicate with sendmail. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_setconn must be called once before <A href="smfi_main.html">smfi_main</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Sets the socket through which the filter communicates with sendmail.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>oconn</TD> - <TD>The address of the desired communication socket. - The address should be a NULL-terminated string in "proto:address" - format: - <UL> - <LI><CODE>{unix|local}:/path/to/file</CODE> -- A named pipe. - <LI><CODE>inet:port@{hostname|ip-address}</CODE> -- An IPV4 socket. - <LI><CODE>inet6:port@{hostname|ip-address}</CODE> -- An IPV6 socket. - </UL> - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_setconn will not fail on an invalid address. -The failure will only be detected in <A href="smfi_main.html">smfi_main</A>. -Nevertheless, smfi_setconn may fail for other reasons, e.g., -due to a lack of memory. -</TD> -</TR> - -<TR> -<TH valign="top" align=left>NOTES</TH> - -<TD> -<UL> - <LI>If possible, filters should not run as root when communicating - over unix/local domain sockets. - <LI>Unix/local sockets should have their permissions set to - 0600 (read/write permission only for the socket's owner) or - 0660 (read/write permission for the socket's owner and group) - which is useful if the sendmail RunAsUser option is used. - The permissions for a unix/local domain socket are determined as - usual by <CODE>umask</CODE>, which should be set to 007 or 077. - Note some operating systems (e.g, Solaris) don't use the - permissions of the socket. On those systems, place the socket in a - protected directory. -</UL> -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_setdbg.html b/contrib/sendmail/libmilter/docs/smfi_setdbg.html deleted file mode 100644 index e001d3f..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_setdbg.html +++ /dev/null @@ -1,67 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_setdbg</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_setdbg.html,v 1.3 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_setdbg</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_setdbg( - int level; -); -</PRE> -Set the debugging (tracing) level for the milter library. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called from any any routine at any time.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>smfi_setdbg sets the milter library's internal debugging level -to a new level so that code details may be traced. -A level of zero turns off debugging. The greater -(more positive) the level the more detailed the debugging. Six is -the current, highest, useful value.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>level</TD> - <TD>The new debugging level - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_setdbg returns MI_SUCCESS by default. -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_setmlreply.html b/contrib/sendmail/libmilter/docs/smfi_setmlreply.html deleted file mode 100644 index b01bacf..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_setmlreply.html +++ /dev/null @@ -1,145 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_setmlreply</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_setmlreply.html,v 1.4 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_setmlreply</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_setmlreply( - SMFICTX *ctx, - char *rcode, - char *xcode, - ... -); -</PRE> -Set the default SMTP error reply code to a multi-line response. Only 4XX -and 5XX replies are accepted. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_setmlreply may be called from any of the xxfi_ callbacks -other than xxfi_connect.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Directly set the SMTP error reply code for this connection to the given -lines after the xcode. The list of arguments must be NULL terminated. -This code will be used on subsequent error replies resulting from actions -taken by this filter.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>rcode</TD> - <TD>The three-digit (RFC 821/2821) SMTP reply code, as a - null-terminated string. rcode cannot be NULL, and must be a valid - 4XX or 5XX reply code. - </TD></TR> - <TR valign="top"><TD>xcode</TD> - <TD>The extended (RFC 1893/2034) reply code. If xcode is NULL, no - extended code is used. Otherwise, xcode must conform to RFC 1893/2034. - </TD></TR> - <TR valign="top"><TD>...</TD> - <TD>The remainder of the arguments are single lines of text, up to - 32 arguments, which will be used as the text part of the SMTP - reply. The list must be NULL terminated. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Example ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> -<TD> -For example, the code:<BR> -<PRE> - ret = smfi_setmlreply(ctx, "550", "5.7.0", - "Spammer access rejected", - "Please see our policy at:", - "http://www.example.com/spampolicy.html", - NULL); -</PRE> -<BR>would give the SMTP response:<BR> -<PRE> -550-5.7.0 Spammer access rejected -550-5.7.0 Please see our policy at: -550 5.7.0 http://www.example.com/spampolicy.html -</PRE> -</TD> -</TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_setmlreply will fail and return MI_FAILURE if: -<UL> - <LI>The rcode or xcode argument is invalid. - <LI>A memory-allocation failure occurs. - <LI>If any text line contains a carraige return or line feed. - <LI>The length of any text line is more than MAXREPLYLEN (980). - <LI>More than 32 lines of text replies are given. -</UL> -Otherwise, it return MI_SUCCESS. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -<UL> -<LI>Values passed to smfi_setmlreply are not checked for standards compliance. -<LI>The message parameter should contain only printable characters, -other characters may lead to undefined behavior. -For example, CR or LF will cause the call to fail, -single '%' characters will cause the text to be ignored -(if there really should be a '%' in the string, -use '%%' just like for <TT>printf(3)</TT>). -<LI>For details about reply codes and their meanings, please see RFC's -<A href="http://www.rfc-editor.org/rfc/rfc821.txt">821</A>/ -<A href="http://www.rfc-editor.org/rfc/rfc2821.txt">2821</A> -and -<A href="http://www.rfc-editor.org/rfc/rfc1893.txt">1893</A>/ -<A href="http://www.rfc-editor.org/rfc/rfc2034.txt">2034</A>. -<LI>If the reply code (rcode) given is a '4XX' code but SMFI_REJECT is used -for the message, the custom reply is not used. -<LI>Similarly, if the reply code (rcode) given is a '5XX' code but -SMFI_TEMPFAIL is used for the message, the custom reply is not used. -<BR> -Note: in neither of the last two cases an error is returned to the milter, -libmilter silently ignores the reply code. -<LI>If the milter returns SMFI_TEMPFAIL and sets the reply code to '421', -then the SMTP server will terminate the SMTP session with a 421 error code. -</UL> -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2002-2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_setpriv.html b/contrib/sendmail/libmilter/docs/smfi_setpriv.html deleted file mode 100644 index 1c287eb..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_setpriv.html +++ /dev/null @@ -1,80 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_setpriv</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_setpriv.html,v 1.11 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_setpriv</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_setpriv( - SMFICTX *ctx, - void *privatedata -); -</PRE> -Set the private data pointer for this connection. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_setpriv may be called in any of the xxfi_* callbacks.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Sets the private data pointer for the context ctx.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>privatedata</TD> - <TD>Pointer to private data. This value will be returned by subsequent calls to <A href="smfi_getpriv.html">smfi_getpriv</A> using ctx. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_setpriv returns MI_FAILURE if ctx is an invalid context. -Otherwise, it returns MI_SUCCESS.</TD> -</TR> - -<TR> -<TH valign="top" align=left>NOTES</TH> - -<TD>There is only one private data pointer per connection; multiple -calls to smfi_setpriv with different values will cause previous values -to be lost. -<P> -Before a filter terminates it should release the private data -and set the pointer to NULL. -</TD> - -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_setreply.html b/contrib/sendmail/libmilter/docs/smfi_setreply.html deleted file mode 100644 index d857815..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_setreply.html +++ /dev/null @@ -1,117 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_setreply</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_setreply.html,v 1.17 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_setreply</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_setreply( - SMFICTX *ctx, - char *rcode, - char *xcode, - char *message -); -</PRE> -Set the default SMTP error reply code. Only 4XX and 5XX replies are accepted. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_setreply may be called from any of the xxfi_ callbacks -other than xxfi_connect.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Directly set the SMTP error reply code for this connection. This code -will be used on subsequent error replies resulting from actions taken by -this filter.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>rcode</TD> - <TD>The three-digit (RFC 821/2821) SMTP reply code, as a - null-terminated string. rcode cannot be NULL, and must be a valid - 4XX or 5XX reply code. - </TD></TR> - <TR valign="top"><TD>xcode</TD> - <TD>The extended (RFC 1893/2034) reply code. If xcode is NULL, no - extended code is used. Otherwise, xcode must conform to RFC 1893/2034. - </TD></TR> - <TR valign="top"><TD>message</TD> - <TD>The text part of the SMTP reply. If message is NULL, an empty message is used. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_setreply will fail and return MI_FAILURE if: -<UL> - <LI>The rcode or xcode argument is invalid. - <LI>A memory-allocation failure occurs. -</UL> -Otherwise, it return MI_SUCCESS. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD> -<UL> -<LI>Values passed to smfi_setreply are not checked for standards compliance. -<LI>The message parameter should contain only printable characters, -other characters may lead to undefined behavior. -For example, CR or LF will cause the call to fail, -single '%' characters will cause the text to be ignored -(if there really should be a '%' in the string, -use '%%' just like for <TT>printf(3)</TT>). -<LI>For details about reply codes and their meanings, please see RFC's -<A href="http://www.rfc-editor.org/rfc/rfc821.txt">821</A>/ -<A href="http://www.rfc-editor.org/rfc/rfc2821.txt">2821</A> -and -<A href="http://www.rfc-editor.org/rfc/rfc1893.txt">1893</A>/ -<A href="http://www.rfc-editor.org/rfc/rfc2034.txt">2034</A>. -<LI>If the reply code (rcode) given is a '4XX' code but SMFI_REJECT is used -for the message, the custom reply is not used. -<LI>Similarly, if the reply code (rcode) given is a '5XX' code but -SMFI_TEMPFAIL is used for the message, the custom reply is not used. -<BR> -Note: in neither of the last two cases an error is returned to the milter, -libmilter silently ignores the reply code. -<LI>If the milter returns SMFI_TEMPFAIL and sets the reply code to '421', -then the SMTP server will terminate the SMTP session with a 421 error code. -</UL> -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2002-2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_setsymlist.html b/contrib/sendmail/libmilter/docs/smfi_setsymlist.html deleted file mode 100644 index 7e8edff..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_setsymlist.html +++ /dev/null @@ -1,107 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_setsymlist</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_setsymlist.html,v 1.5 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_setsymlist</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_setsymlist( - SMFICTX *ctx, - int stage, - char *macros -); -</PRE> -Set the list of macros that the milter wants to receive from the MTA -for a protocol stage. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>This function must only be called during -<A HREF="xxfi_negotiate.html">xxfi_negotiate()</A>. -</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>This function can be used to override the list of macros that the -milter wants to receive from the MTA. -</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - - <TR><TD>ctx</TD> - <TD>the opaque context structure. - </TD></TR> - - <TR><TD>stage</TD> - <TD>the protocol stage during which the macro list should be used. - See the file - <CODE>include/libmilter/mfapi.h</CODE> for legal values, - look for the C macros with the prefix - <CODE>SMFIM_</CODE>. - Available protocol stages are at least - the initial connection, HELO/EHLO, MAIL, RCPT, DATA, - end of header, and - the end of a message. - </TD></TR> - - <TR><TD>macros</TD> - <TD>list of macros (separated by space). - Example: "{rcpt_mailer} {rcpt_host}" - </TD></TR> - - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>MI_FAILURE is returned if -<UL> -<LI>there is not enough free memory to make a copy of the macro list, -<LI><CODE>macros</CODE> is <CODE>NULL</CODE> or empty, -<LI><CODE>stage</CODE> is not a valid protocol stage, -<LI>the macro list for -<CODE>stage</CODE> has been set before. -</UL> -Otherwise MI_SUCCESS is returned. -</TD> -</TR> - -<!----------- Notes ----------> -<TR align="left" valign=top> -<TH>NOTES</TH> -<TD>There is an internal limit on the number of macros that can be -set (currently 5), -however, this limit is not enforced by libmilter, only by the MTA, -but a possible violation of this restriction is not communicated back to -the milter.</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_settimeout.html b/contrib/sendmail/libmilter/docs/smfi_settimeout.html deleted file mode 100644 index 97d41cb..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_settimeout.html +++ /dev/null @@ -1,66 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_settimeout</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_settimeout.html,v 1.14 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_settimeout</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_settimeout( - int otimeout -); -</PRE> -Set the filter's I/O timeout value. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>smfi_settimeout should only be called before <A href="smfi_main.html">smfi_main</A>.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>Sets the number of seconds libmilter will wait -for an MTA communication (read or write) before timing out. -If smfi_settimeout is not called, a default timeout of 7210 seconds is used. -</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>otimeout</TD> - <TD>The number of seconds to wait before timing out (> 0). - Zero means no wait, <B>not</B> "wait forever". - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_settimeout always returns MI_SUCCESS.</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2002-2003, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_stop.html b/contrib/sendmail/libmilter/docs/smfi_stop.html deleted file mode 100644 index 87ecdb2..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_stop.html +++ /dev/null @@ -1,74 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_stop</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_stop.html,v 1.6 2006/12/21 18:30:35 ca Exp $ ---> -<H1>smfi_stop</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_stop(void); -</PRE> -Shutdown the milter. -No connections will be accepted after this call. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>Called from any of the <A href="api.html#Callbacks">Callback</A> routines -or any error-handling routines at any time.</TD> -</TR> -<TR align="left" valign=top> -<TH width="80">Effects</TH> -<TD>The smfi_stop routine prevents that new connections -will be accepted, -however, it does not wait for existing connections (threads) to terminate. -It will cause -<A href="smfi_main.html">smfi_main</A> to return to the calling program, -which may then exit or warm-restart. -</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>void</TD> - <TD>Takes no arguement. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>RETURN VALUES</TH> - -<TD>smfi_stop always returns SMFI_CONTINUE. But note: -<UL> - <LI>Another internal routine may already have asked the milter to abort. - <LI>Another routine may already have asked the milter to stop. - <LI>There is no way to cancel the stop process once it has begun. -</UL> -</TD> -</TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2003, 2005 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/smfi_version.html b/contrib/sendmail/libmilter/docs/smfi_version.html deleted file mode 100644 index 3c1fc05..0000000 --- a/contrib/sendmail/libmilter/docs/smfi_version.html +++ /dev/null @@ -1,86 +0,0 @@ -<HTML> -<HEAD><TITLE>smfi_version()</TITLE></HEAD> -<BODY> -<!-- -$Id: smfi_version.html,v 1.5 2007/03/22 17:30:57 ca Exp $ ---> -<H1>smfi_version()</H1> - -<TABLE BORDER="0" CELLSPACING=4 CELLPADDING=4> -<!---------- Synopsis -----------> -<TR><TH VALIGN="TOP" ALIGN=LEFT WIDTH=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -int smfi_version( - unsigned int *pmajor, - unsigned int *pminor, - unsigned int *ppl -); -</PRE> -Get the (runtime) version of libmilter. -</TD></TR> - -<!----------- Description ----------> -<TR><TH VALIGN="TOP" ALIGN=LEFT>DESCRIPTION</TH><TD> -<TABLE BORDER="1" CELLSPACING=1 CELLPADDING=4> -<TR ALIGN="LEFT" VALIGN=TOP> -<TH WIDTH="80">Called When</TH> -<TD>smfi_version may be called at any time.</TD> -</TR> -<TR ALIGN="LEFT" VALIGN=TOP> -<TH WIDTH="80">Effects</TH> -<TD>None.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH VALIGN="TOP" ALIGN=LEFT>ARGUMENTS</TH><TD> - <TABLE BORDER="1" CELLSPACING=0> - <TR BGCOLOR="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR VALIGN="TOP"><TD>pmajor</TD> - <TD>Pointer to an unsigned int variable to store major version number. - </TD></TR> - <TR VALIGN="TOP"><TD>pminor</TD> - <TD>Pointer to an unsigned int variable to store minor version number. - </TD></TR> - <TR VALIGN="TOP"><TD>ppl</TD> - <TD>Pointer to an unsigned int variable to store patch level number. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH VALIGN="TOP" ALIGN=LEFT>RETURN VALUES</TH> -<TD>smfi_version returns MI_SUCCESS.</TD> -</TR> - -</TABLE> - -Note: the compile time version of libmilter is available in the macro -<CODE>SMFI_VERSION</CODE>. -A milter can check this macro to determine which functions to use -(at compile time via C preprocessor statements). -Using this macro and the -<CODE>smfi_version()</CODE> -function, -a milter can determine at runtime whether it has been (dynamically) -linked against the expected libmilter version. -To extract the major and minor version as well as the current patch level -from this macro, the macros -<CODE>SM_LM_VRS_MAJOR(v)</CODE>, -<CODE>SM_LM_VRS_MINOR(v)</CODE>, and -<CODE>SM_LM_VRS_PLVL(v)</CODE> -can be used, respectively. - - -<HR SIZE="1"> -<FONT SIZE="-1"> -Copyright (c) 2006, 2007 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_abort.html b/contrib/sendmail/libmilter/docs/xxfi_abort.html deleted file mode 100644 index 0664dc1..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_abort.html +++ /dev/null @@ -1,83 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_abort</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_abort.html,v 1.12 2006/12/21 18:30:35 ca Exp $ ---> -<H1>xxfi_abort</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_abort)( - SMFICTX *ctx -); -</PRE> -Handle the current message's being aborted. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_abort may be called at any time during message processing (i.e. between some message-oriented routine and <A href="xxfi_eom.html">xxfi_eom</A>).</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD> -<UL> -<LI>xxfi_abort must reclaim any resources allocated on a per-message -basis, and must be tolerant of being called between any two -message-oriented callbacks. - -<LI>Calls to xxfi_abort and <A href="xxfi_eom.html">xxfi_eom</A> are -mutually exclusive. - -<LI>xxfi_abort is not responsible for reclaiming connection-specific -data, since <A href="xxfi_close.html">xxfi_close</A> is always called -when a connection is closed. - -<LI>Since the current message is already being aborted, the return -value is currently ignored. - -<LI>xxfi_abort is only called if the message is aborted outside the -filter's control <B>and</B> the filter has not completed its -message-oriented processing. For example, if a filter has already -returned SMFIS_ACCEPT, SMFIS_REJECT, or SMFIS_DISCARD from a -message-oriented routine, xxfi_abort will not be called even if the -message is later aborted outside its control. -</UL> -</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_body.html b/contrib/sendmail/libmilter/docs/xxfi_body.html deleted file mode 100644 index 0a5f0f3..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_body.html +++ /dev/null @@ -1,97 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_body</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_body.html,v 1.17 2007/03/26 20:12:46 ca Exp $ ---> -<H1>xxfi_body</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_body)( - SMFICTX *ctx, - unsigned char *bodyp, - size_t len -); -</PRE> -Handle a piece of a message's body. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_body is called zero or more times between xxfi_eoh and xxfi_eom.</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>bodyp</TD> - <TD>Pointer to the start of this block of body data. bodyp is not valid outside this call to xxfi_body. - </TD></TR> - <TR valign="top"><TD>len</TD> - <TD>The amount of data pointed to by bodyp. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD> -<UL> -<LI>bodyp points to a sequence of bytes. -It is <EM>not</EM> a C string (a sequence of characters that is terminated by '\0'). -Therefore, do not use the usual C string functions like <CODE>strlen(3)</CODE> -on this byte block. -Moreover, the byte sequence may contain '\0' characters inside the block. -Hence even if a trailing '\0' is added, C string functions may still fail -to work as expected. -<LI>Since message bodies can be very large, defining xxfi_body can -significantly impact filter performance. -<LI>End-of-lines are represented as received from SMTP (normally CR/LF). -<LI>Later filters will see body changes made by earlier ones. -<LI>Message bodies may be sent in multiple chunks, with one call to - xxfi_body per chunk. -<LI>Return -<A HREF="api.html#SMFIS_SKIP">SMFIS_SKIP</A> -if a milter has received sufficiently many -body chunks to make a decision, -but still wants to invoke -message modification functions that are only allowed to be called from -<A HREF="xxfi_eom.html">xxfi_eom()</A>. -Note: the milter <EM>must</EM> -<A HREF="xxfi_negotiate.html">negotiate</A> -this behavior with the MTA, i.e., it must check whether -the protocol action -<A HREF="xxfi_negotiate.html#SMFIP_SKIP"><CODE>SMFIP_SKIP</CODE></A> -is available and if so, the milter must request it. -</UL> -</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2003, 2007 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_close.html b/contrib/sendmail/libmilter/docs/xxfi_close.html deleted file mode 100644 index 2c2ae77..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_close.html +++ /dev/null @@ -1,81 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_close</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_close.html,v 1.13 2006/12/21 18:30:35 ca Exp $ ---> -<H1>xxfi_close</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_close)( - SMFICTX *ctx -); -</PRE> -The current connection is being closed. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_close is always called once at the end of each connection.</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD> -<UL> -<LI>xxfi_close may be called "out-of-order", i.e. before even the -xxfi_connect is called. -After a connection is established by the MTA to the filter, -if the MTA decides this connection's traffic will be discarded -(e.g. via an access_db result), no data will be passed to the -filter from the MTA until the client closes down. -At that time, xxfi_close is called. -It can therefore be the only callback ever used for a given connection, -and developers should anticipate this possibility when crafting their -xxfi_close code. -In particular, it is incorrect to assume the private context pointer -will be something other than NULL in this callback. -<LI>xxfi_close is called on close even if the previous mail -transaction was aborted. -<LI>xxfi_close is responsible for freeing any resources allocated on a -per-connection basis. -<LI>Since the connection is already closing, the return value is -currently ignored. -</UL> -</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003, 2004 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_connect.html b/contrib/sendmail/libmilter/docs/xxfi_connect.html deleted file mode 100644 index 87d5eeb..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_connect.html +++ /dev/null @@ -1,121 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_connect</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_connect.html,v 1.19 2007/01/15 22:24:45 ca Exp $ ---> -<H1>xxfi_connect</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_connect)( - SMFICTX *ctx, - char *hostname, - _SOCK_ADDR *hostaddr); -</PRE> -</TD></TR> -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR> -<TH valign="top" align=left width=80>Called When</TH> -<TD>Once, at the start of each SMTP connection.</TD> -</TR> -<TR> -<TH valign="top" align=left width=80>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> -<!-- -This callback function is invoked on each connection to the mail -filter program. -The callback is to be implemented by the Milter application developers. -The name of the callback can be any valid function name. -The function pointer is to be assigned to the -smfiDesc.xxfi_connect and the pointer to the smfiDesc structure -is passed to smfi_register(). -</TD></TR> ---> -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR><TD>ctx</TD> - <TD>the opaque context structure. - </TD></TR> - <TR><TD>hostname</TD> - <TD>the host name of the message sender, as determined by a - reverse lookup on the host address. - If the reverse lookup fails - or if none of the IP addresses of the resolved host name - matches the original IP address, - hostname will contain the message sender's IP - address enclosed in square brackets (e.g. `[a.b.c.d]'). - If the SMTP connection is made via stdin the value is - <CODE>localhost</CODE>. - </TD></TR> - <TR><TD>hostaddr</TD> - <TD>the host address, - as determined by a <CODE>getpeername(2)</CODE> call on the SMTP socket. - NULL if the type is not supported in the current version or if - the SMTP connection is made via stdin. - </TD></TR> - </TABLE> -</TD></TR> -<!----------- Return values ----------> -<!-- -<TR> -<TH valign="top" align=left>SPECIAL RETURN VALUES</TH> -<TD><TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR> - <TR valign="top"> - <TD>SMFIS_ACCEPT</TD> - <TD>Accept all commands and messages from this client without any - further contact with the filter. </TD> - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_CONTINUE</TD> - <TD>Continue normal processing. </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_DISCARD</TD> - <TD>Undefined behaviour; do not use. </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_TEMPFAIL</TD> - <TD>Reject all commands and messages from this client with a - temporary failure reply code. - If also used in conjunction with <CODE>smfi_setreply()</CODE> - to set a reply whose SMTP code is 421, - the MTA will drop the connection immediately. </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_REJECT</TD> - <TD>Reject all commands and messages from this client with a - permanent failure reply code. </TD> - </TR> -</TABLE> -</TR> ---> -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD>If an earlier filter rejects the connection in its xxfi_connect() -routine, this filter's xxfi_connect() will not be called.</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000-2001, 2003, 2007 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_data.html b/contrib/sendmail/libmilter/docs/xxfi_data.html deleted file mode 100644 index 2633ee5..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_data.html +++ /dev/null @@ -1,89 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_data</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_data.html,v 1.4 2007/01/25 01:00:20 ca Exp $ ---> -<H1>xxfi_data</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_data)( - SMFICTX *ctx -); -</PRE> -Handle the DATA command. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_data is called when the client uses the DATA command. -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>SPECIAL RETURN VALUES</TH> -<TD><TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR> - <TR valign="top"> - <TD>SMFIS_TEMPFAIL</TD> - <TD>Reject this message with a temporary error. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_REJECT</TD> - <TD>Reject this message. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_DISCARD</TD> - <TD>Accept and silently discard this message. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_ACCEPT</TD> - <TD>Accept this message. - </TD> - </TR> -</TABLE> -</TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD>For more details on ESMTP responses, please see RFC -<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_envfrom.html b/contrib/sendmail/libmilter/docs/xxfi_envfrom.html deleted file mode 100644 index 6ae88cf..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_envfrom.html +++ /dev/null @@ -1,97 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_envfrom</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_envfrom.html,v 1.14 2007/01/25 01:00:20 ca Exp $ ---> -<H1>xxfi_envfrom</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_envfrom)( - SMFICTX *ctx, - char **argv -); -</PRE> -Handle the MAIL (envelope sender) command. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_envfrom is called once at the beginning of each message -(MAIL command), -before xxfi_envrcpt.</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>argv</TD> - <TD>Null-terminated SMTP command arguments; - argv[0] is guaranteed to be the sender address. - Later arguments are the ESMTP arguments. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>SPECIAL RETURN VALUES</TH> -<TD><TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR> - <TR valign="top"> - <TD>SMFIS_TEMPFAIL</TD> - <TD>Reject this sender and message with a temporary error; a new sender (and hence a new message) may subsequently be specified. <A href="xxfi_abort.html">xxfi_abort</A> is not called. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_REJECT</TD> - <TD>Reject this sender and message; a new sender/message may be specified. <A href="xxfi_abort.html">xxfi_abort</A> is not called. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_DISCARD</TD> - <TD>Accept and silently discard this message. <A href="xxfi_abort.html">xxfi_abort</A> is not called. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_ACCEPT</TD> - <TD>Accept this message. <A href="xxfi_abort.html">xxfi_abort</A> is not called. - </TD> - </TR> -</TABLE> -</TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD>For more details on ESMTP responses, please see RFC -<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html b/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html deleted file mode 100644 index 9fb4ce8..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html +++ /dev/null @@ -1,97 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_envrcpt</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_envrcpt.html,v 1.15 2007/01/25 01:00:20 ca Exp $ ---> -<H1>xxfi_envrcpt</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_envrcpt)( - SMFICTX *ctx, - char **argv -); -</PRE> -Handle the envelope RCPT command. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_envrcpt is called once per recipient, hence one or more times per message, immediately after xxfi_envfrom.</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>argv</TD> - <TD>Null-terminated SMTP command arguments; - argv[0] is guaranteed to be the recipient address. - Later arguments are the ESMTP arguments. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>SPECIAL RETURN VALUES</TH> -<TD><TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR> - <TR valign="top"> - <TD>SMFIS_TEMPFAIL</TD> - <TD>Temporarily fail for this particular recipient; further recipients - may still be sent. <A href="xxfi_abort.html">xxfi_abort</A> is not called. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_REJECT</TD> - <TD>Reject this particular recipient; further recipients may still be sent. - <A href="xxfi_abort.html">xxfi_abort</A> is not called. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_DISCARD</TD> - <TD>Accept and discard the message. <A href="xxfi_abort.html">xxfi_abort</A> will be called. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_ACCEPT</TD> - <TD>Accept recipient. <A href="xxfi_abort.html">xxfi_abort</A> will not be called. - </TD> - </TR> -</TABLE> -</TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD>For more details on ESMTP responses, please see RFC -<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_eoh.html b/contrib/sendmail/libmilter/docs/xxfi_eoh.html deleted file mode 100644 index 2a74e7a..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_eoh.html +++ /dev/null @@ -1,56 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_eoh</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_eoh.html,v 1.11 2006/12/21 18:30:35 ca Exp $ ---> -<H1>xxfi_eoh</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_eoh)( - SMFICTX *ctx -); -</PRE> -Handle the end of message headers. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_eoh is called once after all headers have been sent and processed. -</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - </TABLE> -</TD></TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_eom.html b/contrib/sendmail/libmilter/docs/xxfi_eom.html deleted file mode 100644 index b5aee8b..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_eom.html +++ /dev/null @@ -1,62 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_eom</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_eom.html,v 1.12 2006/12/21 18:30:36 ca Exp $ ---> -<H1>xxfi_eom</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_eom)( - SMFICTX *ctx -); -</PRE> -End of a message. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_eom is called once after all calls to <A href="xxfi_body.html">xxfi_body</A> for a given message.</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD>A filter is required to make all its modifications to the message headers, body, and envelope in xxfi_eom. -Modifications are made via the smfi_* routines. -</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_header.html b/contrib/sendmail/libmilter/docs/xxfi_header.html deleted file mode 100644 index 8a5462f..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_header.html +++ /dev/null @@ -1,111 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_header</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_header.html,v 1.17 2006/12/21 18:30:36 ca Exp $ ---> -<H1>xxfi_header</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_header)( - SMFICTX *ctx, - char *headerf, - char *headerv -); -</PRE> -Handle a message header. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_header is called once for each message header.</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>headerf</TD> - <TD> Header field name. - </TD></TR> - <TR valign="top"><TD>headerv</TD> - <TD>Header field value. - The content of the header may include folded white space, - i.e., multiple lines with following white space - where lines are separated by LF (not CR/LF). - The trailing line terminator (CR/LF) is removed. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD> -<UL> -<LI>Starting with sendmail 8.14, spaces after the colon in a header -field are preserved if requested using the flag -<A HREF="xxfi_negotiate.html#SMFIP_HDR_LEADSPC"><CODE>SMFIP_HDR_LEADSPC</CODE></A>. -That is, the header - -<PRE> -From: sender <f@example.com> -To: user <t@example.com> -Subject:no -</PRE> - -will be sent to a milter as - -<PRE> -"From", " sender <f@example.com>" -"To", " user <t@example.com>" -"Subject", "no" -</PRE> - -while previously -(or without the flag -<A HREF="xxfi_negotiate.html#SMFIP_HDR_LEADSPC"><CODE>SMFIP_HDR_LEADSPC</CODE></A>) -it was: - -<PRE> -"From", "sender <f@example.com>" -"To", "user <t@example.com>" -"Subject", "no" -</PRE> - - -<LI>Later filters will see header changes/additions made by earlier ones. -<LI>For much more detail about header format, please see -RFC <A href="http://www.rfc-editor.org/rfc/rfc822.html">822</A> -and -RFC <A href="http://www.rfc-editor.org/rfc/rfc2822.html">2822</A> -</UL> -</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003, 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_helo.html b/contrib/sendmail/libmilter/docs/xxfi_helo.html deleted file mode 100644 index 613cb19..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_helo.html +++ /dev/null @@ -1,64 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_helo</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_helo.html,v 1.12 2006/12/21 18:30:36 ca Exp $ ---> -<H1>xxfi_helo</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_helo)( - SMFICTX *ctx, - char *helohost -); -</PRE> -Handle the HELO/EHLO command. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> <TD>xxfi_helo is called whenever the client -sends a HELO/EHLO command. -It may therefore be called several times or even not at all; -some restrictions can be imposed by the MTA configuration. -</TD> -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>helohost</TD> - <TD>Value passed to HELO/EHLO command, which should be - the domain name of the sending host (but is, in practice, - anything the sending host wants to send). - </TD></TR> - </TABLE> -</TD></TR> - -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2000, 2003, 2005 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_negotiate.html b/contrib/sendmail/libmilter/docs/xxfi_negotiate.html deleted file mode 100644 index 0f69f70..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_negotiate.html +++ /dev/null @@ -1,277 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_negotiate</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_negotiate.html,v 1.23 2006/12/20 18:57:08 ca Exp $ ---> -<H1>xxfi_negotiate</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -#include <libmilter/mfdef.h> -sfsistat (*xxfi_negotiate)( - SMFICTX *ctx, - unsigned long f0, - unsigned long f1, - unsigned long f2, - unsigned long f3, - unsigned long *pf0, - unsigned long *pf1, - unsigned long *pf2, - unsigned long *pf3); -</PRE> -</TD></TR> -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR> -<TH valign="top" align=left width=80>Called When</TH> -<TD>Once, at the start of each SMTP connection.</TD> -</TR> -<TR> -<TH valign="top" align=left width=80>Default Behavior</TH> -<TD>Return SMFIS_ALL_OPTS to change nothing.</TD> -</TR> -</TABLE> -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR><TD>ctx</TD> - <TD>the opaque context structure. - </TD></TR> - <TR><TD>f0</TD> - <TD>the actions offered by the MTA. - </TD></TR> - <TR><TD>f1</TD> - <TD>the protocol steps offered by the MTA. - <TR><TD>f2</TD> - <TD>for future extensions. - </TD></TR> - <TR><TD>f3</TD> - <TD>for future extensions. - </TD></TR> - <TR><TD>pf0</TD> - <TD>the actions requested by the milter. - </TD></TR> - <TR><TD>pf1</TD> - <TD>the protocol steps requested by the milter. - <TR><TD>pf2</TD> - <TD>for future extensions. - </TD></TR> - <TR><TD>pf3</TD> - <TD>for future extensions. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>SPECIAL RETURN VALUES</TH> -<TD><TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR> - <TR valign="top"> - <TD>SMFIS_ALL_OPTS</TD> - <TD> -If a milter just wants to inspect the available protocol steps -and actions, then it can return -SMFIS_ALL_OPTS -and the MTA will make all protocol steps and actions available -to the milter. -In this case, no values should be assigned to the output parameters -<CODE>pf0</CODE> - <CODE>pf3</CODE> -as they will be ignored. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_REJECT</TD> - <TD>Milter startup fails and it will not be contacted again -(for the current connection). - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_CONTINUE</TD> - <TD>Continue processing. - In this case the milter <EM>must</EM> set all output parameters - <CODE>pf0</CODE> - <CODE>pf3</CODE>. - See below for an explanation how to set those output parameters. - </TD> - </TR> -</TABLE> -</TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD>This function allows a milter to dynamically determine and -request operations and actions during startup. -In previous versions, the actions (f0) were fixed in the -<A HREF="smfi_register.html#flags">flags</A> field of the -<A HREF="smfi_register.html#smfiDesc">smfiDesc</A> -structure -and the protocol steps (f1) were implicitly derived by checking whether -a callback was defined. -Due to the extensions in the new milter version, -such a static selection will not work if a milter requires -new actions that are not available when talking to an older MTA. -Hence in the negotiation callback a milter can determine -which operations are available and dynamically select -those which it needs and which are offered. -If some operations are not available, the milter may either fall back -to an older mode or abort the session and ask the user to upgrade. - -<!-- -<P> -The protocol steps are defined in -<CODE>include/libmilter/mfdef.h</CODE>: -the macros start with -<CODE>SMFIP_</CODE>. ---> - -<P> -Protocol steps -(<CODE>f1</CODE>, <CODE>*pf1</CODE>): -<UL> -<LI><A NAME="SMFIP_RCPT_REJ"><CODE>SMFIP_RCPT_REJ</CODE></A>: -By setting this bit, a milter can request that the -MTA should also send <CODE>RCPT</CODE> commands that have been rejected -because the user is unknown (or similar reasons), but not those -which have been rejected because of syntax errors etc. -If a milter requests this protocol step, -then it should check the macro -<CODE>{rcpt_mailer}</CODE>: -if that is set to -<CODE>error</CODE>, -then the recipient will be rejected by the MTA. -Usually the macros -<CODE>{rcpt_host}</CODE> and <CODE>{rcpt_addr}</CODE> -will contain an enhanced status code and an error text -in that case, respectively. - -<LI><A NAME="SMFIP_SKIP"><CODE>SMFIP_SKIP</CODE></A> -indicates that the MTA understand the -<A HREF="api.html#SMFIS_SKIP">SMFIS_SKIP</A> -return code. - -<LI><A NAME="SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A> -indicates that the MTA understand the -<A HREF="api.html#SMFIS_NOREPLY">SMFIS_NOREPLY</A> -return code. -There are flags for various protocol stages: - -<UL> - -<LI><A NAME="SMFIP_NR_CONN"><CODE>SMFIP_NR_CONN</CODE></A>: -<A HREF="xxfi_connect.html">xxfi_connect()</A> - -<LI><A NAME="SMFIP_NR_HELO"><CODE>SMFIP_NR_HELO</CODE></A>: -<A HREF="xxfi_helo.html">xxfi_helo()</A> - -<LI><A NAME="SMFIP_NR_MAIL"><CODE>SMFIP_NR_MAIL</CODE></A>: -<A HREF="xxfi_envfrom.html">xxfi_envfrom()</A> - -<LI><A NAME="SMFIP_NR_RCPT"><CODE>SMFIP_NR_RCPT</CODE></A>: -<A HREF="xxfi_envrcpt.html">xxfi_envrcpt()</A> - -<LI><A NAME="SMFIP_NR_DATA"><CODE>SMFIP_NR_DATA</CODE></A>: -<A HREF="xxfi_data.html">xxfi_data()</A> - -<LI><A NAME="SMFIP_NR_UNKN"><CODE>SMFIP_NR_UNKN</CODE></A>: -<A HREF="xxfi_unknown.html">xxfi_unknown()</A> - -<LI><A NAME="SMFIP_NR_EOH"><CODE>SMFIP_NR_EOH</CODE></A>: -<A HREF="xxfi_eoh.html">xxfi_eoh()</A> - -<LI><A NAME="SMFIP_NR_BODY"><CODE>SMFIP_NR_BODY</CODE></A>: -<A HREF="xxfi_body.html">xxfi_body()</A> - -<LI><A NAME="SMFIP_NR_HDR"><CODE>SMFIP_NR_HDR</CODE></A>: -<A HREF="xxfi_header.html">xxfi_header()</A> - -</UL> - -<LI><A NAME="SMFIP_HDR_LEADSPC"><CODE>SMFIP_HDR_LEADSPC</CODE></A> -indicates that the MTA can send header values with leading space intact. -If this protocol step is requested, then the MTA will also not add a leading -space to headers when they are added, inserted, or changed. - -<!-- -:'a,.s;^#define \(SMFIP_NO[A-Z]*\)[ ].*;<LI><A NAME="\1"><CODE>\1</CODE></A>:; ---> -<LI>The MTA can be instructed not to send information about -various SMTP stages, these flags start with: -<A NAME="SMFIP_NO"><CODE>SMFIP_NO*</CODE></A>. -<UL> -<LI><A NAME="SMFIP_NOCONNECT"><CODE>SMFIP_NOCONNECT</CODE></A>: -<A HREF="xxfi_connect.html">xxfi_connect()</A> -<LI><A NAME="SMFIP_NOHELO"><CODE>SMFIP_NOHELO</CODE></A>: -<A HREF="xxfi_header.html">xxfi_header()</A> -<LI><A NAME="SMFIP_NOMAIL"><CODE>SMFIP_NOMAIL</CODE></A>: -<A HREF="xxfi_envfrom.html">xxfi_envfrom()</A> -<LI><A NAME="SMFIP_NORCPT"><CODE>SMFIP_NORCPT</CODE></A>: -<A HREF="xxfi_envrcpt.html">xxfi_envrcpt()</A> -<LI><A NAME="SMFIP_NOBODY"><CODE>SMFIP_NOBODY</CODE></A>: -<A HREF="xxfi_body.html">xxfi_body()</A> -<LI><A NAME="SMFIP_NOHDRS"><CODE>SMFIP_NOHDRS</CODE></A>: -<A HREF="xxfi_header.html">xxfi_header()</A> -<LI><A NAME="SMFIP_NOEOH"><CODE>SMFIP_NOEOH</CODE></A>: -<A HREF="xxfi_eoh.html">xxfi_eoh()</A> -<LI><A NAME="SMFIP_NOUNKNOWN"><CODE>SMFIP_NOUNKNOWN</CODE></A>: -<A HREF="xxfi_unknown.html">xxfi_unknown()</A> -<LI><A NAME="SMFIP_NODATA"><CODE>SMFIP_NODATA</CODE></A>: -<A HREF="xxfi_data.html">xxfi_data()</A> -</UL> - -For each of these xxfi_* callbacks that a milter does not use -the corresponding flag <EM>should</EM> be set in -<CODE>*pf1</CODE>. - -</UL> - -<P> -The available actions -(<CODE>f0</CODE>, <CODE>*pf0</CODE>) -are -<!-- -defined in -<CODE>include/libmilter/mfapi.h</CODE>: -the macros start with -<CODE>SMFIF_</CODE>; -these are ---> -described -<A HREF="smfi_register.html#flags">elsewhere (xxfi_flags)</A>. - -<P> -If a milter returns SMFIS_CONTINUE, then it <EM>must</EM> -set the desired actions and protocol steps -via the (output) parameters -<CODE>pf0</CODE> -and -<CODE>pf1</CODE> -(which correspond to -<CODE>f0</CODE> -and -<CODE>f1</CODE>, respectively). -The (output) parameters -<CODE>pf2</CODE> and -<CODE>pf3</CODE> -should be set to 0 for compatibility with future versions. - -</TD> -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/docs/xxfi_unknown.html b/contrib/sendmail/libmilter/docs/xxfi_unknown.html deleted file mode 100644 index 0455dfd..0000000 --- a/contrib/sendmail/libmilter/docs/xxfi_unknown.html +++ /dev/null @@ -1,84 +0,0 @@ -<HTML> -<HEAD><TITLE>xxfi_unknown</TITLE></HEAD> -<BODY> -<!-- -$Id: xxfi_unknown.html,v 1.4 2007/04/23 16:30:42 ca Exp $ ---> -<H1>xxfi_unknown</H1> - -<TABLE border="0" cellspacing=4 cellpadding=4> -<!---------- Synopsis -----------> -<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD> -<PRE> -#include <libmilter/mfapi.h> -sfsistat (*xxfi_unknown)( - SMFICTX *ctx, - const char *arg -); -</PRE> -Handle unknown and unimplemented SMTP commands. -</TD></TR> - -<!----------- Description ----------> -<TR><TH valign="top" align=left>DESCRIPTION</TH><TD> -<TABLE border="1" cellspacing=1 cellpadding=4> -<TR align="left" valign=top> -<TH width="80">Called When</TH> -<TD>xxfi_unknown is called when the client uses an SMTP command -that is either unknown or not implemented by the MTA. -</TR> -<TR align="left" valign=top> -<TH>Default Behavior</TH> -<TD>Do nothing; return SMFIS_CONTINUE.</TD> -</TR> -</TABLE> - -<!----------- Arguments ----------> -<TR><TH valign="top" align=left>ARGUMENTS</TH><TD> - <TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR> - <TR valign="top"><TD>ctx</TD> - <TD>Opaque context structure. - </TD></TR> - <TR valign="top"><TD>arg</TD> - <TD>SMTP command including all arguments. - </TD></TR> - </TABLE> -</TD></TR> - -<!----------- Return values ----------> -<TR> -<TH valign="top" align=left>SPECIAL RETURN VALUES</TH> -<TD><TABLE border="1" cellspacing=0> - <TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR> - <TR valign="top"> - <TD>SMFIS_TEMPFAIL</TD> - <TD>Reject this command with a temporary error. - </TD> - </TR> - <TR valign="top"> - <TD>SMFIS_REJECT</TD> - <TD>Reject this command. - </TD> - </TR> -</TABLE> -</TR> - -<!----------- Notes ----------> -<TR> -<TH valign="top" align=left>NOTES</TH> -<TD>The SMTP command will always be rejected by the server, -it is only possible to return a different error code. -</TR> -</TABLE> - -<HR size="1"> -<FONT size="-1"> -Copyright (c) 2006 Sendmail, Inc. and its suppliers. -All rights reserved. -<BR> -By using this file, you agree to the terms and conditions set -forth in the LICENSE. -</FONT> -</BODY> -</HTML> diff --git a/contrib/sendmail/libmilter/engine.c b/contrib/sendmail/libmilter/engine.c deleted file mode 100644 index a024312..0000000 --- a/contrib/sendmail/libmilter/engine.c +++ /dev/null @@ -1,1777 +0,0 @@ -/* - * Copyright (c) 1999-2004, 2006, 2007 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: engine.c,v 8.159 2007/04/23 22:22:50 ca Exp $") - -#include "libmilter.h" - -#if NETINET || NETINET6 -# include <arpa/inet.h> -#endif /* NETINET || NETINET6 */ - -/* generic argument for functions in the command table */ -struct arg_struct -{ - size_t a_len; /* length of buffer */ - char *a_buf; /* argument string */ - int a_idx; /* index for macro array */ - SMFICTX_PTR a_ctx; /* context */ -}; - -typedef struct arg_struct genarg; - -/* structure for commands received from MTA */ -struct cmdfct_t -{ - char cm_cmd; /* command */ - int cm_argt; /* type of arguments expected */ - int cm_next; /* next state */ - int cm_todo; /* what to do next */ - int cm_macros; /* index for macros */ - int (*cm_fct) __P((genarg *)); /* function to execute */ -}; - -typedef struct cmdfct_t cmdfct; - -/* possible values for cm_argt */ -#define CM_ARG0 0 /* no args */ -#define CM_ARG1 1 /* one arg (string) */ -#define CM_ARG2 2 /* two args (strings) */ -#define CM_ARGA 4 /* one string and _SOCK_ADDR */ -#define CM_ARGO 5 /* two integers */ -#define CM_ARGV 8 /* \0 separated list of args, NULL-terminated */ -#define CM_ARGN 9 /* \0 separated list of args (strings) */ - -/* possible values for cm_todo */ -#define CT_CONT 0x0000 /* continue reading commands */ -#define CT_IGNO 0x0001 /* continue even when error */ - -/* not needed right now, done via return code instead */ -#define CT_KEEP 0x0004 /* keep buffer (contains symbols) */ -#define CT_END 0x0008 /* last command of session, stop replying */ - -/* index in macro array: macros only for these commands */ -#define CI_NONE (-1) -#define CI_CONN 0 -#define CI_HELO 1 -#define CI_MAIL 2 -#define CI_RCPT 3 -#define CI_DATA 4 -#define CI_EOM 5 -#define CI_EOH 6 -#define CI_LAST CI_EOH -#if CI_LAST < CI_DATA -ERROR: do not compile with CI_LAST < CI_DATA -#endif -#if CI_LAST < CI_EOM -ERROR: do not compile with CI_LAST < CI_EOM -#endif -#if CI_LAST < CI_EOH -ERROR: do not compile with CI_LAST < CI_EOH -#endif -#if CI_LAST < CI_ENVRCPT -ERROR: do not compile with CI_LAST < CI_ENVRCPT -#endif -#if CI_LAST < CI_ENVFROM -ERROR: do not compile with CI_LAST < CI_ENVFROM -#endif -#if CI_LAST < CI_HELO -ERROR: do not compile with CI_LAST < CI_HELO -#endif -#if CI_LAST < CI_CONNECT -ERROR: do not compile with CI_LAST < CI_CONNECT -#endif -#if CI_LAST >= MAX_MACROS_ENTRIES -ERROR: do not compile with CI_LAST >= MAX_MACROS_ENTRIES -#endif - -/* function prototypes */ -static int st_abortfct __P((genarg *)); -static int st_macros __P((genarg *)); -static int st_optionneg __P((genarg *)); -static int st_bodychunk __P((genarg *)); -static int st_connectinfo __P((genarg *)); -static int st_bodyend __P((genarg *)); -static int st_helo __P((genarg *)); -static int st_header __P((genarg *)); -static int st_sender __P((genarg *)); -static int st_rcpt __P((genarg *)); -static int st_unknown __P((genarg *)); -static int st_data __P((genarg *)); -static int st_eoh __P((genarg *)); -static int st_quit __P((genarg *)); -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)); -static int dec_arg2 __P((char *, size_t, char **, char **)); - -#if _FFR_WORKERS_POOL -static bool mi_rd_socket_ready __P((int)); -#endif /* _FFR_WORKERS_POOL */ - -/* states */ -#define ST_NONE (-1) -#define ST_INIT 0 /* initial state */ -#define ST_OPTS 1 /* option negotiation */ -#define ST_CONN 2 /* connection info */ -#define ST_HELO 3 /* helo */ -#define ST_MAIL 4 /* mail from */ -#define ST_RCPT 5 /* rcpt to */ -#define ST_DATA 6 /* data */ -#define ST_HDRS 7 /* headers */ -#define ST_EOHS 8 /* end of headers */ -#define ST_BODY 9 /* body */ -#define ST_ENDM 10 /* end of message */ -#define ST_QUIT 11 /* quit */ -#define ST_ABRT 12 /* abort */ -#define ST_UNKN 13 /* unknown SMTP command */ -#define ST_Q_NC 14 /* quit, new connection follows */ -#define ST_LAST ST_Q_NC /* last valid state */ -#define ST_SKIP 16 /* 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) -** each state has a set of allowed transitions ('or' of bits of states) -** so a state transition is valid if the mask of the next state -** is set in the NX_* value -** this function is coded in trans_ok(), see below. -*/ - -#define MI_MASK(x) (0x0001 << (x)) /* generate a bit "mask" for a state */ -#define NX_INIT (MI_MASK(ST_OPTS)) -#define NX_OPTS (MI_MASK(ST_CONN) | MI_MASK(ST_UNKN)) -#define NX_CONN (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN)) -#define NX_HELO (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN)) -#define NX_MAIL (MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | MI_MASK(ST_UNKN)) -#define NX_RCPT (MI_MASK(ST_HDRS) | MI_MASK(ST_EOHS) | MI_MASK(ST_DATA) | \ - MI_MASK(ST_BODY) | MI_MASK(ST_ENDM) | \ - MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | MI_MASK(ST_UNKN)) -#define NX_DATA (MI_MASK(ST_EOHS) | MI_MASK(ST_HDRS) | MI_MASK(ST_ABRT)) -#define NX_HDRS (MI_MASK(ST_EOHS) | MI_MASK(ST_HDRS) | MI_MASK(ST_ABRT)) -#define NX_EOHS (MI_MASK(ST_BODY) | MI_MASK(ST_ENDM) | MI_MASK(ST_ABRT)) -#define NX_BODY (MI_MASK(ST_ENDM) | MI_MASK(ST_BODY) | MI_MASK(ST_ABRT)) -#define NX_ENDM (MI_MASK(ST_QUIT) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN) | \ - MI_MASK(ST_Q_NC)) -#define NX_QUIT 0 -#define NX_ABRT 0 -#define NX_UNKN (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | \ - MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | \ - MI_MASK(ST_DATA) | \ - MI_MASK(ST_BODY) | MI_MASK(ST_UNKN) | \ - MI_MASK(ST_ABRT) | MI_MASK(ST_QUIT) | MI_MASK(ST_Q_NC)) -#define NX_Q_NC (MI_MASK(ST_CONN) | MI_MASK(ST_UNKN)) -#define NX_SKIP MI_MASK(ST_SKIP) - -static int next_states[] = -{ - NX_INIT - , NX_OPTS - , NX_CONN - , NX_HELO - , NX_MAIL - , NX_RCPT - , NX_DATA - , NX_HDRS - , NX_EOHS - , NX_BODY - , NX_ENDM - , NX_QUIT - , NX_ABRT - , NX_UNKN - , NX_Q_NC -}; - -#define SIZE_NEXT_STATES (sizeof(next_states) / sizeof(next_states[0])) - -/* commands received by milter */ -static cmdfct cmds[] = -{ - {SMFIC_ABORT, CM_ARG0, ST_ABRT, CT_CONT, CI_NONE, st_abortfct } -, {SMFIC_MACRO, CM_ARGV, ST_NONE, CT_KEEP, CI_NONE, st_macros } -, {SMFIC_BODY, CM_ARG1, ST_BODY, CT_CONT, CI_NONE, st_bodychunk } -, {SMFIC_CONNECT, CM_ARG2, ST_CONN, CT_CONT, CI_CONN, st_connectinfo } -, {SMFIC_BODYEOB, CM_ARG1, ST_ENDM, CT_CONT, CI_EOM, st_bodyend } -, {SMFIC_HELO, CM_ARG1, ST_HELO, CT_CONT, CI_HELO, st_helo } -, {SMFIC_HEADER, CM_ARG2, ST_HDRS, CT_CONT, CI_NONE, st_header } -, {SMFIC_MAIL, CM_ARGV, ST_MAIL, CT_CONT, CI_MAIL, st_sender } -, {SMFIC_OPTNEG, CM_ARGO, ST_OPTS, CT_CONT, CI_NONE, st_optionneg } -, {SMFIC_EOH, CM_ARG0, ST_EOHS, CT_CONT, CI_EOH, st_eoh } -, {SMFIC_QUIT, CM_ARG0, ST_QUIT, CT_END, CI_NONE, st_quit } -, {SMFIC_DATA, CM_ARG0, ST_DATA, CT_CONT, CI_DATA, st_data } -, {SMFIC_RCPT, CM_ARGV, ST_RCPT, CT_IGNO, CI_RCPT, st_rcpt } -, {SMFIC_UNKNOWN, CM_ARG1, ST_UNKN, CT_IGNO, CI_NONE, st_unknown } -, {SMFIC_QUIT_NC, CM_ARG0, ST_Q_NC, CT_CONT, CI_NONE, st_quit } -}; - -/* -** Additional (internal) reply codes; -** must be coordinated wit libmilter/mfapi.h -*/ - -#define _SMFIS_KEEP 20 -#define _SMFIS_ABORT 21 -#define _SMFIS_OPTIONS 22 -#define _SMFIS_NOREPLY SMFIS_NOREPLY -#define _SMFIS_FAIL (-1) -#define _SMFIS_NONE (-2) - -/* -** MI_ENGINE -- receive commands and process them -** -** Parameters: -** ctx -- context structure -** -** Returns: -** MI_FAILURE/MI_SUCCESS -*/ - -int -mi_engine(ctx) - SMFICTX_PTR ctx; -{ - size_t len; - 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; - genarg arg; - struct timeval timeout; - int (*f) __P((genarg *)); - sfsistat (*fi_abort) __P((SMFICTX *)); - sfsistat (*fi_close) __P((SMFICTX *)); - - arg.a_ctx = ctx; - sd = ctx->ctx_sd; - fi_abort = ctx->ctx_smfi->xxfi_abort; -#if _FFR_WORKERS_POOL - curstate = ctx->ctx_state; - if (curstate == ST_INIT) - { - mi_clr_macros(ctx, 0); - fix_stm(ctx); - } -#else /* _FFR_WORKERS_POOL */ - mi_clr_macros(ctx, 0); - fix_stm(ctx); -#endif /* _FFR_WORKERS_POOL */ - r = _SMFIS_NONE; - 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) - { - if (ctx->ctx_dbg > 3) - sm_dprintf("[%ld] milter_abort\n", - (long) ctx->ctx_id); - ret = MI_FAILURE; - break; - } - - /* - ** Notice: buf is allocated by mi_rd_cmd() and it will - ** usually be free()d after it has been used in f(). - ** However, if the function returns _SMFIS_KEEP then buf - ** contains macros and will not be free()d. - ** Hence r must be set to _SMFIS_NONE if a new buf is - ** allocated to avoid problem with housekeeping, esp. - ** if the code "break"s out of the loop. - */ - -#if _FFR_WORKERS_POOL - /* Is the socket ready to be read ??? */ - if (!mi_rd_socket_ready(sd)) - { - ret = MI_CONTINUE; - break; - } -#endif /* _FFR_WORKERS_POOL */ - - r = _SMFIS_NONE; - if ((buf = mi_rd_cmd(sd, &timeout, &cmd, &len, - ctx->ctx_smfi->xxfi_name)) == NULL && - cmd < SMFIC_VALIDCMD) - { - if (ctx->ctx_dbg > 5) - sm_dprintf("[%ld] mi_engine: mi_rd_cmd error (%x)\n", - (long) ctx->ctx_id, (int) cmd); - - /* - ** eof is currently treated as failure -> - ** abort() instead of close(), otherwise use: - ** if (cmd != SMFIC_EOF) - */ - - ret = MI_FAILURE; - break; - } - if (ctx->ctx_dbg > 4) - sm_dprintf("[%ld] got cmd '%c' len %d\n", - (long) ctx->ctx_id, cmd, (int) len); - for (i = 0; i < ncmds; i++) - { - if (cmd == cmds[i].cm_cmd) - break; - } - if (i >= ncmds) - { - /* unknown command */ - if (ctx->ctx_dbg > 1) - sm_dprintf("[%ld] cmd '%c' unknown\n", - (long) ctx->ctx_id, cmd); - ret = MI_FAILURE; - break; - } - if ((f = cmds[i].cm_fct) == NULL) - { - /* stop for now */ - if (ctx->ctx_dbg > 1) - sm_dprintf("[%ld] cmd '%c' not impl\n", - (long) ctx->ctx_id, cmd); - ret = MI_FAILURE; - break; - } - - /* is new state ok? */ - newstate = cmds[i].cm_next; - if (ctx->ctx_dbg > 5) - sm_dprintf("[%ld] cur %x new %x nextmask %x\n", - (long) ctx->ctx_id, - curstate, newstate, next_states[curstate]); - - if (newstate != ST_NONE && !trans_ok(curstate, newstate)) - { - if (ctx->ctx_dbg > 1) - sm_dprintf("[%ld] abort: cur %d (%x) new %d (%x) next %x\n", - (long) ctx->ctx_id, - curstate, MI_MASK(curstate), - newstate, MI_MASK(newstate), - next_states[curstate]); - - /* call abort only if in a mail transaction */ - if (fi_abort != NULL && call_abort) - (void) (*fi_abort)(ctx); - - /* - ** try to reach the new state from HELO - ** if it can't be reached, ignore the command. - */ - - curstate = ST_HELO; - if (!trans_ok(curstate, newstate)) - { - if (buf != NULL) - { - free(buf); - buf = NULL; - } - continue; - } - } - arg.a_len = len; - arg.a_buf = buf; - if (newstate != ST_NONE) - { - curstate = newstate; - ctx->ctx_state = curstate; - } - arg.a_idx = cmds[i].cm_macros; - call_abort = ST_IN_MAIL(curstate); - - /* call function to deal with command */ - MI_MONITOR_BEGIN(ctx, cmd); - r = (*f)(&arg); - MI_MONITOR_END(ctx, cmd); - if (r != _SMFIS_KEEP && buf != NULL) - { - free(buf); - buf = NULL; - } - if (sendreply(r, sd, &timeout, ctx) != MI_SUCCESS) - { - ret = MI_FAILURE; - break; - } - - if (r == SMFIS_ACCEPT) - { - /* accept mail, no further actions taken */ - curstate = ST_HELO; - } - else if (r == SMFIS_REJECT || r == SMFIS_DISCARD || - r == SMFIS_TEMPFAIL) - { - /* - ** further actions depend on current state - ** if the IGNO bit is set: "ignore" the error, - ** i.e., stay in the current state - */ - if (!bitset(CT_IGNO, cmds[i].cm_todo)) - curstate = ST_HELO; - } - else if (r == _SMFIS_ABORT) - { - if (ctx->ctx_dbg > 5) - sm_dprintf("[%ld] function returned abort\n", - (long) ctx->ctx_id); - ret = MI_FAILURE; - break; - } - } while (!bitset(CT_END, cmds[i].cm_todo)); - - ctx->ctx_state = curstate; - - if (ret == MI_FAILURE) - { - /* call abort only if in a mail transaction */ - if (fi_abort != NULL && call_abort) - (void) (*fi_abort)(ctx); - } - - /* has close been called? */ - if (ctx->ctx_state != ST_QUIT -#if _FFR_WORKERS_POOL - && ret != MI_CONTINUE -#endif /* _FFR_WORKERS_POOL */ - ) - { - if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL) - (void) (*fi_close)(ctx); - } - if (r != _SMFIS_KEEP && buf != NULL) - free(buf); -#if !_FFR_WORKERS_POOL - mi_clr_macros(ctx, 0); -#endif /* _FFR_WORKERS_POOL */ - return ret; -} - -static size_t milter_addsymlist __P((SMFICTX_PTR, char *, char **)); - -static size_t -milter_addsymlist(ctx, buf, newbuf) - SMFICTX_PTR ctx; - char *buf; - char **newbuf; -{ - size_t len; - int i; - mi_int32 v; - char *buffer; - - SM_ASSERT(ctx != NULL); - SM_ASSERT(buf != NULL); - SM_ASSERT(newbuf != NULL); - len = 0; - for (i = 0; i < MAX_MACROS_ENTRIES; i++) - { - if (ctx->ctx_mac_list[i] != NULL) - { - len += strlen(ctx->ctx_mac_list[i]) + 1 + - MILTER_LEN_BYTES; - } - } - if (len > 0) - { - size_t offset; - - SM_ASSERT(len + MILTER_OPTLEN > len); - len += MILTER_OPTLEN; - buffer = malloc(len); - if (buffer != NULL) - { - (void) memcpy(buffer, buf, MILTER_OPTLEN); - offset = MILTER_OPTLEN; - for (i = 0; i < MAX_MACROS_ENTRIES; i++) - { - size_t l; - - if (ctx->ctx_mac_list[i] == NULL) - continue; - - SM_ASSERT(offset + MILTER_LEN_BYTES < len); - v = htonl(i); - (void) memcpy(buffer + offset, (void *) &v, - MILTER_LEN_BYTES); - offset += MILTER_LEN_BYTES; - l = strlen(ctx->ctx_mac_list[i]) + 1; - SM_ASSERT(offset + l <= len); - (void) memcpy(buffer + offset, - ctx->ctx_mac_list[i], l); - offset += l; - } - } - else - { - /* oops ... */ - } - } - else - { - len = MILTER_OPTLEN; - buffer = buf; - } - *newbuf = buffer; - return len; -} - -/* -** GET_NR_BIT -- get "no reply" bit matching state -** -** Parameters: -** state -- current protocol stage -** -** Returns: -** 0: no matching bit -** >0: the matching "no reply" bit -*/ - -static unsigned long get_nr_bit __P((int)); - -static unsigned long -get_nr_bit(state) - int state; -{ - unsigned long bit; - - switch (state) - { - case ST_CONN: - bit = SMFIP_NR_CONN; - break; - case ST_HELO: - bit = SMFIP_NR_HELO; - break; - case ST_MAIL: - bit = SMFIP_NR_MAIL; - break; - case ST_RCPT: - bit = SMFIP_NR_RCPT; - break; - case ST_DATA: - bit = SMFIP_NR_DATA; - break; - case ST_UNKN: - bit = SMFIP_NR_UNKN; - break; - case ST_HDRS: - bit = SMFIP_NR_HDR; - break; - case ST_EOHS: - bit = SMFIP_NR_EOH; - break; - case ST_BODY: - bit = SMFIP_NR_BODY; - break; - default: - bit = 0; - break; - } - return bit; -} - -/* -** SENDREPLY -- send a reply to the MTA -** -** Parameters: -** r -- reply code -** sd -- socket descriptor -** timeout_ptr -- (ptr to) timeout to use for sending -** ctx -- context structure -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -static int -sendreply(r, sd, timeout_ptr, ctx) - sfsistat r; - socket_t sd; - struct timeval *timeout_ptr; - SMFICTX_PTR ctx; -{ - int ret; - unsigned long bit; - - ret = MI_SUCCESS; - - bit = get_nr_bit(ctx->ctx_state); - if (bit != 0 && (ctx->ctx_pflags & bit) != 0 && r != SMFIS_NOREPLY) - { - if (r >= SMFIS_CONTINUE && r < _SMFIS_KEEP) - { - /* milter said it wouldn't reply, but it lied... */ - smi_log(SMI_LOG_ERR, - "%s: milter claimed not to reply in state %d but did anyway %d\n", - ctx->ctx_smfi->xxfi_name, - ctx->ctx_state, r); - - } - - /* - ** Force specified behavior, otherwise libmilter - ** and MTA will fail to communicate properly. - */ - - switch (r) - { - case SMFIS_CONTINUE: - case SMFIS_TEMPFAIL: - case SMFIS_REJECT: - case SMFIS_DISCARD: - case SMFIS_ACCEPT: - case SMFIS_SKIP: - case _SMFIS_OPTIONS: - r = SMFIS_NOREPLY; - break; - } - } - - switch (r) - { - case SMFIS_CONTINUE: - ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_CONTINUE, NULL, 0); - break; - case SMFIS_TEMPFAIL: - case SMFIS_REJECT: - if (ctx->ctx_reply != NULL && - ((r == SMFIS_TEMPFAIL && *ctx->ctx_reply == '4') || - (r == SMFIS_REJECT && *ctx->ctx_reply == '5'))) - { - ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_REPLYCODE, - ctx->ctx_reply, - strlen(ctx->ctx_reply) + 1); - free(ctx->ctx_reply); - ctx->ctx_reply = NULL; - } - else - { - ret = mi_wr_cmd(sd, timeout_ptr, r == SMFIS_REJECT ? - SMFIR_REJECT : SMFIR_TEMPFAIL, NULL, 0); - } - break; - case SMFIS_DISCARD: - ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_DISCARD, NULL, 0); - break; - case SMFIS_ACCEPT: - ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_ACCEPT, NULL, 0); - break; - case SMFIS_SKIP: - ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_SKIP, NULL, 0); - break; - case _SMFIS_OPTIONS: - { - mi_int32 v; - size_t len; - char *buffer; - char buf[MILTER_OPTLEN]; - - v = htonl(ctx->ctx_prot_vers2mta); - (void) memcpy(&(buf[0]), (void *) &v, - MILTER_LEN_BYTES); - v = htonl(ctx->ctx_aflags); - (void) memcpy(&(buf[MILTER_LEN_BYTES]), (void *) &v, - MILTER_LEN_BYTES); - v = htonl(ctx->ctx_pflags2mta); - (void) memcpy(&(buf[MILTER_LEN_BYTES * 2]), - (void *) &v, MILTER_LEN_BYTES); - len = milter_addsymlist(ctx, buf, &buffer); - if (buffer != NULL) - ret = mi_wr_cmd(sd, timeout_ptr, SMFIC_OPTNEG, - buffer, len); - else - ret = MI_FAILURE; - } - break; - case SMFIS_NOREPLY: - if (bit != 0 && - (ctx->ctx_pflags & bit) != 0 && - (ctx->ctx_mta_pflags & bit) == 0) - { - /* - ** milter doesn't want to send a reply, - ** but the MTA doesn't have that feature: fake it. - */ - - ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_CONTINUE, NULL, - 0); - } - break; - default: /* don't send a reply */ - break; - } - return ret; -} - -/* -** CLR_MACROS -- clear set of macros starting from a given index -** -** Parameters: -** ctx -- context structure -** m -- index from which to clear all macros -** -** Returns: -** None. -*/ - -void -mi_clr_macros(ctx, m) - SMFICTX_PTR ctx; - int m; -{ - int i; - - for (i = m; i < MAX_MACROS_ENTRIES; i++) - { - if (ctx->ctx_mac_ptr[i] != NULL) - { - free(ctx->ctx_mac_ptr[i]); - ctx->ctx_mac_ptr[i] = NULL; - } - if (ctx->ctx_mac_buf[i] != NULL) - { - free(ctx->ctx_mac_buf[i]); - ctx->ctx_mac_buf[i] = NULL; - } - } -} - -/* -** ST_OPTIONNEG -- negotiate options -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** abort/send options/continue -*/ - -static int -st_optionneg(g) - genarg *g; -{ - mi_int32 i, v, fake_pflags; - SMFICTX_PTR ctx; - int (*fi_negotiate) __P((SMFICTX *, - unsigned long, unsigned long, - unsigned long, unsigned long, - unsigned long *, unsigned long *, - unsigned long *, unsigned long *)); - - if (g == NULL || g->a_ctx->ctx_smfi == NULL) - return SMFIS_CONTINUE; - ctx = g->a_ctx; - mi_clr_macros(ctx, g->a_idx + 1); - ctx->ctx_prot_vers = SMFI_PROT_VERSION; - - /* check for minimum length */ - if (g->a_len < MILTER_OPTLEN) - { - smi_log(SMI_LOG_ERR, - "%s: st_optionneg[%ld]: len too short %d < %d", - ctx->ctx_smfi->xxfi_name, - (long) ctx->ctx_id, (int) g->a_len, - MILTER_OPTLEN); - return _SMFIS_ABORT; - } - - /* protocol version */ - (void) memcpy((void *) &i, (void *) &(g->a_buf[0]), MILTER_LEN_BYTES); - v = ntohl(i); - -#define SMFI_PROT_VERSION_MIN 2 - - /* check for minimum version */ - if (v < SMFI_PROT_VERSION_MIN) - { - smi_log(SMI_LOG_ERR, - "%s: st_optionneg[%ld]: protocol version too old %d < %d", - ctx->ctx_smfi->xxfi_name, - (long) ctx->ctx_id, v, SMFI_PROT_VERSION_MIN); - return _SMFIS_ABORT; - } - ctx->ctx_mta_prot_vers = v; - if (ctx->ctx_prot_vers < ctx->ctx_mta_prot_vers) - ctx->ctx_prot_vers2mta = ctx->ctx_prot_vers; - else - ctx->ctx_prot_vers2mta = ctx->ctx_mta_prot_vers; - - (void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES]), - MILTER_LEN_BYTES); - v = ntohl(i); - - /* no flags? set to default value for V1 actions */ - if (v == 0) - v = SMFI_V1_ACTS; - ctx->ctx_mta_aflags = v; /* MTA action flags */ - - (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; - ctx->ctx_mta_pflags = v; /* MTA protocol flags */ - - /* - ** Copy flags from milter struct into libmilter context; - ** this variable will be used later on to check whether - ** the MTA "actions" can fulfill the milter requirements, - ** but it may be overwritten by the negotiate callback. - */ - - ctx->ctx_aflags = ctx->ctx_smfi->xxfi_flags; - fake_pflags = SMFIP_NR_CONN - |SMFIP_NR_HELO - |SMFIP_NR_MAIL - |SMFIP_NR_RCPT - |SMFIP_NR_DATA - |SMFIP_NR_UNKN - |SMFIP_NR_HDR - |SMFIP_NR_EOH - |SMFIP_NR_BODY - ; - - if (g->a_ctx->ctx_smfi != NULL && - g->a_ctx->ctx_smfi->xxfi_version > 4 && - (fi_negotiate = g->a_ctx->ctx_smfi->xxfi_negotiate) != NULL) - { - int r; - unsigned long m_aflags, m_pflags, m_f2, m_f3; - - /* - ** let milter decide whether the features offered by the - ** MTA are "good enough". - ** Notes: - ** - libmilter can "fake" some features (e.g., SMFIP_NR_HDR) - ** - m_f2, m_f3 are for future extensions - */ - - m_f2 = m_f3 = 0; - m_aflags = ctx->ctx_mta_aflags; - m_pflags = ctx->ctx_pflags; - if ((SMFIP_SKIP & ctx->ctx_mta_pflags) != 0) - m_pflags |= SMFIP_SKIP; - r = fi_negotiate(g->a_ctx, - ctx->ctx_mta_aflags, - ctx->ctx_mta_pflags|fake_pflags, - 0, 0, - &m_aflags, &m_pflags, &m_f2, &m_f3); - - /* - ** Types of protocol flags (pflags): - ** 1. do NOT send protocol step X - ** 2. MTA can do/understand something extra (SKIP, - ** send unknown RCPTs) - ** 3. MTA can deal with "no reply" for various protocol steps - ** Note: this mean that it isn't possible to simply set all - ** flags to get "everything": - ** setting a flag of type 1 turns off a step - ** (it should be the other way around: - ** a flag means a protocol step can be sent) - ** setting a flag of type 3 requires that milter - ** never sends a reply for the corresponding step. - ** Summary: the "negation" of protocol flags is causing - ** problems, but at least for type 3 there is no simple - ** solution. - ** - ** What should "all options" mean? - ** send all protocol steps _except_ those for which there is - ** no callback (currently registered in ctx_pflags) - ** expect SKIP as return code? Yes - ** send unknown RCPTs? No, - ** must be explicitly requested? - ** "no reply" for some protocol steps? No, - ** must be explicitly requested. - */ - - if (SMFIS_ALL_OPTS == r) - { - ctx->ctx_aflags = ctx->ctx_mta_aflags; - ctx->ctx_pflags2mta = ctx->ctx_pflags; - if ((SMFIP_SKIP & ctx->ctx_mta_pflags) != 0) - ctx->ctx_pflags2mta |= SMFIP_SKIP; - } - else if (r != SMFIS_CONTINUE) - { - smi_log(SMI_LOG_ERR, - "%s: st_optionneg[%ld]: xxfi_negotiate returned %d (protocol options=0x%lx, actions=0x%lx)", - ctx->ctx_smfi->xxfi_name, - (long) ctx->ctx_id, r, ctx->ctx_mta_pflags, - ctx->ctx_mta_aflags); - return _SMFIS_ABORT; - } - else - { - ctx->ctx_aflags = m_aflags; - ctx->ctx_pflags = m_pflags; - ctx->ctx_pflags2mta = m_pflags; - } - - /* check whether some flags need to be "faked" */ - i = ctx->ctx_pflags2mta; - if ((ctx->ctx_mta_pflags & i) != i) - { - unsigned int idx; - unsigned long b; - - /* - ** If some behavior can be faked (set in fake_pflags), - ** but the MTA doesn't support it, then unset - ** that flag in the value that is sent to the MTA. - */ - - for (idx = 0; idx < 32; idx++) - { - b = 1 << idx; - if ((ctx->ctx_mta_pflags & b) != b && - (fake_pflags & b) == b) - ctx->ctx_pflags2mta &= ~b; - } - } - } - else - { - /* - ** Set the protocol flags based on the values determined - ** in mi_listener() which checked the defined callbacks. - */ - - ctx->ctx_pflags2mta = ctx->ctx_pflags; - } - - /* check whether actions and protocol requirements can be satisfied */ - i = ctx->ctx_aflags; - if ((i & ctx->ctx_mta_aflags) != i) - { - smi_log(SMI_LOG_ERR, - "%s: st_optionneg[%ld]: 0x%lx does not fulfill action requirements 0x%x", - ctx->ctx_smfi->xxfi_name, - (long) ctx->ctx_id, ctx->ctx_mta_aflags, i); - return _SMFIS_ABORT; - } - - i = ctx->ctx_pflags2mta; - if ((ctx->ctx_mta_pflags & i) != i) - { - /* - ** Older MTAs do not support some protocol steps. - ** As this protocol is a bit "wierd" (it asks for steps - ** NOT to be taken/sent) we have to check whether we - ** should turn off those "negative" requests. - ** Currently these are only SMFIP_NODATA and SMFIP_NOUNKNOWN. - */ - - if (bitset(SMFIP_NODATA, ctx->ctx_pflags2mta) && - !bitset(SMFIP_NODATA, ctx->ctx_mta_pflags)) - ctx->ctx_pflags2mta &= ~SMFIP_NODATA; - if (bitset(SMFIP_NOUNKNOWN, ctx->ctx_pflags2mta) && - !bitset(SMFIP_NOUNKNOWN, ctx->ctx_mta_pflags)) - ctx->ctx_pflags2mta &= ~SMFIP_NOUNKNOWN; - i = ctx->ctx_pflags2mta; - } - - if ((ctx->ctx_mta_pflags & i) != i) - { - smi_log(SMI_LOG_ERR, - "%s: st_optionneg[%ld]: 0x%lx does not fulfill protocol requirements 0x%x", - ctx->ctx_smfi->xxfi_name, - (long) ctx->ctx_id, ctx->ctx_mta_pflags, i); - return _SMFIS_ABORT; - } - - if (ctx->ctx_dbg > 3) - sm_dprintf("[%ld] milter_negotiate:" - " mta_actions=0x%lx, mta_flags=0x%lx" - " actions=0x%lx, flags=0x%lx\n" - , (long) ctx->ctx_id - , ctx->ctx_mta_aflags, ctx->ctx_mta_pflags - , ctx->ctx_aflags, ctx->ctx_pflags); - - return _SMFIS_OPTIONS; -} - -/* -** ST_CONNECTINFO -- receive connection information -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_connectinfo(g) - genarg *g; -{ - size_t l; - size_t i; - char *s, family; - unsigned short port = 0; - _SOCK_ADDR sockaddr; - sfsistat (*fi_connect) __P((SMFICTX *, char *, _SOCK_ADDR *)); - - if (g == NULL) - return _SMFIS_ABORT; - mi_clr_macros(g->a_ctx, g->a_idx + 1); - if (g->a_ctx->ctx_smfi == NULL || - (fi_connect = g->a_ctx->ctx_smfi->xxfi_connect) == NULL) - return SMFIS_CONTINUE; - - s = g->a_buf; - i = 0; - l = g->a_len; - while (s[i] != '\0' && i <= l) - ++i; - if (i + 1 >= l) - return _SMFIS_ABORT; - - /* Move past trailing \0 in host string */ - i++; - family = s[i++]; - (void) memset(&sockaddr, '\0', sizeof sockaddr); - if (family != SMFIA_UNKNOWN) - { - if (i + sizeof port >= l) - { - smi_log(SMI_LOG_ERR, - "%s: connect[%ld]: wrong len %d >= %d", - g->a_ctx->ctx_smfi->xxfi_name, - (long) g->a_ctx->ctx_id, (int) i, (int) l); - return _SMFIS_ABORT; - } - (void) memcpy((void *) &port, (void *) (s + i), - sizeof port); - i += sizeof port; - - /* make sure string is terminated */ - if (s[l - 1] != '\0') - return _SMFIS_ABORT; -# if NETINET - if (family == SMFIA_INET) - { - if (inet_aton(s + i, (struct in_addr *) &sockaddr.sin.sin_addr) - != 1) - { - smi_log(SMI_LOG_ERR, - "%s: connect[%ld]: inet_aton failed", - g->a_ctx->ctx_smfi->xxfi_name, - (long) g->a_ctx->ctx_id); - return _SMFIS_ABORT; - } - sockaddr.sa.sa_family = AF_INET; - if (port > 0) - sockaddr.sin.sin_port = port; - } - else -# endif /* NETINET */ -# if NETINET6 - if (family == SMFIA_INET6) - { - if (mi_inet_pton(AF_INET6, s + i, - &sockaddr.sin6.sin6_addr) != 1) - { - smi_log(SMI_LOG_ERR, - "%s: connect[%ld]: mi_inet_pton failed", - g->a_ctx->ctx_smfi->xxfi_name, - (long) g->a_ctx->ctx_id); - return _SMFIS_ABORT; - } - sockaddr.sa.sa_family = AF_INET6; - if (port > 0) - sockaddr.sin6.sin6_port = port; - } - else -# endif /* NETINET6 */ -# if NETUNIX - if (family == SMFIA_UNIX) - { - if (sm_strlcpy(sockaddr.sunix.sun_path, s + i, - sizeof sockaddr.sunix.sun_path) >= - sizeof sockaddr.sunix.sun_path) - { - smi_log(SMI_LOG_ERR, - "%s: connect[%ld]: path too long", - g->a_ctx->ctx_smfi->xxfi_name, - (long) g->a_ctx->ctx_id); - return _SMFIS_ABORT; - } - sockaddr.sunix.sun_family = AF_UNIX; - } - else -# endif /* NETUNIX */ - { - smi_log(SMI_LOG_ERR, - "%s: connect[%ld]: unknown family %d", - g->a_ctx->ctx_smfi->xxfi_name, - (long) g->a_ctx->ctx_id, family); - return _SMFIS_ABORT; - } - } - return (*fi_connect)(g->a_ctx, g->a_buf, - family != SMFIA_UNKNOWN ? &sockaddr : NULL); -} - -/* -** ST_EOH -- end of headers -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_eoh(g) - genarg *g; -{ - sfsistat (*fi_eoh) __P((SMFICTX *)); - - if (g == NULL) - return _SMFIS_ABORT; - if (g->a_ctx->ctx_smfi != NULL && - (fi_eoh = g->a_ctx->ctx_smfi->xxfi_eoh) != NULL) - return (*fi_eoh)(g->a_ctx); - return SMFIS_CONTINUE; -} - -/* -** ST_DATA -- DATA command -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_data(g) - genarg *g; -{ - sfsistat (*fi_data) __P((SMFICTX *)); - - if (g == NULL) - return _SMFIS_ABORT; - if (g->a_ctx->ctx_smfi != NULL && - g->a_ctx->ctx_smfi->xxfi_version > 3 && - (fi_data = g->a_ctx->ctx_smfi->xxfi_data) != NULL) - return (*fi_data)(g->a_ctx); - return SMFIS_CONTINUE; -} - -/* -** ST_HELO -- helo/ehlo command -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_helo(g) - genarg *g; -{ - sfsistat (*fi_helo) __P((SMFICTX *, char *)); - - if (g == NULL) - return _SMFIS_ABORT; - mi_clr_macros(g->a_ctx, g->a_idx + 1); - if (g->a_ctx->ctx_smfi != NULL && - (fi_helo = g->a_ctx->ctx_smfi->xxfi_helo) != NULL) - { - /* paranoia: check for terminating '\0' */ - if (g->a_len == 0 || g->a_buf[g->a_len - 1] != '\0') - return MI_FAILURE; - return (*fi_helo)(g->a_ctx, g->a_buf); - } - return SMFIS_CONTINUE; -} - -/* -** ST_HEADER -- header line -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_header(g) - genarg *g; -{ - char *hf, *hv; - sfsistat (*fi_header) __P((SMFICTX *, char *, char *)); - - if (g == NULL) - return _SMFIS_ABORT; - if (g->a_ctx->ctx_smfi == NULL || - (fi_header = g->a_ctx->ctx_smfi->xxfi_header) == NULL) - return SMFIS_CONTINUE; - if (dec_arg2(g->a_buf, g->a_len, &hf, &hv) == MI_SUCCESS) - return (*fi_header)(g->a_ctx, hf, hv); - else - 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; \ - if ((argv = dec_argv(g->a_buf, g->a_len)) == NULL) \ - return _SMFIS_ABORT; \ - r = (*lf)(g->a_ctx, argv); \ - free(argv); \ - return r; - -/* -** ST_SENDER -- MAIL FROM command -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_sender(g) - genarg *g; -{ - ARGV_FCT(fi_envfrom, xxfi_envfrom, CI_MAIL) -} - -/* -** ST_RCPT -- RCPT TO command -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_rcpt(g) - genarg *g; -{ - ARGV_FCT(fi_envrcpt, xxfi_envrcpt, CI_RCPT) -} - -/* -** ST_UNKNOWN -- unrecognized or unimplemented command -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_unknown(g) - genarg *g; -{ - sfsistat (*fi_unknown) __P((SMFICTX *, const char *)); - - if (g == NULL) - return _SMFIS_ABORT; - if (g->a_ctx->ctx_smfi != NULL && - g->a_ctx->ctx_smfi->xxfi_version > 2 && - (fi_unknown = g->a_ctx->ctx_smfi->xxfi_unknown) != NULL) - return (*fi_unknown)(g->a_ctx, (const char *) g->a_buf); - return SMFIS_CONTINUE; -} - -/* -** ST_MACROS -- deal with macros received from the MTA -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue/keep -** -** Side effects: -** set pointer in macro array to current values. -*/ - -static int -st_macros(g) - genarg *g; -{ - int i; - char **argv; - - if (g == NULL || g->a_len < 1) - return _SMFIS_FAIL; - if ((argv = dec_argv(g->a_buf + 1, g->a_len - 1)) == NULL) - return _SMFIS_FAIL; - switch (g->a_buf[0]) - { - case SMFIC_CONNECT: - i = CI_CONN; - break; - case SMFIC_HELO: - i = CI_HELO; - break; - case SMFIC_MAIL: - i = CI_MAIL; - break; - case SMFIC_RCPT: - i = CI_RCPT; - break; - case SMFIC_DATA: - i = CI_DATA; - break; - case SMFIC_BODYEOB: - i = CI_EOM; - break; - case SMFIC_EOH: - i = CI_EOH; - break; - default: - free(argv); - return _SMFIS_FAIL; - } - if (g->a_ctx->ctx_mac_ptr[i] != NULL) - free(g->a_ctx->ctx_mac_ptr[i]); - if (g->a_ctx->ctx_mac_buf[i] != NULL) - free(g->a_ctx->ctx_mac_buf[i]); - g->a_ctx->ctx_mac_ptr[i] = argv; - g->a_ctx->ctx_mac_buf[i] = g->a_buf; - return _SMFIS_KEEP; -} - -/* -** ST_QUIT -- quit command -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** noreply -*/ - -/* ARGSUSED */ -static int -st_quit(g) - genarg *g; -{ - sfsistat (*fi_close) __P((SMFICTX *)); - - if (g == NULL) - return _SMFIS_ABORT; - if (g->a_ctx->ctx_smfi != NULL && - (fi_close = g->a_ctx->ctx_smfi->xxfi_close) != NULL) - (void) (*fi_close)(g->a_ctx); - mi_clr_macros(g->a_ctx, 0); - return _SMFIS_NOREPLY; -} - -/* -** ST_BODYCHUNK -- deal with a piece of the mail body -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -*/ - -static int -st_bodychunk(g) - genarg *g; -{ - 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, (unsigned char *)g->a_buf, - g->a_len); - return SMFIS_CONTINUE; -} - -/* -** ST_BODYEND -- deal with the last piece of the mail body -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** continue or filter-specified value -** -** Side effects: -** sends a reply for the body part (if non-empty). -*/ - -static int -st_bodyend(g) - genarg *g; -{ - sfsistat r; - sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); - sfsistat (*fi_eom) __P((SMFICTX *)); - - if (g == NULL) - return _SMFIS_ABORT; - r = SMFIS_CONTINUE; - if (g->a_ctx->ctx_smfi != NULL) - { - if ((fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL && - g->a_len > 0) - { - socket_t sd; - struct timeval timeout; - - timeout.tv_sec = g->a_ctx->ctx_timeout; - timeout.tv_usec = 0; - sd = g->a_ctx->ctx_sd; - 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; - } - } - if (r == SMFIS_CONTINUE && - (fi_eom = g->a_ctx->ctx_smfi->xxfi_eom) != NULL) - return (*fi_eom)(g->a_ctx); - return r; -} - -/* -** ST_ABORTFCT -- deal with aborts -** -** Parameters: -** g -- generic argument structure -** -** Returns: -** abort or filter-specified value -*/ - -static int -st_abortfct(g) - genarg *g; -{ - sfsistat (*fi_abort) __P((SMFICTX *)); - - if (g == NULL) - return _SMFIS_ABORT; - if (g != NULL && g->a_ctx->ctx_smfi != NULL && - (fi_abort = g->a_ctx->ctx_smfi->xxfi_abort) != NULL) - (void) (*fi_abort)(g->a_ctx); - return _SMFIS_NOREPLY; -} - -/* -** TRANS_OK -- is the state transition ok? -** -** Parameters: -** old -- old state -** new -- new state -** -** Returns: -** state transition ok -*/ - -static bool -trans_ok(old, new) - int old, new; -{ - int s, n; - - s = old; - if (s >= SIZE_NEXT_STATES) - return false; - do - { - /* is this state transition allowed? */ - if ((MI_MASK(new) & next_states[s]) != 0) - return true; - - /* - ** no: try next state; - ** this works since the relevant states are ordered - ** strict sequentially - */ - - n = s + 1; - if (n >= SIZE_NEXT_STATES) - return false; - - /* - ** can we actually "skip" this state? - ** 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; - } while (s < SIZE_NEXT_STATES); - return false; -} - -/* -** FIX_STM -- add "skip" bits to the state transition table -** -** Parameters: -** ctx -- context structure -** -** Returns: -** None. -** -** Side effects: -** may change state transition table. -*/ - -static void -fix_stm(ctx) - SMFICTX_PTR ctx; -{ - unsigned long fl; - - if (ctx == NULL || ctx->ctx_smfi == NULL) - return; - fl = ctx->ctx_pflags; - if (bitset(SMFIP_NOCONNECT, fl)) - next_states[ST_CONN] |= NX_SKIP; - if (bitset(SMFIP_NOHELO, fl)) - next_states[ST_HELO] |= NX_SKIP; - if (bitset(SMFIP_NOMAIL, fl)) - next_states[ST_MAIL] |= NX_SKIP; - if (bitset(SMFIP_NORCPT, fl)) - next_states[ST_RCPT] |= NX_SKIP; - if (bitset(SMFIP_NOHDRS, fl)) - next_states[ST_HDRS] |= NX_SKIP; - if (bitset(SMFIP_NOEOH, fl)) - next_states[ST_EOHS] |= NX_SKIP; - if (bitset(SMFIP_NOBODY, fl)) - next_states[ST_BODY] |= NX_SKIP; - if (bitset(SMFIP_NODATA, fl)) - next_states[ST_DATA] |= NX_SKIP; - if (bitset(SMFIP_NOUNKNOWN, fl)) - next_states[ST_UNKN] |= NX_SKIP; -} - -/* -** DEC_ARGV -- split a buffer into a list of strings, NULL terminated -** -** Parameters: -** buf -- buffer with several strings -** len -- length of buffer -** -** Returns: -** array of pointers to the individual strings -*/ - -static char ** -dec_argv(buf, len) - char *buf; - size_t len; -{ - char **s; - size_t i; - int elem, nelem; - - nelem = 0; - for (i = 0; i < len; i++) - { - if (buf[i] == '\0') - ++nelem; - } - if (nelem == 0) - return NULL; - - /* last entry is only for the name */ - s = (char **)malloc((nelem + 1) * (sizeof *s)); - if (s == NULL) - return NULL; - s[0] = buf; - for (i = 0, elem = 0; i < len && elem < nelem; i++) - { - if (buf[i] == '\0') - { - ++elem; - if (i + 1 >= len) - s[elem] = NULL; - else - s[elem] = &(buf[i + 1]); - } - } - - /* overwrite last entry (already done above, just paranoia) */ - s[elem] = NULL; - return s; -} - -/* -** DEC_ARG2 -- split a buffer into two strings -** -** Parameters: -** buf -- buffer with two strings -** len -- length of buffer -** s1,s2 -- pointer to result strings -** -** Returns: -** MI_FAILURE/MI_SUCCESS -*/ - -static int -dec_arg2(buf, len, s1, s2) - char *buf; - size_t len; - char **s1; - char **s2; -{ - size_t i; - - /* paranoia: check for terminating '\0' */ - if (len == 0 || buf[len - 1] != '\0') - return MI_FAILURE; - *s1 = buf; - for (i = 1; i < len && buf[i] != '\0'; i++) - continue; - if (i >= len - 1) - return MI_FAILURE; - *s2 = buf + i + 1; - return MI_SUCCESS; -} - -/* -** SENDOK -- is it ok for the filter to send stuff to the MTA? -** -** Parameters: -** ctx -- context structure -** flag -- flag to check -** -** Returns: -** sending allowed (in current state) -*/ - -bool -mi_sendok(ctx, flag) - SMFICTX_PTR ctx; - int flag; -{ - if (ctx == NULL || ctx->ctx_smfi == NULL) - return false; - - /* did the milter request this operation? */ - if (flag != 0 && !bitset(flag, ctx->ctx_aflags)) - return false; - - /* are we in the correct state? It must be "End of Message". */ - return ctx->ctx_state == ST_ENDM; -} - -#if _FFR_WORKERS_POOL -/* -** MI_RD_SOCKET_READY - checks if the socket is ready for read(2) -** -** Parameters: -** sd -- socket_t -** -** Returns: -** true iff socket is ready for read(2) -*/ - -#define MI_RD_CMD_TO 1 -#define MI_RD_MAX_ERR 16 - -static bool -mi_rd_socket_ready (sd) - socket_t sd; -{ - int n; - int nerr = 0; -#if SM_CONF_POLL - struct pollfd pfd; -#else /* SM_CONF_POLL */ - fd_set rd_set, exc_set; -#endif /* SM_CONF_POLL */ - - do - { -#if SM_CONF_POLL - pfd.fd = sd; - pfd.events = POLLIN; - pfd.revents = 0; - - n = poll(&pfd, 1, MI_RD_CMD_TO); -#else /* SM_CONF_POLL */ - struct timeval timeout; - - FD_ZERO(&rd_set); - FD_ZERO(&exc_set); - FD_SET(sd, &rd_set); - FD_SET(sd, &exc_set); - - timeout.tv_sec = MI_RD_CMD_TO / 1000; - timeout.tv_usec = 0; - n = select(sd + 1, &rd_set, NULL, &exc_set, &timeout); -#endif /* SM_CONF_POLL */ - - if (n < 0) - { - if (errno == EINTR) - { - nerr++; - continue; - } - return true; - } - - if (n == 0) - return false; - break; - } while (nerr < MI_RD_MAX_ERR); - if (nerr >= MI_RD_MAX_ERR) - return false; - -#if SM_CONF_POLL - return (pfd.revents != 0); -#else /* SM_CONF_POLL */ - return FD_ISSET(sd, &rd_set) || FD_ISSET(sd, &exc_set); -#endif /* SM_CONF_POLL */ -} -#endif /* _FFR_WORKERS_POOL */ diff --git a/contrib/sendmail/libmilter/example.c b/contrib/sendmail/libmilter/example.c deleted file mode 100644 index 5a09f1d..0000000 --- a/contrib/sendmail/libmilter/example.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2006 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - * $Id: example.c,v 8.3 2006/12/20 21:22:34 ca Exp $ - */ - -/* -** A trivial example filter that logs all email to a file. -** This milter also has some callbacks which it does not really use, -** but they are defined to serve as an example. -*/ - -#include <sys/types.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sysexits.h> -#include <unistd.h> - -#include "libmilter/mfapi.h" -#include "libmilter/mfdef.h" - -#ifndef true -# define false 0 -# define true 1 -#endif /* ! true */ - -struct mlfiPriv -{ - char *mlfi_fname; - FILE *mlfi_fp; -}; - -#define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx)) - -static unsigned long mta_caps = 0; - -sfsistat -mlfi_cleanup(ctx, ok) - SMFICTX *ctx; - bool ok; -{ - sfsistat rstat = SMFIS_CONTINUE; - struct mlfiPriv *priv = MLFIPRIV; - char *p; - char host[512]; - char hbuf[1024]; - - if (priv == NULL) - return rstat; - - /* close the archive file */ - if (priv->mlfi_fp != NULL && fclose(priv->mlfi_fp) == EOF) - { - /* failed; we have to wait until later */ - rstat = SMFIS_TEMPFAIL; - (void) unlink(priv->mlfi_fname); - } - else if (ok) - { - /* add a header to the message announcing our presence */ - if (gethostname(host, sizeof host) < 0) - snprintf(host, sizeof host, "localhost"); - p = strrchr(priv->mlfi_fname, '/'); - if (p == NULL) - p = priv->mlfi_fname; - else - p++; - snprintf(hbuf, sizeof hbuf, "%s@%s", p, host); - smfi_addheader(ctx, "X-Archived", hbuf); - } - else - { - /* message was aborted -- delete the archive file */ - (void) unlink(priv->mlfi_fname); - } - - /* release private memory */ - free(priv->mlfi_fname); - free(priv); - smfi_setpriv(ctx, NULL); - - /* return status */ - return rstat; -} - - -sfsistat -mlfi_envfrom(ctx, envfrom) - SMFICTX *ctx; - char **envfrom; -{ - struct mlfiPriv *priv; - int fd = -1; - - /* allocate some private memory */ - priv = malloc(sizeof *priv); - if (priv == NULL) - { - /* can't accept this message right now */ - return SMFIS_TEMPFAIL; - } - memset(priv, '\0', sizeof *priv); - - /* open a file to store this message */ - priv->mlfi_fname = strdup("/tmp/msg.XXXXXXXX"); - if (priv->mlfi_fname == NULL) - { - free(priv); - return SMFIS_TEMPFAIL; - } - if ((fd = mkstemp(priv->mlfi_fname)) < 0 || - (priv->mlfi_fp = fdopen(fd, "w+")) == NULL) - { - if (fd >= 0) - (void) close(fd); - free(priv->mlfi_fname); - free(priv); - return SMFIS_TEMPFAIL; - } - - /* save the private data */ - smfi_setpriv(ctx, priv); - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -mlfi_header(ctx, headerf, headerv) - SMFICTX *ctx; - char *headerf; - char *headerv; -{ - /* write the header to the log file */ - fprintf(MLFIPRIV->mlfi_fp, "%s: %s\r\n", headerf, headerv); - - /* continue processing */ - return ((mta_caps & SMFIP_NR_HDR) != 0) - ? SMFIS_NOREPLY : SMFIS_CONTINUE; -} - -sfsistat -mlfi_eoh(ctx) - SMFICTX *ctx; -{ - /* output the blank line between the header and the body */ - fprintf(MLFIPRIV->mlfi_fp, "\r\n"); - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -mlfi_body(ctx, bodyp, bodylen) - SMFICTX *ctx; - u_char *bodyp; - size_t bodylen; -{ - /* output body block to log file */ - if (fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp) <= 0) - { - /* write failed */ - (void) mlfi_cleanup(ctx, false); - return SMFIS_TEMPFAIL; - } - - /* continue processing */ - return SMFIS_CONTINUE; -} - -sfsistat -mlfi_eom(ctx) - SMFICTX *ctx; -{ - return mlfi_cleanup(ctx, true); -} - -sfsistat -mlfi_close(ctx) - SMFICTX *ctx; -{ - return SMFIS_ACCEPT; -} - -sfsistat -mlfi_abort(ctx) - SMFICTX *ctx; -{ - return mlfi_cleanup(ctx, false); -} - -sfsistat -mlfi_unknown(ctx, cmd) - SMFICTX *ctx; - char *cmd; -{ - return SMFIS_CONTINUE; -} - -sfsistat -mlfi_data(ctx) - SMFICTX *ctx; -{ - return SMFIS_CONTINUE; -} - -sfsistat -mlfi_negotiate(ctx, f0, f1, f2, f3, pf0, pf1, pf2, pf3) - SMFICTX *ctx; - unsigned long f0; - unsigned long f1; - unsigned long f2; - unsigned long f3; - unsigned long *pf0; - unsigned long *pf1; - unsigned long *pf2; - unsigned long *pf3; -{ - /* milter actions: add headers */ - *pf0 = SMFIF_ADDHDRS; - - /* milter protocol steps: all but connect, HELO, RCPT */ - *pf1 = SMFIP_NOCONNECT|SMFIP_NOHELO|SMFIP_NORCPT; - mta_caps = f1; - if ((mta_caps & SMFIP_NR_HDR) != 0) - *pf1 |= SMFIP_NR_HDR; - *pf2 = 0; - *pf3 = 0; - return SMFIS_CONTINUE; -} - -struct smfiDesc smfilter = -{ - "SampleFilter", /* filter name */ - SMFI_VERSION, /* version code -- do not change */ - SMFIF_ADDHDRS, /* flags */ - NULL, /* connection info filter */ - NULL, /* SMTP HELO command filter */ - mlfi_envfrom, /* envelope sender filter */ - NULL, /* envelope recipient filter */ - mlfi_header, /* header filter */ - mlfi_eoh, /* end of header */ - mlfi_body, /* body block filter */ - mlfi_eom, /* end of message */ - mlfi_abort, /* message aborted */ - mlfi_close, /* connection cleanup */ - mlfi_unknown, /* unknown/unimplemented SMTP commands */ - mlfi_data, /* DATA command filter */ - mlfi_negotiate /* option negotation at connection startup */ -}; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - bool setconn; - int c; - - setconn = false; - - /* Process command line options */ - while ((c = getopt(argc, argv, "p:")) != -1) - { - switch (c) - { - case 'p': - if (optarg == NULL || *optarg == '\0') - { - (void) fprintf(stderr, "Illegal conn: %s\n", - optarg); - exit(EX_USAGE); - } - (void) smfi_setconn(optarg); - setconn = true; - break; - - } - } - if (!setconn) - { - fprintf(stderr, "%s: Missing required -p argument\n", argv[0]); - exit(EX_USAGE); - } - if (smfi_register(smfilter) == MI_FAILURE) - { - fprintf(stderr, "smfi_register failed\n"); - exit(EX_UNAVAILABLE); - } - return smfi_main(); -} - diff --git a/contrib/sendmail/libmilter/handler.c b/contrib/sendmail/libmilter/handler.c deleted file mode 100644 index 5fd4b26..0000000 --- a/contrib/sendmail/libmilter/handler.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 1999-2003, 2006 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: handler.c,v 8.38 2006/11/02 02:38:22 ca Exp $") - -#include "libmilter.h" - -#if !_FFR_WORKERS_POOL -/* -** HANDLE_SESSION -- Handle a connected session in its own context -** -** Parameters: -** ctx -- context structure -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -mi_handle_session(ctx) - SMFICTX_PTR ctx; -{ - int ret; - - if (ctx == NULL) - return MI_FAILURE; - ctx->ctx_id = (sthread_t) sthread_get_id(); - - /* - ** Detach so resources are free when the thread returns. - ** If we ever "wait" for threads, this call must be removed. - */ - - if (pthread_detach(ctx->ctx_id) != 0) - ret = MI_FAILURE; - else - ret = mi_engine(ctx); - if (ValidSocket(ctx->ctx_sd)) - { - (void) closesocket(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, - "%s: private data not NULL", - ctx->ctx_smfi->xxfi_name); - } - mi_clr_macros(ctx, 0); - free(ctx); - ctx = NULL; - return ret; -} -#endif /* !_FFR_WORKERS_POOL */ diff --git a/contrib/sendmail/libmilter/libmilter.h b/contrib/sendmail/libmilter/libmilter.h deleted file mode 100644 index 5a12409..0000000 --- a/contrib/sendmail/libmilter/libmilter.h +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (c) 1999-2003, 2006 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - */ - -/* -** LIBMILTER.H -- include file for mail filter library functions -*/ - -#ifndef _LIBMILTER_H -# define _LIBMILTER_H 1 - -#include <sm/gen.h> - -#ifdef _DEFINE -# define EXTERN -# define INIT(x) = x -SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.74 2006/12/19 18:19:52 ca Exp $") -#else /* _DEFINE */ -# define EXTERN extern -# define INIT(x) -#endif /* _DEFINE */ - - -#include "sm/tailq.h" - -#define NOT_SENDMAIL 1 -#define _SOCK_ADDR union bigsockaddr -#include "sendmail.h" - -#ifdef SM_ASSERT -#undef SM_ASSERT -#endif -#ifndef SM_ASSERT -#include <assert.h> -#define SM_ASSERT(x) assert(x) -#endif - -#include "libmilter/milter.h" - -#define MAX_MACROS_ENTRIES 7 /* max size of macro pointer array */ - -typedef SM_TAILQ_HEAD(, smfi_str) smfi_hd_T; -typedef struct smfi_str smfi_str_S; - -/* -** Context for one milter session. -** -** Notes: -** There is a 1-1 correlation between a sendmail SMTP server process, -** an SMTP session, and an milter context. Due to the nature of SMTP -** session handling in sendmail 8, this libmilter implementation deals -** only with a single SMTP session per MTA - libmilter connection. -** -** There is no "global" context for libmilter, global variables are -** just that (they are not "collected" in a context). -** -** Implementation hint: -** macros are stored in mac_buf[] as sequence of: -** macro_name \0 macro_value -** (just as read from the MTA) -** mac_ptr is a list of pointers into mac_buf to the beginning of each -** entry, i.e., macro_name, macro_value, ... -*/ - -struct smfi_str -{ - sthread_t ctx_id; /* thread id */ - socket_t ctx_sd; /* socket descriptor */ - int ctx_dbg; /* debug level */ - time_t ctx_timeout; /* timeout */ - int ctx_state; /* state */ - smfiDesc_ptr ctx_smfi; /* filter description */ - - int ctx_prot_vers; /* libmilter protocol version */ - unsigned long ctx_aflags; /* milter action flags */ - - unsigned long ctx_pflags; /* milter protocol flags */ - - /* - ** milter protocol flags that are sent to the MTA; - ** this is the same as ctx_pflags except for those flags that - ** are not offered by the MTA but emulated in libmilter. - */ - - unsigned long ctx_pflags2mta; - - /* - ** milter protocol version that is sent to the MTA; - ** this is the same as ctx_prot_vers unless the - ** MTA protocol version (ctx_mta_prot_vers) is smaller - ** but still "acceptable". - */ - - int ctx_prot_vers2mta; - - char **ctx_mac_ptr[MAX_MACROS_ENTRIES]; - char *ctx_mac_buf[MAX_MACROS_ENTRIES]; - char *ctx_mac_list[MAX_MACROS_ENTRIES]; - char *ctx_reply; /* reply code */ - void *ctx_privdata; /* private data */ - - int ctx_mta_prot_vers; /* MTA protocol version */ - unsigned long ctx_mta_pflags; /* MTA protocol flags */ - unsigned long ctx_mta_aflags; /* MTA action flags */ - -#if _FFR_THREAD_MONITOR - time_t ctx_start; /* start time of thread */ - SM_TAILQ_ENTRY(smfi_str) ctx_mon_link; -#endif /* _FFR_THREAD_MONITOR */ - -#if _FFR_WORKERS_POOL - long ctx_sid; /* session identifier */ - int ctx_wstate; /* state of the session (worker pool) */ - int ctx_wait; /* elapsed time waiting for sm cmd */ - SM_TAILQ_ENTRY(smfi_str) ctx_link; -#endif /* _FFR_WORKERS_POOL */ -}; - -# define ValidSocket(sd) ((sd) >= 0) -# define INVALID_SOCKET (-1) -# define closesocket close -# define MI_SOCK_READ(s, b, l) read(s, b, l) -# define MI_SOCK_READ_FAIL(x) ((x) < 0) -# 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) - -#if _FFR_WORKERS_POOL -/* SM_CONF_POLL shall be defined with _FFR_WORKERS_POOL */ -# if !SM_CONF_POLL -# define SM_CONF_POLL 1 -# endif /* SM_CONF_POLL */ -#endif /* _FFR_WORKERS_POOL */ - -typedef pthread_cond_t scond_t; -#define scond_init(cp) pthread_cond_init(cp, NULL) -#define scond_destroy(cp) pthread_cond_destroy(cp) -#define scond_wait(cp, mp) pthread_cond_wait(cp, mp) -#define scond_signal(cp) pthread_cond_signal(cp) -#define scond_broadcast(cp) pthread_cond_broadcast(cp) -#define scond_timedwait(cp, mp, to) \ - do \ - { \ - struct timespec timeout; \ - struct timeval now; \ - gettimeofday(&now, NULL); \ - timeout.tv_sec = now.tv_sec + to; \ - timeout.tv_nsec = now.tv_usec / 1000; \ - r = pthread_cond_timedwait(cp,mp,&timeout); \ - if (r != 0 && r != ETIMEDOUT) \ - smi_log(SMI_LOG_ERR, \ - "pthread_cond_timedwait error %d", r); \ - } while (0) - - -#if SM_CONF_POLL - -# include <poll.h> -# define MI_POLLSELECT "poll" - -# define MI_POLL_RD_FLAGS (POLLIN | POLLPRI) -# define MI_POLL_WR_FLAGS (POLLOUT) -# define MI_MS(timeout) (((timeout)->tv_sec * 1000) + (timeout)->tv_usec) - -# define FD_RD_VAR(rds, excs) struct pollfd rds -# define FD_WR_VAR(wrs) struct pollfd wrs - -# define FD_RD_INIT(sd, rds, excs) \ - (rds).fd = (sd); \ - (rds).events = MI_POLL_RD_FLAGS; \ - (rds).revents = 0 - -# define FD_WR_INIT(sd, wrs) \ - (wrs).fd = (sd); \ - (wrs).events = MI_POLL_WR_FLAGS; \ - (wrs).revents = 0 - -# define FD_IS_RD_EXC(sd, rds, excs) \ - (((rds).revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) - -# define FD_IS_WR_RDY(sd, wrs) \ - (((wrs).revents & MI_POLL_WR_FLAGS) != 0) - -# define FD_IS_RD_RDY(sd, rds, excs) \ - (((rds).revents & MI_POLL_RD_FLAGS) != 0) - -# define FD_WR_READY(sd, excs, timeout) \ - poll(&(wrs), 1, MI_MS(timeout)) - -# define FD_RD_READY(sd, rds, excs, timeout) \ - poll(&(rds), 1, MI_MS(timeout)) - -#else /* SM_CONF_POLL */ - -# include <sm/fdset.h> -# define MI_POLLSELECT "select" - -# define FD_RD_VAR(rds, excs) fd_set rds, excs -# define FD_WR_VAR(wrs) fd_set wrs - -# define FD_RD_INIT(sd, rds, excs) \ - FD_ZERO(&(rds)); \ - FD_SET((unsigned int) (sd), &(rds)); \ - FD_ZERO(&(excs)); \ - FD_SET((unsigned int) (sd), &(excs)) - -# define FD_WR_INIT(sd, wrs) \ - FD_ZERO(&(wrs)); \ - FD_SET((unsigned int) (sd), &(wrs)) - -# define FD_IS_RD_EXC(sd, rds, excs) FD_ISSET(sd, &(excs)) -# define FD_IS_WR_RDY(sd, wrs) FD_ISSET((sd), &(wrs)) -# define FD_IS_RD_RDY(sd, rds, excs) FD_ISSET((sd), &(rds)) - -# define FD_WR_READY(sd, wrs, timeout) \ - select((sd) + 1, NULL, &(wrs), NULL, (timeout)) -# define FD_RD_READY(sd, rds, excs, timeout) \ - select((sd) + 1, &(rds), NULL, &(excs), (timeout)) - -#endif /* SM_CONF_POLL */ - -#include <sys/time.h> - -/* some defaults */ -#define MI_TIMEOUT 7210 /* default timeout for read/write */ -#define MI_CHK_TIME 5 /* checking whether to terminate */ - -#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 */ -#define SMFIC_SELECT ((char) 2) /* select error */ -#define SMFIC_MALLOC ((char) 3) /* malloc error */ -#define SMFIC_RECVERR ((char) 4) /* recv() error */ -#define SMFIC_EOF ((char) 5) /* eof */ -#define SMFIC_UNKNERR ((char) 6) /* unknown error */ -#define SMFIC_TOOBIG ((char) 7) /* body chunk too big */ -#define SMFIC_VALIDCMD ' ' /* first valid command */ - -/* hack */ -#define smi_log syslog -#define sm_dprintf (void) printf -#define milter_ret int -#define SMI_LOG_ERR LOG_ERR -#define SMI_LOG_FATAL LOG_ERR -#define SMI_LOG_WARN LOG_WARNING -#define SMI_LOG_INFO LOG_INFO -#define SMI_LOG_DEBUG LOG_DEBUG - -/* stop? */ -#define MILTER_CONT 0 -#define MILTER_STOP 1 -#define MILTER_ABRT 2 - -/* 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, 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 int mi_inet_pton __P((int, const char *, void *)); -extern void mi_closener __P((void)); -extern int mi_opensocket __P((char *, int, int, bool, smfiDesc_ptr)); - -/* communication functions */ -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)); - - -#if _FFR_THREAD_MONITOR -extern bool Monitor; - -#define MI_MONITOR_INIT() mi_monitor_init() -#define MI_MONITOR_BEGIN(ctx, cmd) \ - do \ - { \ - if (Monitor) \ - mi_monitor_work_begin(ctx, cmd);\ - } while (0) - -#define MI_MONITOR_END(ctx, cmd) \ - do \ - { \ - if (Monitor) \ - mi_monitor_work_end(ctx, cmd); \ - } while (0) - -int mi_monitor_init __P((void)); -int mi_monitor_work_begin __P((SMFICTX_PTR, int)); -int mi_monitor_work_end __P((SMFICTX_PTR, int)); - -#else /* _FFR_THREAD_MONITOR */ -#define MI_MONITOR_INIT() MI_SUCCESS -#define MI_MONITOR_BEGIN(ctx, cmd) -#define MI_MONITOR_END(ctx, cmd) -#endif /* _FFR_THREAD_MONITOR */ - -#if _FFR_WORKERS_POOL -extern int mi_pool_manager_init __P((void)); -extern int mi_pool_controller_init __P((void)); -extern int mi_start_session __P((SMFICTX_PTR)); -#endif /* _FFR_WORKERS_POOL */ - -#endif /* ! _LIBMILTER_H */ diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c deleted file mode 100644 index 6e68ae5..0000000 --- a/contrib/sendmail/libmilter/listener.c +++ /dev/null @@ -1,973 +0,0 @@ -/* - * Copyright (c) 1999-2007 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: listener.c,v 8.124 2007/04/23 22:22:50 ca Exp $") - -/* -** listener.c -- threaded network listener -*/ - -#include "libmilter.h" -#include <sm/errstring.h> - -#include <sys/types.h> -#include <sys/stat.h> - - -# if NETINET || NETINET6 -# include <arpa/inet.h> -# endif /* NETINET || NETINET6 */ -# if SM_CONF_POLL -# undef SM_FD_OK_SELECT -# define SM_FD_OK_SELECT(fd) true -# endif /* SM_CONF_POLL */ - -static smutex_t L_Mutex; -static int L_family; -static SOCKADDR_LEN_T L_socksize; -static socket_t listenfd = INVALID_SOCKET; - -static socket_t mi_milteropen __P((char *, int, bool, char *)); -#if !_FFR_WORKERS_POOL -static void *mi_thread_handle_wrapper __P((void *)); -#endif /* !_FFR_WORKERS_POOL */ - -/* -** MI_OPENSOCKET -- create the socket where this filter and the MTA will meet -** -** Parameters: -** conn -- connection description -** backlog -- listen backlog -** dbg -- debug level -** rmsocket -- if true, try to unlink() the socket first -** (UNIX domain sockets only) -** smfi -- filter structure to use -** -** Return value: -** MI_SUCCESS/MI_FAILURE -*/ - -int -mi_opensocket(conn, backlog, dbg, rmsocket, smfi) - char *conn; - int backlog; - int dbg; - bool rmsocket; - smfiDesc_ptr smfi; -{ - if (smfi == NULL || conn == NULL) - return MI_FAILURE; - - if (ValidSocket(listenfd)) - return MI_SUCCESS; - - if (dbg > 0) - { - smi_log(SMI_LOG_DEBUG, - "%s: Opening listen socket on conn %s", - smfi->xxfi_name, conn); - } - (void) smutex_init(&L_Mutex); - (void) smutex_lock(&L_Mutex); - listenfd = mi_milteropen(conn, backlog, rmsocket, 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; - } - if (!SM_FD_OK_SELECT(listenfd)) - { - 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); - return MI_SUCCESS; -} - -/* -** MI_MILTEROPEN -- setup socket to listen on -** -** Parameters: -** conn -- connection description -** backlog -- listen backlog -** rmsocket -- if true, try to unlink() the socket first -** (UNIX domain sockets only) -** name -- name for logging -** -** 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, rmsocket, name) - char *conn; - int backlog; - bool rmsocket; - char *name; -{ - socket_t sock; - int sockopt = 1; - int fdflags; - size_t len = 0; - char *p; - char *colon; - char *at; - SOCKADDR addr; - - if (conn == NULL || conn[0] == '\0') - { - smi_log(SMI_LOG_ERR, "%s: empty or missing socket information", - name); - return INVALID_SOCKET; - } - (void) memset(&addr, '\0', sizeof addr); - - /* protocol:filename or protocol:port@host */ - p = conn; - colon = strchr(p, ':'); - if (colon != NULL) - { - *colon = '\0'; - - if (*p == '\0') - { -#if NETUNIX - /* default to AF_UNIX */ - addr.sa.sa_family = AF_UNIX; - L_socksize = sizeof (struct sockaddr_un); -#else /* NETUNIX */ -# if NETINET - /* default to AF_INET */ - addr.sa.sa_family = AF_INET; - L_socksize = sizeof addr.sin; -# else /* NETINET */ -# if NETINET6 - /* default to AF_INET6 */ - addr.sa.sa_family = AF_INET6; - L_socksize = sizeof addr.sin6; -# else /* NETINET6 */ - /* no protocols available */ - smi_log(SMI_LOG_ERR, - "%s: no valid socket protocols available", - name); - return INVALID_SOCKET; -# endif /* NETINET6 */ -# endif /* NETINET */ -#endif /* NETUNIX */ - } -#if NETUNIX - else if (strcasecmp(p, "unix") == 0 || - strcasecmp(p, "local") == 0) - { - addr.sa.sa_family = AF_UNIX; - L_socksize = sizeof (struct sockaddr_un); - } -#endif /* NETUNIX */ -#if NETINET - else if (strcasecmp(p, "inet") == 0) - { - addr.sa.sa_family = AF_INET; - L_socksize = sizeof addr.sin; - } -#endif /* NETINET */ -#if NETINET6 - else if (strcasecmp(p, "inet6") == 0) - { - addr.sa.sa_family = AF_INET6; - L_socksize = sizeof addr.sin6; - } -#endif /* NETINET6 */ - else - { - smi_log(SMI_LOG_ERR, "%s: unknown socket type %s", - name, p); - return INVALID_SOCKET; - } - *colon++ = ':'; - } - else - { - colon = p; -#if NETUNIX - /* default to AF_UNIX */ - addr.sa.sa_family = AF_UNIX; - L_socksize = sizeof (struct sockaddr_un); -#else /* NETUNIX */ -# if NETINET - /* default to AF_INET */ - addr.sa.sa_family = AF_INET; - L_socksize = sizeof addr.sin; -# else /* NETINET */ -# if NETINET6 - /* default to AF_INET6 */ - addr.sa.sa_family = AF_INET6; - L_socksize = sizeof addr.sin6; -# else /* NETINET6 */ - smi_log(SMI_LOG_ERR, "%s: unknown socket type %s", - name, p); - return INVALID_SOCKET; -# endif /* NETINET6 */ -# endif /* NETINET */ -#endif /* NETUNIX */ - } - -#if NETUNIX - if (addr.sa.sa_family == AF_UNIX) - { -# if 0 - long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_CREAT|SFF_MUSTOWN; -# endif /* 0 */ - - at = colon; - 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); - - /* if not safe, don't create */ - if (errno != 0) - { - smi_log(SMI_LOG_ERR, - "%s: UNIX socket name %s unsafe", - name, colon); - return INVALID_SOCKET; - } -# endif /* 0 */ - } -#endif /* NETUNIX */ - -#if NETINET || NETINET6 - if ( -# if NETINET - addr.sa.sa_family == AF_INET -# endif /* NETINET */ -# if NETINET && NETINET6 - || -# endif /* NETINET && NETINET6 */ -# if NETINET6 - addr.sa.sa_family == AF_INET6 -# endif /* NETINET6 */ - ) - { - unsigned short port; - - /* Parse port@host */ - at = strchr(colon, '@'); - if (at == NULL) - { - switch (addr.sa.sa_family) - { -# if NETINET - case AF_INET: - addr.sin.sin_addr.s_addr = INADDR_ANY; - break; -# endif /* NETINET */ - -# if NETINET6 - case AF_INET6: - addr.sin6.sin6_addr = in6addr_any; - break; -# endif /* NETINET6 */ - } - } - else - *at = '\0'; - - if (isascii(*colon) && isdigit(*colon)) - port = htons((unsigned short) atoi(colon)); - else - { -# ifdef NO_GETSERVBYNAME - smi_log(SMI_LOG_ERR, "%s: invalid port number %s", - name, colon); - return INVALID_SOCKET; -# else /* NO_GETSERVBYNAME */ - register struct servent *sp; - - sp = getservbyname(colon, "tcp"); - if (sp == NULL) - { - smi_log(SMI_LOG_ERR, - "%s: unknown port name %s", - name, colon); - return INVALID_SOCKET; - } - port = sp->s_port; -# endif /* NO_GETSERVBYNAME */ - } - if (at != NULL) - { - *at++ = '@'; - if (*at == '[') - { - char *end; - - end = strchr(at, ']'); - if (end != NULL) - { - bool found = false; -# if NETINET - unsigned long hid = INADDR_NONE; -# endif /* NETINET */ -# if NETINET6 - struct sockaddr_in6 hid6; -# endif /* NETINET6 */ - - *end = '\0'; -# if NETINET - if (addr.sa.sa_family == AF_INET && - (hid = inet_addr(&at[1])) != INADDR_NONE) - { - addr.sin.sin_addr.s_addr = hid; - addr.sin.sin_port = port; - found = true; - } -# endif /* NETINET */ -# if NETINET6 - (void) memset(&hid6, '\0', sizeof hid6); - if (addr.sa.sa_family == AF_INET6 && - 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; - } -# endif /* NETINET6 */ - *end = ']'; - if (!found) - { - smi_log(SMI_LOG_ERR, - "%s: Invalid numeric domain spec \"%s\"", - name, at); - return INVALID_SOCKET; - } - } - else - { - smi_log(SMI_LOG_ERR, - "%s: Invalid numeric domain spec \"%s\"", - name, at); - 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 INVALID_SOCKET; - } - addr.sa.sa_family = hp->h_addrtype; - switch (hp->h_addrtype) - { -# if NETINET - case AF_INET: - (void) memmove(&addr.sin.sin_addr, - hp->h_addr, - INADDRSZ); - addr.sin.sin_port = port; - break; -# endif /* NETINET */ - -# if NETINET6 - case AF_INET6: - (void) memmove(&addr.sin6.sin6_addr, - hp->h_addr, - IN6ADDRSZ); - addr.sin6.sin6_port = port; - break; -# endif /* NETINET6 */ - - default: - smi_log(SMI_LOG_ERR, - "%s: Unknown protocol for %s (%d)", - name, at, hp->h_addrtype); - return INVALID_SOCKET; - } -# if NETINET6 - freehostent(hp); -# endif /* NETINET6 */ - } - } - else - { - switch (addr.sa.sa_family) - { -# if NETINET - case AF_INET: - addr.sin.sin_port = port; - break; -# endif /* NETINET */ -# if NETINET6 - case AF_INET6: - addr.sin6.sin6_port = port; - break; -# endif /* NETINET6 */ - } - } - } -#endif /* NETINET || NETINET6 */ - - sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); - if (!ValidSocket(sock)) - { - smi_log(SMI_LOG_ERR, - "%s: Unable to create new socket: %s", - name, sm_errstring(errno)); - return INVALID_SOCKET; - } - - if ((fdflags = fcntl(sock, F_GETFD, 0)) == -1 || - fcntl(sock, F_SETFD, fdflags | FD_CLOEXEC) == -1) - { - smi_log(SMI_LOG_ERR, - "%s: Unable to set close-on-exec: %s", name, - sm_errstring(errno)); - (void) closesocket(sock); - return INVALID_SOCKET; - } - - if ( -#if NETUNIX - addr.sa.sa_family != AF_UNIX && -#endif /* NETUNIX */ - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt, - sizeof(sockopt)) == -1) - { - smi_log(SMI_LOG_ERR, - "%s: set reuseaddr failed (%s)", name, - sm_errstring(errno)); - (void) closesocket(sock); - return INVALID_SOCKET; - } - -#if NETUNIX - if (addr.sa.sa_family == AF_UNIX && rmsocket) - { - struct stat s; - - if (stat(colon, &s) != 0) - { - if (errno != ENOENT) - { - smi_log(SMI_LOG_ERR, - "%s: Unable to stat() %s: %s", - name, colon, sm_errstring(errno)); - (void) closesocket(sock); - return INVALID_SOCKET; - } - } - else if (!S_ISSOCK(s.st_mode)) - { - smi_log(SMI_LOG_ERR, - "%s: %s is not a UNIX domain socket", - name, colon); - (void) closesocket(sock); - return INVALID_SOCKET; - } - else if (unlink(colon) != 0) - { - smi_log(SMI_LOG_ERR, - "%s: Unable to remove %s: %s", - name, colon, sm_errstring(errno)); - (void) closesocket(sock); - return INVALID_SOCKET; - } - } -#endif /* NETUNIX */ - - if (bind(sock, &addr.sa, L_socksize) < 0) - { - smi_log(SMI_LOG_ERR, - "%s: Unable to bind to port %s: %s", - name, conn, sm_errstring(errno)); - (void) closesocket(sock); - return INVALID_SOCKET; - } - - if (listen(sock, backlog) < 0) - { - smi_log(SMI_LOG_ERR, - "%s: listen call failed: %s", name, - sm_errstring(errno)); - (void) closesocket(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, (int) len, sm_errstring(errno)); - (void) closesocket(sock); - return INVALID_SOCKET; - } - } -#endif /* NETUNIX */ - L_family = addr.sa.sa_family; - return sock; -} - -#if !_FFR_WORKERS_POOL -/* -** MI_THREAD_HANDLE_WRAPPER -- small wrapper to handle session -** -** Parameters: -** arg -- argument to pass to mi_handle_session() -** -** Returns: -** results from mi_handle_session() -*/ - -static void * -mi_thread_handle_wrapper(arg) - void *arg; -{ - /* - ** Note: on some systems this generates a compiler warning: - ** cast to pointer from integer of different size - ** You can safely ignore this warning as the result of this function - ** is not used anywhere. - */ - - return (void *) mi_handle_session(arg); -} -#endif /* _FFR_WORKERS_POOL */ - -/* -** MI_CLOSENER -- close listen socket -** -** Parameters: -** none. -** -** Returns: -** none. -*/ - -void -mi_closener() -{ - (void) smutex_lock(&L_Mutex); - if (ValidSocket(listenfd)) - { -#if NETUNIX - bool removable; - struct stat sockinfo; - struct stat fileinfo; - - removable = sockpath != NULL && - geteuid() != 0 && - fstat(listenfd, &sockinfo) == 0 && - (S_ISFIFO(sockinfo.st_mode) -# ifdef S_ISSOCK - || S_ISSOCK(sockinfo.st_mode) -# endif /* S_ISSOCK */ - ); -#endif /* NETUNIX */ - - (void) closesocket(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) -# ifdef S_ISSOCK - || S_ISSOCK(fileinfo.st_mode) -# endif /* S_ISSOCK */ - ) - && - (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); -} - -/* -** MI_LISTENER -- Generic listener harness -** -** Open up listen port -** Wait for connections -** -** Parameters: -** conn -- connection description -** dbg -- debug level -** smfi -- filter structure to use -** timeout -- timeout for reads/writes -** backlog -- listen queue backlog size -** -** Returns: -** MI_SUCCESS -- Exited normally -** (session finished or we were told to exit) -** MI_FAILURE -- Network initialization failed. -*/ - -#if BROKEN_PTHREAD_SLEEP - -/* -** Solaris 2.6, perhaps others, gets an internal threads library panic -** when sleep() is used: -** -** thread_create() failed, returned 11 (EINVAL) -** co_enable, thr_create() returned error = 24 -** libthread panic: co_enable failed (PID: 17793 LWP 1) -** stacktrace: -** ef526b10 -** ef52646c -** ef534cbc -** 156a4 -** 14644 -** 1413c -** 135e0 -** 0 -*/ - -# define MI_SLEEP(s) \ -{ \ - int rs = 0; \ - struct timeval st; \ - \ - st.tv_sec = (s); \ - st.tv_usec = 0; \ - if (st.tv_sec > 0) \ - { \ - for (;;) \ - { \ - rs = select(0, NULL, NULL, NULL, &st); \ - if (rs < 0 && errno == EINTR) \ - continue; \ - if (rs != 0) \ - { \ - smi_log(SMI_LOG_ERR, \ - "MI_SLEEP(): select() returned non-zero result %d, errno = %d", \ - rs, errno); \ - } \ - break; \ - } \ - } \ -} -#else /* BROKEN_PTHREAD_SLEEP */ -# define MI_SLEEP(s) sleep((s)) -#endif /* BROKEN_PTHREAD_SLEEP */ - -int -mi_listener(conn, dbg, smfi, timeout, backlog) - char *conn; - int dbg; - smfiDesc_ptr smfi; - time_t timeout; - int backlog; -{ - socket_t connfd = INVALID_SOCKET; -#if _FFR_DUP_FD - socket_t dupfd = INVALID_SOCKET; -#endif /* _FFR_DUP_FD */ - int sockopt = 1; - int r, mistop; - int ret = MI_SUCCESS; - 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; -#if !_FFR_WORKERS_POOL - sthread_t thread_id; -#endif /* !_FFR_WORKERS_POOL */ - _SOCK_ADDR cliaddr; - SOCKADDR_LEN_T clilen; - SMFICTX_PTR ctx; - FD_RD_VAR(rds, excs); - struct timeval chktime; - - if (mi_opensocket(conn, backlog, dbg, false, smfi) == MI_FAILURE) - return MI_FAILURE; - -#if _FFR_WORKERS_POOL - if (mi_pool_controller_init() == MI_FAILURE) - return MI_FAILURE; -#endif /* _FFR_WORKERS_POOL */ - - clilen = L_socksize; - while ((mistop = mi_stop()) == MILTER_CONT) - { - (void) smutex_lock(&L_Mutex); - if (!ValidSocket(listenfd)) - { - ret = MI_FAILURE; - smi_log(SMI_LOG_ERR, - "%s: listenfd=%d corrupted, terminating, errno=%d", - smfi->xxfi_name, listenfd, errno); - (void) smutex_unlock(&L_Mutex); - break; - } - - /* select on interface ports */ - FD_RD_INIT(listenfd, rds, excs); - chktime.tv_sec = MI_CHK_TIME; - chktime.tv_usec = 0; - r = FD_RD_READY(listenfd, rds, excs, &chktime); - if (r == 0) /* timeout */ - { - (void) smutex_unlock(&L_Mutex); - continue; /* just check mi_stop() */ - } - if (r < 0) - { - save_errno = errno; - (void) smutex_unlock(&L_Mutex); - if (save_errno == EINTR) - continue; - 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_IS_RD_RDY(listenfd, rds, excs)) - { - /* some error: just stop for now... */ - ret = MI_FAILURE; - (void) smutex_unlock(&L_Mutex); - smi_log(SMI_LOG_ERR, - "%s: %s() returned exception for socket, abort", - smfi->xxfi_name, MI_POLLSELECT); - break; - } - scnt = 0; /* reset error counter for select() */ - - (void) memset(&cliaddr, '\0', sizeof cliaddr); - connfd = accept(listenfd, (struct sockaddr *) &cliaddr, - &clilen); - save_errno = errno; - (void) smutex_unlock(&L_Mutex); - - /* - ** If remote side closes before accept() finishes, - ** sockaddr might not be fully filled in. - */ - - if (ValidSocket(connfd) && - (clilen == 0 || -# ifdef BSD4_4_SOCKADDR - cliaddr.sa.sa_len == 0 || -# endif /* BSD4_4_SOCKADDR */ - cliaddr.sa.sa_family != L_family)) - { - (void) closesocket(connfd); - connfd = INVALID_SOCKET; - save_errno = EINVAL; - } - - /* check if acceptable for select() */ - if (ValidSocket(connfd) && !SM_FD_OK_SELECT(connfd)) - { - (void) closesocket(connfd); - connfd = INVALID_SOCKET; - save_errno = ERANGE; - } - - if (!ValidSocket(connfd)) - { - if (save_errno == EINTR -#ifdef EAGAIN - || save_errno == EAGAIN -#endif /* EAGAIN */ -#ifdef ECONNABORTED - || save_errno == ECONNABORTED -#endif /* ECONNABORTED */ -#ifdef EMFILE - || save_errno == EMFILE -#endif /* EMFILE */ -#ifdef ENFILE - || save_errno == ENFILE -#endif /* ENFILE */ -#ifdef ENOBUFS - || save_errno == ENOBUFS -#endif /* ENOBUFS */ -#ifdef ENOMEM - || save_errno == ENOMEM -#endif /* ENOMEM */ -#ifdef ENOSR - || save_errno == ENOSR -#endif /* ENOSR */ -#ifdef EWOULDBLOCK - || save_errno == EWOULDBLOCK -#endif /* EWOULDBLOCK */ - ) - 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) - { - ret = MI_FAILURE; - break; - } - continue; - } - acnt = 0; /* reset error counter for accept() */ -#if _FFR_DUP_FD - dupfd = fcntl(connfd, F_DUPFD, 256); - if (ValidSocket(dupfd) && SM_FD_OK_SELECT(dupfd)) - { - close(connfd); - connfd = dupfd; - dupfd = INVALID_SOCKET; - } -#endif /* _FFR_DUP_FD */ - - if (setsockopt(connfd, SOL_SOCKET, SO_KEEPALIVE, - (void *) &sockopt, sizeof sockopt) < 0) - { - smi_log(SMI_LOG_WARN, - "%s: set keepalive failed (%s)", - smfi->xxfi_name, sm_errstring(errno)); - /* XXX: continue? */ - } - if ((ctx = (SMFICTX_PTR) malloc(sizeof *ctx)) == NULL) - { - (void) closesocket(connfd); - 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) - { - ret = MI_FAILURE; - break; - } - continue; - } - mcnt = 0; /* reset error counter for malloc() */ - (void) memset(ctx, '\0', sizeof *ctx); - ctx->ctx_sd = connfd; - ctx->ctx_dbg = dbg; - ctx->ctx_timeout = timeout; - ctx->ctx_smfi = smfi; - if (smfi->xxfi_connect == NULL) - ctx->ctx_pflags |= SMFIP_NOCONNECT; - if (smfi->xxfi_helo == NULL) - ctx->ctx_pflags |= SMFIP_NOHELO; - if (smfi->xxfi_envfrom == NULL) - ctx->ctx_pflags |= SMFIP_NOMAIL; - if (smfi->xxfi_envrcpt == NULL) - ctx->ctx_pflags |= SMFIP_NORCPT; - if (smfi->xxfi_header == NULL) - ctx->ctx_pflags |= SMFIP_NOHDRS; - if (smfi->xxfi_eoh == NULL) - ctx->ctx_pflags |= SMFIP_NOEOH; - if (smfi->xxfi_body == NULL) - ctx->ctx_pflags |= SMFIP_NOBODY; - if (smfi->xxfi_version <= 3 || smfi->xxfi_data == NULL) - ctx->ctx_pflags |= SMFIP_NODATA; - if (smfi->xxfi_version <= 2 || smfi->xxfi_unknown == NULL) - ctx->ctx_pflags |= SMFIP_NOUNKNOWN; - -#if _FFR_WORKERS_POOL -# define LOG_CRT_FAIL "%s: mi_start_session() failed: %d, %s" - if ((r = mi_start_session(ctx)) != MI_SUCCESS) -#else /* _FFR_WORKERS_POOL */ -# define LOG_CRT_FAIL "%s: thread_create() failed: %d, %s" - if ((r = thread_create(&thread_id, - mi_thread_handle_wrapper, - (void *) ctx)) != 0) -#endif /* _FFR_WORKERS_POOL */ - { - tcnt++; - smi_log(SMI_LOG_ERR, - LOG_CRT_FAIL, - smfi->xxfi_name, r, - tcnt >= MAX_FAILS_T ? "abort" : "try again"); - MI_SLEEP(tcnt); - (void) closesocket(connfd); - free(ctx); - if (tcnt >= MAX_FAILS_T) - { - ret = MI_FAILURE; - break; - } - continue; - } - tcnt = 0; - } - if (ret != MI_SUCCESS) - mi_stop_milters(MILTER_ABRT); - else - { - if (mistop != MILTER_CONT) - smi_log(SMI_LOG_INFO, "%s: mi_stop=%d", - smfi->xxfi_name, mistop); - mi_closener(); - } - (void) smutex_destroy(&L_Mutex); - return ret; -} diff --git a/contrib/sendmail/libmilter/main.c b/contrib/sendmail/libmilter/main.c deleted file mode 100644 index faff4f8..0000000 --- a/contrib/sendmail/libmilter/main.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 1999-2003, 2006, 2007 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: main.c,v 8.83 2007/04/23 22:22:50 ca Exp $") - -#define _DEFINE 1 -#include "libmilter.h" -#include <fcntl.h> -#include <sys/stat.h> - - -static smfiDesc_ptr smfi = NULL; - -/* -** SMFI_REGISTER -- register a filter description -** -** Parameters: -** smfilter -- description of filter to register -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_register(smfilter) - smfiDesc_str smfilter; -{ - size_t len; - - if (smfi == NULL) - { - smfi = (smfiDesc_ptr) malloc(sizeof *smfi); - if (smfi == NULL) - return MI_FAILURE; - } - (void) memcpy(smfi, &smfilter, sizeof *smfi); - if (smfilter.xxfi_name == NULL) - smfilter.xxfi_name = "Unknown"; - - len = strlen(smfilter.xxfi_name) + 1; - smfi->xxfi_name = (char *) malloc(len); - if (smfi->xxfi_name == NULL) - return MI_FAILURE; - (void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len); - - /* compare milter version with hard coded version */ - if (smfi->xxfi_version != SMFI_VERSION && - smfi->xxfi_version != 2 && - smfi->xxfi_version != 3 && - smfi->xxfi_version != 4) - { - /* 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); - - /* XXX how about smfi? */ - free(smfi->xxfi_name); - 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; -} - -/* -** 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_OPENSOCKET -- try the socket setup to make sure we'll be -** able to start up -** -** Parameters: -** rmsocket -- if true, instructs libmilter to attempt -** to remove the socket before creating it; -** only applies for "local:" or "unix:" sockets -** -** Return: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_opensocket(rmsocket) - bool rmsocket; -{ - if (smfi == NULL || conn == NULL) - return MI_FAILURE; - - return mi_opensocket(conn, backlog, dbg, rmsocket, smfi); -} - -/* -** SMFI_SETDBG -- set debug level. -** -** Parameters: -** odbg -- new debug level. -** -** Returns: -** MI_SUCCESS -*/ - -int -smfi_setdbg(odbg) - int odbg; -{ - dbg = odbg; - return MI_SUCCESS; -} - -/* -** SMFI_SETTIMEOUT -- set timeout (for read/write). -** -** Parameters: -** otimeout -- new timeout. -** -** Returns: -** MI_SUCCESS -*/ - -int -smfi_settimeout(otimeout) - int otimeout; -{ - timeout = 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; -{ - size_t l; - - if (oconn == NULL || *oconn == '\0') - return MI_FAILURE; - l = strlen(oconn) + 1; - if ((conn = (char *) malloc(l)) == NULL) - return MI_FAILURE; - if (sm_strlcpy(conn, oconn, l) >= l) - return MI_FAILURE; - return MI_SUCCESS; -} - -/* -** SMFI_SETBACKLOG -- set backlog -** -** Parameters: -** obacklog -- new backlog. -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_setbacklog(obacklog) - int obacklog; -{ - if (obacklog <= 0) - return MI_FAILURE; - backlog = obacklog; - return MI_SUCCESS; -} - - -/* -** SMFI_MAIN -- setup milter connnection and start listener. -** -** Parameters: -** none. -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_main() -{ - int r; - - (void) signal(SIGPIPE, SIG_IGN); - if (conn == NULL) - { - smi_log(SMI_LOG_FATAL, "%s: missing connection information", - smfi->xxfi_name); - return MI_FAILURE; - } - - (void) atexit(mi_clean_signals); - if (mi_control_startup(smfi->xxfi_name) != MI_SUCCESS) - { - smi_log(SMI_LOG_FATAL, - "%s: Couldn't start signal thread", - smfi->xxfi_name); - return MI_FAILURE; - } - r = MI_MONITOR_INIT(); - - /* Startup the listener */ - if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS) - r = MI_FAILURE; - - return r; -} - diff --git a/contrib/sendmail/libmilter/monitor.c b/contrib/sendmail/libmilter/monitor.c deleted file mode 100644 index 366cf75..0000000 --- a/contrib/sendmail/libmilter/monitor.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2006 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: monitor.c,v 8.7 2007/04/23 16:26:28 ca Exp $") -#include "libmilter.h" - -#if _FFR_THREAD_MONITOR - -/* -** Thread Monitoring -** Todo: more error checking (return code from function calls) -** add comments. -*/ - -bool Monitor = false; /* use monitoring? */ -static unsigned int Mon_exec_time = 0; - -/* mutex protects Mon_cur_ctx, Mon_ctx_head, and ctx_start */ -static smutex_t Mon_mutex; -static scond_t Mon_cv; - -/* -** Current ctx to monitor. -** Invariant: -** Mon_cur_ctx == NULL || Mon_cur_ctx is thread which was started the longest -** time ago. -** -** Basically the entries in the list are ordered by time because new -** entries are appended at the end. However, due to the concurrent -** execution (multi-threaded) and no guaranteed order of wakeups -** after a mutex_lock() attempt, the order might not be strict, -** i.e., if the list contains e1 and e2 (in that order) then -** the the start time of e2 can be (slightly) smaller than that of e1. -** However, this slight inaccurracy should not matter for the proper -** working of this algorithm. -*/ - -static SMFICTX_PTR Mon_cur_ctx = NULL; -static smfi_hd_T Mon_ctx_head; /* head of the linked list of active contexts */ - -/* -** SMFI_SET_MAX_EXEC_TIME -- set maximum execution time for a thread -** -** Parameters: -** tm -- maximum execution time for a thread -** -** Returns: -** MI_SUCCESS -*/ - -int -smfi_set_max_exec_time(tm) - unsigned int tm; -{ - Mon_exec_time = tm; - return MI_SUCCESS; -} - -/* -** MI_MONITOR_THREAD -- monitoring thread -** -** Parameters: -** arg -- ignored (required by pthread_create()) -** -** Returns: -** NULL on termination. -*/ - -static void * -mi_monitor_thread(arg) - void *arg; -{ - sthread_t tid; - int r; - time_t now, end; - - SM_ASSERT(Monitor); - SM_ASSERT(Mon_exec_time > 0); - tid = (sthread_t) sthread_get_id(); - if (pthread_detach(tid) != 0) - { - /* log an error */ - return (void *)1; - } - -/* -** NOTE: this is "flow through" code, -** do NOT use do { } while ("break" is used here!) -*/ - -#define MON_CHK_STOP \ - now = time(NULL); \ - end = Mon_cur_ctx->ctx_start + Mon_exec_time; \ - if (now > end) \ - { \ - smi_log(SMI_LOG_ERR, \ - "WARNING: monitor timeout triggered, now=%ld, end=%ld, tid=%ld, state=0x%x",\ - (long) now, (long) end, \ - (long) Mon_cur_ctx->ctx_id, Mon_cur_ctx->ctx_state);\ - mi_stop_milters(MILTER_STOP); \ - break; \ - } - - (void) smutex_lock(&Mon_mutex); - while (mi_stop() == MILTER_CONT) - { - if (Mon_cur_ctx != NULL && Mon_cur_ctx->ctx_start > 0) - { - struct timespec abstime; - - MON_CHK_STOP; - abstime.tv_sec = end; - abstime.tv_nsec = 0; - r = pthread_cond_timedwait(&Mon_cv, &Mon_mutex, - &abstime); - } - else - r = pthread_cond_wait(&Mon_cv, &Mon_mutex); - if (mi_stop() != MILTER_CONT) - break; - if (Mon_cur_ctx != NULL && Mon_cur_ctx->ctx_start > 0) - { - MON_CHK_STOP; - } - } - (void) smutex_unlock(&Mon_mutex); - - return NULL; -} - -/* -** MI_MONITOR_INIT -- initialize monitoring thread -** -** Parameters: none -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -mi_monitor_init() -{ - int r; - sthread_t tid; - - SM_ASSERT(!Monitor); - if (Mon_exec_time <= 0) - return MI_SUCCESS; - Monitor = true; - if (!smutex_init(&Mon_mutex)) - return MI_FAILURE; - if (scond_init(&Mon_cv) != 0) - return MI_FAILURE; - SM_TAILQ_INIT(&Mon_ctx_head); - - r = thread_create(&tid, mi_monitor_thread, (void *)NULL); - if (r != 0) - return r; - return MI_SUCCESS; -} - -/* -** MI_MONITOR_WORK_BEGIN -- record start of thread execution -** -** Parameters: -** ctx -- session context -** cmd -- milter command char -** -** Returns: -** 0 -*/ - -int -mi_monitor_work_begin(ctx, cmd) - SMFICTX_PTR ctx; - int cmd; -{ - (void) smutex_lock(&Mon_mutex); - if (NULL == Mon_cur_ctx) - { - Mon_cur_ctx = ctx; - (void) scond_signal(&Mon_cv); - } - ctx->ctx_start = time(NULL); - SM_TAILQ_INSERT_TAIL(&Mon_ctx_head, ctx, ctx_mon_link); - (void) smutex_unlock(&Mon_mutex); - return 0; -} - -/* -** MI_MONITOR_WORK_END -- record end of thread execution -** -** Parameters: -** ctx -- session context -** cmd -- milter command char -** -** Returns: -** 0 -*/ - -int -mi_monitor_work_end(ctx, cmd) - SMFICTX_PTR ctx; - int cmd; -{ - (void) smutex_lock(&Mon_mutex); - ctx->ctx_start = 0; - SM_TAILQ_REMOVE(&Mon_ctx_head, ctx, ctx_mon_link); - if (Mon_cur_ctx == ctx) - { - if (SM_TAILQ_EMPTY(&Mon_ctx_head)) - Mon_cur_ctx = NULL; - else - Mon_cur_ctx = SM_TAILQ_FIRST(&Mon_ctx_head); - } - (void) smutex_unlock(&Mon_mutex); - return 0; -} -#endif /* _FFR_THREAD_MONITOR */ diff --git a/contrib/sendmail/libmilter/signal.c b/contrib/sendmail/libmilter/signal.c deleted file mode 100644 index ad68469..0000000 --- a/contrib/sendmail/libmilter/signal.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 1999-2004, 2006 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: signal.c,v 8.44 2006/03/03 03:42:04 ca Exp $") - -#include "libmilter.h" - -/* -** thread to handle signals -*/ - -static smutex_t M_Mutex; - -static int MilterStop = MILTER_CONT; - -static void *mi_signal_thread __P((void *)); -static int mi_spawn_signal_thread __P((char *)); - -/* -** MI_STOP -- return value of MilterStop -** -** Parameters: -** none. -** -** Returns: -** value of MilterStop -*/ - -int -mi_stop() -{ - return MilterStop; -} -/* -** MI_STOP_MILTERS -- set value of MilterStop -** -** Parameters: -** v -- new value for MilterStop. -** -** Returns: -** none. -*/ - -void -mi_stop_milters(v) - int 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: -** none. -** -** Returns: -** none. -*/ - -void -mi_clean_signals() -{ - (void) smutex_destroy(&M_Mutex); -} -/* -** MI_SIGNAL_THREAD -- thread to deal with signals -** -** Parameters: -** name -- name of milter -** -** Returns: -** NULL -*/ - -static void * -mi_signal_thread(name) - void *name; -{ - int sig, errs, sigerr; - sigset_t set; - - (void) sigemptyset(&set); - (void) sigaddset(&set, SIGHUP); - (void) sigaddset(&set, SIGTERM); - - /* Handle Ctrl-C gracefully for debugging */ - (void) sigaddset(&set, SIGINT); - errs = 0; - - for (;;) - { - sigerr = sig = 0; -#if defined(SOLARIS) || defined(__svr5__) - if ((sig = sigwait(&set)) < 0) -#else /* defined(SOLARIS) || defined(__svr5__) */ - if ((sigerr = sigwait(&set, &sig)) != 0) -#endif /* defined(SOLARIS) || defined(__svr5__) */ - { - /* some OS return -1 and set errno: copy it */ - if (sigerr <= 0) - sigerr = errno; - - /* this can happen on OSF/1 (at least) */ - if (sigerr == EINTR) - continue; - smi_log(SMI_LOG_ERR, - "%s: sigwait returned error: %d", - (char *)name, sigerr); - if (++errs > MAX_FAILS_T) - { - mi_stop_milters(MILTER_ABRT); - return NULL; - } - continue; - } - errs = 0; - - switch (sig) - { - case SIGHUP: - case SIGTERM: - mi_stop_milters(MILTER_STOP); - return NULL; - case SIGINT: - mi_stop_milters(MILTER_ABRT); - return NULL; - default: - smi_log(SMI_LOG_ERR, - "%s: sigwait returned unmasked signal: %d", - (char *)name, sig); - break; - } - } - /* NOTREACHED */ -} -/* -** MI_SPAWN_SIGNAL_THREAD -- spawn thread to handle signals -** -** Parameters: -** name -- name of milter -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -static int -mi_spawn_signal_thread(name) - char *name; -{ - sthread_t tid; - int r; - sigset_t set; - - /* Mask HUP and KILL signals */ - (void) sigemptyset(&set); - (void) sigaddset(&set, SIGHUP); - (void) sigaddset(&set, SIGTERM); - (void) sigaddset(&set, SIGINT); - - if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) - { - smi_log(SMI_LOG_ERR, - "%s: Couldn't mask HUP and KILL signals", name); - return MI_FAILURE; - } - r = thread_create(&tid, mi_signal_thread, (void *)name); - if (r != 0) - { - smi_log(SMI_LOG_ERR, - "%s: Couldn't start signal thread: %d", - name, r); - return MI_FAILURE; - } - return MI_SUCCESS; -} -/* -** MI_CONTROL_STARTUP -- startup for thread to handle signals -** -** Parameters: -** name -- name of milter -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -mi_control_startup(name) - char *name; -{ - - if (!smutex_init(&M_Mutex)) - { - smi_log(SMI_LOG_ERR, - "%s: Couldn't initialize control pipe mutex", name); - return MI_FAILURE; - } - - /* - ** spawn_signal_thread must happen before other threads are spawned - ** off so that it can mask the right signals and other threads - ** will inherit that mask. - */ - if (mi_spawn_signal_thread(name) == MI_FAILURE) - { - smi_log(SMI_LOG_ERR, - "%s: Couldn't spawn signal thread", name); - (void) smutex_destroy(&M_Mutex); - return MI_FAILURE; - } - return MI_SUCCESS; -} diff --git a/contrib/sendmail/libmilter/sm_gethost.c b/contrib/sendmail/libmilter/sm_gethost.c deleted file mode 100644 index 5706b89..0000000 --- a/contrib/sendmail/libmilter/sm_gethost.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 1999-2001, 2004 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: sm_gethost.c,v 8.27 2004/08/20 21:12:37 ca Exp $") - -#include <sendmail.h> -#if NETINET || NETINET6 -# include <arpa/inet.h> -#endif /* NETINET || NETINET6 */ -#include "libmilter.h" - -/* -** MI_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX -** -** Some operating systems have wierd problems with the gethostbyXXX -** routines. For example, Solaris versions at least through 2.3 -** don't properly deliver a canonical h_name field. This tries to -** work around these problems. -** -** Support IPv6 as well as IPv4. -*/ - -#if NETINET6 && NEEDSGETIPNODE - -static struct hostent *getipnodebyname __P((char *, int, int, int *)); - -# ifndef AI_ADDRCONFIG -# define AI_ADDRCONFIG 0 /* dummy */ -# endif /* ! AI_ADDRCONFIG */ -# ifndef AI_ALL -# define AI_ALL 0 /* dummy */ -# endif /* ! AI_ALL */ -# ifndef AI_DEFAULT -# define AI_DEFAULT 0 /* dummy */ -# endif /* ! AI_DEFAULT */ - -static struct hostent * -getipnodebyname(name, family, flags, err) - char *name; - int family; - int flags; - int *err; -{ - bool resv6 = true; - struct hostent *h; - - if (family == AF_INET6) - { - /* From RFC2133, section 6.1 */ - resv6 = bitset(RES_USE_INET6, _res.options); - _res.options |= RES_USE_INET6; - } - SM_SET_H_ERRNO(0); - h = gethostbyname(name); - if (family == AF_INET6 && !resv6) - _res.options &= ~RES_USE_INET6; - *err = h_errno; - return h; -} - -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 /* NEEDSGETIPNODE && NETINET6 */ - -struct hostent * -mi_gethostbyname(name, family) - char *name; - int family; -{ - struct hostent *h = NULL; -#if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) -# if SOLARIS == 20300 || SOLARIS == 203 - static struct hostent hp; - static char buf[1000]; - extern struct hostent *_switch_gethostbyname_r(); - - h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno); -# else /* SOLARIS == 20300 || SOLARIS == 203 */ - extern struct hostent *__switch_gethostbyname(); - - h = __switch_gethostbyname(name); -# endif /* SOLARIS == 20300 || SOLARIS == 203 */ -#else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */ -# if NETINET6 - int flags = AI_DEFAULT|AI_ALL; - int err; -# endif /* NETINET6 */ - -# if NETINET6 -# if ADDRCONFIG_IS_BROKEN - flags &= ~AI_ADDRCONFIG; -# endif /* ADDRCONFIG_IS_BROKEN */ - h = getipnodebyname(name, family, flags, &err); - SM_SET_H_ERRNO(err); -# else /* NETINET6 */ - h = gethostbyname(name); -# endif /* NETINET6 */ - -#endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */ - return h; -} - -#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/contrib/sendmail/libmilter/smfi.c b/contrib/sendmail/libmilter/smfi.c deleted file mode 100644 index 138623e..0000000 --- a/contrib/sendmail/libmilter/smfi.c +++ /dev/null @@ -1,889 +0,0 @@ -/* - * Copyright (c) 1999-2007 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: smfi.c,v 8.83 2007/04/23 16:44:39 ca Exp $") -#include <sm/varargs.h> -#include "libmilter.h" - -static int smfi_header __P((SMFICTX *, int, int, char *, char *)); -static int myisenhsc __P((const char *, int)); - -/* for smfi_set{ml}reply, let's be generous. 256/16 should be sufficient */ -#define MAXREPLYLEN 980 /* max. length of a reply string */ -#define MAXREPLIES 32 /* max. number of reply strings */ - -/* -** SMFI_HEADER -- send a header to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** cmd -- Header modification command -** hdridx -- Header index -** headerf -- Header field name -** headerv -- Header field value -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -static int -smfi_header(ctx, cmd, hdridx, headerf, headerv) - SMFICTX *ctx; - int cmd; - int hdridx; - char *headerf; - char *headerv; -{ - size_t len, l1, l2, offset; - int r; - mi_int32 v; - char *buf; - struct timeval timeout; - - if (headerf == NULL || *headerf == '\0' || headerv == NULL) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - l1 = strlen(headerf) + 1; - l2 = strlen(headerv) + 1; - len = l1 + l2; - if (hdridx >= 0) - len += MILTER_LEN_BYTES; - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; - offset = 0; - if (hdridx >= 0) - { - v = htonl(hdridx); - (void) memcpy(&(buf[0]), (void *) &v, MILTER_LEN_BYTES); - offset += MILTER_LEN_BYTES; - } - (void) memcpy(buf + offset, headerf, l1); - (void) memcpy(buf + offset + l1, headerv, l2); - r = mi_wr_cmd(ctx->ctx_sd, &timeout, cmd, buf, len); - free(buf); - return r; -} - -/* -** SMFI_ADDHEADER -- send a new header to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** headerf -- Header field name -** headerv -- Header field value -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_addheader(ctx, headerf, headerv) - SMFICTX *ctx; - char *headerf; - char *headerv; -{ - if (!mi_sendok(ctx, SMFIF_ADDHDRS)) - return MI_FAILURE; - - return smfi_header(ctx, SMFIR_ADDHEADER, -1, headerf, headerv); -} - -/* -** SMFI_INSHEADER -- send a new header to the MTA (to be inserted) -** -** Parameters: -** ctx -- Opaque context structure -** hdridx -- index into header list where insertion should occur -** headerf -- Header field name -** headerv -- Header field value -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_insheader(ctx, hdridx, headerf, headerv) - SMFICTX *ctx; - int hdridx; - char *headerf; - char *headerv; -{ - if (!mi_sendok(ctx, SMFIF_ADDHDRS) || hdridx < 0) - return MI_FAILURE; - - return smfi_header(ctx, SMFIR_INSHEADER, hdridx, headerf, headerv); -} - -/* -** 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; -{ - if (!mi_sendok(ctx, SMFIF_CHGHDRS) || hdridx < 0) - return MI_FAILURE; - if (headerv == NULL) - headerv = ""; - - return smfi_header(ctx, SMFIR_CHGHEADER, hdridx, headerf, headerv); -} - -#if 0 -/* -** BUF_CRT_SEND -- construct buffer to send from arguments -** -** Parameters: -** ctx -- Opaque context structure -** cmd -- command -** arg0 -- first argument -** argv -- list of arguments (NULL terminated) -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -static int -buf_crt_send __P((SMFICTX *, int cmd, char *, char **)); - -static int -buf_crt_send(ctx, cmd, arg0, argv) - SMFICTX *ctx; - int cmd; - char *arg0; - char **argv; -{ - size_t len, l0, l1, offset; - int r; - char *buf, *arg, **argvl; - struct timeval timeout; - - if (arg0 == NULL || *arg0 == '\0') - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - l0 = strlen(arg0) + 1; - len = l0; - argvl = argv; - while (argvl != NULL && (arg = *argv) != NULL && *arg != '\0') - { - l1 = strlen(arg) + 1; - len += l1; - SM_ASSERT(len > l1); - } - - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; - (void) memcpy(buf, arg0, l0); - offset = l0; - - argvl = argv; - while (argvl != NULL && (arg = *argv) != NULL && *arg != '\0') - { - l1 = strlen(arg) + 1; - SM_ASSERT(offset < len); - SM_ASSERT(offset + l1 <= len); - (void) memcpy(buf + offset, arg, l1); - offset += l1; - SM_ASSERT(offset > l1); - } - - r = mi_wr_cmd(ctx->ctx_sd, &timeout, cmd, buf, len); - free(buf); - return r; -} -#endif /* 0 */ - -/* -** SEND2 -- construct buffer to send from arguments -** -** Parameters: -** ctx -- Opaque context structure -** cmd -- command -** arg0 -- first argument -** argv -- list of arguments (NULL terminated) -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -static int -send2 __P((SMFICTX *, int cmd, char *, char *)); - -static int -send2(ctx, cmd, arg0, arg1) - SMFICTX *ctx; - int cmd; - char *arg0; - char *arg1; -{ - size_t len, l0, l1, offset; - int r; - char *buf; - struct timeval timeout; - - if (arg0 == NULL || *arg0 == '\0') - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - l0 = strlen(arg0) + 1; - len = l0; - if (arg1 != NULL) - { - l1 = strlen(arg1) + 1; - len += l1; - SM_ASSERT(len > l1); - } - - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; - (void) memcpy(buf, arg0, l0); - offset = l0; - - if (arg1 != NULL) - { - l1 = strlen(arg1) + 1; - SM_ASSERT(offset < len); - SM_ASSERT(offset + l1 <= len); - (void) memcpy(buf + offset, arg1, l1); - offset += l1; - SM_ASSERT(offset > l1); - } - - r = mi_wr_cmd(ctx->ctx_sd, &timeout, cmd, buf, len); - free(buf); - return r; -} - -/* -** SMFI_CHGFROM -- change enveloper sender ("from") address -** -** Parameters: -** ctx -- Opaque context structure -** from -- new envelope sender address ("MAIL From") -** args -- ESMTP arguments -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_chgfrom(ctx, from, args) - SMFICTX *ctx; - char *from; - char *args; -{ - if (from == NULL || *from == '\0') - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_CHGFROM)) - return MI_FAILURE; - return send2(ctx, SMFIR_CHGFROM, from, args); -} - -/* -** SMFI_SETSYMLIST -- set list of macros that the MTA should send. -** -** Parameters: -** ctx -- Opaque context structure -** where -- SMTP stage -** macros -- list of macros -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_setsymlist(ctx, where, macros) - SMFICTX *ctx; - int where; - char *macros; -{ - SM_ASSERT(ctx != NULL); - - if (macros == NULL || *macros == '\0') - return MI_FAILURE; - if (where < SMFIM_FIRST || where > SMFIM_LAST) - return MI_FAILURE; - if (where < 0 || where >= MAX_MACROS_ENTRIES) - return MI_FAILURE; - - if (ctx->ctx_mac_list[where] != NULL) - return MI_FAILURE; - - ctx->ctx_mac_list[where] = strdup(macros); - if (ctx->ctx_mac_list[where] == NULL) - return MI_FAILURE; - - return MI_SUCCESS; -} - -/* -** SMFI_ADDRCPT_PAR -- send an additional recipient to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** rcpt -- recipient address -** args -- ESMTP arguments -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_addrcpt_par(ctx, rcpt, args) - SMFICTX *ctx; - char *rcpt; - char *args; -{ - if (rcpt == NULL || *rcpt == '\0') - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_ADDRCPT_PAR)) - return MI_FAILURE; - return send2(ctx, SMFIR_ADDRCPT_PAR, rcpt, args); -} - -/* -** SMFI_ADDRCPT -- send an additional recipient to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** rcpt -- recipient address -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_addrcpt(ctx, rcpt) - SMFICTX *ctx; - char *rcpt; -{ - size_t len; - struct timeval timeout; - - 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_sd, &timeout, SMFIR_ADDRCPT, rcpt, len); -} - -/* -** SMFI_DELRCPT -- send a recipient to be removed to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** rcpt -- recipient address -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_delrcpt(ctx, rcpt) - SMFICTX *ctx; - char *rcpt; -{ - size_t len; - struct timeval timeout; - - 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_sd, &timeout, SMFIR_DELRCPT, rcpt, len); -} - -/* -** SMFI_REPLACEBODY -- send a body chunk to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** bodyp -- body chunk -** bodylen -- length of body chunk -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_replacebody(ctx, bodyp, bodylen) - SMFICTX *ctx; - unsigned char *bodyp; - int bodylen; -{ - int len, off, r; - struct timeval timeout; - - if (bodylen < 0 || - (bodyp == NULL && bodylen > 0)) - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_CHGBODY)) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - - /* split body chunk if necessary */ - off = 0; - do - { - len = (bodylen >= MILTER_CHUNK_SIZE) ? MILTER_CHUNK_SIZE : - bodylen; - if ((r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_REPLBODY, - (char *) (bodyp + off), len)) != MI_SUCCESS) - return r; - off += len; - bodylen -= len; - } while (bodylen > 0); - return MI_SUCCESS; -} - -/* -** SMFI_QUARANTINE -- quarantine an envelope -** -** Parameters: -** ctx -- Opaque context structure -** reason -- why? -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_quarantine(ctx, reason) - SMFICTX *ctx; - char *reason; -{ - size_t len; - int r; - char *buf; - struct timeval timeout; - - if (reason == NULL || *reason == '\0') - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_QUARANTINE)) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - len = strlen(reason) + 1; - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; - (void) memcpy(buf, reason, len); - r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_QUARANTINE, buf, len); - free(buf); - return r; -} - -/* -** MYISENHSC -- check whether a string contains an enhanced status code -** -** Parameters: -** s -- string with possible enhanced status code. -** delim -- delim for enhanced status code. -** -** Returns: -** 0 -- no enhanced status code. -** >4 -- length of enhanced status code. -** -** Side Effects: -** none. -*/ - -static int -myisenhsc(s, delim) - const char *s; - int delim; -{ - int l, h; - - if (s == NULL) - return 0; - if (!((*s == '2' || *s == '4' || *s == '5') && s[1] == '.')) - return 0; - h = 0; - l = 2; - while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h])) - ++h; - if (h == 0 || s[l + h] != '.') - return 0; - l += h + 1; - h = 0; - while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h])) - ++h; - if (h == 0 || s[l + h] != delim) - return 0; - return l + h; -} - -/* -** SMFI_SETREPLY -- set the reply code for the next reply to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** rcode -- The three-digit (RFC 821) SMTP reply code. -** xcode -- The extended (RFC 2034) reply code. -** message -- The text part of the SMTP reply. -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_setreply(ctx, rcode, xcode, message) - SMFICTX *ctx; - char *rcode; - char *xcode; - char *message; -{ - size_t len; - char *buf; - - if (rcode == NULL || ctx == NULL) - return MI_FAILURE; - - /* ### <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; - if (xcode != NULL) - { - if (!myisenhsc(xcode, '\0')) - return MI_FAILURE; - len += strlen(xcode) + 1; - } - if (message != NULL) - { - size_t ml; - - /* XXX check also for unprintable chars? */ - if (strpbrk(message, "\r\n") != NULL) - return MI_FAILURE; - ml = strlen(message); - if (ml > MAXREPLYLEN) - return MI_FAILURE; - len += ml + 1; - } - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; /* oops */ - (void) sm_strlcpy(buf, rcode, len); - (void) sm_strlcat(buf, " ", len); - if (xcode != NULL) - (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; - return MI_SUCCESS; -} - -/* -** SMFI_SETMLREPLY -- set multiline reply code for the next reply to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** rcode -- The three-digit (RFC 821) SMTP reply code. -** xcode -- The extended (RFC 2034) reply code. -** txt, ... -- The text part of the SMTP reply, -** MUST be terminated with NULL. -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -#if SM_VA_STD -smfi_setmlreply(SMFICTX *ctx, const char *rcode, const char *xcode, ...) -#else /* SM_VA_STD */ -smfi_setmlreply(ctx, rcode, xcode, va_alist) - SMFICTX *ctx; - const char *rcode; - const char *xcode; - va_dcl -#endif /* SM_VA_STD */ -{ - size_t len; - size_t rlen; - int args; - char *buf, *txt; - const char *xc; - char repl[16]; - SM_VA_LOCAL_DECL - - if (rcode == NULL || ctx == NULL) - return MI_FAILURE; - - /* ### <sp> */ - len = strlen(rcode) + 1; - if (len != 4) - 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; - if (xcode != NULL) - { - if (!myisenhsc(xcode, '\0')) - return MI_FAILURE; - xc = xcode; - } - else - { - if (rcode[0] == '4') - xc = "4.0.0"; - else - xc = "5.0.0"; - } - - /* add trailing space */ - len += strlen(xc) + 1; - rlen = len; - args = 0; - SM_VA_START(ap, xcode); - while ((txt = SM_VA_ARG(ap, char *)) != NULL) - { - size_t tl; - - tl = strlen(txt); - if (tl > MAXREPLYLEN) - break; - - /* this text, reply codes, \r\n */ - len += tl + 2 + rlen; - if (++args > MAXREPLIES) - break; - - /* XXX check also for unprintable chars? */ - if (strpbrk(txt, "\r\n") != NULL) - break; - } - SM_VA_END(ap); - if (txt != NULL) - return MI_FAILURE; - - /* trailing '\0' */ - ++len; - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; /* oops */ - (void) sm_strlcpyn(buf, len, 3, rcode, args == 1 ? " " : "-", xc); - (void) sm_strlcpyn(repl, sizeof repl, 4, rcode, args == 1 ? " " : "-", - xc, " "); - SM_VA_START(ap, xcode); - txt = SM_VA_ARG(ap, char *); - if (txt != NULL) - { - (void) sm_strlcat2(buf, " ", txt, len); - while ((txt = SM_VA_ARG(ap, char *)) != NULL) - { - if (--args <= 1) - repl[3] = ' '; - (void) sm_strlcat2(buf, "\r\n", repl, len); - (void) sm_strlcat(buf, txt, len); - } - } - if (ctx->ctx_reply != NULL) - free(ctx->ctx_reply); - ctx->ctx_reply = buf; - SM_VA_END(ap); - return MI_SUCCESS; -} - -/* -** SMFI_SETPRIV -- set private data -** -** Parameters: -** ctx -- Opaque context structure -** privatedata -- pointer to private data -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_setpriv(ctx, privatedata) - SMFICTX *ctx; - void *privatedata; -{ - if (ctx == NULL) - return MI_FAILURE; - ctx->ctx_privdata = privatedata; - return MI_SUCCESS; -} - -/* -** SMFI_GETPRIV -- get private data -** -** Parameters: -** ctx -- Opaque context structure -** -** Returns: -** pointer to private data -*/ - -void * -smfi_getpriv(ctx) - SMFICTX *ctx; -{ - if (ctx == NULL) - return NULL; - return ctx->ctx_privdata; -} - -/* -** SMFI_GETSYMVAL -- get the value of a macro -** -** See explanation in mfapi.h about layout of the structures. -** -** Parameters: -** ctx -- Opaque context structure -** symname -- name of macro -** -** Returns: -** value of macro (NULL in case of failure) -*/ - -char * -smfi_getsymval(ctx, symname) - SMFICTX *ctx; - char *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) - { - if ((s = ctx->ctx_mac_ptr[i]) == NULL || - ctx->ctx_mac_buf[i] == NULL) - continue; - while (s != NULL && *s != NULL) - { - 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 */ - } - } - return NULL; -} - -/* -** SMFI_PROGRESS -- send "progress" message to the MTA to prevent premature -** timeouts during long milter-side operations -** -** Parameters: -** ctx -- Opaque context structure -** -** Return value: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_progress(ctx) - SMFICTX *ctx; -{ - struct timeval timeout; - - if (ctx == NULL) - return MI_FAILURE; - - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - - return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_PROGRESS, NULL, 0); -} - -/* -** SMFI_VERSION -- return (runtime) version of libmilter -** -** Parameters: -** major -- (pointer to) major version -** minor -- (pointer to) minor version -** patchlevel -- (pointer to) patchlevel version -** -** Return value: -** MI_SUCCESS -*/ - -int -smfi_version(major, minor, patchlevel) - unsigned int *major; - unsigned int *minor; - unsigned int *patchlevel; -{ - if (major != NULL) - *major = SM_LM_VRS_MAJOR(SMFI_VERSION); - if (minor != NULL) - *minor = SM_LM_VRS_MINOR(SMFI_VERSION); - if (patchlevel != NULL) - *patchlevel = SM_LM_VRS_PLVL(SMFI_VERSION); - return MI_SUCCESS; -} diff --git a/contrib/sendmail/libmilter/worker.c b/contrib/sendmail/libmilter/worker.c deleted file mode 100644 index 0402678..0000000 --- a/contrib/sendmail/libmilter/worker.c +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Copyright (c) 2003-2004, 2006 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - * Contributed by Jose Marcio Martins da Cruz - Ecole des Mines de Paris - * Jose-Marcio.Martins@ensmp.fr - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: worker.c,v 8.9 2006/12/18 18:26:51 ca Exp $") - -#include "libmilter.h" - -#if _FFR_WORKERS_POOL - -typedef struct taskmgr_S taskmgr_T; - -#define TM_SIGNATURE 0x23021957 - -struct taskmgr_S -{ - long tm_signature; /* has the controller been initialized */ - sthread_t tm_tid; /* thread id of controller */ - smfi_hd_T tm_ctx_head; /* head of the linked list of contexts */ - - int tm_nb_workers; /* number of workers in the pool */ - int tm_nb_idle; /* number of workers waiting */ - - int tm_p[2]; /* poll control pipe */ - - smutex_t tm_w_mutex; /* linked list access mutex */ - scond_t tm_w_cond; /* */ -}; - -static taskmgr_T Tskmgr = {0}; - -#define WRK_CTX_HEAD Tskmgr.tm_ctx_head - -#define RD_PIPE (Tskmgr.tm_p[0]) -#define WR_PIPE (Tskmgr.tm_p[1]) - -#define PIPE_SEND_SIGNAL() \ - do \ - { \ - char evt = 0x5a; \ - int fd = WR_PIPE; \ - if (write(fd, &evt, sizeof(evt)) != sizeof(evt)) \ - smi_log(SMI_LOG_ERR, \ - "Error writing to event pipe: %s", \ - sm_errstring(errno)); \ - } while (0) - -#ifndef USE_PIPE_WAKE_POLL -# define USE_PIPE_WAKE_POLL 1 -#endif /* USE_PIPE_WAKE_POLL */ - -/* poll check periodicity (default 10000 - 10 s) */ -#define POLL_TIMEOUT 10000 - -/* worker conditional wait timeout (default 10 s) */ -#define COND_TIMEOUT 10 - -/* functions */ -static int mi_close_session __P((SMFICTX_PTR)); - -static void *mi_worker __P((void *)); -static void *mi_pool_controller __P((void *)); - -static int mi_list_add_ctx __P((SMFICTX_PTR)); -static int mi_list_del_ctx __P((SMFICTX_PTR)); - -/* -** periodicity of cleaning up old sessions (timedout) -** sessions list will be checked to find old inactive -** sessions each DT_CHECK_OLD_SESSIONS sec -*/ - -#define DT_CHECK_OLD_SESSIONS 600 - -#ifndef OLD_SESSION_TIMEOUT -# define OLD_SESSION_TIMEOUT ctx->ctx_timeout -#endif /* OLD_SESSION_TIMEOUT */ - -/* session states - with respect to the pool of workers */ -#define WKST_INIT 0 /* initial state */ -#define WKST_READY_TO_RUN 1 /* command ready do be read */ -#define WKST_RUNNING 2 /* session running on a worker */ -#define WKST_READY_TO_WAIT 3 /* session just finished by a worker */ -#define WKST_WAITING 4 /* waiting for new command */ -#define WKST_CLOSING 5 /* session finished */ - -#ifndef MIN_WORKERS -# define MIN_WORKERS 2 /* minimum number of threads to keep around */ -#endif - -#define MIN_IDLE 1 /* minimum number of idle threads */ - - -/* -** Macros for threads and mutex management -*/ - -#define TASKMGR_LOCK() \ - do \ - { \ - if (!smutex_lock(&Tskmgr.tm_w_mutex)) \ - smi_log(SMI_LOG_ERR, "TASKMGR_LOCK error"); \ - } while (0) - -#define TASKMGR_UNLOCK() \ - do \ - { \ - if (!smutex_unlock(&Tskmgr.tm_w_mutex)) \ - smi_log(SMI_LOG_ERR, "TASKMGR_UNLOCK error"); \ - } while (0) - -#define TASKMGR_COND_WAIT() \ - scond_timedwait(&Tskmgr.tm_w_cond, &Tskmgr.tm_w_mutex, COND_TIMEOUT) - -#define TASKMGR_COND_SIGNAL() \ - do \ - { \ - if (scond_signal(&Tskmgr.tm_w_cond) != 0) \ - smi_log(SMI_LOG_ERR, "TASKMGR_COND_SIGNAL error"); \ - } while (0) - -#define LAUNCH_WORKER(ctx) \ - do \ - { \ - int r; \ - sthread_t tid; \ - \ - if ((r = thread_create(&tid, mi_worker, ctx)) != 0) \ - smi_log(SMI_LOG_ERR, "LAUNCH_WORKER error: %s",\ - sm_errstring(r)); \ - } while (0) - -#if POOL_DEBUG -# define POOL_LEV_DPRINTF(lev, x) \ - do { \ - if ((lev) < ctx->ctx_dbg) \ - sm_dprintf x; \ - } while (0) -#else /* POOL_DEBUG */ -# define POOL_LEV_DPRINTF(lev, x) -#endif /* POOL_DEBUG */ - -/* -** MI_START_SESSION -- Start a session in the pool of workers -** -** Parameters: -** ctx -- context structure -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -mi_start_session(ctx) - SMFICTX_PTR ctx; -{ - static long id = 0; - - SM_ASSERT(Tskmgr.tm_signature == TM_SIGNATURE); - SM_ASSERT(ctx != NULL); - POOL_LEV_DPRINTF(4, ("PIPE r=[%d] w=[%d]", RD_PIPE, WR_PIPE)); - TASKMGR_LOCK(); - - if (mi_list_add_ctx(ctx) != MI_SUCCESS) - { - TASKMGR_UNLOCK(); - return MI_FAILURE; - } - - ctx->ctx_sid = id++; - - /* if there is an idle worker, signal it, otherwise start new worker */ - if (Tskmgr.tm_nb_idle > 0) - { - ctx->ctx_wstate = WKST_READY_TO_RUN; - TASKMGR_COND_SIGNAL(); - } - else - { - ctx->ctx_wstate = WKST_RUNNING; - LAUNCH_WORKER(ctx); - } - TASKMGR_UNLOCK(); - return MI_SUCCESS; -} - -/* -** MI_CLOSE_SESSION -- Close a session and clean up data structures -** -** Parameters: -** ctx -- context structure -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -static int -mi_close_session(ctx) - SMFICTX_PTR ctx; -{ - SM_ASSERT(ctx != NULL); - - (void) mi_list_del_ctx(ctx); - if (ValidSocket(ctx->ctx_sd)) - { - (void) closesocket(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, "%s: private data not NULL", - ctx->ctx_smfi->xxfi_name); - } - mi_clr_macros(ctx, 0); - free(ctx); - - return MI_SUCCESS; -} - -/* -** MI_POOL_CONTROLER_INIT -- Launch the worker pool controller -** Must be called before starting sessions. -** -** Parameters: -** none -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -mi_pool_controller_init() -{ - sthread_t tid; - int r, i; - - if (Tskmgr.tm_signature == TM_SIGNATURE) - return MI_SUCCESS; - - SM_TAILQ_INIT(&WRK_CTX_HEAD); - Tskmgr.tm_tid = (sthread_t) -1; - Tskmgr.tm_nb_workers = 0; - Tskmgr.tm_nb_idle = 0; - - if (pipe(Tskmgr.tm_p) != 0) - { - smi_log(SMI_LOG_ERR, "can't create event pipe: %s", - sm_errstring(r)); - return MI_FAILURE; - } - - POOL_LEV_DPRINTF(4, ("PIPE r=[%d] w=[%d]", RD_PIPE, WR_PIPE)); - - (void) smutex_init(&Tskmgr.tm_w_mutex); - (void) scond_init(&Tskmgr.tm_w_cond); - - /* Launch the pool controller */ - if ((r = thread_create(&tid, mi_pool_controller, (void *) NULL)) != 0) - { - smi_log(SMI_LOG_ERR, "can't create controller thread: %s", - sm_errstring(r)); - return MI_FAILURE; - } - Tskmgr.tm_tid = tid; - Tskmgr.tm_signature = TM_SIGNATURE; - - /* Create the pool of workers */ - for (i = 0; i < MIN_WORKERS; i++) - { - if ((r = thread_create(&tid, mi_worker, (void *) NULL)) != 0) - { - smi_log(SMI_LOG_ERR, "can't create workers crew: %s", - sm_errstring(r)); - return MI_FAILURE; - } - } - - return MI_SUCCESS; -} - -/* -** MI_POOL_CONTROLLER -- manage the pool of workers -** This thread must be running when listener begins -** starting sessions -** -** Parameters: -** arg -- unused -** -** Returns: -** NULL -** -** Control flow: -** for (;;) -** Look for timed out sessions -** Select sessions to wait for sendmail command -** Poll set of file descriptors -** if timeout -** continue -** For each file descriptor ready -** launch new thread if no worker available -** else -** signal waiting worker -*/ - -/* Poll structure array (pollfd) size step */ -#define PFD_STEP 256 - -#define WAIT_FD(i) (pfd[i].fd) -#define WAITFN "POLL" - -static void * -mi_pool_controller(arg) - void *arg; -{ - struct pollfd *pfd = NULL; - int dim_pfd = 0; - bool rebuild_set = true; - int pcnt = 0; /* error count for poll() failures */ - - Tskmgr.tm_tid = sthread_get_id(); - if (pthread_detach(Tskmgr.tm_tid) != 0) - { - smi_log(SMI_LOG_ERR, "Failed to detach pool controller thread"); - return NULL; - } - - pfd = (struct pollfd *) malloc(PFD_STEP * sizeof(struct pollfd)); - if (pfd == NULL) - { - smi_log(SMI_LOG_ERR, "Failed to malloc pollfd array: %s", - sm_errstring(errno)); - return NULL; - } - dim_pfd = PFD_STEP; - - for (;;) - { - SMFICTX_PTR ctx; - int nfd, rfd, i; - time_t now; - time_t lastcheck; - - POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN)); - - if (mi_stop() != MILTER_CONT) - break; - - TASKMGR_LOCK(); - - now = time(NULL); - - /* check for timed out sessions? */ - if (lastcheck + DT_CHECK_OLD_SESSIONS < now) - { - SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link) - { - if (ctx->ctx_wstate == WKST_WAITING) - { - if (ctx->ctx_wait == 0) - { - ctx->ctx_wait = now; - continue; - } - - /* if session timed out, close it */ - if (ctx->ctx_wait + OLD_SESSION_TIMEOUT - < now) - { - sfsistat (*fi_close) __P((SMFICTX *)); - - POOL_LEV_DPRINTF(4, - ("Closing old connection: sd=%d id=%d", - ctx->ctx_sd, - ctx->ctx_sid)); - - if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL) - (void) (*fi_close)(ctx); - - mi_close_session(ctx); - ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD); - continue; - } - } - } - lastcheck = now; - } - - if (rebuild_set) - { - /* - ** Initialize poll set. - ** Insert into the poll set the file descriptors of - ** all sessions waiting for a command from sendmail. - */ - - nfd = 0; - - /* begin with worker pipe */ - pfd[nfd].fd = RD_PIPE; - pfd[nfd].events = MI_POLL_RD_FLAGS; - pfd[nfd].revents = 0; - nfd++; - - SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link) - { - /* - ** update ctx_wait - start of wait moment - - ** for timeout - */ - - if (ctx->ctx_wstate == WKST_READY_TO_WAIT) - ctx->ctx_wait = now; - - /* add the session to the pollfd array? */ - if ((ctx->ctx_wstate == WKST_READY_TO_WAIT) || - (ctx->ctx_wstate == WKST_WAITING)) - { - /* - ** Resize the pollfd array if it - ** isn't large enough. - */ - - if (nfd >= dim_pfd) - { - struct pollfd *tpfd; - size_t new; - - new = (dim_pfd + PFD_STEP) * - sizeof(*tpfd); - tpfd = (struct pollfd *) - realloc(pfd, new); - if (tpfd != NULL) - { - pfd = tpfd; - dim_pfd += PFD_STEP; - } - else - { - smi_log(SMI_LOG_ERR, - "Failed to realloc pollfd array:%s", - sm_errstring(errno)); - } - } - - /* add the session to pollfd array */ - if (nfd < dim_pfd) - { - ctx->ctx_wstate = WKST_WAITING; - pfd[nfd].fd = ctx->ctx_sd; - pfd[nfd].events = MI_POLL_RD_FLAGS; - pfd[nfd].revents = 0; - nfd++; - } - } - } - } - - TASKMGR_UNLOCK(); - - /* Everything is ready, let's wait for an event */ - rfd = poll(pfd, nfd, POLL_TIMEOUT); - - POOL_LEV_DPRINTF(4, ("%s returned: at epoch %d value %d", - WAITFN, now, nfd)); - - /* timeout */ - if (rfd == 0) - continue; - - rebuild_set = true; - - /* error */ - if (rfd < 0) - { - if (errno == EINTR) - continue; - pcnt++; - smi_log(SMI_LOG_ERR, - "%s() failed (%s), %s", - WAITFN, sm_errstring(errno), - pcnt >= MAX_FAILS_S ? "abort" : "try again"); - - if (pcnt >= MAX_FAILS_S) - goto err; - } - pcnt = 0; - - /* something happened */ - for (i = 0; i < nfd; i++) - { - if (pfd[i].revents == 0) - continue; - - POOL_LEV_DPRINTF(4, ("%s event on pfd[%d/%d]=%d ", - WAITFN, i, nfd, - WAIT_FD(i))); - - /* has a worker signaled an end of task ? */ - if (WAIT_FD(i) == RD_PIPE) - { - char evt = 0; - int r = 0; - - POOL_LEV_DPRINTF(4, - ("PIPE WILL READ evt = %08X %08X", - pfd[i].events, pfd[i].revents)); - - if ((pfd[i].revents & MI_POLL_RD_FLAGS) != 0) - { - r = read(RD_PIPE, &evt, sizeof(evt)); - if (r == sizeof(evt)) - { - /* Do nothing */ - } - } - - POOL_LEV_DPRINTF(4, - ("PIPE DONE READ i=[%d] fd=[%d] r=[%d] evt=[%d]", - i, RD_PIPE, r, evt)); - - if ((pfd[i].revents & ~MI_POLL_RD_FLAGS) != 0) - { - /* Exception handling */ - } - continue; - } - - /* no ! sendmail wants to send a command */ - SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link) - { - if (ctx->ctx_wstate != WKST_WAITING) - continue; - - POOL_LEV_DPRINTF(4, - ("Checking context sd=%d - fd=%d ", - ctx->ctx_sd , WAIT_FD(i))); - - if (ctx->ctx_sd == pfd[i].fd) - { - TASKMGR_LOCK(); - - POOL_LEV_DPRINTF(4, - ("TASK: found %d for fd[%d]=%d", - ctx->ctx_sid, i, WAIT_FD(i))); - - if (Tskmgr.tm_nb_idle > 0) - { - ctx->ctx_wstate = WKST_READY_TO_RUN; - TASKMGR_COND_SIGNAL(); - } - else - { - ctx->ctx_wstate = WKST_RUNNING; - LAUNCH_WORKER(ctx); - } - TASKMGR_UNLOCK(); - break; - } - } - - POOL_LEV_DPRINTF(4, - ("TASK %s FOUND - Checking PIPE for fd[%d]", - ctx != NULL ? "" : "NOT", WAIT_FD(i))); - } - } - - err: - if (pfd != NULL) - free(pfd); - - Tskmgr.tm_signature = 0; - for (;;) - { - SMFICTX_PTR ctx; - - ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD); - if (ctx == NULL) - break; - mi_close_session(ctx); - } - - (void) smutex_destroy(&Tskmgr.tm_w_mutex); - (void) scond_destroy(&Tskmgr.tm_w_cond); - - return NULL; -} - -/* -** Look for a task ready to run. -** Value of ctx is NULL or a pointer to a task ready to run. -*/ - -#define GET_TASK_READY_TO_RUN() \ - SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link) \ - { \ - if (ctx->ctx_wstate == WKST_READY_TO_RUN) \ - { \ - ctx->ctx_wstate = WKST_RUNNING; \ - break; \ - } \ - } - -/* -** MI_WORKER -- worker thread -** executes tasks distributed by the mi_pool_controller -** or by mi_start_session -** -** Parameters: -** arg -- pointer to context structure -** -** Returns: -** NULL pointer -*/ - -static void * -mi_worker(arg) - void *arg; -{ - SMFICTX_PTR ctx; - bool done; - sthread_t t_id; - int r; - - ctx = (SMFICTX_PTR) arg; - done = false; - if (ctx != NULL) - ctx->ctx_wstate = WKST_RUNNING; - - t_id = sthread_get_id(); - if (pthread_detach(t_id) != 0) - { - smi_log(SMI_LOG_ERR, "Failed to detach worker thread"); - if (ctx != NULL) - ctx->ctx_wstate = WKST_READY_TO_RUN; - return NULL; - } - - TASKMGR_LOCK(); - Tskmgr.tm_nb_workers++; - TASKMGR_UNLOCK(); - - while (!done) - { - if (mi_stop() != MILTER_CONT) - break; - - /* let's handle next task... */ - if (ctx != NULL) - { - int res; - - POOL_LEV_DPRINTF(4, - ("worker %d: new task -> let's handle it", - t_id)); - res = mi_engine(ctx); - POOL_LEV_DPRINTF(4, - ("worker %d: mi_engine returned %d", t_id, res)); - - TASKMGR_LOCK(); - if (res != MI_CONTINUE) - { - ctx->ctx_wstate = WKST_CLOSING; - - /* - ** Delete context from linked list of - ** sessions and close session. - */ - - mi_close_session(ctx); - } - else - { - ctx->ctx_wstate = WKST_READY_TO_WAIT; - - POOL_LEV_DPRINTF(4, - ("writing to event pipe...")); - - /* - ** Signal task controller to add new session - ** to poll set. - */ - - PIPE_SEND_SIGNAL(); - } - TASKMGR_UNLOCK(); - ctx = NULL; - - } - - /* check if there is any task waiting to be served */ - TASKMGR_LOCK(); - - GET_TASK_READY_TO_RUN(); - - /* Got a task? */ - if (ctx != NULL) - { - TASKMGR_UNLOCK(); - continue; - } - - /* - ** if not, let's check if there is enough idle workers - ** if yes: quit - */ - - if (Tskmgr.tm_nb_workers > MIN_WORKERS && - Tskmgr.tm_nb_idle > MIN_IDLE) - done = true; - - POOL_LEV_DPRINTF(4, ("worker %d: checking ... %d %d", t_id, - Tskmgr.tm_nb_workers, Tskmgr.tm_nb_idle + 1)); - - if (done) - { - POOL_LEV_DPRINTF(4, ("worker %d: quitting... ", t_id)); - Tskmgr.tm_nb_workers--; - TASKMGR_UNLOCK(); - continue; - } - - /* - ** if no task ready to run, wait for another one - */ - - Tskmgr.tm_nb_idle++; - TASKMGR_COND_WAIT(); - Tskmgr.tm_nb_idle--; - - /* look for a task */ - GET_TASK_READY_TO_RUN(); - - TASKMGR_UNLOCK(); - } - return NULL; -} - -/* -** MI_LIST_ADD_CTX -- add new session to linked list -** -** Parameters: -** ctx -- context structure -** -** Returns: -** MI_FAILURE/MI_SUCCESS -*/ - -static int -mi_list_add_ctx(ctx) - SMFICTX_PTR ctx; -{ - SM_ASSERT(ctx != NULL); - SM_TAILQ_INSERT_TAIL(&WRK_CTX_HEAD, ctx, ctx_link); - return MI_SUCCESS; -} - -/* -** MI_LIST_DEL_CTX -- remove session from linked list when finished -** -** Parameters: -** ctx -- context structure -** -** Returns: -** MI_FAILURE/MI_SUCCESS -*/ - -static int -mi_list_del_ctx(ctx) - SMFICTX_PTR ctx; -{ - SM_ASSERT(ctx != NULL); - if (SM_TAILQ_EMPTY(&WRK_CTX_HEAD)) - return MI_FAILURE; - - SM_TAILQ_REMOVE(&WRK_CTX_HEAD, ctx, ctx_link); - return MI_SUCCESS; -} -#endif /* _FFR_WORKERS_POOL */ |