#!/bin/sh

alterator_api_version=1
po_domain="alterator-clamav"

set -f

. alterator-sh-functions
. shell-config
. shell-quote
. shell-ini-config


crontab=/etc/cron.d/freshclam
cron=/etc/init.d/crond
freshclam=/usr/bin/freshclam
FRESHCONF=/etc/clamav/freshclam.conf
CLAMDCONF=/etc/clamav/clamd.conf
CLAMSCONF=/etc/clamsmtpd.conf

init_pager()
{
    q_path="$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
    write_string_param per_page "25"
    write_string_param total "$(find $q_path -name virus*| wc -l)"
}

init_selector()
{
    write_enum_item "25" "`_ "25 lines"`"
    write_enum_item "50" "`_ "50 lines"`"
    write_enum_item "100" "`_ "100 lines"`"
    write_enum_item "150" "`_ "150 lines"`"
    write_enum_item "200" "`_ "200 lines"`"
}

q_list()
{
    
    if [ "$in_start" -le 0 ];then
	f=1
    else
	f="$in_start"
    fi
    t=$(($f + $in_size -1))
    q_path="$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
     ls $q_path/ |grep "^virus" | sed -n -e "$f,$t p" | while read file; do
          q_from=""
          q_to=""
          q_date=""
          q_from=$(grep "^From:" "$q_path/$file" | sed -e s/^From:[[:space:]]//g |sed -e s/.*\<//g | sed -e s/\>//g)
          q_to=$(grep "^To:" "$q_path/$file" | sed -e s/^To:[[:space:]]//g | sed -e s/.*\<//g | sed -e s/\>//g)
          q_subj=$(grep "^Subject:" "$q_path/$file" |sed -e s/^Subject:[[:space:]]//g  )
          q_date=`date +%d.%m.%Y -d "$(grep "^Date:" "$q_path/$file" | cut -f2 -d ':')"`
          
          write_table_item  \
            name "$file" \
            q_subj "$q_subj" \
            q_date "$q_date" \
            q_from "$q_from" \
            q_to "$q_to" 
        done
}

f_list()
{
    q_path="$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
    find "$q_path" -name virus*  | \
    while read file ; do
	write_enum_item "$file" "$(basename $file)"
    done
}

test_file() 
{
    local file=
    q_path="$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
    if [ -f "$in_file" ];then
	file="$in_file"
    else
	file=$(find "$q_path" -name $(basename $in_file))
    fi
    
    	q_from=$(grep "^From:" "$file" | sed -e s/^From:[[:space:]]//g | sed -e s/.*\<//g | sed -e s/\>//g)
	q_to=$(grep "^To:" "$file" | sed -e s/^To:[[:space:]]//g | sed -e s/.*\<//g | sed -e s/\>//g)
	q_date="$(grep "^Date:" "$file" | cut -f2 -d ':')"
	q_subj=$(grep "^Subject:" "$file" | cut -f2 -d ':')
	q_reason="$(/usr/bin/clamdscan --no-summary "$file"|cut -f2 -d ':')"
	
	write_string_param "q_file" "$file"
	write_string_param "q_from" "$q_from"
	write_string_param "q_to" "$q_to"
	write_string_param "q_date" "$q_date"
	write_string_param "q_subj" "$q_subj"
	write_string_param "q_reason" "$q_reason"
}

delete_filelist() 
{
    local IFS=';'
    q_path="$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
    for file in $in_qfiles; do
	rm -f "$q_path/$file"
    done
}

rm_file()
{ 
    local file=`basename $in_file`
    q_path="$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
    rm -f "$q_path/$file"
}


modules()
{
    if [ -f "/usr/bin/freshclam" ];then 
	write_bool_param freshclam "Yes"
    else
	write_bool_param freshclam "No"
    fi
    
    if [ -f "/usr/lib/samba/vfs/vscan-clamav.so" ];then
        write_bool_param vscan "Yes"
    else
        write_bool_param vscan "No"
    fi

    if [ -f "/usr/sbin/clamsmtpd" ];then
        write_bool_param clamsmtpd "Yes"
    else
	write_bool_param clamsmtpd "No"
    fi
}

scan(){
    local file=
    q_path="$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
    if [ -f "$in_file" ];then
	file="$in_file"
    else
	file=$(find "$q_path" -name $(basename $in_file))
    fi
    msg="$(/usr/bin/clamdscan --no-summary "$file")"
    write_error "$msg"
}


daemon()
{
    if test_bool "$in_status"; then
        service clamd start
        service clamsmtpd start
	chkconfig clamd on
	chkconfig clamsmtpd on
    else
        service clamsmtpd stop
        service clamd stop
        chkconfig clamd off
        chkconfig clamsmtpd off
    fi
}

reload()
{
	service clamd reload && service clamsmtpd reload
	write_string_param retcode "$?"
}

shell_set()
{
    local file=$1;shift
    local name="$1";shift;
    quote_sed_regexp_variable value "$1";shift;
    local msg="${1:-invalid value}"

    if [ -n "$name" -a -n "$value" ];then
	sed -e "/^#$name\s/s/^#//g" -i "$file"
        sed -e "/^$name/s/.*/$name $value/g" -i "$file"
    else
        write_error "$msg"
        return 1
    fi
    return 0
}

shell_off()
{
    local file=$1;shift
    local name="$1";shift;
    sed -e "/^$name\s/s/.*/#&/g" -i "$file"

}

shell_on()
{
    local file=$1;shift
    local name="$1";shift;
    sed -e "/^#$name\s/s/^#//g" -i "$file"
}


write_settings()
{
    local zone=$(grep "$(shell_config_get /etc/sysconfig/clock ZONE)" /usr/share/zoneinfo/zone.tab  | cut -f1)

    service clamsmtpd stop
    service clamd stop

    [ -n "$in_l_port" ] && shell_set "$CLAMSCONF" "Listen:" "$in_l_port"
    [ -n "$in_out_port" ] && shell_set "$CLAMSCONF" "OutAddress:" "$in_out_port"

    [ -n "$in_use_dbdns" ] && shell_on "$FRESHCONF" "DNSDatabaseInfo" || shell_off  "$FRESHCONF" "DNSDatabaseInfo" 
    if [ -n "$in_use_dbmirror" ];then
        sed -e "/^#DatabaseMirror db\s/s/^#//g" -i "$FRESHCONF"
        sed -e "/DatabaseMirror db\./s/.*/DatabaseMirror db\.$zone\.clamav\.net/g" -i "$FRESHCONF"
     else
        sed -e "/^DatabaseMirror db\./s/.*/#&/g" -i "$FRESHCONF" 
    fi

    if [ -n "$in_use_proxy" ];then
	shell_set "$FRESHCONF" "HTTPProxyServer" $in_proxy_host
	shell_set "$FRESHCONF" "HTTPProxyPort"  $in_proxy_port
	shell_set "$FRESHCONF" "HTTPProxyPassword"  $in_proxy_password
	shell_set "$FRESHCONF" "HTTPProxyUsername"  $in_proxy_user
    else
        for option in HTTPProxyServer HTTPProxyPort HTTPProxyPassword HTTPProxyUsername;do
	    sed -e "/^$option\s/s/.*/#&/g" -i "$FRESHCONF"
	done
    fi

    [ -n "$in_use_quarantine" ] && shell_set "$CLAMSCONF" "Quarantine:" "yes" ||shell_set "$CLAMSCONF" "Quarantine:" "no"
    
    if [ -n "$in_q_path" ];then
	mkdir -p "$in_q_path"
	chown -R mail:mail "$in_q_path"
	shell_set "$CLAMDCONF" "TemporaryDirectory" "$in_q_path"
	shell_set "$CLAMSCONF" "TempDirectory:" "$in_q_path"
    fi

    [ -n "$in_use_vascript" ] && shell_set "$CLAMSCONF" "VirusAction:" "$in_va_script" ||shell_off "$CLAMSCONF" "VirusAction:" 

    [ -n "$in_use_header" ] && shell_on "$CLAMSCONF" "Header:" || shell_off "$CLAMSCONF" "Header:" 
    if [ -n "$in_x_header" ]; then 
	sed -e "/^Header:/s/.*/Header: $(quote_sed_regexp "$in_x_header")/g" -i "$CLAMSCONF"
    fi

    if [ -n "$in_is_transparent_proxy" ]; then
	sed -e "/^#TransparentProxy:\s/s/^#//g" -i "$CLAMSCONF"
	shell_set "$CLAMSCONF" "TransparentProxy:" "on"
    else
	sed -e "/^TransparentProxy:\s/s/.*/#&/g" -i "$CLAMSCONF"
	shell_set "$CLAMSCONF" "TransparentProxy:" "off"
	sed -e "/^TransparentProxy:\s/s/.*/#&/g" -i "$CLAMSCONF"
    fi
    
    service clamd start
    service clamsmtpd start
}

##
# initiates database update
# writes retcode
#
update_bases()
{
	$freshclam --quiet --daemon-notify
	write_string_param retcode "$?"
}

get_cron()
{
	cat $crontab | ( read M H d m w;
	    [ "$M" == "*/30" -a "$H" == "*" ] && write_string_param update_period "30"
	    [ "$M" == "5" -a "$H" == "*" ] && write_string_param update_period "60"
	    [ "$M" == "10" -a "$H" == "*/2" ] && write_string_param update_period "120"
	    [ "$M" == "15" -a "$H" == "*/3" ] && write_string_param update_period "180"
	    [ "$M" == "20" -a "$H" == "*/4" ] && write_string_param update_period "240"
	    [ "$M" == "25" -a "$H" == "*/8" ] && write_string_param update_period "480"
	)
	
}

set_cron()
{
        timestring=""
        case "$in_time" in
    	    30)
    		timestring="*/30 * * * *"
    	    ;;
    	    60)
    		timestring="5 * * * *"
    	    ;;
    	    120)
    		timestring="10 */2 * * *"
    	    ;;
    	    180)
    		timestring="15 */3 * * *"
    	    ;;
    	    240)
    		timestring="20 */4 * * *"
    	    ;;
    	    480)
    	        timestring="25 */8 * * *"
    	    ;;
    	    *)
    		timestring="*/30 * * * *"
    	    ;;
    	esac
	echo -e "$timestring\troot\t[ -f /var/run/clamav/clamd.pid ] && /usr/bin/freshclam --quiet --daemon-notify" > $crontab
	$cron reload
}

enable_cron()
{
#    [ -n "$1" ] || return
    echo $(set|grep in_) >&2
    if [ "$in_cron" == "#t" ];then
	sed -e "/^#.*freshclam/s/^#//g" -i "$crontab"
    else
	sed -e "/^[^#].*freshclam/s/.*/#&/g" -i "$crontab" 
    fi
    
    $cron reload
}

status()
{
    update_date=`date +"%d.%m.%Y" -r /var/lib/clamav/daily.cld`
    update_time=`date +"%H:%M" -r /var/lib/clamav/daily.cld`
    q_path="$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
    echo "$(/sbin/chkconfig --list | grep clamd)" | grep -v -q ":on"; write_bool_param daemon "$?"
    grep -q "^#" "$crontab"; write_bool_param enable_updates "$?"
    get_cron
    write_string_param cur_status "$(service clamd status)"
    write_string_param update_date "$update_date"
    write_string_param update_time "$update_time"
    write_string_param quarantine_status "$(find $q_path -name virus*| wc -l)"
    #
    write_bool_param use_proxy $(grep -sc "^HTTPProxyServer" "$FRESHCONF")
    write_bool_param use_quarantine $(grep -sc "^Quarantine: yes" "$CLAMSCONF")
    write_bool_param use_dbdns $(grep -sc "^DNSDatabaseInfo" "$FRESHCONF")
    write_bool_param use_dbmirror $(grep -sc "^DatabaseMirror db" "$FRESHCONF")
    write_bool_param is_transparent_proxy $(grep -sc "^TransparentProxy:" "$CLAMSCONF")
    write_bool_param use_header $(grep -sc "^Header:" "$CLAMSCONF")
    write_bool_param use_va_script $(grep -sc "^VirusAction:" "$CLAMSCONF")
    #
    write_string_param db_mirror "$(grep "\(^\|^#\)DatabaseMirror db" "$FRESHCONF"| cut -f 2 -d ' ')"
    write_string_param proxy_host "$(grep "\(^\|^#\)HTTPProxyServer" "$FRESHCONF" | cut -f 2 -d ' ')"
    write_string_param proxy_port "$(grep "\(^\|^#\)HTTPProxyPort" "$FRESHCONF" | cut -f 2 -d ' ')"
    write_string_param proxy_user "$(grep "\(^\|^#\)HTTPProxyUsername" "$FRESHCONF" | cut -f 2 -d ' ')"
    write_string_param proxy_password "$(grep "\(^\|^#\)HTTPProxyPassword" "$FRESHCONF" | cut -f 2 -d ' ')"
    write_string_param db_dns "$(grep "DNSDatabaseInfo" "$FRESHCONF"| cut -f 2 -d ' ')"
    write_string_param l_port "$(grep "^Listen:" "$CLAMSCONF"| cut -f 2 -d ' ')"
    write_string_param out_port "$(grep "^OutAddress:" "$CLAMSCONF"| cut -f 2 -d ' ')"
    write_string_param q_path "$(grep "\(^\|^#\)TemporaryDirectory" "$CLAMDCONF"| cut -f2 -d ' ')"
    write_string_param x_header "$(grep "\(^\|^#\)Header:" "$CLAMSCONF"| sed -e "s/\(^\|^#\)Header: //g" )"
    write_string_param va_script "$(grep "VirusAction:" "$CLAMSCONF"| cut -f2 -d ' ' )"
    
}

state()
{
    write_string_param cur_status "$(service clamd status)"
}


#alterator_export_proc status
#alterator_export_proc state
#alterator_export_proc daemon
#alterator_export_proc reload
#alterator_export_proc write_settings
#alterator_export_proc update_bases
#alterator_export_proc get_cron
#alterator_export_proc set_cron
#alterator_export_proc enable_cron

on_message()
{
        case "$in_action" in
               list)
                      case "$in__objects" in
                    	 qlist)
                    	    q_list
                         ;;
                    	 flist)
                    	    f_list
                         ;;
                         selector)
                            init_selector
                         ;;
                         *)
                         ;;
                      esac
                         ;;

               read)
                      case "$in__objects" in
                        status) 
                    	    status
                    	;;
                        state) 
                    	    state
                    	;;
                        modules) 
                    	    modules
                        ;;
                        pager)
                            init_pager
                        ;;
                        file)
                            [ -z "$in_file" ] || test_file "$in_file"
                        ;;
                        *)
                        ;;
                      esac
                      ;;
                write)
                      case "$in__objects" in
                        daemon) daemon;;
                        reload) reload;;
                        update_bases) update_bases;;
                        write_settings) write_settings;;
                        set_cron) set_cron;;
                        enable_cron) enable_cron;;
                         scan)
                            [ -z "$in_file" ] || scan "$in_file"
                         ;;
                        *)
                        ;;
                      esac
                ;;
                delete)
            	      case "$in__objects" in
            	        file)
            	    	    [ -z "$in_file" ] || rm_file "$in_file" 
            	        ;;
            	        filelist)
            	    	    [ -z "$in_qfiles" ] || delete_filelist "$in_qfiles"
            	        ;;
            	        *)
            		;;
            	esac
            ;;
        esac
}


message_loop
