#!/bin/sh
# Copyright (c) 2012 Stefan Jakobs
# Author: Stefan Jakobs
#
#    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 3 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, see <http://www.gnu.org/licenses/>..
#
# based on the template by SuSE Linux
#
# /etc/init.d/dccifd
#
# /usr/sbin/rcdccifd
#
### BEGIN INIT INFO
# Provides:		dccifd
# Required-Start: $network $remote_fs $syslog $named $time
# Should-Start:   ypbind sendmail
# Required-Stop:	$null
# Should-Stop:    $null
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Short-Description:	dccifd is the DCC interface daemon 
# Description:		dccifd can be uses by an MTA, Contentfilter  
#	or other programms to calculate the DCC checksum of a message
#	and passes that to a DCC server to get the reputation score 
#	of that checksum. This script will start the interface daemon.
### END INIT INFO

DCC_HOMEDIR=/var/lib/dcc
DCC_BIN=$DCC_HOMEDIR/libexec/dccifd
DCC_CONFIG=$DCC_HOMEDIR/dcc_conf
LOGGER_TAG=dccifd.init

# Check existence of the binary
test -x $DCC_BIN || { echo "$DCC_BIN not installed"; exit 5; }

# Set here DEBUG=-x or set it in $DCC_CONFIG to enable debugging
DEBUG=

# Check existence of the needed config file
test -r $DCC_CONFIG || { echo "$DCC_CONFIG not installed" ;
	if [ "$1" == "stop" ]; then exit 0 ;
	else exit 6; fi; }
# Read config
. $DCC_CONFIG

if [ -n "$DEBUG" ] && [ "$DEBUG" == "-x" ]; then set -x; fi
DCC_PID=$DCC_RUNDIR/dccifd.pid
DCC_LOGGER="logger -p $DCC_ERROR_LOG_FACILITY -t $LOGGER_TAG"

# convert old `dccifd -G` to `dccifd -Gon`
DCCIFD_ARGS=`echo "$DCCIFD_ARGS"                                        \
        | sed -e 's/-\([64VdbxANQW]\{1,\}\)G/-\1 -G/g'                  \
            -e 's/-G\([^- ]\)/-G -\1/g'                                 \
            -e 's/-G/-Gon/g'  -e 's/-G[  ]*on[   ]*on/-Gon/g'`
if [ -n "$GREY_CLIENT_ARGS" ]; then
    if test X`expr "X$GREY_CLIENT_ARGS" : '.*\(-G\)'` = X; then
        GREY_CLIENT_ARGS="-G$GREY_CLIENT_ARGS"
    fi
    DCCIFD_ARGS="$GREY_CLIENT_ARGS $DCCIFD_ARGS"
fi

if [ -n "$DCCIFD_USERDIRS" ]; then
    DCCIFD_ARGS="-U$DCCIFD_USERDIRS $DCCIFD_ARGS"
fi
if [ -n "$DCCIFD_WHITECLNT" ]; then
    DCCIFD_ARGS="-w$DCCIFD_WHITECLNT $DCCIFD_ARGS"
fi
if [ -n "$DCCIFD_LOGDIR" ]; then
    DCCIFD_ARGS="-l$DCCIFD_LOGDIR $DCCIFD_ARGS"
fi

CKS="$REP_ARGS"
if [ -n "$DCCIFD_LOG_AT$DCCIFD_REJECT_AT" ]; then
    for CK in ${DCCIFD_CKSUMS:=CMN} $DCCIFD_XTRA_CKSUMS; do
        CKS="$CKS -t$CK,$DCCIFD_LOG_AT,$DCCIFD_REJECT_AT"
    done
fi

DCCIFD_ARGS="$CKS $DNSBL_ARGS $DCC_LOG_ARGS $DCCIFD_ARGS"

if [ -n "$DCC_RUNDIR" ] && [ "$DCC_RUNDIR" != "/var/run/dcc" ]; then
    DCCIFD_ARGS="-R$DCC_RUNDIR $DCCIFD_ARGS"
fi


# Shell functions sourced from /etc/rc.status:
#      rc_check         check and set local and overall rc status
#      rc_status        check and set local and overall rc status
#      rc_status -v     ditto but be verbose in local rc status
#      rc_status -v -r  ditto and clear the local rc status
#      rc_failed        set local and overall rc status to failed
#      rc_failed <num>  set local and overall rc status to <num><num>
#      rc_reset         clear local rc status (overall remains)
#      rc_exit          exit appropriate to overall rc status
. /etc/rc.status

# Reset status of this service
rc_reset

# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
#
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signalling is not supported) are
# considered a success.


case "$1" in
    start)
        if [ ! -d $DCC_RUNDIR ]; then
            mkdir $DCC_RUNDIR
            chown $DCCUID "$DCC_RUNDIR"
            eval $DCC_LOGGER "created $DCC_RUNDIR" 
        elif [ -d "$DCC_RUNDIR" ]; then
            chown $DCCUID "$DCC_RUNDIR"
            eval $DCC_LOGGER "changed owner of $DCC_RUNDIR to $DCCUID" 
        fi
        echo -n "Starting dccifd "
        /sbin/startproc $DCC_BIN -I$DCCUID $DCCIFD_ARGS 
        # Remember status and be verbose
        rc_status -v
        if $(/sbin/checkproc $DCC_BIN); then
            eval $DCC_LOGGER "starting successful" 
        else
            eval $DCC_LOGGER "starting failed"
        fi
        ;;
    stop)
        echo -n "Shutting down dccifd "
        /sbin/killproc -TERM $DCC_BIN

        # Remember status and be verbose
        rc_status -v
        if $(/sbin/checkproc $DCC_BIN); then 
            eval $DCC_LOGGER "shutdown failed"
        else
            eval $DCC_LOGGER "shutdown successful" 
        fi
        if [ -e $DCC_PID ]; then rm $DCC_PID ; fi
        ;;
    restart|reload|force-reload)
        ## 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
        ;;
    try-restart)
        ## Stop the service and if this succeeds (i.e. the 
        ## service was running before), start it again.
        ## Note: try-restart is not (yet) part of LSB (as of 0.7.5)
        $0 status >/dev/null &&  $0 restart

        # Remember status and be quiet
        rc_status
        ;;
    status)
        echo -n "Checking for service dccifd "
        /sbin/checkproc $DCC_BIN

        # Remember status and be quiet
        rc_status -v
        ;;
    *)
        echo "Usage: $0 {start|stop|status|restart|reload|force-reload|try-restart}"
        exit 1
        ;;
esac
rc_exit

