ports/113293: [MAINTAINER] mail/spamd: update to 4.1.1

Alex Samorukov samm at os2.kiev.ua
Sun Jun 3 16:00:14 UTC 2007


>Number:         113293
>Category:       ports
>Synopsis:       [MAINTAINER] mail/spamd: update to 4.1.1
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          maintainer-update
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jun 03 16:00:13 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Alex Samorukov
>Release:        FreeBSD 5.4-RELEASE-p22 i386
>Organization:
Shevchenko Didkovskiy and Partners
>Environment:
System: FreeBSD deepvision.tsua.net 5.4-RELEASE-p22 FreeBSD 5.4-RELEASE-p22 #6: Thu Feb  1 14:16:07 EET
>Description:
- Update to 4.1.1
- New IPFW support
- Many project home

Added file(s):
- files/obspamd.in
- files/obspamlogd.in
- files/pkg-deinstall.in
- files/pkg-install.in
- files/pkg-message.in

Removed file(s):
- files/patch-greyc
- files/patch-greyh
- files/patch-spamd
- files/patch-spamd-setup
- files/patch-spamdm
- files/pfspamd.sh.in
- pkg-install
- pkg-message
- pkg-plist
- work/.build_done.spamd._usr_local
- work/.configure_done.spamd._usr_local
- work/.extract_done.spamd._usr_local
- work/.patch_done.spamd._usr_local
- work/spamd_3.7/Makefile
- work/spamd_3.7/doc/spamd.conf
- work/spamd_3.7/doc/spamd.conf.5
- work/spamd_3.7/spamd/Makefile
- work/spamd_3.7/spamd/grey.c
- work/spamd_3.7/spamd/grey.c.orig
- work/spamd_3.7/spamd/grey.h
- work/spamd_3.7/spamd/grey.h.orig
- work/spamd_3.7/spamd/grey.o
- work/spamd_3.7/spamd/sdl.c
- work/spamd_3.7/spamd/sdl.h
- work/spamd_3.7/spamd/sdl.o
- work/spamd_3.7/spamd/spamd
- work/spamd_3.7/spamd/spamd.8
- work/spamd_3.7/spamd/spamd.8.bak
- work/spamd_3.7/spamd/spamd.8.gz
- work/spamd_3.7/spamd/spamd.8.orig
- work/spamd_3.7/spamd/spamd.c
- work/spamd_3.7/spamd/spamd.c.orig
- work/spamd_3.7/spamd/spamd.o
- work/spamd_3.7/spamd-setup/Makefile
- work/spamd_3.7/spamd-setup/spamd-setup
- work/spamd_3.7/spamd-setup/spamd-setup.8
- work/spamd_3.7/spamd-setup/spamd-setup.8.bak
- work/spamd_3.7/spamd-setup/spamd-setup.8.gz
- work/spamd_3.7/spamd-setup/spamd-setup.c
- work/spamd_3.7/spamd-setup/spamd-setup.c.bak
- work/spamd_3.7/spamd-setup/spamd-setup.c.orig
- work/spamd_3.7/spamd-setup/spamd-setup.o
- work/spamd_3.7/spamdb/Makefile
- work/spamd_3.7/spamdb/spamdb
- work/spamd_3.7/spamdb/spamdb.8
- work/spamd_3.7/spamdb/spamdb.8.gz
- work/spamd_3.7/spamdb/spamdb.c
- work/spamd_3.7/spamdb/spamdb.o
- work/spamd_3.7/spamlogd/Makefile
- work/spamd_3.7/spamlogd/spamlogd
- work/spamd_3.7/spamlogd/spamlogd.8
- work/spamd_3.7/spamlogd/spamlogd.8.gz
- work/spamd_3.7/spamlogd/spamlogd.c
- work/spamd_3.7/spamlogd/spamlogd.o

Generated with FreeBSD Port Tools 0.77
>How-To-Repeat:
>Fix:

--- spamd-4.1.1.patch begins here ---
diff -ruN --exclude=CVS /usr/ports/mail/spamd/Makefile /usr/home/samm/spamd/Makefile
--- /usr/ports/mail/spamd/Makefile	Thu Apr 26 08:42:02 2007
+++ /usr/home/samm/spamd/Makefile	Sun Jun  3 18:57:26 2007
@@ -1,75 +1,90 @@
-# New ports collection makefile for:	spamd
-# Date created:		23 June 2003
+# New ports collection makefile for:    spamd
+# Date created:         04 April 2007
 # Whom:			Max Laier <max at love2party.net>
 #
-# $FreeBSD: ports/mail/spamd/Makefile,v 1.12 2007/03/20 15:16:44 delphij Exp $
+# $FreeBSD$
 #
 
 PORTNAME=	spamd
-PORTVERSION=	3.7
-PORTREVISION=	3
+PORTVERSION=	4.1.1
 CATEGORIES=	mail
-MASTER_SITES=	${MASTER_SITE_LOCAL}
-MASTER_SITE_SUBDIR=	delphij
-DISTNAME=	${PORTNAME}_${PORTVERSION}
+MASTER_SITES=	BERLIOS
+MASTER_SITE_SUBDIR=freebsdspamd
+DISTNAME=	${PORTNAME}-${PORTVERSION}
 
 MAINTAINER=	samm at os2.kiev.ua
 COMMENT=	Traps spammers with a very slow smtp-login and return 4xx error
 
-USE_BZIP2=	yes
-
 .include <bsd.port.pre.mk>
 
-.if defined(WITH_IPFW)
-CFLAGS+= -DIPFW
-.if ${OSVERSION} < 490000
-BROKEN=		IPFW with Tables is required for this port to function properly
-.endif
-.else
 .if ${OSVERSION} < 502117
 BROKEN=		OpenBSD 3.5 pf/pfctl is necessary for this port to function properly.
 .else
 LOCAL_PFCTL=	/sbin/pfctl
 .endif
-.endif
 
-USE_RC_SUBR=	pfspamd.sh
+USE_RC_SUBR?=	obspamd obspamlogd
 
-.if !defined(BATCH) && !defined(PACKAGE_BUILDING)
-IS_INTERACTIVE=	yes
-.endif
+SPAMDUSER?=	_spamd
+SPAMDGROUP?=	_spamd
+SPAMDDIR?=	/var/empty
+
+SPAMDUID=	132
+SPAMDGID=	${SPAMDUID}
 
 MAN5=		spamd.conf.5
 MAN8=		spamd.8 spamd-setup.8 spamdb.8 spamlogd.8
+PORTDOCS=	ipfw-spamd.txt
 
-SAMPLE_SPAMD_CONF=	${PREFIX}/etc/spamd.conf.sample
+PLIST_DIRS=	etc/spamd
+PLIST_FILES=	libexec/spamd libexec/spamlogd \
+		sbin/spamd-setup sbin/spamdb \
+		etc/spamd/spamd.conf.sample
+
+CONFIG_DIR=		${PREFIX}/etc/spamd
+SAMPLE_SPAMD_CONF=	${CONFIG_DIR}/spamd.conf.sample
+
+PLIST_SUB=	SPAMDDIR=${SPAMDDIR} \
+		SPAMDUSER=${SPAMDUSER} \
+		SPAMDGROUP=${SPAMDGROUP} \
+		SPAMDUID=${SPAMDUID} \
+		SPAMDGID=${SPAMDGID}
+
+SUB_FILES=	pkg-install \
+		pkg-deinstall \
+		pkg-message
 
-post-patch:
-	@${REINPLACE_CMD} -e 's|%%LOCAL_PFCTL%%|${LOCAL_PFCTL}|;	\
-	    s|%%LOCAL_SPAMD_CONF%%|${PREFIX}/etc/spamd.conf|'		\
-	    ${WRKSRC}/spamd-setup/spamd-setup.c
-	@${REINPLACE_CMD} -e 's|/etc/spamd.conf|${PREFIX}/etc/spamd.conf|' \
-	    ${WRKSRC}/spamd/spamd.8 ${WRKSRC}/spamd-setup/spamd-setup.8
-
-pre-su-install:
-.if !defined(BATCH) && !defined(PACKAGE_BUILDING)
-	@${SETENV} PKG_PREFIX=${PREFIX} ${SH} ${PKGINSTALL} ${PKGNAME} PRE-INSTALL
-.endif
+SUB_LIST=	PREFIX=${PREFIX} \
+		${PLIST_SUB}
+
+pre-install:
+	@${SH} ${PKGINSTALL} ${DISTNAME} PRE-INSTALL
+
+post-install:
+	@${CAT} ${PKGMESSAGE}
 
 do-install:
 	${INSTALL_PROGRAM} ${WRKSRC}/spamd/spamd ${PREFIX}/libexec
 	${INSTALL_PROGRAM} ${WRKSRC}/spamlogd/spamlogd ${PREFIX}/libexec
 	${INSTALL_PROGRAM} ${WRKSRC}/spamd-setup/spamd-setup ${PREFIX}/sbin
 	${INSTALL_PROGRAM} ${WRKSRC}/spamdb/spamdb ${PREFIX}/sbin
-	${INSTALL_MAN} ${WRKSRC}/doc/spamd.conf.5 ${PREFIX}/man/man5
+	${INSTALL_MAN} ${WRKSRC}/etc/spamd.conf.5 ${PREFIX}/man/man5
 	${INSTALL_MAN} ${WRKSRC}/spamd/spamd.8 ${PREFIX}/man/man8
 	${INSTALL_MAN} ${WRKSRC}/spamd-setup/spamd-setup.8 ${PREFIX}/man/man8
 	${INSTALL_MAN} ${WRKSRC}/spamdb/spamdb.8 ${PREFIX}/man/man8
 	${INSTALL_MAN} ${WRKSRC}/spamlogd/spamlogd.8 ${PREFIX}/man/man8
-	@if [ ! -f ${SAMPLE_SPAMD_CONF} ]; then			\
+	@if [ ! -d ${CONFIG_DIR} ]; then                        \
+		${MKDIR} ${CONFIG_DIR}; \
+	fi
+	@if [ ! -f ${SAMPLE_SPAMD_CONF} ]; then                 \
 		${ECHO_MSG} "Installing ${SAMPLE_SPAMD_CONF} file."; \
-		${INSTALL_DATA} ${WRKSRC}/doc/spamd.conf	\
-		${SAMPLE_SPAMD_CONF};				\
+		${ECHO_MSG} "${INSTALL_DATA} -v -p ${WRKSRC}/etc/spamd.conf ${SAMPLE_SPAMD_CONF}";                              \
+		${INSTALL_DATA} -v -p ${WRKSRC}/etc/spamd.conf  \
+		${SAMPLE_SPAMD_CONF};                           \
 	fi
+.if !defined(NOPORTDOCS)
+	@${MKDIR} ${DOCSDIR}
+	@${INSTALL_DATA} ${WRKSRC}/doc/ipfw-spamd.txt ${DOCSDIR}/
+.endif
 
 .include <bsd.port.post.mk>
diff -ruN --exclude=CVS /usr/ports/mail/spamd/distinfo /usr/home/samm/spamd/distinfo
--- /usr/ports/mail/spamd/distinfo	Thu Jan 26 21:27:27 2006
+++ /usr/home/samm/spamd/distinfo	Sun Jun  3 18:49:28 2007
@@ -1,3 +1,3 @@
-MD5 (spamd_3.7.tar.bz2) = e1d96b9d7b1d4189dca510ff0000383f
-SHA256 (spamd_3.7.tar.bz2) = a06ad07ead38240f13ea01c5d0315179e7089ed8fb8fe6544b1860bd8cfdc355
-SIZE (spamd_3.7.tar.bz2) = 28066
+MD5 (spamd-4.1.1.tar.gz) = 6cf6a92b709e1907162fd1c59af7943a
+SHA256 (spamd-4.1.1.tar.gz) = b6e8b00ec0b3ff5ff3e73de2fab3f3bbbd3d95807ef1a946a6302666d17c503a
+SIZE (spamd-4.1.1.tar.gz) = 50179
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/obspamd.in /usr/home/samm/spamd/files/obspamd.in
--- /usr/ports/mail/spamd/files/obspamd.in	Thu Jan  1 03:00:00 1970
+++ /usr/home/samm/spamd/files/obspamd.in	Mon Apr 23 18:33:35 2007
@@ -0,0 +1,70 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: obspamd
+# REQUIRE: NETWORKING SERVERS
+# BEFORE:  DAEMON
+# KEYWORD: shutdown
+
+#
+# Define these spamd_* variables in one of these files:
+#       /etc/rc.conf
+#       /etc/rc.conf.local
+#
+# obspamd_enable="YES"	# Run the spamd(8) daemon (YES/NO).
+# obspamd_flags=""	# Extra flags for spamd(8) (if enabled).
+#
+# DO NOT CHANGE THESE DEFAULT VALUES HERE
+#
+obspamd_enable=${obspamd_enable:-"NO"}
+obspamd_flags=${obspamd_flags:-""}
+
+. %%RC_SUBR%%
+
+name="obspamd"
+rcvar=`set_rcvar`
+
+command="%%PREFIX%%/libexec/spamd"
+start_precmd="obspamd_precmd"
+start_postcmd="obspamd_postcmd"
+restart_postcmd="obspamd_postcmd"
+stop_postcmd="obspamd_cleanup"
+pidfile="/var/run/spamd.pid"
+
+obspamd_precmd()
+{
+	_rc=0
+	echo "${obspamd_flags}" | grep "\-b" 2>&1 > /dev/null
+	if [ $? -eq 1 ]; then
+		/sbin/mount -p | grep 'fdescfs.*/dev/fd.*fdescfs.*rw' 2>&1 > /dev/null
+		_rc=${?}
+		if [ ${_rc} -ne 0 ]; then
+			echo "Unable to start spamd in greylisting mode"
+			echo ""
+			echo "Please mount fdescfs with the following line in /etc/fstab"
+			echo ""
+			echo "  fdescfs /dev/fd fdescfs rw 0 0"
+			echo ""
+		fi
+		return ${_rc}
+	fi
+}
+
+obspamd_postcmd()
+{
+	if [ -x %%PREFIX%%/sbin/spamd-setup ]; then
+		if [ -r %%PREFIX%%/etc/spamd/spamd.conf ]; then
+			%%PREFIX%%/sbin/spamd-setup &
+		fi
+	fi
+}
+
+obspamd_cleanup()
+{
+	/bin/rm -f ${pidfile}
+}
+
+load_rc_config $name
+run_rc_command "$1"
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/obspamlogd.in /usr/home/samm/spamd/files/obspamlogd.in
--- /usr/ports/mail/spamd/files/obspamlogd.in	Thu Jan  1 03:00:00 1970
+++ /usr/home/samm/spamd/files/obspamlogd.in	Mon Apr 23 18:33:35 2007
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: obspamlogd
+# REQUIRE: NETWORKING SERVERS obspamd
+# BEFORE:  DAEMON
+# KEYWORD: shutdown
+
+#
+# Define these obspamlogd_* variables in one of these files:
+#       /etc/rc.conf
+#       /etc/rc.conf.local
+#
+# obspamlogd_enable="YES"	# Run the spamlogd(8) daemon (YES/NO).
+# obspamlogd_flags=""		# Extra flags for spamlogd(8) (if enabled).
+#
+# DO NOT CHANGE THESE DEFAULT VALUES HERE
+#
+obspamlogd_enable=${obspamlogd_enable:-"NO"}
+obspamlogd_flags=${obspamlogd_flags:-""}
+
+. %%RC_SUBR%%
+
+name="obspamlogd"
+rcvar=`set_rcvar`
+
+command="%%PREFIX%%/libexec/spamlogd"
+start_precmd="obspamlogd_precmd"
+stop_postcmd="obspamlogd_cleanup"
+pidfile="/var/run/spamlogd.pid"
+
+obspamlogd_precmd()
+{
+	_rc=0
+	/sbin/mount -p | grep 'fdescfs.*/dev/fd.*fdescfs.*rw' 2>&1 > /dev/null
+	_rc=${?}
+	if [ ${_rc} -ne 0 ]; then
+		echo "Unable to start ${name}"
+		echo ""
+		echo "Please mount fdescfs with the following line in /etc/fstab"
+		echo ""
+		echo "  fdescfs /dev/fd fdescfs rw 0 0"
+		echo ""
+	fi
+	return ${_rc}
+}
+
+obspamlogd_cleanup()
+{
+	/bin/rm -f ${pidfile}
+}
+
+load_rc_config $name
+run_rc_command "$1"
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/patch-greyc /usr/home/samm/spamd/files/patch-greyc
--- /usr/ports/mail/spamd/files/patch-greyc	Tue May  2 11:54:50 2006
+++ /usr/home/samm/spamd/files/patch-greyc	Thu Jan  1 03:00:00 1970
@@ -1,131 +0,0 @@
---- spamd/grey.c	Wed Apr 13 03:22:17 2005
-+++ spamd/grey.c	Mon Mar 20 15:26:18 2006
-@@ -39,6 +39,10 @@
- #include <unistd.h>
- #include <netdb.h>
- 
-+#ifdef IPFW
-+#include <netinet/ip_fw.h>
-+#endif
-+
- #include "grey.h"
- 
- extern time_t passtime, greyexp, whiteexp, trapexp;
-@@ -65,13 +69,17 @@
- char *traplist_msg = "\"Your address %A has mailed to spamtraps here\\n\"";
- 
- pid_t db_pid = -1;
--int pfdev;
- int spamdconf;
- 
-+#ifdef IPFW
-+extern int tabno;
-+#else
-+int pfdev;
- static char *pargv[11]= {
- 	"pfctl", "-p", "/dev/pf", "-q", "-t",
- 	"spamd-white", "-T", "replace", "-f" "-", NULL
- };
-+#endif
- 
- /* If the parent gets a signal, kill off the children and exit */
- /* ARGSUSED */
-@@ -104,6 +112,7 @@
- 	return(0);
- }
- 
-+#ifndef IPFW
- int
- configure_pf(char **addrs, int count)
- {
-@@ -166,11 +175,54 @@
- 	for (i = 0; i < count; i++)
- 		if (addrs[i] != NULL)
- 			fprintf(pf, "%s/32\n", addrs[i]);
-+
- 	fclose(pf);
- 	waitpid(pid, NULL, 0);
- 	sigaction(SIGCHLD, &sa, NULL);
- 	return(0);
- }
-+#else
-+int
-+configure_pf(char **addrs, int count)
-+{
-+	static int s = -1;
-+	ipfw_table_entry ent;
-+	int i;
-+
-+	if (s == -1)
-+		s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-+	if (s < 0)
-+	{
-+		syslog_r(LOG_INFO, &sdata, "IPFW socket unavailable (%m)");
-+		return(-1);
-+	}
-+
-+	/* flush the table */	
-+	ent.tbl = tabno;
-+	if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_FLUSH,  &ent.tbl, sizeof(ent.tbl)) < 0)
-+	{
-+		syslog_r(LOG_INFO, &sdata, "IPFW setsockopt(IP_FW_TABLE_FLUSH) (%m)");
-+		return(-1);
-+	}
-+
-+	for (i = 0; i < count; i++)
-+		if (addrs[i] != NULL)
-+	{
-+		/* add addrs[i] to tabno */
-+		ent.tbl = tabno;
-+		ent.masklen = 32;
-+		ent.value = 0;
-+		inet_aton(addrs[i], (struct in_addr *)&ent.addr);
-+		if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_ADD,  &ent, sizeof(ent)) < 0)
-+		{
-+			syslog_r(LOG_INFO, &sdata, "IPFW setsockopt(IP_FW_TABLE_ADD) (%m)");
-+			return(-1);
-+		}
-+	}
-+
-+	return(0);
-+}
-+#endif
- 
- void
- freeaddrlists(void)
-@@ -590,11 +642,13 @@
- 	int i;
- 	struct sigaction sa;
- 
-+#ifndef IPFW
- 	pfdev = open("/dev/pf", O_RDWR);
- 	if (pfdev == -1) {
- 		syslog_r(LOG_ERR, &sdata, "open of /dev/pf failed (%m)");
- 		exit(1);
- 	}
-+#endif
- 
- 	/* check to see if /var/db/spamd exists, if not, create it */
- 	if ((i = open(PATH_SPAMD_DB, O_RDWR, 0)) == -1 && errno == ENOENT) {
-@@ -636,7 +690,9 @@
- 		 * child, talks to jailed spamd over greypipe,
- 		 * updates db. has no access to pf.
- 		 */
-+#ifndef IPFW
- 		close(pfdev);
-+#endif
- 		setproctitle("(%s update)", PATH_SPAMD_DB);
- 		greyreader();
- 		/* NOTREACHED */
-@@ -655,7 +711,11 @@
- 	sigaction(SIGCHLD, &sa, NULL);
- 	sigaction(SIGINT, &sa, NULL);
- 
-+#ifndef IPFW
- 	setproctitle("(pf <spamd-white> update)");
-+#else
-+	setproctitle("(ipfw white table update)");
-+#endif
- 	greyscanner();
- 	/* NOTREACHED */
- 	exit(1);
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/patch-greyh /usr/home/samm/spamd/files/patch-greyh
--- /usr/ports/mail/spamd/files/patch-greyh	Tue May  2 11:54:50 2006
+++ /usr/home/samm/spamd/files/patch-greyh	Thu Jan  1 03:00:00 1970
@@ -1,10 +0,0 @@
---- spamd/grey.h	Thu Mar 16 19:55:33 2006
-+++ spamd/grey.h	Thu Mar 16 19:55:56 2006
-@@ -22,6 +22,7 @@
- #define WHITEEXP (60 * 60 * 24 * 36) /* remove white entries after 36 days */
- #define TRAPEXP (60 * 60 * 24) /* hitting a spamtrap blacklists for a day */
- #define PATH_PFCTL "/sbin/pfctl"
-+#define PATH_IPFW "/sbin/ipfw"
- #define DB_SCAN_INTERVAL 60
- #define PATH_SPAMD_DB "/var/db/spamd"
- 
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/patch-spamd /usr/home/samm/spamd/files/patch-spamd
--- /usr/ports/mail/spamd/files/patch-spamd	Tue May  2 11:54:50 2006
+++ /usr/home/samm/spamd/files/patch-spamd	Thu Jan  1 03:00:00 1970
@@ -1,48 +0,0 @@
---- spamd/spamd.c	Thu Mar 16 20:56:45 2006
-+++ spamd/spamd.c	Thu Mar 16 21:07:11 2006
-@@ -123,6 +123,10 @@
- pid_t jail_pid = -1;
- u_short cfg_port;
- 
-+#ifdef IPFW
-+int tabno=1;
-+#endif
-+
- extern struct sdlist *blacklists;
- 
- int conffd = -1;
-@@ -153,6 +157,10 @@
- 	    "             [-G mins:hours:hours] [-n name] [-p port]\n");
- 	fprintf(stderr,
- 	    "             [-r reply] [-s secs] [-w window]\n");
-+#ifdef IPFW
-+	fprintf(stderr,
-+	    "             [-t table_no]\n");
-+#endif
- 	exit(1);
- }
- 
-@@ -958,7 +966,11 @@
- 	if (gethostname(hostname, sizeof hostname) == -1)
- 		err(1, "gethostname");
- 
-+#ifdef IPFW
-+	while ((ch = getopt(argc, argv, "45b:c:B:p:dgG:r:s:n:vw:t:")) != -1) {
-+#else
- 	while ((ch = getopt(argc, argv, "45b:c:B:p:dgG:r:s:n:vw:")) != -1) {
-+#endif
- 		switch (ch) {
- 		case '4':
- 			nreply = "450";
-@@ -1015,6 +1027,11 @@
- 		case 'v':
- 			verbose = 1;
- 			break;
-+#ifdef IPFW
-+		case 't':
-+			tabno = atoi(optarg);
-+			break;
-+#endif
- 		case 'w':
- 			window = atoi(optarg);
- 			if (window <= 0)
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/patch-spamd-setup /usr/home/samm/spamd/files/patch-spamd-setup
--- /usr/ports/mail/spamd/files/patch-spamd-setup	Thu Apr 26 08:42:02 2007
+++ /usr/home/samm/spamd/files/patch-spamd-setup	Thu Jan  1 03:00:00 1970
@@ -1,110 +0,0 @@
---- spamd-setup/spamd-setup.c.orig	Wed Apr 13 01:18:59 2005
-+++ spamd-setup/spamd-setup.c	Wed May 10 01:55:13 2006
-@@ -41,6 +41,11 @@
- #include <netdb.h>
- #include <zlib.h>
- 
-+#ifdef IPFW
-+#include <net/if.h>
-+#include <netinet/ip_fw.h>
-+#endif
-+
- #define PATH_FTP		"/usr/bin/ftp"
- #define PATH_PFCTL		"%%LOCAL_PFCTL%%"
- #define PATH_SPAMD_CONF		"%%LOCAL_SPAMD_CONF%%"
-@@ -93,6 +98,11 @@
- int		debug;
- int		dryrun;
- 
-+#ifdef IPFW
-+int tabno=2;
-+#endif
-+
-+
- u_int32_t
- imask(u_int8_t b)
- {
-@@ -630,6 +640,7 @@
- }
- 
- 
-+#ifndef IPFW
- int
- configure_pf(struct cidr **blacklists)
- {
-@@ -676,6 +687,51 @@
- 	}
- 	return(0);
- }
-+#else
-+int
-+configure_pf(struct cidr **blacklists)
-+{
-+	static int s = -1;
-+	ipfw_table_entry ent;
-+
-+	if (s == -1)
-+		s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-+	if (s < 0)
-+	{
-+		err(1, "IPFW socket unavailable");
-+		return(-1);
-+	}
-+
-+	/* flush the table */   
-+	ent.tbl = tabno;
-+	if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_FLUSH,  &ent.tbl, sizeof(ent.tbl)) < 0)
-+	{
-+		err(1, "IPFW setsockopt(IP_FW_TABLE_FLUSH)");
-+		return(-1);
-+	}
-+
-+	while (*blacklists != NULL) {
-+		struct cidr *b = *blacklists;
-+
-+		while (b->addr != 0) {
-+			/* add b to tabno */
-+			ent.tbl = tabno;
-+			ent.masklen = b->bits;
-+			ent.value = 0;
-+			inet_aton(atop(b->addr), (struct in_addr *)&ent.addr);
-+			if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_ADD,  &ent, sizeof(ent)) < 0)
-+			{
-+				err(1, "IPFW setsockopt(IP_FW_TABLE_ADD)");
-+				return(-1);
-+			}
-+			b++;
-+		}
-+		blacklists++;
-+	}
-+
-+	return(0);
-+}
-+#endif
- 
- int
- getlist(char ** db_array, char *name, struct blacklist *blist,
-@@ -773,7 +829,11 @@
- 	struct servent *ent;
- 	int i, ch;
- 
-+#ifndef IPFW
- 	while ((ch = getopt(argc, argv, "nd")) != -1) {
-+#else
-+	while ((ch = getopt(argc, argv, "ndt:")) != -1) {
-+#endif
- 		switch (ch) {
- 		case 'n':
- 			dryrun = 1;
-@@ -781,6 +841,11 @@
- 		case 'd':
- 			debug = 1;
- 			break;
-+#ifdef IPFW
-+		case 't':
-+			tabno = atoi(optarg);
-+			break;
-+#endif
- 		default:
- 			break;
- 		}
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/patch-spamdm /usr/home/samm/spamd/files/patch-spamdm
--- /usr/ports/mail/spamd/files/patch-spamdm	Tue May  2 11:54:50 2006
+++ /usr/home/samm/spamd/files/patch-spamdm	Thu Jan  1 03:00:00 1970
@@ -1,89 +0,0 @@
---- spamd/spamd.8	Wed Apr 13 03:21:48 2005
-+++ spamd/spamd.8	Mon Mar 20 15:12:10 2006
-@@ -49,6 +49,8 @@
- daemon which rejects false mail.
- If the
- .Xr pf 4
-+or
-+.Xr ipfw 4
- packet filter is configured to redirect port 25 (SMTP) to this daemon,
- it will attempt to waste the time and resources of the spam sender.
- .Pp
-@@ -151,11 +153,15 @@
- which processes a list of spammers' addresses, and applies appropriate
- .Xr pfctl 8
- .Em rdr
-+or
-+.Xr ipfw 8
-+.Em fwd
- rules.
- .Xr spamd-setup 8
- is run from
- .Xr cron 8 .
- .Sh REDIRECTING SMTP CONNECTIONS
-+.Ss "When using PF"
- With
- .Xr pf 4 ,
- connections to port 25 (SMTP) can be redirected to another host or port,
-@@ -189,6 +195,8 @@
- can also be used to load addresses into the
- .Em <spamd>
- table.
-+
-+
- .Xr spamd-setup 8
- also has the added benefit of being able to remove addresses from
- blacklists, and will connect to
-@@ -203,6 +211,52 @@
- This is important as it allows legitimate mail
- senders to pressure spam sources into behaving properly so that they
- may be removed from the relevant blacklists.
-+
-+.Ss "If compiled with IPFW"
-+With
-+.Xr ipfw 4 ,
-+the syntax for redirection of TCP sessions is quite different
-+from that of
-+.Xr pf 4 .
-+The
-+.Em fwd
-+rule used for this purpose are described in
-+.Xr ipfw 8 .
-+The rules should be added to the ruleset called by /etc/rc.firewall
-+to be present at boot time.
-+.Bd -literal -offset 4n
-+fwd 127.0.0.1,8025 tcp from table(2) to me 25 in
-+allow tcp from table(1) to me 25 in
-+fwd 127.0.0.1,8025 tcp from any to me 25 in
-+.Ed
-+.Pp
-+Any addresses in the blacklist table
-+.Em 2
-+and not in the whitelist table
-+.Em 1
-+are then redirected to
-+.Nm
-+running on port 8025.
-+Addresses can be loaded into the blacklist
-+.Em table ,
-+like:
-+.Bd -literal -offset 4n
-+# ipfw table 1 add a.b.c.d/x
-+.Ed
-+.Pp
-+.Xr spamd-setup 8
-+can also be used to load addresses into the blacklist table
-+.Em 2 .
-+.Pp
-+The 
-+.Op Fl t Ar table_no
-+option to 
-+.Em spamd 
-+and 
-+.Em spamd-setup 
-+can be used to change the default table
-+numbers.
-+
- .Sh CONFIGURATION CONNECTIONS
- .Nm
- listens for configuration connections on the port identified by the
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/pfspamd.sh.in /usr/home/samm/spamd/files/pfspamd.sh.in
--- /usr/ports/mail/spamd/files/pfspamd.sh.in	Thu Apr 26 08:42:02 2007
+++ /usr/home/samm/spamd/files/pfspamd.sh.in	Thu Jan  1 03:00:00 1970
@@ -1,49 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD: ports/mail/spamd/files/pfspamd.sh.in,v 1.2 2007/03/20 15:16:44 delphij Exp $
-#
-
-# PROVIDE: pfspamd
-# REQUIRE: NETWORKING
-# BEFORE:  mail
-# KEYWORD: shutdown
-
-#
-# Add the following lines to /etc/rc.conf to enable spamd:
-# pfspamd_enable (bool):	Set to "NO" by default.
-#				Set it to "YES" to enable spamd
-# pfspamd_flags (str):		Set to "" by default.
-#				Extra flags passed to start command.
-# pfspamd_setup_flags (str):		Set to "" by default.
-#				Extra flags passed to spamd-setup command.
-
-. %%RC_SUBR%%
-
-name="pfspamd"
-rcvar=`set_rcvar`
-
-command="%%PREFIX%%/libexec/spamd"
-start_postcmd="pfspamd_postcmd"
-restart_postcmd="pfspamd_postcmd"
-
-[ -z "$pfspamd_enable" ]	&& pfspamd_enable="NO"
-[ -z "$pfspamd_flags" ]		&& pfspamd_flags=""
-[ -z "$pfspamd_setup_flags" ]	&& pfspamd_setup_flags=""
-
-load_rc_config $name
-
-# we override check_process to avoid conflict with the spamd from sa-spamd
-check_process()
-{
- ps ax -o pid,command | grep "libexec/spamd" | grep -v grep | awk '{print $1}'
-}
-
-
-pfspamd_postcmd() 
-{
-	if [ -x %%PREFIX%%/sbin/spamd-setup ]; then
-		%%PREFIX%%/sbin/spamd-setup $pfspamd_setup_flags
-	fi
-}
-
-run_rc_command "$1"
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/pkg-deinstall.in /usr/home/samm/spamd/files/pkg-deinstall.in
--- /usr/ports/mail/spamd/files/pkg-deinstall.in	Thu Jan  1 03:00:00 1970
+++ /usr/home/samm/spamd/files/pkg-deinstall.in	Tue Apr 10 18:49:02 2007
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+#
+
+SPAMDDIR=%%SPAMDDIR%%
+SPAMDUSER=%%SPAMDUSER%%
+SPAMDGROUP=%%SPAMDGROUP%%
+
+if [ "$2" = "POST-DEINSTALL" ]; then
+  if /usr/sbin/pw group show "${SPAMDGROUP}" 2>&1 >/dev/null; then
+    echo "You should manually remove the \"${SPAMDGROUP}\" group."
+  fi
+
+  if /usr/sbin/pw user show "${SPAMDUSER}" 2>&1 >/dev/null; then
+    echo "You should manually remove the \"${SPAMDUSER}\" user."
+  fi
+
+  if [ -e "${SPAMDDIR}" ]; then
+    echo "You should manually remove the \"${SPAMDDIR}\" directory."
+  fi
+fi
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/pkg-install.in /usr/home/samm/spamd/files/pkg-install.in
--- /usr/ports/mail/spamd/files/pkg-install.in	Thu Jan  1 03:00:00 1970
+++ /usr/home/samm/spamd/files/pkg-install.in	Wed Apr 18 15:58:31 2007
@@ -0,0 +1,148 @@
+#!/bin/sh
+#
+#
+
+SPAMDDIR=%%SPAMDDIR%%
+SPAMDUSER=%%SPAMDUSER%%
+SPAMDGROUP=%%SPAMDGROUP%%
+SPAMDUID=%%SPAMDUID%%
+SPAMDGID=%%SPAMDGID%%
+
+ask() {
+  local question default answer
+
+  question=$1
+  default=$2
+  if [ -z "${PACKAGE_BUILDING}" ]; then
+    read -p "${question} [${default}]? " answer
+  fi
+  if [ "x${answer}" = "x" ]; then
+    answer=${default}
+  fi
+  echo ${answer}
+}
+
+yesno() {
+  local default question answer
+
+  question=$1
+  default=$2
+  while :; do
+    answer=$(ask "${question}" "${default}")
+    case "${answer}" in
+      [Yy][Ee][Ss]|[Yy])
+        return 0
+        ;;
+      [Nn][Oo]|[Nn])
+        return 1
+        ;;
+    esac
+    echo "Please answer yes or no."
+   done
+}
+
+check_db() {
+    DB=/var/db/spamd
+    if [ -f ${DB} ]; then
+	OWN=`ls -l ${DB} | awk '{print $3}'`
+	GRP=`ls -l ${DB} | awk '{print $4}'`
+    fi
+    if [ "x${OWN}" != "x${SPAMDUSER}" ]; then
+	echo "change ${BD} owner to ${SPAMDUSER}:"
+	/usr/sbin/chown ${SPAMDUSER} ${DB}
+    fi
+    if [ "x${GRP}" != "x${SPAMDGROUP}" ]; then
+	echo "change ${BD} owner to :${SPAMDUSER}"
+	/usr/sbin/chown :${SPAMDGROUP} ${DB}
+    fi
+}
+
+check_service() {
+    local name number type comment
+    
+    name=$1
+    number=$2
+    type=$3
+    comment=$4
+    
+    FILE="/etc/services"
+    # check
+    OK=no
+    HAS_SERVICE=no
+    COUNT=1
+    for i in `grep $name $FILE `; do
+	if [ $COUNT = 1 ] && [ X"$i" = X"$name" ]; then
+	    HAS_SERVICE=yes
+	elif [ $COUNT = 2 ] && [ $HAS_SERVICE = yes ] && \
+		[ X"$i" = X"$number/$type" ]; then
+	    OK=yes
+	    break
+	fi
+	COUNT=`expr ${COUNT} + 1`
+    done
+    # add an entry for SERVICE to /etc/services
+    if [ $OK = no ]; then
+	echo "This system has no entry for $name in ${FILE}"
+	if yesno "Would you like to add it automatically?" y; then
+	    mv ${FILE} ${FILE}.bak
+	    (grep -v $name ${FILE}.bak ; \
+		echo "$name	$number/$type	# $comment") \
+		>> ${FILE}
+	    rm ${FILE}.bak
+	else
+	    echo "Please add '$name $number/$type' into ${FILE}, and try again."
+	    return 1
+	fi
+    fi
+    return 0
+}
+
+
+if [ "$2" = "PRE-INSTALL" ]; then
+  check_dbown=0	
+  if /usr/sbin/pw group show "${SPAMDGROUP}" 2>&1 >/dev/null; then
+    echo "You already have a \"${SPAMDGROUP}\" group, so I will use it."
+  else
+    echo "You need a \"${SPAMDGROUP}\" group."
+    if yesno "Would you like me to create it" "YES"; then
+      /usr/sbin/pw groupadd "${SPAMDGROUP}" -g "${SPAMDGID}" -h - || \
+        /usr/sbin/pw groupadd "${SPAMDGROUP}" -h - || exit
+      echo "Done."
+      check_dbown=1
+    else
+      echo "Please create the \"${SPAMDGROUP}\" group manually and try again."
+      exit 1
+    fi
+  fi
+
+  if /usr/sbin/pw user show "${SPAMDUSER}" 2>&1 >/dev/null; then
+    echo "You already have a \"${SPAMDUSER}\" user, so I will use it."
+  else
+    echo "You need a \"${SPAMDUSER}\" user."
+    if yesno "Would you like me to create it" "YES"; then
+      /usr/sbin/pw useradd "${SPAMDUSER}" -u "${SPAMDUID}" -g "${SPAMDGROUP}" -h - -d "${SPAMDDIR}" \
+        -s /sbin/nologin -c "spamd pseudo-user" || \
+        /usr/sbin/pw useradd "${SPAMDUSER}" -g "${SPAMDGROUP}" -h - -d "${SPAMDDIR}" \
+        -s /sbin/nologin -c "spamd pseudo-user" || exit
+      check_dbown=1
+    else
+      echo "Please create the \"${SPAMDUSER}\" user manually and try again."
+      exit 1
+    fi
+  fi
+
+  if [ ${check_dbown} -eq 1 ]; then
+    check_db
+  fi
+
+  if ! check_service spamd 8025 tcp "spamd(8)"; then
+    exit 1
+  fi
+  if ! check_service spamd-cfg 8026 tcp "spamd(8) configuration"; then
+    exit 1
+  fi
+  if ! check_service spamd-sync 8025 udp "spamd(8) synchronisation"; then
+    exit 1
+  fi
+
+fi
diff -ruN --exclude=CVS /usr/ports/mail/spamd/files/pkg-message.in /usr/home/samm/spamd/files/pkg-message.in
--- /usr/ports/mail/spamd/files/pkg-message.in	Thu Jan  1 03:00:00 1970
+++ /usr/home/samm/spamd/files/pkg-message.in	Sun Jun  3 18:49:28 2007
@@ -0,0 +1,42 @@
+**********************************************************************
+To enable spamd you need:
+
+1) Enable spamd in /etc/rc.conf with the following line:
+   obspamd_enable="YES"
+   obspamlogd_enable="YES"
+
+2) Configuration template is available in %%PREFIX%%/etc/spamd as
+   spamd.conf.sample file.  Copy then to spamd.conf file and
+   edit to suit your needs.
+
+3) mount fdescfs to /dev/fd with the following line in /etc/fstab
+	fdescfs  	/dev/fd  	fdescfs rw 	0 	0
+
+4) Add following lines to the pf.conf(5)
+
+  table <spamd-white> persist
+  no rdr inet proto tcp from <spamd-white> to any \
+      port smtp
+  rdr pass inet proto tcp from any to any \
+      port smtp -> 127.0.0.1 port spamd
+
+ !!!!!!!!!!!! --  I M P O T A N T  -  N O T E S  -- !!!!!!!!!!!!!!!!!
+ !
+ ! changes in Ver. 4.1.x:
+ !  - UID/GID is reserved to: _spamd:_spamd
+ !    check the owner of /var/db/spamd
+ !  - greylisting is now the default
+ !  - paramer: -b is now blacklist (Ver. < 4.1.x it is bind address)
+ !  - paramer: -l is now listen address
+ !  - spamdb: format is now HASH, helo/ehlo is also stored in db
+ !    convert will be done at the first start of spamd
+ !    if you have scripts that use spamdb review this scripts
+ !  - config files: new location is %%PREFIX%%/etc/spamd
+ !  - spamtrapp addresses: remove the surrounding '< >' signs
+ !  - pfspamd.sh was renamed to the obspamd
+ !  - IPFW support (beta) added to the sources.
+ !    See %%PREFIX%%/%%DOCSDIR%%/spamd-ipfw.txt for usage manual.
+ !
+ !!!!!!!!!!!! --  I M P O T A N T  -  N O T E S  -- !!!!!!!!!!!!!!!!!
+
+**********************************************************************
diff -ruN --exclude=CVS /usr/ports/mail/spamd/pkg-descr /usr/home/samm/spamd/pkg-descr
--- /usr/ports/mail/spamd/pkg-descr	Wed Nov  8 22:37:58 2006
+++ /usr/home/samm/spamd/pkg-descr	Tue Apr 10 11:41:43 2007
@@ -1,17 +1,21 @@
-Tarpits like spamd are fake SMTP servers, which accept connections but don't
-deliver mail. Instead, they keep the connections open and reply very slowly.
-If the peer is patient enough to actually complete the SMTP dialogue (which
-will take ten minutes or more), the tarpit returns a 'temporary error' code
-(4xx), which indicates that the mail could not be delivered successfully and
-that the sender should keep the mail in his queue and retry again later. If
-he does, the same procedure repeats. Until, after several attempts, wasting
-both his queue space and socket handles for several days, he gives up. The
-resources I have to waste to do this are minimal.
+Spamd is a fake sendmail(8)-like daemon which rejects false mail. It is 
+designed to be very efficient so that it does not slow down the receiving
+machine.
 
-If the sender is badly configured, an uncooperative recipient might actually
-delay his entire queue handling for several minutes each time he connects to
-the tarpit. And many spammers use badly configured open relays
+spamd considers sending hosts to be of three types:
 
-WWW: http://www.OpenBSD.org/spamd/
+ blacklisted hosts are redirected to spamd and tarpitted i.e. they are 
+ communicated with very slowly to consume the sender's resources. Mail is
+ rejected with either a 450 or 550 error message. A blacklisted host will not
+ be allowed to talk to a real mail server.
+
+ whitelisted hosts do not talk to spamd. Their connections are instead sent to
+ a real mail server, such as sendmail(8).
+
+ greylisted hosts are redirected to spamd, but spamd has not yet decided if
+ they are likely spammers. They are given a temporary failure message by spamd
+ when they try to deliver mail.
+
+WWW: http://freebsdspamd.berlios.de/
 
 -Max <max at love2party.net>
diff -ruN --exclude=CVS /usr/ports/mail/spamd/pkg-install /usr/home/samm/spamd/pkg-install
--- /usr/ports/mail/spamd/pkg-install	Tue Sep 30 02:01:21 2003
+++ /usr/home/samm/spamd/pkg-install	Thu Jan  1 03:00:00 1970
@@ -1,84 +0,0 @@
-#!/bin/sh
-# an installation script for spamd copied from pf_freebsd
-
-ask() {
-    local question default answer
-
-    question=$1
-    default=$2
-    if [ -z "${PACKAGE_BUILDING}" ]; then
-	read -p "${question} (y/n) [${default}]? " answer
-    fi
-    if [ x${answer} = x ]; then
-	answer=${default}
-    fi
-    echo ${answer}
-}
-
-yesno() {
-    local dflt question answer
-
-    question=$1
-    dflt=$2
-    while :; do
-	answer=$(ask "${question}" "${dflt}")
-	case "${answer}" in
-	[Yy]*)		return 0;;
-	[Nn]*)		return 1;;
-	esac
-	echo "Please answer yes or no."
-    done
-}
-
-check_service() {
-    local name number type comment
-    
-    name=$1
-    number=$2
-    type=$3
-    comment=$4
-    
-    FILE="/etc/services"
-    # check
-    OK=no
-    HAS_SERVICE=no
-    COUNT=1
-    for i in `grep $name $FILE `; do
-	if [ $COUNT = 1 ] && [ X"$i" = X"$name" ]; then
-	    HAS_SERVICE=yes
-	elif [ $COUNT = 2 ] && [ $HAS_SERVICE = yes ] && \
-		[ X"$i" = X"$number/$type" ]; then
-	    OK=yes
-	    break
-	fi
-	COUNT=`expr ${COUNT} + 1`
-    done
-    # add an entry for SERVICE to /etc/services
-    if [ $OK = no ]; then
-	echo "This system has no entry for $name in ${FILE}"
-	if yesno "Would you like to add it automatically?" y; then
-	    mv ${FILE} ${FILE}.bak
-	    (grep -v $name ${FILE}.bak ; \
-		echo "$name	$number/$type	# $comment") \
-		>> ${FILE}
-	    rm ${FILE}.bak
-	else
-	    echo "Please add '$name $number/$type' into ${FILE}, and try again."
-	    return 1
-	fi
-    fi
-    return 0
-}
-
-case $2 in
-PRE-INSTALL)
-
-    if ! check_service spamd 8025 tcp "# spamd(8)"; then
-	exit 1
-    fi
-    if ! check_service spamd-cfg 8026 tcp "# spamd(8) configuration"; then
-	exit 1
-    fi
-    ;;
-
-esac
diff -ruN --exclude=CVS /usr/ports/mail/spamd/pkg-message /usr/home/samm/spamd/pkg-message
--- /usr/ports/mail/spamd/pkg-message	Thu Jan 13 04:54:46 2005
+++ /usr/home/samm/spamd/pkg-message	Thu Jan  1 03:00:00 1970
@@ -1,9 +0,0 @@
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-In order to use spamd greylisting feature you have to have a mounted fdescfs(5)
-at /dev/fd.  This is done by adding:
-
-        fdescfs /dev/fd fdescfs rw 0 0
-
-to /etc/fstab.  You may need either a customised kernel, or kldload the fdescfs
-kernel module.
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff -ruN --exclude=CVS /usr/ports/mail/spamd/pkg-plist /usr/home/samm/spamd/pkg-plist
--- /usr/ports/mail/spamd/pkg-plist	Tue May 23 14:17:08 2006
+++ /usr/home/samm/spamd/pkg-plist	Thu Jan  1 03:00:00 1970
@@ -1,5 +0,0 @@
-libexec/spamd
-libexec/spamlogd
-sbin/spamd-setup
-sbin/spamdb
-etc/spamd.conf.sample
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/Makefile /usr/home/samm/spamd/work/spamd_3.7/Makefile
--- /usr/ports/mail/spamd/work/spamd_3.7/Makefile	Sun Oct  3 16:09:15 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/Makefile	Thu Jan  1 03:00:00 1970
@@ -1,7 +0,0 @@
-#
-# Makefile for OpenBSD spamd
-#
-
-SUBDIR+= spamd spamd-setup spamdb spamlogd
-
-.include <bsd.subdir.mk>
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/doc/spamd.conf /usr/home/samm/spamd/work/spamd_3.7/doc/spamd.conf
--- /usr/ports/mail/spamd/work/spamd_3.7/doc/spamd.conf	Sun Jan 16 19:16:44 2005
+++ /usr/home/samm/spamd/work/spamd_3.7/doc/spamd.conf	Thu Jan  1 03:00:00 1970
@@ -1,86 +0,0 @@
-# $OpenBSD: spamd.conf,v 1.12 2005/01/16 17:16:44 deraadt Exp $
-#
-# spamd config file, read by spamd-setup(8) for spamd(8)
-#
-# See spamd.conf(5)
-#
-# Configures whitelists and blacklists for spamd
-#
-# Strings follow getcap(3) convention escapes, other than you
-# can have a bare colon (:) inside a quoted string and it
-# will deal with it. See spamd-setup(8) for more details.
-#
-# "all" must be here, and defines the order in which lists are applied
-# whitelists apply to the previous blacklist. more than one whitelist
-# may be applied to each blacklist
-#
-# As of November 2004, a place to search for black lists is
-#     http://spamlinks.net/filter-bl.htm
-#
-# Some of the URLs below point to www.openbsd.org locations.  Those
-# files are likely to be mirrored to other OpenBSD www mirrors located
-# around the world.  Hence, it is possible to edit this file and rewrite
-# www.openbsd.org with, for instance, to www.de.openbsd.org
-
-all:\
-	:spamhaus:china:korea:
-
-# Mirrored from http://spfilter.openrbl.org/data/sbl/SBL.cidr.bz2
-spamhaus:\
-	:black:\
-	:msg="SPAM. Your address %A is in the Spamhaus Block List\n\
-	See http://www.spamhaus.org/sbl and\
-	http://www.abuse.net/sbl.phtml?IP=%A for more details":\
-	:method=http:\
-	:file=www.openbsd.org/spamd/SBL.cidr.gz:
-
-# Mirrored from http://www.spews.org/spews_list_level1.txt
-spews1:\
-	:black:\
-	:msg="SPAM. Your address %A is in the spews level 1 database\n\
-	See http://www.spews.org/ask.cgi?x=%A for more details":\
-	:method=http:\
-	:file=www.openbsd.org/spamd/spews_list_level1.txt.gz:
-
-# Mirrored from http://www.spews.org/spews_list_level2.txt
-spews2:\
-	:black:\
-	:msg="SPAM. Your address %A is in the spews level 2 database\n\
-	See http://www.spews.org/ask.cgi?x=%A for more details":\
-	:method=http:\
-	:file=www.openbsd.org/spamd/spews_list_level2.txt.gz:
-
-# Mirrored from http://www.okean.com/chinacidr.txt
-china:\
-	:black:\
-	:msg="SPAM. Your address %A appears to be from China\n\
-	See http://www.okean.com/asianspamblocks.html for more details":\
-	:method=http:\
-	:file=www.openbsd.org/spamd/chinacidr.txt.gz:
-
-# Mirrored from http://www.okean.com/koreacidr.txt
-korea:\
-	:black:\
-	:msg="SPAM. Your address %A appears to be from Korea\n\
-	See http://www.okean.com/asianspamblocks.html for more details":\
-	:method=http:\
-	:file=www.openbsd.org/spamd/koreacidr.txt.gz:
-
-
-# Whitelists are done like this, and must be added to "all" after each
-# blacklist from which you want the addresses in the whitelist removed.
-#
-#whitelist:\
-#	:white:\
-#	:file=/var/mail/whitelist.txt:
-
-relaydb-black:\
-	:black:\
-	:msg="SPAM. Your address %A is in my relaydb list.":\
-	:method=exec:\
-	:file=relaydb -4lb:
-
-relaydb-white:\
-	:white:\
-	:method=exec:\
-	:file=relaydb -4lw:
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/doc/spamd.conf.5 /usr/home/samm/spamd/work/spamd_3.7/doc/spamd.conf.5
--- /usr/ports/mail/spamd/work/spamd_3.7/doc/spamd.conf.5	Thu Jan 29 19:44:29 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/doc/spamd.conf.5	Thu Jan  1 03:00:00 1970
@@ -1,190 +0,0 @@
-.\"	$OpenBSD: spamd.conf.5,v 1.12 2004/01/29 17:44:29 jmc Exp $
-.\"
-.\" Copyright (c) 2003 Jason L. Wright (jason at thought.net)
-.\" Copyright (c) 2003 Bob Beck
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd March 8, 2003
-.Dt SPAMD.CONF 5
-.Os
-.Sh NAME
-.Nm spamd.conf
-.Nd configuration file read by
-.Xr spamd-setup 8
-for
-.Xr spamd 8
-.Sh SYNOPSIS
-.Nm spamd.conf
-.Sh DESCRIPTION
-The
-.Nm
-file is read by
-.Xr spamd-setup 8
-to configure blacklists and whitelists with corresponding
-.Xr pf 4
-table entries for
-.Xr spamd 8 .
-.Nm
-follows the syntax of configuration databases as documented in
-.Xr getcap 3 .
-Example:
-.Bd -literal -offset indent
-all:\e
-	:spews1:white:myblack:
-
-spews1:\e
-	:black:\e
-	:msg="SPAM. Your address \&%A is in the spews\e
-	level 1 database\ensee http://www.spews.org/ask.cgi?x=\&%A\en":\e
-	:method=http:\e
-	:file=www.spews.org/spews_list_level1.txt:
-
-white:\e
-	:white:\e
-	:method=file:\e
-	:file=/var/mail/mywhite.txt:
-
-myblack:\e
-	:black:\e
-	:msg=/var/mail/myblackmsg.txt:\e
-	:method=file:\e
-	:file=/var/mail/myblack.txt:
-.Ed
-.Pp
-The default configuration file must include the entry
-.Ar all
-which specifies the order in which named blacklists and whitelists
-are to be applied.
-The addresses in a whitelist are removed from the preceding blacklist.
-In the above example, if the address was present in all three lists, blacklists
-.Ar spews1
-and
-.Ar myblack ,
-as well as whitelist
-.Ar white ,
-the address would be removed from blacklist
-.Ar spews1
-by the subsequent
-.Ar white
-whitelist.
-However, the address would not be removed from the
-.Ar myblack
-blacklist.
-To remove all the addresses in
-.Ar white
-from
-.Ar myblack ,
-the configuration
-.Bd -literal -offset indent
-all:\e
-	:spews1:white:myblack:white:
-.Ed
-.Pp
-would be used instead.
-.Pp
-Blacklists and whitelists are then constructed by name;
-blacklists are identified by the capability
-.Ar black ,
-and whitelists by the capability
-.Ar white .
-.Pp
-The source of the addresses for blacklists and whitelists is
-specified using the
-.Ar method
-and
-.Ar file
-capability entries.
-.Pp
-.Ar method
-specifies the method by which to retrieve a file containing a list of
-addresses that consist of the blacklist or whitelist, and may be
-.Ar http ,
-.Ar ftp ,
-.Ar file
-or
-.Ar exec .
-The methods
-.Ar http ,
-.Ar ftp
-and
-.Ar file
-capabilities will make
-.Nm
-retrieve a list of addresses specified in the location in the
-.Ar file
-capability for the list.
-The
-.Ar exec
-capability will make
-.Nm
-spawn the program with arguments indicated in the
-.Ar file
-capability for the list, and reads a list of addresses
-from the output of the program.
-.Pp
-The format of the list of addresses is expected to consist of one
-network block or address per line (optionally followed by a space and
-text that is ignored).
-Comment lines beginning with
-.Ar #
-are ignored.
-Network blocks may be specified in any of the formats as in
-the following example:
-.Bd -literal -offset indent
-# CIDR format
-192.168.20.0/24
-# A start - end range
-192.168.21.0 - 192.168.21.255
-# As a single IP address
-192.168.23.1
-.Ed
-.Pp
-Each blacklist must include a message, specified in the
-.Ar msg
-capability as a string.
-If the
-.Ar msg
-string is enclosed in double quotes, the characters in the quoted string
-are escaped as specified in
-.Xr getcap 3
-with the exception that a colon (:) is allowed in the quoted string.
-The resulting string is used as the message.
-Alternatively, if the
-.Ar msg
-string is not specified in quotes, it is assumed to be a local filename
-from which the message text may be read.
-.Pp
-The message is configured in
-.Xr spamd 8
-to be displayed in the SMTP dialogue to any connections that match
-addresses in the blacklist.
-The sequence \e" in the message will produce a double quote in the output.
-The sequence %% will produce a single % in the output,
-and the sequence \&%A will be expanded in the message by
-.Xr spamd 8
-to display the connecting IP address in the output.
-.Sh SEE ALSO
-.Xr ftp 1 ,
-.Xr pf 4 ,
-.Xr spamd 8 ,
-.Xr spamd-setup 8
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/Makefile /usr/home/samm/spamd/work/spamd_3.7/spamd/Makefile
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/Makefile	Sun Oct  3 16:09:15 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/Makefile	Thu Jan  1 03:00:00 1970
@@ -1,9 +0,0 @@
-#	$OpenBSD: Makefile,v 1.7 2004/02/26 07:28:55 beck Exp $
-
-PROG=	spamd
-SRCS=	spamd.c sdl.c grey.c
-MAN=	spamd.8
-
-CFLAGS+= -Wall -Wstrict-prototypes -ansi
-
-.include <bsd.prog.mk>
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.c /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.c
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.c	Fri Feb  2 10:40:32 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.c	Thu Jan  1 03:00:00 1970
@@ -1,722 +0,0 @@
-/*	$OpenBSD: grey.c,v 1.21 2005/03/12 00:02:07 beck Exp $	*/
-
-/*
- * Copyright (c) 2004,2005 Bob Beck.  All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/fcntl.h>
-#include <sys/wait.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <db.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <time.h>
-#include <unistd.h>
-#include <netdb.h>
-
-#ifdef IPFW
-#include <netinet/ip_fw.h>
-#endif
-
-#include "grey.h"
-
-extern time_t passtime, greyexp, whiteexp, trapexp;
-#ifdef __OpenBSD__
-extern struct syslog_data sdata;
-#else
-#define	syslog_r(l, s, args...)	syslog(l,args)
-#define	openlog_r(i, l, f, s)	openlog(i, l, f)
-extern int sdata;					/* dummy */
-#endif
-extern struct passwd *pw;
-extern u_short cfg_port;
-extern pid_t jail_pid;
-extern FILE * trapcfg;
-extern FILE * grey;
-extern int debug;
-
-size_t whitecount, whitealloc;
-size_t trapcount, trapalloc;
-char **whitelist;
-char **traplist;
-
-char *traplist_name = "spamd-greytrap";
-char *traplist_msg = "\"Your address %A has mailed to spamtraps here\\n\"";
-
-pid_t db_pid = -1;
-int spamdconf;
-
-#ifdef IPFW
-extern int tabno;
-#else
-int pfdev;
-static char *pargv[11]= {
-	"pfctl", "-p", "/dev/pf", "-q", "-t",
-	"spamd-white", "-T", "replace", "-f" "-", NULL
-};
-#endif
-
-/* If the parent gets a signal, kill off the children and exit */
-/* ARGSUSED */
-static void
-sig_term_chld(int sig)
-{
-	if (db_pid != -1)
-		kill(db_pid, SIGTERM);
-	if (jail_pid != -1)
-		kill(jail_pid, SIGTERM);
-	_exit(1);
-}
-
-/*
- * Greatly simplified version from spamd_setup.c  - only
- * sends one blacklist to an already open stream. Has no need
- * to collapse cidr ranges since these are only ever single
- * host hits.
- */
-int
-configure_spamd(char **addrs, int count, FILE *sdc)
-{
-	int i;
-
-	fprintf(sdc, "%s;%s;", traplist_name, traplist_msg);
-	for (i = 0; i < count; i++)
-		fprintf(sdc, "%s/32;", addrs[i]);
-	fprintf(sdc, "\n");
-	fflush(sdc);
-	return(0);
-}
-
-#ifndef IPFW
-int
-configure_pf(char **addrs, int count)
-{
-	FILE *pf = NULL;
-	int i, pdes[2];
-	pid_t pid;
-	char *fdpath;
-	struct sigaction sa;
-
-	sigfillset(&sa.sa_mask);
-	sa.sa_flags = SA_RESTART;
-	sa.sa_handler = sig_term_chld;
-
-	if (debug)
-		fprintf(stderr, "configure_pf - device on fd %d\n", pfdev);
-	if (pfdev < 1 || pfdev > 63)
-		return(-1);
-	if (asprintf(&fdpath, "/dev/fd/%d", pfdev) == -1)
-		return(-1);
-	pargv[2] = fdpath;
-	if (pipe(pdes) != 0) {
-		syslog_r(LOG_INFO, &sdata, "pipe failed (%m)");
-		free(fdpath);
-		fdpath = NULL;
-		return(-1);
-	}
-	signal(SIGCHLD, SIG_DFL);
-	switch (pid = fork()) {
-	case -1:
-		syslog_r(LOG_INFO, &sdata, "fork failed (%m)");
-		free(fdpath);
-		fdpath = NULL;
-		close(pdes[0]);
-		close(pdes[1]);
-		sigaction(SIGCHLD, &sa, NULL);
-		return(-1);
-	case 0:
-		/* child */
-		close(pdes[1]);
-		if (pdes[0] != STDIN_FILENO) {
-			dup2(pdes[0], STDIN_FILENO);
-			close(pdes[0]);
-		}
-		execvp(PATH_PFCTL, pargv);
-		syslog_r(LOG_ERR, &sdata, "can't exec %s:%m", PATH_PFCTL);
-		_exit(1);
-	}
-
-	/* parent */
-	free(fdpath);
-	fdpath = NULL;
-	close(pdes[0]);
-	pf = fdopen(pdes[1], "w");
-	if (pf == NULL) {
-		syslog_r(LOG_INFO, &sdata, "fdopen failed (%m)");
-		close(pdes[1]);
-		sigaction(SIGCHLD, &sa, NULL);
-		return(-1);
-	}
-	for (i = 0; i < count; i++)
-		if (addrs[i] != NULL)
-			fprintf(pf, "%s/32\n", addrs[i]);
-
-	fclose(pf);
-	waitpid(pid, NULL, 0);
-	sigaction(SIGCHLD, &sa, NULL);
-	return(0);
-}
-#else
-int
-configure_pf(char **addrs, int count)
-{
-	static int s = -1;
-	ipfw_table_entry ent;
-	int i;
-
-	if (s == -1)
-		s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-	if (s < 0)
-	{
-		syslog_r(LOG_INFO, &sdata, "IPFW socket unavailable (%m)");
-		return(-1);
-	}
-
-	/* flush the table */	
-	ent.tbl = tabno;
-	if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_FLUSH,  &ent.tbl, sizeof(ent.tbl)) < 0)
-	{
-		syslog_r(LOG_INFO, &sdata, "IPFW setsockopt(IP_FW_TABLE_FLUSH) (%m)");
-		return(-1);
-	}
-
-	for (i = 0; i < count; i++)
-		if (addrs[i] != NULL)
-	{
-		/* add addrs[i] to tabno */
-		ent.tbl = tabno;
-		ent.masklen = 32;
-		ent.value = 0;
-		inet_aton(addrs[i], (struct in_addr *)&ent.addr);
-		if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_ADD,  &ent, sizeof(ent)) < 0)
-		{
-			syslog_r(LOG_INFO, &sdata, "IPFW setsockopt(IP_FW_TABLE_ADD) (%m)");
-			return(-1);
-		}
-	}
-
-	return(0);
-}
-#endif
-
-void
-freeaddrlists(void)
-{
-	int i;
-
-	if (whitelist != NULL)
-		for (i = 0; i < whitecount; i++) {
-			free(whitelist[i]);
-			whitelist[i] = NULL;
-		}
-	whitecount = 0;
-	if (traplist != NULL) {
-		for (i = 0; i < trapcount; i++) {
-			free(traplist[i]);
-			traplist[i] = NULL;
-		}
-	}
-	trapcount = 0;
-}
-
-/* validate, then add to list of addrs to whitelist */
-int
-addwhiteaddr(char *addr)
-{
-	struct addrinfo hints, *res;
-
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;		/*for now*/
-	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
-	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
-	hints.ai_flags = AI_NUMERICHOST;
-
-	if (getaddrinfo(addr, NULL, &hints, &res) == 0) {
-		if (whitecount == whitealloc) {
-			char **tmp;
-
-			tmp = realloc(whitelist,
-			    (whitealloc + 1024) * sizeof(char *));
-			if (tmp == NULL) {
-				freeaddrinfo(res);
-				return(-1);
-			}
-			whitelist = tmp;
-			whitealloc += 1024;
-		}
-		whitelist[whitecount] = strdup(addr);
-		if (whitelist[whitecount] == NULL) {
-			freeaddrinfo(res);
-			return(-1);
-		}
-		whitecount++;
-		freeaddrinfo(res);
-	} else
-		return(-1);
-	return(0);
-}
-
-/* validate, then add to list of addrs to traplist */
-int
-addtrapaddr(char *addr)
-{
-	struct addrinfo hints, *res;
-
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;		/*for now*/
-	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
-	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
-	hints.ai_flags = AI_NUMERICHOST;
-
-	if (getaddrinfo(addr, NULL, &hints, &res) == 0) {
-		if (trapcount == trapalloc) {
-			char **tmp;
-
-			tmp = realloc(traplist,
-			    (trapalloc + 1024) * sizeof(char *));
-			if (tmp == NULL) {
-				freeaddrinfo(res);
-				return(-1);
-			}
-			traplist = tmp;
-			trapalloc += 1024;
-		}
-		traplist[trapcount] = strdup(addr);
-		if (traplist[trapcount] == NULL) {
-			freeaddrinfo(res);
-			return(-1);
-		}
-		trapcount++;
-		freeaddrinfo(res);
-	} else
-		return(-1);
-	return(0);
-}
-
-
-int
-greyscan(char *dbname)
-{
-	BTREEINFO	btreeinfo;
-	DBT		dbk, dbd;
-	DB		*db;
-	struct gdata	gd;
-	int		r;
-	char		*a = NULL;
-	size_t		asiz = 0;
-	time_t now = time(NULL);
-
-	/* walk db, expire, and whitelist */
-
-	memset(&btreeinfo, 0, sizeof(btreeinfo));
-	db = dbopen(dbname, O_EXLOCK|O_RDWR, 0600, DB_BTREE, &btreeinfo);
-	if (db == NULL) {
-		syslog_r(LOG_INFO, &sdata, "dbopen failed (%m)");
-		return(-1);
-	}
-	memset(&dbk, 0, sizeof(dbk));
-	memset(&dbd, 0, sizeof(dbd));
-	for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r;
-	    r = db->seq(db, &dbk, &dbd, R_NEXT)) {
-		if ((dbk.size < 1) || dbd.size != sizeof(struct gdata)) {
-			goto bad;
-		}
-		if (asiz < dbk.size + 1) {
-			char *tmp;
-
-			tmp = realloc(a, dbk.size * 2);
-			if (tmp == NULL)
-				goto bad;
-			a = tmp;
-			asiz = dbk.size * 2;
-		}
-		memset(a, 0, asiz);
-		memcpy(a, dbk.data, dbk.size);
-		memcpy(&gd, dbd.data, sizeof(gd));
-		if (gd.expire <= now && gd.pcount != -2) {
-			/* get rid of entry */
-			if (debug)
-				fprintf(stderr, "deleting %s\n", a);
-			if (db->del(db, &dbk, 0)) {
-				goto bad;
-			}
-			db->sync(db, 0);
-		} else if (gd.pcount == -1) {
-			/* this is a greytrap hit */
-			if ((addtrapaddr(a) == -1) &&
-			    db->del(db, &dbk, 0)) {
-				db->sync(db, 0);
-				goto bad;
-			}
-			if (debug)
-				fprintf(stderr, "trapped %s\n", a);
-		} else if (gd.pcount >= 0 && gd.pass <= now) {
-			int tuple = 0;
-			char *cp;
-
-			/*
-			 * remove this tuple-keyed  entry from db
-			 * add address to whitelist
-			 * add an address-keyed entry to db
-			 */
-			cp = strchr(a, '\n');
-			if (cp != NULL) {
-				tuple = 1;
-				*cp = '\0';
-			}
-			if ((addwhiteaddr(a) == -1) && db->del(db, &dbk, 0)) {
-				db->sync(db, 0);
-				goto bad;
-			}
-			if (tuple) {
-				if (db->del(db, &dbk, 0)) {
-					db->sync(db, 0);
-					goto bad;
-				}
-				/* re-add entry, keyed only by ip */
-				memset(&dbk, 0, sizeof(dbk));
-				dbk.size = strlen(a);
-				dbk.data = a;
-				memset(&dbd, 0, sizeof(dbd));
-				gd.expire = now + whiteexp;
-				dbd.size = sizeof(gd);
-				dbd.data = &gd;
-				if (db->put(db, &dbk, &dbd, 0)) {
-					db->sync(db, 0);
-					goto bad;
-				}
-				db->sync(db, 0);
-				syslog_r(LOG_DEBUG, &sdata,
-				    "whitelisting %s in %s", a, dbname);
-
-			}
-			if (debug)
-				fprintf(stderr, "whitelisted %s\n", a);
-		}
-	}
-	configure_pf(whitelist, whitecount);
-	if (configure_spamd(traplist, trapcount, trapcfg) == -1)
-		syslog_r(LOG_DEBUG, &sdata, "configure_spamd failed");
-
-	db->close(db);
-	db = NULL;
-	freeaddrlists();
-	free(a);
-	a = NULL;
-	asiz = 0;
-	return(0);
- bad:
-	db->close(db);
-	db = NULL;
-	freeaddrlists();
-	free(a);
-	a = NULL;
-	asiz = 0;
-	return(-1);
-}
-
-int
-greyupdate(char *dbname, char *ip, char *from, char *to)
-{
-	BTREEINFO	btreeinfo;
-	DBT		dbk, dbd;
-	DB		*db;
-	char		*key = NULL;
-	char		*trap = NULL;
-	char		*lookup;
-	struct gdata	gd;
-	time_t		now, expire;
-	int		i, r, spamtrap;
-
-	now = time(NULL);
-
-	/* open with lock, find record, update, close, unlock */
-	memset(&btreeinfo, 0, sizeof(btreeinfo));
-	db = dbopen(dbname, O_EXLOCK|O_RDWR, 0600, DB_BTREE, &btreeinfo);
-	if (db == NULL)
-		return(-1);
-	if (asprintf(&key, "%s\n%s\n%s", ip, from, to) == -1)
-		goto bad;
-	if ((trap = strdup(to)) == NULL)
-		goto bad;
-	for (i = 0; trap[i] != '\0'; i++)
-		if (isupper(trap[i]))
-			trap[i] = tolower(trap[i]);
-	memset(&dbk, 0, sizeof(dbk));
-	dbk.size = strlen(trap);
-	dbk.data = trap;
-	memset(&dbd, 0, sizeof(dbd));
-	r = db->get(db, &dbk, &dbd, 0);
-	if (r == -1)
-		goto bad;
-	if (r) {
-		/* didn't exist - so this doesn't match a known spamtrap  */
-		spamtrap = 0;
-		lookup = key;
-		expire = greyexp;
-	} else {
-		/* To: address is a spamtrap, so add as a greytrap entry */
-		spamtrap = 1;
-		lookup = ip;
-		expire = trapexp;
-	}
-	memset(&dbk, 0, sizeof(dbk));
-	dbk.size = strlen(lookup);
-	dbk.data = lookup;
-	memset(&dbd, 0, sizeof(dbd));
-	r = db->get(db, &dbk, &dbd, 0);
-	if (r == -1)
-		goto bad;
-	if (r) {
-		/* new entry */
-		memset(&gd, 0, sizeof(gd));
-		gd.first = now;
-		gd.bcount = 1;
-		gd.pcount = spamtrap ? -1 : 0;
-		gd.pass = now + expire;
-		gd.expire = now + expire;
-		memset(&dbk, 0, sizeof(dbk));
-		dbk.size = strlen(lookup);
-		dbk.data = lookup;
-		memset(&dbd, 0, sizeof(dbd));
-		dbd.size = sizeof(gd);
-		dbd.data = &gd;
-		r = db->put(db, &dbk, &dbd, 0);
-		db->sync(db, 0);
-		if (r)
-			goto bad;
-		if (debug)
-			fprintf(stderr, "added %s %s\n",
-			    spamtrap ? "greytrap entry for" : "", lookup);
-	} else {
-		/* existing entry */
-		if (dbd.size != sizeof(gd)) {
-			/* whatever this is, it doesn't belong */
-			db->del(db, &dbk, 0);
-			db->sync(db, 0);
-			goto bad;
-		}
-		memcpy(&gd, dbd.data, sizeof(gd));
-		gd.bcount++;
-		gd.pcount = spamtrap ? -1 : 0;
-		if (gd.first + passtime < now)
-			gd.pass = now;
-		memset(&dbk, 0, sizeof(dbk));
-		dbk.size = strlen(lookup);
-		dbk.data = lookup;
-		memset(&dbd, 0, sizeof(dbd));
-		dbd.size = sizeof(gd);
-		dbd.data = &gd;
-		r = db->put(db, &dbk, &dbd, 0);
-		db->sync(db, 0);
-		if (r)
-			goto bad;
-		if (debug)
-			fprintf(stderr, "updated %s\n", lookup);
-	}
-	free(key);
-	key = NULL;
-	free(trap);
-	trap = NULL;
-	db->close(db);
-	db = NULL;
-	return(0);
- bad:
-	free(key);
-	key = NULL;
-	free(trap);
-	trap = NULL;
-	db->close(db);
-	db = NULL;
-	return(-1);
-}
-
-int
-greyreader(void)
-{
-	char ip[32], from[MAX_MAIL], to[MAX_MAIL], *buf;
-	size_t len;
-	int state;
-	struct addrinfo hints, *res;
-
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;		/*for now*/
-	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
-	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
-	hints.ai_flags = AI_NUMERICHOST;
-
-	state = 0;
-	if (grey == NULL) {
-		syslog_r(LOG_ERR, &sdata, "No greylist pipe stream!\n");
-		exit(1);
-	}
-	while ((buf = fgetln(grey, &len))) {
-		if (buf[len - 1] == '\n')
-			buf[len - 1] = '\0';
-		else
-			/* all valid lines end in \n */
-			continue;
-		if (strlen(buf) < 4)
-			continue;
-
-		switch (state) {
-		case 0:
-			if (strncmp(buf, "IP:", 3) != 0)
-				break;
-			strlcpy(ip, buf+3, sizeof(ip));
-			if (getaddrinfo(ip, NULL, &hints, &res) == 0) {
-				freeaddrinfo(res);
-				state = 1;
-			} else
-				state = 0;
-			break;
-		case 1:
-			if (strncmp(buf, "FR:", 3) != 0) {
-				state = 0;
-				break;
-			}
-			strlcpy(from, buf+3, sizeof(from));
-			state = 2;
-			break;
-		case 2:
-			if (strncmp(buf, "TO:", 3) != 0) {
-				state = 0;
-				break;
-			}
-			strlcpy(to, buf+3, sizeof(to));
-			if (debug)
-				fprintf(stderr,
-				    "Got Grey IP %s from %s to %s\n",
-				    ip, from, to);
-			greyupdate(PATH_SPAMD_DB, ip, from, to);
-			state = 0;
-			break;
-		}
-	}
-	return (0);
-}
-
-void
-greyscanner(void)
-{
-	int i;
-
-	for (;;) {
-		sleep(DB_SCAN_INTERVAL);
-		i = greyscan(PATH_SPAMD_DB);
-		if (i == -1)
-			syslog_r(LOG_NOTICE, &sdata, "scan of %s failed",
-			    PATH_SPAMD_DB);
-	}
-	/* NOTREACHED */
-}
-
-int
-greywatcher(void)
-{
-	int i;
-	struct sigaction sa;
-
-#ifndef IPFW
-	pfdev = open("/dev/pf", O_RDWR);
-	if (pfdev == -1) {
-		syslog_r(LOG_ERR, &sdata, "open of /dev/pf failed (%m)");
-		exit(1);
-	}
-#endif
-
-	/* check to see if /var/db/spamd exists, if not, create it */
-	if ((i = open(PATH_SPAMD_DB, O_RDWR, 0)) == -1 && errno == ENOENT) {
-		i = open(PATH_SPAMD_DB, O_RDWR|O_CREAT, 0644);
-		if (i == -1) {
-			syslog_r(LOG_ERR, &sdata, "create %s failed (%m)",
-			    PATH_SPAMD_DB);
-			exit(1);
-		}
-		/* if we are dropping privs, chown to that user */
-		if (pw && (fchown(i, pw->pw_uid, pw->pw_gid) == -1)) {
-			syslog_r(LOG_ERR, &sdata, "chown %s failed (%m)",
-			    PATH_SPAMD_DB);
-			exit(1);
-		}
-	}
-	if (i != -1)
-		close(i);
-
-	/*
-	 * lose root, continue as non-root user
-	 * XXX Should not be _spamd - as it currently is.
-	 */
-	if (pw) {
-		setgroups(1, &pw->pw_gid);
-		setegid(pw->pw_gid);
-		setgid(pw->pw_gid);
-		seteuid(pw->pw_uid);
-		setuid(pw->pw_uid);
-	}
-
-	db_pid = fork();
-	switch(db_pid) {
-	case -1:
-		syslog_r(LOG_ERR, &sdata, "fork failed (%m)");
-		exit(1);
-	case 0:
-		/*
-		 * child, talks to jailed spamd over greypipe,
-		 * updates db. has no access to pf.
-		 */
-#ifndef IPFW
-		close(pfdev);
-#endif
-		setproctitle("(%s update)", PATH_SPAMD_DB);
-		greyreader();
-		/* NOTREACHED */
-		_exit(1);
-	}
-	/*
-	 * parent, scans db periodically for changes and updates
-	 * pf whitelist table accordingly.
-	 */
-	fclose(grey);
-	sigfillset(&sa.sa_mask);
-	sa.sa_flags = SA_RESTART;
-	sa.sa_handler = sig_term_chld;
-	sigaction(SIGTERM, &sa, NULL);
-	sigaction(SIGHUP,  &sa, NULL);
-	sigaction(SIGCHLD, &sa, NULL);
-	sigaction(SIGINT, &sa, NULL);
-
-#ifndef IPFW
-	setproctitle("(pf <spamd-white> update)");
-#else
-	setproctitle("(ipfw white table update)");
-#endif
-	greyscanner();
-	/* NOTREACHED */
-	exit(1);
-}
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.c.orig /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.c.orig
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.c.orig	Tue Apr 12 20:22:17 2005
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.c.orig	Thu Jan  1 03:00:00 1970
@@ -1,662 +0,0 @@
-/*	$OpenBSD: grey.c,v 1.21 2005/03/12 00:02:07 beck Exp $	*/
-
-/*
- * Copyright (c) 2004,2005 Bob Beck.  All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/fcntl.h>
-#include <sys/wait.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <db.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <time.h>
-#include <unistd.h>
-#include <netdb.h>
-
-#include "grey.h"
-
-extern time_t passtime, greyexp, whiteexp, trapexp;
-#ifdef __OpenBSD__
-extern struct syslog_data sdata;
-#else
-#define	syslog_r(l, s, args...)	syslog(l,args)
-#define	openlog_r(i, l, f, s)	openlog(i, l, f)
-extern int sdata;					/* dummy */
-#endif
-extern struct passwd *pw;
-extern u_short cfg_port;
-extern pid_t jail_pid;
-extern FILE * trapcfg;
-extern FILE * grey;
-extern int debug;
-
-size_t whitecount, whitealloc;
-size_t trapcount, trapalloc;
-char **whitelist;
-char **traplist;
-
-char *traplist_name = "spamd-greytrap";
-char *traplist_msg = "\"Your address %A has mailed to spamtraps here\\n\"";
-
-pid_t db_pid = -1;
-int pfdev;
-int spamdconf;
-
-static char *pargv[11]= {
-	"pfctl", "-p", "/dev/pf", "-q", "-t",
-	"spamd-white", "-T", "replace", "-f" "-", NULL
-};
-
-/* If the parent gets a signal, kill off the children and exit */
-/* ARGSUSED */
-static void
-sig_term_chld(int sig)
-{
-	if (db_pid != -1)
-		kill(db_pid, SIGTERM);
-	if (jail_pid != -1)
-		kill(jail_pid, SIGTERM);
-	_exit(1);
-}
-
-/*
- * Greatly simplified version from spamd_setup.c  - only
- * sends one blacklist to an already open stream. Has no need
- * to collapse cidr ranges since these are only ever single
- * host hits.
- */
-int
-configure_spamd(char **addrs, int count, FILE *sdc)
-{
-	int i;
-
-	fprintf(sdc, "%s;%s;", traplist_name, traplist_msg);
-	for (i = 0; i < count; i++)
-		fprintf(sdc, "%s/32;", addrs[i]);
-	fprintf(sdc, "\n");
-	fflush(sdc);
-	return(0);
-}
-
-int
-configure_pf(char **addrs, int count)
-{
-	FILE *pf = NULL;
-	int i, pdes[2];
-	pid_t pid;
-	char *fdpath;
-	struct sigaction sa;
-
-	sigfillset(&sa.sa_mask);
-	sa.sa_flags = SA_RESTART;
-	sa.sa_handler = sig_term_chld;
-
-	if (debug)
-		fprintf(stderr, "configure_pf - device on fd %d\n", pfdev);
-	if (pfdev < 1 || pfdev > 63)
-		return(-1);
-	if (asprintf(&fdpath, "/dev/fd/%d", pfdev) == -1)
-		return(-1);
-	pargv[2] = fdpath;
-	if (pipe(pdes) != 0) {
-		syslog_r(LOG_INFO, &sdata, "pipe failed (%m)");
-		free(fdpath);
-		fdpath = NULL;
-		return(-1);
-	}
-	signal(SIGCHLD, SIG_DFL);
-	switch (pid = fork()) {
-	case -1:
-		syslog_r(LOG_INFO, &sdata, "fork failed (%m)");
-		free(fdpath);
-		fdpath = NULL;
-		close(pdes[0]);
-		close(pdes[1]);
-		sigaction(SIGCHLD, &sa, NULL);
-		return(-1);
-	case 0:
-		/* child */
-		close(pdes[1]);
-		if (pdes[0] != STDIN_FILENO) {
-			dup2(pdes[0], STDIN_FILENO);
-			close(pdes[0]);
-		}
-		execvp(PATH_PFCTL, pargv);
-		syslog_r(LOG_ERR, &sdata, "can't exec %s:%m", PATH_PFCTL);
-		_exit(1);
-	}
-
-	/* parent */
-	free(fdpath);
-	fdpath = NULL;
-	close(pdes[0]);
-	pf = fdopen(pdes[1], "w");
-	if (pf == NULL) {
-		syslog_r(LOG_INFO, &sdata, "fdopen failed (%m)");
-		close(pdes[1]);
-		sigaction(SIGCHLD, &sa, NULL);
-		return(-1);
-	}
-	for (i = 0; i < count; i++)
-		if (addrs[i] != NULL)
-			fprintf(pf, "%s/32\n", addrs[i]);
-	fclose(pf);
-	waitpid(pid, NULL, 0);
-	sigaction(SIGCHLD, &sa, NULL);
-	return(0);
-}
-
-void
-freeaddrlists(void)
-{
-	int i;
-
-	if (whitelist != NULL)
-		for (i = 0; i < whitecount; i++) {
-			free(whitelist[i]);
-			whitelist[i] = NULL;
-		}
-	whitecount = 0;
-	if (traplist != NULL) {
-		for (i = 0; i < trapcount; i++) {
-			free(traplist[i]);
-			traplist[i] = NULL;
-		}
-	}
-	trapcount = 0;
-}
-
-/* validate, then add to list of addrs to whitelist */
-int
-addwhiteaddr(char *addr)
-{
-	struct addrinfo hints, *res;
-
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;		/*for now*/
-	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
-	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
-	hints.ai_flags = AI_NUMERICHOST;
-
-	if (getaddrinfo(addr, NULL, &hints, &res) == 0) {
-		if (whitecount == whitealloc) {
-			char **tmp;
-
-			tmp = realloc(whitelist,
-			    (whitealloc + 1024) * sizeof(char *));
-			if (tmp == NULL) {
-				freeaddrinfo(res);
-				return(-1);
-			}
-			whitelist = tmp;
-			whitealloc += 1024;
-		}
-		whitelist[whitecount] = strdup(addr);
-		if (whitelist[whitecount] == NULL) {
-			freeaddrinfo(res);
-			return(-1);
-		}
-		whitecount++;
-		freeaddrinfo(res);
-	} else
-		return(-1);
-	return(0);
-}
-
-/* validate, then add to list of addrs to traplist */
-int
-addtrapaddr(char *addr)
-{
-	struct addrinfo hints, *res;
-
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;		/*for now*/
-	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
-	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
-	hints.ai_flags = AI_NUMERICHOST;
-
-	if (getaddrinfo(addr, NULL, &hints, &res) == 0) {
-		if (trapcount == trapalloc) {
-			char **tmp;
-
-			tmp = realloc(traplist,
-			    (trapalloc + 1024) * sizeof(char *));
-			if (tmp == NULL) {
-				freeaddrinfo(res);
-				return(-1);
-			}
-			traplist = tmp;
-			trapalloc += 1024;
-		}
-		traplist[trapcount] = strdup(addr);
-		if (traplist[trapcount] == NULL) {
-			freeaddrinfo(res);
-			return(-1);
-		}
-		trapcount++;
-		freeaddrinfo(res);
-	} else
-		return(-1);
-	return(0);
-}
-
-
-int
-greyscan(char *dbname)
-{
-	BTREEINFO	btreeinfo;
-	DBT		dbk, dbd;
-	DB		*db;
-	struct gdata	gd;
-	int		r;
-	char		*a = NULL;
-	size_t		asiz = 0;
-	time_t now = time(NULL);
-
-	/* walk db, expire, and whitelist */
-
-	memset(&btreeinfo, 0, sizeof(btreeinfo));
-	db = dbopen(dbname, O_EXLOCK|O_RDWR, 0600, DB_BTREE, &btreeinfo);
-	if (db == NULL) {
-		syslog_r(LOG_INFO, &sdata, "dbopen failed (%m)");
-		return(-1);
-	}
-	memset(&dbk, 0, sizeof(dbk));
-	memset(&dbd, 0, sizeof(dbd));
-	for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r;
-	    r = db->seq(db, &dbk, &dbd, R_NEXT)) {
-		if ((dbk.size < 1) || dbd.size != sizeof(struct gdata)) {
-			goto bad;
-		}
-		if (asiz < dbk.size + 1) {
-			char *tmp;
-
-			tmp = realloc(a, dbk.size * 2);
-			if (tmp == NULL)
-				goto bad;
-			a = tmp;
-			asiz = dbk.size * 2;
-		}
-		memset(a, 0, asiz);
-		memcpy(a, dbk.data, dbk.size);
-		memcpy(&gd, dbd.data, sizeof(gd));
-		if (gd.expire <= now && gd.pcount != -2) {
-			/* get rid of entry */
-			if (debug)
-				fprintf(stderr, "deleting %s\n", a);
-			if (db->del(db, &dbk, 0)) {
-				goto bad;
-			}
-			db->sync(db, 0);
-		} else if (gd.pcount == -1) {
-			/* this is a greytrap hit */
-			if ((addtrapaddr(a) == -1) &&
-			    db->del(db, &dbk, 0)) {
-				db->sync(db, 0);
-				goto bad;
-			}
-			if (debug)
-				fprintf(stderr, "trapped %s\n", a);
-		} else if (gd.pcount >= 0 && gd.pass <= now) {
-			int tuple = 0;
-			char *cp;
-
-			/*
-			 * remove this tuple-keyed  entry from db
-			 * add address to whitelist
-			 * add an address-keyed entry to db
-			 */
-			cp = strchr(a, '\n');
-			if (cp != NULL) {
-				tuple = 1;
-				*cp = '\0';
-			}
-			if ((addwhiteaddr(a) == -1) && db->del(db, &dbk, 0)) {
-				db->sync(db, 0);
-				goto bad;
-			}
-			if (tuple) {
-				if (db->del(db, &dbk, 0)) {
-					db->sync(db, 0);
-					goto bad;
-				}
-				/* re-add entry, keyed only by ip */
-				memset(&dbk, 0, sizeof(dbk));
-				dbk.size = strlen(a);
-				dbk.data = a;
-				memset(&dbd, 0, sizeof(dbd));
-				gd.expire = now + whiteexp;
-				dbd.size = sizeof(gd);
-				dbd.data = &gd;
-				if (db->put(db, &dbk, &dbd, 0)) {
-					db->sync(db, 0);
-					goto bad;
-				}
-				db->sync(db, 0);
-				syslog_r(LOG_DEBUG, &sdata,
-				    "whitelisting %s in %s", a, dbname);
-
-			}
-			if (debug)
-				fprintf(stderr, "whitelisted %s\n", a);
-		}
-	}
-	configure_pf(whitelist, whitecount);
-	if (configure_spamd(traplist, trapcount, trapcfg) == -1)
-		syslog_r(LOG_DEBUG, &sdata, "configure_spamd failed");
-
-	db->close(db);
-	db = NULL;
-	freeaddrlists();
-	free(a);
-	a = NULL;
-	asiz = 0;
-	return(0);
- bad:
-	db->close(db);
-	db = NULL;
-	freeaddrlists();
-	free(a);
-	a = NULL;
-	asiz = 0;
-	return(-1);
-}
-
-int
-greyupdate(char *dbname, char *ip, char *from, char *to)
-{
-	BTREEINFO	btreeinfo;
-	DBT		dbk, dbd;
-	DB		*db;
-	char		*key = NULL;
-	char		*trap = NULL;
-	char		*lookup;
-	struct gdata	gd;
-	time_t		now, expire;
-	int		i, r, spamtrap;
-
-	now = time(NULL);
-
-	/* open with lock, find record, update, close, unlock */
-	memset(&btreeinfo, 0, sizeof(btreeinfo));
-	db = dbopen(dbname, O_EXLOCK|O_RDWR, 0600, DB_BTREE, &btreeinfo);
-	if (db == NULL)
-		return(-1);
-	if (asprintf(&key, "%s\n%s\n%s", ip, from, to) == -1)
-		goto bad;
-	if ((trap = strdup(to)) == NULL)
-		goto bad;
-	for (i = 0; trap[i] != '\0'; i++)
-		if (isupper(trap[i]))
-			trap[i] = tolower(trap[i]);
-	memset(&dbk, 0, sizeof(dbk));
-	dbk.size = strlen(trap);
-	dbk.data = trap;
-	memset(&dbd, 0, sizeof(dbd));
-	r = db->get(db, &dbk, &dbd, 0);
-	if (r == -1)
-		goto bad;
-	if (r) {
-		/* didn't exist - so this doesn't match a known spamtrap  */
-		spamtrap = 0;
-		lookup = key;
-		expire = greyexp;
-	} else {
-		/* To: address is a spamtrap, so add as a greytrap entry */
-		spamtrap = 1;
-		lookup = ip;
-		expire = trapexp;
-	}
-	memset(&dbk, 0, sizeof(dbk));
-	dbk.size = strlen(lookup);
-	dbk.data = lookup;
-	memset(&dbd, 0, sizeof(dbd));
-	r = db->get(db, &dbk, &dbd, 0);
-	if (r == -1)
-		goto bad;
-	if (r) {
-		/* new entry */
-		memset(&gd, 0, sizeof(gd));
-		gd.first = now;
-		gd.bcount = 1;
-		gd.pcount = spamtrap ? -1 : 0;
-		gd.pass = now + expire;
-		gd.expire = now + expire;
-		memset(&dbk, 0, sizeof(dbk));
-		dbk.size = strlen(lookup);
-		dbk.data = lookup;
-		memset(&dbd, 0, sizeof(dbd));
-		dbd.size = sizeof(gd);
-		dbd.data = &gd;
-		r = db->put(db, &dbk, &dbd, 0);
-		db->sync(db, 0);
-		if (r)
-			goto bad;
-		if (debug)
-			fprintf(stderr, "added %s %s\n",
-			    spamtrap ? "greytrap entry for" : "", lookup);
-	} else {
-		/* existing entry */
-		if (dbd.size != sizeof(gd)) {
-			/* whatever this is, it doesn't belong */
-			db->del(db, &dbk, 0);
-			db->sync(db, 0);
-			goto bad;
-		}
-		memcpy(&gd, dbd.data, sizeof(gd));
-		gd.bcount++;
-		gd.pcount = spamtrap ? -1 : 0;
-		if (gd.first + passtime < now)
-			gd.pass = now;
-		memset(&dbk, 0, sizeof(dbk));
-		dbk.size = strlen(lookup);
-		dbk.data = lookup;
-		memset(&dbd, 0, sizeof(dbd));
-		dbd.size = sizeof(gd);
-		dbd.data = &gd;
-		r = db->put(db, &dbk, &dbd, 0);
-		db->sync(db, 0);
-		if (r)
-			goto bad;
-		if (debug)
-			fprintf(stderr, "updated %s\n", lookup);
-	}
-	free(key);
-	key = NULL;
-	free(trap);
-	trap = NULL;
-	db->close(db);
-	db = NULL;
-	return(0);
- bad:
-	free(key);
-	key = NULL;
-	free(trap);
-	trap = NULL;
-	db->close(db);
-	db = NULL;
-	return(-1);
-}
-
-int
-greyreader(void)
-{
-	char ip[32], from[MAX_MAIL], to[MAX_MAIL], *buf;
-	size_t len;
-	int state;
-	struct addrinfo hints, *res;
-
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;		/*for now*/
-	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
-	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
-	hints.ai_flags = AI_NUMERICHOST;
-
-	state = 0;
-	if (grey == NULL) {
-		syslog_r(LOG_ERR, &sdata, "No greylist pipe stream!\n");
-		exit(1);
-	}
-	while ((buf = fgetln(grey, &len))) {
-		if (buf[len - 1] == '\n')
-			buf[len - 1] = '\0';
-		else
-			/* all valid lines end in \n */
-			continue;
-		if (strlen(buf) < 4)
-			continue;
-
-		switch (state) {
-		case 0:
-			if (strncmp(buf, "IP:", 3) != 0)
-				break;
-			strlcpy(ip, buf+3, sizeof(ip));
-			if (getaddrinfo(ip, NULL, &hints, &res) == 0) {
-				freeaddrinfo(res);
-				state = 1;
-			} else
-				state = 0;
-			break;
-		case 1:
-			if (strncmp(buf, "FR:", 3) != 0) {
-				state = 0;
-				break;
-			}
-			strlcpy(from, buf+3, sizeof(from));
-			state = 2;
-			break;
-		case 2:
-			if (strncmp(buf, "TO:", 3) != 0) {
-				state = 0;
-				break;
-			}
-			strlcpy(to, buf+3, sizeof(to));
-			if (debug)
-				fprintf(stderr,
-				    "Got Grey IP %s from %s to %s\n",
-				    ip, from, to);
-			greyupdate(PATH_SPAMD_DB, ip, from, to);
-			state = 0;
-			break;
-		}
-	}
-	return (0);
-}
-
-void
-greyscanner(void)
-{
-	int i;
-
-	for (;;) {
-		sleep(DB_SCAN_INTERVAL);
-		i = greyscan(PATH_SPAMD_DB);
-		if (i == -1)
-			syslog_r(LOG_NOTICE, &sdata, "scan of %s failed",
-			    PATH_SPAMD_DB);
-	}
-	/* NOTREACHED */
-}
-
-int
-greywatcher(void)
-{
-	int i;
-	struct sigaction sa;
-
-	pfdev = open("/dev/pf", O_RDWR);
-	if (pfdev == -1) {
-		syslog_r(LOG_ERR, &sdata, "open of /dev/pf failed (%m)");
-		exit(1);
-	}
-
-	/* check to see if /var/db/spamd exists, if not, create it */
-	if ((i = open(PATH_SPAMD_DB, O_RDWR, 0)) == -1 && errno == ENOENT) {
-		i = open(PATH_SPAMD_DB, O_RDWR|O_CREAT, 0644);
-		if (i == -1) {
-			syslog_r(LOG_ERR, &sdata, "create %s failed (%m)",
-			    PATH_SPAMD_DB);
-			exit(1);
-		}
-		/* if we are dropping privs, chown to that user */
-		if (pw && (fchown(i, pw->pw_uid, pw->pw_gid) == -1)) {
-			syslog_r(LOG_ERR, &sdata, "chown %s failed (%m)",
-			    PATH_SPAMD_DB);
-			exit(1);
-		}
-	}
-	if (i != -1)
-		close(i);
-
-	/*
-	 * lose root, continue as non-root user
-	 * XXX Should not be _spamd - as it currently is.
-	 */
-	if (pw) {
-		setgroups(1, &pw->pw_gid);
-		setegid(pw->pw_gid);
-		setgid(pw->pw_gid);
-		seteuid(pw->pw_uid);
-		setuid(pw->pw_uid);
-	}
-
-	db_pid = fork();
-	switch(db_pid) {
-	case -1:
-		syslog_r(LOG_ERR, &sdata, "fork failed (%m)");
-		exit(1);
-	case 0:
-		/*
-		 * child, talks to jailed spamd over greypipe,
-		 * updates db. has no access to pf.
-		 */
-		close(pfdev);
-		setproctitle("(%s update)", PATH_SPAMD_DB);
-		greyreader();
-		/* NOTREACHED */
-		_exit(1);
-	}
-	/*
-	 * parent, scans db periodically for changes and updates
-	 * pf whitelist table accordingly.
-	 */
-	fclose(grey);
-	sigfillset(&sa.sa_mask);
-	sa.sa_flags = SA_RESTART;
-	sa.sa_handler = sig_term_chld;
-	sigaction(SIGTERM, &sa, NULL);
-	sigaction(SIGHUP,  &sa, NULL);
-	sigaction(SIGCHLD, &sa, NULL);
-	sigaction(SIGINT, &sa, NULL);
-
-	setproctitle("(pf <spamd-white> update)");
-	greyscanner();
-	/* NOTREACHED */
-	exit(1);
-}
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.h /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.h
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.h	Fri Feb  2 10:40:32 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.h	Thu Jan  1 03:00:00 1970
@@ -1,37 +0,0 @@
-/*	$OpenBSD: grey.h,v 1.5 2005/03/11 23:09:53 beck Exp $	*/
-
-/*
- * Copyright (c) 2004 Bob Beck.  All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define MAX_MAIL 1024 /* how big an email address will we consider */
-#define PASSTIME (60 * 25) /* pass after first retry seen after 25 mins */
-#define GREYEXP (60 * 60 * 4) /* remove grey entries after 4 hours */
-#define WHITEEXP (60 * 60 * 24 * 36) /* remove white entries after 36 days */
-#define TRAPEXP (60 * 60 * 24) /* hitting a spamtrap blacklists for a day */
-#define PATH_PFCTL "/sbin/pfctl"
-#define PATH_IPFW "/sbin/ipfw"
-#define DB_SCAN_INTERVAL 60
-#define PATH_SPAMD_DB "/var/db/spamd"
-
-struct gdata {
-	time_t first;  /* when did we see it first */
-	time_t pass;   /* when was it whitelisted */
-	time_t expire; /* when will we get rid of this entry */
-	int bcount;    /* how many times have we blocked it */
-	int pcount;    /* how many times passed, or -1 for spamtrap */
-};
-
-extern int greywatcher(void);
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.h.orig /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.h.orig
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.h.orig	Tue Apr 12 20:21:48 2005
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.h.orig	Thu Jan  1 03:00:00 1970
@@ -1,36 +0,0 @@
-/*	$OpenBSD: grey.h,v 1.5 2005/03/11 23:09:53 beck Exp $	*/
-
-/*
- * Copyright (c) 2004 Bob Beck.  All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define MAX_MAIL 1024 /* how big an email address will we consider */
-#define PASSTIME (60 * 25) /* pass after first retry seen after 25 mins */
-#define GREYEXP (60 * 60 * 4) /* remove grey entries after 4 hours */
-#define WHITEEXP (60 * 60 * 24 * 36) /* remove white entries after 36 days */
-#define TRAPEXP (60 * 60 * 24) /* hitting a spamtrap blacklists for a day */
-#define PATH_PFCTL "/sbin/pfctl"
-#define DB_SCAN_INTERVAL 60
-#define PATH_SPAMD_DB "/var/db/spamd"
-
-struct gdata {
-	time_t first;  /* when did we see it first */
-	time_t pass;   /* when was it whitelisted */
-	time_t expire; /* when will we get rid of this entry */
-	int bcount;    /* how many times have we blocked it */
-	int pcount;    /* how many times passed, or -1 for spamtrap */
-};
-
-extern int greywatcher(void);
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamd/grey.o and /usr/home/samm/spamd/work/spamd_3.7/spamd/grey.o differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/sdl.c /usr/home/samm/spamd/work/spamd_3.7/spamd/sdl.c
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/sdl.c	Sun Oct  3 16:09:15 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/sdl.c	Thu Jan  1 03:00:00 1970
@@ -1,271 +0,0 @@
-/*	$OpenBSD: sdl.c,v 1.12 2004/02/26 08:18:56 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003 Bob Beck.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * sdl.c - Implement spamd source lists
- *
- * This consists of everything we need to do to determine which lists
- * someone is on. Spamd gets the connecting address, and looks it up
- * against all lists to determine what deferral messages to feed back
- * to the connecting machine. - The redirection to spamd will happen
- * from pf in the kernel, first macth will rdr to us. Spamd (along with
- * setup) must keep track of *all* matches, so as to tell someone all the
- * lists that they are on.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "sdl.h"
-
-static void sdl_free(struct sdlist *);
-static void sdl_clear(struct sdlist *);
-int match_addr(struct sdaddr *a, struct sdaddr *m, struct sdaddr *b,
-    sa_family_t af);
-
-extern int debug;
-struct sdlist *blacklists = NULL;
-int blc = 0, blu = 0;
-
-int
-sdl_add(char *sdname, char *sdstring, char ** addrs, int addrc)
-{
-	int i, index = -1;
-	char astring[40];
-	unsigned int maskbits;
-	struct sdaddr *m, *n;
-
-	/*
-	 * if a blacklist of same tag name is already there, replace it,
-	 * otherwise append.
-	 */
-	for (i = 0; i < blu; i++) {
-		if (strcmp(blacklists[i].tag, sdname) == 0) {
-			index = i;
-			break;
-		}
-	}
-	if (index != -1) {
-		if (debug > 0)
-			printf("replacing list %s\n", blacklists[index].tag);
-		sdl_free(&blacklists[index]);
-	} else {
-		if (debug > 0)
-			printf("adding list %s\n", sdname);
-		index = blu;
-	}
-	if (index == blu && blu == blc) {
-		struct sdlist *tmp;
-
-		tmp = realloc(blacklists, (blc + 128) *
-		    sizeof(struct sdlist));
-		if (tmp == NULL)
-			return (-1);
-		blacklists = tmp;
-		blc += 128;
-		sdl_clear(&blacklists[index]);
-	}
-
-	if ((blacklists[index].tag = strdup(sdname)) == NULL)
-		goto misc_error;
-	if ((blacklists[index].string = strdup(sdstring)) == NULL)
-		goto misc_error;
-
-	blacklists[index].naddrs = addrc;
-
-	/*
-	 * Cycle through addrs, converting. We assume they are correctly
-	 * formatted v4 and v6 addrs, if they don't all convert correctly, the
-	 * add fails. Each address should be address/maskbits
-	 */
-	blacklists[index].addrs = malloc(addrc * sizeof(struct sdentry));
-	if (blacklists[index].addrs == NULL)
-		goto misc_error;
-
-	for(i = 0; i < addrc; i++) {
-		int j, k, af;
-
-		n = &blacklists[index].addrs[i].sda;
-		m = &blacklists[index].addrs[i].sdm;
-
-		j = sscanf(addrs[i], "%39[^/]/%u", astring, &maskbits);
-		if (j != 2)
-			goto parse_error;
-		if (maskbits > 128)
-			goto parse_error;
-		/*
-		 * sanity check! we don't allow a 0 mask -
-		 * don't blacklist the entire net.
-		 */
-		if (maskbits == 0)
-			goto parse_error;
-		if (strchr(astring, ':') != NULL)
-			af = AF_INET6;
-		else
-			af = AF_INET;
-		if (af == AF_INET && maskbits > 32)
-			goto parse_error;
-		j = inet_pton(af, astring, n);
-		if (j != 1)
-			goto parse_error;
-		if (debug > 0)
-			printf("added %s/%u\n", astring, maskbits);
-
-		/* set mask, borrowed from pf */
-		k = 0;
-		for (j = 0; j < 4; j++)
-			m->addr32[j] = 0;
-		while (maskbits >= 32) {
-			m->addr32[k++] = 0xffffffff;
-			maskbits -= 32;
-		}
-		for (j = 31; j > 31 - maskbits; --j)
-			m->addr32[k] |= (1 << j);
-		if (maskbits)
-			m->addr32[k] = htonl(m->addr32[k]);
-
-		/* mask off address bits that won't ever be used */
-		for (j = 0; j < 4; j++)
-			n->addr32[j] = n->addr32[j] & m->addr32[j];
-	}
-	if (index == blu) {
-		blu++;
-		blacklists[blu].tag = NULL;
-	}
-	return (0);
- parse_error:
-	if (debug > 0)
-		printf("sdl_add: parse error, \"%s\"\n", addrs[i]);
- misc_error:
-	sdl_free(&blacklists[index]);
-	return (-1);
-}
-
-
-/*
- * Return 1 if the addresses a (with mask m) matches address b
- * otherwise return 0. It is assumed that address a has been
- * pre-masked out, we only need to mask b.
- */
-int
-match_addr(struct sdaddr *a, struct sdaddr *m, struct sdaddr *b,
-    sa_family_t af)
-{
-	int	match = 0;
-
-	switch (af) {
-	case AF_INET:
-		if ((a->addr32[0]) ==
-		    (b->addr32[0] & m->addr32[0]))
-			match++;
-		break;
-	case AF_INET6:
-		if (((a->addr32[0]) ==
-		    (b->addr32[0] & m->addr32[0])) &&
-		    ((a->addr32[1]) ==
-		    (b->addr32[1] & m->addr32[1])) &&
-		    ((a->addr32[2]) ==
-		    (b->addr32[2] & m->addr32[2])) &&
-		    ((a->addr32[3]) ==
-		    (b->addr32[3] & m->addr32[3])))
-			match++;
-		break;
-	}
-	return (match);
-}
-
-
-/*
- * Given an address and address family
- * return list of pointers to matching nodes. or NULL if none.
- */
-struct sdlist **
-sdl_lookup(struct sdlist *head, int af, void * src)
-{
-	int i, matches = 0;
-	struct sdlist *sdl;
-	struct sdentry *sda;
-	struct sdaddr *source = (struct sdaddr *) src;
-	int sdnewlen = 0;
-	struct sdlist **sdnew = NULL;
-
-	if (head == NULL)
-		return (NULL);
-	else
-		sdl = head;
-	while (sdl->tag != NULL) {
-		for (i = 0; i < sdl->naddrs; i++) {
-			sda = sdl->addrs + i;
-			if (match_addr(&sda->sda, &sda->sdm, source, af)) {
-				if (matches == sdnewlen) {
-					struct sdlist **tmp;
-
-					tmp = realloc(sdnew,
-					    (sdnewlen + 128) *
-					    sizeof(struct sdlist *));
-					if (tmp == NULL)
-						/*
-						 * XXX out of memory -
-						 * return what we have
-						 */
-						return (sdnew);
-					sdnew = tmp;
-					sdnewlen += 128;
-				}
-				sdnew[matches]= sdl;
-				matches++;
-				sdnew[matches]=NULL;
-				break;
-			}
-		}
-		sdl++;
-	}
-	return (sdnew);
-}
-
-static void
-sdl_free(struct sdlist *sdl)
-{
-	free(sdl->tag);
-	free(sdl->string);
-	free(sdl->addrs);
-	sdl_clear(sdl);
-}
-
-static void
-sdl_clear(struct sdlist *sdl)
-{
-	sdl->tag = NULL;
-	sdl->string = NULL;
-	sdl->addrs = NULL;
-	sdl->naddrs = 0;
-}
-
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/sdl.h /usr/home/samm/spamd/work/spamd_3.7/spamd/sdl.h
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/sdl.h	Sun Oct  3 16:09:15 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/sdl.h	Thu Jan  1 03:00:00 1970
@@ -1,71 +0,0 @@
-/*	$OpenBSD: sdl.h,v 1.2 2004/02/26 08:18:56 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003 Bob Beck, Kjell Wooding.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SDL_H_
-#define _SDL_H_
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#ifdef __OpenBSD__
-#include <netinet/ip_ipsp.h>
-#endif
-
-/* spamd source list */
-struct sdlist {
-	char *tag;	/* sdlist source name */
-	char *string;	/* Format (451) string with no smtp code or \r\n */
-	struct sdentry *addrs;
-	size_t naddrs;
-};
-
-/* yeah. Stolen from pf */
-struct sdaddr {
-	union {
-		struct in_addr		v4;
-		struct in6_addr		v6;
-		u_int8_t		addr8[16];
-		u_int16_t		addr16[8];
-		u_int32_t		addr32[4];
-	} _sda;		    /* 128-bit address */
-#define v4	_sda.v4
-#define v6	_sda.v6
-#define addr8	_sda.addr8
-#define addr16	_sda.addr16
-#define addr32	_sda.addr32
-};
-
-/* spamd netblock (black) list */
-struct sdentry {
-	struct sdaddr sda;
-	struct sdaddr sdm;
-};
-
-
-extern int	sdl_add(char *, char *, char **, int);
-extern struct sdlist **sdl_lookup(struct sdlist *head,
-	    int af, void * src);
-
-#endif	/* _SDL_H_ */
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamd/sdl.o and /usr/home/samm/spamd/work/spamd_3.7/spamd/sdl.o differ
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd and /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.8 /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.8
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.8	Fri Feb  2 10:40:32 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.8	Thu Jan  1 03:00:00 1970
@@ -1,473 +0,0 @@
-.\"	$OpenBSD: spamd.8,v 1.53 2005/03/11 23:09:53 beck Exp $
-.\"
-.\" Copyright (c) 2002 Theo de Raadt.  All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd December 18, 2002
-.Dt SPAMD 8
-.Os
-.Sh NAME
-.Nm spamd
-.Nd spam deferral daemon
-.Sh SYNOPSIS
-.Nm spamd
-.Bk -words
-.Op Fl 45dgv
-.Op Fl B Ar maxblack
-.Op Fl b Ar address
-.Op Fl c Ar maxcon
-.Op Fl G Ar passtime:greyexp:whiteexp
-.Op Fl n Ar name
-.Op Fl p Ar port
-.Op Fl r Ar reply
-.Op Fl s Ar secs
-.Op Fl w Ar window
-.Ek
-.Sh DESCRIPTION
-.Nm
-is a fake
-.Xr sendmail 8 Ns -like
-daemon which rejects false mail.
-If the
-.Xr pf 4
-or
-.Xr ipfw 4
-packet filter is configured to redirect port 25 (SMTP) to this daemon,
-it will attempt to waste the time and resources of the spam sender.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl 4
-For black listed entries, return error code 450 to the spammer (default).
-.It Fl 5
-For black-listed entries, return error code 550 to the spammer.
-.It Fl B Ar maxblack
-The maximum number of concurrent blacklisted connections to allow in
-greylisting mode.
-This value may not be greater than maxcon (see below).
-The default is maxcon \- 100
-.It Fl b Ar address
-Specify the local address to which
-.Nm
-is to
-.Xr bind 2 .
-By default
-.Nm
-listens on all local addresses.
-.It Fl c Ar maxcon
-The maximum number of concurrent connections to allow.
-The default is 800.
-.It Fl d
-Debug mode.
-.Nm
-does not
-.Xr fork 2
-into the background.
-.It Fl G Ar passtime:greyexp:whiteexp
-Adjust the three time parameters for greylisting; see
-.Sx GREYLISTING
-below.
-.Ar passtime
-defaults to 25 (minutes),
-.Ar greyexp
-to 4 (hours),
-and
-.Ar whiteexp
-to 864 (hours, approximately 36 days).
-.It Fl g
-Greylisting mode; see
-.Sx GREYLISTING
-below.
-.It Fl n Ar name
-The SMTP version banner that is reported upon initial connection.
-.It Fl p Ar port
-Specify a different port number from the default port that
-.Nm
-should listen for redirected SMTP connections on.
-The default port is found by looking for the named service
-.Em spamd
-using
-.Xr getservbyname 3 .
-.It Fl r Ar reply
-The SMTP error to return to the spammer, i.e. 450, 451, 550.
-This defaults to 450.
-.It Fl s Ar secs
-Delay each character sent to the client by the specified
-amount of seconds.
-Defaults to 1.
-.It Fl v
-Enable verbose logging.
-By default
-.Nm
-logs connections, disconnections and blacklist matches to
-.Xr syslogd 8
-at
-.Dv LOG_INFO
-level.
-With verbose logging enabled, message detail
-including subject and recipient information is logged at
-.Dv LOG_INFO ,
-along with the message body and SMTP dialogue being logged at
-.Dv LOG_DEBUG
-level.
-.It Fl w Ar window
-Set the socket receive buffer to this many bytes, adjusting the window size.
-.El
-.Pp
-.Nm
-is designed to be very efficient so that it does not slow down the
-receiving machine.
-Spam is never accepted, but always rejected with either a 450 or 550
-error message.
-The normal way that spam has been dealt with in the past is to either
-accept and drop, or outright block.
-When configured to use 450 responses,
-.Nm
-takes neither of these actions: it rejects the mail back to the senders'
-queue.
-.Pp
-.Nm
-is best started from
-.Xr rc 8
-in conjunction with the
-.Xr spamd-setup 8
-which processes a list of spammers' addresses, and applies appropriate
-.Xr pfctl 8
-.Em rdr
-or
-.Xr ipfw 8
-.Em fwd
-rules.
-.Xr spamd-setup 8
-is run from
-.Xr cron 8 .
-.Sh REDIRECTING SMTP CONNECTIONS
-.Ss "When using PF"
-With
-.Xr pf 4 ,
-connections to port 25 (SMTP) can be redirected to another host or port,
-based on the source address of the sender.
-The
-.Em rdr
-rules used for this purpose are described in
-.Xr pf.conf 5 .
-The rules can be loaded into a
-.Em table
-to simplify handling.
-.Bd -literal -offset 4n
-table <spamd> persist
-rdr pass inet proto tcp from <spamd> to any \e
-    port smtp -> 127.0.0.1 port 8025
-.Ed
-.Pp
-Any addresses in table
-.Em <spamd>
-are then redirected to
-.Nm
-running on port 8025.
-Addresses can be loaded into the
-.Em table ,
-like:
-.Bd -literal -offset 4n
-# pfctl -q -t spamd -T replace -f /usr/local/share/spammers
-.Ed
-.Pp
-.Xr spamd-setup 8
-can also be used to load addresses into the
-.Em <spamd>
-table.
-
-
-.Xr spamd-setup 8
-also has the added benefit of being able to remove addresses from
-blacklists, and will connect to
-.Nm
-over a localhost socket, giving
-.Nm
-information about each source of blacklist addresses, as well as custom
-rejection messages for each blacklist source
-that can be used to let any real person whose mail
-is deferred by spamd know why their address has been listed
-from sending mail.
-This is important as it allows legitimate mail
-senders to pressure spam sources into behaving properly so that they
-may be removed from the relevant blacklists.
-
-.Ss "If compiled with IPFW"
-With
-.Xr ipfw 4 ,
-the syntax for redirection of TCP sessions is quite different
-from that of
-.Xr pf 4 .
-The
-.Em fwd
-rule used for this purpose are described in
-.Xr ipfw 8 .
-The rules should be added to the ruleset called by /etc/rc.firewall
-to be present at boot time.
-.Bd -literal -offset 4n
-fwd 127.0.0.1,8025 tcp from table(2) to me 25 in
-allow tcp from table(1) to me 25 in
-fwd 127.0.0.1,8025 tcp from any to me 25 in
-.Ed
-.Pp
-Any addresses in the blacklist table
-.Em 2
-and not in the whitelist table
-.Em 1
-are then redirected to
-.Nm
-running on port 8025.
-Addresses can be loaded into the blacklist
-.Em table ,
-like:
-.Bd -literal -offset 4n
-# ipfw table 1 add a.b.c.d/x
-.Ed
-.Pp
-.Xr spamd-setup 8
-can also be used to load addresses into the blacklist table
-.Em 2 .
-.Pp
-The 
-.Op Fl t Ar table_no
-option to 
-.Em spamd 
-and 
-.Em spamd-setup 
-can be used to change the default table
-numbers.
-
-.Sh CONFIGURATION CONNECTIONS
-.Nm
-listens for configuration connections on the port identified by the
-named service
-.Em spamd-cfg
-(see
-.Xr services 5 ) .
-The configuration socket listens only on the INADDR_LOOPBACK
-address.
-Configuration of spamd is done by connecting to the configuration
-socket, and sending blacklist information, one blacklist per line.
-Each blacklist consists of a name, a message to reject mail
-with, and addresses in CIDR format, all separated by semicolons (;):
-.Bd -literal -offset indent
-tag;"rejection message";aaa.bbb.ccc.ddd/mm;aaa.bbb.ccc.ddd/mm
-.Ed
-.Pp
-The rejection message must be inside double quotes.
-A \e" will produce a double quote in the output.
-\en will produce a newline.
-%A will expand to the connecting IP address in dotted quad format.
-%% may be used to produce a single % in the output.
-\e\e will produce a single \e.
-.Nm
-will reject mail by displaying all the messages from all blacklists in which
-a connecting address is matched.
-.Xr spamd-setup 8
-is normally used to configure this information.
-.Sh GREYLISTING
-When run in greylisting mode,
-.Nm
-will run in the normal mode for any addresses blacklisted by
-.Xr spamd-setup 8 .
-Connections from addresses not blacklisted by
-.Xr spamd-setup 8
-will be considered for greylisting.
-Such connections will not be stuttered at or delayed,
-and will receive the pleasantly innocuous temporary failure of:
-.Bd -literal -offset 4n
-451 Temporary failure, please try again later.
-.Ed
-.Pp
-in the SMTP dialogue immediately after the recipient is specified.
-.Nm
-will use the db file in
-.Pa /var/db/spamd
-to track these non-blacklisted connections to
-.Nm
-by connecting IP address, envelope-from, and envelope-to, or "tuple" for
-short.
-.Pp
-A previously unseen tuple is added to the
-.Pa /var/db/spamd
-database, recording the time an initial connection attempt was seen.
-After
-.Em passtime
-minutes if
-.Nm
-sees a retried attempt to deliver mail for the same tuple,
-.Nm
-will whitelist the connecting address by adding it as a
-whitelist entry to
-.Pa /var/db/spamd .
-.Pp
-.Nm
-regularly scans the
-.Pa /var/db/spamd
-database and configures all whitelist addresses as the
-.Em spamd-white
-.Xr pf 4
-table.
-The
-.Em spamd-white
-table must be used to allow connections to pass to the
-real MTA as in the following
-.Xr pf.conf 5
-example:
-.Bd -literal -offset 4n
-table <spamd> persist
-table <spamd-white> persist
-rdr pass inet proto tcp from <spamd> to any \e
-    port smtp -> 127.0.0.1 port 8025
-rdr pass inet proto tcp from !<spamd-white> to any port smtp \e
-    -> 127.0.0.1 port 8025
-.Ed
-.Pp
-With this configuration,
-.Xr spamd-setup 8
-should be used to configure blacklists in
-.Nm
-and add them to the
-.Em spamd
-.Xr pf 4
-table.
-These connections will be stuttered at by
-.Nm .
-All other connections not in the
-.Em spamd-white
-table are redirected to
-.Nm
-but will not be stuttered at.
-Such connections will be
-considered for greylisting and eventual whitelisting (by addition
-to the
-.Em spamd-white
-table so they are not redirected) if they retry mail delivery.
-.Pp
-.Nm
-removes tuple entries from the
-.Pa /var/db/spamd
-database if delivery has not been retried within
-.Em greyexp
-hours from the initial time a connection is seen.
-The default is 4 hours as this is the most common setting after which
-MTA's will give up attempting to retry delivery of a message.
-.Pp
-.Nm
-removes whitelist entries from the
-.Pa /var/db/spamd
-database if no mail delivery activity has been seen from the
-whitelisted address by
-.Xr spamlogd 8
-within
-.Em whiteexp
-hours from the initial time an address
-is whitelisted.
-The default is 36 days to allow for the delivery of
-monthly mailing list digests without greylist delays every time.
-.Xr spamlogd 8
-should be used to update the whitelist entries in
-.Pa /var/db/spamd
-when connections are seen to pass to the real MTA on the
-.Em smtp
-port.
-.Sh GREYTRAPPING
-When greylisting with
-.Nm
-it may be useful to define
-.Em spamtrap
-destination addresses to catch spammers as they send mail from greylisted
-hosts.
-Such
-.Em spamtrap
-addresses affect only greylisted connections to
-.Nm
-and are used to temporarily blacklist a host that is obviously sending spam.
-Unused email addresses or email addresses on spammers' lists are very
-useful for this.
-When a host that is currently greylisted attempts to send mail to a
-.Em spamtrap
-address, it is blacklisted for 24 hours by adding the host to the
-.Nm
-blacklist
-.Em spamd-greytrap .
-Spamtrap addresses are added to the
-.Pa /var/db/spamd
-database with the following
-.Xr spamdb 8
-command:
-.Pp
-.Dl spamdb -T -a \&"<spamtrap at mydomain.org>\&"
-.Pp
-It should be entered exactly as the address will be used in the SMTP dialogue.
-See
-.Xr spamdb 8
-for further details.
-.Sh LOGGING
-.Nm
-sends log messages to
-.Xr syslogd 8
-using
-.Em facility
-daemon and, with increasing verbosity,
-.Em level
-err, warn, info and debug.
-The following
-.Xr syslog.conf 5
-section can be used to log connection details to a dedicated file:
-.Bd -literal -offset indent
-!spamd
-daemon.err;daemon.warn;daemon.info	/var/log/spamd
-.Ed
-.Sh FILES
-/usr/local/etc/spamd.conf
-.Sh SEE ALSO
-.Xr pf.conf 5 ,
-.Xr services 5 ,
-.Xr spamd.conf 5 ,
-.Xr syslog.conf 5 ,
-.Xr pfctl 8 ,
-.Xr spamd-setup 8 ,
-.Xr spamdb 8 ,
-.Xr spamlogd 8 ,
-.Xr syslogd 8
-.Sh HISTORY
-The
-.Nm
-command
-appeared in
-.Ox 3.3 .
-.Sh BUGS
-.Nm
-currently uses the user
-.Dq _spamd
-outside a chroot jail when running in greylisting mode, and requires
-the greylisting database in
-.Pa /var/db/spamd
-to be owned by the
-.Dq _spamd
-user.
-This is wrong and should change to a distinct user from the
-one used by the chrooted
-.Nm
-process.
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.8.bak /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.8.bak
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.8.bak	Fri Feb  2 10:40:32 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.8.bak	Thu Jan  1 03:00:00 1970
@@ -1,473 +0,0 @@
-.\"	$OpenBSD: spamd.8,v 1.53 2005/03/11 23:09:53 beck Exp $
-.\"
-.\" Copyright (c) 2002 Theo de Raadt.  All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd December 18, 2002
-.Dt SPAMD 8
-.Os
-.Sh NAME
-.Nm spamd
-.Nd spam deferral daemon
-.Sh SYNOPSIS
-.Nm spamd
-.Bk -words
-.Op Fl 45dgv
-.Op Fl B Ar maxblack
-.Op Fl b Ar address
-.Op Fl c Ar maxcon
-.Op Fl G Ar passtime:greyexp:whiteexp
-.Op Fl n Ar name
-.Op Fl p Ar port
-.Op Fl r Ar reply
-.Op Fl s Ar secs
-.Op Fl w Ar window
-.Ek
-.Sh DESCRIPTION
-.Nm
-is a fake
-.Xr sendmail 8 Ns -like
-daemon which rejects false mail.
-If the
-.Xr pf 4
-or
-.Xr ipfw 4
-packet filter is configured to redirect port 25 (SMTP) to this daemon,
-it will attempt to waste the time and resources of the spam sender.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl 4
-For black listed entries, return error code 450 to the spammer (default).
-.It Fl 5
-For black-listed entries, return error code 550 to the spammer.
-.It Fl B Ar maxblack
-The maximum number of concurrent blacklisted connections to allow in
-greylisting mode.
-This value may not be greater than maxcon (see below).
-The default is maxcon \- 100
-.It Fl b Ar address
-Specify the local address to which
-.Nm
-is to
-.Xr bind 2 .
-By default
-.Nm
-listens on all local addresses.
-.It Fl c Ar maxcon
-The maximum number of concurrent connections to allow.
-The default is 800.
-.It Fl d
-Debug mode.
-.Nm
-does not
-.Xr fork 2
-into the background.
-.It Fl G Ar passtime:greyexp:whiteexp
-Adjust the three time parameters for greylisting; see
-.Sx GREYLISTING
-below.
-.Ar passtime
-defaults to 25 (minutes),
-.Ar greyexp
-to 4 (hours),
-and
-.Ar whiteexp
-to 864 (hours, approximately 36 days).
-.It Fl g
-Greylisting mode; see
-.Sx GREYLISTING
-below.
-.It Fl n Ar name
-The SMTP version banner that is reported upon initial connection.
-.It Fl p Ar port
-Specify a different port number from the default port that
-.Nm
-should listen for redirected SMTP connections on.
-The default port is found by looking for the named service
-.Em spamd
-using
-.Xr getservbyname 3 .
-.It Fl r Ar reply
-The SMTP error to return to the spammer, i.e. 450, 451, 550.
-This defaults to 450.
-.It Fl s Ar secs
-Delay each character sent to the client by the specified
-amount of seconds.
-Defaults to 1.
-.It Fl v
-Enable verbose logging.
-By default
-.Nm
-logs connections, disconnections and blacklist matches to
-.Xr syslogd 8
-at
-.Dv LOG_INFO
-level.
-With verbose logging enabled, message detail
-including subject and recipient information is logged at
-.Dv LOG_INFO ,
-along with the message body and SMTP dialogue being logged at
-.Dv LOG_DEBUG
-level.
-.It Fl w Ar window
-Set the socket receive buffer to this many bytes, adjusting the window size.
-.El
-.Pp
-.Nm
-is designed to be very efficient so that it does not slow down the
-receiving machine.
-Spam is never accepted, but always rejected with either a 450 or 550
-error message.
-The normal way that spam has been dealt with in the past is to either
-accept and drop, or outright block.
-When configured to use 450 responses,
-.Nm
-takes neither of these actions: it rejects the mail back to the senders'
-queue.
-.Pp
-.Nm
-is best started from
-.Xr rc 8
-in conjunction with the
-.Xr spamd-setup 8
-which processes a list of spammers' addresses, and applies appropriate
-.Xr pfctl 8
-.Em rdr
-or
-.Xr ipfw 8
-.Em fwd
-rules.
-.Xr spamd-setup 8
-is run from
-.Xr cron 8 .
-.Sh REDIRECTING SMTP CONNECTIONS
-.Ss "When using PF"
-With
-.Xr pf 4 ,
-connections to port 25 (SMTP) can be redirected to another host or port,
-based on the source address of the sender.
-The
-.Em rdr
-rules used for this purpose are described in
-.Xr pf.conf 5 .
-The rules can be loaded into a
-.Em table
-to simplify handling.
-.Bd -literal -offset 4n
-table <spamd> persist
-rdr pass inet proto tcp from <spamd> to any \e
-    port smtp -> 127.0.0.1 port 8025
-.Ed
-.Pp
-Any addresses in table
-.Em <spamd>
-are then redirected to
-.Nm
-running on port 8025.
-Addresses can be loaded into the
-.Em table ,
-like:
-.Bd -literal -offset 4n
-# pfctl -q -t spamd -T replace -f /usr/local/share/spammers
-.Ed
-.Pp
-.Xr spamd-setup 8
-can also be used to load addresses into the
-.Em <spamd>
-table.
-
-
-.Xr spamd-setup 8
-also has the added benefit of being able to remove addresses from
-blacklists, and will connect to
-.Nm
-over a localhost socket, giving
-.Nm
-information about each source of blacklist addresses, as well as custom
-rejection messages for each blacklist source
-that can be used to let any real person whose mail
-is deferred by spamd know why their address has been listed
-from sending mail.
-This is important as it allows legitimate mail
-senders to pressure spam sources into behaving properly so that they
-may be removed from the relevant blacklists.
-
-.Ss "If compiled with IPFW"
-With
-.Xr ipfw 4 ,
-the syntax for redirection of TCP sessions is quite different
-from that of
-.Xr pf 4 .
-The
-.Em fwd
-rule used for this purpose are described in
-.Xr ipfw 8 .
-The rules should be added to the ruleset called by /etc/rc.firewall
-to be present at boot time.
-.Bd -literal -offset 4n
-fwd 127.0.0.1,8025 tcp from table(2) to me 25 in
-allow tcp from table(1) to me 25 in
-fwd 127.0.0.1,8025 tcp from any to me 25 in
-.Ed
-.Pp
-Any addresses in the blacklist table
-.Em 2
-and not in the whitelist table
-.Em 1
-are then redirected to
-.Nm
-running on port 8025.
-Addresses can be loaded into the blacklist
-.Em table ,
-like:
-.Bd -literal -offset 4n
-# ipfw table 1 add a.b.c.d/x
-.Ed
-.Pp
-.Xr spamd-setup 8
-can also be used to load addresses into the blacklist table
-.Em 2 .
-.Pp
-The 
-.Op Fl t Ar table_no
-option to 
-.Em spamd 
-and 
-.Em spamd-setup 
-can be used to change the default table
-numbers.
-
-.Sh CONFIGURATION CONNECTIONS
-.Nm
-listens for configuration connections on the port identified by the
-named service
-.Em spamd-cfg
-(see
-.Xr services 5 ) .
-The configuration socket listens only on the INADDR_LOOPBACK
-address.
-Configuration of spamd is done by connecting to the configuration
-socket, and sending blacklist information, one blacklist per line.
-Each blacklist consists of a name, a message to reject mail
-with, and addresses in CIDR format, all separated by semicolons (;):
-.Bd -literal -offset indent
-tag;"rejection message";aaa.bbb.ccc.ddd/mm;aaa.bbb.ccc.ddd/mm
-.Ed
-.Pp
-The rejection message must be inside double quotes.
-A \e" will produce a double quote in the output.
-\en will produce a newline.
-%A will expand to the connecting IP address in dotted quad format.
-%% may be used to produce a single % in the output.
-\e\e will produce a single \e.
-.Nm
-will reject mail by displaying all the messages from all blacklists in which
-a connecting address is matched.
-.Xr spamd-setup 8
-is normally used to configure this information.
-.Sh GREYLISTING
-When run in greylisting mode,
-.Nm
-will run in the normal mode for any addresses blacklisted by
-.Xr spamd-setup 8 .
-Connections from addresses not blacklisted by
-.Xr spamd-setup 8
-will be considered for greylisting.
-Such connections will not be stuttered at or delayed,
-and will receive the pleasantly innocuous temporary failure of:
-.Bd -literal -offset 4n
-451 Temporary failure, please try again later.
-.Ed
-.Pp
-in the SMTP dialogue immediately after the recipient is specified.
-.Nm
-will use the db file in
-.Pa /var/db/spamd
-to track these non-blacklisted connections to
-.Nm
-by connecting IP address, envelope-from, and envelope-to, or "tuple" for
-short.
-.Pp
-A previously unseen tuple is added to the
-.Pa /var/db/spamd
-database, recording the time an initial connection attempt was seen.
-After
-.Em passtime
-minutes if
-.Nm
-sees a retried attempt to deliver mail for the same tuple,
-.Nm
-will whitelist the connecting address by adding it as a
-whitelist entry to
-.Pa /var/db/spamd .
-.Pp
-.Nm
-regularly scans the
-.Pa /var/db/spamd
-database and configures all whitelist addresses as the
-.Em spamd-white
-.Xr pf 4
-table.
-The
-.Em spamd-white
-table must be used to allow connections to pass to the
-real MTA as in the following
-.Xr pf.conf 5
-example:
-.Bd -literal -offset 4n
-table <spamd> persist
-table <spamd-white> persist
-rdr pass inet proto tcp from <spamd> to any \e
-    port smtp -> 127.0.0.1 port 8025
-rdr pass inet proto tcp from !<spamd-white> to any port smtp \e
-    -> 127.0.0.1 port 8025
-.Ed
-.Pp
-With this configuration,
-.Xr spamd-setup 8
-should be used to configure blacklists in
-.Nm
-and add them to the
-.Em spamd
-.Xr pf 4
-table.
-These connections will be stuttered at by
-.Nm .
-All other connections not in the
-.Em spamd-white
-table are redirected to
-.Nm
-but will not be stuttered at.
-Such connections will be
-considered for greylisting and eventual whitelisting (by addition
-to the
-.Em spamd-white
-table so they are not redirected) if they retry mail delivery.
-.Pp
-.Nm
-removes tuple entries from the
-.Pa /var/db/spamd
-database if delivery has not been retried within
-.Em greyexp
-hours from the initial time a connection is seen.
-The default is 4 hours as this is the most common setting after which
-MTA's will give up attempting to retry delivery of a message.
-.Pp
-.Nm
-removes whitelist entries from the
-.Pa /var/db/spamd
-database if no mail delivery activity has been seen from the
-whitelisted address by
-.Xr spamlogd 8
-within
-.Em whiteexp
-hours from the initial time an address
-is whitelisted.
-The default is 36 days to allow for the delivery of
-monthly mailing list digests without greylist delays every time.
-.Xr spamlogd 8
-should be used to update the whitelist entries in
-.Pa /var/db/spamd
-when connections are seen to pass to the real MTA on the
-.Em smtp
-port.
-.Sh GREYTRAPPING
-When greylisting with
-.Nm
-it may be useful to define
-.Em spamtrap
-destination addresses to catch spammers as they send mail from greylisted
-hosts.
-Such
-.Em spamtrap
-addresses affect only greylisted connections to
-.Nm
-and are used to temporarily blacklist a host that is obviously sending spam.
-Unused email addresses or email addresses on spammers' lists are very
-useful for this.
-When a host that is currently greylisted attempts to send mail to a
-.Em spamtrap
-address, it is blacklisted for 24 hours by adding the host to the
-.Nm
-blacklist
-.Em spamd-greytrap .
-Spamtrap addresses are added to the
-.Pa /var/db/spamd
-database with the following
-.Xr spamdb 8
-command:
-.Pp
-.Dl spamdb -T -a \&"<spamtrap at mydomain.org>\&"
-.Pp
-It should be entered exactly as the address will be used in the SMTP dialogue.
-See
-.Xr spamdb 8
-for further details.
-.Sh LOGGING
-.Nm
-sends log messages to
-.Xr syslogd 8
-using
-.Em facility
-daemon and, with increasing verbosity,
-.Em level
-err, warn, info and debug.
-The following
-.Xr syslog.conf 5
-section can be used to log connection details to a dedicated file:
-.Bd -literal -offset indent
-!spamd
-daemon.err;daemon.warn;daemon.info	/var/log/spamd
-.Ed
-.Sh FILES
-/etc/spamd.conf
-.Sh SEE ALSO
-.Xr pf.conf 5 ,
-.Xr services 5 ,
-.Xr spamd.conf 5 ,
-.Xr syslog.conf 5 ,
-.Xr pfctl 8 ,
-.Xr spamd-setup 8 ,
-.Xr spamdb 8 ,
-.Xr spamlogd 8 ,
-.Xr syslogd 8
-.Sh HISTORY
-The
-.Nm
-command
-appeared in
-.Ox 3.3 .
-.Sh BUGS
-.Nm
-currently uses the user
-.Dq _spamd
-outside a chroot jail when running in greylisting mode, and requires
-the greylisting database in
-.Pa /var/db/spamd
-to be owned by the
-.Dq _spamd
-user.
-This is wrong and should change to a distinct user from the
-one used by the chrooted
-.Nm
-process.
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.8.gz and /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.8.gz differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.8.orig /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.8.orig
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.8.orig	Tue Apr 12 20:21:48 2005
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.8.orig	Thu Jan  1 03:00:00 1970
@@ -1,419 +0,0 @@
-.\"	$OpenBSD: spamd.8,v 1.53 2005/03/11 23:09:53 beck Exp $
-.\"
-.\" Copyright (c) 2002 Theo de Raadt.  All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd December 18, 2002
-.Dt SPAMD 8
-.Os
-.Sh NAME
-.Nm spamd
-.Nd spam deferral daemon
-.Sh SYNOPSIS
-.Nm spamd
-.Bk -words
-.Op Fl 45dgv
-.Op Fl B Ar maxblack
-.Op Fl b Ar address
-.Op Fl c Ar maxcon
-.Op Fl G Ar passtime:greyexp:whiteexp
-.Op Fl n Ar name
-.Op Fl p Ar port
-.Op Fl r Ar reply
-.Op Fl s Ar secs
-.Op Fl w Ar window
-.Ek
-.Sh DESCRIPTION
-.Nm
-is a fake
-.Xr sendmail 8 Ns -like
-daemon which rejects false mail.
-If the
-.Xr pf 4
-packet filter is configured to redirect port 25 (SMTP) to this daemon,
-it will attempt to waste the time and resources of the spam sender.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl 4
-For black listed entries, return error code 450 to the spammer (default).
-.It Fl 5
-For black-listed entries, return error code 550 to the spammer.
-.It Fl B Ar maxblack
-The maximum number of concurrent blacklisted connections to allow in
-greylisting mode.
-This value may not be greater than maxcon (see below).
-The default is maxcon \- 100
-.It Fl b Ar address
-Specify the local address to which
-.Nm
-is to
-.Xr bind 2 .
-By default
-.Nm
-listens on all local addresses.
-.It Fl c Ar maxcon
-The maximum number of concurrent connections to allow.
-The default is 800.
-.It Fl d
-Debug mode.
-.Nm
-does not
-.Xr fork 2
-into the background.
-.It Fl G Ar passtime:greyexp:whiteexp
-Adjust the three time parameters for greylisting; see
-.Sx GREYLISTING
-below.
-.Ar passtime
-defaults to 25 (minutes),
-.Ar greyexp
-to 4 (hours),
-and
-.Ar whiteexp
-to 864 (hours, approximately 36 days).
-.It Fl g
-Greylisting mode; see
-.Sx GREYLISTING
-below.
-.It Fl n Ar name
-The SMTP version banner that is reported upon initial connection.
-.It Fl p Ar port
-Specify a different port number from the default port that
-.Nm
-should listen for redirected SMTP connections on.
-The default port is found by looking for the named service
-.Em spamd
-using
-.Xr getservbyname 3 .
-.It Fl r Ar reply
-The SMTP error to return to the spammer, i.e. 450, 451, 550.
-This defaults to 450.
-.It Fl s Ar secs
-Delay each character sent to the client by the specified
-amount of seconds.
-Defaults to 1.
-.It Fl v
-Enable verbose logging.
-By default
-.Nm
-logs connections, disconnections and blacklist matches to
-.Xr syslogd 8
-at
-.Dv LOG_INFO
-level.
-With verbose logging enabled, message detail
-including subject and recipient information is logged at
-.Dv LOG_INFO ,
-along with the message body and SMTP dialogue being logged at
-.Dv LOG_DEBUG
-level.
-.It Fl w Ar window
-Set the socket receive buffer to this many bytes, adjusting the window size.
-.El
-.Pp
-.Nm
-is designed to be very efficient so that it does not slow down the
-receiving machine.
-Spam is never accepted, but always rejected with either a 450 or 550
-error message.
-The normal way that spam has been dealt with in the past is to either
-accept and drop, or outright block.
-When configured to use 450 responses,
-.Nm
-takes neither of these actions: it rejects the mail back to the senders'
-queue.
-.Pp
-.Nm
-is best started from
-.Xr rc 8
-in conjunction with the
-.Xr spamd-setup 8
-which processes a list of spammers' addresses, and applies appropriate
-.Xr pfctl 8
-.Em rdr
-rules.
-.Xr spamd-setup 8
-is run from
-.Xr cron 8 .
-.Sh REDIRECTING SMTP CONNECTIONS
-With
-.Xr pf 4 ,
-connections to port 25 (SMTP) can be redirected to another host or port,
-based on the source address of the sender.
-The
-.Em rdr
-rules used for this purpose are described in
-.Xr pf.conf 5 .
-The rules can be loaded into a
-.Em table
-to simplify handling.
-.Bd -literal -offset 4n
-table <spamd> persist
-rdr pass inet proto tcp from <spamd> to any \e
-    port smtp -> 127.0.0.1 port 8025
-.Ed
-.Pp
-Any addresses in table
-.Em <spamd>
-are then redirected to
-.Nm
-running on port 8025.
-Addresses can be loaded into the
-.Em table ,
-like:
-.Bd -literal -offset 4n
-# pfctl -q -t spamd -T replace -f /usr/local/share/spammers
-.Ed
-.Pp
-.Xr spamd-setup 8
-can also be used to load addresses into the
-.Em <spamd>
-table.
-.Xr spamd-setup 8
-also has the added benefit of being able to remove addresses from
-blacklists, and will connect to
-.Nm
-over a localhost socket, giving
-.Nm
-information about each source of blacklist addresses, as well as custom
-rejection messages for each blacklist source
-that can be used to let any real person whose mail
-is deferred by spamd know why their address has been listed
-from sending mail.
-This is important as it allows legitimate mail
-senders to pressure spam sources into behaving properly so that they
-may be removed from the relevant blacklists.
-.Sh CONFIGURATION CONNECTIONS
-.Nm
-listens for configuration connections on the port identified by the
-named service
-.Em spamd-cfg
-(see
-.Xr services 5 ) .
-The configuration socket listens only on the INADDR_LOOPBACK
-address.
-Configuration of spamd is done by connecting to the configuration
-socket, and sending blacklist information, one blacklist per line.
-Each blacklist consists of a name, a message to reject mail
-with, and addresses in CIDR format, all separated by semicolons (;):
-.Bd -literal -offset indent
-tag;"rejection message";aaa.bbb.ccc.ddd/mm;aaa.bbb.ccc.ddd/mm
-.Ed
-.Pp
-The rejection message must be inside double quotes.
-A \e" will produce a double quote in the output.
-\en will produce a newline.
-%A will expand to the connecting IP address in dotted quad format.
-%% may be used to produce a single % in the output.
-\e\e will produce a single \e.
-.Nm
-will reject mail by displaying all the messages from all blacklists in which
-a connecting address is matched.
-.Xr spamd-setup 8
-is normally used to configure this information.
-.Sh GREYLISTING
-When run in greylisting mode,
-.Nm
-will run in the normal mode for any addresses blacklisted by
-.Xr spamd-setup 8 .
-Connections from addresses not blacklisted by
-.Xr spamd-setup 8
-will be considered for greylisting.
-Such connections will not be stuttered at or delayed,
-and will receive the pleasantly innocuous temporary failure of:
-.Bd -literal -offset 4n
-451 Temporary failure, please try again later.
-.Ed
-.Pp
-in the SMTP dialogue immediately after the recipient is specified.
-.Nm
-will use the db file in
-.Pa /var/db/spamd
-to track these non-blacklisted connections to
-.Nm
-by connecting IP address, envelope-from, and envelope-to, or "tuple" for
-short.
-.Pp
-A previously unseen tuple is added to the
-.Pa /var/db/spamd
-database, recording the time an initial connection attempt was seen.
-After
-.Em passtime
-minutes if
-.Nm
-sees a retried attempt to deliver mail for the same tuple,
-.Nm
-will whitelist the connecting address by adding it as a
-whitelist entry to
-.Pa /var/db/spamd .
-.Pp
-.Nm
-regularly scans the
-.Pa /var/db/spamd
-database and configures all whitelist addresses as the
-.Em spamd-white
-.Xr pf 4
-table.
-The
-.Em spamd-white
-table must be used to allow connections to pass to the
-real MTA as in the following
-.Xr pf.conf 5
-example:
-.Bd -literal -offset 4n
-table <spamd> persist
-table <spamd-white> persist
-rdr pass inet proto tcp from <spamd> to any \e
-    port smtp -> 127.0.0.1 port 8025
-rdr pass inet proto tcp from !<spamd-white> to any port smtp \e
-    -> 127.0.0.1 port 8025
-.Ed
-.Pp
-With this configuration,
-.Xr spamd-setup 8
-should be used to configure blacklists in
-.Nm
-and add them to the
-.Em spamd
-.Xr pf 4
-table.
-These connections will be stuttered at by
-.Nm .
-All other connections not in the
-.Em spamd-white
-table are redirected to
-.Nm
-but will not be stuttered at.
-Such connections will be
-considered for greylisting and eventual whitelisting (by addition
-to the
-.Em spamd-white
-table so they are not redirected) if they retry mail delivery.
-.Pp
-.Nm
-removes tuple entries from the
-.Pa /var/db/spamd
-database if delivery has not been retried within
-.Em greyexp
-hours from the initial time a connection is seen.
-The default is 4 hours as this is the most common setting after which
-MTA's will give up attempting to retry delivery of a message.
-.Pp
-.Nm
-removes whitelist entries from the
-.Pa /var/db/spamd
-database if no mail delivery activity has been seen from the
-whitelisted address by
-.Xr spamlogd 8
-within
-.Em whiteexp
-hours from the initial time an address
-is whitelisted.
-The default is 36 days to allow for the delivery of
-monthly mailing list digests without greylist delays every time.
-.Xr spamlogd 8
-should be used to update the whitelist entries in
-.Pa /var/db/spamd
-when connections are seen to pass to the real MTA on the
-.Em smtp
-port.
-.Sh GREYTRAPPING
-When greylisting with
-.Nm
-it may be useful to define
-.Em spamtrap
-destination addresses to catch spammers as they send mail from greylisted
-hosts.
-Such
-.Em spamtrap
-addresses affect only greylisted connections to
-.Nm
-and are used to temporarily blacklist a host that is obviously sending spam.
-Unused email addresses or email addresses on spammers' lists are very
-useful for this.
-When a host that is currently greylisted attempts to send mail to a
-.Em spamtrap
-address, it is blacklisted for 24 hours by adding the host to the
-.Nm
-blacklist
-.Em spamd-greytrap .
-Spamtrap addresses are added to the
-.Pa /var/db/spamd
-database with the following
-.Xr spamdb 8
-command:
-.Pp
-.Dl spamdb -T -a \&"<spamtrap at mydomain.org>\&"
-.Pp
-It should be entered exactly as the address will be used in the SMTP dialogue.
-See
-.Xr spamdb 8
-for further details.
-.Sh LOGGING
-.Nm
-sends log messages to
-.Xr syslogd 8
-using
-.Em facility
-daemon and, with increasing verbosity,
-.Em level
-err, warn, info and debug.
-The following
-.Xr syslog.conf 5
-section can be used to log connection details to a dedicated file:
-.Bd -literal -offset indent
-!spamd
-daemon.err;daemon.warn;daemon.info	/var/log/spamd
-.Ed
-.Sh FILES
-/etc/spamd.conf
-.Sh SEE ALSO
-.Xr pf.conf 5 ,
-.Xr services 5 ,
-.Xr spamd.conf 5 ,
-.Xr syslog.conf 5 ,
-.Xr pfctl 8 ,
-.Xr spamd-setup 8 ,
-.Xr spamdb 8 ,
-.Xr spamlogd 8 ,
-.Xr syslogd 8
-.Sh HISTORY
-The
-.Nm
-command
-appeared in
-.Ox 3.3 .
-.Sh BUGS
-.Nm
-currently uses the user
-.Dq _spamd
-outside a chroot jail when running in greylisting mode, and requires
-the greylisting database in
-.Pa /var/db/spamd
-to be owned by the
-.Dq _spamd
-user.
-This is wrong and should change to a distinct user from the
-one used by the chrooted
-.Nm
-process.
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.c /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.c
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.c	Fri Feb  2 10:40:32 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.c	Thu Jan  1 03:00:00 1970
@@ -1,1322 +0,0 @@
-/*	$OpenBSD: spamd.c,v 1.75 2005/03/11 23:09:53 beck Exp $	*/
-
-/*
- * Copyright (c) 2002 Theo de Raadt.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/resource.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <err.h>
-#include <errno.h>
-#include <getopt.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <netdb.h>
-
-#include "sdl.h"
-#include "grey.h"
-
-struct con {
-	int fd;
-	int state;
-	int laststate;
-	int af;
-	struct sockaddr_storage ss;
-	void *ia;
-	char addr[32];
-	char mail[MAX_MAIL], rcpt[MAX_MAIL];
-	struct sdlist **blacklists;
-
-	/*
-	 * we will do stuttering by changing these to time_t's of
-	 * now + n, and only advancing when the time is in the past/now
-	 */
-	time_t r;
-	time_t w;
-	time_t s;
-
-	char ibuf[8192];
-	char *ip;
-	int il;
-	char rend[5];	/* any chars in here causes input termination */
-
-	char *obuf;
-	char *lists;
-	size_t osize;
-	char *op;
-	int ol;
-	int data_lines;
-	int data_body;
-	int stutter;
-	int sr;
-} *con;
-
-void     usage(void);
-char    *grow_obuf(struct con *, int);
-int      parse_configline(char *);
-void     parse_configs(void);
-void     do_config(void);
-int      append_error_string (struct con *, size_t, char *, int, void *);
-void     build_reply(struct  con *);
-void     doreply(struct con *);
-void     setlog(char *, size_t, char *);
-void     initcon(struct con *, int, struct sockaddr *);
-void     closecon(struct con *);
-int      match(const char *, const char *);
-void     nextstate(struct con *);
-void     handler(struct con *);
-void     handlew(struct con *, int one);
-
-char hostname[MAXHOSTNAMELEN];
-#ifdef __OpenBSD__
-struct syslog_data sdata = SYSLOG_DATA_INIT;
-#else
-#define	syslog_r(l, s, args...)	syslog(l,args)
-#define	openlog_r(i, l, f, s)	openlog(i, l, f)
-int sdata = 0;						/* dummy */
-#endif
-char *reply = NULL;
-char *nreply = "450";
-char *spamd = "spamd IP-based SPAM blocker";
-int greypipe[2];
-int trappipe[2];
-FILE *grey;
-FILE *trapcfg;
-time_t passtime = PASSTIME;
-time_t greyexp = GREYEXP;
-time_t whiteexp = WHITEEXP;
-time_t trapexp = TRAPEXP;
-struct passwd *pw;
-pid_t jail_pid = -1;
-u_short cfg_port;
-
-#ifdef IPFW
-int tabno=1;
-#endif
-
-extern struct sdlist *blacklists;
-
-int conffd = -1;
-int trapfd = -1;
-char *cb;
-size_t cbs, cbu;
-
-time_t t;
-
-#define MAXCON 800
-int maxcon = MAXCON;
-int maxblack = MAXCON;
-int blackcount;
-int clients;
-int debug;
-int greylist;
-int verbose;
-int stutter = 1;
-int window;
-#define MAXTIME 400
-
-void
-usage(void)
-{
-	fprintf(stderr,
-	    "usage: spamd [-45dgv] [-B maxblack] [-b address] [-c maxcon]\n");
-	fprintf(stderr,
-	    "             [-G mins:hours:hours] [-n name] [-p port]\n");
-	fprintf(stderr,
-	    "             [-r reply] [-s secs] [-w window]\n");
-#ifdef IPFW
-	fprintf(stderr,
-	    "             [-t table_no]\n");
-#endif
-	exit(1);
-}
-
-char *
-grow_obuf(struct con *cp, int off)
-{
-	char *tmp;
-
-	tmp = realloc(cp->obuf, cp->osize + 8192);
-	if (tmp == NULL) {
-		free(cp->obuf);
-		cp->obuf = NULL;
-		cp->osize = 0;
-		return (NULL);
-	} else {
-		cp->osize += 8192;
-		cp->obuf = tmp;
-		return (cp->obuf + off);
-	}
-}
-
-int
-parse_configline(char *line)
-{
-	char *cp, prev, *name, *msg;
-	static char **av = NULL;
-	static size_t ac = 0;
-	size_t au = 0;
-	int mdone = 0;
-
-	name = line;
-
-	for (cp = name; *cp && *cp != ';'; cp++)
-		;
-	if (*cp != ';')
-		goto parse_error;
-	*cp++ = '\0';
-	msg = cp;
-	if (*cp++ != '"')
-		goto parse_error;
-	prev = '\0';
-	for (; !mdone; cp++) {
-		switch (*cp) {
-		case '\\':
-			if (!prev)
-				prev = *cp;
-			else
-				prev = '\0';
-			break;
-		case '"':
-			if (prev != '\\') {
-				cp++;
-				if (*cp == ';') {
-					mdone = 1;
-					*cp = '\0';
-				} else
-					goto parse_error;
-			}
-			break;
-		case '\0':
-			goto parse_error;
-		default:
-			prev = '\0';
-			break;
-		}
-	}
-
-	do {
-		if (ac == au) {
-			char **tmp;
-
-			tmp = realloc(av, (ac + 2048) * sizeof(char *));
-			if (tmp == NULL) {
-				free(av);
-				av = NULL;
-				ac = 0;
-				return (-1);
-			}
-			av = tmp;
-			ac += 2048;
-		}
-	} while ((av[au++] = strsep(&cp, ";")) != NULL);
-
-	/* toss empty last entry to allow for trailing ; */
-	if (av[au - 1][0] == '\0');
-		au--;
-
-	if (au < 1)
-		goto parse_error;
-	else
-		sdl_add(name, msg, av, au - 1);
-	return (0);
-
-parse_error:
-	if (debug > 0)
-		printf("bogus config line - need 'tag;message;a/m;a/m;a/m...'\n");
-	return (-1);
-}
-
-void
-parse_configs(void)
-{
-	char *start, *end;
-	int i;
-
-	if (cbu == cbs) {
-		char *tmp;
-
-		tmp = realloc(cb, cbs + 8192);
-		if (tmp == NULL) {
-			if (debug > 0)
-				perror("malloc()");
-			free(cb);
-			cb = NULL;
-			cbs = cbu = 0;
-			return;
-		}
-		cbs += 8192;
-		cb = tmp;
-	}
-	cb[cbu++] = '\0';
-
-	start = cb;
-	end = start;
-	for (i = 0; i < cbu; i++) {
-		if (*end == '\n') {
-			*end = '\0';
-			if (end > start + 1)
-				parse_configline(start);
-			start = ++end;
-		} else
-			++end;
-	}
-	if (end > start + 1)
-		parse_configline(start);
-}
-
-void
-do_config(void)
-{
-	int n;
-
-	if (debug > 0)
-		printf("got configuration connection\n");
-
-	if (cbu == cbs) {
-		char *tmp;
-
-		tmp = realloc(cb, cbs + 8192);
-		if (tmp == NULL) {
-			if (debug > 0)
-				perror("malloc()");
-			free(cb);
-			cb = NULL;
-			cbs = 0;
-			goto configdone;
-		}
-		cbs += 8192;
-		cb = tmp;
-	}
-
-	n = read(conffd, cb + cbu, cbs - cbu);
-	if (debug > 0)
-		printf("read %d config bytes\n", n);
-	if (n == 0) {
-		parse_configs();
-		goto configdone;
-	} else if (n == -1) {
-		if (debug > 0)
-			perror("read()");
-		goto configdone;
-	} else
-		cbu += n;
-	return;
-
-configdone:
-	cbu = 0;
-	close(conffd);
-	conffd = -1;
-}
-
-
-int
-read_configline(FILE *config)
-{
-	char *buf;
-	size_t len;
-
-	if ((buf = fgetln(config, &len))) {
-		if (buf[len - 1] == '\n')
-			buf[len - 1] = '\0';
-		else
-			return(-1);	/* all valid lines end in \n */
-		parse_configline(buf);
-	} else {
-		syslog_r(LOG_DEBUG, &sdata, "read_configline: fgetln (%m)");
-		return(-1);
-	}
-	return(0);
-}
-
-int
-append_error_string(struct con *cp, size_t off, char *fmt, int af, void *ia)
-{
-	char sav = '\0';
-	static int lastcont = 0;
-	char *c = cp->obuf + off;
-	char *s = fmt;
-	size_t len = cp->osize - off;
-	int i = 0;
-
-	if (off == 0)
-		lastcont = 0;
-
-	if (lastcont != 0)
-		cp->obuf[lastcont] = '-';
-	snprintf(c, len, "%s ", nreply);
-	i += strlen(c);
-	lastcont = off + i - 1;
-	if (*s == '"')
-		s++;
-	while (*s) {
-		/*
-		 * Make sure we at minimum, have room to add a
-		 * format code (4 bytes), and a v6 address(39 bytes)
-		 * and a byte saved in sav.
-		 */
-		if (i >= len - 46) {
-			c = grow_obuf(cp, off);
-			if (c == NULL)
-				return (-1);
-			len = cp->osize - (off + i);
-		}
-
-		if (c[i-1] == '\n') {
-			if (lastcont != 0)
-				cp->obuf[lastcont] = '-';
-			snprintf(c + i, len, "%s ", nreply);
-			i += strlen(c);
-			lastcont = off + i - 1;
-		}
-
-		switch (*s) {
-		case '\\':
-		case '%':
-			if (!sav)
-				sav = *s;
-			else {
-				c[i++] = sav;
-				sav = '\0';
-				c[i] = '\0';
-			}
-			break;
-		case '"':
-		case 'A':
-		case 'n':
-			if (*(s+1) == '\0') {
-				break;
-			}
-			if (sav == '\\' && *s == 'n') {
-				c[i++] = '\n';
-				sav = '\0';
-				c[i] = '\0';
-				break;
-			} else if (sav == '\\' && *s == '"') {
-				c[i++] = '"';
-				sav = '\0';
-				c[i] = '\0';
-				break;
-			} else if (sav == '%' && *s == 'A') {
-				inet_ntop(af, ia, c + i, (len - i));
-				i += strlen(c + i);
-				sav = '\0';
-				break;
-			}
-			/* fallthrough */
-		default:
-			if (sav)
-			c[i++] = sav;
-			c[i++] = *s;
-			sav = '\0';
-			c[i] = '\0';
-			break;
-		}
-		s++;
-	}
-	return (i);
-}
-
-char *
-loglists(struct con *cp)
-{
-	static char matchlists[80];
-	struct sdlist **matches;
-	int s = sizeof(matchlists) - 4;
-
-	matchlists[0] = '\0';
-	matches = cp->blacklists;
-	if (matches == NULL)
-		return(NULL);
-	for (; *matches; matches++) {
-
-		/* don't report an insane amount of lists in the logs.
-		 * just truncate and indicate with ...
-		 */
-		if (strlen(matchlists) + strlen(matches[0]->tag) + 1
-		    >= s)
-			strlcat(matchlists, " ...", sizeof(matchlists));
-		else {
-			strlcat(matchlists, " ", s);
-			strlcat(matchlists, matches[0]->tag, s);
-		}
-	}
-	return matchlists;
-}
-
-void
-build_reply(struct con *cp)
-{
-	struct sdlist **matches;
-	int off = 0;
-
-	matches = cp->blacklists;
-	if (matches == NULL)
-		goto nomatch;
-	for (; *matches; matches++) {
-		int used = 0;
-		char *c = cp->obuf + off;
-		int left = cp->osize - off;
-
-		used = append_error_string(cp, off, matches[0]->string,
-		    cp->af, cp->ia);
-		if (used == -1)
-			goto bad;
-		off += used;
-		left -= used;
-		if (cp->obuf[off - 1] != '\n') {
-			if (left < 1) {
-				c = grow_obuf(cp, off);
-				if (c == NULL)
-					goto bad;
-			}
-			cp->obuf[off++] = '\n';
-			cp->obuf[off] = '\0';
-		}
-	}
-	return;
-nomatch:
-	/* No match. give generic reply */
-	free(cp->obuf);
-	cp->obuf = NULL;
-	cp->osize = 0;
-	if (cp->blacklists != NULL)
-		asprintf(&cp->obuf,
-		    "%s-Sorry %s\n"
-		    "%s-You are trying to send mail from an address "
-		    "listed by one\n"
-		    "%s or more IP-based registries as being a SPAM source.\n",
-		    nreply, cp->addr, nreply, nreply);
-	else
-		asprintf(&cp->obuf,
-		    "451 Temporary failure, please try again later.\r\n");
-	if (cp->obuf != NULL)
-		cp->osize = strlen(cp->obuf) + 1;
-	else
-		cp->osize = 0;
-	return;
-bad:
-	if (cp->obuf != NULL) {
-		free(cp->obuf);
-		cp->obuf = NULL;
-		cp->osize = 0;
-	}
-}
-
-void
-doreply(struct con *cp)
-{
-	if (reply)
-		snprintf(cp->obuf, cp->osize, "%s %s\n", nreply, reply);
-	build_reply(cp);
-}
-
-void
-setlog(char *p, size_t len, char *f)
-{
-	char *s;
-
-	s = strsep(&f, ":");
-	if (!f)
-		return;
-	while (*f == ' ' || *f == '\t')
-		f++;
-	s = strsep(&f, " \t");
-	if (s == NULL)
-		return;
-	strlcpy(p, s, len);
-	s = strsep(&p, " \t\n\r");
-	if (s == NULL)
-		return;
-	s = strsep(&p, " \t\n\r");
-	if (s)
-		*s = '\0';
-}
-
-void
-initcon(struct con *cp, int fd, struct sockaddr *sa)
-{
-	time_t t;
-	char *tmp;
-	int error;
-
-	time(&t);
-	free(cp->obuf);
-	cp->obuf = NULL;
-	cp->osize = 0;
-	free(cp->blacklists);
-	cp->blacklists = NULL;
-	free(cp->lists);
-	cp->lists = NULL;
-	bzero(cp, sizeof(struct con));
-	if (grow_obuf(cp, 0) == NULL)
-		err(1, "malloc");
-	cp->fd = fd;
-	if (sa->sa_len > sizeof(cp->ss))
-		errx(1, "sockaddr size");
-	if (sa->sa_family != AF_INET)
-		errx(1, "not supported yet");
-	memcpy(&cp->ss, sa, sa->sa_len);
-	cp->af = sa->sa_family;
-	cp->ia = &((struct sockaddr_in *)sa)->sin_addr;
-	cp->blacklists = sdl_lookup(blacklists, cp->af, cp->ia);
-	cp->stutter = (greylist && cp->blacklists == NULL) ? 0 : stutter;
-	error = getnameinfo(sa, sa->sa_len, cp->addr, sizeof(cp->addr), NULL, 0,
-	    NI_NUMERICHOST);
-	if (error)
-		errx(1, "%s", gai_strerror(error));
-	tmp = strdup(ctime(&t));
-	if (tmp == NULL)
-		err(1, "malloc");
-	tmp[strlen(tmp) - 1] = '\0'; /* nuke newline */
-	snprintf(cp->obuf, cp->osize,
-		 "220 %s ESMTP %s; %s\r\n",
-		 hostname, spamd, tmp);
-	free(tmp);
-	cp->op = cp->obuf;
-	cp->ol = strlen(cp->op);
-	cp->w = t + cp->stutter;
-	cp->s = t;
-	strlcpy(cp->rend, "\n", sizeof cp->rend);
-	clients++;
-	if (cp->blacklists != NULL) {
-		blackcount++;
-		if (greylist && blackcount > maxblack) {
-			closecon(cp); /* close and free */
-			return;
-		}
-		cp->lists = strdup(loglists(cp));
-	}
-	else
-		cp->lists = NULL;
-}
-
-void
-closecon(struct con *cp)
-{
-	time_t t;
-
-	time(&t);
-	syslog_r(LOG_INFO, &sdata, "%s: disconnected after %ld seconds.%s%s",
-	    cp->addr, (long)(t - cp->s),
-	    ((cp->lists == NULL) ? "" : " lists:"),
-	    ((cp->lists == NULL) ? "": cp->lists));
-	if (debug > 0)
-		printf("%s connected for %ld seconds.\n", cp->addr,
-		    (long)(t - cp->s));
-	if (cp->lists != NULL) {
-		free(cp->lists);
-		cp->lists = NULL;
-	}
-	if (cp->blacklists != NULL) {
-		blackcount--;
-		free(cp->blacklists);
-		cp->blacklists = NULL;
-	}
-	if (cp->obuf != NULL) {
-		free(cp->obuf);
-		cp->obuf = NULL;
-		cp->osize = 0;
-	}
-	close(cp->fd);
-	clients--;
-	cp->fd = -1;
-}
-
-int
-match(const char *s1, const char *s2)
-{
-	return (strncasecmp(s1, s2, strlen(s2)) == 0);
-}
-
-void
-nextstate(struct con *cp)
-{
-	if (match(cp->ibuf, "QUIT") && cp->state < 99) {
-		snprintf(cp->obuf, cp->osize, "221 %s\r\n", hostname);
-		cp->op = cp->obuf;
-		cp->ol = strlen(cp->op);
-		cp->w = t + cp->stutter;
-		cp->laststate = cp->state;
-		cp->state = 99;
-		return;
-	}
-
-	if (match(cp->ibuf, "RSET") && cp->state > 2 && cp->state < 50) {
-		snprintf(cp->obuf, cp->osize,
-		    "250 Ok to start over.\r\n");
-		cp->op = cp->obuf;
-		cp->ol = strlen(cp->op);
-		cp->w = t + cp->stutter;
-		cp->laststate = cp->state;
-		cp->state = 2;
-		return;
-	}
-	switch (cp->state) {
-	case 0:
-		/* banner sent; wait for input */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 1;
-		cp->r = t;
-		break;
-	case 1:
-		/* received input: parse, and select next state */
-		if (match(cp->ibuf, "HELO") ||
-		    match(cp->ibuf, "EHLO")) {
-			snprintf(cp->obuf, cp->osize,
-			    "250 Hello, spam sender. "
-			    "Pleased to be wasting your time.\r\n");
-			cp->op = cp->obuf;
-			cp->ol = strlen(cp->op);
-			cp->laststate = cp->state;
-			cp->state = 2;
-			cp->w = t + cp->stutter;
-			break;
-		}
-		goto mail;
-	case 2:
-		/* sent 250 Hello, wait for input */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 3;
-		cp->r = t;
-		break;
-	mail:
-	case 3:
-		if (match(cp->ibuf, "MAIL")) {
-			setlog(cp->mail, sizeof cp->mail, cp->ibuf);
-			snprintf(cp->obuf, cp->osize,
-			    "250 You are about to try to deliver spam. "
-			    "Your time will be spent, for nothing.\r\n");
-			cp->op = cp->obuf;
-			cp->ol = strlen(cp->op);
-			cp->laststate = cp->state;
-			cp->state = 4;
-			cp->w = t + cp->stutter;
-			break;
-		}
-		goto rcpt;
-	case 4:
-		/* sent 250 Sender ok */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 5;
-		cp->r = t;
-		break;
-	rcpt:
-	case 5:
-		if (match(cp->ibuf, "RCPT")) {
-			setlog(cp->rcpt, sizeof(cp->rcpt), cp->ibuf);
-			snprintf(cp->obuf, cp->osize,
-			    "250 This is hurting you more than it is "
-			    "hurting me.\r\n");
-			cp->op = cp->obuf;
-			cp->ol = strlen(cp->op);
-			cp->laststate = cp->state;
-			cp->state = 6;
-			cp->w = t + cp->stutter;
-			if (cp->mail[0] && cp->rcpt[0]) {
-				if (verbose)
-					syslog_r(LOG_INFO, &sdata,
-					    "(%s) %s: %s -> %s",
-					    cp->blacklists ? "BLACK" : "GREY",
-					    cp->addr, cp->mail,
-					    cp->rcpt);
-				if (debug)
-					fprintf(stderr, "(%s) %s: %s -> %s\n",
-					    cp->blacklists ? "BLACK" : "GREY",
-					    cp->addr, cp->mail, cp->rcpt);
-				if (greylist && cp->blacklists == NULL) {
-					/* send this info to the greylister */
-					fprintf(grey, "IP:%s\nFR:%s\nTO:%s\n",
-					    cp->addr, cp->mail, cp->rcpt);
-					fflush(grey);
-					cp->laststate = cp->state;
-					cp->state = 98;
-					goto done;
-				}
-			}
-			break;
-		}
-		goto spam;
-	case 6:
-		/* sent 250 blah */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 5;
-		cp->r = t;
-		break;
-
-	spam:
-	case 50:
-		if (match(cp->ibuf, "DATA")) {
-			snprintf(cp->obuf, cp->osize,
-			    "354 Enter spam, end with \".\" on a line by "
-			    "itself\r\n");
-			cp->state = 60;
-			if (window && setsockopt(cp->fd, SOL_SOCKET, SO_RCVBUF,
-			    &window, sizeof(window)) == -1) {
-				syslog_r(LOG_DEBUG, &sdata,"setsockopt: %m");
-				/* don't fail if this doesn't work. */
-			}
-		} else {
-			snprintf(cp->obuf, cp->osize,
-			    "500 5.5.1 Command unrecognized\r\n");
-			cp->state = cp->laststate;
-		}
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->op = cp->obuf;
-		cp->ol = strlen(cp->op);
-		cp->w = t + cp->stutter;
-		break;
-	case 60:
-		/* sent 354 blah */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 70;
-		cp->r = t;
-		break;
-	case 70: {
-		char *p, *q;
-
-		for (p = q = cp->ibuf; q <= cp->ip; ++q)
-			if (*q == '\n' || q == cp->ip) {
-				*q = 0;
-				if (q > p && q[-1] == '\r')
-					q[-1] = 0;
-				if (!strcmp(p, ".") ||
-				    (cp->data_body && ++cp->data_lines >= 10)) {
-					cp->laststate = cp->state;
-					cp->state = 98;
-					goto done;
-				}
-				if (!cp->data_body && !*p)
-					cp->data_body = 1;
-				if (verbose && cp->data_body && *p)
-					syslog_r(LOG_DEBUG, &sdata, "%s: "
-					    "Body: %s", cp->addr, p);
-				else if (verbose && (match(p, "FROM:") ||
-				    match(p, "TO:") || match(p, "SUBJECT:")))
-					syslog_r(LOG_INFO, &sdata, "%s: %s",
-					    cp->addr, p);
-				p = ++q;
-			}
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->r = t;
-		break;
-	}
-	done:
-	case 98:
-		doreply(cp);
-		cp->op = cp->obuf;
-		cp->ol = strlen(cp->op);
-		cp->w = t + cp->stutter;
-		cp->laststate = cp->state;
-		cp->state = 99;
-		break;
-	case 99:
-		closecon(cp);
-		break;
-	default:
-		errx(1, "illegal state %d", cp->state);
-		break;
-	}
-}
-
-void
-handler(struct con *cp)
-{
-	int end = 0;
-	int n;
-
-	if (cp->r) {
-		n = read(cp->fd, cp->ip, cp->il);
-		if (n == 0)
-			closecon(cp);
-		else if (n == -1) {
-			if (debug > 0)
-				perror("read()");
-			closecon(cp);
-		} else {
-			cp->ip[n] = '\0';
-			if (cp->rend[0])
-				if (strpbrk(cp->ip, cp->rend))
-					end = 1;
-			cp->ip += n;
-			cp->il -= n;
-		}
-	}
-	if (end || cp->il == 0) {
-		while (cp->ip > cp->ibuf &&
-		    (cp->ip[-1] == '\r' || cp->ip[-1] == '\n'))
-			cp->ip--;
-		*cp->ip = '\0';
-		cp->r = 0;
-		nextstate(cp);
-	}
-}
-
-void
-handlew(struct con *cp, int one)
-{
-	int n;
-
-	if (cp->w) {
-		if (*cp->op == '\n' && !cp->sr) {
-			/* insert \r before \n */
-			n = write(cp->fd, "\r", 1);
-			if (n == 0) {
-				closecon(cp);
-				goto handled;
-			} else if (n == -1) {
-				if (debug > 0 && errno != EPIPE)
-					perror("write()");
-				closecon(cp);
-				goto handled;
-			}
-		}
-		if (*cp->op == '\r')
-			cp->sr = 1;
-		else
-			cp->sr = 0;
-		n = write(cp->fd, cp->op, (one && cp->stutter) ? 1 : cp->ol);
-		if (n == 0)
-			closecon(cp);
-		else if (n == -1) {
-			if (debug > 0 && errno != EPIPE)
-				perror("write()");
-			closecon(cp);
-		} else {
-			cp->op += n;
-			cp->ol -= n;
-		}
-	}
-handled:
-	cp->w = t + cp->stutter;
-	if (cp->ol == 0) {
-		cp->w = 0;
-		nextstate(cp);
-	}
-}
-
-int
-main(int argc, char *argv[])
-{
-	fd_set *fdsr = NULL, *fdsw = NULL;
-	struct sockaddr_in sin;
-	struct sockaddr_in lin;
-	int ch, s, s2, conflisten = 0, i, omax = 0, one = 1;
-	socklen_t sinlen;
-	u_short port;
-	struct servent *ent;
-	struct rlimit rlp;
-	char *bind_address = NULL;
-
-	tzset();
-	openlog_r("spamd", LOG_PID | LOG_NDELAY, LOG_DAEMON, &sdata);
-
-	if ((ent = getservbyname("spamd", "tcp")) == NULL)
-		errx(1, "Can't find service \"spamd\" in /etc/services");
-	port = ntohs(ent->s_port);
-	if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL)
-		errx(1, "Can't find service \"spamd-cfg\" in /etc/services");
-	cfg_port = ntohs(ent->s_port);
-
-	if (gethostname(hostname, sizeof hostname) == -1)
-		err(1, "gethostname");
-
-#ifdef IPFW
-	while ((ch = getopt(argc, argv, "45b:c:B:p:dgG:r:s:n:vw:t:")) != -1) {
-#else
-	while ((ch = getopt(argc, argv, "45b:c:B:p:dgG:r:s:n:vw:")) != -1) {
-#endif
-		switch (ch) {
-		case '4':
-			nreply = "450";
-			break;
-		case '5':
-			nreply = "550";
-			break;
-		case 'b':
-			bind_address = optarg;
-			break;
-		case 'B':
-			i = atoi(optarg);
-			maxblack = i;
-			break;
-		case 'c':
-			i = atoi(optarg);
-			if (i > MAXCON)
-				usage();
-			maxcon = i;
-			break;
-		case 'p':
-			i = atoi(optarg);
-			port = i;
-			break;
-		case 'd':
-			debug = 1;
-			break;
-		case 'g':
-			greylist = 1;
-			break;
-		case 'G':
-			if (sscanf(optarg, "%d:%d:%d", &passtime, &greyexp,
-			    &whiteexp) != 3)
-				usage();
-			/* convert to seconds from minutes */
-			passtime *= 60;
-			/* convert to seconds from hours */
-			whiteexp *= (60 * 60);
-			/* convert to seconds from hours */
-			greyexp *= (60 * 60);
-			break;
-		case 'r':
-			reply = optarg;
-			break;
-		case 's':
-			i = atoi(optarg);
-			if (i < 0 || i > 10)
-				usage();
-			stutter = i;
-			break;
-		case 'n':
-			spamd = optarg;
-			break;
-		case 'v':
-			verbose = 1;
-			break;
-#ifdef IPFW
-		case 't':
-			tabno = atoi(optarg);
-			break;
-#endif
-		case 'w':
-			window = atoi(optarg);
-			if (window <= 0)
-				usage();
-			break;
-		default:
-			usage();
-			break;
-		}
-	}
-
-	if (!greylist)
-		maxblack = maxcon;
-	else if (maxblack > maxcon)
-		usage();
-
-	rlp.rlim_cur = rlp.rlim_max = maxcon + 15;
-	if (setrlimit(RLIMIT_NOFILE, &rlp) == -1)
-		err(1, "setrlimit");
-
-	con = calloc(maxcon, sizeof(*con));
-	if (con == NULL)
-		err(1, "calloc");
-
-	con->obuf = malloc(8192);
-
-	if (con->obuf == NULL)
-		err(1, "malloc");
-	con->osize = 8192;
-
-	for (i = 0; i < maxcon; i++)
-		con[i].fd = -1;
-
-	signal(SIGPIPE, SIG_IGN);
-
-	s = socket(AF_INET, SOCK_STREAM, 0);
-	if (s == -1)
-		err(1, "socket");
-
-	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one,
-	    sizeof(one)) == -1)
-		return (-1);
-
-	conflisten = socket(AF_INET, SOCK_STREAM, 0);
-	if (conflisten == -1)
-		err(1, "socket");
-
-	if (setsockopt(conflisten, SOL_SOCKET, SO_REUSEADDR, &one,
-	    sizeof(one)) == -1)
-		return (-1);
-
-	memset(&sin, 0, sizeof sin);
-	sin.sin_len = sizeof(sin);
-	if (bind_address) {
-		if (inet_pton(AF_INET, bind_address, &sin.sin_addr) != 1)
-			err(1, "inet_pton");
-	} else
-		sin.sin_addr.s_addr = htonl(INADDR_ANY);
-	sin.sin_family = AF_INET;
-	sin.sin_port = htons(port);
-
-	if (bind(s, (struct sockaddr *)&sin, sizeof sin) == -1)
-		err(1, "bind");
-
-	memset(&lin, 0, sizeof sin);
-	lin.sin_len = sizeof(sin);
-	lin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-	lin.sin_family = AF_INET;
-	lin.sin_port = htons(cfg_port);
-
-	if (bind(conflisten, (struct sockaddr *)&lin, sizeof lin) == -1)
-		err(1, "bind local");
-
-	pw = getpwnam("_spamd");
-	if (!pw)
-		pw = getpwnam("nobody");
-
-	if (debug == 0) {
-		if (daemon(1, 1) == -1)
-			err(1, "daemon");
-	}
-
-	if (greylist) {
-		maxblack = (maxblack >= maxcon) ? maxcon - 100 : maxblack;
-		if (maxblack < 0)
-			maxblack = 0;
-
-		/* open pipe to talk to greylister */
-		if (pipe(greypipe) == -1) {
-			syslog(LOG_ERR, "pipe (%m)");
-			exit(1);
-		}
-		/* open pipe to recieve spamtrap configs */
-		if (pipe(trappipe) == -1) {
-			syslog(LOG_ERR, "pipe (%m)");
-			exit(1);
-		}
-		jail_pid = fork();
-		switch(jail_pid) {
-		case -1:
-			syslog(LOG_ERR, "fork (%m)");
-			exit(1);
-		case 0:
-			/* child - continue */
-			grey = fdopen(greypipe[1], "w");
-			if (grey == NULL) {
-				syslog(LOG_ERR, "fdopen (%m)");
-				_exit(1);
-			}
-			close(greypipe[0]);
-			trapfd = trappipe[0];
-			trapcfg = fdopen(trappipe[0], "r");
-			if (trapcfg == NULL) {
-				syslog(LOG_ERR, "fdopen (%m)");
-				_exit(1);
-			}
-			close(trappipe[1]);
-			goto jail;
-		}
-		/* parent - run greylister */
-		grey = fdopen(greypipe[0], "r");
-		if (grey == NULL) {
-			syslog(LOG_ERR, "fdopen (%m)");
-			exit(1);
-		}
-		close(greypipe[1]);
-		trapcfg = fdopen(trappipe[1], "w");
-		if (trapcfg == NULL) {
-			syslog(LOG_ERR, "fdopen (%m)");
-			exit(1);
-		}
-		close(trappipe[0]);
-		return(greywatcher());
-		/* NOTREACHED */
-	}
-
-jail:
-	if (chroot("/var/empty") == -1 || chdir("/") == -1) {
-		syslog(LOG_ERR, "cannot chdir to /var/empty.");
-		exit(1);
-	}
-
-	if (pw) {
-		setgroups(1, &pw->pw_gid);
-		setegid(pw->pw_gid);
-		setgid(pw->pw_gid);
-		seteuid(pw->pw_uid);
-		setuid(pw->pw_uid);
-	}
-
-	if (listen(s, 10) == -1)
-		err(1, "listen");
-
-	if (listen(conflisten, 10) == -1)
-		err(1, "listen");
-
-	if (debug != 0)
-		printf("listening for incoming connections.\n");
-	syslog_r(LOG_WARNING, &sdata, "listening for incoming connections.");
-
-	while (1) {
-		struct timeval tv, *tvp;
-		int max, i, n;
-		int writers;
-
-		max = MAX(s, conflisten);
-		max = MAX(max, conffd);
-		max = MAX(max, trapfd);
-
-		time(&t);
-		for (i = 0; i < maxcon; i++)
-			if (con[i].fd != -1)
-				max = MAX(max, con[i].fd);
-
-		if (max > omax) {
-			free(fdsr);
-			fdsr = NULL;
-			free(fdsw);
-			fdsw = NULL;
-			fdsr = (fd_set *)calloc(howmany(max+1, NFDBITS),
-			    sizeof(fd_mask));
-			if (fdsr == NULL)
-				err(1, "calloc");
-			fdsw = (fd_set *)calloc(howmany(max+1, NFDBITS),
-			    sizeof(fd_mask));
-			if (fdsw == NULL)
-				err(1, "calloc");
-			omax = max;
-		} else {
-			memset(fdsr, 0, howmany(max+1, NFDBITS) *
-			    sizeof(fd_mask));
-			memset(fdsw, 0, howmany(max+1, NFDBITS) *
-			    sizeof(fd_mask));
-		}
-
-		writers = 0;
-		for (i = 0; i < maxcon; i++) {
-			if (con[i].fd != -1 && con[i].r) {
-				if (con[i].r + MAXTIME <= t) {
-					closecon(&con[i]);
-					continue;
-				}
-				FD_SET(con[i].fd, fdsr);
-			}
-			if (con[i].fd != -1 && con[i].w) {
-				if (con[i].w + MAXTIME <= t) {
-					closecon(&con[i]);
-					continue;
-				}
-				if (con[i].w <= t)
-					FD_SET(con[i].fd, fdsw);
-				writers = 1;
-			}
-		}
-		FD_SET(s, fdsr);
-
-		/* only one active config conn at a time */
-		if (conffd == -1)
-			FD_SET(conflisten, fdsr);
-		else
-			FD_SET(conffd, fdsr);
-		if (trapfd != -1)
-			FD_SET(trapfd, fdsr);
-
-		if (writers == 0) {
-			tvp = NULL;
-		} else {
-			tv.tv_sec = 1;
-			tv.tv_usec = 0;
-			tvp = &tv;
-		}
-
-		n = select(max+1, fdsr, fdsw, NULL, tvp);
-		if (n == -1) {
-			if (errno != EINTR)
-				err(1, "select");
-			continue;
-		}
-		if (n == 0)
-			continue;
-
-		for (i = 0; i < maxcon; i++) {
-			if (con[i].fd != -1 && FD_ISSET(con[i].fd, fdsr))
-				handler(&con[i]);
-			if (con[i].fd != -1 && FD_ISSET(con[i].fd, fdsw))
-				handlew(&con[i], clients + 5 < maxcon);
-		}
-		if (FD_ISSET(s, fdsr)) {
-			sinlen = sizeof(sin);
-			s2 = accept(s, (struct sockaddr *)&sin, &sinlen);
-			if (s2 == -1)
-				/* accept failed, they may try again */
-				continue;
-			for (i = 0; i < maxcon; i++)
-				if (con[i].fd == -1)
-					break;
-			if (i == maxcon)
-				close(s2);
-			else {
-				initcon(&con[i], s2, (struct sockaddr *)&sin);
-				syslog_r(LOG_INFO, &sdata,
-				    "%s: connected (%d/%d)%s%s",
-				    con[i].addr, clients, blackcount,
-				    ((con[i].lists == NULL) ? "" :
-				    ", lists:"),
-				    ((con[i].lists == NULL) ? "":
-				    con[i].lists));
-			}
-		}
-		if (FD_ISSET(conflisten, fdsr)) {
-			sinlen = sizeof(lin);
-			conffd = accept(conflisten, (struct sockaddr *)&lin,
-			    &sinlen);
-			if (conffd == -1)
-				/* accept failed, they may try again */
-				continue;
-			else if (ntohs(lin.sin_port) >= IPPORT_RESERVED) {
-				close(conffd);
-				conffd = -1;
-			}
-		}
-		if (conffd != -1 && FD_ISSET(conffd, fdsr))
-			do_config();
-		if (trapfd != -1 && FD_ISSET(trapfd, fdsr))
-			read_configline(trapcfg);
-	}
-	exit(1);
-}
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.c.orig /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.c.orig
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.c.orig	Tue Apr 12 20:21:48 2005
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.c.orig	Thu Jan  1 03:00:00 1970
@@ -1,1305 +0,0 @@
-/*	$OpenBSD: spamd.c,v 1.75 2005/03/11 23:09:53 beck Exp $	*/
-
-/*
- * Copyright (c) 2002 Theo de Raadt.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/resource.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <err.h>
-#include <errno.h>
-#include <getopt.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <netdb.h>
-
-#include "sdl.h"
-#include "grey.h"
-
-struct con {
-	int fd;
-	int state;
-	int laststate;
-	int af;
-	struct sockaddr_storage ss;
-	void *ia;
-	char addr[32];
-	char mail[MAX_MAIL], rcpt[MAX_MAIL];
-	struct sdlist **blacklists;
-
-	/*
-	 * we will do stuttering by changing these to time_t's of
-	 * now + n, and only advancing when the time is in the past/now
-	 */
-	time_t r;
-	time_t w;
-	time_t s;
-
-	char ibuf[8192];
-	char *ip;
-	int il;
-	char rend[5];	/* any chars in here causes input termination */
-
-	char *obuf;
-	char *lists;
-	size_t osize;
-	char *op;
-	int ol;
-	int data_lines;
-	int data_body;
-	int stutter;
-	int sr;
-} *con;
-
-void     usage(void);
-char    *grow_obuf(struct con *, int);
-int      parse_configline(char *);
-void     parse_configs(void);
-void     do_config(void);
-int      append_error_string (struct con *, size_t, char *, int, void *);
-void     build_reply(struct  con *);
-void     doreply(struct con *);
-void     setlog(char *, size_t, char *);
-void     initcon(struct con *, int, struct sockaddr *);
-void     closecon(struct con *);
-int      match(const char *, const char *);
-void     nextstate(struct con *);
-void     handler(struct con *);
-void     handlew(struct con *, int one);
-
-char hostname[MAXHOSTNAMELEN];
-#ifdef __OpenBSD__
-struct syslog_data sdata = SYSLOG_DATA_INIT;
-#else
-#define	syslog_r(l, s, args...)	syslog(l,args)
-#define	openlog_r(i, l, f, s)	openlog(i, l, f)
-int sdata = 0;						/* dummy */
-#endif
-char *reply = NULL;
-char *nreply = "450";
-char *spamd = "spamd IP-based SPAM blocker";
-int greypipe[2];
-int trappipe[2];
-FILE *grey;
-FILE *trapcfg;
-time_t passtime = PASSTIME;
-time_t greyexp = GREYEXP;
-time_t whiteexp = WHITEEXP;
-time_t trapexp = TRAPEXP;
-struct passwd *pw;
-pid_t jail_pid = -1;
-u_short cfg_port;
-
-extern struct sdlist *blacklists;
-
-int conffd = -1;
-int trapfd = -1;
-char *cb;
-size_t cbs, cbu;
-
-time_t t;
-
-#define MAXCON 800
-int maxcon = MAXCON;
-int maxblack = MAXCON;
-int blackcount;
-int clients;
-int debug;
-int greylist;
-int verbose;
-int stutter = 1;
-int window;
-#define MAXTIME 400
-
-void
-usage(void)
-{
-	fprintf(stderr,
-	    "usage: spamd [-45dgv] [-B maxblack] [-b address] [-c maxcon]\n");
-	fprintf(stderr,
-	    "             [-G mins:hours:hours] [-n name] [-p port]\n");
-	fprintf(stderr,
-	    "             [-r reply] [-s secs] [-w window]\n");
-	exit(1);
-}
-
-char *
-grow_obuf(struct con *cp, int off)
-{
-	char *tmp;
-
-	tmp = realloc(cp->obuf, cp->osize + 8192);
-	if (tmp == NULL) {
-		free(cp->obuf);
-		cp->obuf = NULL;
-		cp->osize = 0;
-		return (NULL);
-	} else {
-		cp->osize += 8192;
-		cp->obuf = tmp;
-		return (cp->obuf + off);
-	}
-}
-
-int
-parse_configline(char *line)
-{
-	char *cp, prev, *name, *msg;
-	static char **av = NULL;
-	static size_t ac = 0;
-	size_t au = 0;
-	int mdone = 0;
-
-	name = line;
-
-	for (cp = name; *cp && *cp != ';'; cp++)
-		;
-	if (*cp != ';')
-		goto parse_error;
-	*cp++ = '\0';
-	msg = cp;
-	if (*cp++ != '"')
-		goto parse_error;
-	prev = '\0';
-	for (; !mdone; cp++) {
-		switch (*cp) {
-		case '\\':
-			if (!prev)
-				prev = *cp;
-			else
-				prev = '\0';
-			break;
-		case '"':
-			if (prev != '\\') {
-				cp++;
-				if (*cp == ';') {
-					mdone = 1;
-					*cp = '\0';
-				} else
-					goto parse_error;
-			}
-			break;
-		case '\0':
-			goto parse_error;
-		default:
-			prev = '\0';
-			break;
-		}
-	}
-
-	do {
-		if (ac == au) {
-			char **tmp;
-
-			tmp = realloc(av, (ac + 2048) * sizeof(char *));
-			if (tmp == NULL) {
-				free(av);
-				av = NULL;
-				ac = 0;
-				return (-1);
-			}
-			av = tmp;
-			ac += 2048;
-		}
-	} while ((av[au++] = strsep(&cp, ";")) != NULL);
-
-	/* toss empty last entry to allow for trailing ; */
-	if (av[au - 1][0] == '\0');
-		au--;
-
-	if (au < 1)
-		goto parse_error;
-	else
-		sdl_add(name, msg, av, au - 1);
-	return (0);
-
-parse_error:
-	if (debug > 0)
-		printf("bogus config line - need 'tag;message;a/m;a/m;a/m...'\n");
-	return (-1);
-}
-
-void
-parse_configs(void)
-{
-	char *start, *end;
-	int i;
-
-	if (cbu == cbs) {
-		char *tmp;
-
-		tmp = realloc(cb, cbs + 8192);
-		if (tmp == NULL) {
-			if (debug > 0)
-				perror("malloc()");
-			free(cb);
-			cb = NULL;
-			cbs = cbu = 0;
-			return;
-		}
-		cbs += 8192;
-		cb = tmp;
-	}
-	cb[cbu++] = '\0';
-
-	start = cb;
-	end = start;
-	for (i = 0; i < cbu; i++) {
-		if (*end == '\n') {
-			*end = '\0';
-			if (end > start + 1)
-				parse_configline(start);
-			start = ++end;
-		} else
-			++end;
-	}
-	if (end > start + 1)
-		parse_configline(start);
-}
-
-void
-do_config(void)
-{
-	int n;
-
-	if (debug > 0)
-		printf("got configuration connection\n");
-
-	if (cbu == cbs) {
-		char *tmp;
-
-		tmp = realloc(cb, cbs + 8192);
-		if (tmp == NULL) {
-			if (debug > 0)
-				perror("malloc()");
-			free(cb);
-			cb = NULL;
-			cbs = 0;
-			goto configdone;
-		}
-		cbs += 8192;
-		cb = tmp;
-	}
-
-	n = read(conffd, cb + cbu, cbs - cbu);
-	if (debug > 0)
-		printf("read %d config bytes\n", n);
-	if (n == 0) {
-		parse_configs();
-		goto configdone;
-	} else if (n == -1) {
-		if (debug > 0)
-			perror("read()");
-		goto configdone;
-	} else
-		cbu += n;
-	return;
-
-configdone:
-	cbu = 0;
-	close(conffd);
-	conffd = -1;
-}
-
-
-int
-read_configline(FILE *config)
-{
-	char *buf;
-	size_t len;
-
-	if ((buf = fgetln(config, &len))) {
-		if (buf[len - 1] == '\n')
-			buf[len - 1] = '\0';
-		else
-			return(-1);	/* all valid lines end in \n */
-		parse_configline(buf);
-	} else {
-		syslog_r(LOG_DEBUG, &sdata, "read_configline: fgetln (%m)");
-		return(-1);
-	}
-	return(0);
-}
-
-int
-append_error_string(struct con *cp, size_t off, char *fmt, int af, void *ia)
-{
-	char sav = '\0';
-	static int lastcont = 0;
-	char *c = cp->obuf + off;
-	char *s = fmt;
-	size_t len = cp->osize - off;
-	int i = 0;
-
-	if (off == 0)
-		lastcont = 0;
-
-	if (lastcont != 0)
-		cp->obuf[lastcont] = '-';
-	snprintf(c, len, "%s ", nreply);
-	i += strlen(c);
-	lastcont = off + i - 1;
-	if (*s == '"')
-		s++;
-	while (*s) {
-		/*
-		 * Make sure we at minimum, have room to add a
-		 * format code (4 bytes), and a v6 address(39 bytes)
-		 * and a byte saved in sav.
-		 */
-		if (i >= len - 46) {
-			c = grow_obuf(cp, off);
-			if (c == NULL)
-				return (-1);
-			len = cp->osize - (off + i);
-		}
-
-		if (c[i-1] == '\n') {
-			if (lastcont != 0)
-				cp->obuf[lastcont] = '-';
-			snprintf(c + i, len, "%s ", nreply);
-			i += strlen(c);
-			lastcont = off + i - 1;
-		}
-
-		switch (*s) {
-		case '\\':
-		case '%':
-			if (!sav)
-				sav = *s;
-			else {
-				c[i++] = sav;
-				sav = '\0';
-				c[i] = '\0';
-			}
-			break;
-		case '"':
-		case 'A':
-		case 'n':
-			if (*(s+1) == '\0') {
-				break;
-			}
-			if (sav == '\\' && *s == 'n') {
-				c[i++] = '\n';
-				sav = '\0';
-				c[i] = '\0';
-				break;
-			} else if (sav == '\\' && *s == '"') {
-				c[i++] = '"';
-				sav = '\0';
-				c[i] = '\0';
-				break;
-			} else if (sav == '%' && *s == 'A') {
-				inet_ntop(af, ia, c + i, (len - i));
-				i += strlen(c + i);
-				sav = '\0';
-				break;
-			}
-			/* fallthrough */
-		default:
-			if (sav)
-			c[i++] = sav;
-			c[i++] = *s;
-			sav = '\0';
-			c[i] = '\0';
-			break;
-		}
-		s++;
-	}
-	return (i);
-}
-
-char *
-loglists(struct con *cp)
-{
-	static char matchlists[80];
-	struct sdlist **matches;
-	int s = sizeof(matchlists) - 4;
-
-	matchlists[0] = '\0';
-	matches = cp->blacklists;
-	if (matches == NULL)
-		return(NULL);
-	for (; *matches; matches++) {
-
-		/* don't report an insane amount of lists in the logs.
-		 * just truncate and indicate with ...
-		 */
-		if (strlen(matchlists) + strlen(matches[0]->tag) + 1
-		    >= s)
-			strlcat(matchlists, " ...", sizeof(matchlists));
-		else {
-			strlcat(matchlists, " ", s);
-			strlcat(matchlists, matches[0]->tag, s);
-		}
-	}
-	return matchlists;
-}
-
-void
-build_reply(struct con *cp)
-{
-	struct sdlist **matches;
-	int off = 0;
-
-	matches = cp->blacklists;
-	if (matches == NULL)
-		goto nomatch;
-	for (; *matches; matches++) {
-		int used = 0;
-		char *c = cp->obuf + off;
-		int left = cp->osize - off;
-
-		used = append_error_string(cp, off, matches[0]->string,
-		    cp->af, cp->ia);
-		if (used == -1)
-			goto bad;
-		off += used;
-		left -= used;
-		if (cp->obuf[off - 1] != '\n') {
-			if (left < 1) {
-				c = grow_obuf(cp, off);
-				if (c == NULL)
-					goto bad;
-			}
-			cp->obuf[off++] = '\n';
-			cp->obuf[off] = '\0';
-		}
-	}
-	return;
-nomatch:
-	/* No match. give generic reply */
-	free(cp->obuf);
-	cp->obuf = NULL;
-	cp->osize = 0;
-	if (cp->blacklists != NULL)
-		asprintf(&cp->obuf,
-		    "%s-Sorry %s\n"
-		    "%s-You are trying to send mail from an address "
-		    "listed by one\n"
-		    "%s or more IP-based registries as being a SPAM source.\n",
-		    nreply, cp->addr, nreply, nreply);
-	else
-		asprintf(&cp->obuf,
-		    "451 Temporary failure, please try again later.\r\n");
-	if (cp->obuf != NULL)
-		cp->osize = strlen(cp->obuf) + 1;
-	else
-		cp->osize = 0;
-	return;
-bad:
-	if (cp->obuf != NULL) {
-		free(cp->obuf);
-		cp->obuf = NULL;
-		cp->osize = 0;
-	}
-}
-
-void
-doreply(struct con *cp)
-{
-	if (reply)
-		snprintf(cp->obuf, cp->osize, "%s %s\n", nreply, reply);
-	build_reply(cp);
-}
-
-void
-setlog(char *p, size_t len, char *f)
-{
-	char *s;
-
-	s = strsep(&f, ":");
-	if (!f)
-		return;
-	while (*f == ' ' || *f == '\t')
-		f++;
-	s = strsep(&f, " \t");
-	if (s == NULL)
-		return;
-	strlcpy(p, s, len);
-	s = strsep(&p, " \t\n\r");
-	if (s == NULL)
-		return;
-	s = strsep(&p, " \t\n\r");
-	if (s)
-		*s = '\0';
-}
-
-void
-initcon(struct con *cp, int fd, struct sockaddr *sa)
-{
-	time_t t;
-	char *tmp;
-	int error;
-
-	time(&t);
-	free(cp->obuf);
-	cp->obuf = NULL;
-	cp->osize = 0;
-	free(cp->blacklists);
-	cp->blacklists = NULL;
-	free(cp->lists);
-	cp->lists = NULL;
-	bzero(cp, sizeof(struct con));
-	if (grow_obuf(cp, 0) == NULL)
-		err(1, "malloc");
-	cp->fd = fd;
-	if (sa->sa_len > sizeof(cp->ss))
-		errx(1, "sockaddr size");
-	if (sa->sa_family != AF_INET)
-		errx(1, "not supported yet");
-	memcpy(&cp->ss, sa, sa->sa_len);
-	cp->af = sa->sa_family;
-	cp->ia = &((struct sockaddr_in *)sa)->sin_addr;
-	cp->blacklists = sdl_lookup(blacklists, cp->af, cp->ia);
-	cp->stutter = (greylist && cp->blacklists == NULL) ? 0 : stutter;
-	error = getnameinfo(sa, sa->sa_len, cp->addr, sizeof(cp->addr), NULL, 0,
-	    NI_NUMERICHOST);
-	if (error)
-		errx(1, "%s", gai_strerror(error));
-	tmp = strdup(ctime(&t));
-	if (tmp == NULL)
-		err(1, "malloc");
-	tmp[strlen(tmp) - 1] = '\0'; /* nuke newline */
-	snprintf(cp->obuf, cp->osize,
-		 "220 %s ESMTP %s; %s\r\n",
-		 hostname, spamd, tmp);
-	free(tmp);
-	cp->op = cp->obuf;
-	cp->ol = strlen(cp->op);
-	cp->w = t + cp->stutter;
-	cp->s = t;
-	strlcpy(cp->rend, "\n", sizeof cp->rend);
-	clients++;
-	if (cp->blacklists != NULL) {
-		blackcount++;
-		if (greylist && blackcount > maxblack) {
-			closecon(cp); /* close and free */
-			return;
-		}
-		cp->lists = strdup(loglists(cp));
-	}
-	else
-		cp->lists = NULL;
-}
-
-void
-closecon(struct con *cp)
-{
-	time_t t;
-
-	time(&t);
-	syslog_r(LOG_INFO, &sdata, "%s: disconnected after %ld seconds.%s%s",
-	    cp->addr, (long)(t - cp->s),
-	    ((cp->lists == NULL) ? "" : " lists:"),
-	    ((cp->lists == NULL) ? "": cp->lists));
-	if (debug > 0)
-		printf("%s connected for %ld seconds.\n", cp->addr,
-		    (long)(t - cp->s));
-	if (cp->lists != NULL) {
-		free(cp->lists);
-		cp->lists = NULL;
-	}
-	if (cp->blacklists != NULL) {
-		blackcount--;
-		free(cp->blacklists);
-		cp->blacklists = NULL;
-	}
-	if (cp->obuf != NULL) {
-		free(cp->obuf);
-		cp->obuf = NULL;
-		cp->osize = 0;
-	}
-	close(cp->fd);
-	clients--;
-	cp->fd = -1;
-}
-
-int
-match(const char *s1, const char *s2)
-{
-	return (strncasecmp(s1, s2, strlen(s2)) == 0);
-}
-
-void
-nextstate(struct con *cp)
-{
-	if (match(cp->ibuf, "QUIT") && cp->state < 99) {
-		snprintf(cp->obuf, cp->osize, "221 %s\r\n", hostname);
-		cp->op = cp->obuf;
-		cp->ol = strlen(cp->op);
-		cp->w = t + cp->stutter;
-		cp->laststate = cp->state;
-		cp->state = 99;
-		return;
-	}
-
-	if (match(cp->ibuf, "RSET") && cp->state > 2 && cp->state < 50) {
-		snprintf(cp->obuf, cp->osize,
-		    "250 Ok to start over.\r\n");
-		cp->op = cp->obuf;
-		cp->ol = strlen(cp->op);
-		cp->w = t + cp->stutter;
-		cp->laststate = cp->state;
-		cp->state = 2;
-		return;
-	}
-	switch (cp->state) {
-	case 0:
-		/* banner sent; wait for input */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 1;
-		cp->r = t;
-		break;
-	case 1:
-		/* received input: parse, and select next state */
-		if (match(cp->ibuf, "HELO") ||
-		    match(cp->ibuf, "EHLO")) {
-			snprintf(cp->obuf, cp->osize,
-			    "250 Hello, spam sender. "
-			    "Pleased to be wasting your time.\r\n");
-			cp->op = cp->obuf;
-			cp->ol = strlen(cp->op);
-			cp->laststate = cp->state;
-			cp->state = 2;
-			cp->w = t + cp->stutter;
-			break;
-		}
-		goto mail;
-	case 2:
-		/* sent 250 Hello, wait for input */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 3;
-		cp->r = t;
-		break;
-	mail:
-	case 3:
-		if (match(cp->ibuf, "MAIL")) {
-			setlog(cp->mail, sizeof cp->mail, cp->ibuf);
-			snprintf(cp->obuf, cp->osize,
-			    "250 You are about to try to deliver spam. "
-			    "Your time will be spent, for nothing.\r\n");
-			cp->op = cp->obuf;
-			cp->ol = strlen(cp->op);
-			cp->laststate = cp->state;
-			cp->state = 4;
-			cp->w = t + cp->stutter;
-			break;
-		}
-		goto rcpt;
-	case 4:
-		/* sent 250 Sender ok */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 5;
-		cp->r = t;
-		break;
-	rcpt:
-	case 5:
-		if (match(cp->ibuf, "RCPT")) {
-			setlog(cp->rcpt, sizeof(cp->rcpt), cp->ibuf);
-			snprintf(cp->obuf, cp->osize,
-			    "250 This is hurting you more than it is "
-			    "hurting me.\r\n");
-			cp->op = cp->obuf;
-			cp->ol = strlen(cp->op);
-			cp->laststate = cp->state;
-			cp->state = 6;
-			cp->w = t + cp->stutter;
-			if (cp->mail[0] && cp->rcpt[0]) {
-				if (verbose)
-					syslog_r(LOG_INFO, &sdata,
-					    "(%s) %s: %s -> %s",
-					    cp->blacklists ? "BLACK" : "GREY",
-					    cp->addr, cp->mail,
-					    cp->rcpt);
-				if (debug)
-					fprintf(stderr, "(%s) %s: %s -> %s\n",
-					    cp->blacklists ? "BLACK" : "GREY",
-					    cp->addr, cp->mail, cp->rcpt);
-				if (greylist && cp->blacklists == NULL) {
-					/* send this info to the greylister */
-					fprintf(grey, "IP:%s\nFR:%s\nTO:%s\n",
-					    cp->addr, cp->mail, cp->rcpt);
-					fflush(grey);
-					cp->laststate = cp->state;
-					cp->state = 98;
-					goto done;
-				}
-			}
-			break;
-		}
-		goto spam;
-	case 6:
-		/* sent 250 blah */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 5;
-		cp->r = t;
-		break;
-
-	spam:
-	case 50:
-		if (match(cp->ibuf, "DATA")) {
-			snprintf(cp->obuf, cp->osize,
-			    "354 Enter spam, end with \".\" on a line by "
-			    "itself\r\n");
-			cp->state = 60;
-			if (window && setsockopt(cp->fd, SOL_SOCKET, SO_RCVBUF,
-			    &window, sizeof(window)) == -1) {
-				syslog_r(LOG_DEBUG, &sdata,"setsockopt: %m");
-				/* don't fail if this doesn't work. */
-			}
-		} else {
-			snprintf(cp->obuf, cp->osize,
-			    "500 5.5.1 Command unrecognized\r\n");
-			cp->state = cp->laststate;
-		}
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->op = cp->obuf;
-		cp->ol = strlen(cp->op);
-		cp->w = t + cp->stutter;
-		break;
-	case 60:
-		/* sent 354 blah */
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->laststate = cp->state;
-		cp->state = 70;
-		cp->r = t;
-		break;
-	case 70: {
-		char *p, *q;
-
-		for (p = q = cp->ibuf; q <= cp->ip; ++q)
-			if (*q == '\n' || q == cp->ip) {
-				*q = 0;
-				if (q > p && q[-1] == '\r')
-					q[-1] = 0;
-				if (!strcmp(p, ".") ||
-				    (cp->data_body && ++cp->data_lines >= 10)) {
-					cp->laststate = cp->state;
-					cp->state = 98;
-					goto done;
-				}
-				if (!cp->data_body && !*p)
-					cp->data_body = 1;
-				if (verbose && cp->data_body && *p)
-					syslog_r(LOG_DEBUG, &sdata, "%s: "
-					    "Body: %s", cp->addr, p);
-				else if (verbose && (match(p, "FROM:") ||
-				    match(p, "TO:") || match(p, "SUBJECT:")))
-					syslog_r(LOG_INFO, &sdata, "%s: %s",
-					    cp->addr, p);
-				p = ++q;
-			}
-		cp->ip = cp->ibuf;
-		cp->il = sizeof(cp->ibuf) - 1;
-		cp->r = t;
-		break;
-	}
-	done:
-	case 98:
-		doreply(cp);
-		cp->op = cp->obuf;
-		cp->ol = strlen(cp->op);
-		cp->w = t + cp->stutter;
-		cp->laststate = cp->state;
-		cp->state = 99;
-		break;
-	case 99:
-		closecon(cp);
-		break;
-	default:
-		errx(1, "illegal state %d", cp->state);
-		break;
-	}
-}
-
-void
-handler(struct con *cp)
-{
-	int end = 0;
-	int n;
-
-	if (cp->r) {
-		n = read(cp->fd, cp->ip, cp->il);
-		if (n == 0)
-			closecon(cp);
-		else if (n == -1) {
-			if (debug > 0)
-				perror("read()");
-			closecon(cp);
-		} else {
-			cp->ip[n] = '\0';
-			if (cp->rend[0])
-				if (strpbrk(cp->ip, cp->rend))
-					end = 1;
-			cp->ip += n;
-			cp->il -= n;
-		}
-	}
-	if (end || cp->il == 0) {
-		while (cp->ip > cp->ibuf &&
-		    (cp->ip[-1] == '\r' || cp->ip[-1] == '\n'))
-			cp->ip--;
-		*cp->ip = '\0';
-		cp->r = 0;
-		nextstate(cp);
-	}
-}
-
-void
-handlew(struct con *cp, int one)
-{
-	int n;
-
-	if (cp->w) {
-		if (*cp->op == '\n' && !cp->sr) {
-			/* insert \r before \n */
-			n = write(cp->fd, "\r", 1);
-			if (n == 0) {
-				closecon(cp);
-				goto handled;
-			} else if (n == -1) {
-				if (debug > 0 && errno != EPIPE)
-					perror("write()");
-				closecon(cp);
-				goto handled;
-			}
-		}
-		if (*cp->op == '\r')
-			cp->sr = 1;
-		else
-			cp->sr = 0;
-		n = write(cp->fd, cp->op, (one && cp->stutter) ? 1 : cp->ol);
-		if (n == 0)
-			closecon(cp);
-		else if (n == -1) {
-			if (debug > 0 && errno != EPIPE)
-				perror("write()");
-			closecon(cp);
-		} else {
-			cp->op += n;
-			cp->ol -= n;
-		}
-	}
-handled:
-	cp->w = t + cp->stutter;
-	if (cp->ol == 0) {
-		cp->w = 0;
-		nextstate(cp);
-	}
-}
-
-int
-main(int argc, char *argv[])
-{
-	fd_set *fdsr = NULL, *fdsw = NULL;
-	struct sockaddr_in sin;
-	struct sockaddr_in lin;
-	int ch, s, s2, conflisten = 0, i, omax = 0, one = 1;
-	socklen_t sinlen;
-	u_short port;
-	struct servent *ent;
-	struct rlimit rlp;
-	char *bind_address = NULL;
-
-	tzset();
-	openlog_r("spamd", LOG_PID | LOG_NDELAY, LOG_DAEMON, &sdata);
-
-	if ((ent = getservbyname("spamd", "tcp")) == NULL)
-		errx(1, "Can't find service \"spamd\" in /etc/services");
-	port = ntohs(ent->s_port);
-	if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL)
-		errx(1, "Can't find service \"spamd-cfg\" in /etc/services");
-	cfg_port = ntohs(ent->s_port);
-
-	if (gethostname(hostname, sizeof hostname) == -1)
-		err(1, "gethostname");
-
-	while ((ch = getopt(argc, argv, "45b:c:B:p:dgG:r:s:n:vw:")) != -1) {
-		switch (ch) {
-		case '4':
-			nreply = "450";
-			break;
-		case '5':
-			nreply = "550";
-			break;
-		case 'b':
-			bind_address = optarg;
-			break;
-		case 'B':
-			i = atoi(optarg);
-			maxblack = i;
-			break;
-		case 'c':
-			i = atoi(optarg);
-			if (i > MAXCON)
-				usage();
-			maxcon = i;
-			break;
-		case 'p':
-			i = atoi(optarg);
-			port = i;
-			break;
-		case 'd':
-			debug = 1;
-			break;
-		case 'g':
-			greylist = 1;
-			break;
-		case 'G':
-			if (sscanf(optarg, "%d:%d:%d", &passtime, &greyexp,
-			    &whiteexp) != 3)
-				usage();
-			/* convert to seconds from minutes */
-			passtime *= 60;
-			/* convert to seconds from hours */
-			whiteexp *= (60 * 60);
-			/* convert to seconds from hours */
-			greyexp *= (60 * 60);
-			break;
-		case 'r':
-			reply = optarg;
-			break;
-		case 's':
-			i = atoi(optarg);
-			if (i < 0 || i > 10)
-				usage();
-			stutter = i;
-			break;
-		case 'n':
-			spamd = optarg;
-			break;
-		case 'v':
-			verbose = 1;
-			break;
-		case 'w':
-			window = atoi(optarg);
-			if (window <= 0)
-				usage();
-			break;
-		default:
-			usage();
-			break;
-		}
-	}
-
-	if (!greylist)
-		maxblack = maxcon;
-	else if (maxblack > maxcon)
-		usage();
-
-	rlp.rlim_cur = rlp.rlim_max = maxcon + 15;
-	if (setrlimit(RLIMIT_NOFILE, &rlp) == -1)
-		err(1, "setrlimit");
-
-	con = calloc(maxcon, sizeof(*con));
-	if (con == NULL)
-		err(1, "calloc");
-
-	con->obuf = malloc(8192);
-
-	if (con->obuf == NULL)
-		err(1, "malloc");
-	con->osize = 8192;
-
-	for (i = 0; i < maxcon; i++)
-		con[i].fd = -1;
-
-	signal(SIGPIPE, SIG_IGN);
-
-	s = socket(AF_INET, SOCK_STREAM, 0);
-	if (s == -1)
-		err(1, "socket");
-
-	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one,
-	    sizeof(one)) == -1)
-		return (-1);
-
-	conflisten = socket(AF_INET, SOCK_STREAM, 0);
-	if (conflisten == -1)
-		err(1, "socket");
-
-	if (setsockopt(conflisten, SOL_SOCKET, SO_REUSEADDR, &one,
-	    sizeof(one)) == -1)
-		return (-1);
-
-	memset(&sin, 0, sizeof sin);
-	sin.sin_len = sizeof(sin);
-	if (bind_address) {
-		if (inet_pton(AF_INET, bind_address, &sin.sin_addr) != 1)
-			err(1, "inet_pton");
-	} else
-		sin.sin_addr.s_addr = htonl(INADDR_ANY);
-	sin.sin_family = AF_INET;
-	sin.sin_port = htons(port);
-
-	if (bind(s, (struct sockaddr *)&sin, sizeof sin) == -1)
-		err(1, "bind");
-
-	memset(&lin, 0, sizeof sin);
-	lin.sin_len = sizeof(sin);
-	lin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-	lin.sin_family = AF_INET;
-	lin.sin_port = htons(cfg_port);
-
-	if (bind(conflisten, (struct sockaddr *)&lin, sizeof lin) == -1)
-		err(1, "bind local");
-
-	pw = getpwnam("_spamd");
-	if (!pw)
-		pw = getpwnam("nobody");
-
-	if (debug == 0) {
-		if (daemon(1, 1) == -1)
-			err(1, "daemon");
-	}
-
-	if (greylist) {
-		maxblack = (maxblack >= maxcon) ? maxcon - 100 : maxblack;
-		if (maxblack < 0)
-			maxblack = 0;
-
-		/* open pipe to talk to greylister */
-		if (pipe(greypipe) == -1) {
-			syslog(LOG_ERR, "pipe (%m)");
-			exit(1);
-		}
-		/* open pipe to recieve spamtrap configs */
-		if (pipe(trappipe) == -1) {
-			syslog(LOG_ERR, "pipe (%m)");
-			exit(1);
-		}
-		jail_pid = fork();
-		switch(jail_pid) {
-		case -1:
-			syslog(LOG_ERR, "fork (%m)");
-			exit(1);
-		case 0:
-			/* child - continue */
-			grey = fdopen(greypipe[1], "w");
-			if (grey == NULL) {
-				syslog(LOG_ERR, "fdopen (%m)");
-				_exit(1);
-			}
-			close(greypipe[0]);
-			trapfd = trappipe[0];
-			trapcfg = fdopen(trappipe[0], "r");
-			if (trapcfg == NULL) {
-				syslog(LOG_ERR, "fdopen (%m)");
-				_exit(1);
-			}
-			close(trappipe[1]);
-			goto jail;
-		}
-		/* parent - run greylister */
-		grey = fdopen(greypipe[0], "r");
-		if (grey == NULL) {
-			syslog(LOG_ERR, "fdopen (%m)");
-			exit(1);
-		}
-		close(greypipe[1]);
-		trapcfg = fdopen(trappipe[1], "w");
-		if (trapcfg == NULL) {
-			syslog(LOG_ERR, "fdopen (%m)");
-			exit(1);
-		}
-		close(trappipe[0]);
-		return(greywatcher());
-		/* NOTREACHED */
-	}
-
-jail:
-	if (chroot("/var/empty") == -1 || chdir("/") == -1) {
-		syslog(LOG_ERR, "cannot chdir to /var/empty.");
-		exit(1);
-	}
-
-	if (pw) {
-		setgroups(1, &pw->pw_gid);
-		setegid(pw->pw_gid);
-		setgid(pw->pw_gid);
-		seteuid(pw->pw_uid);
-		setuid(pw->pw_uid);
-	}
-
-	if (listen(s, 10) == -1)
-		err(1, "listen");
-
-	if (listen(conflisten, 10) == -1)
-		err(1, "listen");
-
-	if (debug != 0)
-		printf("listening for incoming connections.\n");
-	syslog_r(LOG_WARNING, &sdata, "listening for incoming connections.");
-
-	while (1) {
-		struct timeval tv, *tvp;
-		int max, i, n;
-		int writers;
-
-		max = MAX(s, conflisten);
-		max = MAX(max, conffd);
-		max = MAX(max, trapfd);
-
-		time(&t);
-		for (i = 0; i < maxcon; i++)
-			if (con[i].fd != -1)
-				max = MAX(max, con[i].fd);
-
-		if (max > omax) {
-			free(fdsr);
-			fdsr = NULL;
-			free(fdsw);
-			fdsw = NULL;
-			fdsr = (fd_set *)calloc(howmany(max+1, NFDBITS),
-			    sizeof(fd_mask));
-			if (fdsr == NULL)
-				err(1, "calloc");
-			fdsw = (fd_set *)calloc(howmany(max+1, NFDBITS),
-			    sizeof(fd_mask));
-			if (fdsw == NULL)
-				err(1, "calloc");
-			omax = max;
-		} else {
-			memset(fdsr, 0, howmany(max+1, NFDBITS) *
-			    sizeof(fd_mask));
-			memset(fdsw, 0, howmany(max+1, NFDBITS) *
-			    sizeof(fd_mask));
-		}
-
-		writers = 0;
-		for (i = 0; i < maxcon; i++) {
-			if (con[i].fd != -1 && con[i].r) {
-				if (con[i].r + MAXTIME <= t) {
-					closecon(&con[i]);
-					continue;
-				}
-				FD_SET(con[i].fd, fdsr);
-			}
-			if (con[i].fd != -1 && con[i].w) {
-				if (con[i].w + MAXTIME <= t) {
-					closecon(&con[i]);
-					continue;
-				}
-				if (con[i].w <= t)
-					FD_SET(con[i].fd, fdsw);
-				writers = 1;
-			}
-		}
-		FD_SET(s, fdsr);
-
-		/* only one active config conn at a time */
-		if (conffd == -1)
-			FD_SET(conflisten, fdsr);
-		else
-			FD_SET(conffd, fdsr);
-		if (trapfd != -1)
-			FD_SET(trapfd, fdsr);
-
-		if (writers == 0) {
-			tvp = NULL;
-		} else {
-			tv.tv_sec = 1;
-			tv.tv_usec = 0;
-			tvp = &tv;
-		}
-
-		n = select(max+1, fdsr, fdsw, NULL, tvp);
-		if (n == -1) {
-			if (errno != EINTR)
-				err(1, "select");
-			continue;
-		}
-		if (n == 0)
-			continue;
-
-		for (i = 0; i < maxcon; i++) {
-			if (con[i].fd != -1 && FD_ISSET(con[i].fd, fdsr))
-				handler(&con[i]);
-			if (con[i].fd != -1 && FD_ISSET(con[i].fd, fdsw))
-				handlew(&con[i], clients + 5 < maxcon);
-		}
-		if (FD_ISSET(s, fdsr)) {
-			sinlen = sizeof(sin);
-			s2 = accept(s, (struct sockaddr *)&sin, &sinlen);
-			if (s2 == -1)
-				/* accept failed, they may try again */
-				continue;
-			for (i = 0; i < maxcon; i++)
-				if (con[i].fd == -1)
-					break;
-			if (i == maxcon)
-				close(s2);
-			else {
-				initcon(&con[i], s2, (struct sockaddr *)&sin);
-				syslog_r(LOG_INFO, &sdata,
-				    "%s: connected (%d/%d)%s%s",
-				    con[i].addr, clients, blackcount,
-				    ((con[i].lists == NULL) ? "" :
-				    ", lists:"),
-				    ((con[i].lists == NULL) ? "":
-				    con[i].lists));
-			}
-		}
-		if (FD_ISSET(conflisten, fdsr)) {
-			sinlen = sizeof(lin);
-			conffd = accept(conflisten, (struct sockaddr *)&lin,
-			    &sinlen);
-			if (conffd == -1)
-				/* accept failed, they may try again */
-				continue;
-			else if (ntohs(lin.sin_port) >= IPPORT_RESERVED) {
-				close(conffd);
-				conffd = -1;
-			}
-		}
-		if (conffd != -1 && FD_ISSET(conffd, fdsr))
-			do_config();
-		if (trapfd != -1 && FD_ISSET(trapfd, fdsr))
-			read_configline(trapcfg);
-	}
-	exit(1);
-}
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamd/spamd.o and /usr/home/samm/spamd/work/spamd_3.7/spamd/spamd.o differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/Makefile /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/Makefile
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/Makefile	Sun Oct  3 16:09:15 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/Makefile	Thu Jan  1 03:00:00 1970
@@ -1,12 +0,0 @@
-#	$OpenBSD: Makefile,v 1.3 2004/01/21 08:07:41 deraadt Exp $
-
-PROG=	spamd-setup
-SRCS=	spamd-setup.c
-MAN=	spamd-setup.8
-
-LDADD=	-lz
-DPADD=	${LIBZ}
-
-CFLAGS+= -Wall -Wstrict-prototypes -ansi -D_NO_NAMESPACE_POLLUTION
-
-.include <bsd.prog.mk>
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup and /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8 /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8	Fri Feb  2 10:40:32 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8	Thu Jan  1 03:00:00 1970
@@ -1,95 +0,0 @@
-.\"	$OpenBSD: spamd-setup.8,v 1.9 2004/01/29 17:41:00 jmc Exp $
-.\"
-.\" Copyright (c) 2003 Jason L. Wright (jason at thought.net)
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd February 14, 2003
-.Dt SPAMD-SETUP 8
-.Os
-.Sh NAME
-.Nm spamd-setup
-.Nd parse and load file of spammer addresses
-.Sh SYNOPSIS
-.Nm spamd-setup
-.Op Fl dn
-.Sh DESCRIPTION
-The
-.Nm
-utility adds blacklists by adding addresses to the
-.Xr pf 4
-table
-.Em <spamd> ,
-as well as configuring mail rejection messages for
-the added list of addresses in
-.Xr spamd 8 .
-The
-.Em spamd
-table is used in conjunction with a
-.Xr pf 4
-redirection rule to selectively redirect mail connections
-to the
-.Xr spamd 8
-daemon.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl d
-Debug mode reports a few pieces of information.
-.It Fl n
-Dry-run mode.
-No data is shipped to
-.Xr pf 4 .
-.El
-.Pp
-Blacklists and whitelists are specified in the configuration file
-.Pa /usr/local/etc/spamd.conf
-and are processed in the order specified in the
-.Ar all
-tag.
-Output is concatenated to build up a table for
-.Xr pf 4 .
-Then the blacklist addresses are sent to a running
-.Xr spamd 8
-along with the message spamd will give on mail rejection when a
-matching client connects.
-The configuration port for
-.Xr spamd 8
-is found from
-.Xr services 5 ,
-by looking for the named service
-.Em spamd-cfg .
-.Pp
-.Nm
-reads all configuration information from a
-.Xr spamd.conf 5
-file.
-.Sh FILES
-.Bd -literal
-/usr/local/etc/spamd.conf
-.Ed
-.Sh SEE ALSO
-.Xr ftp 1 ,
-.Xr pf 4 ,
-.Xr services 5 ,
-.Xr spamd.conf 5 ,
-.Xr spamd 8
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8.bak /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8.bak
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8.bak	Sun Oct  3 16:09:15 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8.bak	Thu Jan  1 03:00:00 1970
@@ -1,95 +0,0 @@
-.\"	$OpenBSD: spamd-setup.8,v 1.9 2004/01/29 17:41:00 jmc Exp $
-.\"
-.\" Copyright (c) 2003 Jason L. Wright (jason at thought.net)
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd February 14, 2003
-.Dt SPAMD-SETUP 8
-.Os
-.Sh NAME
-.Nm spamd-setup
-.Nd parse and load file of spammer addresses
-.Sh SYNOPSIS
-.Nm spamd-setup
-.Op Fl dn
-.Sh DESCRIPTION
-The
-.Nm
-utility adds blacklists by adding addresses to the
-.Xr pf 4
-table
-.Em <spamd> ,
-as well as configuring mail rejection messages for
-the added list of addresses in
-.Xr spamd 8 .
-The
-.Em spamd
-table is used in conjunction with a
-.Xr pf 4
-redirection rule to selectively redirect mail connections
-to the
-.Xr spamd 8
-daemon.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl d
-Debug mode reports a few pieces of information.
-.It Fl n
-Dry-run mode.
-No data is shipped to
-.Xr pf 4 .
-.El
-.Pp
-Blacklists and whitelists are specified in the configuration file
-.Pa /etc/spamd.conf
-and are processed in the order specified in the
-.Ar all
-tag.
-Output is concatenated to build up a table for
-.Xr pf 4 .
-Then the blacklist addresses are sent to a running
-.Xr spamd 8
-along with the message spamd will give on mail rejection when a
-matching client connects.
-The configuration port for
-.Xr spamd 8
-is found from
-.Xr services 5 ,
-by looking for the named service
-.Em spamd-cfg .
-.Pp
-.Nm
-reads all configuration information from a
-.Xr spamd.conf 5
-file.
-.Sh FILES
-.Bd -literal
-/etc/spamd.conf
-.Ed
-.Sh SEE ALSO
-.Xr ftp 1 ,
-.Xr pf 4 ,
-.Xr services 5 ,
-.Xr spamd.conf 5 ,
-.Xr spamd 8
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8.gz and /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.8.gz differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c	Fri Feb  2 10:40:32 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c	Thu Jan  1 03:00:00 1970
@@ -1,924 +0,0 @@
-/*	$OpenBSD: spamd-setup.c,v 1.21 2005/03/02 16:45:30 dhartmei Exp $ */
-
-/*
- * Copyright (c) 2003 Bob Beck.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <err.h>
-#ifdef __OpenBSD__
-#include <netinet/ip_ipsp.h>
-#endif
-#include <netdb.h>
-#include <zlib.h>
-
-#ifdef IPFW
-#include <net/if.h>
-#include <netinet/ip_fw.h>
-#endif
-
-#define PATH_FTP		"/usr/bin/ftp"
-#define PATH_PFCTL		""
-#define PATH_SPAMD_CONF		"/usr/local/etc/spamd.conf"
-#define SPAMD_ARG_MAX		256 /* max # of args to an exec */
-
-struct cidr {
-	u_int32_t addr;
-	u_int8_t bits;
-};
-
-struct bl {
-	u_int32_t addr;
-	int8_t b;
-	int8_t w;
-};
-
-struct blacklist {
-	char *name;
-	char *message;
-	struct bl *bl;
-	size_t blc, bls;
-	u_int8_t black;
-	int count;
-};
-
-u_int32_t	imask(u_int8_t b);
-u_int8_t	maxblock(u_int32_t addr, u_int8_t bits);
-u_int8_t	maxdiff(u_int32_t a, u_int32_t b);
-struct cidr	*range2cidrlist(u_int32_t start, u_int32_t end);
-void		cidr2range(struct cidr cidr, u_int32_t *start, u_int32_t *end);
-char		*atop(u_int32_t addr);
-u_int32_t	ptoa(char *cp);
-int		parse_netblock(char *buf, struct bl *start, struct bl *end,
-		    int white);
-int		open_child(char *file, char **argv);
-int		fileget(char *url);
-int		open_file(char *method, char *file);
-char		*fix_quoted_colons(char *buf);
-void		do_message(FILE *sdc, char *msg);
-struct bl	*add_blacklist(struct bl *bl, int *blc, int *bls, gzFile gzf,
-		    int white);
-int		cmpbl(const void *a, const void *b);
-struct cidr	**collapse_blacklist(struct bl *bl, int blc);
-int		configure_spamd(u_short dport, char *name, char *message,
-		    struct cidr **blacklists);
-int		configure_pf(struct cidr **blacklists);
-int		getlist(char ** db_array, char *name, struct blacklist *blist,
-		    struct blacklist *blistnew);
-
-int		debug;
-int		dryrun;
-
-#ifdef IPFW
-int tabno=2;
-#endif
-
-
-u_int32_t
-imask(u_int8_t b)
-{
-	u_int32_t j = 0;
-	int i;
-
-	for (i = 31; i > 31 - b; --i)
-		j |= (1 << i);
-	return(j);
-}
-
-u_int8_t
-maxblock(u_int32_t addr, u_int8_t bits)
-{
-	while (bits > 0) {
-		u_int32_t m = imask(bits - 1);
-
-		if ((addr & m) != addr)
-			return (bits);
-		bits--;
-	}
-	return(bits);
-}
-
-u_int8_t
-maxdiff(u_int32_t a, u_int32_t b)
-{
-	u_int8_t bits = 0;
-
-	b++;
-	while (bits < 32) {
-		u_int32_t m = imask(bits);
-
-		if ((a & m) != (b & m))
-			return (bits);
-		bits++;
-	}
-	return(bits);
-}
-
-struct cidr *
-range2cidrlist(u_int32_t start, u_int32_t end)
-{
-	struct cidr *list = NULL;
-	size_t cs = 0, cu = 0;
-
-	while (end >= start) {
-		u_int8_t maxsize = maxblock(start, 32);
-		u_int8_t diff = maxdiff(start, end);
-
-		maxsize = MAX(maxsize, diff);
-		if (cs == cu) {
-			struct cidr *tmp;
-
-			tmp = realloc(list, (cs + 32) * sizeof(struct cidr));
-			if (tmp == NULL)
-				errx(1, "malloc failed");
-			list = tmp;
-			cs += 32;
-		}
-		list[cu].addr = start;
-		list[cu].bits = maxsize;
-		cu++;
-		list[cu].addr = 0;
-		list[cu].bits = 0;
-		start = start + (1 << (32 - maxsize));
-	}
-	return(list);
-}
-
-void
-cidr2range(struct cidr cidr, u_int32_t *start, u_int32_t *end)
-{
-	*start = cidr.addr;
-	*end = cidr.addr + (1 << (32 - cidr.bits)) - 1;
-}
-
-char *
-atop(u_int32_t addr)
-{
-	struct in_addr in;
-
-	memset(&in, 0, sizeof(in));
-	in.s_addr = htonl(addr);
-	return(inet_ntoa(in));
-}
-
-int
-parse_netblock(char *buf, struct bl *start, struct bl *end, int white)
-{
-	char astring[16], astring2[16];
-	unsigned maskbits;
-
-	/* skip leading spaces */
-	while (*buf == ' ')
-		buf++;
-	/* bail if it's a comment */
-	if (*buf == '#')
-		return(0);
-	/* otherwise, look for a netblock of some sort */
-	if (sscanf(buf, "%15[^/]/%u", astring, &maskbits) == 2) {
-		/* looks like a cidr */
-		struct cidr c;
-
-		memset(&c.addr, 0, sizeof(c.addr));
-		if (inet_net_pton(AF_INET, astring, &c.addr, sizeof(c.addr))
-		    == -1)
-			return(0);
-		c.addr = ntohl(c.addr);
-		if (maskbits > 32)
-			return(0);
-		c.bits = maskbits;
-		cidr2range(c, &start->addr, &end->addr);
-		end->addr += 1;
-	} else if (sscanf(buf, "%15[0123456789.]%*[ -]%15[0123456789.]",
-	    astring, astring2) == 2) {
-		/* looks like start - end */
-		memset(&start->addr, 0, sizeof(start->addr));
-		memset(&end->addr, 0, sizeof(end->addr));
-		if (inet_net_pton(AF_INET, astring, &start->addr,
-		    sizeof(start->addr)) == -1)
-			return(0);
-		start->addr = ntohl(start->addr);
-		if (inet_net_pton(AF_INET, astring2, &end->addr,
-		    sizeof(end->addr)) == -1)
-			return(0);
-		end->addr = ntohl(end->addr) + 1;
-		if (start > end)
-			return(0);
-	} else if (sscanf(buf, "%15[0123456789.]", astring) == 1) {
-		/* just a single address */
-		memset(&start->addr, 0, sizeof(start->addr));
-		if (inet_net_pton(AF_INET, astring, &start->addr,
-		    sizeof(start->addr)) == -1)
-			return(0);
-		start->addr = ntohl(start->addr);
-		end->addr = start->addr + 1;
-	} else
-		return(0);
-
-	if (white) {
-		start->b = 0;
-		start->w = 1;
-		end->b = 0;
-		end->w = -1;
-	} else {
-		start->b = 1;
-		start->w = 0;
-		end->b = -1;
-		end->w = 0;
-	}
-	return(1);
-}
-
-int
-open_child(char *file, char **argv)
-{
-	int pdes[2];
-
-	if (pipe(pdes) != 0)
-		return(-1);
-	switch (fork()) {
-	case -1:
-		close(pdes[0]);
-		close(pdes[1]);
-		return(-1);
-	case 0:
-		/* child */
-		close(pdes[0]);
-		if (pdes[1] != STDOUT_FILENO) {
-			dup2(pdes[1], STDOUT_FILENO);
-			close(pdes[1]);
-		}
-		execvp(file, argv);
-		_exit(1);
-	}
-
-	/* parent */
-	close(pdes[1]);
-	return(pdes[0]);
-}
-
-int
-fileget(char *url)
-{
-	char *argv[6];
-
-	argv[0] = "ftp";
-	argv[1] = "-V";
-	argv[2] = "-o";
-	argv[3] = "-";
-	argv[4] = url;
-	argv[5] = NULL;
-
-	if (debug)
-		fprintf(stderr, "Getting %s\n", url);
-
-	return open_child(PATH_FTP, argv);
-}
-
-int
-open_file(char *method, char *file)
-{
-	char *url;
-
-	if ((method == NULL) || (strcmp(method, "file") == 0))
-		return(open(file, O_RDONLY));
-	if ((strcmp(method, "http") == 0) ||
-	    strcmp(method, "ftp") == 0) {
-		int i;
-
-		asprintf(&url, "%s://%s", method, file);
-		if (url == NULL)
-			return(-1);
-		i = fileget(url);
-		free(url);
-		return(i);
-	} else if (strcmp(method, "exec") == 0) {
-		char **ap, **argv;
-		int len, i, oerrno;
-
-		len = strlen(file);
-		argv = malloc(len * sizeof(char *));
-		if (argv == NULL)
-			errx(1, "malloc failed");
-		for (ap = argv; ap < &argv[len - 1] &&
-		    (*ap = strsep(&file, " \t")) != NULL;) {
-			if (**ap != '\0')
-				ap++;
-		}
-		*ap = NULL;
-		i = open_child(argv[0], argv);
-		oerrno = errno;
-		free(argv);
-		errno = oerrno;
-		return(i);
-	}
-	errx(1, "Unknown method %s", method);
-	return(-1); /* NOTREACHED */
-}
-
-/*
- * fix_quoted_colons walks through a buffer returned by cgetent.  We
- * look for quoted strings, to escape colons (:) in quoted strings for
- * getcap by replacing them with \C so cgetstr() deals with it correctly
- * without having to see the \C bletchery in a configuration file that
- * needs to have urls in it. Frees the buffer passed to it, passes back
- * another larger one, with can be used with cgetxxx(), like the original
- * buffer, it must be freed by the caller.
- * This should really be a temporary fix until there is a sanctioned
- * way to make getcap(3) handle quoted strings like this in a nicer
- * way.
- */
-char *
-fix_quoted_colons(char *buf)
-{
-	int nbs = 0, i = 0, j = 0, in = 0;
-	char *newbuf, last;
-
-	nbs = strlen(buf) + 128;
-	newbuf = malloc(nbs);
-	if (newbuf == NULL)
-		return NULL;
-	last = '\0';
-	for (i = 0; i < strlen(buf); i++) {
-		switch (buf[i]) {
-		case ':':
-			if (in) {
-				newbuf[j++] = '\\';
-				newbuf[j++] = 'C';
-			} else
-				newbuf[j++] = buf[i];
-			break;
-		case '"':
-			if (last != '\\')
-				in = !in;
-			newbuf[j++] = buf[i];
-			break;
-		default:
-			newbuf[j++] = buf[i];
-		}
-		if (j == nbs) {
-			char *tmp;
-
-			nbs += 128;
-			tmp = realloc(newbuf, nbs);
-			if (tmp == NULL)
-				errx(1, "malloc failed");
-			newbuf = tmp;
-		}
-	}
-	free(buf);
-	newbuf[j] = '\0';
-	return(newbuf);
-}
-
-void
-do_message(FILE *sdc, char *msg)
-{
-	int i, n, bu = 0, bs = 0, len;
-	char *buf = NULL, last;
-
-	len = strlen(msg);
-	if (msg[0] == '"' && msg[len - 1] == '"') {
-		/* quoted msg, escape newlines and send it out */
-		msg[len - 1] = '\0';
-		buf = msg+1;
-		bu = len - 2;
-		goto sendit;
-	} else {
-		int fd;
-
-		/*
-		 * message isn't quoted - try to open a local
-		 * file and read the message from it.
-		 */
-		fd = open(msg, O_RDONLY);
-		if (fd == -1)
-			err(1, "Can't open message from %s", msg);
-		for (;;) {
-			if (bu == bs) {
-				char *tmp;
-
-				tmp = realloc(buf, bs + 8192);
-				if (tmp == NULL)
-					errx(1, "malloc failed");
-				bs += 8192;
-				buf = tmp;
-			}
-
-			n = read(fd, buf + bu, bs - bu);
-			if (n == 0) {
-				goto sendit;
-			} else if (n == -1) {
-				err(1, "Can't read from %s", msg);
-			} else
-				bu += n;
-		}
-		buf[bu]='\0';
-	}
- sendit:
-	fprintf(sdc, ";\"");
-	last = '\0';
-	for (i = 0; i < bu; i++) {
-		/* handle escaping the things spamd wants */
-		switch (buf[i]) {
-		case 'n':
-			if (last == '\\')
-				fprintf(sdc, "\\\\n");
-			else
-				fputc('n', sdc);
-			last = '\0';
-			break;
-		case '\n':
-			fprintf(sdc, "\\n");
-			last = '\0';
-			break;
-		case '"':
-			fputc('\\', sdc);
-			/* fall through */
-		default:
-			fputc(buf[i], sdc);
-			last = '\0';
-		}
-	}
-	fputc('"', sdc);
-	if (bs != 0)
-		free(buf);
-}
-
-/* retrieve a list from fd. add to blacklist bl */
-struct bl *
-add_blacklist(struct bl *bl, int *blc, int *bls, gzFile gzf, int white)
-{
-	int i, n, start, bu = 0, bs = 0, serrno = 0;
-	char *buf = NULL;
-
-	for (;;) {
-		/* read in gzf, then parse */
-		if (bu == bs) {
-			char *tmp;
-
-			tmp = realloc(buf, bs + 8192 + 1);
-			if (tmp == NULL) {
-				free(buf);
-				buf = NULL;
-				bs = 0;
-				serrno = errno;
-				goto bldone;
-			}
-			bs += 8192;
-			buf = tmp;
-		}
-
-		n = gzread(gzf, buf + bu, bs - bu);
-		if (n == 0)
-			goto parse;
-		else if (n == -1) {
-			serrno = errno;
-			goto bldone;
-		} else
-			bu += n;
-	}
- parse:
-	start = 0;
-	for (i = 0; i <= bu; i++) {
-		if (*blc == *bls) {
-			struct bl *tmp;
-
-			*bls += 1024;
-			tmp = realloc(bl, *bls * sizeof(struct bl));
-			if (tmp == NULL) {
-				*bls -= 1024;
-				serrno = errno;
-				goto bldone;
-			}
-			bl = tmp;
-		}
-		if (i == bu || buf[i] == '\n') {
-			buf[i] = '\0';
-			if (parse_netblock(buf + start,
-			    bl + *blc, bl + *blc + 1, white))
-				*blc+=2;
-			start = i+1;
-		}
-	}
-	if (bu == 0)
-		errno = EIO;
- bldone:
-	if (buf)
-		free(buf);
-	if (serrno)
-		errno = serrno;
-	return (bl);
-}
-
-int
-cmpbl(const void *a, const void *b)
-{
-	if (((struct bl *)a)->addr > ((struct bl *) b)->addr)
-		return(1);
-	if (((struct bl *)a)->addr < ((struct bl *) b)->addr)
-		return(-1);
-	return(0);
-}
-
-/*
- * collapse_blacklist takes blacklist/whitelist entries sorts, removes
- * overlaps and whitelist portions, and returns netblocks to blacklist
- * as lists of nonoverlapping cidr blocks suitable for feeding in
- * printable form to pfctl or spamd.
- */
-struct cidr **
-collapse_blacklist(struct bl *bl, int blc)
-{
-	int bs = 0, ws = 0, state=0, cli, i;
-	u_int32_t bstart = 0;
-	struct cidr **cl;
-
-	if (blc == 0)
-		return(NULL);
-	cl = malloc((blc / 2) * sizeof(struct cidr));
-	if (cl == NULL) {
-		return (NULL);
-	}
-	qsort(bl, blc, sizeof(struct bl), cmpbl);
-	cli = 0;
-	cl[cli] = NULL;
-	for (i = 0; i < blc;) {
-		int laststate = state;
-		u_int32_t addr = bl[i].addr;
-
-		do {
-			bs += bl[i].b;
-			ws += bl[i].w;
-			i++;
-		} while (bl[i].addr == addr);
-		if (state == 1 && bs == 0)
-			state = 0;
-		else if (state == 0 && bs > 0)
-			state = 1;
-		if (ws > 0)
-			state = 0;
-		if (laststate == 0 && state == 1) {
-			/* start blacklist */
-			bstart = addr;
-		}
-		if (laststate == 1 && state == 0) {
-			/* end blacklist */
-			cl[cli++] = range2cidrlist(bstart, addr - 1);
-			cl[cli] = NULL;
-		}
-		laststate = state;
-	}
-	return (cl);
-}
-
-int
-configure_spamd(u_short dport, char *name, char *message,
-    struct cidr **blacklists)
-{
-	int lport = IPPORT_RESERVED - 1, s;
-	struct sockaddr_in sin;
-	FILE* sdc;
-
-	s = rresvport(&lport);
-	if (s == -1)
-		return(-1);
-	memset(&sin, 0, sizeof sin);
-	sin.sin_len = sizeof(sin);
-	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-	sin.sin_family = AF_INET;
-	sin.sin_port = htons(dport);
-	if (connect(s, (struct sockaddr *)&sin, sizeof sin) == -1)
-		return(-1);
-	sdc = fdopen(s, "w");
-	if (sdc == NULL) {
-		close(s);
-		return(-1);
-	}
-	fprintf(sdc, "%s", name);
-	do_message(sdc, message);
-	while (*blacklists != NULL) {
-		struct cidr *b = *blacklists;
-		while (b->addr != 0) {
-			fprintf(sdc, ";%s/%u", atop(b->addr), (b->bits));
-			b++;
-		}
-		blacklists++;
-	}
-	fputc('\n', sdc);
-	fclose(sdc);
-	close(s);
-	return(0);
-}
-
-
-#ifndef IPFW
-int
-configure_pf(struct cidr **blacklists)
-{
-	char *argv[9]= {"pfctl", "-q", "-t", "spamd", "-T", "replace",
-	    "-f" "-", NULL};
-	static FILE *pf = NULL;
-	int pdes[2];
-
-	if (pf == NULL) {
-		if (pipe(pdes) != 0)
-			return(-1);
-		switch (fork()) {
-		case -1:
-			close(pdes[0]);
-			close(pdes[1]);
-			return(-1);
-		case 0:
-			/* child */
-			close(pdes[1]);
-			if (pdes[0] != STDIN_FILENO) {
-				dup2(pdes[0], STDIN_FILENO);
-				close(pdes[0]);
-			}
-			execvp(PATH_PFCTL, argv);
-			_exit(1);
-		}
-
-		/* parent */
-		close(pdes[0]);
-		pf = fdopen(pdes[1], "w");
-		if (pf == NULL) {
-			close(pdes[1]);
-			return(-1);
-		}
-	}
-	while (*blacklists != NULL) {
-		struct cidr *b = *blacklists;
-
-		while (b->addr != 0) {
-			fprintf(pf, "%s/%u\n", atop(b->addr), (b->bits));
-			b++;
-		}
-		blacklists++;
-	}
-	return(0);
-}
-#else
-int
-configure_pf(struct cidr **blacklists)
-{
-	static int s = -1;
-	ipfw_table_entry ent;
-
-	if (s == -1)
-		s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-	if (s < 0)
-	{
-		err(1, "IPFW socket unavailable");
-		return(-1);
-	}
-
-	/* flush the table */   
-	ent.tbl = tabno;
-	if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_FLUSH,  &ent.tbl, sizeof(ent.tbl)) < 0)
-	{
-		err(1, "IPFW setsockopt(IP_FW_TABLE_FLUSH)");
-		return(-1);
-	}
-
-	while (*blacklists != NULL) {
-		struct cidr *b = *blacklists;
-
-		while (b->addr != 0) {
-			/* add b to tabno */
-			ent.tbl = tabno;
-			ent.masklen = b->bits;
-			ent.value = 0;
-			inet_aton(atop(b->addr), (struct in_addr *)&ent.addr);
-			if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_ADD,  &ent, sizeof(ent)) < 0)
-			{
-				err(1, "IPFW setsockopt(IP_FW_TABLE_ADD)");
-				return(-1);
-			}
-			b++;
-		}
-		blacklists++;
-	}
-
-	return(0);
-}
-#endif
-
-int
-getlist(char ** db_array, char *name, struct blacklist *blist,
-    struct blacklist *blistnew)
-{
-	char *buf, *method, *file, *message;
-	int blc, bls, fd, black = 0;
-	struct bl *bl = NULL;
-	gzFile gzf;
-
-	if (cgetent(&buf, db_array, name) != 0)
-		err(1, "Can't find \"%s\" in spamd config", name);
-	buf = fix_quoted_colons(buf);
-	if (cgetcap(buf, "black", ':') != NULL) {
-		/* use new list */
-		black = 1;
-		blc = blistnew->blc;
-		bls = blistnew->bls;
-		bl = blistnew->bl;
-	} else if (cgetcap(buf, "white", ':') != NULL) {
-		/* apply to most recent blacklist */
-		black = 0;
-		blc = blist->blc;
-		bls = blist->bls;
-		bl = blist->bl;
-	} else
-		errx(1, "Must have \"black\" or \"white\" in %s", name);
-
-	switch (cgetstr(buf, "msg", &message)) {
-	case -1:
-		if (black)
-			errx(1, "No msg for blacklist \"%s\"", name);
-		break;
-	case -2:
-		errx(1, "malloc failed");
-	}
-
-	switch (cgetstr(buf, "method", &method)) {
-	case -1:
-		method = NULL;
-		break;
-	case -2:
-		errx(1, "malloc failed");
-	}
-
-	switch (cgetstr(buf, "file", &file)) {
-	case -1:
-		errx(1, "No file given for %slist %s",
-		    black ? "black" : "white", name);
-	case -2:
-		errx(1, "malloc failed");
-	default:
-		fd = open_file(method, file);
-		if (fd == -1)
-			err(1, "Can't open %s by %s method",
-			    file, method ? method : "file");
-		free(method);
-		free(file);
-		gzf = gzdopen(fd, "r");
-		if (gzf == NULL)
-			errx(1, "gzdopen");
-	}
-	bl = add_blacklist(bl, &blc, &bls, gzf, !black);
-	gzclose(gzf);
-	if (bl == NULL) {
-		warn("Could not add %slist %s", black ? "black" : "white",
-		    name);
-		return(0);
-	}
-	if (black) {
-		blistnew->message = message;
-		blistnew->name = name;
-		blistnew->black = black;
-		blistnew->bl = bl;
-		blistnew->blc = blc;
-		blistnew->bls = bls;
-	} else {
-		/* whitelist applied to last active blacklist */
-		blist->bl = bl;
-		blist->blc = blc;
-		blist->bls = bls;
-	}
-	if (debug)
-		fprintf(stderr, "%slist %s %d entries\n",
-		    black ? "black" : "white", name, blc / 2);
-	return(black);
-}
-
-int
-main(int argc, char *argv[])
-{
-	size_t dbs, dbc, blc, bls, black, white;
-	char **db_array, *buf, *name;
-	struct blacklist *blists;
-	struct servent *ent;
-	int i, ch;
-
-#ifndef IPFW
-	while ((ch = getopt(argc, argv, "nd")) != -1) {
-#else
-	while ((ch = getopt(argc, argv, "ndt:")) != -1) {
-#endif
-		switch (ch) {
-		case 'n':
-			dryrun = 1;
-			break;
-		case 'd':
-			debug = 1;
-			break;
-#ifdef IPFW
-		case 't':
-			tabno = atoi(optarg);
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-
-	if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL)
-		errx(1, "cannot find service \"spamd-cfg\" in /etc/services");
-	ent->s_port = ntohs(ent->s_port);
-
-	dbs = argc + 2;
-	dbc = 0;
-	db_array = calloc(dbs, sizeof(char *));
-	if (db_array == NULL)
-		errx(1, "malloc failed");
-
-	db_array[dbc]= PATH_SPAMD_CONF;
-	dbc++;
-	for (i = 1; i < argc; i++)
-		db_array[dbc++] = argv[i];
-
-	blists = NULL;
-	blc = bls = 0;
-	if (cgetent(&buf, db_array, "all") != 0)
-		err(1, "Can't find \"all\" in spamd config");
-	name = strsep(&buf, ": \t"); /* skip "all" at start */
-	blc = 0;
-	while ((name = strsep(&buf, ": \t")) != NULL) {
-		if (*name) {
-			/* extract config in order specified in "all" tag */
-			if (blc == bls) {
-				struct blacklist *tmp;
-
-				bls += 1024;
-				tmp = realloc(blists,
-				    bls * sizeof(struct blacklist));
-				if (tmp == NULL)
-					errx(1, "malloc failed");
-				blists = tmp;
-			}
-			if (blc == 0)
-				black = white = 0;
-			else {
-				white = blc - 1;
-				black = blc;
-			}
-			memset(&blists[black], 0, sizeof(struct blacklist));
-			blc += getlist(db_array, name, &blists[white],
-			    &blists[black]);
-		}
-	}
-	for (i = 0; i < blc; i++) {
-		struct cidr **cidrs, **tmp;
-
-		if (blists[i].blc > 0) {
-			cidrs = collapse_blacklist(blists[i].bl,
-			   blists[i].blc);
-			if (cidrs == NULL)
-				errx(1, "malloc failed");
-			if (dryrun)
-				continue;
-
-			if (configure_spamd(ent->s_port, blists[i].name,
-			    blists[i].message, cidrs) == -1)
-				err(1, "Can't connect to spamd on port %d",
-				    ent->s_port);
-			if (configure_pf(cidrs) == -1)
-				err(1, "pfctl failed");
-			tmp = cidrs;
-			while (*tmp != NULL)
-				free(*tmp++);
-			free(cidrs);
-			free(blists[i].bl);
-		}
-	}
-	return (0);
-}
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c.bak /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c.bak
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c.bak	Fri Feb  2 10:40:32 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c.bak	Thu Jan  1 03:00:00 1970
@@ -1,924 +0,0 @@
-/*	$OpenBSD: spamd-setup.c,v 1.21 2005/03/02 16:45:30 dhartmei Exp $ */
-
-/*
- * Copyright (c) 2003 Bob Beck.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <err.h>
-#ifdef __OpenBSD__
-#include <netinet/ip_ipsp.h>
-#endif
-#include <netdb.h>
-#include <zlib.h>
-
-#ifdef IPFW
-#include <net/if.h>
-#include <netinet/ip_fw.h>
-#endif
-
-#define PATH_FTP		"/usr/bin/ftp"
-#define PATH_PFCTL		"%%LOCAL_PFCTL%%"
-#define PATH_SPAMD_CONF		"%%LOCAL_SPAMD_CONF%%"
-#define SPAMD_ARG_MAX		256 /* max # of args to an exec */
-
-struct cidr {
-	u_int32_t addr;
-	u_int8_t bits;
-};
-
-struct bl {
-	u_int32_t addr;
-	int8_t b;
-	int8_t w;
-};
-
-struct blacklist {
-	char *name;
-	char *message;
-	struct bl *bl;
-	size_t blc, bls;
-	u_int8_t black;
-	int count;
-};
-
-u_int32_t	imask(u_int8_t b);
-u_int8_t	maxblock(u_int32_t addr, u_int8_t bits);
-u_int8_t	maxdiff(u_int32_t a, u_int32_t b);
-struct cidr	*range2cidrlist(u_int32_t start, u_int32_t end);
-void		cidr2range(struct cidr cidr, u_int32_t *start, u_int32_t *end);
-char		*atop(u_int32_t addr);
-u_int32_t	ptoa(char *cp);
-int		parse_netblock(char *buf, struct bl *start, struct bl *end,
-		    int white);
-int		open_child(char *file, char **argv);
-int		fileget(char *url);
-int		open_file(char *method, char *file);
-char		*fix_quoted_colons(char *buf);
-void		do_message(FILE *sdc, char *msg);
-struct bl	*add_blacklist(struct bl *bl, int *blc, int *bls, gzFile gzf,
-		    int white);
-int		cmpbl(const void *a, const void *b);
-struct cidr	**collapse_blacklist(struct bl *bl, int blc);
-int		configure_spamd(u_short dport, char *name, char *message,
-		    struct cidr **blacklists);
-int		configure_pf(struct cidr **blacklists);
-int		getlist(char ** db_array, char *name, struct blacklist *blist,
-		    struct blacklist *blistnew);
-
-int		debug;
-int		dryrun;
-
-#ifdef IPFW
-int tabno=2;
-#endif
-
-
-u_int32_t
-imask(u_int8_t b)
-{
-	u_int32_t j = 0;
-	int i;
-
-	for (i = 31; i > 31 - b; --i)
-		j |= (1 << i);
-	return(j);
-}
-
-u_int8_t
-maxblock(u_int32_t addr, u_int8_t bits)
-{
-	while (bits > 0) {
-		u_int32_t m = imask(bits - 1);
-
-		if ((addr & m) != addr)
-			return (bits);
-		bits--;
-	}
-	return(bits);
-}
-
-u_int8_t
-maxdiff(u_int32_t a, u_int32_t b)
-{
-	u_int8_t bits = 0;
-
-	b++;
-	while (bits < 32) {
-		u_int32_t m = imask(bits);
-
-		if ((a & m) != (b & m))
-			return (bits);
-		bits++;
-	}
-	return(bits);
-}
-
-struct cidr *
-range2cidrlist(u_int32_t start, u_int32_t end)
-{
-	struct cidr *list = NULL;
-	size_t cs = 0, cu = 0;
-
-	while (end >= start) {
-		u_int8_t maxsize = maxblock(start, 32);
-		u_int8_t diff = maxdiff(start, end);
-
-		maxsize = MAX(maxsize, diff);
-		if (cs == cu) {
-			struct cidr *tmp;
-
-			tmp = realloc(list, (cs + 32) * sizeof(struct cidr));
-			if (tmp == NULL)
-				errx(1, "malloc failed");
-			list = tmp;
-			cs += 32;
-		}
-		list[cu].addr = start;
-		list[cu].bits = maxsize;
-		cu++;
-		list[cu].addr = 0;
-		list[cu].bits = 0;
-		start = start + (1 << (32 - maxsize));
-	}
-	return(list);
-}
-
-void
-cidr2range(struct cidr cidr, u_int32_t *start, u_int32_t *end)
-{
-	*start = cidr.addr;
-	*end = cidr.addr + (1 << (32 - cidr.bits)) - 1;
-}
-
-char *
-atop(u_int32_t addr)
-{
-	struct in_addr in;
-
-	memset(&in, 0, sizeof(in));
-	in.s_addr = htonl(addr);
-	return(inet_ntoa(in));
-}
-
-int
-parse_netblock(char *buf, struct bl *start, struct bl *end, int white)
-{
-	char astring[16], astring2[16];
-	unsigned maskbits;
-
-	/* skip leading spaces */
-	while (*buf == ' ')
-		buf++;
-	/* bail if it's a comment */
-	if (*buf == '#')
-		return(0);
-	/* otherwise, look for a netblock of some sort */
-	if (sscanf(buf, "%15[^/]/%u", astring, &maskbits) == 2) {
-		/* looks like a cidr */
-		struct cidr c;
-
-		memset(&c.addr, 0, sizeof(c.addr));
-		if (inet_net_pton(AF_INET, astring, &c.addr, sizeof(c.addr))
-		    == -1)
-			return(0);
-		c.addr = ntohl(c.addr);
-		if (maskbits > 32)
-			return(0);
-		c.bits = maskbits;
-		cidr2range(c, &start->addr, &end->addr);
-		end->addr += 1;
-	} else if (sscanf(buf, "%15[0123456789.]%*[ -]%15[0123456789.]",
-	    astring, astring2) == 2) {
-		/* looks like start - end */
-		memset(&start->addr, 0, sizeof(start->addr));
-		memset(&end->addr, 0, sizeof(end->addr));
-		if (inet_net_pton(AF_INET, astring, &start->addr,
-		    sizeof(start->addr)) == -1)
-			return(0);
-		start->addr = ntohl(start->addr);
-		if (inet_net_pton(AF_INET, astring2, &end->addr,
-		    sizeof(end->addr)) == -1)
-			return(0);
-		end->addr = ntohl(end->addr) + 1;
-		if (start > end)
-			return(0);
-	} else if (sscanf(buf, "%15[0123456789.]", astring) == 1) {
-		/* just a single address */
-		memset(&start->addr, 0, sizeof(start->addr));
-		if (inet_net_pton(AF_INET, astring, &start->addr,
-		    sizeof(start->addr)) == -1)
-			return(0);
-		start->addr = ntohl(start->addr);
-		end->addr = start->addr + 1;
-	} else
-		return(0);
-
-	if (white) {
-		start->b = 0;
-		start->w = 1;
-		end->b = 0;
-		end->w = -1;
-	} else {
-		start->b = 1;
-		start->w = 0;
-		end->b = -1;
-		end->w = 0;
-	}
-	return(1);
-}
-
-int
-open_child(char *file, char **argv)
-{
-	int pdes[2];
-
-	if (pipe(pdes) != 0)
-		return(-1);
-	switch (fork()) {
-	case -1:
-		close(pdes[0]);
-		close(pdes[1]);
-		return(-1);
-	case 0:
-		/* child */
-		close(pdes[0]);
-		if (pdes[1] != STDOUT_FILENO) {
-			dup2(pdes[1], STDOUT_FILENO);
-			close(pdes[1]);
-		}
-		execvp(file, argv);
-		_exit(1);
-	}
-
-	/* parent */
-	close(pdes[1]);
-	return(pdes[0]);
-}
-
-int
-fileget(char *url)
-{
-	char *argv[6];
-
-	argv[0] = "ftp";
-	argv[1] = "-V";
-	argv[2] = "-o";
-	argv[3] = "-";
-	argv[4] = url;
-	argv[5] = NULL;
-
-	if (debug)
-		fprintf(stderr, "Getting %s\n", url);
-
-	return open_child(PATH_FTP, argv);
-}
-
-int
-open_file(char *method, char *file)
-{
-	char *url;
-
-	if ((method == NULL) || (strcmp(method, "file") == 0))
-		return(open(file, O_RDONLY));
-	if ((strcmp(method, "http") == 0) ||
-	    strcmp(method, "ftp") == 0) {
-		int i;
-
-		asprintf(&url, "%s://%s", method, file);
-		if (url == NULL)
-			return(-1);
-		i = fileget(url);
-		free(url);
-		return(i);
-	} else if (strcmp(method, "exec") == 0) {
-		char **ap, **argv;
-		int len, i, oerrno;
-
-		len = strlen(file);
-		argv = malloc(len * sizeof(char *));
-		if (argv == NULL)
-			errx(1, "malloc failed");
-		for (ap = argv; ap < &argv[len - 1] &&
-		    (*ap = strsep(&file, " \t")) != NULL;) {
-			if (**ap != '\0')
-				ap++;
-		}
-		*ap = NULL;
-		i = open_child(argv[0], argv);
-		oerrno = errno;
-		free(argv);
-		errno = oerrno;
-		return(i);
-	}
-	errx(1, "Unknown method %s", method);
-	return(-1); /* NOTREACHED */
-}
-
-/*
- * fix_quoted_colons walks through a buffer returned by cgetent.  We
- * look for quoted strings, to escape colons (:) in quoted strings for
- * getcap by replacing them with \C so cgetstr() deals with it correctly
- * without having to see the \C bletchery in a configuration file that
- * needs to have urls in it. Frees the buffer passed to it, passes back
- * another larger one, with can be used with cgetxxx(), like the original
- * buffer, it must be freed by the caller.
- * This should really be a temporary fix until there is a sanctioned
- * way to make getcap(3) handle quoted strings like this in a nicer
- * way.
- */
-char *
-fix_quoted_colons(char *buf)
-{
-	int nbs = 0, i = 0, j = 0, in = 0;
-	char *newbuf, last;
-
-	nbs = strlen(buf) + 128;
-	newbuf = malloc(nbs);
-	if (newbuf == NULL)
-		return NULL;
-	last = '\0';
-	for (i = 0; i < strlen(buf); i++) {
-		switch (buf[i]) {
-		case ':':
-			if (in) {
-				newbuf[j++] = '\\';
-				newbuf[j++] = 'C';
-			} else
-				newbuf[j++] = buf[i];
-			break;
-		case '"':
-			if (last != '\\')
-				in = !in;
-			newbuf[j++] = buf[i];
-			break;
-		default:
-			newbuf[j++] = buf[i];
-		}
-		if (j == nbs) {
-			char *tmp;
-
-			nbs += 128;
-			tmp = realloc(newbuf, nbs);
-			if (tmp == NULL)
-				errx(1, "malloc failed");
-			newbuf = tmp;
-		}
-	}
-	free(buf);
-	newbuf[j] = '\0';
-	return(newbuf);
-}
-
-void
-do_message(FILE *sdc, char *msg)
-{
-	int i, n, bu = 0, bs = 0, len;
-	char *buf = NULL, last;
-
-	len = strlen(msg);
-	if (msg[0] == '"' && msg[len - 1] == '"') {
-		/* quoted msg, escape newlines and send it out */
-		msg[len - 1] = '\0';
-		buf = msg+1;
-		bu = len - 2;
-		goto sendit;
-	} else {
-		int fd;
-
-		/*
-		 * message isn't quoted - try to open a local
-		 * file and read the message from it.
-		 */
-		fd = open(msg, O_RDONLY);
-		if (fd == -1)
-			err(1, "Can't open message from %s", msg);
-		for (;;) {
-			if (bu == bs) {
-				char *tmp;
-
-				tmp = realloc(buf, bs + 8192);
-				if (tmp == NULL)
-					errx(1, "malloc failed");
-				bs += 8192;
-				buf = tmp;
-			}
-
-			n = read(fd, buf + bu, bs - bu);
-			if (n == 0) {
-				goto sendit;
-			} else if (n == -1) {
-				err(1, "Can't read from %s", msg);
-			} else
-				bu += n;
-		}
-		buf[bu]='\0';
-	}
- sendit:
-	fprintf(sdc, ";\"");
-	last = '\0';
-	for (i = 0; i < bu; i++) {
-		/* handle escaping the things spamd wants */
-		switch (buf[i]) {
-		case 'n':
-			if (last == '\\')
-				fprintf(sdc, "\\\\n");
-			else
-				fputc('n', sdc);
-			last = '\0';
-			break;
-		case '\n':
-			fprintf(sdc, "\\n");
-			last = '\0';
-			break;
-		case '"':
-			fputc('\\', sdc);
-			/* fall through */
-		default:
-			fputc(buf[i], sdc);
-			last = '\0';
-		}
-	}
-	fputc('"', sdc);
-	if (bs != 0)
-		free(buf);
-}
-
-/* retrieve a list from fd. add to blacklist bl */
-struct bl *
-add_blacklist(struct bl *bl, int *blc, int *bls, gzFile gzf, int white)
-{
-	int i, n, start, bu = 0, bs = 0, serrno = 0;
-	char *buf = NULL;
-
-	for (;;) {
-		/* read in gzf, then parse */
-		if (bu == bs) {
-			char *tmp;
-
-			tmp = realloc(buf, bs + 8192 + 1);
-			if (tmp == NULL) {
-				free(buf);
-				buf = NULL;
-				bs = 0;
-				serrno = errno;
-				goto bldone;
-			}
-			bs += 8192;
-			buf = tmp;
-		}
-
-		n = gzread(gzf, buf + bu, bs - bu);
-		if (n == 0)
-			goto parse;
-		else if (n == -1) {
-			serrno = errno;
-			goto bldone;
-		} else
-			bu += n;
-	}
- parse:
-	start = 0;
-	for (i = 0; i <= bu; i++) {
-		if (*blc == *bls) {
-			struct bl *tmp;
-
-			*bls += 1024;
-			tmp = realloc(bl, *bls * sizeof(struct bl));
-			if (tmp == NULL) {
-				*bls -= 1024;
-				serrno = errno;
-				goto bldone;
-			}
-			bl = tmp;
-		}
-		if (i == bu || buf[i] == '\n') {
-			buf[i] = '\0';
-			if (parse_netblock(buf + start,
-			    bl + *blc, bl + *blc + 1, white))
-				*blc+=2;
-			start = i+1;
-		}
-	}
-	if (bu == 0)
-		errno = EIO;
- bldone:
-	if (buf)
-		free(buf);
-	if (serrno)
-		errno = serrno;
-	return (bl);
-}
-
-int
-cmpbl(const void *a, const void *b)
-{
-	if (((struct bl *)a)->addr > ((struct bl *) b)->addr)
-		return(1);
-	if (((struct bl *)a)->addr < ((struct bl *) b)->addr)
-		return(-1);
-	return(0);
-}
-
-/*
- * collapse_blacklist takes blacklist/whitelist entries sorts, removes
- * overlaps and whitelist portions, and returns netblocks to blacklist
- * as lists of nonoverlapping cidr blocks suitable for feeding in
- * printable form to pfctl or spamd.
- */
-struct cidr **
-collapse_blacklist(struct bl *bl, int blc)
-{
-	int bs = 0, ws = 0, state=0, cli, i;
-	u_int32_t bstart = 0;
-	struct cidr **cl;
-
-	if (blc == 0)
-		return(NULL);
-	cl = malloc((blc / 2) * sizeof(struct cidr));
-	if (cl == NULL) {
-		return (NULL);
-	}
-	qsort(bl, blc, sizeof(struct bl), cmpbl);
-	cli = 0;
-	cl[cli] = NULL;
-	for (i = 0; i < blc;) {
-		int laststate = state;
-		u_int32_t addr = bl[i].addr;
-
-		do {
-			bs += bl[i].b;
-			ws += bl[i].w;
-			i++;
-		} while (bl[i].addr == addr);
-		if (state == 1 && bs == 0)
-			state = 0;
-		else if (state == 0 && bs > 0)
-			state = 1;
-		if (ws > 0)
-			state = 0;
-		if (laststate == 0 && state == 1) {
-			/* start blacklist */
-			bstart = addr;
-		}
-		if (laststate == 1 && state == 0) {
-			/* end blacklist */
-			cl[cli++] = range2cidrlist(bstart, addr - 1);
-			cl[cli] = NULL;
-		}
-		laststate = state;
-	}
-	return (cl);
-}
-
-int
-configure_spamd(u_short dport, char *name, char *message,
-    struct cidr **blacklists)
-{
-	int lport = IPPORT_RESERVED - 1, s;
-	struct sockaddr_in sin;
-	FILE* sdc;
-
-	s = rresvport(&lport);
-	if (s == -1)
-		return(-1);
-	memset(&sin, 0, sizeof sin);
-	sin.sin_len = sizeof(sin);
-	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-	sin.sin_family = AF_INET;
-	sin.sin_port = htons(dport);
-	if (connect(s, (struct sockaddr *)&sin, sizeof sin) == -1)
-		return(-1);
-	sdc = fdopen(s, "w");
-	if (sdc == NULL) {
-		close(s);
-		return(-1);
-	}
-	fprintf(sdc, "%s", name);
-	do_message(sdc, message);
-	while (*blacklists != NULL) {
-		struct cidr *b = *blacklists;
-		while (b->addr != 0) {
-			fprintf(sdc, ";%s/%u", atop(b->addr), (b->bits));
-			b++;
-		}
-		blacklists++;
-	}
-	fputc('\n', sdc);
-	fclose(sdc);
-	close(s);
-	return(0);
-}
-
-
-#ifndef IPFW
-int
-configure_pf(struct cidr **blacklists)
-{
-	char *argv[9]= {"pfctl", "-q", "-t", "spamd", "-T", "replace",
-	    "-f" "-", NULL};
-	static FILE *pf = NULL;
-	int pdes[2];
-
-	if (pf == NULL) {
-		if (pipe(pdes) != 0)
-			return(-1);
-		switch (fork()) {
-		case -1:
-			close(pdes[0]);
-			close(pdes[1]);
-			return(-1);
-		case 0:
-			/* child */
-			close(pdes[1]);
-			if (pdes[0] != STDIN_FILENO) {
-				dup2(pdes[0], STDIN_FILENO);
-				close(pdes[0]);
-			}
-			execvp(PATH_PFCTL, argv);
-			_exit(1);
-		}
-
-		/* parent */
-		close(pdes[0]);
-		pf = fdopen(pdes[1], "w");
-		if (pf == NULL) {
-			close(pdes[1]);
-			return(-1);
-		}
-	}
-	while (*blacklists != NULL) {
-		struct cidr *b = *blacklists;
-
-		while (b->addr != 0) {
-			fprintf(pf, "%s/%u\n", atop(b->addr), (b->bits));
-			b++;
-		}
-		blacklists++;
-	}
-	return(0);
-}
-#else
-int
-configure_pf(struct cidr **blacklists)
-{
-	static int s = -1;
-	ipfw_table_entry ent;
-
-	if (s == -1)
-		s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-	if (s < 0)
-	{
-		err(1, "IPFW socket unavailable");
-		return(-1);
-	}
-
-	/* flush the table */   
-	ent.tbl = tabno;
-	if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_FLUSH,  &ent.tbl, sizeof(ent.tbl)) < 0)
-	{
-		err(1, "IPFW setsockopt(IP_FW_TABLE_FLUSH)");
-		return(-1);
-	}
-
-	while (*blacklists != NULL) {
-		struct cidr *b = *blacklists;
-
-		while (b->addr != 0) {
-			/* add b to tabno */
-			ent.tbl = tabno;
-			ent.masklen = b->bits;
-			ent.value = 0;
-			inet_aton(atop(b->addr), (struct in_addr *)&ent.addr);
-			if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_ADD,  &ent, sizeof(ent)) < 0)
-			{
-				err(1, "IPFW setsockopt(IP_FW_TABLE_ADD)");
-				return(-1);
-			}
-			b++;
-		}
-		blacklists++;
-	}
-
-	return(0);
-}
-#endif
-
-int
-getlist(char ** db_array, char *name, struct blacklist *blist,
-    struct blacklist *blistnew)
-{
-	char *buf, *method, *file, *message;
-	int blc, bls, fd, black = 0;
-	struct bl *bl = NULL;
-	gzFile gzf;
-
-	if (cgetent(&buf, db_array, name) != 0)
-		err(1, "Can't find \"%s\" in spamd config", name);
-	buf = fix_quoted_colons(buf);
-	if (cgetcap(buf, "black", ':') != NULL) {
-		/* use new list */
-		black = 1;
-		blc = blistnew->blc;
-		bls = blistnew->bls;
-		bl = blistnew->bl;
-	} else if (cgetcap(buf, "white", ':') != NULL) {
-		/* apply to most recent blacklist */
-		black = 0;
-		blc = blist->blc;
-		bls = blist->bls;
-		bl = blist->bl;
-	} else
-		errx(1, "Must have \"black\" or \"white\" in %s", name);
-
-	switch (cgetstr(buf, "msg", &message)) {
-	case -1:
-		if (black)
-			errx(1, "No msg for blacklist \"%s\"", name);
-		break;
-	case -2:
-		errx(1, "malloc failed");
-	}
-
-	switch (cgetstr(buf, "method", &method)) {
-	case -1:
-		method = NULL;
-		break;
-	case -2:
-		errx(1, "malloc failed");
-	}
-
-	switch (cgetstr(buf, "file", &file)) {
-	case -1:
-		errx(1, "No file given for %slist %s",
-		    black ? "black" : "white", name);
-	case -2:
-		errx(1, "malloc failed");
-	default:
-		fd = open_file(method, file);
-		if (fd == -1)
-			err(1, "Can't open %s by %s method",
-			    file, method ? method : "file");
-		free(method);
-		free(file);
-		gzf = gzdopen(fd, "r");
-		if (gzf == NULL)
-			errx(1, "gzdopen");
-	}
-	bl = add_blacklist(bl, &blc, &bls, gzf, !black);
-	gzclose(gzf);
-	if (bl == NULL) {
-		warn("Could not add %slist %s", black ? "black" : "white",
-		    name);
-		return(0);
-	}
-	if (black) {
-		blistnew->message = message;
-		blistnew->name = name;
-		blistnew->black = black;
-		blistnew->bl = bl;
-		blistnew->blc = blc;
-		blistnew->bls = bls;
-	} else {
-		/* whitelist applied to last active blacklist */
-		blist->bl = bl;
-		blist->blc = blc;
-		blist->bls = bls;
-	}
-	if (debug)
-		fprintf(stderr, "%slist %s %d entries\n",
-		    black ? "black" : "white", name, blc / 2);
-	return(black);
-}
-
-int
-main(int argc, char *argv[])
-{
-	size_t dbs, dbc, blc, bls, black, white;
-	char **db_array, *buf, *name;
-	struct blacklist *blists;
-	struct servent *ent;
-	int i, ch;
-
-#ifndef IPFW
-	while ((ch = getopt(argc, argv, "nd")) != -1) {
-#else
-	while ((ch = getopt(argc, argv, "ndt:")) != -1) {
-#endif
-		switch (ch) {
-		case 'n':
-			dryrun = 1;
-			break;
-		case 'd':
-			debug = 1;
-			break;
-#ifdef IPFW
-		case 't':
-			tabno = atoi(optarg);
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-
-	if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL)
-		errx(1, "cannot find service \"spamd-cfg\" in /etc/services");
-	ent->s_port = ntohs(ent->s_port);
-
-	dbs = argc + 2;
-	dbc = 0;
-	db_array = calloc(dbs, sizeof(char *));
-	if (db_array == NULL)
-		errx(1, "malloc failed");
-
-	db_array[dbc]= PATH_SPAMD_CONF;
-	dbc++;
-	for (i = 1; i < argc; i++)
-		db_array[dbc++] = argv[i];
-
-	blists = NULL;
-	blc = bls = 0;
-	if (cgetent(&buf, db_array, "all") != 0)
-		err(1, "Can't find \"all\" in spamd config");
-	name = strsep(&buf, ": \t"); /* skip "all" at start */
-	blc = 0;
-	while ((name = strsep(&buf, ": \t")) != NULL) {
-		if (*name) {
-			/* extract config in order specified in "all" tag */
-			if (blc == bls) {
-				struct blacklist *tmp;
-
-				bls += 1024;
-				tmp = realloc(blists,
-				    bls * sizeof(struct blacklist));
-				if (tmp == NULL)
-					errx(1, "malloc failed");
-				blists = tmp;
-			}
-			if (blc == 0)
-				black = white = 0;
-			else {
-				white = blc - 1;
-				black = blc;
-			}
-			memset(&blists[black], 0, sizeof(struct blacklist));
-			blc += getlist(db_array, name, &blists[white],
-			    &blists[black]);
-		}
-	}
-	for (i = 0; i < blc; i++) {
-		struct cidr **cidrs, **tmp;
-
-		if (blists[i].blc > 0) {
-			cidrs = collapse_blacklist(blists[i].bl,
-			   blists[i].blc);
-			if (cidrs == NULL)
-				errx(1, "malloc failed");
-			if (dryrun)
-				continue;
-
-			if (configure_spamd(ent->s_port, blists[i].name,
-			    blists[i].message, cidrs) == -1)
-				err(1, "Can't connect to spamd on port %d",
-				    ent->s_port);
-			if (configure_pf(cidrs) == -1)
-				err(1, "pfctl failed");
-			tmp = cidrs;
-			while (*tmp != NULL)
-				free(*tmp++);
-			free(cidrs);
-			free(blists[i].bl);
-		}
-	}
-	return (0);
-}
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c.orig /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c.orig
--- /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c.orig	Tue Apr 12 20:18:59 2005
+++ /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.c.orig	Thu Jan  1 03:00:00 1970
@@ -1,859 +0,0 @@
-/*	$OpenBSD: spamd-setup.c,v 1.21 2005/03/02 16:45:30 dhartmei Exp $ */
-
-/*
- * Copyright (c) 2003 Bob Beck.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <err.h>
-#ifdef __OpenBSD__
-#include <netinet/ip_ipsp.h>
-#endif
-#include <netdb.h>
-#include <zlib.h>
-
-#define PATH_FTP		"/usr/bin/ftp"
-#define PATH_PFCTL		"%%LOCAL_PFCTL%%"
-#define PATH_SPAMD_CONF		"%%LOCAL_SPAMD_CONF%%"
-#define SPAMD_ARG_MAX		256 /* max # of args to an exec */
-
-struct cidr {
-	u_int32_t addr;
-	u_int8_t bits;
-};
-
-struct bl {
-	u_int32_t addr;
-	int8_t b;
-	int8_t w;
-};
-
-struct blacklist {
-	char *name;
-	char *message;
-	struct bl *bl;
-	size_t blc, bls;
-	u_int8_t black;
-	int count;
-};
-
-u_int32_t	imask(u_int8_t b);
-u_int8_t	maxblock(u_int32_t addr, u_int8_t bits);
-u_int8_t	maxdiff(u_int32_t a, u_int32_t b);
-struct cidr	*range2cidrlist(u_int32_t start, u_int32_t end);
-void		cidr2range(struct cidr cidr, u_int32_t *start, u_int32_t *end);
-char		*atop(u_int32_t addr);
-u_int32_t	ptoa(char *cp);
-int		parse_netblock(char *buf, struct bl *start, struct bl *end,
-		    int white);
-int		open_child(char *file, char **argv);
-int		fileget(char *url);
-int		open_file(char *method, char *file);
-char		*fix_quoted_colons(char *buf);
-void		do_message(FILE *sdc, char *msg);
-struct bl	*add_blacklist(struct bl *bl, int *blc, int *bls, gzFile gzf,
-		    int white);
-int		cmpbl(const void *a, const void *b);
-struct cidr	**collapse_blacklist(struct bl *bl, int blc);
-int		configure_spamd(u_short dport, char *name, char *message,
-		    struct cidr **blacklists);
-int		configure_pf(struct cidr **blacklists);
-int		getlist(char ** db_array, char *name, struct blacklist *blist,
-		    struct blacklist *blistnew);
-
-int		debug;
-int		dryrun;
-
-u_int32_t
-imask(u_int8_t b)
-{
-	u_int32_t j = 0;
-	int i;
-
-	for (i = 31; i > 31 - b; --i)
-		j |= (1 << i);
-	return(j);
-}
-
-u_int8_t
-maxblock(u_int32_t addr, u_int8_t bits)
-{
-	while (bits > 0) {
-		u_int32_t m = imask(bits - 1);
-
-		if ((addr & m) != addr)
-			return (bits);
-		bits--;
-	}
-	return(bits);
-}
-
-u_int8_t
-maxdiff(u_int32_t a, u_int32_t b)
-{
-	u_int8_t bits = 0;
-
-	b++;
-	while (bits < 32) {
-		u_int32_t m = imask(bits);
-
-		if ((a & m) != (b & m))
-			return (bits);
-		bits++;
-	}
-	return(bits);
-}
-
-struct cidr *
-range2cidrlist(u_int32_t start, u_int32_t end)
-{
-	struct cidr *list = NULL;
-	size_t cs = 0, cu = 0;
-
-	while (end >= start) {
-		u_int8_t maxsize = maxblock(start, 32);
-		u_int8_t diff = maxdiff(start, end);
-
-		maxsize = MAX(maxsize, diff);
-		if (cs == cu) {
-			struct cidr *tmp;
-
-			tmp = realloc(list, (cs + 32) * sizeof(struct cidr));
-			if (tmp == NULL)
-				errx(1, "malloc failed");
-			list = tmp;
-			cs += 32;
-		}
-		list[cu].addr = start;
-		list[cu].bits = maxsize;
-		cu++;
-		list[cu].addr = 0;
-		list[cu].bits = 0;
-		start = start + (1 << (32 - maxsize));
-	}
-	return(list);
-}
-
-void
-cidr2range(struct cidr cidr, u_int32_t *start, u_int32_t *end)
-{
-	*start = cidr.addr;
-	*end = cidr.addr + (1 << (32 - cidr.bits)) - 1;
-}
-
-char *
-atop(u_int32_t addr)
-{
-	struct in_addr in;
-
-	memset(&in, 0, sizeof(in));
-	in.s_addr = htonl(addr);
-	return(inet_ntoa(in));
-}
-
-int
-parse_netblock(char *buf, struct bl *start, struct bl *end, int white)
-{
-	char astring[16], astring2[16];
-	unsigned maskbits;
-
-	/* skip leading spaces */
-	while (*buf == ' ')
-		buf++;
-	/* bail if it's a comment */
-	if (*buf == '#')
-		return(0);
-	/* otherwise, look for a netblock of some sort */
-	if (sscanf(buf, "%15[^/]/%u", astring, &maskbits) == 2) {
-		/* looks like a cidr */
-		struct cidr c;
-
-		memset(&c.addr, 0, sizeof(c.addr));
-		if (inet_net_pton(AF_INET, astring, &c.addr, sizeof(c.addr))
-		    == -1)
-			return(0);
-		c.addr = ntohl(c.addr);
-		if (maskbits > 32)
-			return(0);
-		c.bits = maskbits;
-		cidr2range(c, &start->addr, &end->addr);
-		end->addr += 1;
-	} else if (sscanf(buf, "%15[0123456789.]%*[ -]%15[0123456789.]",
-	    astring, astring2) == 2) {
-		/* looks like start - end */
-		memset(&start->addr, 0, sizeof(start->addr));
-		memset(&end->addr, 0, sizeof(end->addr));
-		if (inet_net_pton(AF_INET, astring, &start->addr,
-		    sizeof(start->addr)) == -1)
-			return(0);
-		start->addr = ntohl(start->addr);
-		if (inet_net_pton(AF_INET, astring2, &end->addr,
-		    sizeof(end->addr)) == -1)
-			return(0);
-		end->addr = ntohl(end->addr) + 1;
-		if (start > end)
-			return(0);
-	} else if (sscanf(buf, "%15[0123456789.]", astring) == 1) {
-		/* just a single address */
-		memset(&start->addr, 0, sizeof(start->addr));
-		if (inet_net_pton(AF_INET, astring, &start->addr,
-		    sizeof(start->addr)) == -1)
-			return(0);
-		start->addr = ntohl(start->addr);
-		end->addr = start->addr + 1;
-	} else
-		return(0);
-
-	if (white) {
-		start->b = 0;
-		start->w = 1;
-		end->b = 0;
-		end->w = -1;
-	} else {
-		start->b = 1;
-		start->w = 0;
-		end->b = -1;
-		end->w = 0;
-	}
-	return(1);
-}
-
-int
-open_child(char *file, char **argv)
-{
-	int pdes[2];
-
-	if (pipe(pdes) != 0)
-		return(-1);
-	switch (fork()) {
-	case -1:
-		close(pdes[0]);
-		close(pdes[1]);
-		return(-1);
-	case 0:
-		/* child */
-		close(pdes[0]);
-		if (pdes[1] != STDOUT_FILENO) {
-			dup2(pdes[1], STDOUT_FILENO);
-			close(pdes[1]);
-		}
-		execvp(file, argv);
-		_exit(1);
-	}
-
-	/* parent */
-	close(pdes[1]);
-	return(pdes[0]);
-}
-
-int
-fileget(char *url)
-{
-	char *argv[6];
-
-	argv[0] = "ftp";
-	argv[1] = "-V";
-	argv[2] = "-o";
-	argv[3] = "-";
-	argv[4] = url;
-	argv[5] = NULL;
-
-	if (debug)
-		fprintf(stderr, "Getting %s\n", url);
-
-	return open_child(PATH_FTP, argv);
-}
-
-int
-open_file(char *method, char *file)
-{
-	char *url;
-
-	if ((method == NULL) || (strcmp(method, "file") == 0))
-		return(open(file, O_RDONLY));
-	if ((strcmp(method, "http") == 0) ||
-	    strcmp(method, "ftp") == 0) {
-		int i;
-
-		asprintf(&url, "%s://%s", method, file);
-		if (url == NULL)
-			return(-1);
-		i = fileget(url);
-		free(url);
-		return(i);
-	} else if (strcmp(method, "exec") == 0) {
-		char **ap, **argv;
-		int len, i, oerrno;
-
-		len = strlen(file);
-		argv = malloc(len * sizeof(char *));
-		if (argv == NULL)
-			errx(1, "malloc failed");
-		for (ap = argv; ap < &argv[len - 1] &&
-		    (*ap = strsep(&file, " \t")) != NULL;) {
-			if (**ap != '\0')
-				ap++;
-		}
-		*ap = NULL;
-		i = open_child(argv[0], argv);
-		oerrno = errno;
-		free(argv);
-		errno = oerrno;
-		return(i);
-	}
-	errx(1, "Unknown method %s", method);
-	return(-1); /* NOTREACHED */
-}
-
-/*
- * fix_quoted_colons walks through a buffer returned by cgetent.  We
- * look for quoted strings, to escape colons (:) in quoted strings for
- * getcap by replacing them with \C so cgetstr() deals with it correctly
- * without having to see the \C bletchery in a configuration file that
- * needs to have urls in it. Frees the buffer passed to it, passes back
- * another larger one, with can be used with cgetxxx(), like the original
- * buffer, it must be freed by the caller.
- * This should really be a temporary fix until there is a sanctioned
- * way to make getcap(3) handle quoted strings like this in a nicer
- * way.
- */
-char *
-fix_quoted_colons(char *buf)
-{
-	int nbs = 0, i = 0, j = 0, in = 0;
-	char *newbuf, last;
-
-	nbs = strlen(buf) + 128;
-	newbuf = malloc(nbs);
-	if (newbuf == NULL)
-		return NULL;
-	last = '\0';
-	for (i = 0; i < strlen(buf); i++) {
-		switch (buf[i]) {
-		case ':':
-			if (in) {
-				newbuf[j++] = '\\';
-				newbuf[j++] = 'C';
-			} else
-				newbuf[j++] = buf[i];
-			break;
-		case '"':
-			if (last != '\\')
-				in = !in;
-			newbuf[j++] = buf[i];
-			break;
-		default:
-			newbuf[j++] = buf[i];
-		}
-		if (j == nbs) {
-			char *tmp;
-
-			nbs += 128;
-			tmp = realloc(newbuf, nbs);
-			if (tmp == NULL)
-				errx(1, "malloc failed");
-			newbuf = tmp;
-		}
-	}
-	free(buf);
-	newbuf[j] = '\0';
-	return(newbuf);
-}
-
-void
-do_message(FILE *sdc, char *msg)
-{
-	int i, n, bu = 0, bs = 0, len;
-	char *buf = NULL, last;
-
-	len = strlen(msg);
-	if (msg[0] == '"' && msg[len - 1] == '"') {
-		/* quoted msg, escape newlines and send it out */
-		msg[len - 1] = '\0';
-		buf = msg+1;
-		bu = len - 2;
-		goto sendit;
-	} else {
-		int fd;
-
-		/*
-		 * message isn't quoted - try to open a local
-		 * file and read the message from it.
-		 */
-		fd = open(msg, O_RDONLY);
-		if (fd == -1)
-			err(1, "Can't open message from %s", msg);
-		for (;;) {
-			if (bu == bs) {
-				char *tmp;
-
-				tmp = realloc(buf, bs + 8192);
-				if (tmp == NULL)
-					errx(1, "malloc failed");
-				bs += 8192;
-				buf = tmp;
-			}
-
-			n = read(fd, buf + bu, bs - bu);
-			if (n == 0) {
-				goto sendit;
-			} else if (n == -1) {
-				err(1, "Can't read from %s", msg);
-			} else
-				bu += n;
-		}
-		buf[bu]='\0';
-	}
- sendit:
-	fprintf(sdc, ";\"");
-	last = '\0';
-	for (i = 0; i < bu; i++) {
-		/* handle escaping the things spamd wants */
-		switch (buf[i]) {
-		case 'n':
-			if (last == '\\')
-				fprintf(sdc, "\\\\n");
-			else
-				fputc('n', sdc);
-			last = '\0';
-			break;
-		case '\n':
-			fprintf(sdc, "\\n");
-			last = '\0';
-			break;
-		case '"':
-			fputc('\\', sdc);
-			/* fall through */
-		default:
-			fputc(buf[i], sdc);
-			last = '\0';
-		}
-	}
-	fputc('"', sdc);
-	if (bs != 0)
-		free(buf);
-}
-
-/* retrieve a list from fd. add to blacklist bl */
-struct bl *
-add_blacklist(struct bl *bl, int *blc, int *bls, gzFile gzf, int white)
-{
-	int i, n, start, bu = 0, bs = 0, serrno = 0;
-	char *buf = NULL;
-
-	for (;;) {
-		/* read in gzf, then parse */
-		if (bu == bs) {
-			char *tmp;
-
-			tmp = realloc(buf, bs + 8192 + 1);
-			if (tmp == NULL) {
-				free(buf);
-				buf = NULL;
-				bs = 0;
-				serrno = errno;
-				goto bldone;
-			}
-			bs += 8192;
-			buf = tmp;
-		}
-
-		n = gzread(gzf, buf + bu, bs - bu);
-		if (n == 0)
-			goto parse;
-		else if (n == -1) {
-			serrno = errno;
-			goto bldone;
-		} else
-			bu += n;
-	}
- parse:
-	start = 0;
-	for (i = 0; i <= bu; i++) {
-		if (*blc == *bls) {
-			struct bl *tmp;
-
-			*bls += 1024;
-			tmp = realloc(bl, *bls * sizeof(struct bl));
-			if (tmp == NULL) {
-				*bls -= 1024;
-				serrno = errno;
-				goto bldone;
-			}
-			bl = tmp;
-		}
-		if (i == bu || buf[i] == '\n') {
-			buf[i] = '\0';
-			if (parse_netblock(buf + start,
-			    bl + *blc, bl + *blc + 1, white))
-				*blc+=2;
-			start = i+1;
-		}
-	}
-	if (bu == 0)
-		errno = EIO;
- bldone:
-	if (buf)
-		free(buf);
-	if (serrno)
-		errno = serrno;
-	return (bl);
-}
-
-int
-cmpbl(const void *a, const void *b)
-{
-	if (((struct bl *)a)->addr > ((struct bl *) b)->addr)
-		return(1);
-	if (((struct bl *)a)->addr < ((struct bl *) b)->addr)
-		return(-1);
-	return(0);
-}
-
-/*
- * collapse_blacklist takes blacklist/whitelist entries sorts, removes
- * overlaps and whitelist portions, and returns netblocks to blacklist
- * as lists of nonoverlapping cidr blocks suitable for feeding in
- * printable form to pfctl or spamd.
- */
-struct cidr **
-collapse_blacklist(struct bl *bl, int blc)
-{
-	int bs = 0, ws = 0, state=0, cli, i;
-	u_int32_t bstart = 0;
-	struct cidr **cl;
-
-	if (blc == 0)
-		return(NULL);
-	cl = malloc((blc / 2) * sizeof(struct cidr));
-	if (cl == NULL) {
-		return (NULL);
-	}
-	qsort(bl, blc, sizeof(struct bl), cmpbl);
-	cli = 0;
-	cl[cli] = NULL;
-	for (i = 0; i < blc;) {
-		int laststate = state;
-		u_int32_t addr = bl[i].addr;
-
-		do {
-			bs += bl[i].b;
-			ws += bl[i].w;
-			i++;
-		} while (bl[i].addr == addr);
-		if (state == 1 && bs == 0)
-			state = 0;
-		else if (state == 0 && bs > 0)
-			state = 1;
-		if (ws > 0)
-			state = 0;
-		if (laststate == 0 && state == 1) {
-			/* start blacklist */
-			bstart = addr;
-		}
-		if (laststate == 1 && state == 0) {
-			/* end blacklist */
-			cl[cli++] = range2cidrlist(bstart, addr - 1);
-			cl[cli] = NULL;
-		}
-		laststate = state;
-	}
-	return (cl);
-}
-
-int
-configure_spamd(u_short dport, char *name, char *message,
-    struct cidr **blacklists)
-{
-	int lport = IPPORT_RESERVED - 1, s;
-	struct sockaddr_in sin;
-	FILE* sdc;
-
-	s = rresvport(&lport);
-	if (s == -1)
-		return(-1);
-	memset(&sin, 0, sizeof sin);
-	sin.sin_len = sizeof(sin);
-	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-	sin.sin_family = AF_INET;
-	sin.sin_port = htons(dport);
-	if (connect(s, (struct sockaddr *)&sin, sizeof sin) == -1)
-		return(-1);
-	sdc = fdopen(s, "w");
-	if (sdc == NULL) {
-		close(s);
-		return(-1);
-	}
-	fprintf(sdc, "%s", name);
-	do_message(sdc, message);
-	while (*blacklists != NULL) {
-		struct cidr *b = *blacklists;
-		while (b->addr != 0) {
-			fprintf(sdc, ";%s/%u", atop(b->addr), (b->bits));
-			b++;
-		}
-		blacklists++;
-	}
-	fputc('\n', sdc);
-	fclose(sdc);
-	close(s);
-	return(0);
-}
-
-
-int
-configure_pf(struct cidr **blacklists)
-{
-	char *argv[9]= {"pfctl", "-q", "-t", "spamd", "-T", "replace",
-	    "-f" "-", NULL};
-	static FILE *pf = NULL;
-	int pdes[2];
-
-	if (pf == NULL) {
-		if (pipe(pdes) != 0)
-			return(-1);
-		switch (fork()) {
-		case -1:
-			close(pdes[0]);
-			close(pdes[1]);
-			return(-1);
-		case 0:
-			/* child */
-			close(pdes[1]);
-			if (pdes[0] != STDIN_FILENO) {
-				dup2(pdes[0], STDIN_FILENO);
-				close(pdes[0]);
-			}
-			execvp(PATH_PFCTL, argv);
-			_exit(1);
-		}
-
-		/* parent */
-		close(pdes[0]);
-		pf = fdopen(pdes[1], "w");
-		if (pf == NULL) {
-			close(pdes[1]);
-			return(-1);
-		}
-	}
-	while (*blacklists != NULL) {
-		struct cidr *b = *blacklists;
-
-		while (b->addr != 0) {
-			fprintf(pf, "%s/%u\n", atop(b->addr), (b->bits));
-			b++;
-		}
-		blacklists++;
-	}
-	return(0);
-}
-
-int
-getlist(char ** db_array, char *name, struct blacklist *blist,
-    struct blacklist *blistnew)
-{
-	char *buf, *method, *file, *message;
-	int blc, bls, fd, black = 0;
-	struct bl *bl = NULL;
-	gzFile gzf;
-
-	if (cgetent(&buf, db_array, name) != 0)
-		err(1, "Can't find \"%s\" in spamd config", name);
-	buf = fix_quoted_colons(buf);
-	if (cgetcap(buf, "black", ':') != NULL) {
-		/* use new list */
-		black = 1;
-		blc = blistnew->blc;
-		bls = blistnew->bls;
-		bl = blistnew->bl;
-	} else if (cgetcap(buf, "white", ':') != NULL) {
-		/* apply to most recent blacklist */
-		black = 0;
-		blc = blist->blc;
-		bls = blist->bls;
-		bl = blist->bl;
-	} else
-		errx(1, "Must have \"black\" or \"white\" in %s", name);
-
-	switch (cgetstr(buf, "msg", &message)) {
-	case -1:
-		if (black)
-			errx(1, "No msg for blacklist \"%s\"", name);
-		break;
-	case -2:
-		errx(1, "malloc failed");
-	}
-
-	switch (cgetstr(buf, "method", &method)) {
-	case -1:
-		method = NULL;
-		break;
-	case -2:
-		errx(1, "malloc failed");
-	}
-
-	switch (cgetstr(buf, "file", &file)) {
-	case -1:
-		errx(1, "No file given for %slist %s",
-		    black ? "black" : "white", name);
-	case -2:
-		errx(1, "malloc failed");
-	default:
-		fd = open_file(method, file);
-		if (fd == -1)
-			err(1, "Can't open %s by %s method",
-			    file, method ? method : "file");
-		free(method);
-		free(file);
-		gzf = gzdopen(fd, "r");
-		if (gzf == NULL)
-			errx(1, "gzdopen");
-	}
-	bl = add_blacklist(bl, &blc, &bls, gzf, !black);
-	gzclose(gzf);
-	if (bl == NULL) {
-		warn("Could not add %slist %s", black ? "black" : "white",
-		    name);
-		return(0);
-	}
-	if (black) {
-		blistnew->message = message;
-		blistnew->name = name;
-		blistnew->black = black;
-		blistnew->bl = bl;
-		blistnew->blc = blc;
-		blistnew->bls = bls;
-	} else {
-		/* whitelist applied to last active blacklist */
-		blist->bl = bl;
-		blist->blc = blc;
-		blist->bls = bls;
-	}
-	if (debug)
-		fprintf(stderr, "%slist %s %d entries\n",
-		    black ? "black" : "white", name, blc / 2);
-	return(black);
-}
-
-int
-main(int argc, char *argv[])
-{
-	size_t dbs, dbc, blc, bls, black, white;
-	char **db_array, *buf, *name;
-	struct blacklist *blists;
-	struct servent *ent;
-	int i, ch;
-
-	while ((ch = getopt(argc, argv, "nd")) != -1) {
-		switch (ch) {
-		case 'n':
-			dryrun = 1;
-			break;
-		case 'd':
-			debug = 1;
-			break;
-		default:
-			break;
-		}
-	}
-
-	if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL)
-		errx(1, "cannot find service \"spamd-cfg\" in /etc/services");
-	ent->s_port = ntohs(ent->s_port);
-
-	dbs = argc + 2;
-	dbc = 0;
-	db_array = calloc(dbs, sizeof(char *));
-	if (db_array == NULL)
-		errx(1, "malloc failed");
-
-	db_array[dbc]= PATH_SPAMD_CONF;
-	dbc++;
-	for (i = 1; i < argc; i++)
-		db_array[dbc++] = argv[i];
-
-	blists = NULL;
-	blc = bls = 0;
-	if (cgetent(&buf, db_array, "all") != 0)
-		err(1, "Can't find \"all\" in spamd config");
-	name = strsep(&buf, ": \t"); /* skip "all" at start */
-	blc = 0;
-	while ((name = strsep(&buf, ": \t")) != NULL) {
-		if (*name) {
-			/* extract config in order specified in "all" tag */
-			if (blc == bls) {
-				struct blacklist *tmp;
-
-				bls += 1024;
-				tmp = realloc(blists,
-				    bls * sizeof(struct blacklist));
-				if (tmp == NULL)
-					errx(1, "malloc failed");
-				blists = tmp;
-			}
-			if (blc == 0)
-				black = white = 0;
-			else {
-				white = blc - 1;
-				black = blc;
-			}
-			memset(&blists[black], 0, sizeof(struct blacklist));
-			blc += getlist(db_array, name, &blists[white],
-			    &blists[black]);
-		}
-	}
-	for (i = 0; i < blc; i++) {
-		struct cidr **cidrs, **tmp;
-
-		if (blists[i].blc > 0) {
-			cidrs = collapse_blacklist(blists[i].bl,
-			   blists[i].blc);
-			if (cidrs == NULL)
-				errx(1, "malloc failed");
-			if (dryrun)
-				continue;
-
-			if (configure_spamd(ent->s_port, blists[i].name,
-			    blists[i].message, cidrs) == -1)
-				err(1, "Can't connect to spamd on port %d",
-				    ent->s_port);
-			if (configure_pf(cidrs) == -1)
-				err(1, "pfctl failed");
-			tmp = cidrs;
-			while (*tmp != NULL)
-				free(*tmp++);
-			free(cidrs);
-			free(blists[i].bl);
-		}
-	}
-	return (0);
-}
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamd-setup/spamd-setup.o and /usr/home/samm/spamd/work/spamd_3.7/spamd-setup/spamd-setup.o differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamdb/Makefile /usr/home/samm/spamd/work/spamd_3.7/spamdb/Makefile
--- /usr/ports/mail/spamd/work/spamd_3.7/spamdb/Makefile	Sun Oct  3 16:09:15 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/spamdb/Makefile	Thu Jan  1 03:00:00 1970
@@ -1,9 +0,0 @@
-#	$OpenBSD: Makefile,v 1.2 2004/02/27 19:41:39 david Exp $
-
-PROG=	spamdb
-SRCS=	spamdb.c
-MAN=	spamdb.8
-
-CFLAGS+= -Wall -Wstrict-prototypes -ansi -I${.CURDIR}/../spamd
-
-.include <bsd.prog.mk>
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamdb/spamdb and /usr/home/samm/spamd/work/spamd_3.7/spamdb/spamdb differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamdb/spamdb.8 /usr/home/samm/spamd/work/spamd_3.7/spamdb/spamdb.8
--- /usr/ports/mail/spamd/work/spamd_3.7/spamdb/spamdb.8	Tue Apr 12 20:19:22 2005
+++ /usr/home/samm/spamd/work/spamd_3.7/spamdb/spamdb.8	Thu Jan  1 03:00:00 1970
@@ -1,132 +0,0 @@
-.\"	$OpenBSD: spamdb.8,v 1.6 2005/03/12 23:31:04 jmc Exp $
-.\"
-.\" Copyright (c) 2004 Bob Beck.  All rights reserved.
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd February 16, 2004
-.Dt SPAMDB 8
-.Os
-.Sh NAME
-.Nm spamdb
-.Nd spamd database tool
-.Sh SYNOPSIS
-.Nm spamdb
-.Op Fl Tt
-.Op Fl a Ar key
-.Op Fl d Ar key
-.Sh DESCRIPTION
-.Nm
-manipulates the spamd database in
-.Pa /var/db/spamd
-used for
-.Xr spamd 8
-greylisting.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl a Ar key
-Add or update an entry for "key".
-Updates time last seen to now.
-.It Fl d Ar key
-Delete an entry for "key".
-.It Fl T
-Add or delete the key as a SPAMTRAP entry.
-.It Fl t
-Add or delete the key as a TRAPPED entry.
-.El
-.Ss DATABASE OUTPUT FORMAT
-If invoked without any arguments,
-.Nm
-lists the contents of the database in a text format.
-For SPAMTRAP entries the format is:
-.Pp
-.Dl type|mailaddress
-.Pp
-where
-.Em type
-will be SPAMTRAP and
-.Em mailaddress
-will be the email address for which any connections received by
-.Xr spamd 8
-will be blacklisted if mail is sent to this address.
-For TRAPPED entries the format is:
-.Pp
-.Dl type|ip|expire
-.Pp
-where
-.Em type
-will be TRAPPED,
-.Em ip
-will be the IP address blacklisted due to hitting a spamtrap, and
-.Em expire
-will be when the IP is due to be removed from the blacklist.
-For GREY or WHITE entries, the format is:
-.Pp
-.Dl type|source ip|from|to|first|pass|expire|block|pass
-.Pp
-The fields are as follows:
-.Pp
-.Bl -tag -width "source ip" -offset indent -compact
-.It type
-.Em WHITE
-if whitelisted or
-.Em GREY
-if greylisted
-.It source ip
-IP address the connection originated from
-.It from
-envelope-from address for
-.Em GREY
-(empty for
-.Em WHITE
-entries)
-.It to
-envelope-to address for
-.Em GREY
-(empty for
-.Em WHITE
-entries)
-.It first
-time the entry was first seen
-.It pass
-time the entry passed from being
-.Em GREY
-to being
-.Em WHITE
-.It expire
-time the entry will expire and be removed from the database
-.It block
-number of times a corresponding connection received a temporary
-failure from
-.Xr spamd 8
-.It pass
-number of times a corresponding connection has been seen to pass
-to the real MTA by
-.Xr spamlogd 8
-.El
-.Pp
-Note that times are in seconds since the Epoch, in the manner returned by
-.Xr time 3 .
-.Sh FILES
-/var/db/spamd
-.Sh SEE ALSO
-.Xr spamd.conf 5 ,
-.Xr spamd 8 ,
-.Xr spamd-setup 8
-.Sh HISTORY
-The
-.Nm
-command
-appeared in
-.Ox 3.5 .
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamdb/spamdb.8.gz and /usr/home/samm/spamd/work/spamd_3.7/spamdb/spamdb.8.gz differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamdb/spamdb.c /usr/home/samm/spamd/work/spamd_3.7/spamdb/spamdb.c
--- /usr/ports/mail/spamd/work/spamd_3.7/spamdb/spamdb.c	Tue Apr 12 20:20:44 2005
+++ /usr/home/samm/spamd/work/spamd_3.7/spamdb/spamdb.c	Thu Jan  1 03:00:00 1970
@@ -1,304 +0,0 @@
-/*	$OpenBSD: spamdb.c,v 1.14 2005/03/11 23:45:45 beck Exp $	*/
-
-/*
- * Copyright (c) 2004 Bob Beck.  All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <db.h>
-#include <err.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <unistd.h>
-
-#include "grey.h"
-
-/* things we may add/delete from the db */
-#define WHITE 0
-#define TRAPHIT 1
-#define SPAMTRAP 2
-
-int
-dbupdate(char *dbname, char *ip, int add, int type)
-{
-	BTREEINFO	btreeinfo;
-	DBT		dbk, dbd;
-	DB		*db;
-	struct gdata	gd;
-	time_t		now;
-	int		r;
-	struct addrinfo hints, *res;
-
-	now = time(NULL);
-	memset(&btreeinfo, 0, sizeof(btreeinfo));
-	db = dbopen(dbname, O_EXLOCK|O_RDWR, 0600, DB_BTREE, &btreeinfo);
-	if (db == NULL)
-		err(1, "cannot open %s for writing", dbname);
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = PF_UNSPEC;
-	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
-	hints.ai_flags = AI_NUMERICHOST;
-	if (type == TRAPHIT || type == WHITE) {
-		if (getaddrinfo(ip, NULL, &hints, &res) != 0) {
-			warnx("invalid ip address %s", ip);
-			goto bad;
-		}
-		freeaddrinfo(res);
-	}
-	memset(&dbk, 0, sizeof(dbk));
-	dbk.size = strlen(ip);
-	dbk.data = ip;
-	memset(&dbd, 0, sizeof(dbd));
-	if (!add) {
-		/* remove entry */
-		r = db->get(db, &dbk, &dbd, 0);
-		if (r == -1) {
-			warn("db->get failed");
-			goto bad;
-		}
-		if (r) {
-			warnx("no entry for %s", ip);
-			goto bad;
-		} else if (db->del(db, &dbk, 0)) {
-			warn("db->del failed");
-			goto bad;
-		}
-	} else {
-		/* add or update entry */
-		r = db->get(db, &dbk, &dbd, 0);
-		if (r == -1) {
-			warn("db->get failed");
-			goto bad;
-		}
-		if (r) {
-			int i;
-
-			/* new entry */
-			memset(&gd, 0, sizeof(gd));
-			gd.first = now;
-			gd.bcount = 1;
-			switch (type) {
-			case WHITE:
-				gd.pass = now;
-				gd.expire = now + WHITEEXP;
-				break;
-			case TRAPHIT:
-				gd.expire = now + TRAPEXP;
-				gd.pcount = -1;
-				break;
-			case SPAMTRAP:
-				gd.expire = 0;
-				gd.pcount = -2;
-				/* ensure address is lower case*/
-				for (i = 0; ip[i] != '\0'; i++)
-					if (isupper(ip[i]))
-						ip[i] = tolower(ip[i]);
-				break;
-			default:
-				errx(-1, "unknown type %d", type);
-			}
-			memset(&dbk, 0, sizeof(dbk));
-			dbk.size = strlen(ip);
-			dbk.data = ip;
-			memset(&dbd, 0, sizeof(dbd));
-			dbd.size = sizeof(gd);
-			dbd.data = &gd;
-			r = db->put(db, &dbk, &dbd, 0);
-			if (r) {
-				warn("db->put failed");
-				goto bad;
-			}
-		} else {
-			if (dbd.size != sizeof(gd)) {
-				/* whatever this is, it doesn't belong */
-				db->del(db, &dbk, 0);
-				goto bad;
-			}
-			memcpy(&gd, dbd.data, sizeof(gd));
-			gd.pcount++;
-			switch (type) {
-			case WHITE:
-				gd.pass = now;
-				gd.expire = now + WHITEEXP;
-				break;
-			case TRAPHIT:
-				gd.expire = now + TRAPEXP;
-				gd.pcount = -1;
-				break;
-			case SPAMTRAP:
-				gd.expire = 0; /* XXX */
-				gd.pcount = -2;
-				break;
-			default:
-				errx(-1, "unknown type %d", type);
-			}
-
-			memset(&dbk, 0, sizeof(dbk));
-			dbk.size = strlen(ip);
-			dbk.data = ip;
-			memset(&dbd, 0, sizeof(dbd));
-			dbd.size = sizeof(gd);
-			dbd.data = &gd;
-			r = db->put(db, &dbk, &dbd, 0);
-			if (r) {
-				warn("db->put failed");
-				goto bad;
-			}
-		}
-	}
-	db->close(db);
-	db = NULL;
-	return (0);
- bad:
-	db->close(db);
-	db = NULL;
-	return (1);
-}
-
-int
-dblist(char *dbname)
-{
-	BTREEINFO	btreeinfo;
-	DBT		dbk, dbd;
-	DB		*db;
-	struct gdata	gd;
-	int		r;
-
-	/* walk db, list in text format */
-	memset(&btreeinfo, 0, sizeof(btreeinfo));
-	db = dbopen(dbname, O_EXLOCK|O_RDONLY, 0600, DB_BTREE, &btreeinfo);
-	if (db == NULL)
-		err(1, "cannot open %s for reading", dbname);
-	memset(&dbk, 0, sizeof(dbk));
-	memset(&dbd, 0, sizeof(dbd));
-	for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r;
-	    r = db->seq(db, &dbk, &dbd, R_NEXT)) {
-		char *a, *cp;
-
-		if ((dbk.size < 1) || dbd.size != sizeof(struct gdata)) {
-			db->close(db);
-			errx(1, "bogus size db entry - bad db file?");
-		}
-		memcpy(&gd, dbd.data, sizeof(gd));
-		a = malloc(dbk.size + 1);
-		if (a == NULL)
-			err(1, "malloc");
-		memcpy(a, dbk.data, dbk.size);
-		a[dbk.size]='\0';
-		cp = strchr(a, '\n');
-		if (cp == NULL) {
-			/* this is a non-greylist entry */
-			switch (gd.pcount) {
-			case -1: /* spamtrap hit, with expiry time */
-				printf("TRAPPED|%s|%d\n", a, gd.expire);
-				break;
-			case -2: /* spamtrap address */
-				printf("SPAMTRAP|%s\n", a);
-				break;
-			default: /* whitelist */
-				printf("WHITE|%s|||%d|%d|%d|%d|%d\n", a,
-				    gd.first, gd.pass, gd.expire, gd.bcount,
-				    gd.pcount);
-				break;
-			}
-		} else {
-			char *from, *to;
-
-			/* greylist entry */
-			*cp = '\0';
-			from = cp + 1;
-			to = strchr(from, '\n');
-			if (to == NULL) {
-				warnx("No from part in grey key %s", a);
-				free(a);
-				goto bad;
-			}
-			*to = '\0';
-			to++;
-			printf("GREY|%s|%s|%s|%d|%d|%d|%d|%d\n",
-			    a, from, to, gd.first, gd.pass, gd.expire,
-			    gd.bcount, gd.pcount);
-		}
-		free(a);
-	}
-	db->close(db);
-	db = NULL;
-	return (0);
- bad:
-	db->close(db);
-	db = NULL;
-	errx(1, "incorrect db format entry");
-	/* NOTREACHED */
-	return (1);
-}
-
-extern char *__progname;
-
-static int
-usage(void)
-{
-	fprintf(stderr, "usage: %s [-Tt] [-a key] [-d key]\n", __progname);
-	exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
-	int ch, action = 0, type = WHITE;
-	char *ip = NULL;
-
-	while ((ch = getopt(argc, argv, "a:d:tT")) != -1) {
-		switch (ch) {
-		case 'a':
-			action = 1;
-			ip = optarg;
-			break;
-		case 'd':
-			action = 2;
-			ip = optarg;
-			break;
-		case 't':
-			type = TRAPHIT;
-			break;
-		case 'T':
-			type = SPAMTRAP;
-			break;
-		default:
-			usage();
-			break;
-		}
-	}
-
-	switch (action) {
-	case 0:
-		return dblist(PATH_SPAMD_DB);
-	case 1:
-		return dbupdate(PATH_SPAMD_DB, ip, 1, type);
-	case 2:
-		return dbupdate(PATH_SPAMD_DB, ip, 0, type);
-	default:
-		errx(-1, "bad action");
-	}
-	/* NOT REACHED */
-	return (0);
-}
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamdb/spamdb.o and /usr/home/samm/spamd/work/spamd_3.7/spamdb/spamdb.o differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/Makefile /usr/home/samm/spamd/work/spamd_3.7/spamlogd/Makefile
--- /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/Makefile	Fri Feb  2 10:53:08 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamlogd/Makefile	Thu Jan  1 03:00:00 1970
@@ -1,9 +0,0 @@
-#	$OpenBSD: Makefile,v 1.2 2004/02/27 19:41:39 david Exp $
-
-PROG=	spamlogd
-SRCS=	spamlogd.c
-MAN=	spamlogd.8
-
-CFLAGS+= -g -Wall -Wstrict-prototypes -ansi -I${.CURDIR}/../spamd
-
-.include <bsd.prog.mk>
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/spamlogd and /usr/home/samm/spamd/work/spamd_3.7/spamlogd/spamlogd differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/spamlogd.8 /usr/home/samm/spamd/work/spamd_3.7/spamlogd/spamlogd.8
--- /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/spamlogd.8	Sun Oct  3 16:10:56 2004
+++ /usr/home/samm/spamd/work/spamd_3.7/spamlogd/spamlogd.8	Thu Jan  1 03:00:00 1970
@@ -1,114 +0,0 @@
-.\"	$OpenBSD: spamlogd.8,v 1.4 2004/07/14 21:38:09 jmc Exp $
-.\"
-.\" Copyright (c) 2004 Bob Beck.  All rights reserved.
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd February 16, 2004
-.Dt SPAMLOGD 8
-.Os
-.Sh NAME
-.Nm spamlogd
-.Nd spamd whitelist updating daemon
-.Sh SYNOPSIS
-.Nm spamlogd
-.Op Fl I
-.Op Fl i Ar interface
-.Sh DESCRIPTION
-.Nm
-manipulates the
-.Xr spamd 8
-database in
-.Pa /var/db/spamd
-used for
-.Xr spamd 8
-greylisting.
-.Nm
-updates the
-.Pa /var/db/spamd
-whitelist entries whenever a connection
-to port 25 is logged to the
-.Xr pflog 4
-interface.
-The source addresses of inbound connections are whitelisted
-when seen by
-.Nm
-to ensure that their entries in
-.Pa /var/db/spamd
-do not expire if the connecting host continues to send legitimate mail.
-The destination addresses of outbound connections are whitelisted
-when seen by
-.Nm
-so that replies to outbound mail may be received without initial
-greylisting delays
-(see
-.Sx GREYLISTING
-in
-.Xr spamd 8 ) .
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl I
-Specify that
-.Nm
-is only to whitelist inbound SMTP connections.
-By default
-.Nm
-will whitelist the source of inbound SMTP connections, and the
-target of outbound SMTP connections.
-.It Fl i Ar interface
-Specify a network interface on which packets must arrive.
-The default is to watch for connections logged from any interfaces.
-.El
-.Pp
-It is important to be sure to log any connections to and from your real
-MTA in order for
-.Nm
-to update the whitelist entries.
-An example
-.Xr pf.conf 5
-configuration for logging such connections is as follows:
-.Bd -literal -offset indent
-EXT_IF = "fxp0"
-MAILHOSTS = "{129.128.11.10, 129.128.11.43}"
-pass in log on $EXT_IF inet proto tcp to $MAILHOSTS \e
-	port smtp keep state
-pass out log on $EXT_IF inet proto tcp from $MAILHOSTS \e
-	to any port smtp keep state
-.Ed
-.Pp
-.Nm
-sends log messages to
-.Xr syslogd 8
-using facility
-.Em daemon .
-.Nm
-will log each connection it sees at level
-.Dv LOG_DEBUG .
-.Sh FILES
-/var/db/spamd
-.Sh SEE ALSO
-.Xr syslog 3 ,
-.Xr pflog 4 ,
-.Xr spamd.conf 5 ,
-.Xr pflogd 8 ,
-.Xr spamd 8 ,
-.Xr spamd-setup 8 ,
-.Xr spamdb 8 ,
-.Xr syslogd 8 ,
-.Xr tcpdump 8
-.Sh HISTORY
-The
-.Nm
-command first appeared in
-.Ox 3.5 .
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/spamlogd.8.gz and /usr/home/samm/spamd/work/spamd_3.7/spamlogd/spamlogd.8.gz differ
diff -ruN --exclude=CVS /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/spamlogd.c /usr/home/samm/spamd/work/spamd_3.7/spamlogd/spamlogd.c
--- /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/spamlogd.c	Fri Feb  2 10:58:10 2007
+++ /usr/home/samm/spamd/work/spamd_3.7/spamlogd/spamlogd.c	Thu Jan  1 03:00:00 1970
@@ -1,272 +0,0 @@
-/*	$OpenBSD: spamlogd.c,v 1.11 2004/09/18 07:33:03 beck Exp $	*/
-
-/*
- * Copyright (c) 2004 Bob Beck.  All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* watch pf log for mail connections, update whitelist entries. */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <db.h>
-#include <err.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "grey.h"
-#define PATH_TCPDUMP "/usr/sbin/tcpdump"
-
-#ifdef __OpenBSD__
-struct syslog_data sdata = SYSLOG_DATA_INIT;
-#else
-#define	syslog_r(l, s, args...)	syslog(l,args)
-#define	openlog_r(i, l, f, s)	openlog(i, l, f)
-int sdata = 0;					/* dummy */
-#endif
-int inbound; /* do we only whitelist inbound smtp? */
-
-extern char *__progname;
-
-int
-dbupdate(char *dbname, char *ip)
-{
-	BTREEINFO	btreeinfo;
-	DBT		dbk, dbd;
-	DB		*db;
-	struct gdata	gd;
-	time_t		now;
-	int		r;
-	struct in_addr	ia;
-
-	now = time(NULL);
-	memset(&btreeinfo, 0, sizeof(btreeinfo));
-	db = dbopen(dbname, O_EXLOCK|O_RDWR, 0600, DB_BTREE, &btreeinfo);
-	if (db == NULL)
-		return(-1);
-	if (inet_pton(AF_INET, ip, &ia) != 1) {
-		syslog_r(LOG_NOTICE, &sdata, "invalid ip address %s", ip);
-		goto bad;
-	}
-	memset(&dbk, 0, sizeof(dbk));
-	dbk.size = strlen(ip);
-	dbk.data = ip;
-	memset(&dbd, 0, sizeof(dbd));
-	/* add or update whitelist entry */
-	r = db->get(db, &dbk, &dbd, 0);
-	if (r == -1) {
-		syslog_r(LOG_NOTICE, &sdata, "db->get failed (%m)");
-		goto bad;
-	}
-	if (r) {
-		/* new entry */
-		memset(&gd, 0, sizeof(gd));
-		gd.first = now;
-		gd.bcount = 1;
-		gd.pass = now;
-		gd.expire = now + WHITEEXP;
-		memset(&dbk, 0, sizeof(dbk));
-		dbk.size = strlen(ip);
-		dbk.data = ip;
-		memset(&dbd, 0, sizeof(dbd));
-		dbd.size = sizeof(gd);
-		dbd.data = &gd;
-		r = db->put(db, &dbk, &dbd, 0);
-		if (r) {
-			syslog_r(LOG_NOTICE, &sdata, "db->put failed (%m)");
-			goto bad;
-		}
-	} else {
-		if (dbd.size != sizeof(gd)) {
-			/* whatever this is, it doesn't belong */
-			db->del(db, &dbk, 0);
-			goto bad;
-		}
-		memcpy(&gd, dbd.data, sizeof(gd));
-		gd.pcount++;
-		gd.expire = now + WHITEEXP;
-		memset(&dbk, 0, sizeof(dbk));
-		dbk.size = strlen(ip);
-		dbk.data = ip;
-		memset(&dbd, 0, sizeof(dbd));
-		dbd.size = sizeof(gd);
-		dbd.data = &gd;
-		r = db->put(db, &dbk, &dbd, 0);
-		if (r) {
-			syslog_r(LOG_NOTICE, &sdata, "db->put failed (%m)");
-			goto bad;
-		}
-	}
-	db->close(db);
-	db = NULL;
-	return (0);
- bad:
-	db->close(db);
-	db = NULL;
-	return (-1);
-}
-
-static void
-usage(void)
-{
-	fprintf(stderr, "usage: %s [-I] [-i interface]\n", __progname);
-	exit(1);
-}
-
-char *targv[19] = {
-	"tcpdump", "-l",  "-n", "-e", "-i", "pflog0", "-q",
-	"-t", "port", "25", "and", "action", "pass",
-	"and", "tcp[13]&0x12=0x2",
-	NULL, NULL, NULL, NULL
-};
-
-int
-main(int argc, char **argv)
-{
-	int ch, p[2];
-	char *buf, *lbuf;
-	size_t len;
-	FILE *f;
-
-
-	while ((ch = getopt(argc, argv, "i:I")) != -1) {
-		switch (ch) {
-		case 'i':
-			if (targv[17])	/* may only set once */
-				usage();
-			targv[15] = "and";
-			targv[16] = "on";
-			targv[17] = optarg;
-			break;
-		case 'I':
-			inbound = 1;
-			break;
-		default:
-			usage();
-			break;
-		}
-	}
-int ii;
-for(ii=0;ii<=17;ii++)
-{
-    fprintf(stderr,"test:%d:%s\n",ii,targv[ii]);
-}
-
-/*	if (daemon(1, 1) == -1)
-		err(1, "daemon"); */
-	if (pipe(p) == -1)
-		err(1, "pipe");
-	switch (fork()) {
-	case -1:
-		err(1, "fork");
-	case 0:
-		/* child */
-		close(p[0]);
-		close(STDERR_FILENO);
-		if (dup2(p[1], STDOUT_FILENO) == -1) {
-			warn("dup2");
-			_exit(1);
-		}
-		close(p[1]);
-		execvp(PATH_TCPDUMP, targv);
-		warn("exec of %s failed", PATH_TCPDUMP);
-		_exit(1);
-	}
-	fprintf(stderr,"test2\n");
-	/* parent */
-	close(p[1]);
-	f = fdopen(p[0], "r");
-	if (f == NULL)
-		err(1, "fdopen");
-	tzset();
-	fprintf(stderr,"test3\n");
-	openlog_r("spamlogd", LOG_PID | LOG_NDELAY, LOG_DAEMON, &sdata);
-	fprintf(stderr,"test4\n");
-	lbuf = NULL;
-	while ((buf = fgetln(f, &len))) {
-		char *cp = NULL;
-		char *buf2;
-
-		if ((buf2 = malloc(len + 1)) == NULL) {
-			syslog_r(LOG_ERR, &sdata, "malloc failed");
-    	fprintf(stderr,"test5.1\n");
-			exit(1);
-		}
-    	fprintf(stderr,"test5\n");
-		if (buf[len - 1] == '\n')
-			buf[len - 1] = '\0';
-		else {
-			if ((lbuf = (char *)malloc(len + 1)) == NULL) {
-				syslog_r(LOG_ERR, &sdata, "malloc failed");
-				exit(1);
-			}
-			memcpy(lbuf, buf, len);
-			lbuf[len] = '\0';
-			buf = lbuf;
-		}
-		if (strstr(buf, "pass out") != NULL) {
-			/*
-			 * this is outbound traffic - we whitelist
-			 * the destination address, because we assume
-			 * that a reply may come to this outgoing mail
-			 * we are sending.
-			 */
-			if (!inbound && (cp = (strchr(buf, '>'))) != NULL) {
-				if (sscanf(cp, "> %s", buf2) == 1) {
-					cp = strrchr(buf2, '.');
-					if (cp != NULL) {
-						*cp = '\0';
-						cp = buf2;
-						syslog_r(LOG_DEBUG, &sdata,
-						    "outbound %s\n", cp);
-					}
-				} else
-					cp = NULL;
-			}
-
-		} else {
-			/*
-			 * this is inbound traffic - we whitelist
-			 * the source address, because this is
-			 * traffic presumably to our real MTA
-			 */
-			if ((cp = (strchr(buf, '>'))) != NULL) {
-				while (*cp != '.' && cp >= buf) {
-					*cp = '\0';
-					cp--;
-				}
-				*cp ='\0';
-				while (*cp != ' ' && cp >= buf)
-					cp--;
-				cp++;
-				syslog_r(LOG_DEBUG, &sdata,
-				    "inbound %s\n", cp);
-			}
-		}
-		if (cp != NULL)
-			dbupdate(PATH_SPAMD_DB, cp);
-
-		free(lbuf);
-		lbuf = NULL;
-		free(buf2);
-	}
-	exit(0);
-}
Binary files /usr/ports/mail/spamd/work/spamd_3.7/spamlogd/spamlogd.o and /usr/home/samm/spamd/work/spamd_3.7/spamlogd/spamlogd.o differ
--- spamd-4.1.1.patch ends here ---

>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list