// A milter filter to copy outgoing email
//
// Build with:
//       cc -I../../sendmail -I../../include -o bccmilter bccmilter.c libmilter.a ../libsm/libsm.a -pthread
// Install with:
//       cp bccmilter /usr/sbin/
//       chown root:wheel /usr/sbin/bccmilter
//       chmod 755 /usr/sbin/bccmilter
// Execute with:
//       rm -f /var/run/f1.sock
//       bccmilter -p local:/var/run/f1.sock &
//
// For instructions, see:
//       http://www.paracoders.com/monitoring_art.html
//
// DH 8/26/03

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>

#include "libmilter/mfapi.h"

#ifndef true
typedef int bool;
# define false	0
# define true	1
#endif /* ! true */

struct mlfiPriv
{
	bool bCopyMessage;
};

#define MLFIPRIV	((struct mlfiPriv *) smfi_getpriv(ctx))

extern sfsistat	 mlfi_cleanup(SMFICTX *, bool);

sfsistat
mlfi_envfrom(ctx, envfrom)
	SMFICTX *ctx;
	char **envfrom;
{
	struct mlfiPriv *priv;
	char * fromaddr;

	/* 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);
	priv->bCopyMessage = false;

        fromaddr = smfi_getsymval(ctx, "{mail_addr}");

        if (fromaddr)
        {
                // EDIT THIS BEFORE USING!!
		if ((strcasecmp(fromaddr,"child1")==0) ||
                    (strcasecmp(fromaddr,"child2")==0) ||
                    (strcasecmp(fromaddr,"child3")==0))
                {
                       priv->bCopyMessage = true; 
                }

	}

	/* save the private data */
	smfi_setpriv(ctx, priv);

	/* continue processing */
	return SMFIS_CONTINUE;
}


sfsistat
mlfi_eom(ctx)
	SMFICTX *ctx;
{
	struct mlfiPriv *priv = MLFIPRIV;
	
        // EDIT THIS BEFORE USING!!
	if (priv->bCopyMessage)
	{
		smfi_addrcpt(ctx, "parent1@somedomain.com");
	}

	return mlfi_cleanup(ctx, true);
}

sfsistat
mlfi_abort(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;

	/* release private memory */
	free(priv);
	smfi_setpriv(ctx, NULL);

	/* return status */
	return rstat;
}

struct smfiDesc smfilter =
{
	"BCCFilter",	/* filter name */
	SMFI_VERSION,	/* version code -- do not change */
	SMFIF_ADDRCPT,	/* flags */
	NULL,		/* connection info filter */
	NULL,		/* SMTP HELO command filter */
	mlfi_envfrom,	/* envelope sender filter */
	NULL,		/* envelope recipient filter */
	NULL,		/* header filter */
	NULL,		/* end of header */
	NULL,		/* body block filter */
	mlfi_eom,	/* end of message */
	mlfi_abort,	/* message aborted */
	NULL		/* connection cleanup */
};


int
main(argc, argv)
	int argc;
	char *argv[];
{
	int c;
	const char *args = "p:";

	/* 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);
			}
			(void) smfi_setconn(optarg);
			break;

		}
	}
	if (smfi_register(smfilter) == MI_FAILURE)
	{
		fprintf(stderr, "smfi_register failed\n");
		exit(EX_UNAVAILABLE);
	}
	return smfi_main();
}

/* eof */


