[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.94.dfsg.2-1-303-gd86c30a

Michael Tautschnig mt at debian.org
Sun Mar 8 21:23:53 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit ea86953e5c644f653261362c2978e487252a2b45
Author: Michael Tautschnig <mt at debian.org>
Date:   Sun Mar 8 21:42:24 2009 +0100

    Merged changes from upstream tarball for 0.95rc1
    
    - contrib directory has been removed entirely
    - updated main.cvd, daily.cvd
    - some whitespace fixes maybe had been lost during merge
    
    Signed-off-by: Michael Tautschnig <mt at debian.org>

diff --git a/ChangeLog b/ChangeLog
index 1b21e37..0b4f6b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1214,7 +1214,7 @@ Thu Oct 30 16:47:17 CET 2008 (tk)
 Thu Oct 30 13:52:42 CET 2008 (acab)
 -----------------------------------
  * libclamav/vba_extract.c: get_unicode_name off-by-one - bb#1239
-			    reported by Moritz Jodeit <moritz*jodeit.org>
+ 			    reported by Moritz Jodeit <moritz*jodeit.org>
 
 Thu Oct 30 13:07:53 EET 2008 (edwin)
 ------------------------------------
@@ -1870,7 +1870,7 @@ Tue Jul 29 02:44:53 CEST 2008 (acab)
 Tue Jul 29 02:18:11 CEST 2008 (acab)
 ------------------------------------
   * libclamav/autoit.c: rely on generic text normalization for
-			unicode scripts
+  			unicode scripts
   * test: add clam.ea05.exe, clam.ea06.exe
 
 Mon Jul 28 21:04:53 CEST 2008 (acab)
diff --git a/NEWS b/NEWS
index a5dcd5a..934d4ab 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,48 @@
-0.94.2
-------
+0.95rc1
+-------
 
-This is a bugfix release, please refer to the ChangeLog for a complete
-list of changes.
+ClamAV 0.95rc1 introduces many bugfixes, improvements and additions. To make
+the transition easier, we put various tips and upgrade notes on this page:
+https://wiki.clamav.net/Main/UpgradeNotes095
+
+The following are the key features of this release:
+
+    - New clamav-milter: The program has been redesigned and rewritten from
+      scratch. The most notable difference is that the internal mode has been
+      dropped which means that now a working clamd companion is required.
+      The milter now also has its own configuration file.
+
+    - Clamd extensions: The protocol has been extended to lighten the load
+      that clamd puts on the system, solve limitations of the old protocol,
+      and reduce latency when signature updates are received. Fore more
+      information about the new extensions please see the official
+      documentation and the upgrade notes.
+
+    - Improved API: The API used to program ClamAV's engine (libclamav) has
+      been redesigned to use modern object-oriented techniques and solves
+      various API/ABI compatibility issues between old and new releases.
+      You can find more information in Section 6 of clamdoc.pdf and in
+      the upgrade notes.
+
+    - ClamdTOP: This is a new program that allows system administrators to
+      monitor clamd. It provides information about the items in the clamd's
+      queue, clamd's memory usage, and the version of the signature database,
+      all in real-time and in nice curses-based interface.
+
+    - Memory Pool Allocator: Libclamav now includes its own memory pool
+      allocator based on memory mapping. This new solution replaces the
+      traditional malloc/free system for the copy of the signatures that
+      is kept in memory. As a result, clamd requires much less memory,
+      particularly when signature updates are received and the database is
+      loaded into memory.
+
+    - Unified Option Parser: Prior to version 0.95 each program in ClamAV's
+      suite of programs had its own set of runtime options. The new general
+      parser brings consistency of use and validation to these options across
+      the suite. Some command line switches of clamscan have been renamed
+      (the old ones will still be accepted but will have no effect and will
+      result in warnings), please see clamscan(1) and clamscan --help for
+      the details.
 
 --
 The ClamAV team (http://www.clamav.net/team)
diff --git a/README b/README
index 75c8180..ecc75b3 100644
--- a/README
+++ b/README
@@ -2,15 +2,6 @@ Note: This README/NEWS file refers to the source tarball. Some things described
 here may not be available in binary packages.
 --
 
-0.94.2
-------
-
-This is a bugfix release, please refer to the ChangeLog for a complete
-list of changes.
-
---
-The ClamAV team (http://www.clamav.net/team)
-
 
 0.95rc1
 -------
diff --git a/configure b/configure
index 70b6043..a27c6dd 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for clamav 0.94.2.
+# Generated by GNU Autoconf 2.61 for clamav devel.
 #
 # Report bugs to <http://bugs.clamav.net/>.
 #
@@ -725,8 +725,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='clamav'
 PACKAGE_TARNAME='clamav'
-PACKAGE_VERSION='0.94.2'
-PACKAGE_STRING='clamav 0.94.2'
+PACKAGE_VERSION='devel'
+PACKAGE_STRING='clamav devel'
 PACKAGE_BUGREPORT='http://bugs.clamav.net/'
 
 ac_unique_file="clamscan/clamscan.c"
@@ -1452,7 +1452,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures clamav 0.94.2 to adapt to many kinds of systems.
+\`configure' configures clamav devel to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1523,7 +1523,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of clamav 0.94.2:";;
+     short | recursive ) echo "Configuration of clamav devel:";;
    esac
   cat <<\_ACEOF
 
@@ -1670,7 +1670,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-clamav configure 0.94.2
+clamav configure devel
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1684,7 +1684,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by clamav $as_me 0.94.2, which was
+It was created by clamav $as_me devel, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2694,7 +2694,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='clamav'
- VERSION='0.94.2'
+ VERSION='devel'
 
 
 # Some tools Automake needs.
@@ -2838,7 +2838,7 @@ cat >>confdefs.h <<\_ACEOF
 _ACEOF
 
 
-VERSION="0.94.2"
+VERSION="0.95rc1"
 
 cat >>confdefs.h <<_ACEOF
 #define VERSION "$VERSION"
@@ -16761,11 +16761,6 @@ fi
                 LIBCHECK_PREFIX="$basedir"
                 additional_includedir="$basedir/include"
                 ;;
-	     */lib | */lib/)
-                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/lib/"'*$,,'`
-                LIBGMP_PREFIX="$basedir"
-                additional_includedir="$basedir/include"
-                ;;
             esac
             if test "X$additional_includedir" != "X"; then
                                                                                                                 if test "X$additional_includedir" != "X/usr/include"; then
@@ -25164,7 +25159,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by clamav $as_me 0.94.2, which was
+This file was extended by clamav $as_me devel, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -25217,7 +25212,7 @@ Report bugs to <bug-autoconf at gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-clamav config.status 0.94.2
+clamav config.status devel
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/configure.in b/configure.in
index 99131c3..bca7bc5 100644
--- a/configure.in
+++ b/configure.in
@@ -20,7 +20,7 @@ dnl   MA 02110-1301, USA.
 AC_PREREQ([2.59])
 dnl For a release change [devel] to the real version [0.xy]
 dnl also change VERSION below
-AC_INIT([clamav], [0.94.2], [http://bugs.clamav.net/])
+AC_INIT([clamav], [devel], [http://bugs.clamav.net/])
 
 dnl put configure auxiliary into config
 AC_CONFIG_AUX_DIR([config])
@@ -39,8 +39,7 @@ dnl the date in the version
 AC_DEFINE([PACKAGE], PACKAGE_NAME, [Name of package])
 
 dnl change this on a release
-VERSION="0.94.2"
-dnl VERSION="devel-`date +%Y%m%d`"
+VERSION="0.95rc1"
 AC_DEFINE_UNQUOTED([VERSION],"$VERSION",[Version number of package])
 
 LC_CURRENT=6
diff --git a/contrib/clamdwatch/clamdwatch.tar.gz b/contrib/clamdwatch/clamdwatch.tar.gz
deleted file mode 100644
index b327726..0000000
Binary files a/contrib/clamdwatch/clamdwatch.tar.gz and /dev/null differ
diff --git a/contrib/cleanup-partial.pl b/contrib/cleanup-partial.pl
deleted file mode 100755
index 1346f71..0000000
--- a/contrib/cleanup-partial.pl
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/perl
-
-# ---- Settings ----
-# TemporaryDirectory in clamd.conf
-my $TMPDIR='/tmp';
-# How long to wait for next part of RFC1341 message (seconds)
-my $cleanup_interval=3600;
-
-# ---- End of Settings ----
-
-my $partial_dir = "$TMPDIR/clamav-partial";
-#  if there is no partial directory, nothing to clean up
-opendir(DIR, $partial_dir) || exit 0;
-
-my $cleanup_threshold = time - $cleanup_interval;
-while(my $file = readdir(DIR)) {
-	next unless $file =~ m/^clamav-partial-([0-9]+)_[0-9a-f]{32}-[0-9]+$/;
-	my $filetime = $1;
-	unlink "$partial_dir/$file" unless $filetime > $cleanup_threshold;
-}
-closedir DIR;
diff --git a/contrib/init/FreeBSD5.2/clamav b/contrib/init/FreeBSD5.2/clamav
deleted file mode 100755
index d138678..0000000
--- a/contrib/init/FreeBSD5.2/clamav
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/sh
-
-# Copyright (C) 2004 Nigel Horne <njh at bandsman.co.uk>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301, USA.
-#
-# Install into /usr/local/etc/rc.d as /usr/local/etc/rc.d/clamav.sh
-#	chmod 755 /usr/local/etc/rc.d/clamav.sh
-#
-# Add lines such as this to /etc/rc.conf:
-#	clamd_enable="YES"
-#	clamav_milter_enable="YES"
-#	clamav_milter_flags="--max-children=2 --dont-wait --timeout=0 -P local:/var/run/clamav/clamav.sock --pidfile=/var/run/clamav/clamav-milter.pid --quarantine-dir=/var/run/clamav/quarantine"
-#
-# Tested with FreeBSD 5.2 and 5.3
-
-# PROVIDE: clamav
-# REQUIRE: NETWORKING
-# KEYWORD: FreeBSD
-
-. /etc/rc.subr
-
-# Don't allow files larger than 20M to be created, to limit DoS
-# Needs to be large enough to extract the signature files
-ulimit -f 20000
-
-name="clamd"
-rcvar="`set_rcvar`"
-command="/usr/local/sbin/${name}"
-
-load_rc_config $name
-run_rc_command "$1"
-
-name="clamav_milter"
-rcvar="`set_rcvar`"
-command="/usr/local/sbin/clamav-milter"
-
-load_rc_config $name
-run_rc_command "$1"
diff --git a/contrib/init/NetBSD2.0/clamav b/contrib/init/NetBSD2.0/clamav
deleted file mode 100755
index a933458..0000000
--- a/contrib/init/NetBSD2.0/clamav
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/sh
-
-# Copyright (C) 2004 Nigel Horne <njh at bandsman.co.uk>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301, USA.
-#
-# Install into /etc/rc.d as /etc/rc.d/clamav
-#	chmod 755 /etc/rc.d/clamav
-#
-# Add lines such as this to /etc/rc.conf:
-#	clamd="YES"
-#	clamav_milter="YES"
-#	clamav_milter_flags="--max-children=2 --dont-wait --timeout=0 -P local:/var/run/clamav/clamav.sock --pidfile=/var/run/clamav/clamav-milter.pid --quarantine-dir=/var/run/clamav/quarantine"
-#
-# Tested with NetBSD 2.0
-
-# PROVIDE: clamav
-# REQUIRE: NETWORKING
-# KEYWORD: NetBSD
-
-. /etc/rc.subr
-
-# Don't allow files larger than 20M to be created, to limit DoS
-# Needs to be large enough to extract the signature files
-ulimit -f 20000
-
-name="clamd"
-command="/usr/local/sbin/${name}"
-
-load_rc_config $name
-run_rc_command "$1"
-
-name="clamav_milter"
-command="/usr/local/sbin/clamav-milter"
-
-load_rc_config $name
-if [ $clamav_milter = YES ]; then
-	run_rc_command "$1"
-fi
diff --git a/contrib/init/OpenBSD3.6/README b/contrib/init/OpenBSD3.6/README
deleted file mode 100644
index 617a520..0000000
--- a/contrib/init/OpenBSD3.6/README
+++ /dev/null
@@ -1,9 +0,0 @@
-Edit /etc/rc.local adding the following before the "echo '.'" line, you
-should also call freshclam.
-
-if [ -x /usr/local/sbin/clamd ]; then
-	echo -n ' clamd'
-	# Don't allow files larger than 20M to be created, to limit DoS
-	# Needs to be large enough to extract the signature files
-	(ulimit -f 20000 && /usr/local/sbin/clamd)
-fi
diff --git a/contrib/init/RedHat/clamav-milter b/contrib/init/RedHat/clamav-milter
deleted file mode 100755
index 18bf5bf..0000000
--- a/contrib/init/RedHat/clamav-milter
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/bin/sh
-#
-# clamav-milter This script starts and stops the clamav-milter daemon
-#
-# chkconfig: 2345 79 40
-#
-# description: clamav-milter is a daemon which hooks into sendmail and routes \
-#              email messages for virus scanning with ClamAV
-# processname: clamav-milter
-# pidfile: /var/lock/subsys/clamav-milter
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-
-# Source networking configuration.
-. /etc/sysconfig/network
-
-# Local clamav-milter config
-CLAMAV_FLAGS=
-test -f /etc/sysconfig/clamav-milter && . /etc/sysconfig/clamav-milter
-
-# Check that networking is up.
-[ ${NETWORKING} = "no" ] && exit 0
-
-[ -x /usr/local/sbin/clamav-milter ] || exit 0
-PATH=$PATH:/usr/bin:/usr/local/sbin:/usr/local/bin
-
-RETVAL=0
-
-# Clamav-milter must have write access to the pid file, /var/run is not suitable
-default_pidfile=
-[ -d /var/run/clamav-milter ] && default_pidfile=/var/run/clamav-milter/clamav-milter.pid
-[ -d /var/clamav ] && default_pidfile=/var/clamav/clamav-milter.pid
-pidfile=${PIDFILE:-$default_pidfile}
-
-lockfile=/var/lock/subsys/clamav-milter
-
-start() {
-        echo -n "Starting clamav-milter: "
-	# Don't allow files larger than 25M to be created, to limit DoS
-	# Needs to be large enough to extract the signature files
-	ulimit -f 25600
-	if [ ! -z $pidfile ]; then
-		CLAMAV_PID=--pidfile=${pidfile}
-		PID=`pidofproc -p ${pidfile} clamav-milter`
-	else
-		CLAMAV_PID=
-		PID=`pidofproc clamav-milter`
-	fi
-	[ -n "$PID" ] && echo " already running!" && return 1
-        LANG= daemon clamav-milter $CLAMAV_PID ${CLAMAV_FLAGS}
-        RETVAL=$?
-	[ ! -z $pidfile -a -f $pidfile ] && sed -i -e 's/-//' $pidfile
-        echo
-	test $RETVAL -eq 0 && touch ${lockfile}
-	return $RETVAL
-}
-
-stop() {
-        echo -n "Shutting down clamav-milter: "
-	if [ ! -z $pidfile ]; then
-	        killproc -p ${pidfile} clamav-milter
-	else
-		killproc clamav-milter
-	fi
-        RETVAL=$?
-        echo
-	test $RETVAL -eq 0 && rm -f ${lockfile} ${pidfile}
-}
-
-restart() {
-	stop
-	start
-}
-
-# See how we were called.
-case "$1" in
-  start)
-        # Start daemon.
-	start
-        ;;
-  stop)
-        # Stop daemon.
-	stop
-        ;;
-  restart|reload)
-	restart
-        ;;
-  condrestart)
-	test -f ${lockfile} && $0 restart || :
-        ;;
-  status)
-	if [ ! -z $pidfile ]; then
-	        status -p ${pidfile} clamav-milter
-	else
-		status clamav-milter
-	fi
-        ;;
-  *)
-        echo "Usage: $0 {start|stop|reload|restart|condrestart|status}"
-        exit 1
-esac
-
-exit $?
diff --git a/contrib/init/RedHat/clamd b/contrib/init/RedHat/clamd
deleted file mode 100755
index 3e9a214..0000000
--- a/contrib/init/RedHat/clamd
+++ /dev/null
@@ -1,89 +0,0 @@
-#! /bin/bash
-#
-# crond   Start/Stop the clam antivirus daemon.
-#
-# chkconfig: 2345 70 41
-# description: clamd is a standard Linux/UNIX program that scans for Viruses.
-# processname: clamd
-# config: /usr/local/etc/clamd.conf
-# pidfile: /var/lock/subsys/clamd
-
-# Source function library.
-. /etc/init.d/functions
-
-RETVAL=0
-
-# See how we were called.
-
-prog="clamd"
-progdir="/usr/local/sbin"
-
-# Source configuration
-if [ -f /etc/sysconfig/$prog ] ; then
-	. /etc/sysconfig/$prog
-fi
-
-start() {
-	echo -n $"Starting $prog: "
-	# Don't allow files larger than 20M to be created, to limit DoS
-	# Needs to be large enough to extract the signature files
-	ulimit -f 20000
-        LANG= daemon $progdir/$prog
-	RETVAL=$?
-	echo
-	[ $RETVAL -eq 0 ] && touch /var/lock/subsys/clamd
-	return $RETVAL
-}
-
-stop() {
-	echo -n $"Stopping $prog: "
-	# Would be better to send QUIT first, then killproc if that fails
-	killproc $prog
-	RETVAL=$?
-	echo
-	[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/clamd
-	return $RETVAL
-}
-
-rhstatus() {
-	status clamd
-}
-
-restart() {
-	stop
-	start
-}
-
-reload() {
-	echo -n $"Reloading clam daemon configuration: "
-	killproc clamd -HUP
-	retval=$?
-	echo
-	return $RETVAL
-}
-
-case "$1" in
-  start)
-	start
-	;;
-  stop)
-	stop
-	;;
-  restart)
-	restart
-	;;
-  reload)
-	reload
-	;;
-  status)
-	rhstatus
-	;;
-  condrestart)
-	[ -f /var/lock/subsys/clamd ] && restart || :
-	;;
-  *)
-	echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}"
-	exit 1
-esac
-
-exit $?
diff --git a/contrib/init/Solaris10/clamav-milter b/contrib/init/Solaris10/clamav-milter
deleted file mode 100644
index 74c8380..0000000
--- a/contrib/init/Solaris10/clamav-milter
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-CONF_FILE=/usr/local/etc/clamd.conf
-RUNDIR=/var/run/clamav
-CLAMAV_MILTER_FLAGS="-l --max-children=2 local:$RUNDIR/clmilter.sock"
-
-if [ ! -f $CONF_FILE ]; then
-	exit 0
-fi
-
-if [ ! -d $RUNDIR ]; then
-	/usr/bin/mkdir -p -m 700 $RUNDIR
-	USER=`fgrep User ${CONF_FILE} | awk '{ print $2 }'`
-	if [ x$USER != x ]; then
-		chown $USER $RUNDIR
-	fi
-fi
-
-case "$1" in
-	start)
-		/usr/local/sbin/clamav-milter $CLAMAV_MILTER_FLAGS
-		;;
-	stop)
-		kill `ps -ef | awk '$NF ~ /clamav-milter/ { print $2 }'` > /dev/null 2>&1
-		;;
-	*)
-		echo "usage: $0 {start|stop}"
-esac
diff --git a/contrib/init/Solaris10/clamd b/contrib/init/Solaris10/clamd
deleted file mode 100755
index 9afa9f2..0000000
--- a/contrib/init/Solaris10/clamd
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-CONF_FILE=/usr/local/etc/clamd.conf
-
-if [ ! -f $CONF_FILE ]; then
-	exit 0
-fi
-
-case "$1" in
-	start)
-		/usr/local/sbin/clamd
-		;;
-	stop)
-		kill `ps -ef | awk '$NF ~ /clamd/ { print $2 }'` > /dev/null 2>&1
-		;;
-	*)
-		echo "usage: $0 {start|stop}"
-esac
diff --git a/contrib/init/SuSE/clamd b/contrib/init/SuSE/clamd
deleted file mode 100755
index 2e483ff..0000000
--- a/contrib/init/SuSE/clamd
+++ /dev/null
@@ -1,101 +0,0 @@
-#! /bin/sh
-# v1.2 05-2004, martin fuxa, yeti at email.cz
-#
-### BEGIN INIT INFO
-# Provides:       clamd
-# Required-Start: 
-# Required-Stop:  
-# Default-Start:  2 3 5
-# Default-Stop:   0 1 2 6
-# Description:    Control clamav daemon.
-### END INIT INFO
-#
-### HISTORY
-# 2004-05-27 ADD - FreshClam code
-
-# Variables
-PID="/var/run/clamd.pid"
-SBIN="/usr/local/sbin/clamd"
-CONF="/etc/clamav.conf"
-WHAT="Clam AntiVirus"
-
-# START_FRESHCLAM value: 1=true, 0 false
-START_FRESHCLAM=1
-FRESHCLAM_SBIN="/usr/local/bin/freshclam"
-FRESHCLAM_CONF="/etc/freshclam.conf"
-FRESHCLAM_WHAT="FreshClam"
-
-# Source SuSE config
-. /etc/rc.status
-
-test -x $SBIN || exit 5
-test -e $CONF || exit 5
-
-if [ $START_FRESHCLAM = 1 ]
-then
-    test -x $FRESHCLAM_SBIN || exit 5
-    test -e $FRESHCLAM_CONF || exit 5
-fi
-
-# First reset status of this service
-rc_reset
-
-# Process request
-case "$1" in
-    start)
-        if [ $START_FRESHCLAM = 1 ]
-        then
-            echo -n "Starting ${FRESHCLAM_WHAT} ${FRESHCLAM_CONF}"
-            startproc $FRESHCLAM_SBIN --daemon --config-file=${FRESHCLAM_CONF}
-            rc_status -v
-        fi
-        echo -n "Starting ${WHAT} ${CONF} "
-        ## Start daemon with startproc(8). If this fails
-        ## the echo return value is set appropriate.
-        startproc $SBIN $CONF
-        # Remember status and be verbose
-        rc_status -v
-        ## start freshclam
-        
-    ;;
-    stop)
-        echo -n "Shutting down ${WHAT}"
-        ## Stop daemon with killproc(8) and if this fails
-        ## set echo the echo return value.
-        killproc -TERM $SBIN
-        # Remember status and be verbose
-        rc_status -v
-        if [ $START_FRESHCLAM = 1 ]
-        then
-            echo -n "Shutting down ${FRESHCLAM_WHAT}"
-            killproc -TERM $FRESHCLAM_SBIN
-            rc_status -v
-        fi
-    ;;
-    restart)
-        ## Stop the service and regardless of whether it was
-        ## running or not, start it again.
-        $0 stop
-        $0 start
-        # Remember status and be quiet
-        rc_status
-    ;;
-    status)
-        echo -n "Checking for ${WHAT} "
-        checkproc $SBIN
-        rc_status -v
-        if [ $START_FRESHCLAM = 1 ]
-        then
-            echo -n "Checking for ${FRESHCLAM_WHAT} "
-            checkproc $FRESHCLAM_SBIN
-            rc_status -v
-        fi
-    ;;
-
-    *)
-        echo "Usage: $0 {start|stop|status|restart}"
-        exit 1
-    ;;
-esac
-rc_exit
-### END
diff --git a/contrib/make-clamav-milter-conf.pl b/contrib/make-clamav-milter-conf.pl
deleted file mode 100644
index 9d6e34c..0000000
--- a/contrib/make-clamav-milter-conf.pl
+++ /dev/null
@@ -1,429 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use Getopt::Long qw(:config gnu_getopt);
-
-sub wwarn {
-	my $w = shift;
-	warn "WARNING: $w\n";
-}
-
-sub tosconf {
-	my ($cfg, $v) = @_;
-	if($v) {
-		my $sep = $v=~/ / ? '"' : '';
-		$v = "\n$cfg $sep$v$sep";
-	}
-	return $v;
-}
-
-my $notify = 0;
-my $black = 0;
-my $report = 0;
-my $debug = 0;
-my $sign = 0;
-my $broad = 0;
-my $forge = 0;
-my $sanity = 1;
-my $blackhole = 0;
-my $quarantine = 0;
-my $rate = 0;
-my $monitor = 0;
-my $oninfected = 'Reject';
-my $onfail = 'Defer';
-my @localnets = ();
-my $whitelist = '';
-my $config = '';
-my $chroot = '';
-my $pidfile = '';
-my $addheader = 1;
-my $tcpclamds = '';
-my $localclamd;
-
-GetOptions (
-	"from|a:s" => \$notify,
-	"bounce|b" => \$notify,
-	"headers|H" => \$notify,
-	"postmaster|p=s" => \$notify,
-	"postmaster-only|P" => \$notify,
-	"template-file|t=s" => \$notify,
-	"template-headers|1=s" => \$notify,
-	"quiet|q" => sub { $notify = 0 },
-	"dont-blacklist|K=s" => \$black,
-	"blacklist-time|k=i" => \$black,
-	"report-phish|r=s" => \$report,
-	"report-phish-false-positives|R=s" => \$report,
-	"debug-level|x=i" => \$debug,
-	"debug|D" => \$debug,
-	"sign|S" => \$sign,
-	"signature-file|F=s" => \$sign,
-	"broadcast|B=s" => \$broad,
-	"detect-forged-local-address|L" => \$forge,
-	"dont-sanitise|z" => sub { $sanity = 0 },
-	"black-hole-mode|2" => \$blackhole,
-	"quarantine|Q=s" => \$quarantine,
-	"quarantine-dir|U" => \$quarantine,
-	"max-children|m=i" => \$rate,
-	"dont-wait|w" => \$rate,
-	"timeout|T=i" => \$rate,
-	"freshclam-monitor|M=i" => \$monitor,
-	"external|e" => sub { },
-	"no-check-cf" => sub { },
-	"sendmail-cf|0=s" => sub { },
-	"advisory|A" => sub { $oninfected='Accept'; },
-	"noreject|N" => sub { $oninfected='Blackhole'; },
-	"dont-scan-on-error|d" => sub { $onfail = 'Accept'; },
-	"ignore|I=s" => \@localnets,
-	"local|l" => sub { @localnets = (); },
-	"force-scan|f" => sub { @localnets = (); },
-	"whitelist-file|W=s" => \$whitelist,
-	"config-file|c=s" => \$config,
-	"chroot|C=s" => \$chroot,
-	"pidfile|i=s" => \$pidfile,
-	"noxheader|n" => sub { $addheader = 0},
-	"outgoing|o" => sub { push(@localnets, 'localhost'); },
-	"server|s=s" => \$tcpclamds,
-) or die "huh?!";
-
-my %clamds = ();
-foreach (split(/:/, $tcpclamds)) {
-	$clamds{"tcp:$_:3310"}++;
-}
-
-my $user = '';
-my $supgrp = '';
-my $syslog = '';
-my $facility = '';
-my $tempdir = '';
-my $maxsize = '';
-
-if ($config) {
-	my $port = 0;
-	my $ip = '';
-	my $lsock = '';
-	open CFG, "<$chroot/$config" or die "failed to open clamd config file $config";
-	while (<CFG>) {
-		chomp;
-		$port = $1 if /^TCPSocket\s+(.*)$/;
-		$ip = $1 if /^TCPAddr\s+(.*)$/;
-		$lsock = $1 if /^LocalSocket\s+(.*)$/;
-		$user = $1 if /^User\s+(.*)$/;
-		$supgrp = $1 if /^AllowSupplementaryGroups\s+(.*)$/;
-		$syslog = $1 if /^LogSyslog\s+(.*)$/;
-		$facility = $1 if /^LogFacility\s+(.*)$/;
-		$tempdir = $1 if /^TemporaryDirectory\s+(.*)$/;
-		$maxsize = $1 if /^MaxFileSize\s+(.*)$/;
-	}
-	close(CFG);
-	if ($lsock) {
-		$clamds{"unix:$lsock"}++;
-	} elsif ($port) {
-		if($ip) {
-			$clamds{"tcp:$ip:$port"}++;
-		} else {
-			$clamds{"tcp:localhost:$port"}++;
-		}
-	}
-}
-
-die "FAIL: No socket provided" unless $ARGV[0];
-die "FAIL: Unable to determine clamd socket\n" unless scalar keys %clamds;
-
-wwarn "Notifications and bounces are no longer supported.
-As a result the following command line options cannot be converted into new config options:
- --from (-a)
- --bounce (-b)
- --headers (-H)
- --postmaster (-p)
- --postmaster-only (-P)
- --template-file (-t)
- --template-headers (-1)
-" if $notify;
-
-wwarn "Temporary blacklisting of ip addresses is no longer supported.
-As a result the following command line options cannot be converted into new config options:
- --dont-blacklist (-K)
- --blacklist-time (-k)
-" if $black;
-
-wwarn "Phising reports are no longer supported.
-As a result the following command line options cannot be converted into new config options:
- --report-phish (-r)
- --report-phish-false-positives (-R)
-" if $report; 
-
-wwarn "The options --debug (-D) and --debug-level (-x) are no longer supported.
-Please set LogVerbose to yes instead
-" if $debug;
-
-wwarn "Message scan signatures are no longer supported.
-As a result the following command line options cannot be converted into new config options:
- --sign (-S)
- --signature-file (-F)
-" if $sign;
-
-wwarn "Broadcasting is no longer supported\n" if $broad;
-
-wwarn "Forgery detection is no longer supported\n" if $forge;
-
-wwarn "Please be aware that email addresses are no longer checked for weird characters like '|' and ';'\n" if $sanity;
-
-wwarn "Blackhole mode is no longer available\nIf you have a lot users aliased to /dev/null you may want to whitelist them instead\n" if $blackhole;
-
-wwarn "Quarantine now achieved via native milter support\nPlease read more about it in the example config file\n" if $quarantine;
-
-wwarn "Rate limiting in the milter is no longer supported.
-As a result the following command line options cannot be converted into new config options:
- --max-children (-m)
- --dont-wait (-w)
- --timeout (-T)
-Please make use of the native Sendmail / Postfix rate limiting facilities
-" if $rate;
-
-wwarn "The option --freshclam-monitor (-M) only made sense in internal mode\nPlease configure freshclam to notify clamd about updates instead\n" if $monitor;
-
-wwarn "Your whitelist file path has been preserved, however please be aware that its syntax is changed\nInstead of a full email address you are now allowed to use regexes. See the example clamav-milter.conf file for more info.\n" if $whitelist;
-
-wwarn "Here is the auto generated config file. Please review:\n";
-
-my $mysock = tosconf('MilterSocket', $ARGV[0]);
-$chroot = tosconf('Chroot', $chroot);
-$pidfile = tosconf('PidFile', $pidfile);
-$oninfected = tosconf('OnInfected', $oninfected);
-$onfail = tosconf('OnFail', $onfail);
-$whitelist = tosconf('Whitelist', $whitelist);
-$addheader = $addheader ? "\nAddHeader Yes" : '';
-$user = tosconf('User', $user);
-$supgrp = $supgrp ? "\nAllowSupplementaryGroups Yes" : '';
-if ($syslog =~ /yes/i) {
-	$syslog = "LogSyslog yes";
-	$facility = tosconf('LogFacility', $facility);
-} else {
-	$syslog = '';
-	$facility = '';
-}
-$tempdir = tosconf('TemporaryDirectory', $tempdir);
-$maxsize = tosconf('MaxFileSize', $maxsize);
-
-print <<BLOCK1;
-##
-## Example config file for clamav-milter
-## (automatically generated by make-clamav-milter-conf.pl)
-##
-
-# Comment or remove the line below.
-Example
-
-
-##
-## Main options
-##
-
-# Define the interface through which we communicate with sendmail
-# This option is mandatory! Possible formats are:
-# [[unix|local]:]/path/to/file - to specify a unix domain socket
-# inet:port@[hostname|ip-address] - to specify an ipv4 socket
-# inet6:port@[hostname|ip-address] - to specify an ipv6 socket
-#
-# Default: no default
-#MilterSocket /tmp/clamav-milter.socket
-#MilterSocket inet:7357$mysock
-
-# Remove stale socket after unclean shutdown.
-#
-# Default: yes
-#FixStaleSocket yes
-
-# Run as another user (clamav-milter must be started by root for this option to work)
-#
-# Default: unset (don't drop privileges)
-#User clamav$user
-
-# Initialize supplementary group access (clamd must be started by root).
-#
-# Default: no
-#AllowSupplementaryGroups no$supgrp
-
-# Waiting for data from clamd will timeout after this time (seconds).
-# Value of 0 disables the timeout.
-#
-# Default: 120
-#ReadTimeout 300
-
-# Don't fork into background.
-#
-# Default: no
-#Foreground yes
-
-# Chroot to the specified directory.
-# Chrooting is performed just after reading the config file and before dropping privileges.
-#
-# Default: unset (don't chroot)
-#Chroot /newroot$chroot
-
-# This option allows you to save a process identifier of the listening
-# daemon (main thread).
-#
-# Default: disabled
-#PidFile /var/run/clamd.pid$pidfile
-
-# Optional path to the global temporary directory.
-# Default: system specific (usually /tmp or /var/tmp).
-#
-#TemporaryDirectory /var/tmp$tempdir
-
-##
-## Clamd options
-##
-
-# Define the clamd socket to connect to for scanning.
-# If not set (the default), clamav-milter uses internal mode.
-# This option is mandatory! Syntax:
-# ClamdSocket unix:path
-# ClamdSocket tcp:host:port
-# The first syntax specifies a local unix socket (needs an bsolute path) e.g.:
-#     ClamdSocket unix:/var/run/clamd/clamd.socket
-# The second syntax specifies a tcp local or remote tcp socket: the
-# host can be a hostname or an ip address; the ":port" field is only required
-# for IPv6 addresses, otherwise it defaults to 3310
-#     ClamdSocket tcp:192.168.0.1
-#
-# This option can be repeated several times with different sockets or even
-# with the same socket: clamd servers will be selected in a round-robin fashion.
-#
-# Default: no default
-#ClamdSocket tcp:scanner.mydomain:7357
-BLOCK1
-
-print "ClamdSocket \"$_\"\n" foreach (keys %clamds);
-print <<BLOCK2;
-
-
-##
-## Exclusions
-##
-
-# Messages originating from these hosts/networks will not be scanned
-# This option takes a host(name)/mask pair in CIRD notation and can be
-# repeated several times. If "/mask" is omitted, a host is assumed.
-# To specify a locally orignated, non-smtp, email use the keyword "local"
-#
-# Default: unset (scan everything regardless of the origin)
-#LocalNet local
-#LocalNet 192.168.0.0/24
-#LocalNet 1111:2222:3333::/48
-
-# This option specifies a file which contains a list of POSIX regular
-# expressions. Addresses (sent to or from - see below) matching these regexes
-# will not be scanned.  Optionally each line can start with the string "From:"
-# or "To:" (note: no whitespace after the colon) indicating if it is, 
-# respectively, the sender or recipient that is to be whitelisted.
-# If the field is missing, "To:" is assumed.
-# Lines starting with #, : or ! are ignored.
-#
-# Default unset (no exclusion applied)
-#Whitelist /etc/whitelisted_addresses$whitelist
-
-
-##
-## Actions
-##
-
-# The following group of options controls the delievery process under
-# different circumstances.
-# The following actions are available:
-# - Accept
-#   The message is accepted for delievery
-# - Reject
-#   Immediately refuse delievery (a 5xx error is returned to the peer)
-# - Defer
-#   Return a temporary failure message (4xx) to the peer
-# - Blackhole (not available for OnFail)
-#   Like accept but the message is sent to oblivion
-# - Quarantine (not available for OnFail)
-#   Like accept but message is quarantined instead of being deilievered
-#   In sendmail the quarantine queue can be examined via mailq -qQ
-#   For Postfix this causes the message to be accepted but placed on hold
-# 
-# Action to be performed on clean messages (mostly useful for testing)
-# Default Accept
-#OnClean Accept
-
-# Action to be performed on infected messages
-# Default: Quarantine
-#OnInfected Quarantine$oninfected
-
-# Action to be performed on error conditions (this includes failure to
-# allocate data structures, no scanners available, network timeouts,
-# unknown scanner replies and the like)
-# Default Defer
-#OnFail Defer$onfail
-
-# If this option is set to Yes, an "X-Virus-Scanned" and an "X-Virus-Status"
-# headers will be attached to each processed message, possibly replacing
-# existing headers. 
-# Default: No
-#AddHeader Yes$addheader
-
-
-##
-## Logging options
-##
-
-# Uncomment this option to enable logging.
-# LogFile must be writable for the user running daemon.
-# A full path is required.
-#
-# Default: disabled
-#LogFile /tmp/clamav-milter.log
-
-# By default the log file is locked for writing - the lock protects against
-# running clamav-milter multiple times.
-# This option disables log file locking.
-#
-# Default: no
-#LogFileUnlock yes
-
-# Maximum size of the log file.
-# Value of 0 disables the limit.
-# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
-# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size
-# in bytes just don't use modifiers.
-#
-# Default: 1M
-#LogFileMaxSize 2M
-
-# Log time with each message.
-#
-# Default: no
-#LogTime yes
-
-# Use system logger (can work together with LogFile).
-#
-# Default: no
-#LogSyslog yes$syslog
-
-# Specify the type of syslog messages - please refer to 'man syslog'
-# for facility names.
-#
-# Default: LOG_LOCAL6
-#LogFacility LOG_MAIL$facility
-
-# Enable verbose logging.
-#
-# Default: no
-#LogVerbose yes
-
-
-##
-## Limits
-##
-
-# Messages larger than this value won't be scanned.
-# Default: 25M
-#MaxFileSize 150M$maxsize
-BLOCK2
-
-
diff --git a/contrib/mpoolparse/mpoolparse.pl b/contrib/mpoolparse/mpoolparse.pl
deleted file mode 100644
index 70b1ad8..0000000
--- a/contrib/mpoolparse/mpoolparse.pl
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-my %frags = ();
-
-while (<>) {
-	chomp;
-	next unless /^LibClamAV Warning: [mc]alloc .* size (\d+) .*$/;
-	$frags{$1}++;
-}
-
-foreach (sort {$a<=>$b} (keys(%frags))) {
-	print "$_, /* ($frags{$_}) */\n";
-}
-
diff --git a/contrib/old-clamav-milter/INSTALL b/contrib/old-clamav-milter/INSTALL
deleted file mode 100644
index 0f3ead0..0000000
--- a/contrib/old-clamav-milter/INSTALL
+++ /dev/null
@@ -1,439 +0,0 @@
-1. BUILD INSTRUCTIONS
-
-A makefile was supplied with this which should have built the program. If it
-fails please let us know, and here are some hints for building on different
-platforms. You will need to set --enable-milter when running configure for
-the automatic build to work.
-
-Tested OK on Linux/x86 with gcc3.2.
-	cc -O3 -pedantic -Wuninitialized -Wall -pipe -mcpu=pentium -march=pentium -fomit-frame-pointer -ffast-math -finline-functions -funroll-loops clamav-milter.c -pthread -lmilter ../libclamav/.libs/libclamav.a ../clamd/cfgfile.o ../clamd/others.o
-
-Compiles OK on Linux/x86 with tcc 0.9.16, but fails to link errors with 'atexit'
-	tcc -g -b -lmilter -lpthread clamav-milter.c...
-
-Fails to compile on Linux/x86 with icc6.0 (complains about stdio.h...)
-	icc -O3 -tpp7 -xiMKW -ipo -parallel -i_dynamic -w2 clamav-milter.c...
-Fails to build on Linux/x86 with icc7.1 with -ipo (fails on libclamav.a - keeps saying run ranlib). Otherwise it builds and runs OK.
-	icc -O2 -tpp7 -xiMKW -parallel -i_dynamic -w2 -march=pentium4 -mcpu=pentium4 clamav-milter.c...
-
-Tested with Electric Fence 2.2.2, and the bounds checking C compiler from
-	http://sourceforge.net/projects/boundschecking/
-
-Compiles OK on Linux/ppc (YDL2.3) with gcc2.95.4. Needs -lsmutil to link.
-	cc -O3 -pedantic -Wuninitialized -Wall -pipe -fomit-frame-pointer -ffast-math -finline-functions -funroll-loop -pthread -lmilter ../libclamav/.libs/libclamav.a ../clamd/cfgfile.o ../clamd/others.o -lsmutil
-I haven't tested it further on this platform yet.
-YDL3.0 should compile out of the box
-
-Linux/sparc (Gentoo 2004.2) comes with a sendmail that doesn't support MILTER,
-so *before* running "configure --enable-milter", download from
-http://www.sendmail.org/ftp, then:
-	cd .../sendmail-source-directory
-	sh Build
-	make install
-	cd libmilter
-	make install
-
-Sendmail on MacOS/X (10.1) is provided without a development package so this
-can't be run "out of the box"
-
-Solaris 8 doesn't have milter support so clamav-milter won't work unless you
-rebuild sendmail from source.
-
-FreeBSD4.7 use /usr/local/bin/gcc30. GCC3.0 is an optional extra on
-FreeBSD. It comes with getopt.h which is handy. To link you need
--lgnugetopt
-	gcc30 -O3 -DCONFDIR=\"/usr/local/etc\" -I. -I.. -I../clamd -I../libclamav -pedantic -Wuninitialized -Wall -pipe -mcpu=pentium -march=pentium -fomit-frame-pointer -ffast-math -finline-functions -funroll-loops clamav-milter.c -pthread -lmilter ../libclamav/.libs/libclamav.a ../clamd/cfgfile.o ../clamd/others.o -lgnugetopt
-
-FreeBSD4.8: compiles out of the box with either gcc2.95 or gcc3
-
-NetBSD2.0: compiles out of the box
-
-OpenBSD3.4: the supplied sendmail does not come with Milter support.
-Do this *before* running configure (thanks for Per-Olov Sjöhol
-<peo_s at incedo.org> for these instructions).
-
-	echo WANT_LIBMILTER=1 > /etc/mk.conf
-	cd /usr/src/gnu/usr.sbin/sendmail
-	make depend
-	make
-	make install
-	kill -HUP `sed q /var/run/sendmail.pid`
-
-Then do this to make the milter headers available to clamav...
-(the libmilter.a file is already in the right place after the sendmail
-recompiles above)
-
-	cd /usr/include
-	ln -s ../src/gnu/usr.sbin/sendmail/include/libmilter libmilter
-
-Solaris 9 and FreeBSD5 have milter support in the supplied sendmail, but
-doesn't include libmilter so you can't develop milter applications on it.
-Go to sendmail.org, download the latest sendmail, cd to libmilter and
-"make install" there.
-
-Needs -lresolv on Solaris, for res_close().
-
-If, when building clamav-milter, you see the error
-	"undefined reference to smfi_opensocket",
-it means that your sendmail installation is broken. More specifically it means
-that your installed version of libmilter does not agree with your installed
-version of Sendmail. Naturally they must be the same. Check to see if you have
-more than one mfapi.h on your system; if you installed sendmail from source,
-did you remember to install libmilter at the same time? You can ensure that
-your Sendmail is correctly installed if you follow these instructions:
-	cd .../sendmail-source-directory
-	sh Build
-	make install
-	cd libmilter
-	make install
-
-2. INSTALLATION
-
-Install into /usr/local/sbin/clamav-milter.
-
-Ensure that your sendmail supports milters by running
-	/usr/lib/sendmail -d0 < /dev/null | fgrep MILTER
-or
-	/usr/sbin/sendmail -d0 < /dev/null | fgrep MILTER
-
-You should see something like:
-	MATCHGECOS MILTER MIME7TO8 MIME8TO7 NAMED_BIND NETINET NETINET6
-It doesn't matter exactly what you see, as long as the word MILTER is printed.
-
-If you see no output you MUST upgrade your sendmail.
-
-See http://www.nmt.edu/~wcolburn/sendmail-8.12.5/libmilter/docs/sample.html
-
-2.1 LINUX (RedHat, Fedora, YellowDog etc)
-
-Installations for RedHat Linux and it's derivatives such as YellowDog:
-	Ensure that you have the sendmail-devel RPM installed
-	Add to /etc/mail/sendmail.mc before the MAILER statement:
-	INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m;C:30s;E:10m')dnl
-	define(`confINPUT_MAIL_FILTERS', `clamav')
-
-	Note that the INPUT_MAIL_FILTER line must come before the
-		confINPUT_MAIL_FILTERS line.
-
-	Don't worry that the file /var/run/clamav/clmilter.sock doesn't exist,
-		clamav-milter will create it for you. However you will need
-		to create the directory /var/run/clamav (usually owned
-		by user clamav, mode 700).
-
-	Check entry in /usr/local/etc/clamd.conf of the form:
-	LocalSocket /var/run/clamav/clamd.sock
-
-	If you already have a filter (such as spamassassin-milter from
-	http://savannah.nongnu.org/projects/spamass-milt) add it thus:
-	INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m')dnl
-	INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m')
-	define(`confINPUT_MAIL_FILTERS', `spamassassin,clamav')dnl
-
-	mkdir /var/run/clamav
-	chown clamav /var/run/clamav	(if you use User clamav in clamd.conf)
-	chmod 700 /var/run/clamav
-
-	Where /var/run/spamass.sock is the location of the spamass-milt
-	socket file (on some systems it is in /var/run/sendmail/spamass.sock).
-
-2.2 LINUX (Debian)
-
-Installations for Debian Linux:
-	As above for RedHat, except that you need the libmilter-dev package:
-		apt-get install libmilter-dev
-	To use TCPwrappers you need to:
-		apt-get install libwrap0-dev
-
-2.3 FreeBSD
-
-Installations for FreeBSD5 (may be true for other BSDs)
-	Add to /etc/mail/freebsd.mc:
-	INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m')dnl
-	define(`confINPUT_MAIL_FILTERS', `clamav')
-
-	Check entry in /usr/local/etc/clamd.conf of the form:
-	LocalSocket /var/run/clamav/clamd.sock
-
-	If you already have a filter (such as spamassassin-milter from
-	http://savannah.nongnu.org/projects/spamass-milt) add it thus:
-	INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m')dnl
-	INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m')
-	define(`confINPUT_MAIL_FILTERS', `spamassassin,clamav')dnl
-
-	mkdir /var/run/clamav
-	chown clamav /var/run/clamav	(if you use User clamav in clamd.conf)
-	chmod 700 /var/run/clamav
-
-	Where /var/run/spamass.sock is the location of the spamass-milt
-	socket file (on some systems it is in /var/run/sendmail/spamass.sock).
-
-FreeBSD5.3 sendmail comes without libmilter support. You can upgrade by
-	cd /usr/ports/mail/sendmail
-	make install
-
-This may overwrite your existing sendmail configuration, so ensure
-that you back up first.
-
-You should have received a script to install into /etc/rc.d as /etc/rc.d/clamav
-with this software. Add to /etc/rc.conf:
-	clamd_enable="YES"
-	clamav_milter_enable="YES"
-	clamav_milter_flags="--max-children=2 --dont-wait --timeout=0 -P local:/var/run/clamav/clmilter.sock --pidfile=/var/run/clamav/clamav-milter.pid --quarantine-dir=/var/run/clamav/quarantine"
-
-2.4 Solaris 10
-
-Solaris 10 should install out of the box. Edit /etc/mail/cf/cf/main.mc adding
-the line:
-	INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clamav-milter, F=, T=S:4m;R:4m')dnl
-Then:
-	cp /etc/mail/cf/cf/main.cf /etc/mail/main.cf
-	/usr/local/sbin/clamav-milter local:/var/run/clamav/clamav-milter
-	mkdir /var/run/clamav
-	chown clamav /var/run/clamav	(if you use User clamav in clamd.conf)
-	chmod 700 /var/run/clamav
-
-You should have received a script to install into /etc/init.d as
-/etc/init.d/clamav-milter. Then:
-
-	chmod 755 /etc/init.d/clamav-milter
-	cd /etc
-	ln init.d/clamav-milter rc2.d/S90clamav-milter
-	ln init.d/clamav-milter rc0.d/K90clamav-milter
-	/etc/init.d/clamav-milter start
-	/etc/init.d/sendmail restart
-
-2.5 OpenBSD4.1:
-
-OpenBSD4.1 should install out of the box.
-Edit <your .mc file>, or if you have none: cd into /usr/share/sendmail/cf,
-copy openbsd-proto.mc custom.mc, edit custom.mc adding:
-	INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clamav-milter, F=, T=S:4m;R:4m')dnl
-Then run
-	m4 ../m4/cf.m4 custom.mc >/etc/mail/localhost.cf
-and finally restart sendmail by sending it a SIGHUP
-
-2.6 General Installation Issues
-
-You may find INPUT_MAIL_FILTERS is not needed on your machine, however it
-is recommended by the Sendmail documentation and I recommend going along
-with that.
-
-If you see an unsafe socket error from sendmail, it means that the permissions
-of the /var/run/clamav directory are too open; check you have correctly run
-chown and chmod. It may also mean that clamav-milter hasn't started, run
-ps and check your logs.
-
-The above example shows clamav-milter, clamd and sendmail all on the
-same machine, however using TCP they may reside on different machines,
-indeed clamav-milter is capable of talking to multiple clamds for redundancy
-and load balancing. An alternative load balancer is PEN (http://siag.nu/pen/).
-
-I suggest putting SpamAssassin first since you're more likely to get spam
-than a virus/worm sent to you.
-
-Add to /etc/sysconfig/clamav-milter
-	CLAMAV_FLAGS="local:/var/run/clamav/clmilter.sock"
-or if clamd is on a different machine
-	CLAMAV_FLAGS="--server=192.168.1.9 local:/var/run/clamav/clmilter.sock"
-
-If you want clamav-milter to listen on TCP for communication with sendmail,
-for example if they are on different machines use inet:<port>.
-On machine A (running sendmail) you would have in sendmail.mc:
-	INPUT_MAIL_FILTER(`clamav', `S=inet:3311 at machineb, F=T, T=S:4m;R:4m')dnl
-On machine B (running clamav-milter) you would start up clamav-milter thus:
-	clamav-milter inet:3311
-
-You should have received a script to put into /etc/init.d with this software.
-
-You should always start clamd before clamav-milter.
-
-You may also think about the F= entry in sendmail.mc, since it tells sendmail
-what to do with emails if clamav-milter is not running. Setting F=T will tell
-the remote end to resend later (temporary failure), setting F=R will reject
-the email (permanent failure) and setting F= will pass the email through as
-though clamav-milter were not installed, in this case you should warn your
-users that emails are not being scanned. We recommend setting F=T.
-
-You may wish to experiment with the T= entry which governs timeout options. You
-MUST set some type of timeout or a malicious client could cause a Denial of
-Service attack by keeping your clamav-milter threads alive. The types of
-timeout are C (time for clamav-milter to acknowledge to sendmail that it
-has accepted a new connection), S (timeout for sending information from sendmail
-to clamav-milter), R (timeout for sendmail reading a reply from clamav-milter
-when it has been sent some information) and E (timeout for clamav-milter to
-handle the end-of-message request, this needs to be high enough to scan the
-largest file that you will receive since it is at this stage that the file is
-scanned, but short enough to ensure that a DoS can't occur when lots of scans
-are requested). The important entries for clamav-milter are C and E (both
-default to 5 minutes).
-
-WARNING: When running on internal mode (--external is NOT used), clamav-milter
-will need to wait for all connections to stop before it can reload the database
-after running freshclam. It is therefore important that NO timeouts in
-sendmail.cf are set too high or worse still turned off, otherwise clamav-milter
-can wait a long time, perhaps indefinately, while waiting for the system to
-quieten down. The same goes for disabling StreamMaxLength, since receiving a
-very large email to be scanned may take a long time. We advise setting
-StreamMaxLength to 1M.
-
-Don't forget to rebuild sendmail.cf after modifying sendmail.mc. You will
-need to restart sendmail after rebuilding sendmail.cf and starting clamd and
-clamav-milter.
-
-As with all software it is wise to ensure that clamav-milter has the least
-privileges it needs to run. So don't run it as root and don't store the sockets in a directory that can be written by everyone. For example ensure that /var/run
-is owned and writeable only by root and add entries for 'User' and
-'FixStaleSocket' in clamd.conf.
-
-When using UNIX domain sockets via the LocalSocket option of clamd.conf,
-we recommend that you use the --quarantine-dir option since that may improve
-performance.
-
-If you wish to send a warning when a message is blocked, clamav-milter MUST be
-able to call sendmail, for example on a Fedora Linux system:
-
-	# ls -lL /usr/lib/sendmail
-	-rwxr-sr-x  1 root smmsp 732356 Sep  1 11:16 /usr/lib/sendmail
-
-To test that your clamAV system is now intercepting viruses, visit
-http://www.testvirus.org
-
-If, under heavy strain on Linux, you see the message
-	thread_create() failed: 12, abort
-appearing in a log file, you will need to increase the number of threads on
-your system (/proc/sys/kernel/threads-max), or decrease the value of
---max-children.
-
-Clamav-milter performs DNS look ups, if you wish to tweak its timeouts
-see resolv.conf(5).
-
-2.7 Postfix
-
-Clamav-milter has only been designed to work with Sendmail. I understand that
-modern versions of Postfix have milter support, and I've heard that
-Clamav-milter runs with these versions of Postfix, however it is not supported
-with that software and I do not know how much functionality works.
-
-To start clamav-milter:
-
-	# clamav-milter --sendmail-cf= --max-children=2 \
-		--timeout=0 --pidfile=/var/run/clamav/clamav-milter \
-		local:/var/spool/postfix/clamav/clamav-milter
-	# chown clamav:postfix /var/spool/postfix/clamav/clamav-milter
-	# chmod g+w /var/spool/postfix/clamav/clmilter
-
-In /etc/postfix/main.cf set:
-	smtpd_milters = unix:clamav/clamav-milter
-	non_smtpd_milters = unix:clamav/clamav-milter
-
-3. CHANGE HISTORY
-
-See ../ChangeLog
-
-4. INTERNATIONALISATION
-
-The .po file was created with the command
-	xgettext --msgid-bugs-address=bugs at clamav.net --copyright-holder=njh at bandsman.co.uk -L c -d clamav-milter -k_ clamav-milter.c
-
-If you're interested in helping to translate this program please drop the
-author an e-mail.
-
-5. BUG REPORTS
-
-Please send bug reports and/or comments to Nigel Horne <njh at clamav.net> or
-bugs at clamav.net.
-
-Various tips will go here, for example
-	define(`confMILTER_LOG_LEVEL',`22')
-Running in the foreground, valgrind, LogSyslog, LogVerbose, LogFile etc.
-
-5.1. Patches
-
-Patches are welcome, but they must be against the latest CVS version and adhere
-to the coding style of clamav-milter. Coding style is religious, everyone
-believes theirs is great and all others are rubbish.
-
-This is my coding style, live with it. You don't want me in a bad mood because
-I can't read your code when I'm deciding if your code should be incorporated.
-
-Most of this style is based on K&R.
-
-Use the tab key, not space key, to indent.
-
-Except for functions, braces always go on the same line as the condition.
-
-Don't leave to chance, or your knowledge of precedence, use brackets to
-highten the readability.
-
-Choose variable names sensibly, don't use Hungarian style.
-
-The code is ANSI C, not C++, remember that when thinking of comment formats,
-location of declarations, etc.
-
-Patches which use 'goto' will never, ever, be accepted.
-
-Use the design of your code as comments.
-
-Test your patches and document the tests when submitting, e.g. different
-hardware, operating systems, test tools such as valgrind, compilers (gcc, icc,
-Sun's cc).
-
-Function names appear at the start of lines (I use ctags).
-
-Document your changes. If you add, remove, or change functionality you will
-need to update the manual page and possibly the usage message as well.
-
-6. CHROOT JAIL
-
-The instructions will differ for you, but these will give you an idea.
-You will have to do a lot of fiddling if you want notifications to work,
-since clamav-milter calls sendmail to handle the notifications and sendmail
-will run of out the same jail. I've not disabled the notifications, but I
-may in the future - for the moment handling notifications in the jail is an
-excercise for the reader. I've put in a symbolic link to sendmail, but I
-suspect it should be a real copy.
-
-	mkdir /var/run/clamav-root
-	chown clamav:clamav /var/run/clamav-root
-	chmod 750 /var/run/clamav-root
-	cd /var/run/clamav-root
-	mkdir var
-	mkdir var/tmp
-	ln -s var/tmp .
-	mkdir var/log
-	cd var/log
-	ln -s ../../../../../var/log/clamav .
-	cd ..
-	mkdir run
-	mkdir run/clamav
-	chown clamav:clamav run/clamav
-	cd ..
-	mkdir usr
-	mkdir usr/local
-	mkdir usr/local/share
-	ln -s ../../../../../../usr/local/share/clamav .
-	mkdir usr/lib
-	cd usr/lib
-	ln -s ../../../../../usr/lib/sendmail .
-	cd ../..
-	mkdir dev
-	cd dev
-	mknod null c 1 3
-	chown clamav:clamav null
-
-In sendmail.mc:
-INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav-root/var/run/clamav/clmilter.sock, F=T, T=S:4m;R:4m;C:30s;E:10m')dnl
-
-When starting clamav-milter use options such as (notice that the location
-of clmilter.sock is different in sendmail.mc than the location clamav-milter
-expects to see it)
-	--chroot=/var/run/clamav-root --max-children=3 -P --pidfile=/var/run/clamav/clamav-milter.pid --blacklist=60 --black-hole-mode local:/var/run/clamav/clmilter.sock
-
-You may need to modify your shutdown script to look for clamav-milter.pid
-in /var/run/clamav-root/var/run/clamav/clamav-milter.pid
-
-7. TODO
-
-There are several ideas marked as TODO in the source code. If anyone has
-any other suggestions please feel free to contact me. To avoid disappointment
-always contact me before undertaking any work.
diff --git a/contrib/old-clamav-milter/Makefile.am b/contrib/old-clamav-milter/Makefile.am
deleted file mode 100644
index 4a9eda3..0000000
--- a/contrib/old-clamav-milter/Makefile.am
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-#  Copyright (C) 2003 - 2005 Tomasz Kojm <tkojm at clamav.net>
-#
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation; either version 2 of the License, or
-#  (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA 02110-1301, USA.
-
-# FIXME: check automake for 'and' (&&)
-if BUILD_CLAMD
-if HAVE_MILTER
-
-sbin_PROGRAMS = clamav-milter
-
-clamav_milter_SOURCES = \
-    $(top_srcdir)/shared/cfgparser.c \
-    $(top_srcdir)/shared/cfgparser.h \
-    $(top_srcdir)/shared/output.c \
-    $(top_srcdir)/shared/output.h \
-    $(top_srcdir)/shared/getopt.c \
-    $(top_srcdir)/shared/getopt.h \
-    $(top_srcdir)/shared/misc.c \
-    $(top_srcdir)/shared/misc.h \
-    $(top_srcdir)/shared/network.c \
-    $(top_srcdir)/shared/network.h \
-    clamav-milter.c
-man_MANS = $(top_builddir)/docs/man/clamav-milter.8
-
-endif
-endif
-
-LIBS = $(top_builddir)/libclamav/libclamav.la @CLAMAV_MILTER_LIBS@ @THREAD_LIBS@
-AM_CPPFLAGS = -I$(top_srcdir)/clamd -I$(top_srcdir)/libclamav -I$(top_srcdir)/shared -I$(top_srcdir)
-EXTRA_DIST = clamav-milter.c INSTALL
-CLEANFILES=*.gcda *.gcno
-CFLAGS=`echo "@CFLAGS@" | sed -e 's/-Werror[^-]//'`
-
-
diff --git a/contrib/old-clamav-milter/Makefile.in b/contrib/old-clamav-milter/Makefile.in
deleted file mode 100644
index ca7c717..0000000
--- a/contrib/old-clamav-milter/Makefile.in
+++ /dev/null
@@ -1,705 +0,0 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-#
-#  Copyright (C) 2003 - 2005 Tomasz Kojm <tkojm at clamav.net>
-#
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation; either version 2 of the License, or
-#  (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA 02110-1301, USA.
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-target_triplet = @target@
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE at sbin_PROGRAMS =  \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@	clamav-milter$(EXEEXT)
-subdir = clamav-milter
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in INSTALL
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \
-	$(top_srcdir)/m4/argz.m4 $(top_srcdir)/m4/fdpassing.m4 \
-	$(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltdl.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/mmap_private.m4 $(top_srcdir)/m4/resolv.m4 \
-	$(top_srcdir)/configure.in
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/clamav-config.h
-CONFIG_CLEAN_FILES =
-am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
-sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-PROGRAMS = $(sbin_PROGRAMS)
-am__clamav_milter_SOURCES_DIST = $(top_srcdir)/shared/cfgparser.c \
-	$(top_srcdir)/shared/cfgparser.h $(top_srcdir)/shared/output.c \
-	$(top_srcdir)/shared/output.h $(top_srcdir)/shared/getopt.c \
-	$(top_srcdir)/shared/getopt.h $(top_srcdir)/shared/misc.c \
-	$(top_srcdir)/shared/misc.h $(top_srcdir)/shared/network.c \
-	$(top_srcdir)/shared/network.h clamav-milter.c
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE at am_clamav_milter_OBJECTS =  \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@	cfgparser.$(OBJEXT) \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@	output.$(OBJEXT) \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@	getopt.$(OBJEXT) \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@	misc.$(OBJEXT) \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@	network.$(OBJEXT) \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@	clamav-milter.$(OBJEXT)
-clamav_milter_OBJECTS = $(am_clamav_milter_OBJECTS)
-clamav_milter_LDADD = $(LDADD)
-DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/config/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-	$(LDFLAGS) -o $@
-SOURCES = $(clamav_milter_SOURCES)
-DIST_SOURCES = $(am__clamav_milter_SOURCES_DIST)
-man8dir = $(mandir)/man8
-NROFF = nroff
-MANS = $(man_MANS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-ARGZ_H = @ARGZ_H@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFGDIR = @CFGDIR@
-CFLAGS = `echo "@CFLAGS@" | sed -e 's/-Werror[^-]//'`
-CHECK_CPPFLAGS = @CHECK_CPPFLAGS@
-CHECK_LIBS = @CHECK_LIBS@
-CLAMAVGROUP = @CLAMAVGROUP@
-CLAMAVUSER = @CLAMAVUSER@
-CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
-CLAMD_LIBS = @CLAMD_LIBS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DBDIR = @DBDIR@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-FRESHCLAM_LIBS = @FRESHCLAM_LIBS@
-GCOV = @GCOV@
-GENHTML = @GENHTML@
-GETENT = @GETENT@
-GPERF = @GPERF@
-GREP = @GREP@
-HAVE_LIBGMP = @HAVE_LIBGMP@
-INCLTDL = @INCLTDL@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LCOV = @LCOV@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBADD_DL = @LIBADD_DL@
-LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
-LIBADD_DLOPEN = @LIBADD_DLOPEN@
-LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
-LIBBZ2 = @LIBBZ2@
-LIBBZ2_PREFIX = @LIBBZ2_PREFIX@
-LIBCLAMAV_LIBS = @LIBCLAMAV_LIBS@
-LIBCLAMAV_VERSION = @LIBCLAMAV_VERSION@
-LIBGMP = @LIBGMP@
-LIBGMP_PREFIX = @LIBGMP_PREFIX@
-LIBLTDL = @LIBLTDL@
-LIBOBJS = @LIBOBJS@
-LIBS = $(top_builddir)/libclamav/libclamav.la @CLAMAV_MILTER_LIBS@ @THREAD_LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTDLDEPS = @LTDLDEPS@
-LTDLINCL = @LTDLINCL@
-LTDLOPEN = @LTDLOPEN@
-LTLIBBZ2 = @LTLIBBZ2@
-LTLIBGMP = @LTLIBGMP@
-LTLIBOBJS = @LTLIBOBJS@
-LT_CONFIG_H = @LT_CONFIG_H@
-LT_DLLOADERS = @LT_DLLOADERS@
-LT_DLPREOPEN = @LT_DLPREOPEN@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-THREAD_LIBS = @THREAD_LIBS@
-TH_SAFE = @TH_SAFE@
-VERSION = @VERSION@
-VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-ltdl_LIBOBJS = @ltdl_LIBOBJS@
-ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sendmailprog = @sendmailprog@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sys_symbol_underscore = @sys_symbol_underscore@
-sysconfdir = @sysconfdir@
-target = @target@
-target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE at clamav_milter_SOURCES = \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/cfgparser.c \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/cfgparser.h \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/output.c \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/output.h \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/getopt.c \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/getopt.h \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/misc.c \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/misc.h \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/network.c \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    $(top_srcdir)/shared/network.h \
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@    clamav-milter.c
-
- at BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE at man_MANS = $(top_builddir)/docs/man/clamav-milter.8
-AM_CPPFLAGS = -I$(top_srcdir)/clamd -I$(top_srcdir)/libclamav -I$(top_srcdir)/shared -I$(top_srcdir)
-EXTRA_DIST = clamav-milter.c INSTALL
-CLEANFILES = *.gcda *.gcno
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-		&& exit 0; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  clamav-milter/Makefile'; \
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign  clamav-milter/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-sbinPROGRAMS: $(sbin_PROGRAMS)
-	@$(NORMAL_INSTALL)
-	test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
-	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
-	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
-	  if test -f $$p \
-	     || test -f $$p1 \
-	  ; then \
-	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-	   echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-	   $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
-	  else :; fi; \
-	done
-
-uninstall-sbinPROGRAMS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
-	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
-	  echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(sbindir)/$$f"; \
-	done
-
-clean-sbinPROGRAMS:
-	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
-	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
-	  echo " rm -f $$p $$f"; \
-	  rm -f $$p $$f ; \
-	done
-
-installcheck-sbinPROGRAMS: $(sbin_PROGRAMS)
-	bad=0; pid=$$$$; list="$(sbin_PROGRAMS)"; for p in $$list; do \
-	  case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \
-	   *" $$p "* | *" $(srcdir)/$$p "*) continue;; \
-	  esac; \
-	  f=`echo "$$p" | \
-	     sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
-	  for opt in --help --version; do \
-	    if "$(DESTDIR)$(sbindir)/$$f" $$opt >c$${pid}_.out \
-	         2>c$${pid}_.err </dev/null \
-		 && test -n "`cat c$${pid}_.out`" \
-		 && test -z "`cat c$${pid}_.err`"; then :; \
-	    else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
-	  done; \
-	done; rm -f c$${pid}_.???; exit $$bad
-clamav-milter$(EXEEXT): $(clamav_milter_OBJECTS) $(clamav_milter_DEPENDENCIES) 
-	@rm -f clamav-milter$(EXEEXT)
-	$(LINK) $(clamav_milter_OBJECTS) $(clamav_milter_LDADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfgparser.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/clamav-milter.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/getopt.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/misc.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/network.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/output.Po at am__quote@
-
-.c.o:
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(COMPILE) -c $<
-
-.c.obj:
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
- at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
-
-cfgparser.o: $(top_srcdir)/shared/cfgparser.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cfgparser.o -MD -MP -MF $(DEPDIR)/cfgparser.Tpo -c -o cfgparser.o `test -f '$(top_srcdir)/shared/cfgparser.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/cfgparser.c
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/cfgparser.Tpo $(DEPDIR)/cfgparser.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/cfgparser.c' object='cfgparser.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cfgparser.o `test -f '$(top_srcdir)/shared/cfgparser.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/cfgparser.c
-
-cfgparser.obj: $(top_srcdir)/shared/cfgparser.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cfgparser.obj -MD -MP -MF $(DEPDIR)/cfgparser.Tpo -c -o cfgparser.obj `if test -f '$(top_srcdir)/shared/cfgparser.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/cfgparser.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/cfgparser.c'; fi`
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/cfgparser.Tpo $(DEPDIR)/cfgparser.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/cfgparser.c' object='cfgparser.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cfgparser.obj `if test -f '$(top_srcdir)/shared/cfgparser.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/cfgparser.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/cfgparser.c'; fi`
-
-output.o: $(top_srcdir)/shared/output.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT output.o -MD -MP -MF $(DEPDIR)/output.Tpo -c -o output.o `test -f '$(top_srcdir)/shared/output.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/output.c
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/output.Tpo $(DEPDIR)/output.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/output.c' object='output.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o output.o `test -f '$(top_srcdir)/shared/output.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/output.c
-
-output.obj: $(top_srcdir)/shared/output.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT output.obj -MD -MP -MF $(DEPDIR)/output.Tpo -c -o output.obj `if test -f '$(top_srcdir)/shared/output.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/output.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/output.c'; fi`
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/output.Tpo $(DEPDIR)/output.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/output.c' object='output.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o output.obj `if test -f '$(top_srcdir)/shared/output.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/output.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/output.c'; fi`
-
-getopt.o: $(top_srcdir)/shared/getopt.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getopt.o -MD -MP -MF $(DEPDIR)/getopt.Tpo -c -o getopt.o `test -f '$(top_srcdir)/shared/getopt.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/getopt.c
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/getopt.Tpo $(DEPDIR)/getopt.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/getopt.c' object='getopt.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getopt.o `test -f '$(top_srcdir)/shared/getopt.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/getopt.c
-
-getopt.obj: $(top_srcdir)/shared/getopt.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getopt.obj -MD -MP -MF $(DEPDIR)/getopt.Tpo -c -o getopt.obj `if test -f '$(top_srcdir)/shared/getopt.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/getopt.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/getopt.c'; fi`
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/getopt.Tpo $(DEPDIR)/getopt.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/getopt.c' object='getopt.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getopt.obj `if test -f '$(top_srcdir)/shared/getopt.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/getopt.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/getopt.c'; fi`
-
-misc.o: $(top_srcdir)/shared/misc.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT misc.o -MD -MP -MF $(DEPDIR)/misc.Tpo -c -o misc.o `test -f '$(top_srcdir)/shared/misc.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/misc.c
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/misc.Tpo $(DEPDIR)/misc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/misc.c' object='misc.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o misc.o `test -f '$(top_srcdir)/shared/misc.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/misc.c
-
-misc.obj: $(top_srcdir)/shared/misc.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT misc.obj -MD -MP -MF $(DEPDIR)/misc.Tpo -c -o misc.obj `if test -f '$(top_srcdir)/shared/misc.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/misc.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/misc.c'; fi`
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/misc.Tpo $(DEPDIR)/misc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/misc.c' object='misc.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o misc.obj `if test -f '$(top_srcdir)/shared/misc.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/misc.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/misc.c'; fi`
-
-network.o: $(top_srcdir)/shared/network.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT network.o -MD -MP -MF $(DEPDIR)/network.Tpo -c -o network.o `test -f '$(top_srcdir)/shared/network.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/network.c
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/network.Tpo $(DEPDIR)/network.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/network.c' object='network.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o network.o `test -f '$(top_srcdir)/shared/network.c' || echo '$(srcdir)/'`$(top_srcdir)/shared/network.c
-
-network.obj: $(top_srcdir)/shared/network.c
- at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT network.obj -MD -MP -MF $(DEPDIR)/network.Tpo -c -o network.obj `if test -f '$(top_srcdir)/shared/network.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/network.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/network.c'; fi`
- at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/network.Tpo $(DEPDIR)/network.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/shared/network.c' object='network.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o network.obj `if test -f '$(top_srcdir)/shared/network.c'; then $(CYGPATH_W) '$(top_srcdir)/shared/network.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/shared/network.c'; fi`
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-install-man8: $(man8_MANS) $(man_MANS)
-	@$(NORMAL_INSTALL)
-	test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
-	@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
-	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
-	for i in $$l2; do \
-	  case "$$i" in \
-	    *.8*) list="$$list $$i" ;; \
-	  esac; \
-	done; \
-	for i in $$list; do \
-	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
-	  else file=$$i; fi; \
-	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
-	  case "$$ext" in \
-	    8*) ;; \
-	    *) ext='8' ;; \
-	  esac; \
-	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
-	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
-	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
-	  echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
-	  $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
-	done
-uninstall-man8:
-	@$(NORMAL_UNINSTALL)
-	@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
-	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
-	for i in $$l2; do \
-	  case "$$i" in \
-	    *.8*) list="$$list $$i" ;; \
-	  esac; \
-	done; \
-	for i in $$list; do \
-	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
-	  case "$$ext" in \
-	    8*) ;; \
-	    *) ext='8' ;; \
-	  esac; \
-	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
-	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
-	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
-	  echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
-	  rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
-	done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(PROGRAMS) $(MANS)
-installdirs:
-	for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
-	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
-	mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-man
-
-install-dvi: install-dvi-am
-
-install-exec-am: install-sbinPROGRAMS
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man: install-man8
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am: installcheck-sbinPROGRAMS
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-man uninstall-sbinPROGRAMS
-
-uninstall-man: uninstall-man8
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-sbinPROGRAMS ctags distclean \
-	distclean-compile distclean-generic distclean-libtool \
-	distclean-tags distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-dvi \
-	install-dvi-am install-exec install-exec-am install-html \
-	install-html-am install-info install-info-am install-man \
-	install-man8 install-pdf install-pdf-am install-ps \
-	install-ps-am install-sbinPROGRAMS install-strip installcheck \
-	installcheck-am installcheck-sbinPROGRAMS installdirs \
-	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-	pdf pdf-am ps ps-am tags uninstall uninstall-am uninstall-man \
-	uninstall-man8 uninstall-sbinPROGRAMS
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/contrib/old-clamav-milter/clamav-milter.c b/contrib/old-clamav-milter/clamav-milter.c
deleted file mode 100644
index dc69995..0000000
--- a/contrib/old-clamav-milter/clamav-milter.c
+++ /dev/null
@@ -1,7039 +0,0 @@
-/*
- * clamav-milter.c
- *	.../clamav-milter/clamav-milter.c
- *
- *  Copyright (C) 2003-2007 Nigel Horne <njh at bandsman.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- *  MA 02110-1301, USA.
- *
- * Install into /usr/local/sbin/clamav-milter
- * See http://www.elandsys.com/resources/sendmail/libmilter/overview.html
- *
- * For installation instructions see the file INSTALL that came with this file
- *
- * NOTE: first character of strings to logg():
- *	! Error
- *	^ Warning
- *	* Verbose
- *	# Info, but not logged in foreground
- *	Default Info
- */
-static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.312 2007/02/12 22:24:21 njh Exp $";
-
-#if HAVE_CONFIG_H
-#include "clamav-config.h"
-#endif
-
-#include "cfgparser.h"
-#include "target.h"
-#include "str.h"
-#include "../libclamav/others.h"
-#include "output.h"
-#include "clamav.h"
-#include "table.h"
-#include "network.h"
-#include "misc.h"
-
-#include <stdio.h>
-#include <sysexits.h>
-#ifdef	HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#if	HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#if	HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#if	HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#include <sys/wait.h>
-#include <assert.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#include <arpa/inet.h>
-#include <sys/un.h>
-#include <stdarg.h>
-#include <errno.h>
-#if	HAVE_LIBMILTER_MFAPI_H
-#include <libmilter/mfapi.h>
-#endif
-#include <pthread.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <grp.h>
-#if	HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#if	HAVE_RESOLV_H
-#include <arpa/nameser.h>	/* for HEADER */
-#include <resolv.h>
-#endif
-#ifdef	HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <ctype.h>
-
-#if HAVE_MMAP
-#if HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#else /* HAVE_SYS_MMAN_H */
-#undef HAVE_MMAP
-#endif
-#endif
-
-#define NONBLOCK_SELECT_MAX_FAILURES	3
-#define NONBLOCK_MAX_ATTEMPTS	10
-#define	CONNECT_TIMEOUT	5	/* Allow 5 seconds to connect */
-
-#ifdef	C_LINUX
-#include <sys/sendfile.h>	/* FIXME: use sendfile on BSD not Linux */
-#include <libintl.h>
-#include <locale.h>
-
-#define	gettext_noop(s)	s
-#define	_(s)	gettext(s)
-#define	N_(s)	gettext_noop(s)
-
-#else
-
-#define	_(s)	s
-#define	N_(s)	s
-
-#endif
-
-#ifdef	USE_SYSLOG
-#include <syslog.h>
-#endif
-
-#ifdef	WITH_TCPWRAP
-#if	HAVE_TCPD_H
-#include <tcpd.h>
-#endif
-
-int	allow_severity = LOG_DEBUG;
-int	deny_severity = LOG_NOTICE;
-#endif
-
-#ifdef	CL_DEBUG
-static	char	console[] = "/dev/console";
-#endif
-
-#if defined(CL_DEBUG) && defined(C_LINUX)
-#include <sys/resource.h>
-#endif
-
-#define _GNU_SOURCE
-#include <getopt.h>
-
-#ifndef	SENDMAIL_BIN
-#define	SENDMAIL_BIN	"/usr/lib/sendmail"
-#endif
-
-#ifndef HAVE_IN_PORT_T
-typedef	unsigned short	in_port_t;
-#endif
-
-#ifndef	HAVE_IN_ADDR_T
-typedef	unsigned int	in_addr_t;
-#endif
-
-#ifndef	INET6_ADDRSTRLEN
-#ifdef	AF_INET6
-#define	INET6_ADDRSTRLEN	40
-#else
-#define	INET6_ADDRSTRLEN	16
-#endif
-#endif
-
-#ifndef	EX_CONFIG	/* HP-UX */
-#define	EX_CONFIG	78
-#endif
-
-#define	VERSION_LENGTH	128
-#define	DEFAULT_TIMEOUT	120
-
-#define	NTRIES	5	/* How many times we try to connect to a clamd */
-
-/*#define	SESSION*/
-		/* Keep one command connexion open to clamd, otherwise a new
-		 * command connexion is created for each new email
-		 *
-		 * FIXME: When SESSIONS are open, freshclam can hang when
-		 *	notfying clamd of an update. This is most likely to be a
-		 *	problem with the implementation of SESSIONS on clamd.
-		 *	The problem seems worst on BSD.
-		 *
-		 * Note that clamd is buggy and can hang or even crash if you
-		 *	send SESSION command so be aware
-		 */
-
-/*
- * TODO: optional: xmessage on console when virus stopped (SNMP would be real nice!)
- *	Having said that, with LogSysLog you can (on Linux) configure the system
- *	to get messages on the system console, see syslog.conf(5), also you
- *	can use wall(1) in the VirusEvent entry in clamd.conf
- * TODO: Decide action (bounce, discard, reject etc.) based on the virus
- *	found. Those with faked addresses, such as SCO.A want discarding,
- *	others could be bounced properly.
- * TODO: Encrypt mails sent to clamd to stop sniffers. Sending by UNIX domain
- *	sockets is better
- * TODO: Load balancing, allow local machine to talk via UNIX domain socket.
- * TODO: allow each To: line in the whitelist file to specify a quarantine email
- *	address
- * TODO: optionally use zlib to compress data sent to remote hosts
- * TODO: Finish IPv6 support (serverIPs array and SPF are IPv4 only)
- * TODO: Check domainkeys as well as SPF for phish false positives
- */
-
-struct header_node_t {
-	char	*header;
-	struct	header_node_t *next;
-};
-
-struct header_list_struct {
-	struct	header_node_t *first;
-	struct	header_node_t *last;
-};
-
-typedef struct header_list_struct *header_list_t;
-
-/*
- * Local addresses are those not scanned if --local is not set
- * 127.0.0.0 is not in this table since that's goverend by --outgoing
- * Andy Fiddaman <clam at fiddaman.net> added 169.254.0.0/16
- *	(Microsoft default DHCP)
- * TODO: compare this with RFC1918/RFC3330
- */
-#define PACKADDR(a, b, c, d) (((uint32_t)(a) << 24) | ((b) << 16) | ((c) << 8) | (d))
-#define MAKEMASK(bits)	((uint32_t)(0xffffffff << (32 - bits)))
-
-static struct cidr_net {	/* don't make this const because of -I flag */
-	uint32_t	base;
-	uint32_t	mask;
-} localNets[] = {
-	/*{ PACKADDR(127,   0,   0,   0), MAKEMASK(8) },	*   127.0.0.0/8 */
-	{ PACKADDR(192, 168,   0,   0), MAKEMASK(16) },	/* 192.168.0.0/16 - RFC3330 */
-	/*{ PACKADDR(192, 18,   0,   0), MAKEMASK(15) },	* 192.18.0.0/15 - RFC2544 */
-	/*{ PACKADDR(192, 0,   2,   0), MAKEMASK(24) },	* 192.0.2.0/24 - RFC3330 */
-	{ PACKADDR( 10,   0,   0,   0), MAKEMASK(8) },	/*    10.0.0.0/8 */
-	{ PACKADDR(172,  16,   0,   0), MAKEMASK(12) },	/*  172.16.0.0/12 */
-	{ PACKADDR(169, 254,   0,   0), MAKEMASK(16) },	/* 169.254.0.0/16 */
-	{ 0, 0 },	/* space to put eight more via -I addr */
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 }
-};
-#define IFLAG_MAX 8
-
-#ifdef	AF_INET6
-typedef struct cidr_net6 {
-	struct in6_addr	base;
-	int preflen;
-} cidr_net6;
-static	cidr_net6	localNets6[IFLAG_MAX];
-static	int	localNets6_cnt;
-#endif
-
-/*
- * Each libmilter thread has one of these
- */
-struct	privdata {
-	char	*from;	/* Who sent the message */
-	char	*subject;	/* Original subject */
-	char	*sender;	/* Secretary - often used in mailing lists */
-	char	**to;	/* Who is the message going to */
-	char	ip[INET6_ADDRSTRLEN];	/* IP address of the other end */
-	int	numTo;	/* Number of people the message is going to */
-#ifndef	SESSION
-	int	cmdSocket;	/*
-				 * Socket to send/get commands e.g. PORT for
-				 * dataSocket
-				 */
-#endif
-	int	dataSocket;	/* Socket to send data to clamd */
-	char	*filename;	/* Where to store the message in quarantine */
-	u_char	*body;		/* body of the message if Sflag is set */
-	size_t	bodyLen;	/* number of bytes in body */
-	header_list_t headers;	/* Message headers */
-	long	numBytes;	/* Number of bytes sent so far */
-	char	*received;	/* keep track of received from */
-	const	char	*rejectCode;	/* 550 or 554? */
-	unsigned	int	discard:1;	/*
-				 * looks like the remote end is playing ping
-				 * pong with us
-				 */
-#ifdef	HAVE_RESOLV_H
-	unsigned	int	spf_ok:1;
-#endif
-	int	statusCount;	/* number of X-Virus-Status headers */
-	int	serverNumber;	/* Index into serverIPs */
-};
-
-#ifdef	SESSION
-static	int		createSession(unsigned int s);
-#else
-static	int		pingServer(int serverNumber);
-static	void		*try_server(void *var);
-static	int		active_servers(int *active);
-struct	try_server_struct {
-	int	sock;
-	int	rc;
-	struct	sockaddr_in *server;
-	int	server_index;
-};
-#endif
-static	int		findServer(void);
-static	sfsistat	clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr);
-#ifdef	CL_DEBUG
-static	sfsistat	clamfi_helo(SMFICTX *ctx, char *helostring);
-#endif
-static	sfsistat	clamfi_envfrom(SMFICTX *ctx, char **argv);
-static	sfsistat	clamfi_envrcpt(SMFICTX *ctx, char **argv);
-static	sfsistat	clamfi_header(SMFICTX *ctx, char *headerf, char *headerv);
-static	sfsistat	clamfi_eoh(SMFICTX *ctx);
-static	sfsistat	clamfi_body(SMFICTX *ctx, u_char *bodyp, size_t len);
-static	sfsistat	clamfi_eom(SMFICTX *ctx);
-static	sfsistat	clamfi_abort(SMFICTX *ctx);
-static	sfsistat	clamfi_close(SMFICTX *ctx);
-static	void		clamfi_cleanup(SMFICTX *ctx);
-static	void		clamfi_free(struct privdata *privdata, int keep);
-#ifdef __GNUC__
-static	int		clamfi_send(struct privdata *privdata, size_t len, const char *format, ...) __attribute__((format(printf, 3,4)));
-#else
-static	int		clamfi_send(struct privdata *privdata, size_t len, const char *format, ...);
-#endif
-static	long		clamd_recv(int sock, char *buf, size_t len);
-static	off_t		updateSigFile(void);
-static	header_list_t	header_list_new(void);
-static	void	header_list_free(header_list_t list);
-static	void	header_list_add(header_list_t list, const char *headerf, const char *headerv);
-static	void	header_list_print(header_list_t list, FILE *fp);
-static	int	connect2clamd(struct privdata *privdata);
-static	int	sendToFrom(struct privdata *privdata);
-static	int	checkClamd(int log_result);
-static	int	sendtemplate(SMFICTX *ctx, const char *filename, FILE *sendmail, const char *virusname);
-static	int	qfile(struct privdata *privdata, const char *sendmailId, const char *virusname);
-static	int	move(const char *oldfile, const char *newfile);
-static	void	setsubject(SMFICTX *ctx, const char *virusname);
-/*static	int	clamfi_gethostbyname(const char *hostname, struct hostent *hp, char *buf, size_t len);*/
-static	int	add_local_ip(char *address);
-static	int	isLocalAddr(in_addr_t addr);
-static	int	isLocal(const char *addr);
-static	void	clamdIsDown(void);
-static	void	*watchdog(void *a);
-static	int	check_and_reload_database(void);
-static	void	timeoutBlacklist(char *ip_address, int time_of_blacklist, void *v);
-static	void	quit(void);
-static	void	broadcast(const char *mess);
-static	int	loadDatabase(void);
-static	int	increment_connexions(void);
-static	void	decrement_connexions(void);
-static	void	dump_blacklist(char *key, int value, void *v);
-static	int	nonblock_connect(int sock, const struct sockaddr_in *sin, const char *hostname);
-static	int	connect_error(int sock, const char *hostname);
-
-#ifdef	SESSION
-static	pthread_mutex_t	version_mutex = PTHREAD_MUTEX_INITIALIZER;
-static	char	**clamav_versions;	/* max_children elements in the array */
-#define	clamav_version	(clamav_versions[0])
-#else
-static	char	clamav_version[VERSION_LENGTH + 1];
-#endif
-static	int	fflag = 0;	/* force a scan, whatever */
-static	int	oflag = 0;	/* scan messages from our machine? */
-static	int	lflag = 0;	/* scan messages from our site? */
-static	int	Iflag = 0;	/* Added an IP addr to localNets? */
-static	const	char	*progname;	/* our name - usually clamav-milter */
-
-/* Variables for --external */
-static	int	external = 0;	/* scan messages ourself or use clamd? */
-static	pthread_mutex_t	engine_mutex = PTHREAD_MUTEX_INITIALIZER;
-struct  cl_engine *engine = NULL;
-uint64_t maxscansize;
-uint64_t maxfilesize;
-uint32_t maxreclevel;
-uint32_t maxfiles;
-
-static	struct	cl_stat	dbstat;
-static	int	options = CL_SCAN_STDOPT;
-
-#ifdef	BOUNCE
-static	int	bflag = 0;	/*
-				 * send a failure (bounce) message to the
-				 * sender. This probably isn't a good idea
-				 * since most reply addresses will be fake
-				 *
-				 * TODO: Perhaps we can have an option to
-				 * bounce outgoing mail, but not incoming?
-				 */
-#endif
-static	const	char	*iface;	/*
-				 * Broadcast a message when a virus is found,
-				 * this allows remote network management
-				 */
-static	int	broadcastSock = -1;
-static	int	pflag = 0;	/*
-				 * Send a warning to the postmaster only,
-				 * this means user's won't be told when someone
-				 * sent them a virus
-				 */
-static	int	qflag = 0;	/*
-				 * Send no warnings when a virus is found,
-				 * this means that the only log of viruses
-				 * found is the syslog, so it's best to
-				 * enable LogSyslog in clamd.conf
-				 */
-static	int	Sflag = 0;	/*
-				 * Add a signature to each message that
-				 * has been scanned
-				 */
-static	const	char	*sigFilename;	/*
-				 * File where the scanned message signature
-				 * can be found
-				 */
-static	char	*quarantine;	/*
-				 * If a virus is found in an email redirect
-				 * it to this account
-				 */
-static	char	*quarantine_dir; /*
-				 * Path to store messages before scanning.
-				 * Infected ones will be left there.
-				 */
-static	int	nflag = 0;	/*
-				 * Don't add X-Virus-Scanned to header. Patch
-				 * from Dirk Meyer <dirk.meyer at dinoex.sub.org>
-				 */
-static	int	rejectmail = 1;	/*
-				 * Send a 550 rejection when a virus is
-				 * found
-				 */
-static	int	hflag = 0;	/*
-				 * Include original message headers in
-				 * report
-				 */
-static	int	cl_error = SMFIS_TEMPFAIL; /*
-				 * If an error occurs, return
-				 * this status. Allows messages
-				 * to be passed through
-				 * unscanned in the event of
-				 * an error. Patch from
-				 * Joe Talbott <josepht at cstone.net>
-				 */
-static	int	readTimeout = DEFAULT_TIMEOUT; /*
-				 * number of seconds to wait for clamd to
-				 * respond, see ReadTimeout in clamd.conf
-				 */
-static	long	streamMaxLength = -1;	/* StreamMaxLength from clamd.conf */
-static	int	logok = 0;	/*
-				 * Add clean items to the log file
-				 */
-static	const char	*signature = N_("-- \nScanned by ClamAv - http://www.clamav.net\n");
-static	time_t	signatureStamp;
-static	char	*templateFile;	/* e-mail to be sent when virus detected */
-static	char	*templateHeaders;	/* headers to be added to the above */
-static	const char	*tmpdir;
-
-#ifdef	CL_DEBUG
-static	int	debug_level = 0;
-#endif
-
-static	pthread_mutex_t	n_children_mutex = PTHREAD_MUTEX_INITIALIZER;
-static	pthread_cond_t	n_children_cond = PTHREAD_COND_INITIALIZER;
-static	int	n_children = 0;
-static	int	max_children = 0;
-static	unsigned	int	freshclam_monitor = 10;	/*
-							 * how often, in
-							 * seconds, to scan for
-							 * database updates
-							 */
-static	int	child_timeout = 300;	/* number of seconds to wait for
-					 * a child to die. Set to 0 to
-					 * wait forever
-					 */
-static	int	dont_wait = 0;	/*
-				 * If 1 send retry later to the remote end
-				 * if max_chilren is exceeded, otherwise we
-				 * wait for the number to go down
-				 */
-static	int	dont_sanitise = 0; /*
-				 * Don't check for ";" and "|" chars in 
-				 * email addresses.
-				 */
-static	int	advisory = 0;	/*
-				 * Run clamav-milter in advisory mode - viruses
-				 * are flagged rather than deleted. Incompatible
-				 * with quarantine options
-				 */
-static	int	detect_forged_local_address;	/*
-				 * for incoming only mail servers, drop emails
-				 * claiming to be from us that must be false
-				 * Requires that -o, -l or -f are NOT given
-				 */
-static	const	char	*pidFile;
-static	struct	cfgstruct	*copt;
-static	const	char	*localSocket;	/* milter->clamd comms */
-static	in_port_t	tcpSocket;	/* milter->clamd comms */
-static	char	*port = NULL;	/* sendmail->milter comms */
-
-static	const	char	*serverHostNames = "127.0.0.1";
-#if	HAVE_IN_ADDR_T
-static	in_addr_t	*serverIPs;	/* IPv4 only, in network byte order */
-#else
-static	long	*serverIPs;	/* IPv4 only, in network byte order */
-#endif
-static	int	numServers;	/* number of elements in serverIPs array */
-#ifndef	SESSION
-#define	RETRY_SECS	300	/* How often to retry a server that's down */
-static	time_t	*last_failed_pings;	/* For servers that are down. NB: not mutexed */
-#endif
-static	char	*rootdir;	/* for chroot */
-
-#ifdef	SESSION
-static	struct	session {
-	int	sock;	/* fd */
-	enum	{ CMDSOCKET_FREE, CMDSOCKET_INUSE, CMDSOCKET_DOWN }	status;
-} *sessions;	/* max_children elements in the array */
-static	pthread_mutex_t sstatus_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif	/*SESSION*/
-
-static	pthread_cond_t	watchdog_cond = PTHREAD_COND_INITIALIZER;
-
-#ifndef	SHUT_RD
-#define	SHUT_RD		0
-#endif
-#ifndef	SHUT_WR
-#define	SHUT_WR		1
-#endif
-
-static	const	char	*postmaster = "postmaster";
-static	const	char	*from = "MAILER-DAEMON";
-static	int	quitting;
-static	int	reload;	/* reload database when SIGUSR2 is received */
-static	const	char	*report;	/* Report Phishing to this address */
-static	const	char	*report_fps;	/* Report Phish FPs to this address */
-
-static	const	char	*whitelistFile;	/*
-					 * file containing destination email
-					 * addresses that we don't scan
-					 */
-static	const	char	*sendmailCF;	/* location of sendmail.cf to verify */
-static		int	checkCF = 1;
-static	const	char	*pidfile;
-static	int	black_hole_mode; /*
-				 * Since sendmail calls its milters before it
-				 * looks in /etc/aliases we can spend time
-				 * looking for malware that's going to be
-				 * thrown away even if the message is clean.
-				 * Enable this to not scan these messages.
-				 * Sadly, because these days sendmail -bv
-				 * only works as root, you can't use this with
-				 * the User directive, which some won't like
-				 * which also may contain the real target name
-				 *
-				 * smfi_getsymval(ctx, "{rcpt_addr}") only
-				 * handles virtuser, it doesn't also deref
-				 * the alias table, so it isn't any help
-				 */
-
-static	table_t	*blacklist;	/* never freed */
-static	int	blacklist_time;	/* How long to blacklist an IP */
-static	pthread_mutex_t	blacklist_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-#ifdef	CL_DEBUG
-#if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1
-#define HAVE_BACKTRACE
-#endif
-#endif
-
-static	void	sigsegv(int sig);
-static	void	sigusr1(int sig);
-static	void	sigusr2(int sig);
-
-#ifdef HAVE_BACKTRACE
-#include <execinfo.h>
-
-static	void	print_trace(void);
-
-#define	BACKTRACE_SIZE	200
-
-#endif
-
-static	int	verifyIncomingSocketName(const char *sockName);
-static	int	isWhitelisted(const char *emailaddress, int to);
-static	int	isBlacklisted(const char *ip_address);
-static	table_t	*mx(const char *host, table_t *t);
-static	sfsistat	black_hole(const struct privdata *privdata);
-static	int	useful_header(const char *cmd);
-
-extern	short	logg_foreground;
-
-#ifdef HAVE_RESOLV_H
-static	table_t	*resolve(const char *host, table_t *t);
-static	int	spf(struct privdata *privdata, table_t *prevhosts);
-static	void	spf_ip(char *ip, int zero, void *v);
-
-pthread_mutex_t	res_pool_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-#ifdef HAVE_LRESOLV_R
-res_state res_pool;
-uint8_t *res_pool_state;
-pthread_cond_t res_pool_cond = PTHREAD_COND_INITIALIZER;
-
-static int safe_res_query(const char *d, int c, int t, u_char *a, int l) {
-	int i = -1, ret;
-
-	pthread_mutex_lock(&res_pool_mutex);
-	while(i==-1) {
-		int j;
-		for(j=0; j<max_children+1; j++) {
-			if(!res_pool_state[j]) continue;
-			i = j;
-			break;
-		}
-		if(i!=-1) break;
-		pthread_cond_wait(&res_pool_cond, &res_pool_mutex);
-	}
-	res_pool_state[i]=0;
-	pthread_mutex_unlock(&res_pool_mutex);
-
-	ret = res_nquery(&res_pool[i], d, c, t, a, l);
-  
-	pthread_mutex_lock(&res_pool_mutex);
-	res_pool_state[i]=1;
-	pthread_cond_signal(&res_pool_cond);
-	pthread_mutex_unlock(&res_pool_mutex);
-	return ret;
-}
-
-#else /* !HAVE_LRESOLV_R - non thread safe resolver (old bsd's) */
-
-static int safe_res_query(const char *d, int c, int t, u_char *a, int l) {
-	int ret;
-	pthread_mutex_lock(&res_pool_mutex);
-	ret = res_query(d, c, t, a, l);
-	pthread_mutex_unlock(&res_pool_mutex);
-	return ret;
-}
-
-#endif /* HAVE_LRESOLV_R */
-
-#endif /* HAVE_RESOLV_H */
-
-static void
-help(void)
-{
-	printf("\n\tclamav-milter version %s\n", get_version());
-	puts("\tCopyright (C) 2007 Nigel Horne <njh at clamav.net>\n");
-
-	puts(_("\t--advisory\t\t-A\tFlag viruses rather than deleting them."));
-	puts(_("\t--blacklist-time=SECS\t-k\tTime (in seconds) to blacklist an IP."));
-	puts(_("\t--black-hole-mode\t\tDon't scan messages aliased to /dev/null."));
-#ifdef	BOUNCE
-	puts(_("\t--bounce\t\t-b\tSend a failure message to the sender."));
-#endif
-	puts(_("\t--broadcast\t\t-B [IFACE]\tBroadcast to a network manager when a virus is found."));
-	puts(_("\t--chroot=DIR\t\t-C DIR\tChroot to dir when starting."));
-	puts(_("\t--config-file=FILE\t-c FILE\tRead configuration from FILE."));
-	puts(_("\t--debug\t\t\t-D\tPrint debug messages."));
-	puts(_("\t--detect-forged-local-address\t-L\tReject mails that claim to be from us."));
-	puts(_("\t--dont-blacklist\t-K\tDon't blacklist a given IP."));
-	puts(_("\t--dont-scan-on-error\t-d\tPass e-mails through unscanned if a system error occurs."));
-	puts(_("\t--dont-wait\t\t\tAsk remote end to resend if max-children exceeded."));
-	puts(_("\t--dont-sanitise\t\t\tAllow semicolon and pipe characters in email addresses."));
-	puts(_("\t--external\t\t-e\tUse an external scanner (usually clamd)."));
-	puts(_("\t--freshclam-monitor=SECS\t-M SECS\tHow often to check for database update."));
-	puts(_("\t--from=EMAIL\t\t-a EMAIL\tError messages come from here."));
-	puts(_("\t--force-scan\t\t-f\tForce scan all messages (overrides (-o and -l)."));
-	puts(_("\t--help\t\t\t-h\tThis message."));
-	puts(_("\t--headers\t\t-H\tInclude original message headers in the report."));
-	puts(_("\t--ignore IPaddr\t\t-I IPaddr\tAdd IPaddr to LAN IP list (see --local)."));
-	puts(_("\t--local\t\t\t-l\tScan messages sent from machines on our LAN."));
-	puts(_("\t--max-childen\t\t-m\tMaximum number of concurrent scans."));
-	puts(_("\t--outgoing\t\t-o\tScan outgoing messages from this machine."));
-	puts(_("\t--noreject\t\t-N\tDon't reject viruses, silently throw them away."));
-	puts(_("\t--noxheader\t\t-n\tSuppress X-Virus-Scanned/X-Virus-Status headers."));
-	puts(_("\t--pidfile=FILE\t\t-i FILE\tLocation of pidfile."));
-	puts(_("\t--postmaster\t\t-p EMAIL\tPostmaster address [default=postmaster]."));
-	puts(_("\t--postmaster-only\t-P\tSend notifications only to the postmaster."));
-	puts(_("\t--quiet\t\t\t-q\tDon't send e-mail notifications of interceptions."));
-	puts(_("\t--quarantine=USER\t-Q EMAIL\tQuarantine e-mail account."));
-	puts(_("\t--report-phish=EMAIL\t-r EMAIL\tReport phish to this email address."));
-	puts(_("\t--report-phish-false-positives=EMAIL\t-R EMAIL\tReport phish false positves to this email address."));
-	puts(_("\t--quarantine-dir=DIR\t-U DIR\tDirectory to store infected emails."));
-	puts(_("\t--server=SERVER\t\t-s SERVER\tHostname/IP address of server(s) running clamd (when using TCPsocket)."));
-	puts(_("\t--sendmail-cf=FILE\t\tLocation of the sendmail.cf file to verify"));
-	puts(_("\t--no-check-cf\t\tSkip verification of sendmail.cf"));
-	puts(_("\t--sign\t\t\t-S\tAdd a hard-coded signature to each scanned message."));
-	puts(_("\t--signature-file=FILE\t-F FILE\tLocation of signature file."));
-	puts(_("\t--template-file=FILE\t-t FILE\tLocation of e-mail template file."));
-	puts(_("\t--template-headers=FILE\t\tLocation of e-mail headers for template file."));
-	puts(_("\t--timeout=SECS\t\t-T SECS\tTimeout waiting to childen to die."));
-	puts(_("\t--whitelist-file=FILE\t-W FILE\tLocation of the file of whitelisted addresses"));
-	puts(_("\t--version\t\t-V\tPrint the version number of this software."));
-#ifdef	CL_DEBUG
-	puts(_("\t--debug-level=n\t\t-x n\tSets the debug level to 'n'."));
-#endif
-	puts(_("\nFor more information type \"man clamav-milter\"."));
-	puts(_("For bug reports, please refer to http://www.clamav.net/bugs"));
-}
-
-extern char *optarg;
-int
-main(int argc, char **argv)
-{
-	int i, Bflag = 0, server = 0;
-	char *cfgfile = NULL;
-	const char *wont_blacklist = NULL;
-	const struct cfgstruct *cpt;
-	char version[VERSION_LENGTH + 1];
-	pthread_t tid;
-	struct rlimit rlim;
-#ifdef	CL_DEBUG
-	int consolefd;
-#endif
-
-	/*
-	 * The SMFI_VERSION checks are for Sendmail 8.14, which I don't have
-	 * yet, so I can't verify them
-	 * Patch from Andy Fiddaman <clam at fiddaman.net>
-	 */
-	struct smfiDesc smfilter = {
-		"ClamAv", /* filter name */
-		SMFI_VERSION,	/* version code -- leave untouched */
-		SMFIF_ADDHDRS|SMFIF_CHGHDRS,	/* flags - we add and delete headers */
-		clamfi_connect, /* connexion callback */
-#ifdef	CL_DEBUG
-		clamfi_helo,	/* HELO filter callback */
-#else
-		NULL,
-#endif
-		clamfi_envfrom, /* envelope sender filter callback */
-		clamfi_envrcpt, /* envelope recipient filter callback */
-		clamfi_header,	/* header filter callback */
-		clamfi_eoh,	/* end of header callback */
-		clamfi_body,	/* body filter callback */
-		clamfi_eom,	/* end of message callback */
-		clamfi_abort,	/* message aborted callback */
-		clamfi_close,	/* connexion cleanup callback */
-#if	SMFI_VERSION > 2
-		NULL,		/* Unrecognised command */
-#endif
-#if	SMFI_VERSION > 3
-		NULL,		/* DATA command callback */
-#endif
-#if	SMFI_VERSION >= 0x01000000
-		NULL,		/* Negotiation callback */
-#endif
-	};
-
-#if defined(CL_DEBUG) && defined(C_LINUX)
-	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
-	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
-		perror("setrlimit");
-#endif
-
-	/*
-	 * Temporarily enter guessed value into version, will
-	 * be overwritten later by the value returned by clamd
-	 */
-	snprintf(version, sizeof(version) - 1,
-		"ClamAV version %s, clamav-milter version %s",
-		cl_retver(), get_version());
-
-	progname = strrchr(argv[0], '/');
-	if(progname)
-		progname++;
-	else
-		progname = "clamav-milter";
-
-#ifdef	C_LINUX
-	setlocale(LC_ALL, "");
-	bindtextdomain(progname, DATADIR"/clamav-milter/locale");
-	textdomain(progname);
-#endif
-
-	for(;;) {
-		int opt_index = 0;
-#ifdef	BOUNCE
-#ifdef	CL_DEBUG
-		const char *args = "a:AbB:c:C:dDefF:I:i:k:K:lLm:M:nNop:PqQ:r:R:hHs:St:T:U:VwW:x:z0:1:2";
-#else
-		const char *args = "a:AbB:c:C:dDefF:I:i:k:K:lLm:M:nNop:PqQ:r:R:hHs:St:T:U:VwW:z0:1:2";
-#endif
-#else	/*!BOUNCE*/
-#ifdef	CL_DEBUG
-		const char *args = "a:AB:c:C:dDefF:I:i:k:K:lLm:M:nNop:PqQ:r:R:hHs:St:T:U:VwW:x:z0:1:2";
-#else
-		const char *args = "a:AB:c:C:dDefF:I:i:k:K:lLm:M:nNop:PqQ:r:R:hHs:St:T:U:VwW:z0:1:2";
-#endif
-#endif	/*BOUNCE*/
-
-		static struct option long_options[] = {
-			{
-				"from", 2, NULL, 'a'
-			},
-			{
-				"advisory", 0, NULL, 'A'
-			},
-#ifdef	BOUNCE
-			{
-				"bounce", 0, NULL, 'b'
-			},
-#endif
-			{
-				"broadcast", 2, NULL, 'B'
-			},
-			{
-				"config-file", 1, NULL, 'c'
-			},
-			{
-				"chroot", 1, NULL, 'C'
-			},
-			{
-				"detect-forged-local-address", 0, NULL, 'L'
-			},
-			{
-				"dont-blacklist", 1, NULL, 'K'
-			},
-			{
-				"dont-scan-on-error", 0, NULL, 'd'
-			},
-			{
-				"dont-wait", 0, NULL, 'w'
-			},
-			{
-				"dont-sanitise", 0, NULL, 'z'
-			},
-			{
-				"debug", 0, NULL, 'D'
-			},
-			{
-				"external", 0, NULL, 'e'
-			},
-			{
-				"force-scan", 0, NULL, 'f'
-			},
-			{
-				"headers", 0, NULL, 'H'
-			},
-			{
-				"help", 0, NULL, 'h'
-			},
-			{
-				"ignore", 1, NULL, 'I'
-			},
-			{
-				"pidfile", 1, NULL, 'i'
-			},
-			{
-				"blacklist-time", 1, NULL, 'k'
-			},
-			{
-				"local", 0, NULL, 'l'
-			},
-			{
-				"noreject", 0, NULL, 'N'
-			},
-			{
-				"noxheader", 0, NULL, 'n'
-			},
-			{
-				"outgoing", 0, NULL, 'o'
-			},
-			{
-				"postmaster", 1, NULL, 'p'
-			},
-			{
-				"postmaster-only", 0, NULL, 'P',
-			},
-			{
-				"quiet", 0, NULL, 'q'
-			},
-			{
-				"quarantine", 1, NULL, 'Q',
-			},
-			{
-				"report-phish", 1, NULL, 'r'
-			},
-			{
-				"report-phish-false-positives", 1, NULL, 'R'
-			},
-			{
-				"quarantine-dir", 1, NULL, 'U',
-			},
-			{
-				"max-children", 1, NULL, 'm'
-			},
-			{
-				"freshclam-monitor", 1, NULL, 'M'
-			},
-			{
-				"sendmail-cf", 1, NULL, '0'
-			},
-			{
-				"no-check-cf", 0, &checkCF, 0
-			},
-			{
-				"server", 1, NULL, 's'
-			},
-			{
-				"sign", 0, NULL, 'S'
-			},
-			{
-				"signature-file", 1, NULL, 'F'
-			},
-			{
-				"template-file", 1, NULL, 't'
-			},
-			{
-				"template-headers", 1, NULL, '1'
-			},
-			{
-				"timeout", 1, NULL, 'T'
-			},
-			{
-				"whitelist-file", 1, NULL, 'W'
-			},
-			{
-				"version", 0, NULL, 'V'
-			},
-			{
-				"black-hole-mode", 0, NULL, '2'
-			},
-#ifdef	CL_DEBUG
-			{
-				"debug-level", 1, NULL, 'x'
-			},
-#endif
-			{
-				NULL, 0, NULL, '\0'
-			}
-		};
-
-		int ret = getopt_long(argc, argv, args, long_options, &opt_index);
-
-		if(ret == -1)
-			break;
-  		else if(ret == 0)
-  			continue;
-
-		switch(ret) {
-			case 'a':	/* e-mail errors from here */
-				/*
-				 * optarg is optional - if you give --from
-				 * then the --from is set to the orginal,
-				 * probably forged, email address
-				 */
-				from = optarg;
-				break;
-			case 'A':
-				advisory++;
-				break;
-#ifdef	BOUNCE
-			case 'b':	/* bounce worms/viruses */
-				bflag++;
-				break;
-#endif
-			case 'B':	/* broadcast */
-				Bflag++;
-				if(optarg)
-					iface = optarg;
-				break;
-			case 'c':	/* where is clamd.conf? */
-				cfgfile = optarg;
-				break;
-			case 'C':	/* chroot */
-				rootdir = optarg;
-				break;
-			case 'd':	/* don't scan on error */
-				cl_error = SMFIS_ACCEPT;
-				break;
-			case 'D':	/* enable debug messages */
-				cl_debug();
-				break;
-			case 'e':	/* use clamd */
-				external++;
-				break;
-			case 'f':	/* force the scan */
-				fflag++;
-				break;
-			case 'h':
-				help();
-				return EX_OK;
-			case 'H':
-				hflag++;
-				break;
-			case 'i':	/* pidfile */
-				pidfile = optarg;
-				break;
-			case 'k':	/* blacklist time */
-				blacklist_time = atoi(optarg);
-				break;
-			case 'K':	/* don't black list given IP */
-				wont_blacklist = optarg;
-				break;
-			case 'I':	/* --ignore, -I hostname */
-				/*
-				 * Based on patch by jpd at louisiana.edu
-				 */
-				if(Iflag == IFLAG_MAX) {
-					fprintf(stderr,
-						_("%s: %s, -I may only be given %d times\n"),
-							argv[0], optarg, IFLAG_MAX);
-					return EX_USAGE;
-				}
-				if(!add_local_ip(optarg)) {
-					fprintf(stderr,
-						_("%s: Cannot convert -I%s to IPaddr\n"),
-							argv[0], optarg);
-					return EX_USAGE;
-				}
-				Iflag++;
-				break;
-			case 'l':	/* scan mail from the lan */
-				lflag++;
-				break;
-			case 'L':	/* detect forged local addresses */
-				detect_forged_local_address++;
-				break;
-			case 'm':	/* maximum number of children */
-				max_children = atoi(optarg);
-				break;
-			case 'M':	/* how often to monitor for freshclam */
-				freshclam_monitor = atoi(optarg);
-				break;
-			case 'n':	/* don't add X-Virus-Scanned */
-				nflag++;
-				smfilter.xxfi_flags &= ~(SMFIF_ADDHDRS|SMFIF_CHGHDRS);
-				break;
-			case 'N':	/* Do we reject mail or silently drop it */
-				rejectmail = 0;
-				break;
-			case 'o':	/* scan outgoing mail */
-				oflag++;
-				break;
-			case 'p':	/* postmaster e-mail address */
-				postmaster = optarg;
-				break;
-			case 'P':	/* postmaster only */
-				pflag++;
-				break;
-			case 'q':	/* send NO notification email */
-				qflag++;
-				break;
-			case 'Q':	/* quarantine e-mail address */
-				quarantine = optarg;
-				smfilter.xxfi_flags |= SMFIF_CHGHDRS|SMFIF_ADDRCPT|SMFIF_DELRCPT;
-				break;
-			case 'r':	/* report phishing here */
-				/* e.g. reportphishing at antiphishing.org */
-				report = optarg;
-				break;
-			case 'R':	/* report phishing false positives here */
-				report_fps = optarg;
-				break;
-			case 's':	/* server running clamd */
-				server++;
-				serverHostNames = optarg;
-				break;
-			case 'F':	/* signature file */
-				sigFilename = optarg;
-				signature = NULL;
-				/* fall through */
-			case 'S':	/* sign */
-				smfilter.xxfi_flags |= SMFIF_CHGBODY;
-				Sflag++;
-				break;
-			case 't':	/* e-mail template file */
-				templateFile = optarg;
-				break;
-			case '1':	/* headers for the template file */
-				templateHeaders = optarg;
-				break;
-			case '2':
-				black_hole_mode++;
-				break;
-			case 'T':	/* time to wait for child to die */
-				child_timeout = atoi(optarg);
-				break;
-			case 'U':	/* quarantine path */
-				quarantine_dir = optarg;
-				break;
-			case 'V':
-				puts(version);
-				return EX_OK;
-			case 'w':
-				dont_wait++;
-				break;
-			case 'W':
-				whitelistFile = optarg;
-				break;
-			case 'z':
-				dont_sanitise=1;
-				break;
-			case '0':
-				sendmailCF = optarg;
-				break;
-#ifdef	CL_DEBUG
-			case 'x':
-				debug_level = atoi(optarg);
-				break;
-#endif
-			default:
-#ifdef	CL_DEBUG
-				fprintf(stderr, "Usage: %s [-b] [-c FILE] [-F FILE] [--max-children=num] [-e] [-l] [-o] [-p address] [-P] [-q] [-Q USER] [-s SERVER] [-S] [-x#] [-U PATH] [-M#] socket-addr\n", argv[0]);
-#else
-				fprintf(stderr, "Usage: %s [-b] [-c FILE] [-F FILE] [--max-children=num] [-e] [-l] [-o] [-p address] [-P] [-q] [-Q USER] [-s SERVER] [-S] [-U PATH] [-M#] socket-addr\n", argv[0]);
-#endif
-				return EX_USAGE;
-		}
-	}
-
-	/*
-	 * Check sanity of --external and --server arguments
-	 */
-	if(server && !external) {
-		fprintf(stderr,
-			"%s: --server can only be used with --external\n",
-			argv[0]);
-		return EX_USAGE;
-	}
-#ifdef	SESSION
-	if(!external) {
-		fprintf(stderr,
-			_("%s: SESSIONS mode requires --external\n"), argv[0]);
-		return EX_USAGE;
-	}
-#endif
-
-	/* TODO: support freshclam's daemon notify if --external is not given */
-
-	if(optind == argc) {
-		fprintf(stderr, _("%s: No socket-addr given\n"), argv[0]);
-		return EX_USAGE;
-	}
-	port = argv[optind];
-
-	if(rootdir == NULL)	/* FIXME: Handle CHROOT */
-		if(checkCF && verifyIncomingSocketName(port) < 0) {
-			fprintf(stderr, _("%s: socket-addr (%s) doesn't agree with sendmail.cf\n"), argv[0], port);
-			return EX_CONFIG;
-		}
-
-	if(strncasecmp(port, "inet:", 5) == 0)
-		if(!lflag) {
-			/*
-			 * Barmy but true. It seems that clamfi_connect will,
-			 * in this case, get the IP address of the machine
-			 * running sendmail, not of the machine sending the
-			 * mail, so the remote end will be a local address so
-			 * we must scan by enabling --local
-			 *
-			 * TODO: this is probably not needed if the remote
-			 * machine is localhost, need to check though
-			 */
-			fprintf(stderr, _("%s: when using inet: connexion to sendmail you must enable --local\n"), argv[0]);
-			return EX_USAGE;
-		}
-
-	/*
-	 * Sanity checks on the clamav configuration file
-	 */
-	if(cfgfile == NULL) {
-		cfgfile = cli_malloc(strlen(CONFDIR) + 12);	/* leak */
-		sprintf(cfgfile, "%s/clamd.conf", CONFDIR);
-	}
-	if((copt = getcfg(cfgfile, 1, OPT_CLAMD)) == NULL) {
-		fprintf(stderr, _("%s: Can't parse the config file %s\n"),
-			argv[0], cfgfile);
-		return EX_CONFIG;
-	}
-
-	if(detect_forged_local_address) {
-		if(oflag) {
-			fprintf(stderr, _("%s: --detect-forged-local-addresses is not compatible with --outgoing\n"), argv[0]);
-			return EX_CONFIG;
-		}
-		if(lflag) {
-			fprintf(stderr, _("%s: --detect-forged-local-addresses is not compatible with --local\n"), argv[0]);
-			return EX_CONFIG;
-		}
-		if(fflag) {
-			fprintf(stderr, _("%s: --detect-forged-local-addresses is not compatible with --force\n"), argv[0]);
-			return EX_CONFIG;
-		}
-	}
-
-	if(Bflag) {
-		int on;
-
-		broadcastSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-		/*
-		 * SO_BROADCAST doesn't sent to all NICs on Linux, it only
-		 * broadcasts on eth0, which is why there's an optional argument
-		 * to --broadcast to say which NIC to broadcast on. You can use
-		 * SO_BINDTODEVICE to get around that, but you need to have
-		 * uid == 0 for that
-		 */
-		on = 1;
-		if(setsockopt(broadcastSock, SOL_SOCKET, SO_BROADCAST, (int *)&on, sizeof(on)) < 0) {
-			perror("setsockopt");
-			return EX_UNAVAILABLE;
-		}
-		shutdown(broadcastSock, SHUT_RD);
-	}
-
-	/*
-	 * Drop privileges
-	 */
-#ifdef	CL_DEBUG
-	/* Save the fd for later, open while we can */
-	consolefd = open(console, O_WRONLY);
-#endif
-
-	if(getuid() == 0) {
-		if(iface) {
-#ifdef	SO_BINDTODEVICE
-			struct ifreq ifr;
-
-			memset(&ifr, '\0', sizeof(struct ifreq));
-			strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
-			ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0';
-			if(setsockopt(broadcastSock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) {
-				perror(iface);
-				return EX_CONFIG;
-			}
-#else
-			fprintf(stderr, _("%s: The iface option to --broadcast is not supported on your operating system\n"), argv[0]);
-			return EX_CONFIG;
-#endif
-		}
-
-		if(((cpt = cfgopt(copt, "User")) != NULL) && cpt->enabled) {
-			const struct passwd *user;
-
-			if((user = getpwnam(cpt->strarg)) == NULL) {
-				fprintf(stderr, _("%s: Can't get information about user %s\n"), argv[0], cpt->strarg);
-				return EX_CONFIG;
-			}
-
-			if(cfgopt(copt, "AllowSupplementaryGroups")->enabled) {
-#ifdef HAVE_INITGROUPS
-				if(initgroups(cpt->strarg, user->pw_gid) < 0) {
-					perror(cpt->strarg);
-					return EX_CONFIG;
-				}
-#else
-				fprintf(stderr, _("%s: AllowSupplementaryGroups: initgroups not supported.\n"),
-					argv[0]);
-				return EX_CONFIG;
-#endif
-			} else {
-#ifdef	HAVE_SETGROUPS
-				if(setgroups(1, &user->pw_gid) < 0) {
-					perror(cpt->strarg);
-					return EX_CONFIG;
-				}
-#endif
-			}
-
-			setgid(user->pw_gid);
-
-			if(setuid(user->pw_uid) < 0)
-				perror(cpt->strarg);
-#ifdef	CL_DEBUG
-			else
-				printf(_("Running as user %s (UID %d, GID %d)\n"),
-					cpt->strarg, (int)user->pw_uid,
-					(int)user->pw_gid);
-#endif
-
-			/*
-			 * Note, some O/Ss (e.g. OpenBSD/Fedora Linux) FORCE
-			 * you to run as root in black-hole-mode because
-			 * /var/spool/mqueue is mode 700 owned by root!
-			 * Flames to them, not to me, please.
-			 */
-			if(black_hole_mode && (user->pw_uid != 0)) {
-				int are_trusted;
-				FILE *sendmail;
-				char cmd[128];
-
-				/*
-				 * Determine if we're a "trusted user"
-				 */
-				snprintf(cmd, sizeof(cmd) - 1, "%s -bv root</dev/null 2>&1",
-					SENDMAIL_BIN);
-
-				sendmail = popen(cmd, "r");
-
-				if(sendmail == NULL) {
-					perror(SENDMAIL_BIN);
-					are_trusted = 0;
-				} else {
-					int status;
-					char buf[BUFSIZ];
-
-					while(fgets(buf, sizeof(buf), sendmail) != NULL)
-						;
-					/*
-					 * Can't do
-					 * switch(WEXITSTATUS(pclose(sendmail)))
-					 * because that fails to compile on
-					 * NetBSD2.0
-					 */
-					status = pclose(sendmail);
-					switch(WEXITSTATUS(status)) {
-						case EX_NOUSER:
-							/*
-							 * No root? But at least
-							 * we're trusted enough
-							 * to find out!
-							 */
-							are_trusted = 1;
-							break;
-						default:
-							are_trusted = 0;
-							break;
-						case EX_OK:
-							are_trusted = 1;
-					}
-				}
-				if(!are_trusted) {
-					fprintf(stderr, _("%s: You cannot use black hole mode unless %s is a TrustedUser\n"),
-						argv[0], cpt->strarg);
-					return EX_CONFIG;
-				}
-			}
-		} else
-			printf(_("^%s: running as root is not recommended (check \"User\" in %s)\n"), argv[0], cfgfile);
-	} else if(iface) {
-		fprintf(stderr, _("%s: Only root can set an interface for --broadcast\n"), argv[0]);
-		return EX_USAGE;
-	}
-
-	if(advisory && quarantine) {
-		fprintf(stderr, _("%s: Advisory mode doesn't work with quarantine mode\n"), argv[0]);
-		return EX_USAGE;
-	}
-	if(quarantine_dir) {
-		struct stat statb;
-
-		if(advisory) {
-			fprintf(stderr,
-				_("%s: Advisory mode doesn't work with quarantine directories\n"),
-				argv[0]);
-			return EX_USAGE;
-		}
-		if(strstr(quarantine_dir, "ERROR") != NULL) {
-			fprintf(stderr,
-				_("%s: the quarantine directory must not contain the string 'ERROR'\n"),
-				argv[0]);
-			return EX_USAGE;
-		}
-		if(strstr(quarantine_dir, "FOUND") != NULL) {
-			fprintf(stderr,
-				_("%s: the quarantine directory must not contain the string 'FOUND'\n"),
-				argv[0]);
-			return EX_USAGE;
-		}
-		if(strstr(quarantine_dir, "OK") != NULL) {
-			fprintf(stderr,
-				_("%s: the quarantine directory must not contain the string 'OK'\n"),
-				argv[0]);
-			return EX_USAGE;
-		}
-		if(access(quarantine_dir, W_OK) < 0) {
-			perror(quarantine_dir);
-			return EX_USAGE;
-		}
-		if(stat(quarantine_dir, &statb) < 0) {
-			perror(quarantine_dir);
-			return EX_USAGE;
-		}
-		/*
-		 * Quit if the quarantine directory is publically readable
-		 * or writeable
-		 */
-		if(statb.st_mode & 077) {
-			fprintf(stderr, _("%s: insecure quarantine directory %s (mode 0%o)\n"),
-				argv[0], quarantine_dir, (int)statb.st_mode & 0777);
-			return EX_CONFIG;
-		}
-	}
-
-	if(sigFilename && !updateSigFile())
-		return EX_USAGE;
-
-	if(templateFile && (access(templateFile, R_OK) < 0)) {
-		perror(templateFile);
-		return EX_CONFIG;
-	}
-	if(templateHeaders) {
-		if(templateFile == NULL) {
-			fputs(("%s: --template-headers requires --template-file\n"),
-				stderr);
-			return EX_CONFIG;
-		}
-		if(access(templateHeaders, R_OK) < 0) {
-			perror(templateHeaders);
-			return EX_CONFIG;
-		}
-	}
-	if(whitelistFile && (access(whitelistFile, R_OK) < 0)) {
-		perror(whitelistFile);
-		return EX_CONFIG;
-	}
-
-	/*
-	 * If the --max-children flag isn't set, see if MaxThreads
-	 * is set in the config file. Based on an idea by "Richard G. Roberto"
-	 * <rgr at dedlegend.com>
-	 */
-	if((max_children == 0) && ((cpt = cfgopt(copt, "MaxThreads")) != NULL))
-		max_children = cfgopt(copt, "MaxThreads")->numarg;
-
-#ifdef HAVE_LRESOLV_R
-	/* allocate a pool of resolvers */
-	if(!(res_pool=cli_calloc(max_children+1, sizeof(*res_pool))))
-		return EX_OSERR;
-	if(!(res_pool_state=cli_malloc(max_children+1)))
-		return EX_OSERR;
-	memset(res_pool_state, 1, max_children+1);
-	for(i = 0; i < max_children+1; i++)
-		res_ninit(&res_pool[i]);
-#endif
-
-	if((cpt = cfgopt(copt, "ReadTimeout")) != NULL) {
-		readTimeout = cpt->numarg;
-
-		if(readTimeout < 0) {
-			fprintf(stderr, _("%s: ReadTimeout must not be negative in %s\n"),
-				argv[0], cfgfile);
-			return EX_CONFIG;
-		}
-	}
-
-	if((cpt = cfgopt(copt, "StreamMaxLength")) != NULL) {
-		streamMaxLength = (long)cpt->numarg;
-		if(streamMaxLength < 0L) {
-			fprintf(stderr, _("%s: StreamMaxLength must not be negative in %s\n"),
-			argv[0], cfgfile);
-			return EX_CONFIG;
-		}
-	}
-
-	if(((cpt = cfgopt(copt, "LogSyslog")) != NULL) && cpt->enabled) {
-#if defined(USE_SYSLOG) && !defined(C_AIX)
-		int fac = LOG_LOCAL6;
-#endif
-
-		if(cfgopt(copt, "LogVerbose")->enabled) {
-			logg_verbose = 1;
-#ifdef	CL_DEBUG
-#if	((SENDMAIL_VERSION_A > 8) || ((SENDMAIL_VERSION_A == 8) && (SENDMAIL_VERSION_B >= 13)))
-			if(debug_level >= 15)
-				smfi_setdbg(6);
-#endif
-#endif
-		}
-#if defined(USE_SYSLOG) && !defined(C_AIX)
-		logg_syslog = 1;
-
-		if(((cpt = cfgopt(copt, "LogFacility")) != NULL) && cpt->enabled)
-			if((fac = logg_facility(cpt->strarg)) == -1) {
-				fprintf(stderr, "%s: LogFacility: %s: No such facility\n",
-					argv[0], cpt->strarg);
-				return EX_CONFIG;
-			}
-		openlog(progname, LOG_CONS|LOG_PID, fac);
-#endif
-	} else {
-		if(qflag)
-			fprintf(stderr, _("%s: (-q && !LogSyslog): warning - all interception message methods are off\n"),
-				argv[0]);
-#if defined(USE_SYSLOG) && !defined(C_AIX)
-		logg_syslog = 0;
-#endif
-	}
-	/*
-	 * Get the outgoing socket details - the way to talk to clamd, unless
-	 * we're doing the scanning internally
-	 */
-	if(!external) {
-#ifdef	C_LINUX
-		const char *lang;
-#endif
-
-		if(max_children == 0) {
-			fprintf(stderr, _("%s: --max-children must be given if --external is not given\n"), argv[0]);
-			return EX_CONFIG;
-		}
-		if(freshclam_monitor <= 0) {
-			fprintf(stderr, _("%s: --freshclam_monitor must be at least one second\n"), argv[0]);
-			return EX_CONFIG;
-		}
-#ifdef	C_LINUX
-		lang = getenv("LANG");
-
-		if(lang && (strstr(lang, "UTF-8") != NULL)) {
-			fprintf(stderr, "Your LANG environment variable is set to '%s'\n", lang);
-			fprintf(stderr, "This is known to cause problems for some %s installations.\n", argv[0]);
-			fputs("If you get failures with temporary files, please try again with LANG unset.\n", stderr);
-		}
-#endif
-#if	0
-		if(child_timeout) {
-			fprintf(stderr, _("%s: --timeout must not be given if --external is not given\n"), argv[0]);
-			return EX_CONFIG;
-		}
-#endif
-		if (cl_init(CL_INIT_DEFAULT)!=CL_SUCCESS) {
-			fprintf(stderr, "%s: Failed to initialize libclamav, bailing out.\n", argv[0]);
-			return EX_UNAVAILABLE;
-		}
-		if(loadDatabase() != 0) {
-			/*
-			 * Handle the dont-scan-on-error option, which says
-			 * that we pass on emails, unscanned, if an error has
-			 * occurred
-			 */
-			if(cl_error != SMFIS_ACCEPT)
-				return EX_CONFIG;
-
-			fprintf(stderr, _("%s: No emails will be scanned"),
-				argv[0]);
-		}
-		numServers = 1;
-	} else if(((cpt = cfgopt(copt, "LocalSocket")) != NULL) && cpt->enabled) {
-#ifdef	SESSION
-		struct sockaddr_un sockun;
-#endif
-		char *sockname = NULL;
-
-		if(cfgopt(copt, "TCPSocket")->enabled) {
-			fprintf(stderr, _("%s: You can select one server type only (local/TCP) in %s\n"),
-				argv[0], cfgfile);
-			return EX_CONFIG;
-		}
-		if(server) {
-			fprintf(stderr, _("%s: You cannot use the --server option when using LocalSocket in %s\n"),
-				argv[0], cfgfile);
-			return EX_USAGE;
-		}
-		if(strncasecmp(port, "unix:", 5) == 0)
-			sockname = &port[5];
-		else if(strncasecmp(port, "local:", 6) == 0)
-			sockname = &port[6];
-
-		if(sockname && (strcmp(sockname, cpt->strarg) == 0)) {
-			fprintf(stderr, _("The connexion from sendmail to %s (%s) must not\n"),
-				argv[0], sockname);
-			fprintf(stderr, _("be the same as the connexion to clamd (%s) in %s\n"),
-				cpt->strarg, cfgfile);
-			return EX_CONFIG;
-		}
-		/*
-		 * TODO: check --server hasn't been set
-		 */
-		localSocket = cpt->strarg;
-#ifndef	SESSION
-		if(!pingServer(-1)) {
-			fprintf(stderr, _("Can't talk to clamd server via %s\n"),
-				localSocket);
-			fprintf(stderr, _("Check your entry for LocalSocket in %s\n"),
-				cfgfile);
-			return EX_CONFIG;
-		}
-#endif
-		/*if(quarantine_dir == NULL)
-			fprintf(stderr, _("When using Localsocket in %s\nyou may improve performance if you use the --quarantine-dir option\n"), cfgfile);*/
-
-		umask(077);
-
-		serverIPs = (in_addr_t *)cli_malloc(sizeof(in_addr_t));
-#ifdef	INADDR_LOOPBACK
-		serverIPs[0] = htonl(INADDR_LOOPBACK);
-#else
-		serverIPs[0] = inet_addr("127.0.0.1");
-#endif
-
-#ifdef	SESSION
-		memset((char *)&sockun, 0, sizeof(struct sockaddr_un));
-		sockun.sun_family = AF_UNIX;
-		strncpy(sockun.sun_path, localSocket, sizeof(sockun.sun_path));
-		sockun.sun_path[sizeof(sockun.sun_path)-1]='\0';
-
-		sessions = (struct session *)cli_malloc(sizeof(struct session));
-		if((sessions[0].sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
-			perror(localSocket);
-			fprintf(stderr, _("Can't talk to clamd server via %s\n"),
-				localSocket);
-			fprintf(stderr, _("Check your entry for LocalSocket in %s\n"),
-				cfgfile);
-			return EX_CONFIG;
-		}
-		if(connect(sessions[0].sock, (struct sockaddr *)&sockun, sizeof(struct sockaddr_un)) < 0) {
-			perror(localSocket);
-			return EX_UNAVAILABLE;
-		}
-		if(send(sessions[0].sock, "SESSION\n", 8, 0) < 8) {
-			perror("send");
-			fputs(_("!Can't create a clamd session"), stderr);
-			return EX_UNAVAILABLE;
-		}
-		sessions[0].status = CMDSOCKET_FREE;
-#endif
-		/*
-		 * FIXME: Allow connexion to remote servers by TCP/IP whilst
-		 * connecting to the localserver via a UNIX domain socket
-		 */
-		numServers = 1;
-	} else if(((cpt = cfgopt(copt, "TCPSocket")) != NULL) && cpt->enabled) {
-		int activeServers;
-
-		/*
-		 * TCPSocket is in fact a port number not a full socket
-		 */
-		if(quarantine_dir) {
-			fprintf(stderr, _("%s: --quarantine-dir not supported for TCPSocket - use --quarantine\n"), argv[0]);
-			return EX_CONFIG;
-		}
-
-		tcpSocket = (in_port_t)cpt->numarg;
-
-		/*
-		 * cli_strtok's fieldno counts from 0
-		 */
-		for(;;) {
-			char *hostname = cli_strtok(serverHostNames, numServers, ":");
-			if(hostname == NULL)
-				break;
-#ifdef	MAXHOSTNAMELEN
-			if(strlen(hostname) > MAXHOSTNAMELEN) {
-				fprintf(stderr, _("%s: hostname %s is longer than %d characters\n"),
-					argv[0], hostname, MAXHOSTNAMELEN);
-				return EX_CONFIG;
-			}
-#endif
-			numServers++;
-			free(hostname);
-		}
-
-#ifdef	CL_DEBUG
-		printf("numServers: %d\n", numServers);
-#endif
-
-		serverIPs = (in_addr_t *)cli_malloc(numServers * sizeof(in_addr_t));
-		if(serverIPs == NULL)
-			return EX_OSERR;
-		activeServers = 0;
-
-#ifdef	SESSION
-		/*
-		 * We need to know how many connexion to establish to clamd
-		 */
-		if(max_children == 0) {
-			fprintf(stderr, _("%s: --max-children must be given in sessions mode\n"), argv[0]);
-			return EX_CONFIG;
-		}
-#endif
-
-		if(numServers > max_children) {
-			fprintf(stderr, _("%1$s: --max-children (%2$d) is lower than the number of servers you have (%3$d)\n"),
-				argv[0], max_children, numServers);
-			return EX_CONFIG;
-		}
-
-		for(i = 0; i < numServers; i++) {
-#ifdef	MAXHOSTNAMELEN
-			char hostname[MAXHOSTNAMELEN + 1];
-
-			if(cli_strtokbuf(serverHostNames, i, ":", hostname) == NULL)
-				break;
-#else
-			char *hostname = cli_strtok(serverHostNames, i, ":");
-#endif
-
-			/*
-			 * Translate server's name to IP address
-			 */
-			serverIPs[i] = inet_addr(hostname);
-#ifdef	INADDR_NONE
-			if(serverIPs[i] == INADDR_NONE) {
-#else
-			if(serverIPs[i] == (in_addr_t)-1) {
-#endif
-				const struct hostent *h = gethostbyname(hostname);
-
-				if(h == NULL) {
-					fprintf(stderr, _("%s: Unknown host %s\n"),
-						argv[0], hostname);
-					return EX_USAGE;
-				}
-
-				memcpy((char *)&serverIPs[i], h->h_addr, sizeof(serverIPs[i]));
-			}
-
-#if	defined(NTRIES) && ((NTRIES > 1))
-#ifndef	SESSION
-#ifdef	INADDR_LOOPBACK
-			if(serverIPs[i] == htonl(INADDR_LOOPBACK)) {
-#else
-#if	HAVE_IN_ADDR_T
-			if(serverIPs[i] == (in_addr_t)inet_addr("127.0.0.1")) {
-#else
-			if(serverIPs[i] == (long)inet_addr("127.0.0.1")) {
-#endif
-#endif
-				int tries;
-
-				/*
-				 * Fudge to allow clamd to come up on
-				 * our local machine
-				 */
-				for(tries = 0; tries < NTRIES - 1; tries++) {
-					if(pingServer(i))
-						break;
-					if(checkClamd(1))	/* will try all servers */
-						break;
-					puts(_("Waiting for clamd to come up"));
-					/*
-					 * something to do as the system starts
-					 */
-					sync();
-					sleep(1);
-				}
-				/* Will try one more time */
-			}
-#endif	/* NTRIES > 1 */
-
-			if(pingServer(i))
-				activeServers++;
-			else {
-				printf(_("Can't talk to clamd server %s on port %d\n"),
-					hostname, tcpSocket);
-				if(serverIPs[i] == htonl(INADDR_LOOPBACK)) {
-					if(cfgopt(copt, "TCPAddr")->enabled)
-						printf(_("Check the value for TCPAddr in %s\n"), cfgfile);
-				} else
-					printf(_("Check the value for TCPAddr in clamd.conf on %s\n"), hostname);
-			}
-#endif
-
-#ifndef	MAXHOSTNAMELEN
-			free(hostname);
-#endif
-		}
-#ifdef	SESSION
-		activeServers = numServers;
-
-		sessions = (struct session *)cli_calloc(max_children, sizeof(struct session));
-		for(i = 0; i < (int)max_children; i++)
-			if(createSession(i) < 0)
-				return EX_UNAVAILABLE;
-		if(activeServers == 0) {
-			fprintf(stderr, _("Check your entry for TCPSocket in %s\n"),
-				cfgfile);
-		}
-#else
-		if(activeServers == 0) {
-			fprintf(stderr, _("Check your entry for TCPSocket in %s\n"),
-				cfgfile);
-			fputs(_("Can't find any clamd server\n"), stderr);
-			return EX_CONFIG;
-		}
-		last_failed_pings = (time_t *)cli_calloc(numServers, sizeof(time_t));
-#endif
-	} else {
-		fprintf(stderr, _("%s: You must select server type (local/TCP) in %s\n"),
-			argv[0], cfgfile);
-		return EX_CONFIG;
-	}
-
-#ifdef	SESSION
-	if(!external) {
-		if(clamav_versions == NULL) {
-			clamav_versions = (char **)cli_malloc(sizeof(char *));
-			if(clamav_versions == NULL)
-				return EX_TEMPFAIL;
-			clamav_version = cli_strdup(version);
-		}
-	} else {
-		unsigned int session;
-
-		/*
-		 * We need to know how many connexions to establish to clamd
-		 */
-		if(max_children == 0) {
-			fprintf(stderr, _("%s: --max-children must be given in sessions mode\n"), argv[0]);
-			return EX_CONFIG;
-		}
-
-		clamav_versions = (char **)cli_malloc(max_children * sizeof(char *));
-		if(clamav_versions == NULL)
-			return EX_TEMPFAIL;
-
-		for(session = 0; session < max_children; session++) {
-			clamav_versions[session] = cli_strdup(version);
-			if(clamav_versions[session] == NULL)
-				return EX_TEMPFAIL;
-		}
-	}
-#else
-	strcpy(clamav_version, version);
-#endif
-
-	if(((quarantine_dir == NULL) && localSocket) || !external) {
-		/* set the temporary dir */
-		if((cpt = cfgopt(copt, "TemporaryDirectory")) && cpt->enabled) {
-			tmpdir = cpt->strarg;
-			/*
-			 * FIXME: replace this:
-			  cl_settempdir(tmpdir, (short)(cfgopt(copt, "LeaveTemporaryFiles")->enabled)); *
-			 * with:
-			 * cl_engine_set(engine, CL_ENGINE_TMPDIR, cpt->strarg);
-			 * somewhere...
-			 */
-		} else if((tmpdir = getenv("TMPDIR")) == (char *)NULL)
-			if((tmpdir = getenv("TMP")) == (char *)NULL)
-				if((tmpdir = getenv("TEMP")) == (char *)NULL)
-#ifdef	P_tmpdir
-					tmpdir = P_tmpdir;
-#else
-					tmpdir = "/tmp";
-#endif
-
-		/*
-		 * TODO: investigate mkdtemp on LINUX and possibly others
-		 */
-		tmpdir = cli_gentemp(NULL);
-
-		cli_dbgmsg("Making %s\n", tmpdir);
-
-		if(mkdir(tmpdir, 0700)) {
-			perror(tmpdir);
-			return EX_CANTCREAT;
-		}
-	} else
-		tmpdir = NULL;
-
-	if(report) {
-		if(!cfgopt(copt, "PhishingSignatures")->enabled) {
-			fprintf(stderr, "%s: You have chosen --report-phish, but PhishingSignatures is off in %s\n",
-				argv[0], cfgfile);
-			return EX_USAGE;
-		}
-		if((quarantine_dir == NULL) && (tmpdir == NULL)) {
-			/*
-			 * Limitation: doesn't store message in a temporary
-			 * file, so we won't be able to use mail < file
-			 */
-			fprintf(stderr, "%s: when using --external, --report-phish cannot be used without either LocalSocket or --quarantine-dir\n",
-				argv[0]);
-			return EX_USAGE;
-		}
-		if(lflag) {
-			/*
-			 * Naturally, if you attempt to scan the phish you've
-			 * just reported, it'll be blocked!
-			 */
-			fprintf(stderr, "%s: --report-phish cannot be used with --local\n",
-				argv[0]);
-			return EX_USAGE;
-		}
-	}
-	if(report_fps)
-		if(!cfgopt(copt, "PhishingSignatures")->enabled) {
-			fprintf(stderr, "%s: You have chosen --report-phish-false-positives, but PhishingSignatures is off in %s\n",
-				argv[0], cfgfile);
-			return EX_USAGE;
-		}
-
-	if(cfgopt(copt, "Foreground")->enabled)
-		logg_foreground = 1;
-	else {
-		logg_foreground = 0;
-#ifdef	CL_DEBUG
-		printf(_("When debugging it is recommended that you use Foreground mode in %s\n"), cfgfile);
-		puts(_("\tso that you can see all of the messages"));
-#endif
-
-		switch(fork()) {
-			case -1:
-				perror("fork");
-				return EX_OSERR;
-			case 0:	/* child */
-				break;
-			default:	/* parent */
-				return EX_OK;
-		}
-		close(0);
-		open("/dev/null", O_RDONLY);
-
-		/* initialize logger */
-		logg_lock = cfgopt(copt, "LogFileUnlock")->enabled;
-		logg_time = cfgopt(copt, "LogTime")->enabled;
-		logok = cfgopt(copt, "LogClean")->enabled;
-		logg_size = cfgopt(copt, "LogFileMaxSize")->numarg;
-		logg_verbose = mprintf_verbose = cfgopt(copt, "LogVerbose")->enabled;
-
-		if(cfgopt(copt, "Debug")->enabled) /* enable debug messages in libclamav */
-			cl_debug();
-
-		if((cpt = cfgopt(copt, "LogFile"))->enabled) {
-			time_t currtime;
-
-			logg_file = cpt->strarg;
-			if((strlen(logg_file) < 2) ||
-			   ((logg_file[0] != '/') && (logg_file[0] != '\\') && (logg_file[1] != ':'))) {
-				fprintf(stderr, "ERROR: LogFile requires full path.\n");
-				logg_close();
-				freecfg(copt);
-				return 1;
-			}
-			time(&currtime);
-			close(1);
-			if(logg("#ClamAV-milter started at %s", ctime(&currtime))) {
-				fprintf(stderr, "ERROR: Problem with internal logger. Please check the permissions on the %s file.\n", logg_file);
-				logg_close();
-				freecfg(copt);
-				return 1;
-			}
-		} else {
-#ifdef	CL_DEBUG
-			close(1);
-			logg_file = console;
-			if(consolefd < 0) {
-				perror(console);
-				return EX_OSFILE;
-			}
-			dup(consolefd);
-#else
-			int fds[3];
-			logg_file = NULL;
-			if(chdir("/") < 0)
-				perror("/");
-			fds[0] = open("/dev/null", O_RDONLY);
-			fds[1] = open("/dev/null", O_WRONLY);
-			fds[2] = open("/dev/null", O_WRONLY);
-			for(i = 0; i <= 2; i++) {
-				if(fds[i] == -1 || dup2(fds[i], i) == -1) {
-					fprintf(stderr, "ERROR: failed to daemonize.\n");
-					logg_close();
-					freecfg(copt);
-					return 1;
-				}
-			}
-#endif
-		}
-
-		dup2(1, 2);
-
-#ifdef	CL_DEBUG
-		if(consolefd >= 0)
-			close(consolefd);
-#endif
-
-#ifdef HAVE_SETPGRP
-#ifdef SETPGRP_VOID
-		setpgrp();
-#else
-		setpgrp(0,0);
-#endif
-#else
-#ifdef HAVE_SETSID
-		setsid();
-#endif
-#endif
-	}
-
-	if(cfgopt(copt, "Debug")->enabled)
-		/*
-		 * enable debug messages in libclamav, --debug also does this
-		 */
-		cl_debug();
-
-	atexit(quit);
-
-	if(!external) {
-		if(!cfgopt(copt, "ScanMail")->enabled)
-			printf(_("%s: ScanMail not defined in %s (needed without --external), enabling\n"),
-				argv[0], cfgfile);
-
-		options |= CL_SCAN_MAIL;	/* no choice */
-		/*if(!cfgopt(copt, "ScanRAR")->enabled)
-			options |= CL_SCAN_DISABLERAR;*/
-		if(cfgopt(copt, "ArchiveBlockEncrypted")->enabled)
-			options |= CL_SCAN_BLOCKENCRYPTED;
-		if(cfgopt(copt, "ScanPE")->enabled)
-			options |= CL_SCAN_PE;
-		if(cfgopt(copt, "DetectBrokenExecutables")->enabled)
-			options |= CL_SCAN_BLOCKBROKEN;
-		if(cfgopt(copt, "MailFollowURLs")->enabled)
-			options |= CL_SCAN_MAILURL;
-		if(cfgopt(copt, "ScanOLE2")->enabled)
-			options |= CL_SCAN_OLE2;
-		if(cfgopt(copt, "ScanHTML")->enabled)
-			options |= CL_SCAN_HTML;
-
-		if(((cpt = cfgopt(copt, "MaxScanSize")) != NULL) && cpt->enabled)
-			maxscansize = cpt->numarg;
-		else
-			maxscansize = 104857600;
-		if(((cpt = cfgopt(copt, "MaxFileSize")) != NULL) && cpt->enabled)
-			maxfilesize = cpt->numarg;
-		else
-			maxfilesize = 10485760;
-
-		if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
-			if((rlim.rlim_max < maxfilesize) || (rlim.rlim_max < maxscansize))
-				logg("^System limit for file size is lower than maxfilesize or maxscansize\n");
-		} else {
-			logg("^Cannot obtain resource limits for file size\n");
-		}
-
-		if(((cpt = cfgopt(copt, "MaxRecursion")) != NULL) && cpt->enabled)
-			maxreclevel = cpt->numarg;
-		else
-			maxreclevel = 8;
-
-		if(((cpt = cfgopt(copt, "MaxFiles")) != NULL) && cpt->enabled)
-			maxfiles = cpt->numarg;
-		else
-			maxfiles = 1000;
-
-		if(cfgopt(copt, "ScanArchive")->enabled)
-			options |= CL_SCAN_ARCHIVE;
-	}
-
-	pthread_create(&tid, NULL, watchdog, NULL);
-
-	if(((cpt = cfgopt(copt, "PidFile")) != NULL) && cpt->enabled)
-		pidFile = cpt->strarg;
-
-	broadcast(_("Starting clamav-milter"));
-
-	if(rootdir) {
-		if(getuid() == 0) {
-			if(chdir(rootdir) < 0) {
-				perror(rootdir);
-				logg("!chdir %s failed\n", rootdir);
-				return EX_CONFIG;
-			}
-			if(chroot(rootdir) < 0) {
-				perror(rootdir);
-				logg("!chroot %s failed\n", rootdir);
-				return EX_CONFIG;
-			}
-			logg("Chrooted to %s\n", rootdir);
-		} else {
-			logg("!chroot option needs root\n");
-			return EX_CONFIG;
-		}
-	}
-
-	if(pidfile) {
-		/* save the PID */
-		char *p, *q;
-		FILE *fd;
-		const mode_t old_umask = umask(0006);
-
-		if(pidfile[0] != '/') {
-			logg(_("!pidfile: '%s' must be a full pathname"),
-				pidfile);
-
-			return EX_CONFIG;
-		}
-		p = cli_strdup(pidfile);
-		q = strrchr(p, '/');
-		*q = '\0';
-
-		if(rootdir == NULL)
-			if(chdir(p) < 0)	/* safety */
-				perror(p);
-
-		free(p);
-
-		if((fd = fopen(pidfile, "w")) == NULL) {
-			logg(_("!Can't save PID in file %s\n"), pidfile);
-			return EX_CONFIG;
-		}
-#ifdef	C_LINUX
-		/* Ensure that all threads are kill()ed */
-		fprintf(fd, "-%d\n", (int)getpgrp());
-#else
-		fprintf(fd, "%d\n", (int)getpid());
-#endif
-		fclose(fd);
-		umask(old_umask);
-	} else if(tmpdir) {
-		if(rootdir == NULL)
-			if(chdir(tmpdir) < 0) {	/* safety */
-				perror(tmpdir);
-				logg("!chdir %s failed\n", tmpdir);
-			}
-	} else
-		if(rootdir == NULL)
-#ifdef	P_tmpdir
-			if(chdir(P_tmpdir) < 0) {
-				perror(P_tmpdir);
-				logg("!chdir %s failed\n", P_tmpdir);
-			}
-#else
-			if(chdir("/tmp") < 0) {
-				perror("/tmp");
-				logg("!chdir /tmp failed\n", P_tmpdir);
-			}
-#endif
-
-	if(cfgopt(copt, "FixStaleSocket")->enabled) {
-		/*
-		 * Get the incoming socket details - the way sendmail talks to
-		 * us
-		 *
-		 * TODO: There's a security problem here that'll need fixing if
-		 * the User entry of clamd.conf is not used
-		 */
-		if(strncasecmp(port, "unix:", 5) == 0) {
-			if(unlink(&port[5]) < 0)
-				if(errno != ENOENT)
-					perror(&port[5]);
-		} else if(strncasecmp(port, "local:", 6) == 0) {
-			if(unlink(&port[6]) < 0)
-				if(errno != ENOENT)
-					perror(&port[6]);
-		} else if(port[0] == '/') {
-			if(unlink(port) < 0)
-				if(errno != ENOENT)
-					perror(port);
-		}
-	}
-
-	if(smfi_setconn(port) == MI_FAILURE) {
-		cli_errmsg("smfi_setconn failure\n");
-		return EX_SOFTWARE;
-	}
-
-	if(smfi_register(smfilter) == MI_FAILURE) {
-		fprintf(stderr, "smfi_register failure, ensure that you have linked against the correct version of sendmail\n");
-		return EX_UNAVAILABLE;
-	}
-
-#if	((SENDMAIL_VERSION_A > 8) || ((SENDMAIL_VERSION_A == 8) && (SENDMAIL_VERSION_B >= 13)))
-	if(smfi_opensocket(1) == MI_FAILURE) {
-		perror(port);
-		fprintf(stderr, "Can't open/create %s\n", port);
-		return EX_CONFIG;
-	}
-#endif
-
-	signal(SIGPIPE, SIG_IGN);	/* libmilter probably does this as well */
-	signal(SIGXFSZ, SIG_IGN); /* TODO: check if it's safe to call signal() here */
-
-#ifdef	SESSION
-	pthread_mutex_lock(&version_mutex);
-#endif
-	logg(_("Starting %s\n"), clamav_version);
-	logg(_("*Debugging is on\n"));
-
-#ifdef HAVE_RESOLV_H
-#if ! defined(HAVE_LRESOLV_R)
-	if(!(_res.options&RES_INIT))
-		if(res_init() < 0) {
-			fprintf(stderr, "%s: Can't initialise the resolver\n",
-				argv[0]);
-			return EX_UNAVAILABLE;
-		}
-#endif
-	if(blacklist_time) {
-		char name[MAXHOSTNAMELEN + 1];
-
-		if(gethostname(name, sizeof(name)) < 0) {
-			perror("gethostname");
-			return EX_UNAVAILABLE;
-		}
-
-		blacklist = mx(name, NULL);
-		if(blacklist)
-			/* We must never blacklist ourself */
-			tableInsert(blacklist, "127.0.0.1", 0);
-
-		if(wont_blacklist) {
-			char *w;
-
-			i = 0;
-			while((w = cli_strtok(wont_blacklist, i++, ",")) != NULL) {
-				(void)tableInsert(blacklist, w, 0);
-				free(w);
-			}
-		}
-		tableIterate(blacklist, dump_blacklist, NULL);
-	}
-#endif /* HAVE_RESOLV_H */
-
-#ifdef	SESSION
-	pthread_mutex_unlock(&version_mutex);
-#endif
-
-	(void)signal(SIGSEGV, sigsegv);
-	if(!logg_foreground)
-		(void)signal(SIGUSR1, sigusr1);
-	if(!external)
-		(void)signal(SIGUSR2, sigusr2);
-
-	return smfi_main();
-}
-
-#ifdef	SESSION
-/*
- * Use the SESSION command of clamd.
- * Returns -1 for terminal failure, 0 for OK, 1 for nonterminal failure
- * The caller must take care of locking the sessions array
- */
-static int
-createSession(unsigned int s)
-{
-	int ret = 0, fd;
-	const int serverNumber = s % numServers;
-	struct session *session = &sessions[s];
-	const struct protoent *proto;
-	struct sockaddr_in server;
-
-	cli_dbgmsg("createSession session %d, server %d\n", s, serverNumber);
-	assert(s < max_children);
-
-	memset((char *)&server, 0, sizeof(struct sockaddr_in));
-	server.sin_family = AF_INET;
-	server.sin_port = (in_port_t)htons(tcpSocket);
-
-	server.sin_addr.s_addr = serverIPs[serverNumber];
-
-	session->sock = -1;
-	proto = getprotobyname("tcp");
-	if(proto == NULL) {
-		fputs("Unknown prototol tcp, check /etc/protocols\n", stderr);
-		fd = ret = -1;
-	} else if((fd = socket(AF_INET, SOCK_STREAM, proto->p_proto)) < 0) {
-		perror("socket");
-		ret = -1;
-	} else if(connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
-		perror("connect");
-		ret = 1;
-	} else if(send(fd, "SESSION\n", 8, 0) < 8) {
-		perror("send");
-		ret = 1;
-	}
-
-	if(ret != 0) {
-#ifdef	MAXHOSTNAMELEN
-		char hostname[MAXHOSTNAMELEN + 1];
-
-		cli_strtokbuf(serverHostNames, serverNumber, ":", hostname);
-		if(strcmp(hostname, "127.0.0.1") == 0)
-			gethostname(hostname, sizeof(hostname));
-#else
-		char *hostname = cli_strtok(serverHostNames, serverNumber, ":");
-#endif
-
-		session->status = CMDSOCKET_DOWN;
-
-		if(fd >= 0)
-			close(fd);
-
-		cli_warnmsg(_("Check clamd server %s - it may be down\n"), hostname);
-#ifndef	MAXHOSTNAMELEN
-		free(hostname);
-#endif
-
-		broadcast(_("Check clamd server - it may be down"));
-	} else
-		session->sock = fd;
-
-	return ret;
-}
-
-#else
-
-/*
- * Verify that the server is where we think it is
- * Returns true or false
- *
- * serverNumber counts from 0, but is only used for TCPSocket
- */
-static int
-pingServer(int serverNumber)
-{
-	char *ptr;
-	int sock;
-	long nbytes;
-	char buf[128];
-
-	if(localSocket) {
-		struct sockaddr_un server;
-
-		memset((char *)&server, 0, sizeof(struct sockaddr_un));
-		server.sun_family = AF_UNIX;
-		strncpy(server.sun_path, localSocket, sizeof(server.sun_path));
-		server.sun_path[sizeof(server.sun_path)-1]='\0';
-
-		if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
-			perror(localSocket);
-			return 0;
-		}
-		checkClamd(1);
-		if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_un)) < 0) {
-			perror(localSocket);
-			close(sock);
-			return 0;
-		}
-	} else {
-		struct sockaddr_in server;
-		char *hostname;
-
-		memset((char *)&server, 0, sizeof(struct sockaddr_in));
-		server.sin_family = AF_INET;
-		server.sin_port = (in_port_t)htons(tcpSocket);
-
-		assert(serverIPs != NULL);
-#ifdef	INADDR_NONE
-		assert(serverIPs[0] != INADDR_NONE);
-#else
-		assert(serverIPs[0] != (in_addr_t)-1);
-#endif
-
-		server.sin_addr.s_addr = serverIPs[serverNumber];
-
-		if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-			perror("socket");
-			return 0;
-		}
-		hostname = cli_strtok(serverHostNames, serverNumber, ":");
-		/*
-		 * FIXME: use non-blocking connect, once the code is
-		 * amalgomated
-		 */
-		if(nonblock_connect(sock, &server, hostname) < 0) {
-			int is_connected = 0;
-
-#if	(!defined(NTRIES)) || ((NTRIES <= 1))
-			if(errno == ECONNREFUSED) {
-				/*
-				 * During startup there is a race condition:
-				 * clamd can start and fork, then rc will start
-				 * clamav-milter before clamd has run accept(2),
-				 * so we fail to connect.
-				 * In case this is the situation here, we wait
-				 * for a couple of seconds and try again. The
-				 * sync() is because during startup the machine
-				 * won't be doing much for most of the time, so
-				 * we may as well do something constructive!
-				 */
-				sync();
-				sleep(2);
-				if(nonblock_connect(sock, &server, hostname) >= 0)
-					is_connected = 1;
-			}
-#endif
-			if(!is_connected) {
-				if(errno != EINPROGRESS)
-					perror(hostname ? hostname : "connect");
-				close(sock);
-				if(hostname)
-					free(hostname);
-				return 0;
-			}
-		}
-		if(hostname)
-			free(hostname);
-	}
-
-	/*
-	 * It would be better to use PING, check for PONG then issue the
-	 * VERSION command, since that would better validate that we're
-	 * talking to clamd, however clamd closes the session after
-	 * sending PONG :-(
-	 * So this code does not really validate that we're talking to clamd
-	 * Needs a fix to clamd
-	 * Also version command is verbose: says "clamd / ClamAV version"
-	 * instead of "clamAV version"
-	 */
-	cli_dbgmsg("pingServer%d: sending VERSION\n", serverNumber);
-	if(send(sock, "VERSION\n", 8, 0) < 8) {
-		perror("send");
-		return close(sock);
-	}
-
-	shutdown(sock, SHUT_WR);
-
-	nbytes = clamd_recv(sock, buf, sizeof(buf) - 1);
-
-	close(sock);
-
-	if(nbytes < 0) {
-		perror("recv");
-		return 0;
-	}
-	if(nbytes == 0)
-		return 0;
-
-	buf[nbytes] = '\0';
-
-	/* Remove the trailing new line from the reply */
-	if((ptr = strchr(buf, '\n')) != NULL)
-		*ptr = '\0';
-
-	/*
-	 * No real validation is done here
-	 *
-	 * TODO: When connecting to more than one server, give a warning
-	 *	if they're running different versions, or if the virus DBs
-	 *	are out of date (say more than a month old)
-	 */
-	snprintf(clamav_version, sizeof(clamav_version) - 1,
-		"%s\n\tclamav-milter version %s",
-		buf, get_version());
-
-	return 1;
-}
-#endif
-
-/*
- * Find the best server to connect to. No intelligence to this.
- * It is best to weight the order of the servers from most wanted to least
- * wanted
- *
- * Return value is from 0 - index into sessions array
- *
- * If the load balancing fails return the first server in the list, not
- * an error, to be on the safe side
- */
-#ifdef	SESSION
-static int
-findServer(void)
-{
-	unsigned int i, j;
-	struct session *session;
-
-	/*
-	 * FIXME: Sessions code isn't flexible at handling servers
-	 *	appearing and disappearing, e.g. sessions[n_children].sock == -1
-	 */
-	i = 0;
-	pthread_mutex_lock(&n_children_mutex);
-	assert(n_children > 0);
-	assert(n_children <= max_children);
-	j = n_children - 1;
-	pthread_mutex_unlock(&n_children_mutex);
-
-	pthread_mutex_lock(&sstatus_mutex);
-	for(; i < max_children; i++) {
-		const int sess = (j + i) % max_children;
-
-		session = &sessions[sess];
-		cli_dbgmsg("findServer: try server %d\n", sess);
-		if(session->status == CMDSOCKET_FREE) {
-			session->status = CMDSOCKET_INUSE;
-			pthread_mutex_unlock(&sstatus_mutex);
-			return sess;
-		}
-	}
-	pthread_mutex_unlock(&sstatus_mutex);
-
-	/*
-	 * No session free - wait until one comes available. Only
-	 * retries once.
-	 */
-	if(pthread_cond_broadcast(&watchdog_cond) < 0)
-		perror("pthread_cond_broadcast");
-
-	i = 0;
-	session = sessions;
-	pthread_mutex_lock(&sstatus_mutex);
-	for(; i < max_children; i++, session++) {
-		cli_dbgmsg("findServer: try server %d\n", i);
-		if(session->status == CMDSOCKET_FREE) {
-			session->status = CMDSOCKET_INUSE;
-			pthread_mutex_unlock(&sstatus_mutex);
-			return i;
-		}
-	}
-	pthread_mutex_unlock(&sstatus_mutex);
-
-	cli_warnmsg(_("No free clamd sessions\n"));
-
-	return -1;	/* none available - must fail */
-}
-#else
-/*
- * Return value is from 0 - index into serverIPs
- */
-static int
-findServer(void)
-{
-	struct sockaddr_in *servers, *server;
-	int maxsock, i, j, active;
-	int retval;
-	pthread_t *tids;
-	struct try_server_struct *socks;
-	fd_set rfds;
-
-	assert(tcpSocket != 0);
-	assert(numServers > 0);
-
-	if(numServers == 1)
-		return 0;
-
-	if(active_servers(&active) <= 1)
-		return active;
-
-	servers = (struct sockaddr_in *)cli_calloc(numServers, sizeof(struct sockaddr_in));
-	if(servers == NULL)
-		return 0;
-	socks = (struct try_server_struct *)cli_malloc(numServers * sizeof(struct try_server_struct));
-
-	if(max_children > 0) {
-		assert(n_children > 0);
-		assert(n_children <= max_children);
-
-		/*
-		 * Don't worry about no lock - it's doesn't matter if it's
-		 * not really accurate
-		 */
-		j = n_children - 1;	/* look at the next free one */
-		if(j < 0)
-			j = 0;
-	} else
-		/*
-		 * cli_rndnum returns 0..max
-		 */
-		j = cli_rndnum(numServers - 1);
-
-	for(i = 0; i < numServers; i++)
-		socks[i].sock = -1;
-
-	tids = cli_malloc(numServers * sizeof(pthread_t));
-
-	for(i = 0, server = servers; i < numServers; i++, server++) {
-		int sock;
-		int server_index = (i + j) % numServers;
-
-		server->sin_family = AF_INET;
-		server->sin_port = (in_port_t)htons(tcpSocket);
-		server->sin_addr.s_addr = serverIPs[server_index];
-
-		logg("*findServer: try server %d\n", server_index);
-
-		sock = socks[i].sock = socket(AF_INET, SOCK_STREAM, 0);
-
-		if(sock < 0) {
-			perror("socket");
-			while(i--) {
-				pthread_join(tids[i], NULL);
-				if(socks[i].sock >= 0)
-					close(socks[i].sock);
-			}
-			free(socks);
-			free(servers);
-			free(tids);
-			return 0;	/* Use the first server on failure */
-		}
-
-		socks[i].server = server;
-		socks[i].server_index = server_index;
-
-		if(pthread_create(&tids[i], NULL, try_server, &socks[i]) != 0) {
-			perror("pthread_create");
-			j = i;
-			do {
-				if (j!=i) pthread_join(tids[i], NULL);
-				if(socks[i].sock >= 0)
-					close(socks[i].sock);
-			} while(--i >= 0);
-			free(socks);
-			free(servers);
-			free(tids);
-			return 0;	/* Use the first server on failure */
-		}
-	}
-
-	maxsock = -1;
-	FD_ZERO(&rfds);
-
-	for(i = 0; i < numServers; i++) {
-		struct try_server_struct *rc;
-
-		pthread_join(tids[i], (void **)&rc);
-		assert(rc->sock == socks[i].sock);
-		if(rc->rc == 0) {
-			close(rc->sock);
-			socks[i].sock = -1;
-		} else {
-			shutdown(rc->sock, SHUT_WR);
-			FD_SET(rc->sock, &rfds);
-			if(rc->sock > maxsock)
-				maxsock = rc->sock;
-		}
-	}
-
-	free(servers);
-	free(tids);
-
-	if(maxsock == -1) {
-		logg(_("^Couldn't establish a connexion to any clamd server\n"));
-		retval = 0;
-	} else {
-		struct timeval tv;
-
-		tv.tv_sec = readTimeout ? readTimeout : DEFAULT_TIMEOUT;
-		tv.tv_usec = 0;
-
-		retval = select(maxsock + 1, &rfds, NULL, NULL, &tv);
-	}
-
-	if(retval < 0)
-		perror("select");
-
-	for(i = 0; i < numServers; i++)
-		if(socks[i].sock >= 0)
-			close(socks[i].sock);
-
-	if(retval == 0) {
-		free(socks);
-		clamdIsDown();
-		return 0;
-	} else if(retval < 0) {
-		free(socks);
-		logg(_("^findServer: select failed (maxsock = %d)\n"), maxsock);
-		return 0;
-	}
-
-	for(i = 0; i < numServers; i++)
-		if((socks[i].sock >= 0) && (FD_ISSET(socks[i].sock, &rfds))) {
-			const int s = (i + j) % numServers;
-
-			free(socks);
-			logg("*findServer: use server %d\n", s);
-			return s;
-		}
-
-	free(socks);
-	logg(_("^findServer: No response from any server\n"));
-	return 0;
-}
-
-/*
- * How many servers are up at the moment? If a server is marked as down,
- *	don't keep on flooding it with requests to see if it's now back up
- * If only one server is active, let the caller know, which server is the
- *	active one
- */
-static int
-active_servers(int *active)
-{
-	int server, count;
-	time_t now = (time_t)0;
-
-	for(count = server = 0; server < numServers; server++)
-		if(last_failed_pings[server] == (time_t)0) {
-			*active = server;
-			count++;
-		} else {
-			if(now == (time_t)0)
-				time(&now);
-			if(now - last_failed_pings[server] >= RETRY_SECS)
-				/* Try this server again next time */
-				last_failed_pings[server] = (time_t)0;
-		}
-
-	if(count != 1)
-		*active = 0;
-	return count;
-}
-
-/*
- * Connecting to remote servers can take some time, so let's connect to
- *	them in parallel. This routine is started as a thread
- */
-static void *
-try_server(void *var)
-{
-	struct try_server_struct *s = (struct try_server_struct *)var;
-	int sock = s->sock;
-	struct sockaddr *server = (struct sockaddr *)s->server;
-	int server_index = s->server_index;
-
-	if(last_failed_pings[server_index]) {
-		s->rc = 0;
-		return var;
-	}
-
-	logg("*try_server: sock %d\n", sock);
-
-	if((connect(sock, server, sizeof(struct sockaddr)) < 0) ||
-	   (send(sock, "PING\n", 5, 0) < 5)) {
-		time(&last_failed_pings[server_index]);
-		s->rc = 0;
-	} else
-		s->rc = 1;
-
-	if(s->rc == 0) {
-#ifdef	MAXHOSTNAMELEN
-		char hostname[MAXHOSTNAMELEN + 1];
-
-		cli_strtokbuf(serverHostNames, server_index, ":", hostname);
-		if(strcmp(hostname, "127.0.0.1") == 0)
-			gethostname(hostname, sizeof(hostname));
-#else
-		char *hostname = cli_strtok(serverHostNames, server_index, ":");
-#endif
-		perror(hostname);
-		logg(_("^Check clamd server %s - it may be down\n"), hostname);
-#ifndef	MAXHOSTNAMELEN
-		free(hostname);
-#endif
-		broadcast(_("Check clamd server - it may be down\n"));
-	}
-
-	return var;
-}
-#endif
-
-/*
- * Sendmail wants to establish a connexion to us
- * TODO: is it possible (desirable?) to determine if the remote machine has been
- *	compromised?
- */
-static sfsistat
-clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr)
-{
-#if	defined(HAVE_INET_NTOP) || defined(WITH_TCPWRAP)
-	char ip[INET6_ADDRSTRLEN];
-#endif
-	int t;
-	const char *remoteIP;
-	struct privdata *privdata;
-
-	if(quitting)
-		return cl_error;
-
-	if(ctx == NULL) {
-		logg(_("!clamfi_connect: ctx is null"));
-		return cl_error;
-	}
-	if(hostname == NULL) {
-		logg(_("!clamfi_connect: hostname is null"));
-		return cl_error;
-	}
-	if(smfi_getpriv(ctx) != NULL) {
-		/* More than one connexion command, "can't happen" */
-		cli_warnmsg("clamfi_connect: called more than once\n");
-		clamfi_cleanup(ctx);
-		return cl_error;
-	}
-#ifdef AF_INET6
-	if((hostaddr == NULL) ||
-	   ((hostaddr->sa_family == AF_INET) && (&(((struct sockaddr_in *)(hostaddr))->sin_addr) == NULL)) ||
-	   ((hostaddr->sa_family == AF_INET6) && (&(((struct sockaddr_in6 *)(hostaddr))->sin6_addr) == NULL)))
-#else
-	if((hostaddr == NULL) || (&(((struct sockaddr_in *)(hostaddr))->sin_addr) == NULL))
-#endif
-		/*
-		 * According to the sendmail API hostaddr is NULL if
-		 * "the type is not supported in the current version". What
-		 * the documentation doesn't say is the type of what.
-		 *
-		 * Possibly the input is not a TCP/IP socket e.g. stdin?
-		 */
-		remoteIP = "127.0.0.1";
-	else {
-#ifdef HAVE_INET_NTOP
-		switch(hostaddr->sa_family) {
-			case AF_INET:
-				remoteIP = (const char *)inet_ntop(AF_INET, &((struct sockaddr_in *)(hostaddr))->sin_addr, ip, sizeof(ip));
-				break;
-#ifdef AF_INET6
-			case AF_INET6:
-				remoteIP = (const char *)inet_ntop(AF_INET6, &((struct sockaddr_in6 *)(hostaddr))->sin6_addr, ip, sizeof(ip));
-				break;
-#endif
-			default:
-				logg(_("clamfi_connect: Unexpected sa_family %d\n"),
-					hostaddr->sa_family);
-				return cl_error;
-		}
-
-#else
-		remoteIP = inet_ntoa(((struct sockaddr_in *)(hostaddr))->sin_addr);
-#endif
-
-		if(remoteIP == NULL) {
-			logg(_("clamfi_connect: remoteIP is null"));
-			return cl_error;
-		}
-	}
-
-#ifdef	CL_DEBUG
-	if(debug_level >= 4) {
-		if(hostname[0] == '[')
-			logg(_("clamfi_connect: connexion from %s"), remoteIP);
-		else
-			logg(_("clamfi_connect: connexion from %s [%s]"), hostname, remoteIP);
-	}
-#endif
-
-#ifdef	WITH_TCPWRAP
-	/*
-	 * Support /etc/hosts.allow and /etc/hosts.deny
-	 */
-	if(strncasecmp(port, "inet:", 5) == 0) {
-		const char *hostmail;
-		struct hostent hostent;
-		char buf[BUFSIZ];
-		static pthread_mutex_t wrap_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-		/*
-		 * Using TCP/IP for the sendmail->clamav-milter connexion
-		 */
-		if(((hostmail = smfi_getsymval(ctx, "{if_name}")) == NULL) &&
-		   ((hostmail = smfi_getsymval(ctx, "j")) == NULL)) {
-			logg(_("Can't get sendmail hostname"));
-			return cl_error;
-		}
-		/*
-		 * Use hostmail for error statements, not hostname, suggestion
-		 * by Yar Tikhiy <yar at comp.chem.msu.su>
-		 */
-		if(r_gethostbyname(hostmail, &hostent, buf, sizeof(buf)) != 0) {
-			logg(_("^Access Denied: Host Unknown (%s)"), hostmail);
-			if(hostmail[0] == '[')
-				/*
-				 * A case could be made that it's not clamAV's
-				 * job to check a system's DNS configuration
-				 * and let this message through. However I am
-				 * just too worried about any knock on effects
-				 * to do that...
-				 */
-				cli_warnmsg(_("Can't find entry for IP address %s in DNS - check your DNS setting\n"),
-					hostmail);
-			return cl_error;
-		}
-
-#ifdef HAVE_INET_NTOP
-		if(hostent.h_addr &&
-		   (inet_ntop(AF_INET, (struct in_addr *)hostent.h_addr, ip, sizeof(ip)) == NULL)) {
-			perror(hostent.h_name);
-			/*strcpy(ip, (char *)inet_ntoa(*(struct in_addr *)hostent.h_addr));*/
-			logg(_("^Access Denied: Can't get IP address for (%s)"), hostent.h_name);
-			return cl_error;
-		}
-#else
-		strncpy(ip, (char *)inet_ntoa(*(struct in_addr *)hostent.h_addr), sizeof(ip));
-		ip[sizeof(ip)-1]='\0';
-#endif
-
-		/*
-		 * Ask is this is a allowed name or IP number
-		 *
-		 * hosts_ctl uses strtok so it is not thread safe, see
-		 * hosts_access(3)
-		 */
-		pthread_mutex_lock(&wrap_mutex);
-		if(!hosts_ctl(progname, hostent.h_name, ip, STRING_UNKNOWN)) {
-			pthread_mutex_unlock(&wrap_mutex);
-			logg(_("^Access Denied for %s[%s]"), hostent.h_name, ip);
-			return SMFIS_TEMPFAIL;
-		}
-		pthread_mutex_unlock(&wrap_mutex);
-	}
-#endif	/*WITH_TCPWRAP*/
-
-	if(fflag)
-		/*
-		 * Patch from "Richard G. Roberto" <rgr at dedlegend.com>
-		 * Always scan whereever the message is from
-		 */
-		return SMFIS_CONTINUE;
-
-	if(!oflag)
-		if(strcmp(remoteIP, "127.0.0.1") == 0) {
-			logg(_("*clamfi_connect: not scanning outgoing messages"));
-			return SMFIS_ACCEPT;
-		}
-
-	if((!lflag) && isLocal(remoteIP)) {
-#ifdef	CL_DEBUG
-		logg(_("*clamfi_connect: not scanning local messages\n"));
-#endif
-		return SMFIS_ACCEPT;
-	}
-
-#if	defined(HAVE_INET_NTOP) || defined(WITH_TCPWRAP)
-	if(detect_forged_local_address && !isLocal(ip)) {
-#else
-	if(detect_forged_local_address && !isLocal(remoteIP)) {
-#endif
-		char me[MAXHOSTNAMELEN + 1];
-
-		if(gethostname(me, sizeof(me) - 1) < 0) {
-			logg(_("^clamfi_connect: gethostname failed"));
-			return SMFIS_CONTINUE;
-		}
-		logg("*me '%s' hostname '%s'\n", me, hostname);
-		if(strcasecmp(hostname, me) == 0) {
-			logg(_("Rejected connexion falsely claiming to be from here\n"));
-			smfi_setreply(ctx, "550", "5.7.1", _("You have claimed to be me, but you are not"));
-			broadcast(_("Forged local address detected"));
-			return SMFIS_REJECT;
-		}
-	}
-	if(isBlacklisted(remoteIP)) {
-		char mess[128];
-
-		/*
-		 * TODO: Option to greylist rather than blacklist, by sending
-		 *	a try again code
-		 * TODO: state *which* virus
-		 * TODO: add optional list of IP addresses that won't be
-		 *	blacklisted
-		 */
-		logg("Rejected connexion from blacklisted IP %s\n", remoteIP);
-
-		snprintf(mess, sizeof(mess), _("%s is blacklisted because your machine is infected with a virus"), remoteIP);
-		smfi_setreply(ctx, "550", "5.7.1", mess);
-		broadcast(_("Blacklisted IP detected"));
-
-		/*
-		 * Keep them blacklisted
-		 */
-		pthread_mutex_lock(&blacklist_mutex);
-		(void)tableUpdate(blacklist, remoteIP, (int)time((time_t *)0));
-		pthread_mutex_unlock(&blacklist_mutex);
-
-		return SMFIS_REJECT;
-	}
-
-	if(blacklist_time == 0)
-		return SMFIS_CONTINUE;	/* allocate privdata per message */
-
-	pthread_mutex_lock(&blacklist_mutex);
-	t = tableFind(blacklist, remoteIP);
-	pthread_mutex_unlock(&blacklist_mutex);
-
-	if(t == 0)
-		return SMFIS_CONTINUE;	/* this IP will never be blacklisted */
-
-	privdata = (struct privdata *)cli_calloc(1, sizeof(struct privdata));
-	if(privdata == NULL)
-		return cl_error;
-
-#ifdef	SESSION
-	privdata->dataSocket = -1;
-#else
-	privdata->dataSocket = privdata->cmdSocket = -1;
-#endif
-
-	if(smfi_setpriv(ctx, privdata) == MI_SUCCESS) {
-		strcpy(privdata->ip, remoteIP);
-		return SMFIS_CONTINUE;
-	}
-
-	free(privdata);
-
-	return cl_error;
-}
-
-/*
- * Since sendmail requires that MAIL FROM is called before RCPT TO, it is
- *	safe to assume that this routine is called first, so the n_children
- *	handler is put here
- */
-static sfsistat
-clamfi_envfrom(SMFICTX *ctx, char **argv)
-{
-	struct privdata *privdata;
-	const char *mailaddr = argv[0];
-
-	logg("*clamfi_envfrom: %s\n", argv[0]);
-
-	if(isWhitelisted(argv[0], 0)) {
-		logg(_("*clamfi_envfrom: ignoring whitelisted message"));
-		return SMFIS_ACCEPT;
-	}
-
-	if(strcmp(argv[0], "<>") == 0) {
-		mailaddr = smfi_getsymval(ctx, "{mail_addr}");
-		if(mailaddr == NULL)
-			mailaddr = smfi_getsymval(ctx, "_");
-
-		if(mailaddr && *mailaddr)
-			cli_dbgmsg("Message from \"%s\" has no from field\n", mailaddr);
-		else {
-#if	0
-			if(use_syslog)
-				syslog(LOG_NOTICE, _("Rejected email with empty from field"));
-			smfi_setreply(ctx, "554", "5.7.1", _("You have not said who the email is from"));
-			broadcast(_("Reject email with empty from field"));
-			clamfi_cleanup(ctx);
-			return SMFIS_REJECT;
-#endif
-			mailaddr = "<>";
-		}
-	}
-	privdata = smfi_getpriv(ctx);
-
-	if(privdata == NULL) {
-		privdata = (struct privdata *)cli_calloc(1, sizeof(struct privdata));
-		if(privdata == NULL)
-			return cl_error;
-		if(smfi_setpriv(ctx, privdata) != MI_SUCCESS) {
-			free(privdata);
-			return cl_error;
-		}
-		if(!increment_connexions()) {
-			smfi_setreply(ctx, "451", "4.3.2", _("AV system temporarily overloaded - please try later"));
-			free(privdata);
-			smfi_setpriv(ctx, NULL);
-			return SMFIS_TEMPFAIL;
-		}
-	} else {
-		/* More than one message on this connexion */
-		char ip[INET6_ADDRSTRLEN];
-
-		strcpy(ip, privdata->ip);
-		if(isBlacklisted(ip)) {
-			char mess[80 + INET6_ADDRSTRLEN];
-
-			logg("Rejected email from blacklisted IP %s\n", ip);
-
-			/*
-			 * TODO: Option to greylist rather than blacklist, by
-			 *	sending	a try again code
-			 * TODO: state *which* virus
-			 */
-			sprintf(mess, "Your IP (%s) is blacklisted because your machine is infected with a virus", ip);
-			smfi_setreply(ctx, "550", "5.7.1", mess);
-			broadcast(_("Blacklisted IP detected"));
-
-			/*
-			 * Keep them blacklisted
-			 */
-			pthread_mutex_lock(&blacklist_mutex);
-			(void)tableUpdate(blacklist, ip, (int)time((time_t *)0));
-			pthread_mutex_unlock(&blacklist_mutex);
-
-			return SMFIS_REJECT;
-		}
-		clamfi_free(privdata, 1);
-		strcpy(privdata->ip, ip);
-	}
-
-#ifdef	SESSION
-	privdata->dataSocket = -1;
-#else
-	privdata->dataSocket = privdata->cmdSocket = -1;
-#endif
-
-	/*
-	 * Rejection is via 550 until DATA is received. We know that
-	 * DATA has been sent when either we get a header or the end of
-	 * header statement
-	 */
-	privdata->rejectCode = "550";
-
-	privdata->from = cli_strdup(mailaddr);
-
-	if(hflag) {
-		privdata->headers = header_list_new();
-
-		if(privdata->headers == NULL) {
-			clamfi_free(privdata, 1);
-			return cl_error;
-		}
-	}
-
-	return SMFIS_CONTINUE;
-}
-
-#ifdef	CL_DEBUG
-static sfsistat
-clamfi_helo(SMFICTX *ctx, char *helostring)
-{
-	logg("HELO '%s'\n", helostring);
-
-	return SMFIS_CONTINUE;
-}
-#endif
-
-static sfsistat
-clamfi_envrcpt(SMFICTX *ctx, char **argv)
-{
-	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-	const char *to, *ptr;
-
-	logg("*clamfi_envrcpt: %s\n", argv[0]);
-
-	if(privdata == NULL)	/* sanity check */
-		return cl_error;
-
-	if(privdata->to == NULL) {
-		privdata->to = cli_malloc(sizeof(char *) * 2);
-
-		assert(privdata->numTo == 0);
-	} else
-		privdata->to = cli_realloc(privdata->to, sizeof(char *) * (privdata->numTo + 2));
-
-	if(privdata->to == NULL)
-		return cl_error;
-
-	to = smfi_getsymval(ctx, "{rcpt_addr}");
-	if(to == NULL)
-		to = argv[0];
-
-	for(ptr = to; !dont_sanitise && *ptr; ptr++)
-		if(strchr("|;", *ptr) != NULL) {
-			smfi_setreply(ctx, "554", "5.7.1", _("Suspicious recipient address blocked"));
-			logg("^Suspicious recipient address blocked: '%s'\n", to);
-			privdata->to[privdata->numTo] = NULL;
-			if(blacklist_time && privdata->ip[0]) {
-				logg(_("Will blacklist %s for %d seconds because of cracking attempt\n"),
-					privdata->ip, blacklist_time);
-				pthread_mutex_lock(&blacklist_mutex);
-				(void)tableUpdate(blacklist, privdata->ip,
-					(int)time((time_t *)0));
-				pthread_mutex_unlock(&blacklist_mutex);
-			}
-			/*
-			 * REJECT rejects this recipient, not the entire email
-			 */
-			return SMFIS_REJECT;
-		}
-
-	privdata->to[privdata->numTo] = cli_strdup(to);
-	privdata->to[++privdata->numTo] = NULL;
-
-	return SMFIS_CONTINUE;
-}
-
-static sfsistat
-clamfi_header(SMFICTX *ctx, char *headerf, char *headerv)
-{
-	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-
-#ifdef	CL_DEBUG
-	if(debug_level >= 9)
-		logg("*clamfi_header: %s: %s\n", headerf, headerv);
-	else
-		logg("*clamfi_header: %s\n", headerf);
-#else
-	logg("*clamfi_header: %s\n", headerf);
-#endif
-
-	/*
-	 * The DATA instruction from SMTP (RFC2821) must have been sent
-	 */
-	privdata->rejectCode = "554";
-
-	if(hflag)
-		header_list_add(privdata->headers, headerf, headerv);
-	else if((strcasecmp(headerf, "Received") == 0) &&
-		(strncasecmp(headerv, "from ", 5) == 0) &&
-		(strstr(headerv, "localhost") != 0)) {
-		if(privdata->received)
-			free(privdata->received);
-		privdata->received = cli_strdup(headerv);
-	}
-
-	if((strcasecmp(headerf, "Message-ID") == 0) &&
-	   (strncasecmp(headerv, "<MDAEMON", 8) == 0))
-		privdata->discard = 1;
-	else if((strcasecmp(headerf, "Subject") == 0) && headerv) {
-		if(privdata->subject)
-			free(privdata->subject);
-		if(headerv)
-			privdata->subject = cli_strdup(headerv);
-	} else if(strcasecmp(headerf, "X-Virus-Status") == 0)
-		privdata->statusCount++;
-	else if((strcasecmp(headerf, "Sender") == 0) && headerv) {
-		if(privdata->sender)
-			free(privdata->sender);
-		privdata->sender = cli_strdup(headerv);
-	}
-#ifdef	HAVE_RESOLV_H
-	else if((strcasecmp(headerf, "From") == 0) && headerv) {
-		/*
-		 * SPF check against the from header, since the SMTP header
-		 * may be valid. This is not what the SPF spec says, but I
-		 * have seen SPF matches on what are clearly phishes, so by
-		 * checking against the from: header we're less likely to
-		 * FP a real phish
-		 */
-		if(privdata->from)
-			free(privdata->from);
-		privdata->from = cli_strdup(headerv);
-	}
-#endif
-
-	if(!useful_header(headerf)) {
-		logg("*Discarded the header\n");
-		return SMFIS_CONTINUE;
-	}
-
-	if(privdata->dataSocket == -1)
-		/*
-		 * First header - make connexion with clamd
-		 */
-		if(!connect2clamd(privdata)) {
-			clamfi_cleanup(ctx);
-			return cl_error;
-		}
-
-	if(clamfi_send(privdata, 0, "%s: %s\n", headerf, headerv) <= 0) {
-		clamfi_cleanup(ctx);
-		return cl_error;
-	}
-
-	return SMFIS_CONTINUE;
-}
-
-/*
- * At this point DATA will have been received, so we really ought to
- * send 554 back not 550
- */
-static sfsistat
-clamfi_eoh(SMFICTX *ctx)
-{
-	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-	char **to;
-
-	logg(_("*clamfi_eoh\n"));
-
-	/*
-	 * The DATA instruction from SMTP (RFC2821) must have been sent
-	 */
-	privdata->rejectCode = "554";
-
-	if(privdata->dataSocket == -1)
-		/*
-		 * No headers - make connexion with clamd
-		 */
-		if(!connect2clamd(privdata)) {
-			clamfi_cleanup(ctx);
-			return cl_error;
-		}
-
-#if	0
-	/* Mailing lists often say our own posts are from us */
-	if(detect_forged_local_address && privdata->from &&
-	   (!privdata->sender) && !isWhitelisted(privdata->from, 1)) {
-		char me[MAXHOSTNAMELEN + 1];
-		const char *ptr;
-
-		if(gethostname(me, sizeof(me) - 1) < 0) {
-			if(use_syslog)
-				syslog(LOG_WARNING, _("clamfi_eoh: gethostname failed"));
-			return SMFIS_CONTINUE;
-		}
-		ptr = strstr(privdata->from, me);
-		if(ptr && (ptr != privdata->from) && (*--ptr == '@')) {
-			if(use_syslog)
-				syslog(LOG_NOTICE, _("Rejected email falsely claiming to be from %s"), privdata->from);
-			smfi_setreply(ctx, "554", "5.7.1", _("You have claimed to be from me, but you are not"));
-			broadcast(_("Forged local address detected"));
-			clamfi_cleanup(ctx);
-			return SMFIS_REJECT;
-		}
-	}
-#endif
-
-	if(clamfi_send(privdata, 1, "\n") != 1) {
-		clamfi_cleanup(ctx);
-		return cl_error;
-	}
-
-	if(black_hole_mode) {
-		sfsistat rc = black_hole(privdata);
-
-		if(rc != SMFIS_CONTINUE) {
-			clamfi_cleanup(ctx);
-			return rc;
-		}
-	}
-
-	/*
-	 * See if the e-mail is only going to members of the list
-	 * of users we don't scan for. If it is, don't scan, otherwise
-	 * scan
-	 *
-	 * scan = false
-	 * FORALL recipients
-	 *	IF receipient NOT MEMBER OF white address list
-	 *	THEN
-	 *		scan = true
-	 *	FI
-	 * ENDFOR
-	 */
-	for(to = privdata->to; *to; to++)
-		if(!isWhitelisted(*to, 1))
-			/*
-			 * This recipient is not on the whitelist,
-			 * no need to check any further
-			 */
-			return SMFIS_CONTINUE;
-
-	/*
-	 * Didn't find a recipient who is not on the white list, so all
-	 * must be on the white list, so just accept the e-mail
-	 */
-	logg(_("*clamfi_enveoh: ignoring whitelisted message"));
-	clamfi_cleanup(ctx);
-
-	return SMFIS_ACCEPT;
-}
-
-static sfsistat
-clamfi_body(SMFICTX *ctx, u_char *bodyp, size_t len)
-{
-	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-	int nbytes;
-
-	logg(_("*clamfi_envbody: %lu bytes"), (unsigned long)len);
-
-	if(len == 0)	/* unlikely */
-		return SMFIS_CONTINUE;
-
-	if(privdata == NULL)	/* sanity check */
-		return cl_error;
-
-	/*
-	 * TODO:
-	 *	If not in external mode, call cli_scanbuff here, at least for
-	 * the first block
-	 */
-	/*
-	 * Lines starting with From are changed to >From, to
-	 *	avoid FP matches in the scanning code, which will speed it up
-	 */
-	if((len >= 6) && cli_memstr((char *)bodyp, len, "\nFrom ", 6)) {
-		const char *ptr = (const char *)bodyp;
-		int left = len;
-
-		nbytes = 0;
-
-		/*
-		 * FIXME: sending one byte at a time down a socket is
-		 *	inefficient
-		 */
-		do {
-			if(*ptr == '\n') {
-				/*
-				 * FIXME: doesn't work if the \nFrom straddles
-				 * multiple calls to clamfi_body
-				 */
-				if(strncmp(ptr, "\nFrom ", 6) == 0) {
-					nbytes += clamfi_send(privdata, 7, "\n>From ");
-					ptr += 6;
-					left -= 6;
-				} else {
-					nbytes += clamfi_send(privdata, 1, "\n");
-					ptr++;
-					left--;
-				}
-			} else {
-				nbytes += clamfi_send(privdata, 1, ptr++);
-				left--;
-			}
-			if(left < 6 && left > 0) {
-				nbytes += clamfi_send(privdata, left, ptr);
-				break;
-			}
-		} while(left > 0);
-	} else
-		nbytes = clamfi_send(privdata, len, (char *)bodyp);
-
-	if(streamMaxLength > 0L) {
-		if(privdata->numBytes > streamMaxLength) {
-			const char *sendmailId = smfi_getsymval(ctx, "i");
-
-			if(sendmailId == NULL)
-				sendmailId = "Unknown";
-			logg(_("%s: Message more than StreamMaxLength (%ld) bytes - not scanned\n"),
-				sendmailId, streamMaxLength);
-			if(!nflag)
-				smfi_addheader(ctx, "X-Virus-Status", _("Not Scanned - StreamMaxLength exceeded"));
-
-			return SMFIS_ACCEPT;	/* clamfi_close will be called */
-		}
-	}
-	if(nbytes < (int)len) {
-		clamfi_cleanup(ctx);	/* not needed, but just to be safe */
-		return cl_error;
-	}
-	if(Sflag) {
-		if(privdata->body) {
-			assert(privdata->bodyLen > 0);
-			privdata->body = cli_realloc(privdata->body, privdata->bodyLen + len);
-			memcpy(&privdata->body[privdata->bodyLen], bodyp, len);
-			privdata->bodyLen += len;
-		} else {
-			assert(privdata->bodyLen == 0);
-			privdata->body = cli_malloc(len);
-			memcpy(privdata->body, bodyp, len);
-			privdata->bodyLen = len;
-		}
-	}
-	return SMFIS_CONTINUE;
-}
-
-static sfsistat
-clamfi_eom(SMFICTX *ctx)
-{
-	int rc = SMFIS_CONTINUE;
-	char *ptr;
-	const char *sendmailId;
-	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-	char mess[128];
-#ifdef	SESSION
-	struct session *session;
-#endif
-
-	logg("*clamfi_eom\n");
-
-#ifdef	CL_DEBUG
-	assert(privdata != NULL);
-#ifndef	SESSION
-	assert((privdata->cmdSocket >= 0) || (privdata->filename != NULL));
-	assert(!((privdata->cmdSocket >= 0) && (privdata->filename != NULL)));
-#endif
-#endif
-
-	if(external) {
-		shutdown(privdata->dataSocket, SHUT_WR);	/* bug 487 */
-		close(privdata->dataSocket);
-		privdata->dataSocket = -1;
-	}
-
-	if(!nflag) {
-		/*
-		 * remove any existing claims that it's virus free so that
-		 * downstream checkers aren't fooled by a carefully crafted
-		 * virus.
-		 */
-		int i;
-
-		for(i = privdata->statusCount; i > 0; --i)
-			if(smfi_chgheader(ctx, "X-Virus-Status", i, NULL) == MI_FAILURE)
-				logg(_("^Failed to delete X-Virus-Status header %d\n"), i);
-	}
-
-	if(!external) {
-		const char *virname;
-		int ret;
-		struct  cl_engine *cur_engine;
-
-		pthread_mutex_lock(&engine_mutex);
-		ret = cl_engine_addref(engine);
-		cur_engine = engine; /* avoid races */
-		pthread_mutex_unlock(&engine_mutex);
-		if(ret != CL_SUCCESS) {
-			logg("!cl_engine_addref failed\n");
-			clamfi_cleanup(ctx);
-			return cl_error;
-		}
-		switch(cl_scanfile(privdata->filename, &virname, NULL, cur_engine, options)) {
-			case CL_CLEAN:
-				if(logok)
-					logg("#%s: OK\n", privdata->filename);
-				strcpy(mess, "OK");
-				break;
-			case CL_VIRUS:
-				snprintf(mess, sizeof(mess), "%s: %s FOUND", privdata->filename, virname);
-				logg("#%s\n", mess);
-				break;
-			default:
-				snprintf(mess, sizeof(mess), "%s: ERROR", privdata->filename);
-				logg("!%s\n", mess);
-				break;
-		}
-		cl_engine_free(cur_engine); /* drop reference or free */
-
-#ifdef	SESSION
-		session = NULL;
-#endif
-	} else if(privdata->filename) {
-		char cmdbuf[1024];
-		/*
-		 * Create socket to talk to clamd.
-		 */
-#ifndef	SESSION
-		struct sockaddr_un server;
-#endif
-		long nbytes;
-
-		snprintf(cmdbuf, sizeof(cmdbuf) - 1, "SCAN %s", privdata->filename);
-		cli_dbgmsg("clamfi_eom: SCAN %s\n", privdata->filename);
-
-		nbytes = (int)strlen(cmdbuf);
-
-#ifdef	SESSION
-		session = sessions;
-		if(send(session->sock, cmdbuf, nbytes, 0) < nbytes) {
-			perror("send");
-			clamfi_cleanup(ctx);
-			logg(_("failed to send SCAN %s command to clamd\n"), privdata->filename);
-			return cl_error;
-		}
-#else
-		if((privdata->cmdSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
-			perror("socket");
-			clamfi_cleanup(ctx);
-			return cl_error;
-		}
-		memset((char *)&server, 0, sizeof(struct sockaddr_un));
-		server.sun_family = AF_UNIX;
-		strncpy(server.sun_path, localSocket, sizeof(server.sun_path));
-		server.sun_path[sizeof(server.sun_path)-1]='\0';
-
-		if(connect(privdata->cmdSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_un)) < 0) {
-			perror(localSocket);
-			clamfi_cleanup(ctx);
-			return cl_error;
-		}
-		if(send(privdata->cmdSocket, cmdbuf, nbytes, 0) < nbytes) {
-			perror("send");
-			clamfi_cleanup(ctx);
-			logg(_("failed to send SCAN command to clamd\n"));
-			return cl_error;
-		}
-
-		shutdown(privdata->cmdSocket, SHUT_WR);
-#endif
-	}
-#ifdef	SESSION
-	else
-		session = &sessions[privdata->serverNumber];
-#endif
-
-	sendmailId = smfi_getsymval(ctx, "i");
-	if(sendmailId == NULL)
-		sendmailId = "Unknown";
-
-	if(external) {
-		int nbytes;
-#ifdef	SESSION
-#ifdef	CL_DEBUG
-		if(debug_level >= 4)
-			cli_dbgmsg(_("Waiting to read status from fd %d\n"),
-				session->sock);
-#endif
-		nbytes = clamd_recv(session->sock, mess, sizeof(mess) - 1);
-#else
-		nbytes = clamd_recv(privdata->cmdSocket, mess, sizeof(mess) - 1);
-#endif
-		if(nbytes > 0) {
-			mess[nbytes] = '\0';
-			if((ptr = strchr(mess, '\n')) != NULL)
-				*ptr = '\0';
-
-			logg(_("*clamfi_eom: read %s\n"), mess);
-		} else {
-#ifdef	MAXHOSTNAMELEN
-			char hostname[MAXHOSTNAMELEN + 1];
-
-			cli_strtokbuf(serverHostNames, privdata->serverNumber, ":", hostname);
-			if(strcmp(hostname, "127.0.0.1") == 0)
-				gethostname(hostname, sizeof(hostname));
-#else
-			char *hostname = cli_strtok(serverHostNames, privdata->serverNumber, ":");
-#endif
-			if(privdata->subject)
-				logg(_("^%s: clamfi_eom: read nothing from clamd on %s, from %s (%s)\n"),
-					sendmailId, hostname, privdata->from,
-					privdata->subject);
-			else
-				logg(_("^%s: clamfi_eom: read nothing from clamd on %s, from %s\n"),
-					sendmailId, hostname, privdata->from);
-
-			if((!nflag) && (cl_error == SMFIS_ACCEPT))
-				smfi_addheader(ctx, "X-Virus-Status", _("Not Scanned - Read timeout exceeded"));
-#ifndef	MAXHOSTNAMELEN
-			free(hostname);
-#endif
-
-#ifdef	CL_DEBUG
-			/*
-			 * Save the file which caused the timeout, for
-			 * debugging
-			 */
-			if(quarantine_dir) {
-				logg(_("Quarantining failed email\n"));
-				qfile(privdata, sendmailId, "scanning-timeout");
-			}
-#endif
-
-			/*
-			 * TODO: if more than one host has been specified, try
-			 * another one - setting cl_error to SMFIS_TEMPFAIL
-			 * helps by forcing a retry
-			 */
-			clamfi_cleanup(ctx);
-
-#ifdef	SESSION
-			pthread_mutex_lock(&sstatus_mutex);
-			session->status = CMDSOCKET_DOWN;
-			pthread_mutex_unlock(&sstatus_mutex);
-#endif
-			return cl_error;
-		}
-
-#ifdef	SESSION
-		pthread_mutex_lock(&sstatus_mutex);
-		if(session->status == CMDSOCKET_INUSE)
-			session->status = CMDSOCKET_FREE;
-		pthread_mutex_unlock(&sstatus_mutex);
-#else
-		close(privdata->cmdSocket);
-		privdata->cmdSocket = -1;
-#endif
-	}
-
-	if(!nflag) {
-		char buf[1024];
-
-		/*
-		 * Include the hostname where the scan took place
-		 */
-		if(localSocket || !external) {
-#ifdef	MAXHOSTNAMELEN
-			char hostname[MAXHOSTNAMELEN + 1];
-#else
-			char hostname[65];
-#endif
-
-			if(gethostname(hostname, sizeof(hostname)) < 0) {
-				const char *j = smfi_getsymval(ctx, "{j}");
-
-				if(j)
-					strncpy(hostname, j, sizeof(hostname) - 1);
-				else
-					strcpy(hostname, _("Error determining host"));
-				hostname[sizeof(hostname)-1]='\0';
-			} else if(strchr(hostname, '.') == NULL) {
-				/*
-				 * Determine fully qualified name
-				 */
-				struct hostent hostent;
-
-				if((r_gethostbyname(hostname, &hostent, buf, sizeof(buf)) == 0) && hostent.h_name) {
-					strncpy(hostname, hostent.h_name, sizeof(hostname));
-					hostname[sizeof(hostname)-1]='\0';
-				}
-			}
-
-#ifdef	SESSION
-			pthread_mutex_lock(&version_mutex);
-			snprintf(buf, sizeof(buf) - 1, "%s on %s",
-				clamav_versions[privdata->serverNumber], hostname);
-			pthread_mutex_unlock(&version_mutex);
-#else
-			snprintf(buf, sizeof(buf) - 1, "%s on %s",
-				clamav_version, hostname);
-#endif
-		} else {
-#ifdef	MAXHOSTNAMELEN
-			char hostname[MAXHOSTNAMELEN + 1];
-
-			if(cli_strtokbuf(serverHostNames, privdata->serverNumber, ":", hostname)) {
-				if(strcmp(hostname, "127.0.0.1") == 0)
-					gethostname(hostname, sizeof(hostname));
-#else
-			char *hostname = cli_strtok(serverHostNames, privdata->serverNumber, ":");
-			if(hostname) {
-#endif
-
-#ifdef	SESSION
-				pthread_mutex_lock(&version_mutex);
-				snprintf(buf, sizeof(buf) - 1, "%s on %s",
-					clamav_versions[privdata->serverNumber], hostname);
-				pthread_mutex_unlock(&version_mutex);
-#else
-				snprintf(buf, sizeof(buf) - 1, "%s on %s",
-					clamav_version, hostname);
-#endif
-#ifndef	MAXHOSTNAMELEN
-				free(hostname);
-#endif
-			} else
-				/* sanity check failed - should issue warning */
-				strcpy(buf, _("Error determining host"));
-		}
-		smfi_addheader(ctx, "X-Virus-Scanned", buf);
-	}
-
-	/*
-	 * TODO: it would be useful to add a header if mbox.c/FOLLOWURLS was
-	 * exceeded
-	 */
-#ifdef	HAVE_RESOLV_H
-	if((strstr(mess, "FOUND") != NULL) && (strstr(mess, "Phishing") != NULL)) {
-		table_t *prevhosts = tableCreate();
-
-		if(spf(privdata, prevhosts)) {
-			logg(_("%s: Ignoring %s false positive from %s received from %s\n"),
-				sendmailId, mess, privdata->from, privdata->ip);
-			strcpy(mess, "OK");
-			/*
-			 * Report false positive to ClamAV, works best when
-			 * clamav-milter has had to create a local copy of
-			 * the email, e.g. when --quarantine-dir is on
-			 */
-			if(report_fps &&
-			   (smfi_addrcpt(ctx, report_fps) == MI_FAILURE)) {
-				if(privdata->filename) {
-					char cmd[1024];
-
-					snprintf(cmd, sizeof(cmd) - 1,
-						"mail -s \"False Positive: %s\" %s < %s",
-						mess, report_fps,
-						privdata->filename);
-					if(system(cmd) == 0)
-						logg(_("#Reported phishing false positive to %s"), report_fps);
-					else
-						logg(_("^Couldn't report false positive to %s\n"), report_fps);
-				} else
-					/*
-					 * Most likely this is because we're
-					 * attempting to add a recipient on
-					 * another host
-					 */
-					logg(_("^Can't set phish FP header\n"));
-			}
-		}
-		tableDestroy(prevhosts);
-	}
-#endif
-	if(strstr(mess, "ERROR") != NULL) {
-		if(strstr(mess, "Size limit reached") != NULL) {
-			/*
-			 * Clamd has stopped on StreamMaxLength before us
-			 */
-			logg(_("%s: Message more than StreamMaxLength (%ld) bytes - not scanned"),
-				sendmailId, streamMaxLength);
-			if(!nflag)
-				smfi_addheader(ctx, "X-Virus-Status", _("Not Scanned - StreamMaxLength exceeded"));
-			clamfi_cleanup(ctx);	/* not needed, but just to be safe */
-			return SMFIS_ACCEPT;
-		}
-		if(!nflag)
-			smfi_addheader(ctx, "X-Virus-Status", _("Not Scanned"));
-
-		logg("!%s: %s\n", sendmailId, mess);
-		rc = cl_error;
-	} else if((ptr = strstr(mess, "FOUND")) != NULL) {
-		/*
-		 * FIXME: This will give false positives if the
-		 *	word "FOUND" is in the email, e.g. the
-		 *	quarantine directory is /tmp/VIRUSES-FOUND
-		 */
-		int i;
-		char **to, *virusname, *err;
-		char reject[1024];
-
-		/*
-		 * Remove the "FOUND" word, and the space before it
-		 */
-		*--ptr = '\0';
-
-		/* skip over 'stream/filename: ' at the start */
-		if((virusname = strchr(mess, ':')) != NULL)
-			virusname = &virusname[2];
-		else
-			virusname = mess;
-
-		if(!nflag) {
-			char buf[129];
-
-			snprintf(buf, sizeof(buf) - 1, "%s %s", _("Infected with"), virusname);
-			smfi_addheader(ctx, "X-Virus-Status", buf);
-		}
-
-		if(quarantine_dir)
-			qfile(privdata, sendmailId, virusname);
-
-		/*
-		 * Setup err as a list of recipients
-		 */
-		err = (char *)cli_malloc(1024);
-
-		if(err == NULL) {
-			clamfi_cleanup(ctx);
-			return cl_error;
-		}
-
-		/*
-		 * Use snprintf rather than printf since we don't know
-		 * the length of privdata->from and may get a buffer
-		 * overrun
-		 */
-		snprintf(err, 1023, _("Intercepted virus from %s to"),
-			privdata->from);
-
-		ptr = strchr(err, '\0');
-
-		i = 1024;
-
-		for(to = privdata->to; *to; to++) {
-			/*
-			 * Re-alloc if we are about run out of buffer
-			 * space
-			 *
-			 * TODO: Only append *to if it's a valid, local
-			 *	email address
-			 */
-			if(&ptr[strlen(*to) + 2] >= &err[i]) {
-				i += 1024;
-				err = cli_realloc(err, i);
-				if(err == NULL) {
-					clamfi_cleanup(ctx);
-					return cl_error;
-				}
-				ptr = strchr(err, '\0');
-			}
-			ptr = cli_strrcpy(ptr, " ");
-			ptr = cli_strrcpy(ptr, *to);
-		}
-		(void)strcpy(ptr, "\n");
-
-		/* Include the sendmail queue ID in the log */
-		logg("%s: %s %s", sendmailId, mess, err);
-		free(err);
-
-		if(!qflag) {
-			char cmd[128];
-			FILE *sendmail;
-
-			/*
-			 * If the oflag is given this sendmail command
-			 * will cause the mail being generated here to be
-			 * scanned. So if oflag is given we just put the
-			 * item in the queue so there's no scanning of two
-			 * messages at once. It'll still be scanned, but
-			 * not at the same time as the incoming message
-			 *
-			 * FIXME: there is a race condition here when sendmail
-			 * and clamav-milter run on the same machine. If the
-			 * system is very overloaded this sendmail can
-			 * take a long time to start - and may even fail
-			 * is the LA is > REFUSE_LA. In all the time we're
-			 * taking to start this sendmail, the sendmail that's
-			 * started us may timeout waiting for a response and
-			 * let the virus through (albeit tagged with
-			 * X-Virus-Status: Infected) because we haven't
-			 * sent SMFIS_DISCARD or SMFIS_REJECT
-			 *
-			 * -i flag, suggested by Michal Jaegermann
-			 *	<michal at harddata.com>
-			 */
-			snprintf(cmd, sizeof(cmd) - 1,
-				(oflag || fflag) ? "%s -t -i -odq" : "%s -t -i",
-				SENDMAIL_BIN);
-
-			cli_dbgmsg("Calling %s\n", cmd);
-			sendmail = popen(cmd, "w");
-
-			if(sendmail) {
-				if(from && from[0])
-					fprintf(sendmail, "From: %s\n", from);
-				else
-					fprintf(sendmail, "From: %s\n", privdata->from);
-#ifdef	BOUNCE
-				if(bflag && privdata->from) {
-					fprintf(sendmail, "To: %s\n", privdata->from);
-					fprintf(sendmail, "Cc: %s\n", postmaster);
-				} else
-#endif
-					fprintf(sendmail, "To: %s\n", postmaster);
-
-				if((!pflag) && privdata->to)
-					for(to = privdata->to; *to; to++)
-						fprintf(sendmail, "Cc: %s\n", *to);
-				/*
-				 * Auto-submitted is still a draft, keep an
-				 * eye on its format
-				 */
-				fputs("Auto-Submitted: auto-submitted (antivirus notify)\n", sendmail);
-				/* "Sergey Y. Afonin" <asy at kraft-s.ru> */
-				if((ptr = smfi_getsymval(ctx, "{_}")) != NULL)
-					fprintf(sendmail,
-						"X-Infected-Received-From: %s\n",
-						ptr);
-				fputs(_("Subject: Virus intercepted\n"), sendmail);
-
-				if(templateHeaders) {
-					/*
-					 * For example, to state the character
-					 * set of the message:
-					 *	Content-Type: text/plain; charset=koi8-r
-					 *
-					 * Based on a suggestion by Denis
-					 *	Eremenko <moonshade at mail.kz>
-					 */
-					FILE *fin = fopen(templateHeaders, "r");
-
-					if(fin == NULL) {
-						perror(templateHeaders);
-						logg(_("!Can't open e-mail template header file %s"),
-								templateHeaders);
-					} else {
-						int c;
-						int lastc = EOF;
-
-						while((c = getc(fin)) != EOF) {
-							putc(c, sendmail);
-							lastc = c;
-						}
-						fclose(fin);
-						/*
-						 * File not new line terminated
-						 */
-						if(lastc != '\n')
-							fputs(_("\n"), sendmail);
-					}
-				}
-
-				fputs(_("\n"), sendmail);
-
-				if((templateFile == NULL) ||
-				   (sendtemplate(ctx, templateFile, sendmail, virusname) < 0)) {
-					/*
-					 * Use our own hardcoded template
-					 */
-#ifdef	BOUNCE
-					if(bflag)
-						fputs(_("A message you sent to\n"), sendmail);
-					else if(pflag)
-#else
-					if(pflag)
-#endif
-						/*
-						 * The message is only going to
-						 * the postmaster, so include
-						 * some useful information
-						 */
-						fprintf(sendmail, _("The message %1$s sent from %2$s to\n"),
-							sendmailId, privdata->from);
-					else
-						fprintf(sendmail, _("A message sent from %s to\n"),
-							privdata->from);
-
-					for(to = privdata->to; *to; to++)
-						fprintf(sendmail, "\t%s\n", *to);
-					fprintf(sendmail, _("contained %s and has not been accepted for delivery.\n"), virusname);
-
-					if(quarantine_dir != NULL)
-						fprintf(sendmail, _("\nThe message in question has been quarantined as %s\n"), privdata->filename);
-
-					if(hflag) {
-						fprintf(sendmail, _("\nThe message was received by %1$s from %2$s via %3$s\n\n"),
-							smfi_getsymval(ctx, "j"), privdata->from,
-							smfi_getsymval(ctx, "_"));
-						fputs(_("For your information, the original message headers were:\n\n"), sendmail);
-						header_list_print(privdata->headers, sendmail);
-					} else if(privdata->received)
-						/*
-						 * TODO: parse this to find
-						 * real infected machine.
-						 * Need to decide how to find
-						 * if it's a dynamic IP from a
-						 * dial up account in which
-						 * case there may not be much
-						 * we can do if that DHCP has
-						 * set the hostname...
-						 */
-						fprintf(sendmail, _("\nThe infected machine is likely to be here:\n%s\t\n"),
-							privdata->received);
-
-				}
-
-				cli_dbgmsg("Waiting for %s to finish\n", cmd);
-				if(pclose(sendmail) != 0)
-					logg(_("%s: Failed to notify clamAV interception - see dead.letter\n"), sendmailId);
-			} else
-				logg(_("^Can't execute '%s' to send virus notice"), cmd);
-		}
-
-		if(report && (quarantine == NULL) && (!advisory) &&
-		   (strstr(virusname, "Phishing") != NULL)) {
-			/*
-			 * Report phishing to an agency
-			 */
-			for(to = privdata->to; *to; to++) {
-				smfi_delrcpt(ctx, *to);
-				smfi_addheader(ctx, "X-Original-To", *to);
-			}
-			if(smfi_addrcpt(ctx, report) == MI_FAILURE) {
-				/* It's a remote site */
-				if(privdata->filename) {
-					char cmd[1024];
-
-					snprintf(cmd, sizeof(cmd) - 1,
-						"mail -s \"%s\" %s < %s",
-						virusname, report,
-						privdata->filename);
-					if(system(cmd) == 0)
-						logg(_("#Reported phishing to %s"), report);
-					else
-						logg(_("^Couldn't report to %s\n"), report);
-					if((!rejectmail) || privdata->discard)
-						rc = SMFIS_DISCARD;
-					else
-						rc = SMFIS_REJECT;
-				} else {
-					logg(_("^Can't set anti-phish header\n"));
-					rc = (privdata->discard) ? SMFIS_DISCARD : SMFIS_REJECT;
-				}
-			} else {
-				setsubject(ctx, "Phishing attempt trapped by ClamAV and redirected");
-
-				logg("Redirected phish to %s\n", report);
-			}
-		} else if(quarantine) {
-			for(to = privdata->to; *to; to++) {
-				smfi_delrcpt(ctx, *to);
-				smfi_addheader(ctx, "X-Original-To", *to);
-			}
-			/*
-			 * NOTE: on a closed relay this will not work
-			 * if the recipient is a remote address
-			 */
-			if(smfi_addrcpt(ctx, quarantine) == MI_FAILURE) {
-				logg(_("^Can't set quarantine user %s"), quarantine);
-				rc = (privdata->discard) ? SMFIS_DISCARD : SMFIS_REJECT;
-			} else {
-				if(report &&
-				   strstr(virusname, "Phishing") != NULL)
-					(void)smfi_addrcpt(ctx, report);
-				setsubject(ctx, virusname);
-
-				logg("Redirected virus to %s", quarantine);
-			}
-		} else if(advisory)
-			setsubject(ctx, virusname);
-		else if(rejectmail) {
-			if(privdata->discard)
-				rc = SMFIS_DISCARD;
-			else
-				rc = SMFIS_REJECT;	/* Delete the e-mail */
-		} else
-			rc = SMFIS_DISCARD;
-
-		if(quarantine_dir) {
-			/*
-			 * Cleanup filename here otherwise clamfi_free() will
-			 * delete the file that we wish to keep because it
-			 * is infected
-			 */
-			free(privdata->filename);
-			privdata->filename = NULL;
-		}
-
-		/*
-		 * Don't drop the message if it's been forwarded to a
-		 * quarantine email
-		 */
-		snprintf(reject, sizeof(reject) - 1, _("virus %s detected by ClamAV - http://www.clamav.net"), virusname);
-		smfi_setreply(ctx, (const char *)privdata->rejectCode, "5.7.1", reject);
-		broadcast(mess);
-
-		if(blacklist_time && privdata->ip[0]) {
-			logg(_("Will blacklist %s for %d seconds because of %s\n"),
-				privdata->ip, blacklist_time, virusname);
-			pthread_mutex_lock(&blacklist_mutex);
-			(void)tableUpdate(blacklist, privdata->ip,
-				(int)time((time_t *)0));
-			pthread_mutex_unlock(&blacklist_mutex);
-		}
-	} else if((strstr(mess, "OK") == NULL) && (strstr(mess, "Empty file") == NULL)) {
-		if(!nflag)
-			smfi_addheader(ctx, "X-Virus-Status", _("Unknown"));
-		logg(_("!%s: incorrect message \"%s\" from clamd"),
-				sendmailId, mess);
-		rc = cl_error;
-	} else {
-		if(!nflag)
-			smfi_addheader(ctx, "X-Virus-Status", _("Clean"));
-
-		/* Include the sendmail queue ID in the log */
-		if(logok)
-			logg(_("%s: clean message from %s\n"),
-				sendmailId,
-				(privdata->from) ? privdata->from : _("an unknown sender"));
-
-		if(privdata->body) {
-			/*
-			 * Add a signature that all has been scanned OK
-			 *
-			 * Note that this is simple minded and isn't aware of
-			 *	any MIME segments in the message. In practice
-			 *	this means that the message will only display
-			 *	on users' terminals if the message is
-			 *	plain/text
-			 */
-			off_t len = updateSigFile();
-
-			if(len) {
-				assert(Sflag != 0);
-
-				privdata->body = cli_realloc(privdata->body, privdata->bodyLen + len);
-				if(privdata->body) {
-					memcpy(&privdata->body[privdata->bodyLen], signature, len);
-					smfi_replacebody(ctx, privdata->body, privdata->bodyLen + len);
-				}
-			}
-		}
-	}
-
-	return rc;
-}
-
-static sfsistat
-clamfi_abort(SMFICTX *ctx)
-{
-	logg("*clamfi_abort\n");
-
-	clamfi_cleanup(ctx);
-	decrement_connexions();
-
-	logg("*clamfi_abort returns\n");
-
-	return cl_error;
-}
-
-static sfsistat
-clamfi_close(SMFICTX *ctx)
-{
-	logg("*clamfi_close\n");
-
-	clamfi_cleanup(ctx);
-	decrement_connexions();
-
-	return SMFIS_CONTINUE;
-}
-
-static void
-clamfi_cleanup(SMFICTX *ctx)
-{
-	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-
-	cli_dbgmsg("clamfi_cleanup\n");
-
-	if(privdata) {
-		clamfi_free(privdata, 0);
-		smfi_setpriv(ctx, NULL);
-	}
-}
-
-static void
-clamfi_free(struct privdata *privdata, int keep)
-{
-	cli_dbgmsg("clamfi_free\n");
-
-	if(privdata) {
-#ifdef	SESSION
-		struct session *session;
-#endif
-		if(privdata->body)
-			free(privdata->body);
-
-		if(privdata->dataSocket >= 0)
-			close(privdata->dataSocket);
-
-		if(privdata->filename != NULL) {
-			/*
-			 * Don't print an error if the file hasn't been
-			 * created yet
-			 */
-			if((unlink(privdata->filename) < 0) && (errno != ENOENT)) {
-				perror(privdata->filename);
-				logg(_("!Can't remove clean file %s"),
-					privdata->filename);
-			}
-			free(privdata->filename);
-		}
-
-		if(privdata->from) {
-#ifdef	CL_DEBUG
-			if(debug_level >= 9)
-				cli_dbgmsg("Free privdata->from\n");
-#endif
-			free(privdata->from);
-		}
-
-		if(privdata->subject)
-			free(privdata->subject);
-		if(privdata->sender)
-			free(privdata->sender);
-
-		if(privdata->to) {
-			char **to;
-
-			for(to = privdata->to; *to; to++) {
-#ifdef	CL_DEBUG
-				if(debug_level >= 9)
-					cli_dbgmsg("Free *privdata->to\n");
-#endif
-				free(*to);
-			}
-#ifdef	CL_DEBUG
-			if(debug_level >= 9)
-				cli_dbgmsg("Free privdata->to\n");
-#endif
-			free(privdata->to);
-		}
-
-		if(external) {
-#ifdef	SESSION
-			session = &sessions[privdata->serverNumber];
-			pthread_mutex_lock(&sstatus_mutex);
-			if(session->status == CMDSOCKET_INUSE) {
-				/*
-				 * Probably we've got here because
-				 * StreamMaxLength has been reached
-				 */
-#if	0
-				pthread_mutex_unlock(&sstatus_mutex);
-				if(readTimeout) {
-					char buf[64];
-					const int fd = session->sock;
-
-					cli_dbgmsg("clamfi_free: flush server %d fd %d\n",
-						privdata->serverNumber, fd);
-
-					/*
-					 * FIXME: whenever this code gets
-					 *	executed, all of the PINGs fail
-					 *	in the next watchdog cycle
-					 */
-					while(clamd_recv(fd, buf, sizeof(buf)) > 0)
-						;
-				}
-				pthread_mutex_lock(&sstatus_mutex);
-#endif
-				/* Force a reset */
-				session->status = CMDSOCKET_DOWN;
-			}
-			pthread_mutex_unlock(&sstatus_mutex);
-#else
-			if(privdata->cmdSocket >= 0) {
-#if	0
-				char buf[64];
-
-				/*
-				 * Flush the remote end so that clamd doesn't
-				 * get a SIGPIPE
-				 */
-				if(readTimeout)
-					while(clamd_recv(privdata->cmdSocket, buf, sizeof(buf)) > 0)
-						;
-#endif
-				close(privdata->cmdSocket);
-			}
-#endif
-		}
-
-		if(privdata->headers)
-			header_list_free(privdata->headers);
-
-#ifdef	CL_DEBUG
-		if(debug_level >= 9)
-			cli_dbgmsg("Free privdata\n");
-#endif
-		if(privdata->received)
-			free(privdata->received);
-
-		if(keep) {
-			memset(privdata, '\0', sizeof(struct privdata));
-#ifdef	SESSION
-			privdata->dataSocket = -1;
-#else
-			privdata->dataSocket = privdata->cmdSocket = -1;
-#endif
-		} else
-			free(privdata);
-	}
-
-	cli_dbgmsg("clamfi_free returns\n");
-}
-
-/*
- * Returns < 0 for failure, otherwise the number of bytes sent
- */
-static int
-clamfi_send(struct privdata *privdata, size_t len, const char *format, ...)
-{
-	char output[BUFSIZ];
-	const char *ptr;
-	int ret = 0;
-	assert(format != NULL);
-
-	if(len > 0)
-		/*
-		 * It isn't a NUL terminated string. We have a set number of
-		 * bytes to output.
-		 */
-		ptr = format;
-	else {
-		va_list argp;
-
-		va_start(argp, format);
-		vsnprintf(output, sizeof(output) - 1, format, argp);
-		va_end(argp);
-
-		len = strlen(output);
-		ptr = output;
-	}
-#ifdef	CL_DEBUG
-	if(debug_level >= 9) {
-		time_t t;
-		const struct tm *tm;
-
-		time(&t);
-		tm = localtime(&t);
-
-		cli_dbgmsg("%d:%d:%d clamfi_send: len=%u bufsiz=%u, fd=%d\n",
-			tm->tm_hour, tm->tm_min, tm->tm_sec, len,
-			sizeof(output), privdata->dataSocket);
-	}
-#endif
-
-	while(len > 0) {
-		const int nbytes = (privdata->filename) ?
-			write(privdata->dataSocket, ptr, len) :
-			send(privdata->dataSocket, ptr, len, 0);
-
-		assert(privdata->dataSocket >= 0);
-
-		if(nbytes == -1) {
-			if(privdata->filename) {
-#ifdef HAVE_STRERROR_R
-				char buf[32];
-
-				perror(privdata->filename);
-				strerror_r(errno, buf, sizeof(buf));
-				logg(_("!write failure (%lu bytes) to %s: %s\n"),
-					(unsigned long)len, privdata->filename, buf);
-#else
-				perror(privdata->filename);
-				logg(_("!write failure (%lu bytes) to %s: %s\n"),
-					(unsigned long)len, privdata->filename,
-					strerror(errno));
-#endif
-			} else {
-				if(errno == EINTR)
-					continue;
-				perror("send");
-#ifdef HAVE_STRERROR_R
-				{
-					char buf[32];
-					strerror_r(errno, buf, sizeof(buf));
-					logg(_("!write failure (%lu bytes) to clamd: %s\n"),
-						(unsigned long)len, buf);
-				}
-#else
-				logg(_("!write failure (%lu bytes) to clamd: %s\n"),
-					(unsigned long)len, strerror(errno));
-#endif
-				checkClamd(1);
-			}
-
-			return -1;
-		}
-		ret += nbytes;
-		len -= nbytes;
-		ptr = &ptr[nbytes];
-
-		if(streamMaxLength > 0L) {
-			privdata->numBytes += nbytes;
-			if(privdata->numBytes >= streamMaxLength)
-				break;
-		}
-	}
-	return ret;
-}
-
-/*
- * Like strcpy, but return the END of the destination, allowing a quicker
- * means of adding to the end of a string than strcat
- */
-#if	0
-static char *
-strrcpy(char *dest, const char *source)
-{
-	/* Pre assertions */
-	assert(dest != NULL);
-	assert(source != NULL);
-	assert(dest != source);
-
-	while((*dest++ = *source++) != '\0')
-		;
-	return(--dest);
-}
-#endif
-
-/*
- * Read from clamav - timeout if necessary
- */
-static long
-clamd_recv(int sock, char *buf, size_t len)
-{
-	struct timeval tv;
-	long ret;
-
-	assert(sock >= 0);
-
-	if(readTimeout == 0) {
-		do
-			/* TODO: Needs a test for ssize_t in configure */
-			ret = (long)recv(sock, buf, len, 0);
-		while((ret < 0) && (errno == EINTR));
-
-		return ret;
-	}
-
-	tv.tv_sec = readTimeout;
-	tv.tv_usec = 0;
-
-	for(;;) {
-		fd_set rfds;
-
-		FD_ZERO(&rfds);
-		FD_SET(sock, &rfds);
-
-		switch(select(sock + 1, &rfds, NULL, NULL, &tv)) {
-			case -1:
-				if(errno == EINTR)
-					/* FIXME: work out time left */
-					continue;
-				perror("select");
-				return -1;
-			case 0:
-				logg(_("!No data received from clamd in %d seconds\n"), readTimeout);
-				return 0;
-		}
-		break;
-	}
-
-	do
-		ret = recv(sock, buf, len, 0);
-	while((ret < 0) && (errno == EINTR));
-
-	return ret;
-}
-
-/*
- * Read in the signature file
- */
-static off_t
-updateSigFile(void)
-{
-	struct stat statb;
-	int fd;
-
-	if(sigFilename == NULL)
-		/* nothing to read */
-		return 0;
-
-	if(stat(sigFilename, &statb) < 0) {
-		perror(sigFilename);
-		logg(_("Can't stat %s"), sigFilename);
-		return 0;
-	}
-
-	if(statb.st_mtime <= signatureStamp)
-		return statb.st_size;	/* not changed */
-
-	fd = open(sigFilename, O_RDONLY);
-	if(fd < 0) {
-		perror(sigFilename);
-		logg(_("Can't open %s"), sigFilename);
-		return 0;
-	}
-
-	signatureStamp = statb.st_mtime;
-
-	signature = cli_realloc((void *)signature, statb.st_size);
-	if(signature)
-		cli_readn(fd, (void *)signature, statb.st_size);
-	close(fd);
-
-	return statb.st_size;
-}
-
-static header_list_t
-header_list_new(void)
-{
-	header_list_t ret;
-
-	ret = (header_list_t)cli_malloc(sizeof(struct header_list_struct));
-	if(ret) {
-		ret->first = NULL;
-		ret->last = NULL;
-	}
-	return ret;
-}
-
-static void
-header_list_free(header_list_t list)
-{
-	struct header_node_t *iter;
-
-	if(list == NULL)
-		return;
-
-	iter = list->first;
-	while(iter) {
-		struct header_node_t *iter2 = iter->next;
-		free(iter->header);
-		free(iter);
-		iter = iter2;
-	}
-	free(list);
-}
-
-static void
-header_list_add(header_list_t list, const char *headerf, const char *headerv)
-{
-	char *header;
-	size_t len;
-	struct header_node_t *new_node;
-
-	if(list == NULL)
-		return;
-
-	len = (size_t)(strlen(headerf) + strlen(headerv) + 3);
-
-	header = (char *)cli_malloc(len);
-	if(header == NULL)
-		return;
-
-	sprintf(header, "%s: %s", headerf, headerv);
-	new_node = (struct header_node_t *)cli_malloc(sizeof(struct header_node_t));
-	if(new_node == NULL) {
-		free(header);
-		return;
-	}
-	new_node->header = header;
-	new_node->next = NULL;
-	if(list->first == NULL)
-		list->first = new_node;
-	if(list->last)
-		list->last->next = new_node;
-
-	list->last = new_node;
-}
-
-static void
-header_list_print(const header_list_t list, FILE *fp)
-{
-	const struct header_node_t *iter;
-
-	if(list == NULL)
-		return;
-
-	for(iter = list->first; iter; iter = iter->next) {
-		if(strncmp(iter->header, "From ", 5) == 0)
-			putc('>', fp);
-		fprintf(fp, "%s\n", iter->header);
-	}
-}
-
-/*
- * Establish a connexion to clamd
- *	Returns success (1) or failure (0)
- */
-static int
-connect2clamd(struct privdata *privdata)
-{
-	assert(privdata != NULL);
-	assert(privdata->dataSocket == -1);
-	assert(privdata->from != NULL);
-	assert(privdata->to != NULL);
-
-	logg("*connect2clamd\n");
-
-	if(quarantine_dir || tmpdir) {	/* store message in a temporary file */
-		int ntries = 5;
-		const char *dir = (tmpdir) ? tmpdir : quarantine_dir;
-
-		/*
-		 * TODO: investigate mkdtemp on LINUX and possibly others
-		 */
-#ifdef	C_AIX
-		/*
-		 * Patch by Andy Feldt <feldt at nhn.ou.edu>, AIX 5.2 sets errno
-		 * to ENOENT often and sometimes sets errno to 0 (after a
-		 * database reload) for the mkdir call
-		 */
-		if((mkdir(dir, 0700) < 0) && (errno != EEXIST) && (errno > 0) &&
-		    (errno != ENOENT)) {
-#else
-		if((mkdir(dir, 0700) < 0) && (errno != EEXIST)) {
-#endif
-			perror(dir);
-			logg(_("mkdir %s failed"), dir);
-			return 0;
-		}
-		privdata->filename = (char *)cli_malloc(strlen(dir) + 12);
-
-		if(privdata->filename == NULL)
-			return 0;
-
-		do {
-			sprintf(privdata->filename, "%s/msg.XXXXXX", dir);
-#if	defined(C_LINUX) || defined(C_BSD) || defined(HAVE_MKSTEMP) || defined(C_SOLARIS)
-			privdata->dataSocket = mkstemp(privdata->filename);
-#else
-			if(mktemp(privdata->filename) == NULL) {
-				logg(_("mktemp %s failed"), privdata->filename);
-				return 0;
-			}
-			privdata->dataSocket = open(privdata->filename, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC, 0600);
-#endif
-		} while((--ntries > 0) && (privdata->dataSocket < 0));
-
-		if(privdata->dataSocket < 0) {
-			perror(privdata->filename);
-			logg(_("Temporary quarantine file %s creation failed"),
-				privdata->filename);
-			free(privdata->filename);
-			privdata->filename = NULL;
-			return 0;
-		}
-		privdata->serverNumber = 0;
-		cli_dbgmsg("Saving message to %s to scan later\n", privdata->filename);
-	} else {	/* communicate to clamd */
-		int freeServer, nbytes;
-		in_port_t p;
-		struct sockaddr_in reply;
-		char buf[64];
-
-#ifdef	SESSION
-		struct session *session;
-#else
-		assert(privdata->cmdSocket == -1);
-#endif
-
-		/*
-		 * Create socket to talk to clamd. It will tell us the port to
-		 * use to send the data. That will require another socket.
-		 */
-		if(localSocket) {
-#ifndef	SESSION
-			struct sockaddr_un server;
-
-			memset((char *)&server, 0, sizeof(struct sockaddr_un));
-			server.sun_family = AF_UNIX;
-			strncpy(server.sun_path, localSocket, sizeof(server.sun_path));
-			server.sun_path[sizeof(server.sun_path)-1]='\0';
-
-			if((privdata->cmdSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
-				perror("socket");
-				return 0;
-			}
-			if(connect(privdata->cmdSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_un)) < 0) {
-				perror(localSocket);
-				return 0;
-			}
-			privdata->serverNumber = 0;
-#endif
-			freeServer = 0;
-		} else {	/* TCP/IP */
-#ifdef	SESSION
-			freeServer = findServer();
-			if(freeServer < 0)
-				return 0;
-			assert(freeServer < (int)max_children);
-#else
-			struct sockaddr_in server;
-
-			memset((char *)&server, 0, sizeof(struct sockaddr_in));
-			server.sin_family = AF_INET;
-			server.sin_port = (in_port_t)htons(tcpSocket);
-
-			assert(serverIPs != NULL);
-
-			freeServer = findServer();
-			if(freeServer < 0)
-				return 0;
-			assert(freeServer < (int)numServers);
-
-			server.sin_addr.s_addr = serverIPs[freeServer];
-
-			if((privdata->cmdSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-				perror("socket");
-				return 0;
-			}
-			if(connect(privdata->cmdSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
-				char *hostname = cli_strtok(serverHostNames, freeServer, ":");
-
-				perror(hostname ? hostname : "connect");
-				close(privdata->cmdSocket);
-				privdata->cmdSocket = -1;
-				if(hostname)
-					free(hostname);
-				time(&last_failed_pings[freeServer]);
-				return 0;
-			}
-			last_failed_pings[freeServer] = (time_t)0;
-#endif
-			privdata->serverNumber = freeServer;
-		}
-
-#ifdef	SESSION
-		if(serverIPs[freeServer] == (int)inet_addr("127.0.0.1")) {
-			privdata->filename = cli_gentemp(NULL);
-			if(privdata->filename) {
-				cli_dbgmsg("connect2clamd(%d): creating %s\n", freeServer, privdata->filename);
-#ifdef	O_TEXT
-				privdata->dataSocket = open(privdata->filename, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_TEXT, 0600);
-#else
-				privdata->dataSocket = open(privdata->filename, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
-#endif
-				if(privdata->dataSocket < 0) {
-					perror(privdata->filename);
-					free(privdata->filename);
-					privdata->filename = NULL;
-				} else
-					return sendToFrom(privdata);
-			}
-		}
-		cli_dbgmsg("connect2clamd(%d): STREAM\n", freeServer);
-
-		session = &sessions[freeServer];
-		if((session->sock < 0) || (send(session->sock, "STREAM\n", 7, 0) < 7)) {
-			perror("send");
-			pthread_mutex_lock(&sstatus_mutex);
-			session->status = CMDSOCKET_DOWN;
-			pthread_mutex_unlock(&sstatus_mutex);
-			logg(_("!failed to send STREAM command clamd server %d"),
-				freeServer);
-
-			return 0;
-		}
-#else
-		if(send(privdata->cmdSocket, "STREAM\n", 7, 0) < 7) {
-			perror("send");
-			logg(_("!failed to send STREAM command clamd"));
-			return 0;
-		}
-		shutdown(privdata->cmdSocket, SHUT_WR);
-#endif
-
-		/*
-		 * Create socket that we'll use to send the data to clamd
-		 */
-		if((privdata->dataSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-			perror("socket");
-			logg(_("!failed to create TCPSocket to talk to clamd\n"));
-			return 0;
-		}
-
-		shutdown(privdata->dataSocket, SHUT_RD);
-
-#ifdef	SESSION
-		nbytes = clamd_recv(session->sock, buf, sizeof(buf));
-		if(nbytes <= 0) {
-			if(nbytes < 0) {
-				perror("recv");
-				logg(_("!recv failed from clamd getting PORT\n"));
-			} else
-				logg(_("!EOF from clamd getting PORT\n"));
-
-			pthread_mutex_lock(&sstatus_mutex);
-			session->status = CMDSOCKET_DOWN;
-			return pthread_mutex_unlock(&sstatus_mutex);
-		}
-#else
-		nbytes = clamd_recv(privdata->cmdSocket, buf, sizeof(buf));
-		if(nbytes <= 0) {
-			if(nbytes < 0) {
-				perror("recv");
-				logg(_("!recv failed from clamd getting PORT\n"));
-			} else
-				logg(_("!EOF from clamd getting PORT\n"));
-
-			return 0;
-		}
-#endif
-		buf[nbytes] = '\0';
-#ifdef	CL_DEBUG
-		if(debug_level >= 4)
-			cli_dbgmsg("Received: %s\n", buf);
-#endif
-		if(sscanf(buf, "PORT %hu\n", &p) != 1) {
-			logg(_("!Expected port information from clamd, got '%s'\n"),
-				buf);
-#ifdef	SESSION
-			session->status = CMDSOCKET_DOWN;
-			pthread_mutex_unlock(&sstatus_mutex);
-#endif
-			return 0;
-		}
-
-		memset((char *)&reply, 0, sizeof(struct sockaddr_in));
-		reply.sin_family = AF_INET;
-		reply.sin_port = (in_port_t)htons(p);
-
-		assert(serverIPs != NULL);
-
-		reply.sin_addr.s_addr = serverIPs[freeServer];
-
-#ifdef	CL_DEBUG
-		if(debug_level >= 4)
-#ifdef	SESSION
-			cli_dbgmsg(_("Connecting to local port %d - data %d cmd %d\n"),
-				p, privdata->dataSocket, session->sock);
-#else
-			cli_dbgmsg(_("Connecting to local port %d - data %d cmd %d\n"),
-				p, privdata->dataSocket, privdata->cmdSocket);
-#endif
-#endif
-
-		if(connect(privdata->dataSocket, (struct sockaddr *)&reply, sizeof(struct sockaddr_in)) < 0) {
-			perror("connect");
-
-			cli_dbgmsg("Failed to connect to port %d given by clamd\n",
-				p);
-			/* 0.4 - use better error message */
-#ifdef HAVE_STRERROR_R
-			strerror_r(errno, buf, sizeof(buf));
-			logg(_("!Failed to connect to port %d given by clamd: %s"),
-					p, buf);
-#else
-			logg(_("!Failed to connect to port %d given by clamd: %s"), p, strerror(errno));
-#endif
-#ifdef	SESSION
-			pthread_mutex_lock(&sstatus_mutex);
-			session->status = CMDSOCKET_DOWN;
-			pthread_mutex_unlock(&sstatus_mutex);
-#endif
-			return 0;
-		}
-	}
-
-	if(!sendToFrom(privdata))
-		return 0;
-
-	cli_dbgmsg("connect2clamd: serverNumber = %d\n", privdata->serverNumber);
-
-	return 1;
-}
-
-/*
- * Combine the To and From into one clamfi_send to save bandwidth
- * when sending using TCP/IP to connect to a remote clamd, by band
- * width here I mean number of packets
- */
-static int
-sendToFrom(struct privdata *privdata)
-{
-	char **to;
-	char *msg;
-	int length;
-
-	length = strlen(privdata->from) + 34;
-	for(to = privdata->to; *to; to++)
-		length += strlen(*to) + 5;
-
-	msg = cli_malloc(length + 1);
-
-	if(msg) {
-		sprintf(msg, "Received: by clamav-milter\nFrom: %s\n",
-			privdata->from);
-
-		for(to = privdata->to; *to; to++) {
-			char *eom = strchr(msg, '\0');
-
-			sprintf(eom, "To: %s\n", *to);
-		}
-		if(clamfi_send(privdata, length, msg) != length) {
-			free(msg);
-			return 0;
-		}
-		free(msg);
-	} else {
-		if(clamfi_send(privdata, 0,
-		    "Received: by clamav-milter\nFrom: %s\n",
-		    privdata->from) <= 0)
-			return 0;
-
-		for(to = privdata->to; *to; to++)
-			if(clamfi_send(privdata, 0, "To: %s\n", *to) <= 0)
-				return 0;
-	}
-
-	return 1;
-}
-
-/*
- * If possible, check if clamd has died, and, if requested, report if it has
- * Returns true if OK or unknown, otherwise false
- */
-static int
-checkClamd(int log_result)
-{
-	pid_t pid;
-	int fd, nbytes;
-	char buf[9];
-
-	if(!localSocket) {
-		/* communicating via TCP, is one of the servers localhost? */
-		int i, onlocal;
-
-		onlocal = 0;
-		for(i = 0; i < numServers; i++)
-#ifdef	INADDR_LOOPBACK
-			if(serverIPs[0] == htonl(INADDR_LOOPBACK)) {
-#else
-			if(serverIPs[0] == inet_addr("127.0.0.1")) {
-#endif
-				onlocal = 1;
-				break;
-			}
-
-		if(!onlocal) {
-			/* No local clamd, use pingServer() to tell */
-			for(i = 0; i < numServers; i++)
-				if(serverIPs[i] && pingServer(i))
-					return 1;
-			if(log_result)
-				logg(_("!Can't find any clamd server\n"));
-			return 0;
-		}
-	}
-
-	if(pidFile == NULL)
-		return 1;	/* PidFile directive missing from clamd.conf */
-
-	fd = open(pidFile, O_RDONLY);
-	if(fd < 0) {
-		if(log_result) {
-			perror(pidFile);
-			logg(_("!Can't open %s\n"), pidFile);
-		}
-		return 1;	/* unknown */
-	}
-	nbytes = read(fd, buf, sizeof(buf) - 1);
-	if(nbytes < 0)
-		perror(pidFile);
-	else
-		buf[nbytes] = '\0';
-	close(fd);
-	pid = atoi(buf);
-	if((kill(pid, 0) < 0) && (errno == ESRCH)) {
-		if(log_result) {
-			perror("clamd");
-			logg(_("!Clamd (pid %d) seems to have died\n"), (int)pid);
-		}
-		return 0;	/* down */
-	}
-	return 1;	/* up */
-}
-
-/*
- * Send a templated message about an intercepted message. Very basic for
- * now, just to prove it works, will enhance the flexability later, only
- * supports %v and $sendmail_variables$ at present.
- *
- * TODO: more template features
- * TODO: allow filename to start with a '|' taken to mean the output of
- *	a program
- */
-static int
-sendtemplate(SMFICTX *ctx, const char *filename, FILE *sendmail, const char *virusname)
-{
-	FILE *fin = fopen(filename, "r");
-	struct stat statb;
-	char *buf, *ptr /* , *ptr2 */;
-	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-
-	if(fin == NULL) {
-		perror(filename);
-		logg(_("!Can't open e-mail template file %s"), filename);
-		return -1;
-	}
-
-	if(fstat(fileno(fin), &statb) < 0) {
-		/* File disappeared in race condition? */
-		perror(filename);
-		logg(_("!Can't stat e-mail template file %s"), filename);
-		fclose(fin);
-		return -1;
-	}
-	buf = cli_malloc(statb.st_size + 1);
-	if(buf == NULL) {
-		fclose(fin);
-		logg(_("!Out of memory"));
-		return -1;
-	}
-	if(fread(buf, sizeof(char), statb.st_size, fin) != (size_t)statb.st_size) {
-		perror(filename);
-		logg(_("!Error reading e-mail template file %s"),
-			filename);
-		fclose(fin);
-		free(buf);
-		return -1;
-	}
-	fclose(fin);
-	buf[statb.st_size] = '\0';
-
-	for(ptr = buf; *ptr; ptr++)
-		switch(*ptr) {
-			case '%': /* clamAV variable */
-				switch(*++ptr) {
-					case 'v':	/* virus name */
-						fputs(virusname, sendmail);
-						break;
-					case '%':
-						putc('%', sendmail);
-						break;
-					case 'h':	/* headers */
-						if(privdata)
-							header_list_print(privdata->headers, sendmail);
-						break;
-					case '\0':
-						putc('%', sendmail);
-						--ptr;
-						continue;
-					default:
-						logg(_("!%s: Unknown clamAV variable \"%c\"\n"),
-							filename, *ptr);
-						break;
-				}
-				break;
-			case '$': /* sendmail string */ {
-				const char *val;
-				char *end = strchr(++ptr, '$');
-
-				if(end == NULL) {
-					logg(_("!%s: Unterminated sendmail variable \"%s\"\n"),
-						filename, ptr);
-					continue;
-				}
-				*end = '\0';
-
-				val = smfi_getsymval(ctx, ptr);
-				if(val == NULL) {
-					fputs(ptr, sendmail);
-						logg(_("!%s: Unknown sendmail variable \"%s\"\n"),
-							filename, ptr);
-				} else
-					fputs(val, sendmail);
-				ptr = end;
-				break;
-			}
-			case '\\':
-				if(*++ptr == '\0') {
-					--ptr;
-					continue;
-				}
-				putc(*ptr, sendmail);
-				break;
-			default:
-				putc(*ptr, sendmail);
-		}
-
-	free(buf);
-
-	return 0;
-}
-
-/*
- * Keep the infected file in quarantine, return success (0) or failure
- *
- * It's quicker if the quarantine directory is on the same filesystem
- *	as the temporary directory
- */
-static int
-qfile(struct privdata *privdata, const char *sendmailId, const char *virusname)
-{
-	int MM, YY, DD;
-	time_t t;
-	size_t len;
-	char *newname, *ptr;
-	const struct tm *tm;
-
-	assert(privdata != NULL);
-
-	if((privdata->filename == NULL) || (virusname == NULL))
-		return -1;
-
-	cli_dbgmsg("qfile filename '%s' sendmailId '%s' virusname '%s'\n", privdata->filename, sendmailId, virusname);
-
-	len = strlen(quarantine_dir);
-
-	newname = cli_malloc(len + strlen(sendmailId) + strlen(virusname) + 10);
-
-	if(newname == NULL)
-		return -1;
-
-	t = time((time_t *)0);
-	tm = localtime(&t);
-	MM = tm->tm_mon + 1;
-	YY = tm->tm_year - 100;
-	DD = tm->tm_mday;
-
-	sprintf(newname, "%s/%02d%02d%02d", quarantine_dir, YY, MM, DD);
-#ifdef	C_AIX
-	if((mkdir(newname, 0700) < 0) && (errno != EEXIST) && (errno > 0) &&
-	    (errno != ENOENT)) {
-#else
-	if((mkdir(newname, 0700) < 0) && (errno != EEXIST)) {
-#endif
-		perror(newname);
-		logg(_("!mkdir %s failed\n"), newname);
-		return -1;
-	}
-	sprintf(newname, "%s/%02d%02d%02d/%s.%s",
-		quarantine_dir, YY, MM, DD, sendmailId, virusname);
-
-	/*
-	 * Strip out funnies that may be in the name of the virus, such as '/'
-	 * that would cause the quarantine to fail to save since the name
-	 * of the virus is included in the filename
-	 */
-	for(ptr = &newname[len + 8]; *ptr; ptr++) {
-#ifdef	C_DARWIN
-		*ptr &= '\177';
-#endif
-#if	defined(MSDOS) || defined(C_WINDOWS) || defined(C_OS2)
-		if(strchr("/*?<>|\\\"+=,;:\t ", *ptr))
-#else
-		if(*ptr == '/')
-#endif
-			*ptr = '_';
-	}
-	cli_dbgmsg("qfile move '%s' to '%s'\n", privdata->filename, newname);
-
-	if(move(privdata->filename, newname) < 0) {
-		logg(_("^Can't rename %1$s to %2$s\n"),
-			privdata->filename, newname);
-		free(newname);
-		return -1;
-	}
-	free(privdata->filename);
-	privdata->filename = newname;
-
-	logg(_("Email quarantined as %s\n"), newname);
-
-	return 0;
-}
-
-/*
- * Move oldfile to newfile using the fastest possible method
- */
-static int
-move(const char *oldfile, const char *newfile)
-{
-	int ret, c;
-	FILE *fin, *fout;
-#ifdef	C_LINUX
-	struct stat statb;
-	int in, out;
-	off_t offset;
-#endif
-
-	ret = rename(oldfile, newfile);
-	if(ret >= 0)
-		return 0;
-
-	if((ret < 0) && (errno != EXDEV)) {
-		perror(newfile);
-		return -1;
-	}
-
-#ifdef	C_LINUX	/* >= 2.2 */
-	in = open(oldfile, O_RDONLY);
-	if(in < 0) {
-		perror(oldfile);
-		return -1;
-	}
-
-	if(fstat(in, &statb) < 0) {
-		perror(oldfile);
-		close(in);
-		return -1;
-	}
-	out = open(newfile, O_WRONLY|O_CREAT, 0600);
-	if(out < 0) {
-		perror(newfile);
-		close(in);
-		return -1;
-	}
-	offset = (off_t)0;
-	ret = sendfile(out, in, &offset, statb.st_size);
-	close(in);
-	if(ret < 0) {
-		/*
-		 * Fall back if sendfile fails, which will happen on Linux
-		 * 2.6 :-(. FreeBSD works correctly, so the ifdef should be
-		 * fixed
-		 */
-		close(out);
-		unlink(newfile);
-
-		fin = fopen(oldfile, "r");
-		if(fin == NULL)
-			return -1;
-
-		fout = fopen(newfile, "w");
-		if(fout == NULL) {
-			fclose(fin);
-			return -1;
-		}
-		while((c = getc(fin)) != EOF)
-			putc(c, fout);
-
-		fclose(fin);
-		fclose(fout);
-	} else
-		close(out);
-#else
-	fin = fopen(oldfile, "r");
-	if(fin == NULL)
-		return -1;
-
-	fout = fopen(newfile, "w");
-	if(fout == NULL) {
-		fclose(fin);
-		return -1;
-	}
-	while((c = getc(fin)) != EOF)
-		putc(c, fout);
-
-	fclose(fin);
-	fclose(fout);
-#endif
-
-	cli_dbgmsg("removing %s\n", oldfile);
-
-	return unlink(oldfile);
-}
-
-/*
- * Store the name of the virus in the subject of the e-mail
- */
-static void
-setsubject(SMFICTX *ctx, const char *virusname)
-{
-	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-	char subject[128];
-
-	if(privdata->subject)
-		smfi_addheader(ctx, "X-Original-Subject", privdata->subject);
-
-	snprintf(subject, sizeof(subject) - 1, _("[Virus] %s"), virusname);
-	if(privdata->subject)
-		smfi_chgheader(ctx, "Subject", 1, subject);
-	else
-		smfi_addheader(ctx, "Subject", subject);
-}
-
-#if	0
-/*
- * TODO: gethostbyname_r is non-standard so different operating
- * systems do it in different ways. Need more examples
- * Perhaps we could use res_search()?
- * Perhaps we could use http://www.chiark.greenend.org.uk/~ian/adns/
- *
- * Returns 0 for success
- */
-static int
-clamfi_gethostbyname(const char *hostname, struct hostent *hp, char *buf, size_t len)
-{
-#if	defined(HAVE_GETHOSTBYNAME_R_6)
-	/* e.g. Linux */
-	struct hostent *hp2;
-	int ret = -1;
-
-	if((hostname == NULL) || (hp == NULL))
-		return -1;
-	if(gethostbyname_r(hostname, hp, buf, len, &hp2, &ret) < 0)
-		return ret;
-#elif	defined(HAVE_GETHOSTBYNAME_R_5)
-	/* e.g. BSD, Solaris, Cygwin */
-	int ret = -1;
-
-	if((hostname == NULL) || (hp == NULL))
-		return -1;
-	if(gethostbyname_r(hostname, hp, buf, len, &ret) == NULL)
-		return ret;
-#elif	defined(HAVE_GETHOSTBYNAME_R_3)
-	/* e.g. HP/UX, AIX */
-	if((hostname == NULL) || (hp == NULL))
-		return -1;
-	if(gethostbyname_r(hostname, &hp, (struct hostent_data *)buf) < 0)
-		return h_errno;
-#else
-	/* Single thread the code */
-	struct hostent *hp2;
-	static pthread_mutex_t hostent_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-	if((hostname == NULL) || (hp == NULL))
-		return -1;
-
-	pthread_mutex_lock(&hostent_mutex);
-	if((hp2 = gethostbyname(hostname)) == NULL) {
-		pthread_mutex_unlock(&hostent_mutex);
-		return h_errno;
-	}
-	memcpy(hp, hp2, sizeof(struct hostent));
-	pthread_mutex_unlock(&hostent_mutex);
-#endif
-
-	return 0;
-}
-#endif
-
-/*
- * Handle the -I flag
- */
-static int
-add_local_ip(char *address)
-{
-	char *opt, *pref;
-	int preflen;
-	int retval;
-	struct in_addr ignoreIP;
-#ifdef	AF_INET6
-	struct in6_addr ignoreIP6;
-#endif
-
-	opt = cli_strdup(address);
-	if(opt == NULL)
-		return 0;
-
-	pref = strchr(opt, '/'); /* search for "/prefix" */
-	if(pref)
-		*pref = '\0';
-#ifdef HAVE_INET_NTOP
-	/* IPv4 address ? */
-	if(inet_pton(AF_INET, opt, &ignoreIP) > 0) {
-#else
-	if(inet_aton(address, &ignoreIP)) {
-#endif
-		struct cidr_net *net;
-
-		for(net = (struct cidr_net *)localNets; net->base; net++)
-			;
-		if(pref && *(pref+1))
-			preflen = atoi(pref+1);
-		else
-			preflen = 32;
-
-		net->base = ntohl(ignoreIP.s_addr);
-		net->mask = MAKEMASK(preflen);
-
-		retval = 1;
-	}
-
-#ifdef HAVE_INET_NTOP
-#ifdef AF_INET6
-	else if(inet_pton(AF_INET6, opt, &ignoreIP6) > 0) {
-		/* IPv6 address ? */
-		localNets6[localNets6_cnt].base = ignoreIP6;
-
-		if(pref && *(pref+1))
-			preflen = atoi (pref+1);
-		else
-			preflen = 128;
-		localNets6[localNets6_cnt].preflen = preflen;
-		localNets6_cnt++;
-
-		retval = 1;
-	}
-#endif
-#endif
-	else
-		retval = 0;
-
-	free(opt);
-	return retval;
-}
-
-/*
- * Determine if an IPv6 email address is "local". The address is the
- *	human readable version. Calls isLocalAddr if the given address is
- *	IPv4
- */
-static int
-isLocal(const char *addr)
-{
-	struct in_addr ip;
-#ifdef	AF_INET6
-	struct in6_addr ip6;
-#endif
-
-#ifdef HAVE_INET_NTOP
-	if(inet_pton(AF_INET, addr, &ip) > 0)
-		return isLocalAddr(ip.s_addr);
-#ifdef AF_INET6
-	else if(inet_pton (AF_INET6, addr, &ip6) > 0) {
-		int i;
-		const cidr_net6 *pnet6 = localNets6;
-
-		for (i = 0; i < localNets6_cnt; i++) {
-			int match = 1;
-			int j;
-
-			for(j = 0; match && j < (pnet6->preflen >> 3); j++)
-				if(pnet6->base.s6_addr[j] != ip6.s6_addr[j])
-					match = 0;
-			if(match && (j < 16)) {
-				uint8_t mask = (uint8_t)(0xff << (8 - (pnet6->preflen & 7)) & 0xFF);
-
-				if((pnet6->base.s6_addr[j] & mask) != (ip6.s6_addr[j] & mask))
-					match = 0;
-			}
-			if(match)
-				return 1;	/* isLocal */
-			pnet6++;
-		 }
-	}
-#endif	/* AF_INET6 */
-#endif	/* HAVE_INET_NTOP */
-	return isLocalAddr(inet_addr(addr));
-}
-
-/*
- * David Champion <dgc at uchicago.edu>
- *
- * Check whether addr is on network by applying netmasks.
- * addr must be a 32-bit integer-packed IPv4 address in network order.
- * For example:
- *	struct in_addr IPAddress;
- *	isLocal = isLocalAddr(IPAddress.s_addr);
- */
-static int
-isLocalAddr(in_addr_t addr)
-{
-	const struct cidr_net *net;
-
-	for(net = localNets; net->base; net++)
-		if((net->base & net->mask) == (ntohl(addr) & net->mask))
-			return 1;
-
-	return 0;	/* is non-local */
-}
-
-/*
- * Can't connect to any clamd server. This is serious, we need to inform
- * someone. In the absence of SNMP the best way is by e-mail. We
- * don't want to flood so there's a need to restrict to
- * no more than say one message every 15 minutes
- */
-static void
-clamdIsDown(void)
-{
-	static time_t lasttime;
-	time_t thistime, diff;
-	static pthread_mutex_t time_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-	logg(_("!No response from any clamd server - your AV system is not scanning emails\n"));
-
-	time(&thistime);
-	pthread_mutex_lock(&time_mutex);
-	diff = thistime - lasttime;
-	pthread_mutex_unlock(&time_mutex);
-
-	if(diff >= (time_t)(15 * 60)) {
-		char cmd[128];
-		FILE *sendmail;
-
-		snprintf(cmd, sizeof(cmd) - 1, "%s -t -i", SENDMAIL_BIN);
-
-		sendmail = popen(cmd, "w");
-
-		if(sendmail) {
-			fprintf(sendmail, "To: %s\n", postmaster);
-			fprintf(sendmail, "From: %s\n", postmaster);
-			fputs(_("Subject: ClamAV Down\n"), sendmail);
-			fputs("Priority: High\n\n", sendmail);
-
-			fputs(_("This is an automatic message\n\n"), sendmail);
-
-			if(numServers == 1)
-				fputs(_("The clamd program cannot be contacted.\n"), sendmail);
-			else
-				fputs(_("No clamd server can be contacted.\n"), sendmail);
-
-			fputs(_("Emails may not be being scanned, please check your servers.\n"), sendmail);
-
-			if(pclose(sendmail) == 0) {
-				pthread_mutex_lock(&time_mutex);
-				time(&lasttime);
-				pthread_mutex_unlock(&time_mutex);
-			}
-		}
-	}
-}
-
-#ifdef	SESSION
-/*
- * Thread to monitor the links to clamd sessions. Any marked as being in
- * an error state because of previous I/O errors are restarted, and a heartbeat
- * is sent the others
- *
- * It is woken up when the milter goes idle, when there are no free servers
- * available and once every readTimeout-1 seconds
- *
- * TODO: reload the whiteList file if it's been changed
- *
- * TODO: localSocket support
- */
-static void *
-watchdog(void *a)
-{
-	static pthread_mutex_t watchdog_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-	while(!quitting) {
-		unsigned int i;
-		struct timespec ts;
-		struct timeval tp;
-		struct session *session;
-
-		gettimeofday(&tp, NULL);
-
-		ts.tv_sec = tp.tv_sec + freshclam_monitor;
-		ts.tv_nsec = tp.tv_usec * 1000;
-		cli_dbgmsg("watchdog sleeps\n");
-		pthread_mutex_lock(&watchdog_mutex);
-		/*
-		 * Sometimes this returns EPIPE which isn't listed as a
-		 * return value in the Linux man page for pthread_cond_timedwait
-		 * so I'm not sure why it happens
-		 */
-		switch(pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex, &ts)) {
-			case ETIMEDOUT:
-			case 0:
-				break;
-			default:
-				perror("pthread_cond_timedwait");
-		}
-		pthread_mutex_unlock(&watchdog_mutex);
-
-		cli_dbgmsg("watchdog wakes\n");
-
-		if(check_and_reload_database() != 0) {
-			if(cl_error != SMFIS_ACCEPT) {
-				smfi_stop();
-				return NULL;
-			}
-			logg(_("!No emails will be scanned"));
-		}
-
-		i = 0;
-		session = sessions;
-		pthread_mutex_lock(&sstatus_mutex);
-		for(; i < max_children; i++, session++) {
-			const int sock = session->sock;
-
-			/*
-			 * Check all free sessions are still usable
-			 * This could take some time with many free
-			 * sessions to slow remote servers, so only do this
-			 * when the system is quiet (not 100% accurate when
-			 * determining this since n_children isn't locked but
-			 * that doesn't really matter)
-			 */
-			cli_dbgmsg("watchdog: check server %d\n", i);
-			if((n_children == 0) &&
-			   (session->status == CMDSOCKET_FREE) &&
-			   (clamav_versions != NULL)) {
-				if(send(sock, "VERSION\n", 8, 0) == 8) {
-					char buf[81];
-					const int nbytes = clamd_recv(sock, buf, sizeof(buf) - 1);
-
-					if(nbytes <= 0)
-						session->status = CMDSOCKET_DOWN;
-					else {
-						buf[nbytes] = '\0';
-						if(strncmp(buf, "ClamAV ", 7) == 0) {
-							/* Remove the trailing new line from the reply */
-							char *ptr;
-
-							if((ptr = strchr(buf, '\n')) != NULL)
-								*ptr = '\0';
-							pthread_mutex_lock(&version_mutex);
-							if(clamav_versions[i] == NULL)
-								clamav_versions[i] = cli_strdup(buf);
-							else if(strcmp(buf, clamav_versions[i]) != 0) {
-								logg("New version received for server %d: '%s'\n", i, buf);
-								free(clamav_versions[i]);
-								clamav_versions[i] = cli_strdup(buf);
-							}
-							pthread_mutex_unlock(&version_mutex);
-						} else {
-							cli_warnmsg("watchdog: expected \"ClamAV\", got \"%s\"\n", buf);
-							session->status = CMDSOCKET_DOWN;
-						}
-					}
-				} else {
-					perror("send");
-					session->status = CMDSOCKET_DOWN;
-				}
-
-				if(session->status == CMDSOCKET_DOWN)
-					cli_warnmsg("Session %d has gone down\n", i);
-			}
-			/*
-			 * Reset all all dead sessions
-			 */
-			if(session->status == CMDSOCKET_DOWN) {
-				/*
-				 * The END command probably won't get through,
-				 * but let's give it a go anyway
-				 */
-				if(sock >= 0) {
-					send(sock, "END\n", 4, 0);
-					close(sock);
-				}
-
-				cli_dbgmsg("Trying to restart session %d\n", i);
-				if(createSession(i) == 0) {
-					session->status = CMDSOCKET_FREE;
-					cli_warnmsg("Session %d restarted OK\n", i);
-				}
-			}
-		}
-		for(i = 0; i < max_children; i++)
-			if(sessions[i].status != CMDSOCKET_DOWN)
-				break;
-
-		if(i == max_children)
-			clamdIsDown();
-		pthread_mutex_unlock(&sstatus_mutex);
-
-		/* Garbage collect IP addresses no longer blacklisted */
-		if(blacklist) {
-			pthread_mutex_lock(&blacklist_mutex);
-			tableIterate(blacklist, timeoutBlacklist, NULL);
-			pthread_mutex_unlock(&blacklist_mutex);
-		}
-	}
-	cli_dbgmsg("watchdog quits\n");
-	return NULL;
-}
-#else	/*!SESSION*/
-/*
- * Reload the database from time to time, when using the internal scanner
- *
- * TODO: reload the whiteList file if it's been changed
- */
-/*ARGSUSED*/
-static void *
-watchdog(void *a)
-{
-	static pthread_mutex_t watchdog_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-	if((!blacklist_time) && external)
-		return NULL;	/* no need for this thread */
-
-	while(!quitting) {
-		struct timespec ts;
-		struct timeval tp;
-
-		gettimeofday(&tp, NULL);
-
-		ts.tv_sec = tp.tv_sec + freshclam_monitor;
-		ts.tv_nsec = tp.tv_usec * 1000;
-		cli_dbgmsg("watchdog sleeps\n");
-
-		pthread_mutex_lock(&watchdog_mutex);
-		/*
-		 * Sometimes this returns EPIPE which isn't listed as a
-		 * return value in the Linux man page for pthread_cond_timedwait
-		 * so I'm not sure why it happens
-		 */
-		switch(pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex, &ts)) {
-			case ETIMEDOUT:
-			case 0:
-				break;
-			default:
-				perror("pthread_cond_timedwait");
-		}
-		pthread_mutex_unlock(&watchdog_mutex);
-		cli_dbgmsg("watchdog wakes\n");
-
-		/*
-		 * TODO: sanity check that if n_children == 0, that
-		 * root->refcount == 0. Unfortunatly root->refcount isn't
-		 * thread-safe, since it's governed by a mutex that we can't
-		 * see, and there's no access to it via an approved method
-		 */
-		if(check_and_reload_database() != 0) {
-			if(cl_error != SMFIS_ACCEPT) {
-				smfi_stop();
-				return NULL;
-			}
-			logg(_("!No emails will be scanned"));
-		}
-		/* Garbage collect IP addresses no longer blacklisted */
-		if(blacklist) {
-			pthread_mutex_lock(&blacklist_mutex);
-			tableIterate(blacklist, timeoutBlacklist, NULL);
-			pthread_mutex_unlock(&blacklist_mutex);
-		}
-	}
-	cli_dbgmsg("watchdog quits\n");
-	return NULL;
-}
-#endif
-
-/*
- * Check to see if the database needs to be reloaded
- *	Return 0 for success
- */
-static int
-check_and_reload_database(void)
-{
-	int rc;
-
-	if(external)
-		return 0;
-
-	if(reload) {
-		rc = 1;
-		reload = 0;
-	} else
-		rc = cl_statchkdir(&dbstat);
-
-	switch(rc) {
-		case 1:
-			logg("^Database has changed, loading updated database\n");
-			cl_statfree(&dbstat);
-			rc = loadDatabase();
-			if(rc != 0) {
-				logg("!Failed to load updated database\n");
-				return rc;
-			}
-			break;
-		case 0:
-			logg("*Database has not changed\n");
-			break;
-		default:
-			logg("Database error %d - %s is stopping\n",
-				rc, progname);
-			return 1;
-	}
-	return 0;	/* all OK */
-}
-
-static void
-timeoutBlacklist(char *ip_address, int time_of_blacklist, void *v)
-{
-	if(time_of_blacklist == 0)	/* Must not blacklist this IP address */
-		return;
-	if((time((time_t *)0) - time_of_blacklist) > blacklist_time)
-		tableRemove(blacklist, ip_address);
-}
-
-static void
-quit(void)
-{
-	quitting++;
-
-#ifdef	SESSION
-	pthread_mutex_lock(&version_mutex);
-#endif
-	logg(_("Stopping %s\n"), clamav_version);
-#ifdef	SESSION
-	pthread_mutex_unlock(&version_mutex);
-#endif
-
-	if(!external) {
-		pthread_mutex_lock(&engine_mutex);
-		if(engine)
-			cl_engine_free(engine);
-		pthread_mutex_unlock(&engine_mutex);
-	} else {
-#ifdef	SESSION
-		int i = 0;
-		struct session *session = sessions;
-
-		pthread_mutex_lock(&sstatus_mutex);
-		for(; i < ((localSocket != NULL) ? 1 : (int)max_children); i++) {
-			/*
-			 * Check all free sessions are still usable
-			 * This could take some time with many free
-			 * sessions to slow remote servers, so only do this
-			 * when the system is quiet (not 100% accurate when
-			 * determining this since n_children isn't locked but
-			 * that doesn't really matter)
-			 */
-			cli_dbgmsg("quit: close server %d\n", i);
-			if(session->status == CMDSOCKET_FREE) {
-				const int sock = session->sock;
-
-				send(sock, "END\n", 4, 0);
-				shutdown(sock, SHUT_WR);
-				session->status = CMDSOCKET_DOWN;
-				pthread_mutex_unlock(&sstatus_mutex);
-				close(sock);
-				pthread_mutex_lock(&sstatus_mutex);
-			}
-			session++;
-		}
-		pthread_mutex_unlock(&sstatus_mutex);
-#endif
-	}
-
-	if(tmpdir)
-		if(rmdir(tmpdir) < 0)
-			perror(tmpdir);
-
-	broadcast(_("Stopping clamav-milter"));
-
-	if(pidfile)
-		if(unlink(pidfile) < 0)
-			perror(pidfile);
-
-	logg_close();
-}
-
-static void
-broadcast(const char *mess)
-{
-	struct sockaddr_in s;
-
-	if(broadcastSock < 0)
-		return;
-
-	memset(&s, '\0', sizeof(struct sockaddr_in));
-	s.sin_family = AF_INET;
-	s.sin_port = (in_port_t)htons(tcpSocket ? tcpSocket : 3310);
-	s.sin_addr.s_addr = htonl(INADDR_BROADCAST);
-
-	cli_dbgmsg("broadcast %s to %d\n", mess, broadcastSock);
-	if(sendto(broadcastSock, mess, strlen(mess), 0, (struct sockaddr *)&s, sizeof(struct sockaddr_in)) < 0)
-		perror("sendto");
-}
-
-/*
- * Load a new database into the internal scanner
- */
-static int
-loadDatabase(void)
-{
-	int ret;
-	unsigned int signatures, dboptions;
-	char *daily;
-	struct cl_cvd *d;
-	const struct cfgstruct *cpt;
-	static const char *dbdir;
-
-	assert(!external);
-
-	if(dbdir == NULL) {
-		/*
-		 * First time through, find out in which directory the signature
-		 * databases are
-		 */
-		if((cpt = cfgopt(copt, "DatabaseDirectory")) && cpt->enabled)
-			dbdir = cpt->strarg;
-		else
-			dbdir = cl_retdbdir();
-	}
-
-	daily = cli_malloc(strlen(dbdir) + 11);
-	sprintf(daily, "%s/daily.cvd", dbdir);
-	if(access(daily, R_OK) < 0)
-		sprintf(daily, "%s/daily.cld", dbdir);
-
-
-	cli_dbgmsg("loadDatabase: check %s for updates\n", daily);
-
-	d = cl_cvdhead(daily);
-
-	if(d) {
-		char *ptr;
-		time_t t = d->stime;
-		char buf[26];
-
-		snprintf(clamav_version, VERSION_LENGTH,
-			"ClamAV %s/%u/%s", get_version(), d->version,
-			cli_ctime(&t, buf, sizeof(buf)));
-
-		/* Remove ctime's trailing \n */
-		if((ptr = strchr(clamav_version, '\n')) != NULL)
-			*ptr = '\0';
-
-		cl_cvdfree(d);
-	} else
-		snprintf(clamav_version, VERSION_LENGTH,
-			"ClamAV version %s, clamav-milter version %s",
-			cl_retver(), get_version());
-
-	free(daily);
-
-#ifdef	SESSION
-	pthread_mutex_lock(&version_mutex);
-	if(clamav_versions == NULL) {
-		clamav_versions = (char **)cli_malloc(sizeof(char *));
-		if(clamav_versions == NULL) {
-			pthread_mutex_unlock(&version_mutex);
-			return -1;
-		}
-		clamav_version = cli_malloc(VERSION_LENGTH + 1);
-		if(clamav_version == NULL) {
-			free(clamav_versions);
-			clamav_versions = NULL;
-			pthread_mutex_unlock(&version_mutex);
-			return -1;
-		}
-	}
-	pthread_mutex_unlock(&version_mutex);
-#endif
-	signatures = 0;
-	pthread_mutex_lock(&engine_mutex);
-	if(engine) cl_engine_free(engine);
-	engine = cl_engine_new();
-	if (!engine) {
-		logg("!Can't initialize antivirus engine\n");
-		pthread_mutex_unlock(&engine_mutex);
-		return -1;
-	}
-	if(!cfgopt(copt, "PhishingSignatures")->enabled) {
-		logg("Not loading phishing signatures.\n");
-		dboptions = 0;
-	} else
-		dboptions = CL_DB_PHISHING;
-	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_SCANSIZE, &maxscansize))) {
-		logg("!cli_engine_set(CL_ENGINE_MAX_SCANSIZE) failed: %s\n", cl_strerror(ret));
-		cl_engine_free(engine);
-		pthread_mutex_unlock(&engine_mutex);
-		return -1;
-	}
-	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_FILESIZE, &maxfilesize))) {
-		logg("!cli_engine_set(CL_ENGINE_MAX_FILESIZE) failed: %s\n", cl_strerror(ret));
-		cl_engine_free(engine);
-		pthread_mutex_unlock(&engine_mutex);
-		return -1;
-	}
-	ret = cl_load(dbdir, engine, &signatures, dboptions);
-	if(ret != CL_SUCCESS) {
-		logg("!%s\n", cl_strerror(ret));
-		cl_engine_free(engine);
-		pthread_mutex_unlock(&engine_mutex);
-		return -1;
-	}
-	ret = cl_engine_compile(engine);
-	if(ret != CL_SUCCESS) {
-		logg("!Database initialization error: %s\n", cl_strerror(ret));
-		cl_engine_free(engine);
-		pthread_mutex_unlock(&engine_mutex);
-		return -1;
-	}
-	pthread_mutex_unlock(&engine_mutex);
-#ifdef	SESSION
-	pthread_mutex_lock(&version_mutex);
-#endif
-	logg( _("Loaded %s\n"), clamav_version);
-#ifdef	SESSION
-	pthread_mutex_unlock(&version_mutex);
-#endif
-	logg(_("ClamAV: Protecting against %u viruses\n"), signatures);
-	logg("#Database correctly (re)loaded (%u viruses)\n");
-	return cl_statinidir(dbdir, &dbstat);
-}
-
-static void
-sigsegv(int sig)
-{
-	signal(SIGSEGV, SIG_DFL);
-
-#ifdef HAVE_BACKTRACE
-	print_trace();
-#endif
-
-	logg("!Segmentation fault :-( Bye.., notify bugs at clamav.net\n");
-
-	quitting++;
-	smfi_stop();
-}
-
-extern FILE *logg_fd;
-static void
-sigusr1(int sig)
-{
-
-	signal(SIGUSR1, sigusr1);
-
-	if(!(cfgopt(copt, "LogFile"))->enabled)
-		return;
-
-	logg("SIGUSR1 caught: re-opening log file\n");
-	logg_close();
-	logg("*Log file re-opened\n");
-	dup2(fileno(logg_fd), 2);
-}
-
-static void
-sigusr2(int sig)
-{
-	signal(SIGUSR2, sigusr2);
-
-	logg("^SIGUSR2 caught: scheduling database reload\n");
-	reload++;
-}
-
-#ifdef HAVE_BACKTRACE
-static void
-print_trace(void)
-{
-	void *array[BACKTRACE_SIZE];
-	size_t size, i;
-	char **strings;
-	pid_t pid = getpid();
-
-	size = backtrace(array, BACKTRACE_SIZE);
-	strings = backtrace_symbols(array, size);
-
-	logg("*Backtrace of pid %d:\n", pid);
-
-	for(i = 0; i < size; i++)
-		logg("bt[%u]: %s", i, strings[i]);
-
-	/* TODO: dump the current email */
-
-	free(strings);
-}
-#endif
-
-/*
- * Check that the correct port name has been given, i.e. that the
- * input socket to clamav-milter from sendmail, is the same that
- * sendmail has been configured to use as it's output socket
- * Return:	<0 invalid
- *		=0 valid
- *		>0 unknown
- *
- * You wouldn't believe the amount of time I used to waste chasing bug reports
- *	from people who's sendmail.cf didn't tally with the arguments given to
- *	clamav-milter before I put this check in, which is why bug 726 must
- *	never be acted upon.
- *
- * FIXME: return different codes for "the value is wrong" and "sendmail.cf"
- *	hasn't been set up, though that's not so easy to work out.
- */
-static int
-verifyIncomingSocketName(const char *sockName)
-{
-#if HAVE_MMAP
-	int fd, ret;
-	char *ptr;
-	size_t size;
-	struct stat statb;
-
-	if(strncmp(sockName, "inet:", 5) == 0)
-		/*
-		 * clamav-milter is running on a different machine from sendmail
-		 */
-		return 1;
-
-	if(sendmailCF)
-		fd = open(sendmailCF, O_RDONLY);
-	else {
-		fd = open("/etc/mail/sendmail.cf", O_RDONLY);
-		if(fd < 0)
-			fd = open("/etc/sendmail.cf", O_RDONLY);
-	}
-
-	if(fd < 0)
-		return 1;
-
-	if(fstat(fd, &statb) < 0) {
-		close(fd);
-		return 1;
-	}
-
-	size = statb.st_size;
-
-	if(size == 0) {
-		close(fd);
-		return -1;
-	}
-
-	ptr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
-	if(ptr == MAP_FAILED) {
-		perror("mmap");
-		close(fd);
-		return -1;
-	}
-
-	ret = (cli_memstr(ptr, size, sockName, strlen(sockName)) != NULL) ? 1 : -1;
-
-	munmap(ptr, size);
-	close(fd);
-
-	return ret;
-#else	/*!HAVE_MMAP*/
-	return 1;
-#endif
-}
-
-/*
- * If the given email address is whitelisted don't scan emails to them,
- *	the addresses are in angle brackets e.g. <foo at bar.com>.
- *
- * TODO: Allow regular expressions in the addresses
- * TODO: Syntax check the contents of the files
- * TODO: Allow emails of the form "name <address>"
- * TODO: Allow emails not of the form "<address>", i.e. no angle brackets
- * TODO: Assume that if a '@' is missing from the address, that all emails
- *	to that domain are to be whitelisted
- */
-static int
-isWhitelisted(const char *emailaddress, int to)
-{
-	static table_t *to_whitelist, *from_whitelist;	/* never freed */
-	table_t *table;
-
-	logg("*isWhitelisted %s\n", emailaddress);
-
-	/*
-	 * Don't scan messages to the quarantine email address
-	 */
-	if(quarantine && (strcasecmp(quarantine, emailaddress) == 0))
-		return 1;
-
-	if((to_whitelist == NULL) && whitelistFile) {
-		FILE *fin;
-		char buf[BUFSIZ + 1];
-
-		fin = fopen(whitelistFile, "r");
-
-		if(fin == NULL) {
-			perror(whitelistFile);
-			logg(_("!Can't open whitelist file %s"), whitelistFile);
-			return 0;
-		}
-		to_whitelist = tableCreate();
-		from_whitelist = tableCreate();
-
-		if((to_whitelist == NULL) || (from_whitelist == NULL)) {
-			logg(_("!Can't create whitelist table"));
-			if(to_whitelist) {
-				tableDestroy(to_whitelist);
-				to_whitelist = NULL;
-			} else {
-				tableDestroy(from_whitelist);
-				from_whitelist = NULL;
-			}
-			fclose(fin);
-			return 0;
-		}
-
-		while(fgets(buf, sizeof(buf), fin) != NULL) {
-			const char *ptr;
-
-			/* comment line? */
-			switch(buf[0]) {
-				case '#':
-				case '/':
-				case ':':
-					continue;
-			}
-			if(cli_chomp(buf) > 0) {
-				if((ptr = strchr(buf, ':')) != NULL) {
-					do
-						ptr++;
-					while(*ptr && isspace(*ptr));
-
-					if(*ptr == '\0') {
-						logg("*Ignoring bad line '%s'\n",
-							buf);
-						continue;
-					}
-				} else
-					ptr = buf;
-
-				if(strncasecmp(buf, "From:", 5) == 0)
-					table = from_whitelist;
-				else
-					table = to_whitelist;
-
-				(void)tableInsert(table, ptr, 1);
-			}
-		}
-		fclose(fin);
-	}
-	table = (to) ? to_whitelist : from_whitelist;
-
-	if(table && (tableFind(table, emailaddress) == 1))
-		/*
-		 * This recipient is on the whitelist
-		 */
-		return 1;
-
-	return 0;
-}
-
-/*
- * Blacklist IP addresses that send malware. Often in the phishing world, one
- * phish is quickly followed by another. IP addresses are blacklisted for one
- * minute. We can't blacklist for longer since DHCP means we could hit innocent
- * parties, and in theory malware could go through a smart host and affect
- * innocent parties
- *
- * Note that sites which can't be blacklisted will have their timestamp set
- * to 0, since that can never be less than blacklist_time seconds from now
- */
-static int
-isBlacklisted(const char *ip_address)
-{
-	time_t t;
-
-	if(blacklist_time == 0)
-		/* Blacklisting not being used */
-		return 0;
-
-	logg("*isBlacklisted %s\n", ip_address);
-
-	if(isLocal(ip_address))
-		return 0;
-
-	pthread_mutex_lock(&blacklist_mutex);
-	if(blacklist == NULL) {
-		blacklist = tableCreate();
-
-		pthread_mutex_unlock(&blacklist_mutex);
-
-		if(blacklist == NULL)
-			logg(_("!Can't create blacklist table"));
-		return 0;
-	}
-	t = tableFind(blacklist, ip_address);
-	pthread_mutex_unlock(&blacklist_mutex);
-
-	if(t == (time_t)-1)
-		/* IP address is not blacklisted */
-		return 0;
-
-	if(t == (time_t)0)
-		/* IP cannot be blacklisted */
-		return 0;
-
-	if((time((time_t *)0) - t) <= blacklist_time)
-		return 1;
-
-	/* timedout: remove the IP from the blacklist */
-	pthread_mutex_lock(&blacklist_mutex);
-	tableRemove(blacklist, ip_address);
-	pthread_mutex_unlock(&blacklist_mutex);
-
-	return 0;
-}
-
-#ifdef	HAVE_RESOLV_H
-/*
- * Determine our MX peers, they must never be blacklisted
- * See RFC1034 for the definition of the record formats
- *
- * This is only ever called once, which is wrong, but the overheard of calling
- * this from the watchdog isn't worth it
- */
-static table_t *
-mx(const char *host, table_t *t)
-{
-	u_char *p, *end;
-	const HEADER *hp;
-	int len, i;
-	union {
-		HEADER h;
-		u_char u[PACKETSZ];
-	} q;
-	char buf[BUFSIZ];
-
-	if(t == NULL) {
-		t = tableCreate();
-
-		if(t == NULL)
-			return NULL;
-	}
-
-	len = safe_res_query(host, C_IN, T_MX, (u_char *)&q, sizeof(q));
-	if(len < 0)
-		return t;	/* Host has no MX records */
-
-	if((unsigned int)len > sizeof(q))
-		return t;
-
-	hp = &(q.h);
-	p = q.u + HFIXEDSZ;
-	end = q.u + len;
-
-	for(i = ntohs(hp->qdcount); i--; p += len + QFIXEDSZ)
-		if((len = dn_skipname(p, end)) < 0)
-			return t;
-
-	i = ntohs(hp->ancount);
-
-	while((--i >= 0) && (p < end)) {
-		in_addr_t addr;
-		u_short type, pref;
-		u_long ttl;	/* unused */
-
-		if((len = dn_expand(q.u, end, p, buf, sizeof(buf) - 1)) < 0)
-			break;
-		p += len;
-		GETSHORT(type, p);
-		p += INT16SZ;
-		GETLONG(ttl, p);
-		GETSHORT(len, p);
-		if(type != T_MX) {
-			p += len;
-			continue;
-		}
-		GETSHORT(pref, p);
-		if((len = dn_expand(q.u, end, p, buf, sizeof(buf) - 1)) < 0)
-			break;
-		p += len;
-		addr = inet_addr(buf);
-#ifdef	INADDR_NONE
-		if(addr != INADDR_NONE) {
-#else
-		if(addr != (in_addr_t)-1) {
-#endif
-			(void)tableInsert(t, buf, 0);
-		} else
-			t = resolve(buf, t);
-	}
-	return t;
-}
-
-/*
- * If the MX record points to a name, we need to resolve that name. This routine
- * does that
- */
-static table_t *
-resolve(const char *host, table_t *t)
-{
-	u_char *p, *end;
-	const HEADER *hp;
-	int len, i;
-	union {
-		HEADER h;
-		u_char u[PACKETSZ];
-	} q;
-	char buf[BUFSIZ];
-
-	if((host == NULL) || (*host == '\0'))
-		return t;
-
-	len = safe_res_query(host, C_IN, T_A, (u_char *)&q, sizeof(q));
-	if(len < 0)
-		return t;	/* Host has no A records */
-
-	if((unsigned int)len > sizeof(q))
-		return t;
-
-	hp = &(q.h);
-	p = q.u + HFIXEDSZ;
-	end = q.u + len;
-
-	for(i = ntohs(hp->qdcount); i--; p += len + QFIXEDSZ)
-		if((len = dn_skipname(p, end)) < 0)
-			return t;
-
-	i = ntohs(hp->ancount);
-
-	while((--i >= 0) && (p < end)) {
-		u_short type;
-		u_long ttl;
-		const char *ip;
-		struct in_addr addr;
-
-		if((len = dn_expand(q.u, end, p, buf, sizeof(buf) - 1)) < 0)
-			return t;
-		p += len;
-		GETSHORT(type, p);
-		p += INT16SZ;
-		GETLONG(ttl, p);	/* unused */
-		GETSHORT(len, p);
-		if(type != T_A) {
-			p += len;
-			continue;
-		}
-		memcpy(&addr, p, sizeof(struct in_addr));
-		p += 4;	/* Should check len == 4 */
-		ip = inet_ntoa(addr);
-		if(ip) {
-			if(t == NULL) {
-				t = tableCreate();
-
-				if(t == NULL)
-					return NULL;
-			}
-			(void)tableInsert(t, ip, 0);
-		}
-	}
-	return t;
-}
-
-/*
- * Validate SPF records to help to stop Phish false positives
- * http://www.openspf.org/SPF_Record_Syntax
- *
- * Currently only handles ip4, a and mx fields in the DNS record
- * Having said that, this is NOT a replacement for spf-milter, it is NOT
- *	an SPF system, we ONLY use SPF records to reduce phish false positives
- * TODO: IPv6?
- * TODO: cache queries?
- *
- * INPUT: prevhosts, a list of hosts already searched: stops include loops
- *	e.g. mercado.com includes medrcadosw.com which includes mercado.com,
- *	causing a loop
- * Return 1 if SPF says this email is from a legitimate source
- *	0 for fail or unknown
- */
-static int
-spf(struct privdata *privdata, table_t *prevhosts)
-{
-	char *host, *ptr;
-	u_char *p, *end;
-	const HEADER *hp;
-	int len, i;
-	union {
-		HEADER h;
-		u_char u[PACKETSZ];
-	} q;
-	char buf[BUFSIZ];
-
-	if(privdata->spf_ok)
-		return 1;
-	if(privdata->ip[0] == '\0')
-		return 0;
-	if(strcmp(privdata->ip, "127.0.0.1") == 0) {
-		/* Loopback always pass SPF */
-		privdata->spf_ok = 1;
-		return 1;
-	}
-	if(isLocal(privdata->ip)) {
-		/* Local addresses always pass SPF */
-		privdata->spf_ok = 1;
-		return 1;
-	}
-
-	if(privdata->from == NULL)
-		return 0;
-	if((host = strrchr(privdata->from, '@')) == NULL)
-		return 0;
-
-	host = cli_strdup(++host);
-
-	if(host == NULL)
-		return 0;
-
-	ptr = strchr(host, '>');
-
-	if(ptr)
-		*ptr = '\0';
-
-	logg("*SPF query '%s'\n", host);
-	len = safe_res_query(host, C_IN, T_TXT, (u_char *)&q, sizeof(q));
-	if(len < 0) {
-		free(host);
-		return 0;	/* Host has no TXT records */
-	}
-
-	if((unsigned int)len > sizeof(q)) {
-		free(host);
-		return 0;
-	}
-
-	hp = &(q.h);
-	p = q.u + HFIXEDSZ;
-	end = q.u + len;
-
-	for(i = ntohs(hp->qdcount); i--; p += len + QFIXEDSZ)
-		if((len = dn_skipname(p, end)) < 0) {
-			free(host);
-			return 0;
-		}
-
-	i = ntohs(hp->ancount);
-
-	while((--i >= 0) && (p < end) && !privdata->spf_ok) {
-		u_short type;
-		u_long ttl;
-		char txt[BUFSIZ];
-
-		if((len = dn_expand(q.u, end, p, buf, sizeof(buf) - 1)) < 0) {
-			free(host);
-			return 0;
-		}
-		p += len;
-		GETSHORT(type, p);
-		p += INT16SZ;
-		GETLONG(ttl, p);	/* unused */
-		GETSHORT(len, p);
-		if(type != T_TXT) {
-			p += len;
-			continue;
-		}
-		strncpy(txt, (const char *)&p[1], sizeof(txt) - 1);
-		txt[sizeof(txt)-1]='\0';
-		txt[len - 1] = '\0';
-		if((strncmp(txt, "v=spf1 ", 7) == 0) || (strncmp(txt, "spf2.0/pra ", 11) == 0)) {
-			int j;
-			char *record;
-			struct in_addr remote_ip;	/* IP connecting to us */
-
-			logg("*%s(%s): SPF record %s\n",
-				host, privdata->ip, txt);
-#ifdef HAVE_INET_NTOP
-			/* IPv4 address ? */
-			if(inet_pton(AF_INET, privdata->ip, &remote_ip) <= 0) {
-				p += len;
-				continue;
-			}
-#else
-			if(inet_aton(privdata->ip, &remote_ip) == 0) {
-				p += len;
-				continue;
-			}
-#endif
-
-			j = 1;	/* strtok 0 would give the v= part */
-			while((record = cli_strtok(txt, j++, " ")) != NULL) {
-				if(strncmp(record, "ip4:", 4) == 0) {
-					int preflen;
-					char *ip, *pref;
-					uint32_t mask;
-					struct in_addr spf_range;	/* acceptable range of IPs */
-
-					ip = &record[4];
-
-					pref = strchr(ip, '/');
-					preflen = 32;
-					if(pref) {
-						*pref++ = '\0';
-						if(*pref)
-							preflen = atoi(pref);
-					}
-
-#ifdef HAVE_INET_NTOP
-					/* IPv4 address ? */
-					if(inet_pton(AF_INET, ip, &spf_range) <= 0) {
-						free(record);
-						continue;
-					}
-#else
-					if(inet_aton(ip, &spf_range) == 0) {
-						free(record);
-						continue;
-					}
-#endif
-					mask = MAKEMASK(preflen);
-					if((ntohl(remote_ip.s_addr) & mask) == (ntohl(spf_range.s_addr) & mask)) {
-						if(privdata->subject)
-							logg("#SPF ip4 pass (%s) %s is valid for %s\n",
-								privdata->subject, ip, host);
-						else
-							logg("#SPF ip4 pass %s is valid for %s\n", ip, host);
-						privdata->spf_ok = 1;
-					}
-				} else if(strcmp(record, "mx") == 0) {
-					table_t *t = mx(host, NULL);
-
-					if(t) {
-						tableIterate(t, spf_ip,
-							(void *)privdata);
-						tableDestroy(t);
-					}
-				} else if(strcmp(record, "a") == 0) {
-					table_t *t = resolve(host, NULL);
-
-					if(t) {
-						tableIterate(t, spf_ip,
-							(void *)privdata);
-						tableDestroy(t);
-					}
-				} else if(strncmp(record, "a:", 2) == 0) {
-					const char *ahost = &record[2];
-
-					if(*ahost && (strcmp(ahost, host) != 0)) {
-						table_t *t = resolve(ahost, NULL);
-
-						if(t) {
-							tableIterate(t, spf_ip,
-								(void *)privdata);
-							tableDestroy(t);
-						}
-					}
-				} else if(strncmp(record, "mx:", 3) == 0) {
-					const char *mxhost = &record[3];
-
-					if(*mxhost && (strcmp(mxhost, host) != 0)) {
-						table_t *t = mx(mxhost, NULL);
-
-						if(t) {
-							tableIterate(t, spf_ip,
-								(void *)privdata);
-							tableDestroy(t);
-						}
-					}
-				} else if(strncmp(record, "include:", 8) == 0) {
-					const char *inchost = &record[8];
-
-					/*
-					 * Ensure we haven't already looked at
-					 *	the host that's to be included
-					 */
-					if(*inchost &&
-					   (strcmp(inchost, host) != 0) &&
-					   (tableFind(prevhosts, inchost) == -1)) {
-						char *real_from = privdata->from;
-						privdata->from = cli_malloc(strlen(inchost) + 3);
-						sprintf(privdata->from, "n@%s", inchost);
-						tableInsert(prevhosts, host, 0);
-						spf(privdata, prevhosts);
-						free(privdata->from);
-						privdata->from = real_from;
-					}
-				}
-				free(record);
-				if(privdata->spf_ok)
-					break;
-			}
-		}
-		p += len;
-	}
-	free(host);
-
-	return privdata->spf_ok;
-}
-
-static void
-spf_ip(char *ip, int zero, void *v)
-{
-	struct privdata *privdata = (struct privdata *)v;
-
-	if(strcmp(ip, privdata->ip) == 0) {
-		if(privdata->subject)
-			logg("#SPF mx/a pass (%s) %s\n", privdata->subject, ip);
-		else
-			logg("#SPF mx/a pass %s\n", ip);
-		privdata->spf_ok = 1;
-	}
-}
-
-#else	/*!HAVE_RESOLV_H */
-static table_t *
-mx(const char *host, table_t *t)
-{
-	logg(_("^MX peers will not be immune from being blacklisted"));
-
-	if(blacklist == NULL)
-		blacklist = tableCreate();
-	return NULL;
-}
-#endif	/* HAVE_RESOLV_H */
-
-static sfsistat
-black_hole(const struct privdata *privdata)
-{
-	int must_scan;
-	char **to;
-
-	to = privdata->to;
-	must_scan = (*to) ? 0 : 1;
-
-	for(; *to; to++) {
-		pid_t pid, w;
-		int pv[2], status;
-		FILE *sendmail;
-		char buf[BUFSIZ];
-
-		logg("*Calling \"%s -bv %s\"\n", SENDMAIL_BIN, *to);
-
-		if(pipe(pv) < 0) {
-			perror("pipe");
-			logg(_("!Can't create pipe\n"));
-			must_scan = 1;
-			break;
-		}
-		pid = fork();
-		if(pid == 0) {
-			close(1);
-			close(pv[0]);
-			dup2(pv[1], 1);
-			close(pv[1]);
-
-			/*
-			 * Avoid calling popen() since *to isn't trusted
-			 */
-			execl(SENDMAIL_BIN, "sendmail", "-bv", *to, NULL);
-			perror(SENDMAIL_BIN);
-			logg("Can't execl %s\n", SENDMAIL_BIN);
-			_exit(errno ? errno : 1);
-		}
-		if(pid == -1) {
-			perror("fork");
-			logg(_("!Can't fork\n"));
-			close(pv[0]);
-			close(pv[1]);
-			must_scan = 1;
-			break;
-		}
-		close(pv[1]);
-		sendmail = fdopen(pv[0], "r");
-
-		if(sendmail == NULL) {
-			logg("fdopen failed\n");
-			close(pv[0]);
-			must_scan = 1;
-			break;
-		}
-
-		while(fgets(buf, sizeof(buf), sendmail) != NULL) {
-			if(cli_chomp(buf) == 0)
-				continue;
-
-			logg("*sendmail output: %s\n", buf);
-
-			if(strstr(buf, "... deliverable: mailer ")) {
-				const char *p = strstr(buf, ", user ");
-
-				if(strcmp(&p[7], "/dev/null") != 0) {
-					must_scan = 1;
-					break;
-				}
-			}
-		}
-		fclose(sendmail);
-
-		status = -1;
-		do
-			w = wait(&status);
-		while((w != pid) && (w != -1));
-
-		if(w == -1)
-			status = -1;
-		else
-			status = WEXITSTATUS(status);
-
-		switch(status) {
-			case EX_NOUSER:
-			case EX_OK:
-				break;
-			default:
-				logg(_("^Can't execute '%s' to expand '%s' (error %d)\n"),
-					SENDMAIL_BIN, *to, WEXITSTATUS(status));
-				must_scan = 1;
-		}
-		if(must_scan)
-			break;
-	}
-	if(!must_scan) {
-		/* All recipients map to /dev/null */
-		to = privdata->to;
-		if(*to)
-			logg("Discarded, since all recipients (e.g. \"%s\") are /dev/null\n", *to);
-		else
-			logg("Discarded, since all recipients are /dev/null\n");
-		return SMFIS_DISCARD;
-	}
-	return SMFIS_CONTINUE;
-}
-
-/* See also libclamav/mbox.c */
-static int
-useful_header(const char *cmd)
-{
-	if(strcasecmp(cmd, "From") == 0)
-		return 1;
-	if(strcasecmp(cmd, "Received") == 0)
-		return 1;
-	if(strcasecmp(cmd, "Content-Type") == 0)
-		return 1;
-	if(strcasecmp(cmd, "Content-Transfer-Encoding") == 0)
-		return 1;
-	if(strcasecmp(cmd, "Content-Disposition") == 0)
-		return 1;
-	if(strcasecmp(cmd, "De") == 0)
-		return 1;
-
-	return 0;
-}
-
-static int
-increment_connexions(void)
-{
-	if(max_children > 0) {
-		int rc = 0;
-
-		pthread_mutex_lock(&n_children_mutex);
-
-		/*
-		 * Wait a while since sendmail doesn't like it if we
-		 * take too long replying. Effectively this means that
-		 * max_children is more of a hint than a rule
-		 */
-		if(n_children >= max_children) {
-			struct timespec timeout;
-			struct timeval now;
-			struct timezone tz;
-
-			logg((dont_wait) ?
-					_("hit max-children limit (%u >= %u)\n") :
-					_("hit max-children limit (%u >= %u): waiting for some to exit\n"),
-				n_children, max_children);
-
-			if(dont_wait) {
-				pthread_mutex_unlock(&n_children_mutex);
-				return 0;
-			}
-			/*
-			 * Wait for an amount of time for a child to go
-			 *
-			 * Use pthread_cond_timedwait rather than
-			 * pthread_cond_wait since the sendmail which
-			 * calls us will have a timeout that we don't
-			 * want to exceed, stops sendmail getting
-			 * fidgety.
-			 *
-			 * Patch from Damian Menscher
-			 * <menscher at uiuc.edu> to ensure it wakes up
-			 * when a child goes away
-			 */
-			gettimeofday(&now, &tz);
-			do {
-				logg(_("n_children %d: waiting %d seconds for some to exit\n"),
-					n_children, child_timeout);
-
-				if(child_timeout == 0) {
-					pthread_cond_wait(&n_children_cond, &n_children_mutex);
-					rc = 0;
-				} else {
-					timeout.tv_sec = now.tv_sec + child_timeout;
-					timeout.tv_nsec = 0;
-
-					rc = pthread_cond_timedwait(&n_children_cond, &n_children_mutex, &timeout);
-				}
-			} while((n_children >= max_children) && (rc != ETIMEDOUT));
-			logg(_("Finished waiting, n_children = %d\n"), n_children);
-		}
-		n_children++;
-
-		logg("*>n_children = %d\n", n_children);
-		pthread_mutex_unlock(&n_children_mutex);
-
-		if(child_timeout && (rc == ETIMEDOUT))
-			logg(_("Timeout waiting for a child to die\n"));
-	}
-
-	return 1;
-}
-
-static void
-decrement_connexions(void)
-{
-	if(max_children > 0) {
-		pthread_mutex_lock(&n_children_mutex);
-		logg("*decrement_connexions: n_children = %d\n", n_children);
-		/*
-		 * Deliberately errs on the side of broadcasting too many times
-		 */
-		if(n_children > 0)
-			if(--n_children == 0) {
-				logg("*%s is idle\n", progname);
-				if(pthread_cond_broadcast(&watchdog_cond) < 0)
-					perror("pthread_cond_broadcast");
-			}
-#ifdef	CL_DEBUG
-		logg("*pthread_cond_broadcast\n");
-#endif
-		if(pthread_cond_broadcast(&n_children_cond) < 0)
-			perror("pthread_cond_broadcast");
-		logg("*<n_children = %d\n", n_children);
-		pthread_mutex_unlock(&n_children_mutex);
-	}
-}
-
-static void
-dump_blacklist(char *key, int value, void *v)
-{
-	logg(_("Won't blacklist %s\n"), key);
-}
-
-/*
- * Non-blocking connect, based on an idea by Everton da Silva Marques
- *	 <everton.marques at gmail.com>
- * FIXME: There are lots of copies of this code :-(
- */
-static int
-nonblock_connect(int sock, const struct sockaddr_in *sin, const char *hostname)
-{
-	int select_failures;	/* Max. of unexpected select() failures */
-	int attempts;
-	struct timeval timeout;	/* When we should time out */
-	int numfd;		/* Highest fdset fd plus 1 */
-	long flags;
-
-	gettimeofday(&timeout, 0);	/* store when we started to connect */
-
-	if(hostname == NULL)
-		hostname = "clamav-milter";	/* It's only used in debug messages */
-
-#ifdef	F_GETFL
-	flags = fcntl(sock, F_GETFL, 0);
-
-	if(flags == -1L)
-		logg("^getfl: %s\n", strerror(errno));
-	else if(fcntl(sock, F_SETFL, (long)(flags | O_NONBLOCK)) < 0)
-		logg("^setfl: %s\n", strerror(errno));
-#else
-	flags = -1L;
-#endif
-	if(connect(sock, (const struct sockaddr *)sin, sizeof(struct sockaddr_in)) != 0)
-		switch(errno) {
-			case EALREADY:
-			case EINPROGRESS:
-				logg("*%s: connect: %s\n", hostname,
-					strerror(errno));
-				break; /* wait for connection */
-			case EISCONN:
-				return 0; /* connected */
-			default:
-				logg("^%s: connect: %s\n", hostname,
-					strerror(errno));
-#ifdef	F_SETFL
-				if(flags != -1L)
-					if(fcntl(sock, F_SETFL, flags))
-						logg("^f_setfl: %s\n", strerror(errno));
-#endif
-				return -1; /* failed */
-		}
-	else {
-#ifdef	F_SETFL
-		if(flags != -1L)
-			if(fcntl(sock, F_SETFL, flags))
-				logg("^f_setfl: %s\n", strerror(errno));
-#endif
-		return connect_error(sock, hostname);
-	}
-
-	numfd = (int)sock + 1;
-	select_failures = NONBLOCK_SELECT_MAX_FAILURES;
-	attempts = 1;
-	timeout.tv_sec += CONNECT_TIMEOUT;
-
-	for (;;) {
-		int n, t;
-		fd_set fds;
-		struct timeval now, waittime;
-
-		/* Force timeout if we ran out of time */
-		gettimeofday(&now, 0);
-		t = (now.tv_sec == timeout.tv_sec) ?
-			(now.tv_usec > timeout.tv_usec) :
-			(now.tv_sec > timeout.tv_sec);
-
-		if(t) {
-			logg("^%s: connect timeout (%d secs)\n",
-				hostname, CONNECT_TIMEOUT);
-			break;
-		}
-
-		/* Calculate how long to wait */
-		waittime.tv_sec = timeout.tv_sec - now.tv_sec;
-		waittime.tv_usec = timeout.tv_usec - now.tv_usec;
-		if(waittime.tv_usec < 0) {
-			waittime.tv_sec--;
-			waittime.tv_usec += 1000000;
-		}
-
-		/* Init fds with 'sock' as the only fd */
-		FD_ZERO(&fds);
-		FD_SET(sock, &fds);
-
-		n = select(numfd, 0, &fds, 0, &waittime);
-		if(n < 0) {
-			logg("^%s: select attempt %d %s\n",
-				hostname, select_failures, strerror(errno));
-			if(--select_failures >= 0)
-				continue; /* not timed-out, try again */
-			break; /* failed */
-		}
-
-		logg("*%s: select = %d\n", hostname, n);
-
-		if(n) {
-#ifdef	F_SETFL
-			if(flags != -1L)
-				if(fcntl(sock, F_SETFL, flags))
-					logg("^f_setfl: %s\n", strerror(errno));
-#endif
-			return connect_error(sock, hostname);
-		}
-
-		/* timeout */
-		if(attempts++ == NONBLOCK_MAX_ATTEMPTS) {
-			logg("^timeout connecting to %s\n", hostname);
-			break;
-		}
-	}
-
-#ifdef	F_SETFL
-	if(flags != -1L)
-		if(fcntl(sock, F_SETFL, flags))
-			logg("^f_setfl: %s\n", strerror(errno));
-#endif
-	return -1; /* failed */
-}
-
-static int
-connect_error(int sock, const char *hostname)
-{
-#ifdef	SO_ERROR
-	int optval;
-	socklen_t optlen = sizeof(optval);
-
-	getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen);
-
-	if(optval) {
-		logg("^%s: %s\n", hostname, strerror(optval));
-		return -1;
-	}
-#endif
-	return 0;
-}
diff --git a/contrib/old-clamav-milter/clamav-milter.po b/contrib/old-clamav-milter/clamav-milter.po
deleted file mode 100644
index 4a261b2..0000000
--- a/contrib/old-clamav-milter/clamav-milter.po
+++ /dev/null
@@ -1,1122 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR njh at bandsman.co.uk
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: bugs at clamav.net\n"
-"POT-Creation-Date: 2007-10-24 09:05+0100\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: clamav-milter.c:585
-msgid "\t--advisory\t\t-A\tFlag viruses rather than deleting them."
-msgstr ""
-
-#: clamav-milter.c:586
-msgid "\t--blacklist-time=SECS\t-k\tTime (in seconds) to blacklist an IP."
-msgstr ""
-
-#: clamav-milter.c:587
-msgid "\t--black-hole-mode\t\tDon't scan messages aliased to /dev/null."
-msgstr ""
-
-#: clamav-milter.c:589
-msgid "\t--bounce\t\t-b\tSend a failure message to the sender."
-msgstr ""
-
-#: clamav-milter.c:591
-msgid ""
-"\t--broadcast\t\t-B [IFACE]\tBroadcast to a network manager when a virus is "
-"found."
-msgstr ""
-
-#: clamav-milter.c:592
-msgid "\t--chroot=DIR\t\t-C DIR\tChroot to dir when starting."
-msgstr ""
-
-#: clamav-milter.c:593
-msgid "\t--config-file=FILE\t-c FILE\tRead configuration from FILE."
-msgstr ""
-
-#: clamav-milter.c:594
-msgid "\t--debug\t\t\t-D\tPrint debug messages."
-msgstr ""
-
-#: clamav-milter.c:595
-msgid ""
-"\t--detect-forged-local-address\t-L\tReject mails that claim to be from us."
-msgstr ""
-
-#: clamav-milter.c:596
-msgid "\t--dont-blacklist\t-K\tDon't blacklist a given IP."
-msgstr ""
-
-#: clamav-milter.c:597
-msgid ""
-"\t--dont-scan-on-error\t-d\tPass e-mails through unscanned if a system error "
-"occurs."
-msgstr ""
-
-#: clamav-milter.c:598
-msgid "\t--dont-wait\t\t\tAsk remote end to resend if max-children exceeded."
-msgstr ""
-
-#: clamav-milter.c:599
-msgid "\t--external\t\t-e\tUse an external scanner (usually clamd)."
-msgstr ""
-
-#: clamav-milter.c:600
-msgid ""
-"\t--freshclam-monitor=SECS\t-M SECS\tHow often to check for database update."
-msgstr ""
-
-#: clamav-milter.c:601
-msgid "\t--from=EMAIL\t\t-a EMAIL\tError messages come from here."
-msgstr ""
-
-#: clamav-milter.c:602
-msgid "\t--force-scan\t\t-f\tForce scan all messages (overrides (-o and -l)."
-msgstr ""
-
-#: clamav-milter.c:603
-msgid "\t--help\t\t\t-h\tThis message."
-msgstr ""
-
-#: clamav-milter.c:604
-msgid "\t--headers\t\t-H\tInclude original message headers in the report."
-msgstr ""
-
-#: clamav-milter.c:605
-msgid ""
-"\t--ignore IPaddr\t\t-I IPaddr\tAdd IPaddr to LAN IP list (see --local)."
-msgstr ""
-
-#: clamav-milter.c:606
-msgid "\t--local\t\t\t-l\tScan messages sent from machines on our LAN."
-msgstr ""
-
-#: clamav-milter.c:607
-msgid "\t--max-childen\t\t-m\tMaximum number of concurrent scans."
-msgstr ""
-
-#: clamav-milter.c:608
-msgid "\t--outgoing\t\t-o\tScan outgoing messages from this machine."
-msgstr ""
-
-#: clamav-milter.c:609
-msgid "\t--noreject\t\t-N\tDon't reject viruses, silently throw them away."
-msgstr ""
-
-#: clamav-milter.c:610
-msgid "\t--noxheader\t\t-n\tSuppress X-Virus-Scanned/X-Virus-Status headers."
-msgstr ""
-
-#: clamav-milter.c:611
-msgid "\t--pidfile=FILE\t\t-i FILE\tLocation of pidfile."
-msgstr ""
-
-#: clamav-milter.c:612
-msgid "\t--postmaster\t\t-p EMAIL\tPostmaster address [default=postmaster]."
-msgstr ""
-
-#: clamav-milter.c:613
-msgid "\t--postmaster-only\t-P\tSend notifications only to the postmaster."
-msgstr ""
-
-#: clamav-milter.c:614
-msgid "\t--quiet\t\t\t-q\tDon't send e-mail notifications of interceptions."
-msgstr ""
-
-#: clamav-milter.c:615
-msgid "\t--quarantine=USER\t-Q EMAIL\tQuarantine e-mail account."
-msgstr ""
-
-#: clamav-milter.c:616
-msgid "\t--report-phish=EMAIL\t-r EMAIL\tReport phish to this email address."
-msgstr ""
-
-#: clamav-milter.c:617
-msgid ""
-"\t--report-phish-false-positives=EMAIL\t-R EMAIL\tReport phish false "
-"positves to this email address."
-msgstr ""
-
-#: clamav-milter.c:618
-msgid "\t--quarantine-dir=DIR\t-U DIR\tDirectory to store infected emails."
-msgstr ""
-
-#: clamav-milter.c:619
-msgid ""
-"\t--server=SERVER\t\t-s SERVER\tHostname/IP address of server(s) running "
-"clamd (when using TCPsocket)."
-msgstr ""
-
-#: clamav-milter.c:620
-msgid "\t--sendmail-cf=FILE\t\tLocation of the sendmail.cf file to verify"
-msgstr ""
-
-#: clamav-milter.c:621
-msgid "\t--sign\t\t\t-S\tAdd a hard-coded signature to each scanned message."
-msgstr ""
-
-#: clamav-milter.c:622
-msgid "\t--signature-file=FILE\t-F FILE\tLocation of signature file."
-msgstr ""
-
-#: clamav-milter.c:623
-msgid "\t--template-file=FILE\t-t FILE\tLocation of e-mail template file."
-msgstr ""
-
-#: clamav-milter.c:624
-msgid ""
-"\t--template-headers=FILE\t\tLocation of e-mail headers for template file."
-msgstr ""
-
-#: clamav-milter.c:625
-msgid "\t--timeout=SECS\t\t-T SECS\tTimeout waiting to childen to die."
-msgstr ""
-
-#: clamav-milter.c:626
-msgid ""
-"\t--whitelist-file=FILE\t-W FILE\tLocation of the file of whitelisted "
-"addresses"
-msgstr ""
-
-#: clamav-milter.c:627
-msgid "\t--version\t\t-V\tPrint the version number of this software."
-msgstr ""
-
-#: clamav-milter.c:629
-msgid "\t--debug-level=n\t\t-x n\tSets the debug level to 'n'."
-msgstr ""
-
-#: clamav-milter.c:631
-msgid ""
-"\n"
-"For more information type \"man clamav-milter\"."
-msgstr ""
-
-#: clamav-milter.c:632
-msgid "For bug reports, please refer to http://www.clamav.net/bugs"
-msgstr ""
-
-#: clamav-milter.c:931
-#, c-format
-msgid "%s: %s, -I may only be given %d times\n"
-msgstr ""
-
-#: clamav-milter.c:937
-#, c-format
-msgid "%s: Cannot convert -I%s to IPaddr\n"
-msgstr ""
-
-#: clamav-milter.c:1051
-#, c-format
-msgid "%s: SESSIONS mode requires --external\n"
-msgstr ""
-
-#: clamav-milter.c:1059
-#, c-format
-msgid "%s: No socket-addr given\n"
-msgstr ""
-
-#: clamav-milter.c:1066
-#, c-format
-msgid "%s: socket-addr (%s) doesn't agree with sendmail.cf\n"
-msgstr ""
-
-#: clamav-milter.c:1082
-#, c-format
-msgid "%s: when using inet: connexion to sendmail you must enable --local\n"
-msgstr ""
-
-#: clamav-milter.c:1094
-#, c-format
-msgid "%s: Can't parse the config file %s\n"
-msgstr ""
-
-#: clamav-milter.c:1101
-#, c-format
-msgid "%s: --detect-forged-local-addresses is not compatible with --outgoing\n"
-msgstr ""
-
-#: clamav-milter.c:1105
-#, c-format
-msgid "%s: --detect-forged-local-addresses is not compatible with --local\n"
-msgstr ""
-
-#: clamav-milter.c:1109
-#, c-format
-msgid "%s: --detect-forged-local-addresses is not compatible with --force\n"
-msgstr ""
-
-#: clamav-milter.c:1153
-#, c-format
-msgid ""
-"%s: The iface option to --broadcast is not supported on your operating "
-"system\n"
-msgstr ""
-
-#: clamav-milter.c:1162
-#, c-format
-msgid "%s: Can't get information about user %s\n"
-msgstr ""
-
-#: clamav-milter.c:1173
-#, c-format
-msgid "%s: AllowSupplementaryGroups: initgroups not supported.\n"
-msgstr ""
-
-#: clamav-milter.c:1191
-#, c-format
-msgid "Running as user %s (UID %d, GID %d)\n"
-msgstr ""
-
-#: clamav-milter.c:1247
-#, c-format
-msgid "%s: You cannot use black hole mode unless %s is a TrustedUser\n"
-msgstr ""
-
-#: clamav-milter.c:1253
-#, c-format
-msgid "^%s: running as root is not recommended (check \"User\" in %s)\n"
-msgstr ""
-
-#: clamav-milter.c:1255
-#, c-format
-msgid "%s: Only root can set an interface for --broadcast\n"
-msgstr ""
-
-#: clamav-milter.c:1260
-#, c-format
-msgid "%s: Advisory mode doesn't work with quarantine mode\n"
-msgstr ""
-
-#: clamav-milter.c:1268
-#, c-format
-msgid "%s: Advisory mode doesn't work with quarantine directories\n"
-msgstr ""
-
-#: clamav-milter.c:1274
-#, c-format
-msgid "%s: the quarantine directory must not contain the string 'ERROR'\n"
-msgstr ""
-
-#: clamav-milter.c:1280
-#, c-format
-msgid "%s: the quarantine directory must not contain the string 'FOUND'\n"
-msgstr ""
-
-#: clamav-milter.c:1286
-#, c-format
-msgid "%s: the quarantine directory must not contain the string 'OK'\n"
-msgstr ""
-
-#: clamav-milter.c:1303
-#, c-format
-msgid "%s: insecure quarantine directory %s (mode 0%o)\n"
-msgstr ""
-
-#: clamav-milter.c:1344
-#, c-format
-msgid "%s: ReadTimeout must not be negative in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1353
-#, c-format
-msgid "%s: StreamMaxLength must not be negative in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1386
-#, c-format
-msgid ""
-"%s: (-q && !LogSyslog): warning - all interception message methods are off\n"
-msgstr ""
-
-#: clamav-milter.c:1402
-#, c-format
-msgid "%s: --max-children must be given if --external is not given\n"
-msgstr ""
-
-#: clamav-milter.c:1406
-#, c-format
-msgid "%s: --freshclam_monitor must be at least one second\n"
-msgstr ""
-
-#: clamav-milter.c:1420
-#, c-format
-msgid "%s: --timeout must not be given if --external is not given\n"
-msgstr ""
-
-#: clamav-milter.c:1433
-#, c-format
-msgid "%s: No emails will be scanned"
-msgstr ""
-
-#: clamav-milter.c:1444
-#, c-format
-msgid "%s: You can select one server type only (local/TCP) in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1449
-#, c-format
-msgid "%s: You cannot use the --server option when using LocalSocket in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1459
-#, c-format
-msgid "The connexion from sendmail to %s (%s) must not\n"
-msgstr ""
-
-#: clamav-milter.c:1461
-#, c-format
-msgid "be the same as the connexion to clamd (%s) in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1471 clamav-milter.c:1498
-#, c-format
-msgid "Can't talk to clamd server via %s\n"
-msgstr ""
-
-#: clamav-milter.c:1473 clamav-milter.c:1500
-#, c-format
-msgid "Check your entry for LocalSocket in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1510
-msgid "!Can't create a clamd session"
-msgstr ""
-
-#: clamav-milter.c:1527
-#, c-format
-msgid "%s: --quarantine-dir not supported for TCPSocket - use --quarantine\n"
-msgstr ""
-
-#: clamav-milter.c:1542
-#, c-format
-msgid "%s: hostname %s is longer than %d characters\n"
-msgstr ""
-
-#: clamav-milter.c:1561 clamav-milter.c:1694
-#, c-format
-msgid "%s: --max-children must be given in sessions mode\n"
-msgstr ""
-
-#: clamav-milter.c:1567
-#, c-format
-msgid ""
-"%1$s: --max-children (%2$d) is lower than the number of servers you have (%3"
-"$d)\n"
-msgstr ""
-
-#: clamav-milter.c:1594
-#, c-format
-msgid "%s: Unknown host %s\n"
-msgstr ""
-
-#: clamav-milter.c:1624
-msgid "Waiting for clamd to come up\n"
-msgstr ""
-
-#: clamav-milter.c:1638
-#, c-format
-msgid "Can't talk to clamd server %s on port %d\n"
-msgstr ""
-
-#: clamav-milter.c:1642
-#, c-format
-msgid "Check the value for TCPAddr in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1644
-#, c-format
-msgid "Check the value for TCPAddr in clamd.conf on %s\n"
-msgstr ""
-
-#: clamav-milter.c:1660 clamav-milter.c:1668 clamav-milter.c:4773
-msgid "!Can't find any clamd server\n"
-msgstr ""
-
-#: clamav-milter.c:1661 clamav-milter.c:1666
-#, c-format
-msgid "Check your entry for TCPSocket in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1674
-#, c-format
-msgid "%s: You must select server type (local/TCP) in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1777
-#, c-format
-msgid "When debugging it is recommended that you use Foreground mode in %s\n"
-msgstr ""
-
-#: clamav-milter.c:1778
-msgid "\tso that you can see all of the messages"
-msgstr ""
-
-#: clamav-milter.c:1886
-#, c-format
-msgid "%s: ScanMail not defined in %s (needed without --external), enabling\n"
-msgstr ""
-
-#: clamav-milter.c:1946
-msgid "Starting clamav-milter"
-msgstr ""
-
-#: clamav-milter.c:1974
-#, c-format
-msgid "!pidfile: '%s' must be a full pathname"
-msgstr ""
-
-#: clamav-milter.c:1990
-#, c-format
-msgid "!Can't save PID in file %s\n"
-msgstr ""
-
-#: clamav-milter.c:2058
-#, c-format
-msgid "Starting %s\n"
-msgstr ""
-
-#: clamav-milter.c:2059
-msgid "*Debugging is on\n"
-msgstr ""
-
-#: clamav-milter.c:2159
-#, c-format
-msgid "Check clamd server %s - it may be down\n"
-msgstr ""
-
-#: clamav-milter.c:2164
-msgid "Check clamd server - it may be down"
-msgstr ""
-
-#: clamav-milter.c:2374
-msgid "No free clamd sessions\n"
-msgstr ""
-
-#: clamav-milter.c:2495
-msgid "^Couldn't establish a connexion to any clamd server\n"
-msgstr ""
-
-#: clamav-milter.c:2519
-#, c-format
-msgid "^findServer: select failed (maxsock = %d)\n"
-msgstr ""
-
-#: clamav-milter.c:2533
-msgid "^findServer: No response from any server\n"
-msgstr ""
-
-#: clamav-milter.c:2602
-#, c-format
-msgid "^Check clamd server %s - it may be down\n"
-msgstr ""
-
-#: clamav-milter.c:2606
-msgid "Check clamd server - it may be down\n"
-msgstr ""
-
-#: clamav-milter.c:2630
-msgid "!clamfi_connect: ctx is null"
-msgstr ""
-
-#: clamav-milter.c:2634
-msgid "!clamfi_connect: hostname is null"
-msgstr ""
-
-#: clamav-milter.c:2670
-#, c-format
-msgid "clamfi_connect: Unexpected sa_family %d\n"
-msgstr ""
-
-#: clamav-milter.c:2680
-msgid "clamfi_connect: remoteIP is null"
-msgstr ""
-
-#: clamav-milter.c:2688
-#, c-format
-msgid "clamfi_connect: connexion from %s"
-msgstr ""
-
-#: clamav-milter.c:2690
-#, c-format
-msgid "clamfi_connect: connexion from %s [%s]"
-msgstr ""
-
-#: clamav-milter.c:2709
-msgid "Can't get sendmail hostname"
-msgstr ""
-
-#: clamav-milter.c:2717
-#, c-format
-msgid "^Access Denied: Host Unknown (%s)"
-msgstr ""
-
-#: clamav-milter.c:2726
-#, c-format
-msgid "Can't find entry for IP address %s in DNS - check your DNS setting\n"
-msgstr ""
-
-#: clamav-milter.c:2736
-#, c-format
-msgid "^Access Denied: Can't get IP address for (%s)"
-msgstr ""
-
-#: clamav-milter.c:2752
-#, c-format
-msgid "^Access Denied for %s[%s]"
-msgstr ""
-
-#: clamav-milter.c:2768
-msgid "*clamfi_connect: not scanning outgoing messages"
-msgstr ""
-
-#: clamav-milter.c:2774
-msgid "*clamfi_connect: not scanning local messages\n"
-msgstr ""
-
-#: clamav-milter.c:2787
-msgid "^clamfi_connect: gethostname failed"
-msgstr ""
-
-#: clamav-milter.c:2792
-msgid "Rejected connexion falsely claiming to be from here\n"
-msgstr ""
-
-#: clamav-milter.c:2793
-msgid "You have claimed to be me, but you are not"
-msgstr ""
-
-#: clamav-milter.c:2794 clamav-milter.c:3141
-msgid "Forged local address detected"
-msgstr ""
-
-#: clamav-milter.c:2810
-#, c-format
-msgid "%s is blacklisted because your machine is infected with a virus"
-msgstr ""
-
-#: clamav-milter.c:2812 clamav-milter.c:2924
-msgid "Blacklisted IP detected"
-msgstr ""
-
-#: clamav-milter.c:2868
-msgid "*clamfi_envfrom: ignoring whitelisted message"
-msgstr ""
-
-#: clamav-milter.c:2882
-msgid "Rejected email with empty from field"
-msgstr ""
-
-#: clamav-milter.c:2883
-msgid "You have not said who the email is from"
-msgstr ""
-
-#: clamav-milter.c:2884
-msgid "Reject email with empty from field"
-msgstr ""
-
-#: clamav-milter.c:2902
-msgid "AV system temporarily overloaded - please try later"
-msgstr ""
-
-#: clamav-milter.c:2994
-msgid "Suspicious recipient address blocked"
-msgstr ""
-
-#: clamav-milter.c:2998
-#, c-format
-msgid "Will blacklist %s for %d seconds because of cracking attempt\n"
-msgstr ""
-
-#: clamav-milter.c:3108
-msgid "*clamfi_eoh\n"
-msgstr ""
-
-#: clamav-milter.c:3133
-msgid "clamfi_eoh: gethostname failed"
-msgstr ""
-
-#: clamav-milter.c:3139
-#, c-format
-msgid "Rejected email falsely claiming to be from %s"
-msgstr ""
-
-#: clamav-milter.c:3140
-msgid "You have claimed to be from me, but you are not"
-msgstr ""
-
-#: clamav-milter.c:3187
-msgid "*clamfi_enveoh: ignoring whitelisted message"
-msgstr ""
-
-#: clamav-milter.c:3199
-#, c-format
-msgid "*clamfi_envbody: %lu bytes"
-msgstr ""
-
-#: clamav-milter.c:3256
-#, c-format
-msgid "%s: Message more than StreamMaxLength (%ld) bytes - not scanned\n"
-msgstr ""
-
-#: clamav-milter.c:3259 clamav-milter.c:3585
-msgid "Not Scanned - StreamMaxLength exceeded"
-msgstr ""
-
-#: clamav-milter.c:3322
-#, c-format
-msgid "^Failed to delete X-Virus-Status header %d\n"
-msgstr ""
-
-#: clamav-milter.c:3377
-#, c-format
-msgid "failed to send SCAN %s command to clamd\n"
-msgstr ""
-
-#: clamav-milter.c:3398
-msgid "failed to send SCAN command to clamd\n"
-msgstr ""
-
-#: clamav-milter.c:3415
-#, c-format
-msgid "Waiting to read status from fd %d\n"
-msgstr ""
-
-#: clamav-milter.c:3427
-#, c-format
-msgid "*clamfi_eom: read %s\n"
-msgstr ""
-
-#: clamav-milter.c:3445
-#, c-format
-msgid "clamfi_eom: read nothing from clamd on %s\n"
-msgstr ""
-
-#: clamav-milter.c:3490 clamav-milter.c:3537
-msgid "Error determining host"
-msgstr ""
-
-#: clamav-milter.c:3551
-#, c-format
-msgid "%s: Ignoring %s false positive from %s received from %s\n"
-msgstr ""
-
-#: clamav-milter.c:3567
-#, c-format
-msgid "#Reported phishing false positive to %s"
-msgstr ""
-
-#: clamav-milter.c:3569
-#, c-format
-msgid "^Couldn't report false positive to %s\n"
-msgstr ""
-
-#: clamav-milter.c:3571
-msgid "^Can't set phish FP header\n"
-msgstr ""
-
-#: clamav-milter.c:3582
-#, c-format
-msgid "%s: Message more than StreamMaxLength (%ld) bytes - not scanned"
-msgstr ""
-
-#: clamav-milter.c:3590
-msgid "Not Scanned"
-msgstr ""
-
-#: clamav-milter.c:3618
-msgid "Infected with"
-msgstr ""
-
-#: clamav-milter.c:3640
-#, c-format
-msgid "Intercepted virus from %s to"
-msgstr ""
-
-#: clamav-milter.c:3732
-msgid "Subject: Virus intercepted\n"
-msgstr ""
-
-#: clamav-milter.c:3747
-#, c-format
-msgid "!Can't open e-mail template header file %s"
-msgstr ""
-
-#: clamav-milter.c:3762 clamav-milter.c:3766
-msgid "\n"
-msgstr ""
-
-#: clamav-milter.c:3775
-msgid "A message you sent to\n"
-msgstr ""
-
-#: clamav-milter.c:3785
-#, c-format
-msgid "The message %1$s sent from %2$s to\n"
-msgstr ""
-
-#: clamav-milter.c:3788
-#, c-format
-msgid "A message sent from %s to\n"
-msgstr ""
-
-#: clamav-milter.c:3793
-#, c-format
-msgid "contained %s and has not been accepted for delivery.\n"
-msgstr ""
-
-#: clamav-milter.c:3796
-#, c-format
-msgid ""
-"\n"
-"The message in question has been quarantined as %s\n"
-msgstr ""
-
-#: clamav-milter.c:3799
-#, c-format
-msgid ""
-"\n"
-"The message was received by %1$s from %2$s via %3$s\n"
-"\n"
-msgstr ""
-
-#: clamav-milter.c:3802
-msgid ""
-"For your information, the original message headers were:\n"
-"\n"
-msgstr ""
-
-#: clamav-milter.c:3815
-#, c-format
-msgid ""
-"\n"
-"The infected machine is likely to be here:\n"
-"%s\t\n"
-msgstr ""
-
-#: clamav-milter.c:3822
-#, c-format
-msgid "%s: Failed to notify clamAV interception - see dead.letter\n"
-msgstr ""
-
-#: clamav-milter.c:3824
-#, c-format
-msgid "^Can't execute '%s' to send virus notice"
-msgstr ""
-
-#: clamav-milter.c:3846
-#, c-format
-msgid "#Reported phishing to %s"
-msgstr ""
-
-#: clamav-milter.c:3848
-#, c-format
-msgid "^Couldn't report to %s\n"
-msgstr ""
-
-#: clamav-milter.c:3854
-msgid "^Can't set anti-phish header\n"
-msgstr ""
-
-#: clamav-milter.c:3872
-#, c-format
-msgid "^Can't set quarantine user %s"
-msgstr ""
-
-#: clamav-milter.c:3906
-#, c-format
-msgid "virus %s detected by ClamAV - http://www.clamav.net"
-msgstr ""
-
-#: clamav-milter.c:3911
-#, c-format
-msgid "Will blacklist %s for %d seconds because of %s\n"
-msgstr ""
-
-#: clamav-milter.c:3920
-msgid "Unknown"
-msgstr ""
-
-#: clamav-milter.c:3921
-#, c-format
-msgid "!%s: incorrect message \"%s\" from clamd"
-msgstr ""
-
-#: clamav-milter.c:3926
-msgid "Clean"
-msgstr ""
-
-#: clamav-milter.c:3930
-#, c-format
-msgid "%s: clean message from %s\n"
-msgstr ""
-
-#: clamav-milter.c:3932
-msgid "an unknown sender"
-msgstr ""
-
-#: clamav-milter.c:4020
-#, c-format
-msgid "!Can't remove clean file %s"
-msgstr ""
-
-#: clamav-milter.c:4193 clamav-milter.c:4197
-#, c-format
-msgid "!write failure (%lu bytes) to %s: %s\n"
-msgstr ""
-
-#: clamav-milter.c:4209 clamav-milter.c:4213
-#, c-format
-msgid "!write failure (%lu bytes) to clamd: %s\n"
-msgstr ""
-
-#: clamav-milter.c:4290
-#, c-format
-msgid "!No data received from clamd in %d seconds\n"
-msgstr ""
-
-#: clamav-milter.c:4318
-#, c-format
-msgid "Can't stat %s"
-msgstr ""
-
-#: clamav-milter.c:4328
-#, c-format
-msgid "Can't open %s"
-msgstr ""
-
-#: clamav-milter.c:4447
-#, c-format
-msgid "mkdir %s failed"
-msgstr ""
-
-#: clamav-milter.c:4461
-#, c-format
-msgid "mktemp %s failed"
-msgstr ""
-
-#: clamav-milter.c:4470
-#, c-format
-msgid "Temporary quarantine file %s creation failed"
-msgstr ""
-
-#: clamav-milter.c:4581
-#, c-format
-msgid "!failed to send STREAM command clamd server %d"
-msgstr ""
-
-#: clamav-milter.c:4589
-msgid "!failed to send STREAM command clamd"
-msgstr ""
-
-#: clamav-milter.c:4600
-msgid "!failed to create TCPSocket to talk to clamd"
-msgstr ""
-
-#: clamav-milter.c:4611 clamav-milter.c:4624
-msgid "!recv failed from clamd getting PORT"
-msgstr ""
-
-#: clamav-milter.c:4613 clamav-milter.c:4626
-msgid "!EOF from clamd getting PORT"
-msgstr ""
-
-#: clamav-milter.c:4637
-#, c-format
-msgid "!Expected port information from clamd, got '%s'"
-msgstr ""
-
-#: clamav-milter.c:4657 clamav-milter.c:4660
-#, c-format
-msgid "Connecting to local port %d - data %d cmd %d\n"
-msgstr ""
-
-#: clamav-milter.c:4673 clamav-milter.c:4676
-#, c-format
-msgid "!Failed to connect to port %d given by clamd: %s"
-msgstr ""
-
-#: clamav-milter.c:4785
-#, c-format
-msgid "!Can't open %s\n"
-msgstr ""
-
-#: clamav-milter.c:4799
-#, c-format
-msgid "!Clamd (pid %d) seems to have died\n"
-msgstr ""
-
-#: clamav-milter.c:4825
-#, c-format
-msgid "!Can't open e-mail template file %s"
-msgstr ""
-
-#: clamav-milter.c:4832
-#, c-format
-msgid "!Can't stat e-mail template file %s"
-msgstr ""
-
-#: clamav-milter.c:4839
-msgid "!Out of memory"
-msgstr ""
-
-#: clamav-milter.c:4844
-#, c-format
-msgid "!Error reading e-mail template file %s"
-msgstr ""
-
-#: clamav-milter.c:4872
-#, c-format
-msgid "!%s: Unknown clamAV variable \"%c\"\n"
-msgstr ""
-
-#: clamav-milter.c:4882
-#, c-format
-msgid "!%s: Unterminated sendmail variable \"%s\"\n"
-msgstr ""
-
-#: clamav-milter.c:4891
-#, c-format
-msgid "!%s: Unknown sendmail variable \"%s\"\n"
-msgstr ""
-
-#: clamav-milter.c:4957
-#, c-format
-msgid "!mkdir %s failed\n"
-msgstr ""
-
-#: clamav-milter.c:4982
-#, c-format
-msgid "^Can't rename %1$s to %2$s\n"
-msgstr ""
-
-#: clamav-milter.c:4990
-#, c-format
-msgid "Email quarantined as %s\n"
-msgstr ""
-
-#: clamav-milter.c:5098
-#, c-format
-msgid "[Virus] %s"
-msgstr ""
-
-#: clamav-milter.c:5307
-msgid ""
-"!No response from any clamd server - your AV system is not scanning emails\n"
-msgstr ""
-
-#: clamav-milter.c:5325
-msgid "Subject: ClamAV Down\n"
-msgstr ""
-
-#: clamav-milter.c:5328
-msgid ""
-"This is an automatic message\n"
-"\n"
-msgstr ""
-
-#: clamav-milter.c:5331
-msgid "The clamd program cannot be contacted.\n"
-msgstr ""
-
-#: clamav-milter.c:5333
-msgid "No clamd server can be contacted.\n"
-msgstr ""
-
-#: clamav-milter.c:5335
-msgid "Emails may not be being scanned, please check your servers.\n"
-msgstr ""
-
-#: clamav-milter.c:5396 clamav-milter.c:5542
-msgid "!No emails will be scanned"
-msgstr ""
-
-#: clamav-milter.c:5606
-#, c-format
-msgid "Stopping %s\n"
-msgstr ""
-
-#: clamav-milter.c:5654
-msgid "Stopping clamav-milter"
-msgstr ""
-
-#: clamav-milter.c:5802
-#, c-format
-msgid "Loaded %s\n"
-msgstr ""
-
-#: clamav-milter.c:5806
-#, c-format
-msgid "ClamAV: Protecting against %u viruses\n"
-msgstr ""
-
-#: clamav-milter.c:5954
-#, c-format
-msgid "!Can't open whitelist file %s"
-msgstr ""
-
-#: clamav-milter.c:5961
-msgid "!Can't create whitelist table"
-msgstr ""
-
-#: clamav-milter.c:6049
-msgid "!Can't create blacklist table"
-msgstr ""
-
-#: clamav-milter.c:6472
-msgid "^MX peers will not be immune from being blacklisted"
-msgstr ""
-
-#: clamav-milter.c:6498
-msgid "!Can't create pipe\n"
-msgstr ""
-
-#: clamav-milter.c:6519
-msgid "!Can't fork\n"
-msgstr ""
-
-#: clamav-milter.c:6567
-#, c-format
-msgid "^Can't execute '%s' to expand '%s' (error %d)\n"
-msgstr ""
-
-#: clamav-milter.c:6625
-#, c-format
-msgid "hit max-children limit (%u >= %u)\n"
-msgstr ""
-
-#: clamav-milter.c:6626
-#, c-format
-msgid "hit max-children limit (%u >= %u): waiting for some to exit\n"
-msgstr ""
-
-#: clamav-milter.c:6648
-#, c-format
-msgid "n_children %d: waiting %d seconds for some to exit\n"
-msgstr ""
-
-#: clamav-milter.c:6661
-#, c-format
-msgid "Finished waiting, n_children = %d\n"
-msgstr ""
-
-#: clamav-milter.c:6669
-msgid "*Timeout waiting for a child to die\n"
-msgstr ""
-
-#: clamav-milter.c:6703
-#, c-format
-msgid "Won't blacklist %s\n"
-msgstr ""
diff --git a/database/daily.cvd b/database/daily.cvd
index 796637f..6918208 100644
Binary files a/database/daily.cvd and b/database/daily.cvd differ
diff --git a/database/main.cvd b/database/main.cvd
index c9500d0..b751b87 100644
Binary files a/database/main.cvd and b/database/main.cvd differ
diff --git a/docs/html/node56.html b/docs/html/node56.html
index c5ddefa..030eb7b 100644
--- a/docs/html/node56.html
+++ b/docs/html/node56.html
@@ -460,7 +460,6 @@ Donors</A>
 <ADDRESS>
 Tomasz Kojm
 2009-02-25
-
 </ADDRESS>
 </BODY>
 </HTML>

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list