#!/bin/sh
#
# Start/Stop AiGuard
#
# Copyright 2002-2004 AVIRA GmbH
#

PATH="/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin"

SERVICENAME="aiguard"
DEVNAME="dazuko"
DAEMONNAME="avira"
AVDIR="/usr/lib/AVIRA"

DEVFILE="/dev/${DEVNAME}"
DAEMON="${AVDIR}/${DAEMONNAME}"
OS=`uname | tr "[:upper:]" "[:lower:]"`
OSREL="`uname -r`"
KVER="${OS}-${OSREL}"
GUARD_TYPE="workstation"
PRODUCT_VARIANT="desktop"

case "${OS}" in
	sunos)
		ECHO="/usr/lib/AVIRA/echo_sunos"
		if [ ! -x "${ECHO}" ]
		then
			ECHO="echo"
		fi
		;;
	*)
		ECHO="echo"
		;;
esac

case "${OS}" in
	linux)
		if [ "${OSREL#2.6.}" != "${OSREL}" ]; then
			OS="linux26"
		fi

		# Determine the Linux distribution type
		DISTRO="unknown"
		
		[ -e /etc/redhat-release ] && DISTRO="redhat"
		[ -e /etc/mandrake-release -o -e /etc/mandrakelinux-release ] \
					&& DISTRO="mandrake"
		[ -e /etc/fedora-release ] && DISTRO="fedora"
		[ -e /etc/SuSE-release ] && DISTRO="suse"
		[ -e /etc/debian_version ] && DISTRO="debian"
		[ -e /etc/slackware-version ] && DISTRO="slackware"
		[ -e /etc/gentoo-release ] && DISTRO="gentoo"
		[ -e /etc/turbolinux-release ] && DISTRO="turbolinux"
		;;
	
	*)
		DISTRO="$OS"
		;;
esac

case "${DISTRO}" in
	redhat|mandrake|fedora)
		LOCKSUBSYS="/var/lock/subsys/${SERVICENAME}"
		;;
esac

case "${OS}" in
	freebsd)
		KMODULE="${AVDIR}/${KVER}/${DEVNAME}.ko"
		;;
	linux26)
		if [ "`uname -a | grep \ SMP\ `" ]; then
			KVER="${KVER}-smp"
		fi
		KMODULE="${AVDIR}/${KVER}/${DEVNAME}.ko"
		;;
	*)
		if [ "`uname -a | grep \ SMP\ `" ]; then
			KVER="${KVER}-smp"
		fi
		KMODULE="${AVDIR}/${KVER}/${DEVNAME}.o"
		;;
esac

getPROCESSLIST()
{
	PROCESSLIST=""

	case "${OS}" in
		sunos)
			for PROC in `ps -Ao pid,args | grep ${DAEMONNAME}.*[-]-${GUARD_TYPE}`
			do
				if [ -z "`$ECHO ${PROC} | sed -e s/[0-9]//g`" ]
				then
					PROCESSLIST="${PROCESSLIST} ${PROC}"
				fi
			done
			;;
		*)
			for PROC in `ps axw -o 'pid= command=' | grep ${DAEMONNAME}.*[-]-${GUARD_TYPE}`
			do
				if [ -z "`$ECHO ${PROC} | sed -e s/[0-9]//g`" ]
				then
					PROCESSLIST="${PROCESSLIST} ${PROC}"
				fi
			done
			;;
	esac
}

getDEV()
{
	case "${OS}" in
		freebsd)
			DEV=`kldstat | grep ${DEVNAME}`
			;;
		sunos)
			DEV=`modinfo | grep ${DEVNAME}`
			;;
		*)
			DEV=`grep ${DEVNAME} /proc/devices`
			;;
	esac
}

insertModule()
{
	case "${OS}" in
		freebsd)
			kldload ${KMODULE}
			;;
		*)
			insmod ${KMODULE}
			;;
	esac
}

getDEVMAJOR()
{
	case "${OS}" in
		freebsd)
			DEVMAJOR=33
			;;
		*)
			set -- ${DEV}

			DEVMAJOR=${1}
			;;
	esac
}

makeNode()
{
	case "${OS}" in
		freebsd)
			mknod ${DEVFILE} c ${DEVMAJOR} 0
			;;
		*)
			mknod -m 600 ${DEVFILE} c ${DEVMAJOR} 0
			;;
	esac
}

case "$1" in
	start)
		${ECHO} -n "Starting AVIRA: aiguard-${PRODUCT_VARIANT}"

		# check if AiGuard is already running
		getPROCESSLIST
		if [ ! -z "${PROCESSLIST}" ]
		then
			${ECHO} " (FAILED)"
			${ECHO} " "
			${ECHO} "error: ${DAEMONNAME} is already running"
			${ECHO} " "
			$0 status
			exit 1
		fi

		if [ "${OS}" != "sunos" ]
		then
			# get Dazuko device information
			getDEV
			if [ -z "${DEV}" ]
			then
				# no Dazuko device information, Dazuko is not loaded

				# try to load our own Dazuko module

				# check if our own module is available
				if [ ! -f "${KMODULE}" ]
				then
					${ECHO} " (FAILED)"
					${ECHO} " "
					${ECHO} "error: ${KMODULE} is missing"
					${ECHO} " "
					exit 1
				fi

				# we found our own module

				# load it
				insertModule

				# get Dazuko device information
				getDEV
				if [ -z "${DEV}" ]
				then
					# no Dazuko device information, there is a problem

					${ECHO} " (FAILED)"
					${ECHO} " "
					${ECHO} "error: device ${DEVNAME} not loaded"
					${ECHO} "Was Dazuko correctly installed?"
					${ECHO} " "
					exit 1
				fi
			fi

			# Dazuko is loaded

			# check if device node is available
			if [ -c "${DEVFILE}" ]
			then
				# device node is available, check if it works
				# (we grab 10 bytes because of a bug in Dazuko reading)

				dd if=/dev/dazuko bs=10 count=1 > /dev/null 2>&1
				if [ $? -ne 0 ]
				then
					# unable to read from device, this device node is not correct

					# remove the device node
					rm -f "${DEVFILE}"
				fi
			fi

			# check if we need to create a device node
			if [ ! -c "${DEVFILE}" ]
			then
				# there is no device node, so we need to make one

				# get device major number for Dazuko
				getDEVMAJOR

				# make the device node
				makeNode

				# set permissions on the device node
				chown 0:0 "${DEVFILE}"
				if [ $? -ne 0 ]
				then
					# unable to set permissions? there is a problem

					${ECHO} " (FAILED)"
					${ECHO} " "
					${ECHO} "error: could not create node ${DEVFILE}"
					${ECHO} "Please send a problem description to unix_support@avira.com"
					${ECHO} "Very helpful would be the output of 'uname -a' and the name of"
					${ECHO} "your UNIX distribution."
					${ECHO} " "
					exit 1
				fi
			fi

			# Dazuko is loaded and the device node has been created
		fi

		if [ ! -x "${DAEMON}" ]
		then
			# AiGuard missing

			${ECHO} " (FAILED)"
			${ECHO} " "
			${ECHO} "error: ${DAEMON} missing"
			${ECHO} " "
			exit 1
		fi

		# start AiGuard
		${DAEMON} --${GUARD_TYPE}
		if [ $? -ne 0 ]
		then
			# AiGuard failed to start, there is a problem

			${ECHO} " (FAILED)"
			${ECHO} " "
			${ECHO} "error: ${DAEMON} failed"
			${ECHO} "See log files for details."
			${ECHO} " "
			exit 1
		fi

		# give the AiGuard daemons a chance to "get organized"
		sleep 1

		[ -z "$LOCKSUBSYS" ] || touch "$LOCKSUBSYS"

		${ECHO} "."
		;;
	stop)
		${ECHO} -n "Stopping AVIRA: aiguard-${PRODUCT_VARIANT}"

		# get Dazuko device information
		# (if Dazuko is not loaded, AiGuard can't be running)
		getDEV
		if [ ! -z "${DEV}" ]
		then
			# Dazuko is loaded

			# find and send TERM signals to all AiGuard processes
			FOUND=0
			getPROCESSLIST
			for PROC in ${PROCESSLIST}
			do
				FOUND=1
				kill -TERM ${PROC} > /dev/null 2>&1
			done

			# if we there were AiGuard processes, give them a chance to shutdown
			if [ ${FOUND} -eq 1 ]
			then
				sleep 3
			fi

			# all AiGuard processes should now be stopped

			# check if there are any AiGuard processes
			FOUND=0
			getPROCESSLIST
			for PROC in ${PROCESSLIST}
			do
				FOUND=1
			done

			# did we find some?
			if [ ${FOUND} -eq 1 ]
			then
				# there are still processes running? this is a problem

				${ECHO} " (FAILED)"
				${ECHO} " "
				${ECHO} "There may be processes still running."
				${ECHO} " "
				exit 1
			fi
		fi

		[ -z "$LOCKSUBSYS" ] || rm -f "$LOCKSUBSYS"

		${ECHO} "."
		;;
	restart)
		$0 stop
		$0 start
		;;
	status)
		${ECHO} -n "AVIRA Status: aiguard-${PRODUCT_VARIANT} "

		# get Dazuko device information
		getDEV
		if [ -z "${DEV}" ]
		then
			# Dazuko is not loaded

			${ECHO} -n "(not loaded)"
			RC=3
		else
			# Dazuko is loaded

			# count how many AiGuard processes we find
			COUNT=0
			getPROCESSLIST
			for PROC in ${PROCESSLIST}
			do
				COUNT=`expr ${COUNT} + 1`
			done

			# display the results of what we found
			if [ ${COUNT} -ge 1 ]
			then
				${ECHO} -n "(running with ${COUNT} scan daemons)"
				RC=0
			else
				${ECHO} -n "(loaded but no scan daemons)"
				RC=3
			fi
		fi
		${ECHO} "."
		exit ${RC}
		;;
	*)
		${ECHO} "usage: $0 {start|stop|restart|status}"
		exit 1
		;;
esac

exit 0
