xref: /freebsd/contrib/sendmail/libmilter/README (revision 13058a916175518dfbac6ce66b9b8e22ecf43155)
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
1206f25ae9SGregory Neil ShapiroNOTE: Both libmilter and the callouts in sendmail are marked as an FFR (For
138774250cSGregory Neil ShapiroFuture Release).  If you intend to use them in 8.11.X, you must compiled
1406f25ae9SGregory Neil Shapiroboth libmilter and sendmail with -D_FFR_MILTER defined.  You can do this by
1506f25ae9SGregory Neil Shapiroadding the following to your devtools/Site/site.config.m4 file:
1606f25ae9SGregory Neil Shapiro
1706f25ae9SGregory Neil Shapiro	dnl Milter
1806f25ae9SGregory Neil Shapiro	APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_MILTER=1')
1906f25ae9SGregory Neil Shapiro	APPENDDEF(`conf_libmilter_ENVDEF', `-D_FFR_MILTER=1')
2006f25ae9SGregory Neil Shapiro
2106f25ae9SGregory Neil ShapiroYou will also need to define _FFR_MILTER when building your .cf file using
2206f25ae9SGregory Neil Shapirom4.
2306f25ae9SGregory Neil Shapiro
2406f25ae9SGregory Neil Shapiro+-------------------+
2506f25ae9SGregory Neil Shapiro| BUILDING A FILTER |
2606f25ae9SGregory Neil Shapiro+-------------------+
2706f25ae9SGregory Neil Shapiro
2806f25ae9SGregory Neil ShapiroThe following command presumes that the sample code from the end of this
2906f25ae9SGregory Neil ShapiroREADME is saved to a file named 'sample.c' and built in the local platform-
3006f25ae9SGregory Neil Shapirospecific build subdirectory (SRCDIR/obj.*/libmilter).
3106f25ae9SGregory Neil Shapiro
3206f25ae9SGregory Neil Shapiro	cc -I../../sendmail -I../../include -o sample sample.c libmilter.a ../libsmutil/libsmutil.a -pthread
3306f25ae9SGregory Neil Shapiro
3406f25ae9SGregory Neil ShapiroIt is recommended that you build your filters in a location outside of
3506f25ae9SGregory Neil Shapirothe sendmail source tree.  Modify the compiler include references (-I)
3606f25ae9SGregory Neil Shapiroand the library locations accordingly.  Also, some operating systems may
3706f25ae9SGregory Neil Shapirorequire additional libraries.  For example, SunOS 5.X requires '-lresolv
3806f25ae9SGregory Neil Shapiro-lsocket -lnsl'.  Depending on your OS you may need a library instead
3906f25ae9SGregory Neil Shapiroof the option -pthread, e.g., -lpthread.
4006f25ae9SGregory Neil Shapiro
4106f25ae9SGregory Neil ShapiroFilters must be thread-safe!  Many operating systems now provide support for
4206f25ae9SGregory Neil ShapiroPOSIX threads in the standard C libraries.  The compiler flag to link with
4306f25ae9SGregory Neil Shapirothreading support differs according to the compiler and linker used.  Check
4406f25ae9SGregory Neil Shapirothe Makefile in your appropriate obj.*/libmilter build subdirectory if you
4506f25ae9SGregory Neil Shapiroare unsure of the local flag used.
4606f25ae9SGregory Neil Shapiro
47602a2b1bSGregory Neil ShapiroNote that since filters use threads, it may be necessary to alter per
48602a2b1bSGregory Neil Shapiroprocess limits in your filter.  For example, you might look at using
49602a2b1bSGregory Neil Shapirosetrlimit() to increase the number of open file descriptors if your filter
50602a2b1bSGregory Neil Shapirois going to be busy.
51602a2b1bSGregory Neil Shapiro
5206f25ae9SGregory Neil Shapiro
5306f25ae9SGregory Neil Shapiro+----------------------------------------+
5406f25ae9SGregory Neil Shapiro| SPECIFYING FILTERS IN SENDMAIL CONFIGS |
5506f25ae9SGregory Neil Shapiro+----------------------------------------+
5606f25ae9SGregory Neil Shapiro
5706f25ae9SGregory Neil ShapiroFilters are specified with a key letter ``X'' (for ``eXternal'').
5806f25ae9SGregory Neil Shapiro
5906f25ae9SGregory Neil ShapiroFor example:
6006f25ae9SGregory Neil Shapiro
6106f25ae9SGregory Neil Shapiro	Xfilter1, S=local:/var/run/f1.sock, F=R
6213058a91SGregory Neil Shapiro	Xfilter2, S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m
6306f25ae9SGregory Neil Shapiro	Xfilter3, S=inet:3333@localhost
6406f25ae9SGregory Neil Shapiro
6506f25ae9SGregory Neil Shapirospecifies three filters.  Filters can be specified in your .mc file using
6606f25ae9SGregory Neil Shapirothe following:
6706f25ae9SGregory Neil Shapiro
6806f25ae9SGregory Neil Shapiro	INPUT_MAIL_FILTER(`filter1', `S=local:/var/run/f1.sock, F=R')
6913058a91SGregory Neil Shapiro	INPUT_MAIL_FILTER(`filter2', `S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m')
7006f25ae9SGregory Neil Shapiro	INPUT_MAIL_FILTER(`filter3', `S=inet:3333@localhost')
7106f25ae9SGregory Neil Shapiro
7206f25ae9SGregory Neil ShapiroThe first attaches to a Unix-domain socket in the /var/run directory; the
7306f25ae9SGregory Neil Shapirosecond uses an IPv6 socket on port 999 of localhost, and the third uses an
7406f25ae9SGregory Neil ShapiroIPv4 socket on port 3333 of localhost.  The current flags (F=) are:
7506f25ae9SGregory Neil Shapiro
7606f25ae9SGregory Neil Shapiro	R		Reject connection if filter unavailable
7706f25ae9SGregory Neil Shapiro	T		Temporary fail connection if filter unavailable
7806f25ae9SGregory Neil Shapiro
7942e5d165SGregory Neil ShapiroIf neither F=R nor F=T is specified, the message is passed through sendmail
8042e5d165SGregory Neil Shapiroas if the filter were not present.
8142e5d165SGregory Neil Shapiro
8206f25ae9SGregory Neil ShapiroFinally, you can override the default timeouts used by sendmail when
8313058a91SGregory Neil Shapirotalking to the filters using the T= equate.  There are four fields inside
8406f25ae9SGregory Neil Shapiroof the T= equate:
8506f25ae9SGregory Neil Shapiro
8606f25ae9SGregory Neil ShapiroLetter          Meaning
8713058a91SGregory Neil Shapiro  C		Timeout for connecting to a filter (if 0, use system timeout)
8806f25ae9SGregory Neil Shapiro  S		Timeout for sending information from the MTA to a filter
8906f25ae9SGregory Neil Shapiro  R		Timeout for reading reply from the filter
9006f25ae9SGregory Neil Shapiro  E		Overall timeout between sending end-of-message to filter
9106f25ae9SGregory Neil Shapiro		and waiting for the final acknowledgment
9206f25ae9SGregory Neil Shapiro
9306f25ae9SGregory Neil ShapiroNote the separator between each is a ';' as a ',' already separates equates
9413058a91SGregory Neil Shapiroand therefore can't separate timeouts.  The default values (if not set in
9513058a91SGregory Neil Shapirothe config) are:
9606f25ae9SGregory Neil Shapiro
9713058a91SGregory Neil ShapiroT=C:0m;S:10s;R:10s;E:5m
9806f25ae9SGregory Neil Shapiro
9906f25ae9SGregory Neil Shapirowhere 's' is seconds and 'm' is minutes.
10006f25ae9SGregory Neil Shapiro
10142e5d165SGregory Neil ShapiroWhich filters are invoked and their sequencing is handled by the
1028774250cSGregory Neil ShapiroInputMailFilters option. Note: if InputMailFilters is not defined no filters
1038774250cSGregory Neil Shapirowill be used.
10442e5d165SGregory Neil Shapiro
10542e5d165SGregory Neil Shapiro	O InputMailFilters=filter1, filter2, filter3
10642e5d165SGregory Neil Shapiro
10742e5d165SGregory Neil ShapiroThis is is set automatically according to the order of the
10842e5d165SGregory Neil ShapiroINPUT_MAIL_FILTER commands in your .mc file.  Alternatively, you can
10942e5d165SGregory Neil Shapiroreset its value by setting confINPUT_MAIL_FILTERS in your .mc file.
11042e5d165SGregory Neil ShapiroThis options causes the three filters to be called in the same order
11142e5d165SGregory Neil Shapirothey were specified.  It allows for possible future filtering on output
11242e5d165SGregory Neil Shapiro(although this is not intended for this release).
11306f25ae9SGregory Neil Shapiro
11406f25ae9SGregory Neil ShapiroAlso note that a filter can be defined without adding it to the input
11506f25ae9SGregory Neil Shapirofilter list by using MAIL_FILTER() instead of INPUT_MAIL_FILTER() in your
11606f25ae9SGregory Neil Shapiro.mc file.
11706f25ae9SGregory Neil Shapiro
11806f25ae9SGregory Neil ShapiroTo test sendmail with the sample filter, the following might be added (in
11906f25ae9SGregory Neil Shapirothe appropriate locations) to your .mc file:
12006f25ae9SGregory Neil Shapiro
12106f25ae9SGregory Neil Shapiro	INPUT_MAIL_FILTER(`sample', `S=local:/var/run/f1.sock')
12206f25ae9SGregory Neil Shapiro
12306f25ae9SGregory Neil Shapiro
12406f25ae9SGregory Neil Shapiro+------------------+
12506f25ae9SGregory Neil Shapiro| TESTING A FILTER |
12606f25ae9SGregory Neil Shapiro+------------------+
12706f25ae9SGregory Neil Shapiro
12806f25ae9SGregory Neil ShapiroOnce you have compiled a filter, modified your .mc file and restarted
12906f25ae9SGregory Neil Shapirothe sendmail process, you will want to test that the filter performs as
13006f25ae9SGregory Neil Shapirointended.
13106f25ae9SGregory Neil Shapiro
13206f25ae9SGregory Neil ShapiroThe sample filter takes one argument -p, which indicates the local port
13306f25ae9SGregory Neil Shapiroon which to create a listening socket for the filter.  Maintaining
13406f25ae9SGregory Neil Shapiroconsistency with the suggested options for sendmail.cf, this would be the
13506f25ae9SGregory Neil ShapiroUNIX domain socket located in /var/run/f1.sock.
13606f25ae9SGregory Neil Shapiro
13706f25ae9SGregory Neil Shapiro	% ./sample -p local:/var/run/f1.sock
13806f25ae9SGregory Neil Shapiro
13906f25ae9SGregory Neil ShapiroIf the sample filter returns immediately to a command line, there was either
14006f25ae9SGregory Neil Shapiroan error with your command or a problem creating the specified socket.
14106f25ae9SGregory Neil ShapiroFurther logging can be captured through the syslogd daemon.  Using the
14206f25ae9SGregory Neil Shapiro'netstat -a' command can ensure that your filter process is listening on
14306f25ae9SGregory Neil Shapirothe appropriate local socket.
14406f25ae9SGregory Neil Shapiro
14506f25ae9SGregory Neil ShapiroEmail messages must be injected via SMTP to be filtered.  There are two
14606f25ae9SGregory Neil Shapirosimple means of doing this; either using the 'sendmail -bs' command, or
14706f25ae9SGregory Neil Shapiroby telnetting to port 25 of the machine configured for milter.  Once
14806f25ae9SGregory Neil Shapiroconnected via one of these options, the session can be continued through
14906f25ae9SGregory Neil Shapirothe use of standard SMTP commands.
15006f25ae9SGregory Neil Shapiro
15106f25ae9SGregory Neil Shapiro% sendmail -bs
15242e5d165SGregory Neil Shapiro220 test.sendmail.com ESMTP Sendmail 8.11.0/8.11.0; Tue, 10 Nov 1970 13:05:23 -0500 (EST)
15306f25ae9SGregory Neil ShapiroHELO localhost
15406f25ae9SGregory Neil Shapiro250 test.sendmail.com Hello testy@localhost, pleased to meet you
15506f25ae9SGregory Neil ShapiroMAIL From:<testy>
15606f25ae9SGregory Neil Shapiro250 2.1.0 <testy>... Sender ok
15706f25ae9SGregory Neil ShapiroRCPT To:<root>
15806f25ae9SGregory Neil Shapiro250 2.1.5 <root>... Recipient ok
15906f25ae9SGregory Neil ShapiroDATA
16006f25ae9SGregory Neil Shapiro354 Enter mail, end with "." on a line by itself
16106f25ae9SGregory Neil ShapiroFrom: testy@test.sendmail.com
16206f25ae9SGregory Neil ShapiroTo: root@test.sendmail.com
16306f25ae9SGregory Neil ShapiroSubject: testing sample filter
16406f25ae9SGregory Neil Shapiro
16506f25ae9SGregory Neil ShapiroSample body
16606f25ae9SGregory Neil Shapiro.
16706f25ae9SGregory Neil Shapiro250 2.0.0 dB73Zxi25236 Message accepted for delivery
16806f25ae9SGregory Neil ShapiroQUIT
16906f25ae9SGregory Neil Shapiro221 2.0.0 test.sendmail.com closing connection
17006f25ae9SGregory Neil Shapiro
17106f25ae9SGregory Neil ShapiroIn the above example, the lines beginning with numbers are output by the
17206f25ae9SGregory Neil Shapiromail server, and those without are your input.  If everything is working
17306f25ae9SGregory Neil Shapiroproperly, you will find a file in /tmp by the name of msg.XXXXXXXX (where
17406f25ae9SGregory Neil Shapirothe Xs represent any combination of letters and numbers).  This file should
17506f25ae9SGregory Neil Shapirocontain the message body and headers from the test email entered above.
17606f25ae9SGregory Neil Shapiro
17706f25ae9SGregory Neil ShapiroIf the sample filter did not log your test email, there are a number of
17806f25ae9SGregory Neil Shapiromethods to narrow down the source of the problem.  Check your system
17906f25ae9SGregory Neil Shapirologs written by syslogd and see if there are any pertinent lines.  You
18006f25ae9SGregory Neil Shapiromay need to reconfigure syslogd to capture all relevant data.  Additionally,
18106f25ae9SGregory Neil Shapirothe logging level of sendmail can be raised with the LogLevel option.
18206f25ae9SGregory Neil ShapiroSee the sendmail(8) manual page for more information.
18306f25ae9SGregory Neil Shapiro
18406f25ae9SGregory Neil Shapiro
18506f25ae9SGregory Neil Shapiro+--------------------------+
18606f25ae9SGregory Neil Shapiro| SOURCE FOR SAMPLE FILTER |
18706f25ae9SGregory Neil Shapiro+--------------------------+
18806f25ae9SGregory Neil Shapiro
189193538b7SGregory Neil ShapiroNote that the filter below may not be thread safe on some operating
190193538b7SGregory Neil Shapirosystems.  You should check your system man pages for the functions used
191193538b7SGregory Neil Shapirobelow to verify the functions are thread safe.
192193538b7SGregory Neil Shapiro
19306f25ae9SGregory Neil Shapiro/* A trivial filter that logs all email to a file. */
19406f25ae9SGregory Neil Shapiro
19506f25ae9SGregory Neil Shapiro#include <sys/types.h>
19606f25ae9SGregory Neil Shapiro#include <stdio.h>
19706f25ae9SGregory Neil Shapiro#include <stdlib.h>
19806f25ae9SGregory Neil Shapiro#include <string.h>
19906f25ae9SGregory Neil Shapiro#include <sysexits.h>
20006f25ae9SGregory Neil Shapiro#include <unistd.h>
20106f25ae9SGregory Neil Shapiro
20206f25ae9SGregory Neil Shapiro#include "libmilter/mfapi.h"
20306f25ae9SGregory Neil Shapiro
20406f25ae9SGregory Neil Shapirotypedef int bool;
20506f25ae9SGregory Neil Shapiro
20606f25ae9SGregory Neil Shapiro#ifndef FALSE
20706f25ae9SGregory Neil Shapiro# define FALSE	0
20806f25ae9SGregory Neil Shapiro#endif /* ! FALSE*/
20906f25ae9SGregory Neil Shapiro#ifndef TRUE
21006f25ae9SGregory Neil Shapiro# define TRUE	1
21106f25ae9SGregory Neil Shapiro#endif /* ! TRUE*/
21206f25ae9SGregory Neil Shapiro
21306f25ae9SGregory Neil Shapirostruct mlfiPriv
21406f25ae9SGregory Neil Shapiro{
21506f25ae9SGregory Neil Shapiro	char	*mlfi_fname;
21606f25ae9SGregory Neil Shapiro	FILE	*mlfi_fp;
21706f25ae9SGregory Neil Shapiro};
21806f25ae9SGregory Neil Shapiro
21906f25ae9SGregory Neil Shapiro#define MLFIPRIV	((struct mlfiPriv *) smfi_getpriv(ctx))
22006f25ae9SGregory Neil Shapiro
22106f25ae9SGregory Neil Shapiroextern sfsistat	 mlfi_cleanup(SMFICTX *, bool);
22206f25ae9SGregory Neil Shapiro
22306f25ae9SGregory Neil Shapirosfsistat
22406f25ae9SGregory Neil Shapiromlfi_envfrom(ctx, envfrom)
22506f25ae9SGregory Neil Shapiro	SMFICTX *ctx;
22606f25ae9SGregory Neil Shapiro	char **envfrom;
22706f25ae9SGregory Neil Shapiro{
22806f25ae9SGregory Neil Shapiro	struct mlfiPriv *priv;
2298774250cSGregory Neil Shapiro	int fd = -1;
23006f25ae9SGregory Neil Shapiro
23106f25ae9SGregory Neil Shapiro	/* allocate some private memory */
23206f25ae9SGregory Neil Shapiro	priv = malloc(sizeof *priv);
23306f25ae9SGregory Neil Shapiro	if (priv == NULL)
23406f25ae9SGregory Neil Shapiro	{
23506f25ae9SGregory Neil Shapiro		/* can't accept this message right now */
23606f25ae9SGregory Neil Shapiro		return SMFIS_TEMPFAIL;
23706f25ae9SGregory Neil Shapiro	}
23806f25ae9SGregory Neil Shapiro	memset(priv, '\0', sizeof *priv);
23906f25ae9SGregory Neil Shapiro
24006f25ae9SGregory Neil Shapiro	/* open a file to store this message */
24106f25ae9SGregory Neil Shapiro	priv->mlfi_fname = strdup("/tmp/msg.XXXXXXXX");
24206f25ae9SGregory Neil Shapiro	if (priv->mlfi_fname == NULL)
24306f25ae9SGregory Neil Shapiro	{
24406f25ae9SGregory Neil Shapiro		free(priv);
24506f25ae9SGregory Neil Shapiro		return SMFIS_TEMPFAIL;
24606f25ae9SGregory Neil Shapiro	}
24706f25ae9SGregory Neil Shapiro	if ((fd = mkstemp(priv->mlfi_fname)) < 0 ||
24806f25ae9SGregory Neil Shapiro	    (priv->mlfi_fp = fdopen(fd, "w+")) == NULL)
24906f25ae9SGregory Neil Shapiro	{
2508774250cSGregory Neil Shapiro		if (fd >= 0)
2518774250cSGregory Neil Shapiro			(void) close(fd);
25206f25ae9SGregory Neil Shapiro		free(priv->mlfi_fname);
25306f25ae9SGregory Neil Shapiro		free(priv);
25406f25ae9SGregory Neil Shapiro		return SMFIS_TEMPFAIL;
25506f25ae9SGregory Neil Shapiro	}
25606f25ae9SGregory Neil Shapiro
25706f25ae9SGregory Neil Shapiro	/* save the private data */
25806f25ae9SGregory Neil Shapiro	smfi_setpriv(ctx, priv);
25906f25ae9SGregory Neil Shapiro
26006f25ae9SGregory Neil Shapiro	/* continue processing */
26106f25ae9SGregory Neil Shapiro	return SMFIS_CONTINUE;
26206f25ae9SGregory Neil Shapiro}
26306f25ae9SGregory Neil Shapiro
26406f25ae9SGregory Neil Shapirosfsistat
26506f25ae9SGregory Neil Shapiromlfi_header(ctx, headerf, headerv)
26606f25ae9SGregory Neil Shapiro	SMFICTX *ctx;
26706f25ae9SGregory Neil Shapiro	char *headerf;
26806f25ae9SGregory Neil Shapiro	char *headerv;
26906f25ae9SGregory Neil Shapiro{
27006f25ae9SGregory Neil Shapiro	/* write the header to the log file */
27106f25ae9SGregory Neil Shapiro	fprintf(MLFIPRIV->mlfi_fp, "%s: %s\r\n", headerf, headerv);
27206f25ae9SGregory Neil Shapiro
27306f25ae9SGregory Neil Shapiro	/* continue processing */
27406f25ae9SGregory Neil Shapiro	return SMFIS_CONTINUE;
27506f25ae9SGregory Neil Shapiro}
27606f25ae9SGregory Neil Shapiro
27706f25ae9SGregory Neil Shapirosfsistat
27806f25ae9SGregory Neil Shapiromlfi_eoh(ctx)
27906f25ae9SGregory Neil Shapiro	SMFICTX *ctx;
28006f25ae9SGregory Neil Shapiro{
28106f25ae9SGregory Neil Shapiro	/* output the blank line between the header and the body */
28206f25ae9SGregory Neil Shapiro	fprintf(MLFIPRIV->mlfi_fp, "\r\n");
28306f25ae9SGregory Neil Shapiro
28406f25ae9SGregory Neil Shapiro	/* continue processing */
28506f25ae9SGregory Neil Shapiro	return SMFIS_CONTINUE;
28606f25ae9SGregory Neil Shapiro}
28706f25ae9SGregory Neil Shapiro
28806f25ae9SGregory Neil Shapirosfsistat
28906f25ae9SGregory Neil Shapiromlfi_body(ctx, bodyp, bodylen)
29006f25ae9SGregory Neil Shapiro	SMFICTX *ctx;
29106f25ae9SGregory Neil Shapiro	u_char *bodyp;
29206f25ae9SGregory Neil Shapiro	size_t bodylen;
29306f25ae9SGregory Neil Shapiro{
29406f25ae9SGregory Neil Shapiro	/* output body block to log file */
29506f25ae9SGregory Neil Shapiro	if (fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp) <= 0)
29606f25ae9SGregory Neil Shapiro	{
29706f25ae9SGregory Neil Shapiro		/* write failed */
29806f25ae9SGregory Neil Shapiro		(void) mlfi_cleanup(ctx, FALSE);
29906f25ae9SGregory Neil Shapiro		return SMFIS_TEMPFAIL;
30006f25ae9SGregory Neil Shapiro	}
30106f25ae9SGregory Neil Shapiro
30206f25ae9SGregory Neil Shapiro	/* continue processing */
30306f25ae9SGregory Neil Shapiro	return SMFIS_CONTINUE;
30406f25ae9SGregory Neil Shapiro}
30506f25ae9SGregory Neil Shapiro
30606f25ae9SGregory Neil Shapirosfsistat
30706f25ae9SGregory Neil Shapiromlfi_eom(ctx)
30806f25ae9SGregory Neil Shapiro	SMFICTX *ctx;
30906f25ae9SGregory Neil Shapiro{
31006f25ae9SGregory Neil Shapiro	return mlfi_cleanup(ctx, TRUE);
31106f25ae9SGregory Neil Shapiro}
31206f25ae9SGregory Neil Shapiro
31306f25ae9SGregory Neil Shapirosfsistat
31406f25ae9SGregory Neil Shapiromlfi_close(ctx)
31506f25ae9SGregory Neil Shapiro	SMFICTX *ctx;
31606f25ae9SGregory Neil Shapiro{
31706f25ae9SGregory Neil Shapiro	return SMFIS_ACCEPT;
31806f25ae9SGregory Neil Shapiro}
31906f25ae9SGregory Neil Shapiro
32006f25ae9SGregory Neil Shapirosfsistat
32106f25ae9SGregory Neil Shapiromlfi_abort(ctx)
32206f25ae9SGregory Neil Shapiro	SMFICTX *ctx;
32306f25ae9SGregory Neil Shapiro{
32406f25ae9SGregory Neil Shapiro	return mlfi_cleanup(ctx, FALSE);
32506f25ae9SGregory Neil Shapiro}
32606f25ae9SGregory Neil Shapiro
32706f25ae9SGregory Neil Shapirosfsistat
32806f25ae9SGregory Neil Shapiromlfi_cleanup(ctx, ok)
32906f25ae9SGregory Neil Shapiro	SMFICTX *ctx;
33006f25ae9SGregory Neil Shapiro	bool ok;
33106f25ae9SGregory Neil Shapiro{
33206f25ae9SGregory Neil Shapiro	sfsistat rstat = SMFIS_CONTINUE;
33306f25ae9SGregory Neil Shapiro	struct mlfiPriv *priv = MLFIPRIV;
33406f25ae9SGregory Neil Shapiro	char *p;
33506f25ae9SGregory Neil Shapiro	char host[512];
33606f25ae9SGregory Neil Shapiro	char hbuf[1024];
33706f25ae9SGregory Neil Shapiro
33806f25ae9SGregory Neil Shapiro	if (priv == NULL)
33906f25ae9SGregory Neil Shapiro		return rstat;
34006f25ae9SGregory Neil Shapiro
34106f25ae9SGregory Neil Shapiro	/* close the archive file */
34206f25ae9SGregory Neil Shapiro	if (priv->mlfi_fp != NULL && fclose(priv->mlfi_fp) == EOF)
34306f25ae9SGregory Neil Shapiro	{
34406f25ae9SGregory Neil Shapiro		/* failed; we have to wait until later */
34506f25ae9SGregory Neil Shapiro		rstat = SMFIS_TEMPFAIL;
34606f25ae9SGregory Neil Shapiro		(void) unlink(priv->mlfi_fname);
34706f25ae9SGregory Neil Shapiro	}
34806f25ae9SGregory Neil Shapiro	else if (ok)
34906f25ae9SGregory Neil Shapiro	{
35006f25ae9SGregory Neil Shapiro		/* add a header to the message announcing our presence */
35106f25ae9SGregory Neil Shapiro		if (gethostname(host, sizeof host) < 0)
35206f25ae9SGregory Neil Shapiro			strlcpy(host, "localhost", sizeof host);
35306f25ae9SGregory Neil Shapiro		p = strrchr(priv->mlfi_fname, '/');
35406f25ae9SGregory Neil Shapiro		if (p == NULL)
35506f25ae9SGregory Neil Shapiro			p = priv->mlfi_fname;
35606f25ae9SGregory Neil Shapiro		else
35706f25ae9SGregory Neil Shapiro			p++;
35806f25ae9SGregory Neil Shapiro		snprintf(hbuf, sizeof hbuf, "%s@%s", p, host);
35906f25ae9SGregory Neil Shapiro		smfi_addheader(ctx, "X-Archived", hbuf);
36006f25ae9SGregory Neil Shapiro	}
36106f25ae9SGregory Neil Shapiro	else
36206f25ae9SGregory Neil Shapiro	{
36306f25ae9SGregory Neil Shapiro		/* message was aborted -- delete the archive file */
36406f25ae9SGregory Neil Shapiro		(void) unlink(priv->mlfi_fname);
36506f25ae9SGregory Neil Shapiro	}
36606f25ae9SGregory Neil Shapiro
36706f25ae9SGregory Neil Shapiro	/* release private memory */
36806f25ae9SGregory Neil Shapiro	free(priv->mlfi_fname);
36906f25ae9SGregory Neil Shapiro	free(priv);
37006f25ae9SGregory Neil Shapiro	smfi_setpriv(ctx, NULL);
37106f25ae9SGregory Neil Shapiro
37206f25ae9SGregory Neil Shapiro	/* return status */
37306f25ae9SGregory Neil Shapiro	return rstat;
37406f25ae9SGregory Neil Shapiro}
37506f25ae9SGregory Neil Shapiro
37606f25ae9SGregory Neil Shapirostruct smfiDesc smfilter =
37706f25ae9SGregory Neil Shapiro{
37806f25ae9SGregory Neil Shapiro	"SampleFilter",	/* filter name */
37906f25ae9SGregory Neil Shapiro	SMFI_VERSION,	/* version code -- do not change */
38006f25ae9SGregory Neil Shapiro	SMFIF_ADDHDRS,	/* flags */
38106f25ae9SGregory Neil Shapiro	NULL,		/* connection info filter */
38206f25ae9SGregory Neil Shapiro	NULL,		/* SMTP HELO command filter */
38306f25ae9SGregory Neil Shapiro	mlfi_envfrom,	/* envelope sender filter */
38406f25ae9SGregory Neil Shapiro	NULL,		/* envelope recipient filter */
38506f25ae9SGregory Neil Shapiro	mlfi_header,	/* header filter */
38606f25ae9SGregory Neil Shapiro	mlfi_eoh,	/* end of header */
38706f25ae9SGregory Neil Shapiro	mlfi_body,	/* body block filter */
38806f25ae9SGregory Neil Shapiro	mlfi_eom,	/* end of message */
38906f25ae9SGregory Neil Shapiro	mlfi_abort,	/* message aborted */
39006f25ae9SGregory Neil Shapiro	mlfi_close	/* connection cleanup */
39106f25ae9SGregory Neil Shapiro};
39206f25ae9SGregory Neil Shapiro
39306f25ae9SGregory Neil Shapiro
39406f25ae9SGregory Neil Shapiroint
39506f25ae9SGregory Neil Shapiromain(argc, argv)
39606f25ae9SGregory Neil Shapiro	int argc;
39706f25ae9SGregory Neil Shapiro	char *argv[];
39806f25ae9SGregory Neil Shapiro{
39906f25ae9SGregory Neil Shapiro	int c;
40006f25ae9SGregory Neil Shapiro	const char *args = "p:";
40106f25ae9SGregory Neil Shapiro
40206f25ae9SGregory Neil Shapiro	/* Process command line options */
40306f25ae9SGregory Neil Shapiro	while ((c = getopt(argc, argv, args)) != -1)
40406f25ae9SGregory Neil Shapiro	{
40506f25ae9SGregory Neil Shapiro		switch (c)
40606f25ae9SGregory Neil Shapiro		{
40706f25ae9SGregory Neil Shapiro		  case 'p':
40806f25ae9SGregory Neil Shapiro			if (optarg == NULL || *optarg == '\0')
40906f25ae9SGregory Neil Shapiro			{
41006f25ae9SGregory Neil Shapiro				(void) fprintf(stderr, "Illegal conn: %s\n",
41106f25ae9SGregory Neil Shapiro					       optarg);
41206f25ae9SGregory Neil Shapiro				exit(EX_USAGE);
41306f25ae9SGregory Neil Shapiro			}
41406f25ae9SGregory Neil Shapiro			(void) smfi_setconn(optarg);
41506f25ae9SGregory Neil Shapiro			break;
41606f25ae9SGregory Neil Shapiro
41706f25ae9SGregory Neil Shapiro		}
41806f25ae9SGregory Neil Shapiro	}
41906f25ae9SGregory Neil Shapiro	if (smfi_register(smfilter) == MI_FAILURE)
42006f25ae9SGregory Neil Shapiro	{
42106f25ae9SGregory Neil Shapiro		fprintf(stderr, "smfi_register failed\n");
42206f25ae9SGregory Neil Shapiro		exit(EX_UNAVAILABLE);
42306f25ae9SGregory Neil Shapiro	}
42406f25ae9SGregory Neil Shapiro	return smfi_main();
42506f25ae9SGregory Neil Shapiro}
42606f25ae9SGregory Neil Shapiro
42706f25ae9SGregory Neil Shapiro/* eof */
42806f25ae9SGregory Neil Shapiro
42913058a91SGregory Neil Shapiro$Revision: 8.9.2.1.2.19 $, Last updated $Date: 2001/06/28 22:25:14 $
430