#!/bin/sh set -e # Source debconf library . /usr/share/debconf/confmodule # This conf script is capable of backing up db_version 2.0 db_capb backup status_of_proc () { local pidfile daemon name status pidfile= OPTIND=1 while getopts p: opt ; do case "$opt" in p) pidfile="$OPTARG";; esac done shift $(($OPTIND - 1)) if [ -n "$pidfile" ]; then pidfile="-p $pidfile" fi daemon="$1" name="$2" status="0" pidofproc $pidfile $daemon >/dev/null || status="$?" if [ "$status" = 0 ]; then log_success_msg "$name is running" return 0 else log_failure_msg "$name is not running" return $status fi } to_lower() { word="$1" lcword=$(echo "$word" | tr A-Z a-z) echo "$lcword" } is_true() { var="$1" lcvar=$(to_lower "$var") [ 'true' = "$lcvar" ] || [ 'yes' = "$lcvar" ] || [ 1 = "$lcvar" ] return $? } is_false() { var="$1" lcvar=$(to_lower "$var") [ 'false' = "$lcvar" ] || [ 'no' = "$lcvar" ] || [ 0 = "$lcvar" ] return $? } ucf_cleanup() { # This only does something if I've fucked up before # Not entirely impossible :( configfile=$1 if [ `grep "$configfile" /var/lib/ucf/hashfile | wc -l` -gt 1 ]; then grep -v "$configfile" /var/lib/ucf/hashfile > /var/lib/ucf/hashfile.tmp grep "$configfile" /var/lib/ucf/hashfile | tail -n 1 >> /var/lib/ucf/hashfile.tmp mv /var/lib/ucf/hashfile.tmp /var/lib/ucf/hashfile fi } add_to_ucf() { configfile=$1 ucffile=$2 if ! grep -q "$configfile" /var/lib/ucf/hashfile; then md5sum $configfile >> /var/lib/ucf/hashfile cp $configfile $ucffile fi } ucf_upgrade_check() { configfile=$1 sourcefile=$2 ucffile=$3 if [ -f "$configfile" ]; then add_to_ucf $configfile $ucffile ucf --three-way --debconf-ok "$sourcefile" "$configfile" else [ -d /var/lib/ucf/cache ] || mkdir -p /var/lib/ucf/cache cp $sourcefile $configfile add_to_ucf $configfile $ucffile fi } slurp_config() { CLAMAVCONF="$1" if [ -e "$CLAMAVCONF" ]; then for variable in `egrep -v '^[[:space:]]*(#|$)' "$CLAMAVCONF" | awk '{print $1}'`; do case "$variable" in DatabaseMirror) if [ -z "$DatabaseMirror" ]; then for i in `grep ^$variable $CLAMAVCONF | awk '{print $2}'`; do value="$value $i" done else continue fi ;; DatabaseCustomURL) if [ -z "$DatabaseCustomURL" ]; then for i in `grep ^$variable $CLAMAVCONF | awk '{print $2}'`; do value="$value $i" done else continue fi ;; IncludePUA) if [ -z "$IncludePUA" ]; then for i in `grep ^$variable $CLAMAVCONF | awk '{print $2}'`; do value="$i $value" done else continue fi ;; ExcludePUA) if [ -z "$ExcludePUA" ]; then for i in `grep ^$variable $CLAMAVCONF | awk '{print $2}'`; do value="$i $value" done else continue fi ;; ExtraDatabase) if [ -z "$ExtraDatabase" ]; then for i in `grep ^$variable $CLAMAVCONF | awk '{print $2}'`; do value="$value $i" done else continue fi ;; VirusEvent|OnUpdateExecute|OnErrorExecute|RejectMsg) value=`grep ^$variable $CLAMAVCONF | head -n1 | sed -e s/$variable\ //` ;; *) value=`grep ^$variable $CLAMAVCONF | head -n1 | awk '{print $2}'` ;; esac if [ -z "$value" ]; then export "$variable"="true" elif [ "$value" != "$variable" ]; then export "$variable"="$value" else export "$variable"="true" fi unset value done fi } make_dir() { DIR=$1 if [ -d "$DIR" ]; then return 0; fi [ -n "$User" ] || User=clamav mkdir -p -m 0755 "$DIR" chown "$User" "$DIR" } # Debconf Functions isdigit () { case $1 in [[:digit:]]*) ISDIGIT=1 ;; *) ISDIGIT=0 ;; esac } inputdigit () { ISDIGIT=0 while [ "$ISDIGIT" = '0' ]; do db_input "$1" "$2" || true if ! db_go; then return 30 fi db_get $2 || true isdigit $RET if [ "$ISDIGIT" = '0' ]; then db_input critical clamav-base/numinfo || true db_go fi done return 0 } StateGeneric() { PRIO=$1 QUESTION=$2 NEXT=$3 LAST=$4 db_input $PRIO $QUESTION || true if db_go; then STATE=$NEXT else STATE=$LAST fi } StateGenericDigit() { PRIO=$1 QUESTION=$2 NEXT=$3 LAST=$4 inputdigit $PRIO $QUESTION || true if db_go; then STATE=$NEXT else STATE=$LAST fi } CLAMAVCONF='/etc/clamav/clamd.conf' slurp_config "$CLAMAVCONF" # Store conf file values as debconf answers - make sure user changes made # outside of debconf are preserved if [ -n "$User" ]; then db_set clamav-base/User "$User" || true if ! [ "$User" = 'root' ]; then AddGroups=`groups "$User" | awk -F ':' '{print $2}' | sed -e s/"$User"//` fi if [ -n "$AddGroups" ]; then db_set clamav-base/AddGroups "$AddGroups" || true fi fi if [ -n "$TCPSocket" ]; then db_set clamav-base/TcpOrLocal TCP || true elif [ -n "$LocalSocket" ]; then db_set clamav-base/TcpOrLocal UNIX || true fi if [ -n "$LocalSocket" ]; then db_set clamav-base/LocalSocket "$LocalSocket" || true fi if [ -n "$LocalSocketGroup" ]; then db_set clamav-base/LocalSocketGroup "$LocalSocketGroup" || true fi if [ -n "$LocalSocketMode" ]; then db_set clamav-base/LocalSocketMode "$LocalSocketMode" || true fi if [ "$FixStaleSocket" = "true" ]; then db_set clamav-base/FixStaleSocket true || true fi if [ -n "$TCPSocket" ]; then db_set clamav-base/TCPSocket "$TCPSocket" || true fi if [ -n "$TCPaddr" ]; then db_set clamav-base/TCPAddr "$TCPaddr" || true fi if [ "$ScanMail" = "true" ]; then db_set clamav-base/ScanMail true || true fi if [ "$ScanArchive" = "true" ]; then db_set clamav-base/ScanArchive true || true fi if [ -n "$StreamMaxLength" ]; then StreamMaxLength="`echo $StreamMaxLength | sed -e s/M//`" if [ "$StreamMaxLength" = "0" ]; then StreamMaxLength="25" fi db_set clamav-base/StreamMaxLength "$StreamMaxLength" || true fi if [ -n "$MaxDirectoryRecursion" ]; then db_set clamav-base/MaxDirectoryRecursion "$MaxDirectoryRecursion" || true fi if [ "$FollowDirectorySymlinks" = "true" ]; then db_set clamav-base/FollowDirectorySymlinks true || true fi if [ "$FollowFileSymlinks" = "true" ]; then db_set clamav-base/FollowFileSymlinks true || true fi if [ -n "$ReadTimeout" ] && [ -z "$ThreadTimeout" ]; then db_set clamav-base/ReadTimeout "$ReadTimeout" || true elif [ -z "$ReadTimeout" ] && [ -n "$ThreadTimeout" ]; then ReadTimeout="$ThreadTimeout" db_set clamav-base/ReadTimeout "$ReadTimeout" || true elif [ -n "$ReadTimeout" ]; then db_set clamav-base/ReadTimeout "$ReadTimeout" || true fi if [ -n "$MaxThreads" ]; then db_set clamav-base/MaxThreads "$MaxThreads" || true fi if [ -n "$MaxConnectionQueueLength" ]; then db_set clamav-base/MaxConnectionQueueLength "$MaxConnectionQueueLength" || true fi if [ "$LogSyslog" = "true" ]; then db_set clamav-base/LogSyslog true || true fi if [ -n "$LogFile" ]; then db_set clamav-base/LogFile "$LogFile" || true fi if [ "$LogTime" = "true" ]; then db_set clamav-base/LogTime true || true fi if [ "$Bytecode" = "true" ]; then db_set clamav-base/Bytecode true || true fi if [ -n "$BytecodeSecurity" ]; then db_set clamav-base/BytecodeSecurity "$BytecodeSecurity" || true fi if [ -n "$BytecodeTimeout" ]; then db_set clamav-base/BytecodeTimeout "$BytecodeTimeout" || true fi # States StateDebconf() { db_input medium clamav-base/debconf || true if ! db_go; then STATE="End" else db_get clamav-base/debconf || true if [ "$RET" = "false" ]; then STATE="End" else STATE="Socket" fi fi } StateSocket() { db_input medium clamav-base/TcpOrLocal || true if ! db_go; then STATE="Debconf" else db_metaget clamav-base/TcpOrLocal value STATE=$RET fi } StateLocalSocketGroup() { db_input low clamav-base/LocalSocketGroup || true if db_go; then db_metaget clamav-base/LocalSocketGroup value if [ "$RET" = "" ]; then db_set clamav-base/LocalSocketGroup "clamav" || true fi STATE="LocalSocketMode" else STATE="UNIX" fi } StateScanMail() { db_input medium clamav-base/ScanMail || true if db_go; then STATE="ScanArchive" else db_metaget clamav-base/TcpOrLocal value if [ "$RET" = "TCP" ]; then STATE="TCPAddr" else STATE="FixStale" fi fi } StateScanArchive() { db_input low clamav-base/ScanArchive || true if db_go; then db_metaget clamav-base/ScanArchive value if [ "$RET" = "true" ]; then STATE="StreamMaxLength" else STATE="MaxDirectoryRecursion" fi else STATE="ScanMail" fi } StateMaxDirectoryRecursion() { if inputdigit low clamav-base/MaxDirectoryRecursion; then db_metaget clamav-base/MaxDirectoryRecursion value if [ "$RET" = "0" ]; then STATE="FollowDirectorySymlinks" else STATE="FollowFileSymlinks" fi else STATE="ScanArchive" fi } StateFollowFileSymlinks() { db_input low clamav-base/FollowFileSymlinks || true if db_go; then STATE="ReadTimeout" else db_metaget clamav-base/MaxDirectoryRecursion value; if [ "$RET" = "0" ]; then STATE="FollowDirectorySymlinks" else STATE="MaxDirectoryRecursion" fi fi } StateLogFile() { db_input low clamav-base/LogFile || true if db_go; then db_metaget clamav-base/LogFile value if [ "$RET" = "" ]; then db_set clamav-base/LogFile "/var/log/clamav/clamav.log" || true STATE="LogTime" elif [ "$RET" = 'none' ]; then db_set clamav-base/LogFile "" || true STATE="SelfCheck" else STATE="LogTime" fi else STATE="LogSyslog" fi } StateUser() { db_input medium clamav-base/User || true if db_go; then db_metaget clamav-base/User value if [ "$RET" = "" ]; then db_set clamav-base/User "clamav" || true fi STATE="AddGroups" else STATE="SelfCheck" fi } StateBytecode() { db_input low clamav-base/Bytecode || true if db_go; then db_metaget clamav-base/Bytecode value if [ "$RET" = "true" ]; then STATE="BytecodeSecurity" else STATE="End" fi else STATE="AddGroups" fi } # To many options to configure at configure if [ "$1" = "reconfigure" ]; then STATE="Init" elif [ -n "$2" ]; then if [ -z "$User" ]; then STATE="User" fi else STATE="End" fi [ -z "$STATE" ] && STATE='End' # This is the statemachine that controls execution. All the 'real' work is # performed by subfunctions above. while [ "$STATE" != "End" ]; do case "$STATE" in "Init") StateDebconf ;; "Socket") StateSocket ;; "TCP") StateGenericDigit low clamav-base/TCPSocket TCPAddr Socket ;; "TCPAddr") StateGeneric low clamav-base/TCPAddr ScanMail TCP ;; "UNIX") StateGeneric low clamav-base/LocalSocket LocalSocketGroup Socket ;; "LocalSocketGroup") StateLocalSocketGroup ;; "LocalSocketMode") StateGenericDigit low clamav-base/LocalSocketMode FixStale LocalSocketGroup ;; "FixStale") StateGeneric low clamav-base/FixStaleSocket ScanMail LocalSocketMode ;; "ScanMail") StateScanMail ;; "ScanArchive") StateScanArchive ;; "StreamMaxLength") StateGenericDigit low clamav-base/StreamMaxLength MaxDirectoryRecursion ScanArchive ;; "MaxDirectoryRecursion") StateMaxDirectoryRecursion ;; "FollowDirectorySymlinks") StateGeneric low clamav-base/FollowDirectorySymlinks FollowFileSymlinks MaxDirectoryRecursion ;; "FollowFileSymlinks") StateFollowFileSymlinks ;; "ReadTimeout") StateGenericDigit low clamav-base/ReadTimeout MaxThreads FollowFileSymlinks ;; "MaxThreads") StateGenericDigit low clamav-base/MaxThreads MaxConnectionQueueLength ReadTimeout ;; "MaxConnectionQueueLength") StateGenericDigit low clamav-base/MaxConnectionQueueLength LogSyslog MaxThreads ;; "LogSyslog") StateGeneric medium clamav-base/LogSyslog LogFile MaxConnectionQueueLength ;; "LogFile") StateLogFile ;; "LogTime") StateGeneric low clamav-base/LogTime SelfCheck LogFile ;; "SelfCheck") StateGeneric low clamav-base/SelfCheck User LogFile ;; "User") StateUser ;; "AddGroups") StateGeneric medium clamav-base/AddGroups Bytecode User ;; "Bytecode") StateBytecode ;; "BytecodeSecurity") StateGeneric low clamav-base/BytecodeSecurity BytecodeTimeout Bytecode ;; "BytecodeTimeout") StateGenericDigit low clamav-base/BytecodeTimeout End BytecodeSecurity ;; esac done db_stop || true exit 0