#!/bin/sh
#
# $Id: configure,v 1.29 2005/03/02 15:04:09 asv Exp $
#
#########################################################

AWK=awk
SED=sed
GREP=grep
DEBUG="no"

___T_FILTER_PATH___="-- ERROR ---"
___T_FILTER_PARAMS___="-- ERROR ---"
___T_FILTER_UNIX___="-- ERROR ---"
___T_FILTER_SOCKET___="-- ERROR ---"
___T_MILTER_ACTION___="-- ERROR ---"
___T_MILTER_ADDRESS___="-- ERROR ---"
___T_MILTER_LOGLEVEL___="-- ERROR ---"
___T_MILTER_TIMEOUT_1___="-- ERROR ---"
___T_MILTER_TIMEOUT_2___="-- ERROR ---"
___T_COMMENT_LOG___="-- ERROR --"
___T_COMMENT_LCF___="-- ERROR --"
___T_COMMENT_FFR___="-- ERROR --"

OS="-- ERROR ---"
DAEMON_DIR="-- ERROR ---"
DAEMON_INI="-- ERROR ---"
DAEMON_MODE="-- ERROR ---"
DAEMON_PID="-- ERROR ---"
DAEMON_IP="-- ERROR ---"
DAEMON_PORT="-- ERROR ---"
DAEMON_SOCKET="-- ERROR ---"
FILTER_CFG="-- ERROR ---"
FILTER_CFG_NOSTD="-- ERROR ---"
FILTER_TIMEOUT="-- ERROR ---"

# Test bash version

if [ "x$BASH_VERSION" = "x" ] ; then
    echo "You should use bash (version 2.04 at least) as shell to use this script"
    exit
fi
echo "You current shell - bash $BASH_VERSION"

if [ ${BASH_VERSINFO[0]} -eq 2 -a ${BASH_VERSINFO[1]//[a-zA-Z]} -lt 4 ] ; then
    echo "You should use version 2.04 at least to use this script"
    exit
fi
if [ ${BASH_VERSINFO[0]} -lt 2 ]; then
    echo "You should use version 2.04 at least to use this script"
    exit
fi

# Test echo properties

(echo "12345\c" ; echo " ") > echotmp
if $GREP c echotmp > /dev/null 2>&1 ; then
	n='-n'
	c=''
else
	n=''
	c='\c'
fi
rm -f echotmp

echo
echo "PLEASE READ:" 
echo "Use this script AFTER complete configuration of daemon (editing daemon"
echo "ini-file, usually drweb32.ini), drweb filter for sendmail (editing filter"
echo "configuration file, usually drweb_smf.conf) and BEFORE changing"
echo "(or generating from .mc) sendmail configuration file."
echo "NOTE: Scripts work only if daemon and filter installed locally."
echo
echo "Are you ready ?"
echo $n " [default=y]:$c"
read INPUT
if [ "x$INPUT" != "x" -a "x$INPUT" != "xy" -a "x$INPUT" != "xY" ]; then
    echo "Try later. Bye!"
    exit 1
fi    

case "`(uname -sr)2>/dev/null`" in
	"Linux"*)
		OS="Linux"
		;;
	"FreeBSD"*)
		OS="FreeBSD"
        ;;
	"SunOS 5.8"*)
		OS="Solaris"
        ;;
	*)
        echo "Unsupported platfrom."
        exit 1
		;;
esac

# Set paths to daemon 

DAEMON_DIR="/opt/drweb"
if [ ! -f "$DAEMON_DIR/drwebd" ] ; then
    echo
    echo	"Enter path to directory where drwebd was installed"
    while [ ! -f "$DAEMON_DIR/drwebd" ] ; do
        echo $n ">$c"
        read DAEMON_DIR    
    done
fi    

# Try read daemon parameters from ini-file

DAEMON_INI="/etc/drweb/drweb32.ini"
if [ ! -f $DAEMON_INI ] ; then
    echo
    echo	"Enter path to drwebd ini-file (drweb32.ini)"
    while [ ! -f $DAEMON_INI ] ; do
        echo $n ">$c"
        read DAEMON_INI
        if [ "x$DAEMON_INI" = "x" ] ; then
            DAEMON_INI="___not_a_filename___"
        fi
    done    
fi  
  
echo
echo "Dr.Web daemon ... $DAEMON_DIR/drwebd"
echo "Dr.Web daemon ini-file ... $DAEMON_INI"

# Check ini format
POS=`$GREP -i "\[$OS:Daemon\]" $DAEMON_INI | $GREP -v ";"`
if [ "x$POS" = "x" ] ; then
    VER=2
else
    VER=1
fi
echo
echo "Daemon ini-file format version = $VER"

# Read transport

POS=`$GREP -i PidFile $DAEMON_INI | $GREP -v ";"`
if [ "x$POS" = "x" ] ; then
    echo
    echo -n "Daemon pidfile not defined in ini-file ..."
    if [ $VER -eq 1 ] ; then
        POS=`$GREP -i SocketMode $DAEMON_INI | $GREP -v ";" | $AWK '{ print match( $0, /[Tt][Cc][Pp]/ ) }'`
        if [ $POS -eq 0 ] ; then
            echo " but defined UNIX sockets"
            DAEMON_MODE="local"
            DAEMON_SOCKET=`$GREP -i SocketFile $DAEMON_INI | $GREP -v ";" | $AWK '{ str = substr( $0, match( $0, /\/./ ) ); gsub( /["[:blank:]]/, "", str ); print str; }'`
            DAEMON_IP=""
            DAEMON_PORT=""
            DAEMON_PID=""
       else
            echo " but defined TCP sockets"
            DAEMON_MODE="inet"
            DAEMON_IP=`$GREP -i Interfaces $DAEMON_INI | $GREP -v ";" | $AWK '{ str = substr( $0, 1+match( $0, /=./ ) ); gsub( /["[:blank:]]|(,.*)/, "", str ); print str; }'`
            DAEMON_PORT=`$GREP -i DaemonPort $DAEMON_INI | $GREP -v ";" | $AWK '{ str = substr( $0, 1+match( $0, /=./ ) ); gsub( /["[:blank:]]/, "", str ); print str; }'`
            DAEMON_PID=""
            DAEMON_SOCKET=""
       fi
    else # ver = 2
        PORTS=()
        IPS=()
        TCP_NUM=0
        FILES=()
        UNIX_NUM=0
        echo
        ALL=`$GREP -i "Socket[[:space:]]*=" $DAEMON_INI | $GREP -v "^[[:space:]]*;"`
        for (( i=0 ; ; i=$i+1 )) ; do
            SOK=`echo $ALL | $AWK -v idx=$i '{ split( $0, lines, /[[:space:]]*Socket[[:space:]]*=/ ); print lines[idx+2]; }'`
            if [ "x$SOK" = "x" ] ; then
                break
            fi
            XSOK=`echo $SOK | $GREP "^[[:space:]\"]*\/"`    
            if [ "x$XSOK" != "x" ] ; then                 
                FILES[$UNIX_NUM]=$SOK
                UNIX_NUM=`expr $UNIX_NUM + 1` 
            else
                PORTS[$TCP_NUM]=`echo $SOK | $AWK '{ split( $0, words, / / ); print words[1] }'`
                IPS[$TCP_NUM]=`echo $SOK | $AWK '{ split( $0, words, /[[:digit:]]+ / ); print words[2] }'`
                TCP_NUM=`expr $TCP_NUM + 1`
            fi
        done
        echo " found next list of addresses:"
        echo "$TCP_NUM TCP entries"
        for (( i=0; i<$TCP_NUM; i=$i+1 )) ; do
            echo " #$i: PORT = ${PORTS[$i]}, ADDRS = ${IPS[$i]}"
        done
        echo "$UNIX_NUM UNIX entries:"
        for (( i=0; i<$UNIX_NUM; i=$i+1 )) ; do
            echo " #$i: FILE = ${FILES[$i]}"
        done
        echo 
    fi
else
    echo
    echo "Use daemon pidfile for getting him address"
    DAEMON_MODE="pid"
    DAEMON_PID=`$GREP -i PidFile $DAEMON_INI | $GREP -v ";" | $AWK '{ str = substr( $0, match( $0, /\/./ ) ); gsub( /["[:blank:]]/, "", str ); print str; }'`
    DAEMON_IP=""
    DAEMON_PORT=""
    DAEMON_SOCKET=""
fi

# Sets paths for filter

FILTER_DIR=$DAEMON_DIR    
if [ ! -f "$FILTER_DIR/drweb-smf" ] ; then
    echo
    echo    "Enter path to directory where drweb-smf installed"
    while [ ! -f "$FILTER_DIR/drweb-smf" ] ; do
         echo $n ">$c"
         read FILTER_DIR
    done
fi    

# Try read filter parameters from conf-file

FILTER_CFG_NOSTD="no"
FILTER_CFG="/etc/drweb/drweb_smf.conf"
if [ ! -f $FILTER_CFG ] ; then
    FILTER_CFG="$FILTER_CFG/drweb_smf.conf"
    if [ ! -f $FILTER_CFG ] ; then
        FILTER_CFG_NOSTD="yes"
        echo
        echo	"Enter path to drweb-smf configuration file:"
        while [ ! -f $FILTER_CFG ] ; do
            echo $n ">$c"
            read FILTER_CFG
            if [ "x$FILTER_CFG" = "x" ] ; then
                FILTER_CFG="___not_a_filename___"
            fi
        done    
    fi
fi  
  
echo
echo "Dr.Web sendmail filter ... $FILTER_DIR/drweb-smf"
echo "Dr.Web sendmail filter conf-file ... $FILTER_CFG"

# Read transport

TMP=`$GREP -i Address[^a-z] $FILTER_CFG | $GREP -v "#"`
DADR=`echo $TMP | $AWK '{ gsub( /["[:blank:]]/, "", $0 ); str = substr( $0, match( $0, /^Address=/ ), match( substr( $0, 2 ), /MilterAddress=/ ) ); print str; }'`
FADR=`echo $TMP | $AWK '{ gsub( /["[:blank:]]/, "", $0 ); str = substr( $0, 1+match( substr( $0, 2 ), /MilterAddress=/ ) ); print str; }'`
DMODE=`echo $DADR | $AWK '{ str = substr( $0, 1+index( $0, "=" ), index( $0, ":" ) - index( $0, "=" ) - 1 ); print str; }'`
FMODE=`echo $FADR | $AWK '{ str = substr( $0, 1+index( $0, "=" ), index( $0, ":" ) - index( $0, "=" ) - 1 ); print str; }'`
DADR=`echo $DADR | $AWK '{ str = substr( $0, 1+index( $0, "=" ) ); print str; }'`
FADR=`echo $FADR | $AWK '{ str = substr( $0, 1+index( $0, "=" ) ); print str; }'`
echo
echo $n "Daemon address(es) : $DADR"
DADR=`echo $DADR | $AWK '{ split( $0, str, "," ); print str[1]; }'`
echo ", using first : $DADR"
echo "Filter address : $FADR"
if [ "x$FMODE" = "xinet" ] ; then
    FIP=`echo $FADR | $AWK '{ str = substr( $0, 1+index( $0, "@" ) ); print str; }'`
    FPORT=`echo $FADR | $AWK '{ str = substr( $0, 1+index( $0, ":" ), index( $0, "@" ) - index( $0, ":" ) - 1 ); print str; }'`
    FSOCK=""
    ___T_FILTER_UNIX___="\"no\""
    ___T_FILTER_SOCKET___=""
elif [ "x$FMODE" = "xlocal" ] ; then
    FIP=""
    FPORT=""
    FSOCK=`echo $FADR | $AWK '{ str = substr( $0, 1+index( $0, ":" ) ); print str; }'`
    ___T_FILTER_UNIX___="\"yes\""
    ___T_FILTER_SOCKET___=$FSOCK
else
    echo "In $FILTER_CFG specified wrong address family $FMODE for filter"
    exit 1
fi

# try checking address correctness
if [ "x$DMODE" != "xpid" -a "x$DAEMON_MODE" != "xpid" ]; then
    if [ "x$DMODE" = "xinet" ] ; then
        DIP=`echo $DADR | $AWK '{ str = substr( $0, 1+index( $0, "@" ) ); print str; }'`
        DPORT=`echo $DADR | $AWK '{ str = substr( $0, 1+index( $0, ":" ), index( $0, "@" ) - index( $0, ":" ) - 1 ); print str; }'`
        DSOCK=""
        if [ $VER -eq 1 ] ; then
            if [ "x$DIP" != "x$DAEMON_IP" -o "x$DPORT" != "x$DAEMON_PORT" ] ; then
                echo
                echo $n "You specify in $DAEMON_INI daemon address as "
                if [ $DAEMON_MODE = "inet" ] ; then            
                    echo $n "inet:$DAEMON_PORT@$DAEMON_IP"
                else                 
                    echo $n "local:$DAEMON_SOCKET"
                fi                
                echo ", but in $FILTER_CFG you specify daemon address as $DADR"
                echo "Are you sure in your choice ?"
                echo $n " [default=y]:$c"
                read INPUT
                if [ "x$INPUT" = "xn" -o "x$INPUT" = "xN" ] ; then
                    echo "Edit one of configuration files and try again."
                    exit 1
                fi 
            fi
        elif [ $VER -eq 2 ] ; then
            HPORT=`echo ${PORTS[*]} | $GREP $DPORT`
            HADDR=`echo ${IPS[*]} | $GREP $DIP`        
            if [ "x$HADDR" = "x" -o "x$HPORT" = "x" ] ; then
                echo
                echo "Daemon address $DADR "
                echo "specified in $FILTER_CFG does not found "
                echo "in addresses list from $DAEMON_INI"
                echo "Are you sure in your choice ?"
                echo $n " [default=y]:$c"
                read INPUT
                if [ "x$INPUT" = "xn" -o "x$INPUT" = "xN" ] ; then
                    echo "Edit one of configuration files and try again."
                    exit 1
                fi 
            fi
        fi
    elif [ "x$DMODE" = "xlocal" ] ; then
        DIP=""
        DPORT=""
        DSOCK=`echo $DADR | $AWK '{ str = substr( $0, 1+index( $0, ":" ) ); print str; }'`
        if [ $VER -eq 1 ] ; then
            if [ "x$DSOCK" != "x$DAEMON_SOCKET" ] ; then
                echo 
                echo $n "You specify in $DAEMON_INI daemon address as "
                if [ $DAEMON_MODE = "inet" ] ; then            
                    echo $n "inet:$DAEMON_PORT@$DAEMON_IP"
                else                 
                    echo $n "local:$DAEMON_SOCKET"
                fi                
                echo ", but in $FILTER_CFG you specify daemon address as $DADR"
                echo "Are you sure in your choice ?"
                echo $n " [default=y]:$c"
                read INPUT
                if [ "x$INPUT" = "xn" -o "x$INPUT" = "xN" ] ; then
                    echo "Edit one of configuration files and try again."
                    exit 1
                fi 
            fi
        elif [ $VER -eq 2 ] ; then
            HFILE=`echo ${FILES[*]} | $GREP $DSOCK`
            if [ "x$HFILE" = "x" ] ; then
                echo
                echo "Daemon address $DADR "
                echo "specified in $FILTER_CFG does not found"
                echo "in addresses list from $DAEMON_INI"
                echo "Are you sure in your choice ?"
                echo $n " [default=y]:$c"
                read INPUT
                if [ "x$INPUT" = "xn" -o "x$INPUT" = "xN" ] ; then
                    echo "Edit one of configuration files and try again."
                    exit 1
                fi 
            fi
        fi
    else
        echo "In $FILTER_CFG specified wrong address family $FMODE for daemon"
        exit 1
    fi
fi
___T_MILTER_ADDRESS___=$FADR

# Read timeouts

SOCKET_TIMEOUT=`$GREP -i SocketTimeout $DAEMON_INI | $GREP -v ";" | $AWK '{ str = substr( $0, 1+match( $0, /=./ ) ); gsub( /["[:blank:]]/, "", str ); print str; }'`
FILE_TIMEOUT=`$GREP -i FileTimeout $DAEMON_INI | $GREP -v ";" | $AWK '{ str = substr( $0, 1+match( $0, /=./ ) ); gsub( /["[:blank:]]/, "", str ); print str; }'`
FILTER_TIMEOUT=`$GREP -i ^Timeout $FILTER_CFG | $GREP -v "#" | $AWK '{ str = substr( $0, 1+match( $0, /=./ ) ); gsub( /["[:blank:]]/, "", str ); print str; }'`
if [ "x$SOCKET_TIMEOUT" != "x" -a "x$FILE_TIMEOUT" != "x" ] ; then
    RFILTER_TIMEOUT=`expr 2 \* $SOCKET_TIMEOUT + 2 \* $FILE_TIMEOUT`
elif [ "x$SOCKET_TIMEOUT" != "x" ] ; then
    RFILTER_TIMEOUT=`expr 2 \* $SOCKET_TIMEOUT + 80`
elif [ "x$FILE_TIMEOUT" != "x" ] ; then
    RFILTER_TIMEOUT=`expr 2 \* $FILE_TIMEOUT + 80`
else
    RFILTER_TIMEOUT=160
fi
if [ "x$FILTER_TIMEOUT" != "x" ] ; then
    if [ $FILTER_TIMEOUT -lt $RFILTER_TIMEOUT ] ; then
        echo 
        echo "You setup in filter configuration Timeout = $FILTER_TIMEOUT sec"
        echo "but accorfing to daemon ini-file we recommend at least $RFILTER_TIMEOUT sec"
        echo "Are you sure in your choice ?"
        echo $n " [default=y]:$c"
        read INPUT
        if [ "x$INPUT" = "xn" -o "x$INPUT" = "xN" ] ; then
            echo "Edit one of configuration files and try again."
            exit 1
        fi 
    fi
else 
    FILTER_TIMEOUT=0
fi

echo
echo	"Do you use Sendmail version 8.12 and greater ? [y or n]"
echo $n " [default=y]:$c"
read INPUT
if [ "x$INPUT" = "x" -o "x$INPUT" = "xy" -o "x$INPUT" = "xY" ] ; then
    MILTER_FFR="n"
    ___T_COMMENT_LOG___=""
    ___T_COMMENT_LCF___=""
    ___T_COMMENT_FFR___="dnl "
else    
    MILTER_FFR="y"
    ___T_COMMENT_LOG___="dnl "
    ___T_COMMENT_LCF___="# "
    ___T_COMMENT_FFR___=""
fi    

# Action if filter absent

echo
echo    "Please select action that be applied if Sendmail cannot connect to filter"
echo    "or connection with filter is timed out during mail processing. [ a, r, t]"
echo    "( a - accept, r - reject, t - tempfail )"
echo $n " [default=a]:$c"
read INPUT
if [ "x$INPUT" = "x" -o "x$INPUT" = "xa" -o "x$INPUT" = "xA" ] ; then
    ___T_MILTER_ACTION___=""
elif [ "x$INPUT" = "xr" -o "x$INPUT" = "xR" ] ; then
    ___T_MILTER_ACTION___="F=R,"
elif [ "x$INPUT" = "xt" -o "x$INPUT" = "xT" ] ; then
    ___T_MILTER_ACTION___="F=T,"
else
    echo "Wrong value."
    exit 1
fi

# Debug modes

___T_MILTER_LOGLEVEL___=1
echo
echo	"Do you want run in debug mode? [y or n]"
echo $n " [default=n]:$c"
read INPUT
if [ "x$INPUT" = "xy" -o "x$INPUT" = "xY" ] ; then
    echo	"Enter milter log-level ( 0 - quiet .. 14 - very verbose )"
    echo $n " [default=${___T_MILTER_LOGLEVEL___}]:$c"
    read INPUT
    if [ "x$INPUT" != "x" ]; then
        if [ $INPUT -ge 0 -a $INPUT -le 14 ] ; then
            ___T_MILTER_LOGLEVEL___=$INPUT
        fi
    fi
fi    

# Generate parameter string
___T_FILTER_PATH___="$FILTER_DIR/drweb-smf"        
if [ $FILTER_CFG_NOSTD = "yes" ] ; then
    ___T_FILTER_PARAMS___="--conf=$FILTER_CFG"        
else    
    ___T_FILTER_PARAMS___=""        
fi
if [ $FILTER_TIMEOUT -ne 0 ] ; then
    ___T_MILTER_TIMEOUT_1___="`expr $FILTER_TIMEOUT \* 2`s"
    ___T_MILTER_TIMEOUT_2___="1h"
else
    ___T_MILTER_TIMEOUT_1___="10m"
    ___T_MILTER_TIMEOUT_2___="1h"
fi    
        
echo $n "Creating init script...$c"
echo $n " cf.add-on,$c"        
if [ -f sendmail.cf.addon ] ; then
    mv -f sendmail.cf.addon sendmail.cf.addon.bak
fi
$SED \
    	-e "s&___COMMENT_LCF___&${___T_COMMENT_LCF___}&" \
    	-e "s&___MILTER_LOGLEVEL___&${___T_MILTER_LOGLEVEL___}&" \
    	-e "s&___MILTER_ADDRESS___&${___T_MILTER_ADDRESS___}&" \
    	-e "s&___MILTER_ACTION___&${___T_MILTER_ACTION___}&" \
    	-e "s&___MILTER_TIMEOUT_1___&${___T_MILTER_TIMEOUT_1___}&g" \
    	-e "s&___MILTER_TIMEOUT_2___&${___T_MILTER_TIMEOUT_2___}&" \
   		template.cf.addon > sendmail.cf.addon
echo $n " mc.add-on,$c"        
if [ -f sendmail.mc.addon ] ; then
    mv -f sendmail.mc.addon sendmail.mc.addon.bak
fi
$SED \
    	-e "s&___COMMENT_FFR___&${___T_COMMENT_FFR___}&" \
    	-e "s&___COMMENT_LOG___&${___T_COMMENT_LOG___}&" \
    	-e "s&___MILTER_LOGLEVEL___&${___T_MILTER_LOGLEVEL___}&" \
    	-e "s&___MILTER_ADDRESS___&${___T_MILTER_ADDRESS___}&" \
    	-e "s&___MILTER_ACTION___&${___T_MILTER_ACTION___}&" \
    	-e "s&___MILTER_TIMEOUT_1___&${___T_MILTER_TIMEOUT_1___}&g" \
    	-e "s&___MILTER_TIMEOUT_2___&${___T_MILTER_TIMEOUT_2___}&" \
   		template.mc.addon > sendmail.mc.addon
case $OS in
    Linux)
        init_target=drweb-sendmail
        ;;
    FreeBSD)
        init_target=02.drweb-sendmail.sh
        ;;        
    OpenBSD)
        init_target=02.drweb-sendmail.sh
        ;;        
    Solaris)
        init_target=drweb-sendmail
        ;;        
    *)
        init_target=02.drweb-sendmail.sh
        ;;
esac
echo $n " $init_target ...$c"        
if [ -f $init_target ] ; then
    mv -f $init_target ${init_target}.bak
fi
$SED \
    -e "s&___T_FILTER_UNIX___&${___T_FILTER_UNIX___}&" \
    -e "s&___T_FILTER_SOCKET___&${___T_FILTER_SOCKET___}&" \
    -e "s&___T_FILTER_PATH___&${___T_FILTER_PATH___}&" \
    -e "s&___T_FILTER_PARAMS___&${___T_FILTER_PARAMS___}&" \
    template.initscript > $init_target
chmod 0755 $init_target
echo "Done."
echo "Now you can place $init_target under your system init facility"
echo "(Supported chkconfig to tuning runlevels)" 
echo
if [ "x$DEBUG" = "xyes" ] ; then
    echo "___T:"
    echo "fp="${___T_FILTER_PATH___}
    echo "fo="${___T_FILTER_PARAMS___}
    echo "fu="${___T_FILTER_UNIX___}
    echo "fs="${___T_FILTER_SOCKET___}
    echo "mac="${___T_MILTER_ACTION___}
    echo "mad="${___T_MILTER_ADDRESS___}
    echo "ml="${___T_MILTER_LOGLEVEL___}
    echo "mt1="${___T_MILTER_TIMEOUT_1___}
    echo "mt2="${___T_MILTER_TIMEOUT_2___}
    echo "cl="${___T_COMMENT_LOG___}
    echo "clf="${___T_COMMENT_LCF___}
    echo "ffr="${___T_COMMENT_FFR___}
    echo
    echo "Internal:"
    echo "os=$OS"
    echo "dd=$DAEMON_DIR"
    echo "di=$DAEMON_INI"
    echo "dm=$DAEMON_MODE"
    echo "dp=$DAEMON_PID"
    echo "dip=$DAEMON_IP"
    echo "dpt=$DAEMON_PORT"
    echo "ds=$DAEMON_SOCKET"
    echo "fc=$FILTER_CFG"
    echo "fcn=$FILTER_CFG_NOSTD"
    echo "ft=$FILTER_TIMEOUT"
fi

echo "Press Enter to exit ..."
read INPUT
exit 0
