106f25ae9SGregory Neil ShapiroThis directory contains the source files for libmilter. 206f25ae9SGregory Neil Shapiro 306f25ae9SGregory Neil ShapiroThe sendmail Mail Filter API (Milter) is designed to allow third-party 406f25ae9SGregory Neil Shapiroprograms access to mail messages as they are being processed in order to 506f25ae9SGregory Neil Shapirofilter meta-information and content. 606f25ae9SGregory Neil Shapiro 706f25ae9SGregory Neil ShapiroThis README file describes the steps needed to compile and run a filter, 806f25ae9SGregory Neil Shapirothrough reference to a sample filter which is attached at the end of this 906f25ae9SGregory Neil Shapirofile. It is necessary to first build libmilter.a, which can be done by 1006f25ae9SGregory Neil Shapiroissuing the './Build' command in SRCDIR/libmilter . 1106f25ae9SGregory Neil Shapiro 12e92d3f3fSGregory Neil ShapiroStarting with 8.13 sendmail is compiled by default with support for 13e92d3f3fSGregory Neil Shapirothe milter API. 1406f25ae9SGregory Neil Shapiro 1540266059SGregory Neil Shapiro+----------------+ 1640266059SGregory Neil Shapiro| SECURITY HINTS | 1740266059SGregory Neil Shapiro+----------------+ 1840266059SGregory Neil Shapiro 1940266059SGregory Neil ShapiroNote: we strongly recommend not to run any milter as root. Libmilter 2040266059SGregory Neil Shapirodoes not need root access to communicate with sendmail. It is a 2140266059SGregory Neil Shapirogood security practice to run a program only with root privileges 2240266059SGregory Neil Shapiroif really necessary. A milter should probably check first whether 23e92d3f3fSGregory Neil Shapiroit runs as root and refuse to start in that case. libmilter will 24e92d3f3fSGregory Neil Shapironot unlink a socket when running as root. 2540266059SGregory Neil Shapiro 26e92d3f3fSGregory Neil Shapiro+----------------------+ 27e92d3f3fSGregory Neil Shapiro| CONFIGURATION MACROS | 28e92d3f3fSGregory Neil Shapiro+----------------------+ 2940266059SGregory Neil Shapiro 30e92d3f3fSGregory Neil ShapiroLibmilter uses a set of C preprocessor macros to specify platform specific 31e92d3f3fSGregory Neil Shapirofeatures of the C compiler and standard C libraries. 32e92d3f3fSGregory Neil Shapiro 33e92d3f3fSGregory Neil ShapiroSM_CONF_POLL 34e92d3f3fSGregory Neil Shapiro Set to 1 if poll(2) should be used instead of select(2). 3506f25ae9SGregory Neil Shapiro 3606f25ae9SGregory Neil Shapiro+-------------------+ 3706f25ae9SGregory Neil Shapiro| BUILDING A FILTER | 3806f25ae9SGregory Neil Shapiro+-------------------+ 3906f25ae9SGregory Neil Shapiro 4006f25ae9SGregory Neil ShapiroThe following command presumes that the sample code from the end of this 4106f25ae9SGregory Neil ShapiroREADME is saved to a file named 'sample.c' and built in the local platform- 4206f25ae9SGregory Neil Shapirospecific build subdirectory (SRCDIR/obj.*/libmilter). 4306f25ae9SGregory Neil Shapiro 4413bd1963SGregory Neil Shapiro cc -I../../include -o sample sample.c libmilter.a ../libsm/libsm.a -pthread 4506f25ae9SGregory Neil Shapiro 4606f25ae9SGregory Neil ShapiroIt is recommended that you build your filters in a location outside of 4706f25ae9SGregory Neil Shapirothe sendmail source tree. Modify the compiler include references (-I) 4806f25ae9SGregory Neil Shapiroand the library locations accordingly. Also, some operating systems may 4906f25ae9SGregory Neil Shapirorequire additional libraries. For example, SunOS 5.X requires '-lresolv 5040266059SGregory Neil Shapiro-lsocket -lnsl'. Depending on your operating system you may need a library 5140266059SGregory Neil Shapiroinstead of the option -pthread, e.g., -lpthread. 5206f25ae9SGregory Neil Shapiro 5306f25ae9SGregory Neil ShapiroFilters must be thread-safe! Many operating systems now provide support for 5406f25ae9SGregory Neil ShapiroPOSIX threads in the standard C libraries. The compiler flag to link with 5506f25ae9SGregory Neil Shapirothreading support differs according to the compiler and linker used. Check 5606f25ae9SGregory Neil Shapirothe Makefile in your appropriate obj.*/libmilter build subdirectory if you 5706f25ae9SGregory Neil Shapiroare unsure of the local flag used. 5806f25ae9SGregory Neil Shapiro 59602a2b1bSGregory Neil ShapiroNote that since filters use threads, it may be necessary to alter per 60602a2b1bSGregory Neil Shapiroprocess limits in your filter. For example, you might look at using 61602a2b1bSGregory Neil Shapirosetrlimit() to increase the number of open file descriptors if your filter 62602a2b1bSGregory Neil Shapirois going to be busy. 63602a2b1bSGregory Neil Shapiro 6406f25ae9SGregory Neil Shapiro 6506f25ae9SGregory Neil Shapiro+----------------------------------------+ 6606f25ae9SGregory Neil Shapiro| SPECIFYING FILTERS IN SENDMAIL CONFIGS | 6706f25ae9SGregory Neil Shapiro+----------------------------------------+ 6806f25ae9SGregory Neil Shapiro 6906f25ae9SGregory Neil ShapiroFilters are specified with a key letter ``X'' (for ``eXternal''). 7006f25ae9SGregory Neil Shapiro 7106f25ae9SGregory Neil ShapiroFor example: 7206f25ae9SGregory Neil Shapiro 7306f25ae9SGregory Neil Shapiro Xfilter1, S=local:/var/run/f1.sock, F=R 7413058a91SGregory Neil Shapiro Xfilter2, S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m 7506f25ae9SGregory Neil Shapiro Xfilter3, S=inet:3333@localhost 7606f25ae9SGregory Neil Shapiro 7706f25ae9SGregory Neil Shapirospecifies three filters. Filters can be specified in your .mc file using 7806f25ae9SGregory Neil Shapirothe following: 7906f25ae9SGregory Neil Shapiro 8006f25ae9SGregory Neil Shapiro INPUT_MAIL_FILTER(`filter1', `S=local:/var/run/f1.sock, F=R') 8113058a91SGregory Neil Shapiro INPUT_MAIL_FILTER(`filter2', `S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m') 8206f25ae9SGregory Neil Shapiro INPUT_MAIL_FILTER(`filter3', `S=inet:3333@localhost') 8306f25ae9SGregory Neil Shapiro 8406f25ae9SGregory Neil ShapiroThe first attaches to a Unix-domain socket in the /var/run directory; the 8506f25ae9SGregory Neil Shapirosecond uses an IPv6 socket on port 999 of localhost, and the third uses an 8606f25ae9SGregory Neil ShapiroIPv4 socket on port 3333 of localhost. The current flags (F=) are: 8706f25ae9SGregory Neil Shapiro 8806f25ae9SGregory Neil Shapiro R Reject connection if filter unavailable 8906f25ae9SGregory Neil Shapiro T Temporary fail connection if filter unavailable 9006f25ae9SGregory Neil Shapiro 9142e5d165SGregory Neil ShapiroIf neither F=R nor F=T is specified, the message is passed through sendmail 9240266059SGregory Neil Shapiroin case of filter errors as if the failing filters were not present. 9342e5d165SGregory Neil Shapiro 9406f25ae9SGregory Neil ShapiroFinally, you can override the default timeouts used by sendmail when 9513058a91SGregory Neil Shapirotalking to the filters using the T= equate. There are four fields inside 9606f25ae9SGregory Neil Shapiroof the T= equate: 9706f25ae9SGregory Neil Shapiro 9806f25ae9SGregory Neil ShapiroLetter Meaning 9913058a91SGregory Neil Shapiro C Timeout for connecting to a filter (if 0, use system timeout) 10006f25ae9SGregory Neil Shapiro S Timeout for sending information from the MTA to a filter 10106f25ae9SGregory Neil Shapiro R Timeout for reading reply from the filter 10206f25ae9SGregory Neil Shapiro E Overall timeout between sending end-of-message to filter 10306f25ae9SGregory Neil Shapiro and waiting for the final acknowledgment 10406f25ae9SGregory Neil Shapiro 10506f25ae9SGregory Neil ShapiroNote the separator between each is a ';' as a ',' already separates equates 10613058a91SGregory Neil Shapiroand therefore can't separate timeouts. The default values (if not set in 10713058a91SGregory Neil Shapirothe config) are: 10806f25ae9SGregory Neil Shapiro 10940266059SGregory Neil ShapiroT=C:5m;S:10s;R:10s;E:5m 11006f25ae9SGregory Neil Shapiro 11106f25ae9SGregory Neil Shapirowhere 's' is seconds and 'm' is minutes. 11206f25ae9SGregory Neil Shapiro 11342e5d165SGregory Neil ShapiroWhich filters are invoked and their sequencing is handled by the 1148774250cSGregory Neil ShapiroInputMailFilters option. Note: if InputMailFilters is not defined no filters 1158774250cSGregory Neil Shapirowill be used. 11642e5d165SGregory Neil Shapiro 11742e5d165SGregory Neil Shapiro O InputMailFilters=filter1, filter2, filter3 11842e5d165SGregory Neil Shapiro 11942e5d165SGregory Neil ShapiroThis is is set automatically according to the order of the 12042e5d165SGregory Neil ShapiroINPUT_MAIL_FILTER commands in your .mc file. Alternatively, you can 12142e5d165SGregory Neil Shapiroreset its value by setting confINPUT_MAIL_FILTERS in your .mc file. 12242e5d165SGregory Neil ShapiroThis options causes the three filters to be called in the same order 12342e5d165SGregory Neil Shapirothey were specified. It allows for possible future filtering on output 12442e5d165SGregory Neil Shapiro(although this is not intended for this release). 12506f25ae9SGregory Neil Shapiro 12606f25ae9SGregory Neil ShapiroAlso note that a filter can be defined without adding it to the input 12706f25ae9SGregory Neil Shapirofilter list by using MAIL_FILTER() instead of INPUT_MAIL_FILTER() in your 12806f25ae9SGregory Neil Shapiro.mc file. 12906f25ae9SGregory Neil Shapiro 13006f25ae9SGregory Neil ShapiroTo test sendmail with the sample filter, the following might be added (in 13106f25ae9SGregory Neil Shapirothe appropriate locations) to your .mc file: 13206f25ae9SGregory Neil Shapiro 13306f25ae9SGregory Neil Shapiro INPUT_MAIL_FILTER(`sample', `S=local:/var/run/f1.sock') 13406f25ae9SGregory Neil Shapiro 13506f25ae9SGregory Neil Shapiro 13606f25ae9SGregory Neil Shapiro+------------------+ 13706f25ae9SGregory Neil Shapiro| TESTING A FILTER | 13806f25ae9SGregory Neil Shapiro+------------------+ 13906f25ae9SGregory Neil Shapiro 14006f25ae9SGregory Neil ShapiroOnce you have compiled a filter, modified your .mc file and restarted 14106f25ae9SGregory Neil Shapirothe sendmail process, you will want to test that the filter performs as 14206f25ae9SGregory Neil Shapirointended. 14306f25ae9SGregory Neil Shapiro 14406f25ae9SGregory Neil ShapiroThe sample filter takes one argument -p, which indicates the local port 14506f25ae9SGregory Neil Shapiroon which to create a listening socket for the filter. Maintaining 14606f25ae9SGregory Neil Shapiroconsistency with the suggested options for sendmail.cf, this would be the 14706f25ae9SGregory Neil ShapiroUNIX domain socket located in /var/run/f1.sock. 14806f25ae9SGregory Neil Shapiro 14906f25ae9SGregory Neil Shapiro % ./sample -p local:/var/run/f1.sock 15006f25ae9SGregory Neil Shapiro 15106f25ae9SGregory Neil ShapiroIf the sample filter returns immediately to a command line, there was either 15206f25ae9SGregory Neil Shapiroan error with your command or a problem creating the specified socket. 15306f25ae9SGregory Neil ShapiroFurther logging can be captured through the syslogd daemon. Using the 15406f25ae9SGregory Neil Shapiro'netstat -a' command can ensure that your filter process is listening on 15506f25ae9SGregory Neil Shapirothe appropriate local socket. 15606f25ae9SGregory Neil Shapiro 15706f25ae9SGregory Neil ShapiroEmail messages must be injected via SMTP to be filtered. There are two 15806f25ae9SGregory Neil Shapirosimple means of doing this; either using the 'sendmail -bs' command, or 15906f25ae9SGregory Neil Shapiroby telnetting to port 25 of the machine configured for milter. Once 16006f25ae9SGregory Neil Shapiroconnected via one of these options, the session can be continued through 16106f25ae9SGregory Neil Shapirothe use of standard SMTP commands. 16206f25ae9SGregory Neil Shapiro 16306f25ae9SGregory Neil Shapiro% sendmail -bs 16442e5d165SGregory Neil Shapiro220 test.sendmail.com ESMTP Sendmail 8.11.0/8.11.0; Tue, 10 Nov 1970 13:05:23 -0500 (EST) 16506f25ae9SGregory Neil ShapiroHELO localhost 16606f25ae9SGregory Neil Shapiro250 test.sendmail.com Hello testy@localhost, pleased to meet you 16706f25ae9SGregory Neil ShapiroMAIL From:<testy> 16806f25ae9SGregory Neil Shapiro250 2.1.0 <testy>... Sender ok 16906f25ae9SGregory Neil ShapiroRCPT To:<root> 17006f25ae9SGregory Neil Shapiro250 2.1.5 <root>... Recipient ok 17106f25ae9SGregory Neil ShapiroDATA 17206f25ae9SGregory Neil Shapiro354 Enter mail, end with "." on a line by itself 17306f25ae9SGregory Neil ShapiroFrom: testy@test.sendmail.com 17406f25ae9SGregory Neil ShapiroTo: root@test.sendmail.com 17506f25ae9SGregory Neil ShapiroSubject: testing sample filter 17606f25ae9SGregory Neil Shapiro 17706f25ae9SGregory Neil ShapiroSample body 17806f25ae9SGregory Neil Shapiro. 17906f25ae9SGregory Neil Shapiro250 2.0.0 dB73Zxi25236 Message accepted for delivery 18006f25ae9SGregory Neil ShapiroQUIT 18106f25ae9SGregory Neil Shapiro221 2.0.0 test.sendmail.com closing connection 18206f25ae9SGregory Neil Shapiro 18306f25ae9SGregory Neil ShapiroIn the above example, the lines beginning with numbers are output by the 18406f25ae9SGregory Neil Shapiromail server, and those without are your input. If everything is working 18506f25ae9SGregory Neil Shapiroproperly, you will find a file in /tmp by the name of msg.XXXXXXXX (where 18606f25ae9SGregory Neil Shapirothe Xs represent any combination of letters and numbers). This file should 18706f25ae9SGregory Neil Shapirocontain the message body and headers from the test email entered above. 18806f25ae9SGregory Neil Shapiro 18906f25ae9SGregory Neil ShapiroIf the sample filter did not log your test email, there are a number of 19006f25ae9SGregory Neil Shapiromethods to narrow down the source of the problem. Check your system 19106f25ae9SGregory Neil Shapirologs written by syslogd and see if there are any pertinent lines. You 19206f25ae9SGregory Neil Shapiromay need to reconfigure syslogd to capture all relevant data. Additionally, 19306f25ae9SGregory Neil Shapirothe logging level of sendmail can be raised with the LogLevel option. 19406f25ae9SGregory Neil ShapiroSee the sendmail(8) manual page for more information. 19506f25ae9SGregory Neil Shapiro 19606f25ae9SGregory Neil Shapiro 19740266059SGregory Neil Shapiro+--------------+ 19840266059SGregory Neil Shapiro| REQUIREMENTS | 19940266059SGregory Neil Shapiro+--------------+ 20040266059SGregory Neil Shapiro 20140266059SGregory Neil Shapirolibmilter requires pthread support in the operating system. Moreover, it 20240266059SGregory Neil Shapirorequires that the library functions it uses are thread safe; which is true 20340266059SGregory Neil Shapirofor the operating systems libmilter has been developed and tested on. On 20440266059SGregory Neil Shapirosome operating systems this requires special compile time options (e.g., 20540266059SGregory Neil Shapironot just -pthread). libmilter is currently known to work on (modulo problems 20640266059SGregory Neil Shapiroin the pthread support of some specific versions): 20740266059SGregory Neil Shapiro 20840266059SGregory Neil ShapiroFreeBSD 3.x, 4.x 20940266059SGregory Neil ShapiroSunOS 5.x (x >= 5) 21040266059SGregory Neil ShapiroAIX 4.3.x 21140266059SGregory Neil ShapiroHP UX 11.x 21240266059SGregory Neil ShapiroLinux (recent versions/distributions) 21340266059SGregory Neil Shapiro 21440266059SGregory Neil Shapirolibmilter is currently not supported on: 21540266059SGregory Neil Shapiro 21640266059SGregory Neil ShapiroIRIX 6.x 21740266059SGregory Neil ShapiroUltrix 21840266059SGregory Neil Shapiro 21940266059SGregory Neil ShapiroFeedback about problems (and possible fixes) is welcome. 22040266059SGregory Neil Shapiro 22106f25ae9SGregory Neil Shapiro+--------------------------+ 22206f25ae9SGregory Neil Shapiro| SOURCE FOR SAMPLE FILTER | 22306f25ae9SGregory Neil Shapiro+--------------------------+ 22406f25ae9SGregory Neil Shapiro 225193538b7SGregory Neil ShapiroNote that the filter below may not be thread safe on some operating 226193538b7SGregory Neil Shapirosystems. You should check your system man pages for the functions used 227193538b7SGregory Neil Shapirobelow to verify the functions are thread safe. 228193538b7SGregory Neil Shapiro 22906f25ae9SGregory Neil Shapiro/* A trivial filter that logs all email to a file. */ 23006f25ae9SGregory Neil Shapiro 23106f25ae9SGregory Neil Shapiro#include <sys/types.h> 23206f25ae9SGregory Neil Shapiro#include <stdio.h> 23306f25ae9SGregory Neil Shapiro#include <stdlib.h> 23406f25ae9SGregory Neil Shapiro#include <string.h> 23506f25ae9SGregory Neil Shapiro#include <sysexits.h> 23606f25ae9SGregory Neil Shapiro#include <unistd.h> 23706f25ae9SGregory Neil Shapiro 23806f25ae9SGregory Neil Shapiro#include "libmilter/mfapi.h" 23906f25ae9SGregory Neil Shapiro 24040266059SGregory Neil Shapiro#ifndef true 24106f25ae9SGregory Neil Shapirotypedef int bool; 24240266059SGregory Neil Shapiro# define false 0 24340266059SGregory Neil Shapiro# define true 1 24440266059SGregory Neil Shapiro#endif /* ! true */ 24506f25ae9SGregory Neil Shapiro 24606f25ae9SGregory Neil Shapirostruct mlfiPriv 24706f25ae9SGregory Neil Shapiro{ 24806f25ae9SGregory Neil Shapiro char *mlfi_fname; 24906f25ae9SGregory Neil Shapiro FILE *mlfi_fp; 25006f25ae9SGregory Neil Shapiro}; 25106f25ae9SGregory Neil Shapiro 25206f25ae9SGregory Neil Shapiro#define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx)) 25306f25ae9SGregory Neil Shapiro 25406f25ae9SGregory Neil Shapiroextern sfsistat mlfi_cleanup(SMFICTX *, bool); 25506f25ae9SGregory Neil Shapiro 25606f25ae9SGregory Neil Shapirosfsistat 25706f25ae9SGregory Neil Shapiromlfi_envfrom(ctx, envfrom) 25806f25ae9SGregory Neil Shapiro SMFICTX *ctx; 25906f25ae9SGregory Neil Shapiro char **envfrom; 26006f25ae9SGregory Neil Shapiro{ 26106f25ae9SGregory Neil Shapiro struct mlfiPriv *priv; 2628774250cSGregory Neil Shapiro int fd = -1; 26306f25ae9SGregory Neil Shapiro 26406f25ae9SGregory Neil Shapiro /* allocate some private memory */ 26506f25ae9SGregory Neil Shapiro priv = malloc(sizeof *priv); 26606f25ae9SGregory Neil Shapiro if (priv == NULL) 26706f25ae9SGregory Neil Shapiro { 26806f25ae9SGregory Neil Shapiro /* can't accept this message right now */ 26906f25ae9SGregory Neil Shapiro return SMFIS_TEMPFAIL; 27006f25ae9SGregory Neil Shapiro } 27106f25ae9SGregory Neil Shapiro memset(priv, '\0', sizeof *priv); 27206f25ae9SGregory Neil Shapiro 27306f25ae9SGregory Neil Shapiro /* open a file to store this message */ 27406f25ae9SGregory Neil Shapiro priv->mlfi_fname = strdup("/tmp/msg.XXXXXXXX"); 27506f25ae9SGregory Neil Shapiro if (priv->mlfi_fname == NULL) 27606f25ae9SGregory Neil Shapiro { 27706f25ae9SGregory Neil Shapiro free(priv); 27806f25ae9SGregory Neil Shapiro return SMFIS_TEMPFAIL; 27906f25ae9SGregory Neil Shapiro } 28006f25ae9SGregory Neil Shapiro if ((fd = mkstemp(priv->mlfi_fname)) < 0 || 28106f25ae9SGregory Neil Shapiro (priv->mlfi_fp = fdopen(fd, "w+")) == NULL) 28206f25ae9SGregory Neil Shapiro { 2838774250cSGregory Neil Shapiro if (fd >= 0) 2848774250cSGregory Neil Shapiro (void) close(fd); 28506f25ae9SGregory Neil Shapiro free(priv->mlfi_fname); 28606f25ae9SGregory Neil Shapiro free(priv); 28706f25ae9SGregory Neil Shapiro return SMFIS_TEMPFAIL; 28806f25ae9SGregory Neil Shapiro } 28906f25ae9SGregory Neil Shapiro 29006f25ae9SGregory Neil Shapiro /* save the private data */ 29106f25ae9SGregory Neil Shapiro smfi_setpriv(ctx, priv); 29206f25ae9SGregory Neil Shapiro 29306f25ae9SGregory Neil Shapiro /* continue processing */ 29406f25ae9SGregory Neil Shapiro return SMFIS_CONTINUE; 29506f25ae9SGregory Neil Shapiro} 29606f25ae9SGregory Neil Shapiro 29706f25ae9SGregory Neil Shapirosfsistat 29806f25ae9SGregory Neil Shapiromlfi_header(ctx, headerf, headerv) 29906f25ae9SGregory Neil Shapiro SMFICTX *ctx; 30006f25ae9SGregory Neil Shapiro char *headerf; 30106f25ae9SGregory Neil Shapiro char *headerv; 30206f25ae9SGregory Neil Shapiro{ 30306f25ae9SGregory Neil Shapiro /* write the header to the log file */ 30406f25ae9SGregory Neil Shapiro fprintf(MLFIPRIV->mlfi_fp, "%s: %s\r\n", headerf, headerv); 30506f25ae9SGregory Neil Shapiro 30606f25ae9SGregory Neil Shapiro /* continue processing */ 30706f25ae9SGregory Neil Shapiro return SMFIS_CONTINUE; 30806f25ae9SGregory Neil Shapiro} 30906f25ae9SGregory Neil Shapiro 31006f25ae9SGregory Neil Shapirosfsistat 31106f25ae9SGregory Neil Shapiromlfi_eoh(ctx) 31206f25ae9SGregory Neil Shapiro SMFICTX *ctx; 31306f25ae9SGregory Neil Shapiro{ 31406f25ae9SGregory Neil Shapiro /* output the blank line between the header and the body */ 31506f25ae9SGregory Neil Shapiro fprintf(MLFIPRIV->mlfi_fp, "\r\n"); 31606f25ae9SGregory Neil Shapiro 31706f25ae9SGregory Neil Shapiro /* continue processing */ 31806f25ae9SGregory Neil Shapiro return SMFIS_CONTINUE; 31906f25ae9SGregory Neil Shapiro} 32006f25ae9SGregory Neil Shapiro 32106f25ae9SGregory Neil Shapirosfsistat 32206f25ae9SGregory Neil Shapiromlfi_body(ctx, bodyp, bodylen) 32306f25ae9SGregory Neil Shapiro SMFICTX *ctx; 32406f25ae9SGregory Neil Shapiro u_char *bodyp; 32506f25ae9SGregory Neil Shapiro size_t bodylen; 32606f25ae9SGregory Neil Shapiro{ 32706f25ae9SGregory Neil Shapiro /* output body block to log file */ 32806f25ae9SGregory Neil Shapiro if (fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp) <= 0) 32906f25ae9SGregory Neil Shapiro { 33006f25ae9SGregory Neil Shapiro /* write failed */ 33140266059SGregory Neil Shapiro (void) mlfi_cleanup(ctx, false); 33206f25ae9SGregory Neil Shapiro return SMFIS_TEMPFAIL; 33306f25ae9SGregory Neil Shapiro } 33406f25ae9SGregory Neil Shapiro 33506f25ae9SGregory Neil Shapiro /* continue processing */ 33606f25ae9SGregory Neil Shapiro return SMFIS_CONTINUE; 33706f25ae9SGregory Neil Shapiro} 33806f25ae9SGregory Neil Shapiro 33906f25ae9SGregory Neil Shapirosfsistat 34006f25ae9SGregory Neil Shapiromlfi_eom(ctx) 34106f25ae9SGregory Neil Shapiro SMFICTX *ctx; 34206f25ae9SGregory Neil Shapiro{ 34340266059SGregory Neil Shapiro return mlfi_cleanup(ctx, true); 34406f25ae9SGregory Neil Shapiro} 34506f25ae9SGregory Neil Shapiro 34606f25ae9SGregory Neil Shapirosfsistat 34706f25ae9SGregory Neil Shapiromlfi_close(ctx) 34806f25ae9SGregory Neil Shapiro SMFICTX *ctx; 34906f25ae9SGregory Neil Shapiro{ 35006f25ae9SGregory Neil Shapiro return SMFIS_ACCEPT; 35106f25ae9SGregory Neil Shapiro} 35206f25ae9SGregory Neil Shapiro 35306f25ae9SGregory Neil Shapirosfsistat 35406f25ae9SGregory Neil Shapiromlfi_abort(ctx) 35506f25ae9SGregory Neil Shapiro SMFICTX *ctx; 35606f25ae9SGregory Neil Shapiro{ 35740266059SGregory Neil Shapiro return mlfi_cleanup(ctx, false); 35806f25ae9SGregory Neil Shapiro} 35906f25ae9SGregory Neil Shapiro 36006f25ae9SGregory Neil Shapirosfsistat 36106f25ae9SGregory Neil Shapiromlfi_cleanup(ctx, ok) 36206f25ae9SGregory Neil Shapiro SMFICTX *ctx; 36306f25ae9SGregory Neil Shapiro bool ok; 36406f25ae9SGregory Neil Shapiro{ 36506f25ae9SGregory Neil Shapiro sfsistat rstat = SMFIS_CONTINUE; 36606f25ae9SGregory Neil Shapiro struct mlfiPriv *priv = MLFIPRIV; 36706f25ae9SGregory Neil Shapiro char *p; 36806f25ae9SGregory Neil Shapiro char host[512]; 36906f25ae9SGregory Neil Shapiro char hbuf[1024]; 37006f25ae9SGregory Neil Shapiro 37106f25ae9SGregory Neil Shapiro if (priv == NULL) 37206f25ae9SGregory Neil Shapiro return rstat; 37306f25ae9SGregory Neil Shapiro 37406f25ae9SGregory Neil Shapiro /* close the archive file */ 37506f25ae9SGregory Neil Shapiro if (priv->mlfi_fp != NULL && fclose(priv->mlfi_fp) == EOF) 37606f25ae9SGregory Neil Shapiro { 37706f25ae9SGregory Neil Shapiro /* failed; we have to wait until later */ 37806f25ae9SGregory Neil Shapiro rstat = SMFIS_TEMPFAIL; 37906f25ae9SGregory Neil Shapiro (void) unlink(priv->mlfi_fname); 38006f25ae9SGregory Neil Shapiro } 38106f25ae9SGregory Neil Shapiro else if (ok) 38206f25ae9SGregory Neil Shapiro { 38306f25ae9SGregory Neil Shapiro /* add a header to the message announcing our presence */ 38406f25ae9SGregory Neil Shapiro if (gethostname(host, sizeof host) < 0) 38540266059SGregory Neil Shapiro snprintf(host, sizeof host, "localhost"); 38606f25ae9SGregory Neil Shapiro p = strrchr(priv->mlfi_fname, '/'); 38706f25ae9SGregory Neil Shapiro if (p == NULL) 38806f25ae9SGregory Neil Shapiro p = priv->mlfi_fname; 38906f25ae9SGregory Neil Shapiro else 39006f25ae9SGregory Neil Shapiro p++; 39106f25ae9SGregory Neil Shapiro snprintf(hbuf, sizeof hbuf, "%s@%s", p, host); 39206f25ae9SGregory Neil Shapiro smfi_addheader(ctx, "X-Archived", hbuf); 39306f25ae9SGregory Neil Shapiro } 39406f25ae9SGregory Neil Shapiro else 39506f25ae9SGregory Neil Shapiro { 39606f25ae9SGregory Neil Shapiro /* message was aborted -- delete the archive file */ 39706f25ae9SGregory Neil Shapiro (void) unlink(priv->mlfi_fname); 39806f25ae9SGregory Neil Shapiro } 39906f25ae9SGregory Neil Shapiro 40006f25ae9SGregory Neil Shapiro /* release private memory */ 40106f25ae9SGregory Neil Shapiro free(priv->mlfi_fname); 40206f25ae9SGregory Neil Shapiro free(priv); 40306f25ae9SGregory Neil Shapiro smfi_setpriv(ctx, NULL); 40406f25ae9SGregory Neil Shapiro 40506f25ae9SGregory Neil Shapiro /* return status */ 40606f25ae9SGregory Neil Shapiro return rstat; 40706f25ae9SGregory Neil Shapiro} 40806f25ae9SGregory Neil Shapiro 40906f25ae9SGregory Neil Shapirostruct smfiDesc smfilter = 41006f25ae9SGregory Neil Shapiro{ 41106f25ae9SGregory Neil Shapiro "SampleFilter", /* filter name */ 41206f25ae9SGregory Neil Shapiro SMFI_VERSION, /* version code -- do not change */ 41306f25ae9SGregory Neil Shapiro SMFIF_ADDHDRS, /* flags */ 41406f25ae9SGregory Neil Shapiro NULL, /* connection info filter */ 41506f25ae9SGregory Neil Shapiro NULL, /* SMTP HELO command filter */ 41606f25ae9SGregory Neil Shapiro mlfi_envfrom, /* envelope sender filter */ 41706f25ae9SGregory Neil Shapiro NULL, /* envelope recipient filter */ 41806f25ae9SGregory Neil Shapiro mlfi_header, /* header filter */ 41906f25ae9SGregory Neil Shapiro mlfi_eoh, /* end of header */ 42006f25ae9SGregory Neil Shapiro mlfi_body, /* body block filter */ 42106f25ae9SGregory Neil Shapiro mlfi_eom, /* end of message */ 42206f25ae9SGregory Neil Shapiro mlfi_abort, /* message aborted */ 42306f25ae9SGregory Neil Shapiro mlfi_close /* connection cleanup */ 42406f25ae9SGregory Neil Shapiro}; 42506f25ae9SGregory Neil Shapiro 42606f25ae9SGregory Neil Shapiro 42706f25ae9SGregory Neil Shapiroint 42806f25ae9SGregory Neil Shapiromain(argc, argv) 42906f25ae9SGregory Neil Shapiro int argc; 43006f25ae9SGregory Neil Shapiro char *argv[]; 43106f25ae9SGregory Neil Shapiro{ 432a7ec597cSGregory Neil Shapiro bool setconn = false; 43306f25ae9SGregory Neil Shapiro int c; 43406f25ae9SGregory Neil Shapiro const char *args = "p:"; 43506f25ae9SGregory Neil Shapiro 43606f25ae9SGregory Neil Shapiro /* Process command line options */ 43706f25ae9SGregory Neil Shapiro while ((c = getopt(argc, argv, args)) != -1) 43806f25ae9SGregory Neil Shapiro { 43906f25ae9SGregory Neil Shapiro switch (c) 44006f25ae9SGregory Neil Shapiro { 44106f25ae9SGregory Neil Shapiro case 'p': 44206f25ae9SGregory Neil Shapiro if (optarg == NULL || *optarg == '\0') 44306f25ae9SGregory Neil Shapiro { 44406f25ae9SGregory Neil Shapiro (void) fprintf(stderr, "Illegal conn: %s\n", 44506f25ae9SGregory Neil Shapiro optarg); 44606f25ae9SGregory Neil Shapiro exit(EX_USAGE); 44706f25ae9SGregory Neil Shapiro } 44806f25ae9SGregory Neil Shapiro (void) smfi_setconn(optarg); 449a7ec597cSGregory Neil Shapiro setconn = true; 45006f25ae9SGregory Neil Shapiro break; 45106f25ae9SGregory Neil Shapiro 45206f25ae9SGregory Neil Shapiro } 45306f25ae9SGregory Neil Shapiro } 454a7ec597cSGregory Neil Shapiro if (!setconn) 455a7ec597cSGregory Neil Shapiro { 456a7ec597cSGregory Neil Shapiro fprintf(stderr, "%s: Missing required -p argument\n", argv[0]); 457a7ec597cSGregory Neil Shapiro exit(EX_USAGE); 458a7ec597cSGregory Neil Shapiro } 45906f25ae9SGregory Neil Shapiro if (smfi_register(smfilter) == MI_FAILURE) 46006f25ae9SGregory Neil Shapiro { 46106f25ae9SGregory Neil Shapiro fprintf(stderr, "smfi_register failed\n"); 46206f25ae9SGregory Neil Shapiro exit(EX_UNAVAILABLE); 46306f25ae9SGregory Neil Shapiro } 46406f25ae9SGregory Neil Shapiro return smfi_main(); 46506f25ae9SGregory Neil Shapiro} 46606f25ae9SGregory Neil Shapiro 46706f25ae9SGregory Neil Shapiro/* eof */ 46806f25ae9SGregory Neil Shapiro 469e92d3f3fSGregory Neil Shapiro$Revision: 8.40 $, Last updated $Date: 2003/12/11 18:14:34 $ 470