#!/bin/sh
#
# File: /usr/sbin/scanmails
#
# This file is part of AMaViS - A Mail Virus Scanner
#             Version : 0.2.0-pre6
#    available at:
#         http://aachalon.de/AMaViS/ 
#
#    Written by Mogens Kjaer, Carlsberg Laboratory, <mk@crc.dk>
#    Modified by Juergen Quade, Softing GmbH, <quade@softing.com>
#    Modified and maintained by Christian Bricart <shiva@aachalon.de>
#
#   Copyright (C) 1996..99 the people mentioned above
#
#   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 1, 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, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#   The software is provided as is. Please bear in mind that we have 
#   done this in our spare time. While it is as accurate as we could 
#   make it there is a reasonable chance that there are mistakes 
#   somewhere in here. If you email us and tell us about them we will 
#   be happy to fix them but we can't take responsibility for your system. 
#   Basically use this at your own risk. 
#
#####################################################################

scanscriptname=`basename $0`

################################################
# Path to DrSolomon Antivirus                  #
#     (if installed)                           #
#                                              #
# "ufindvir" is the name of the first version  #
# "fvsco" is the name of the current version   # 
################################################
ufindvir=
fvsco=

################################################
# Path to NAI AntiVirus (uvscan)               #
#     (if installed)                           #
################################################
uvscan=/usr/bin/uvscan
uvscan_version=4

################################################
# Path to H+BEDV AntiVir                       #
#     (if installed)                           #
################################################
antivir=

################################################
# Path to Sophos Anti Virus (sweep)            #
#      (if installed)                          #
################################################
sophos=

################################################
# KasperskyLab AntiViral Toolkit Pro (AVP)     #
#           (if installed)                     #
################################################
avp=

################################################
# "mailto" indicates the user to whom          #
#       reports are sent to                    #
################################################
mailto=virusalert

################################################
# "virusmailsdir" indicates the path where      #
#       infected files are saved in            #
################################################
virusmailsdir=/var/spool/virus

################################################
# "tmpdir" indicates where the script operates #
#                   in                         #
################################################
tmpdir=/var/tmp/${scanscriptname}$$

################################################
# "usingqmail" is to indicate if system is     #
# Qmail                                        #
################################################
usingqmail=

################################################
# "var_log" indicates the path where statistic #
# output is logged to                          #
# - if "do_log" is set to "yes"                #
################################################
var_log=/var/log
do_log=yes
do_syslog=yes
syslog_level=mail.info

################################################
# when "x_header" is set to "yes" then an      #
# informative "X-" line will be added to       #
# the mail when delivered                      #
# Note:                                        #
# You may use "X-Message:" here, which         #
# currently is (mis)used by MS-Outlook         #
# clients. Give it a try to see what happens.  #
# You might also want to change it to          #
# "X-Info:" or "X-Virus-Scanner:"              #
#       Mind the preceding "X-"                #
#                         (see also: RFC822)   #
################################################
x_header=yes
X_Header_String="X-AntiVirus: scanned for viruses by AMaViS 0.2.0-pre6 (http://aachalon.de/AMaViS/)"

# alternative entry:
# X_Header_String="X-Message: scanned for viruses by AMaViS 0.2.0-pre6 (http://aachalon.de/AMaViS/)"

################################################
#       paths to required program files        #
#    these are basicly set at install time     #
################################################
test=/usr/bin/test
head=/usr/bin/head
fgrep=/bin/fgrep
grep=/bin/grep
grep_quiet_args=-q
find=/usr/bin/find
sed=/bin/sed
file=/usr/bin/file
logger=/usr/bin/logger
tar=/bin/gtar
securetar=/usr/bin/securetar
gunzip=/bin/gunzip
bunzip=/usr/bin/bunzip2
uncompress=/usr/bin/uncompress
uudecode=/usr/bin/uudecode
unzip=/usr/bin/unzip
zipsecure=/usr/bin/zipsecure
metamail=/usr/bin/metamail
mail=/bin/mail
uncompress=/usr/bin/uncompress
xbin=
unrar=
unarj=
lha=/usr/bin/lha
zoo=
arc=
unfreeze=

procmail=/usr/bin/procmail
formail=/usr/bin/formail

if [ "x${usingqmail}" = "x" ]; then
    deliver=/usr/bin/procmail
else
    deliver=${scanscriptname}-real
fi

if [ "x${usingqmail}" != "x" ] ; then
    if [ "${scanscriptname}" = "qmail-remote" ] ; then
       SENDER="$2"
       RECEIPIENT="$3"
    elif [ "${scanscriptname}" = "qmail-local" ] ; then
       # Sometims qmail-local is called with -- as the first arg
       # this screws up the arg count so shift everything
       if [ "$1" = "--" ] ; then
           RECEIPIENT="$4"@"$7"
           SENDER="$8"
       else
           RECEIPIENT="$3"@"$6"
           SENDER="$7"
       fi
    else
       SENDER="$1"
       RECEIPIENT="$2"
    fi
else
    SENDER="$2"
    RECEIPIENT="$7"
fi


################################################
#                main program                  #
#               --------------                 #
#    - no changes beyond this line should be   #
#                necessary                     #
################################################

log_error()
{
  # Note: the following line seems to be 'bash' specific
  # try to comment it out if it makes some trouble on non
  # Linux systems...
  local _msg
  (
   if read -r _msg ; then
    if [ "x${do_syslog}" = "xyes" ] ; then
     ${logger} -i -p ${syslog_level} -t ${scanscriptname} ${_msg}
    fi
    echo "${_msg}" >> ${tmpdir}/logfile
    log_error
   fi
  )
}

###############################################################
# Chris McDonough informed us, that it is possible to execute #
# programs by sending an email, wich contains a virus and has #
# as return address something like:                           #
#        `/sbin/reboot`@enemy.net                             # 
# or                                                          #
#        $(/sbin/reboot)@enemy.net                            #
# The execution of the command (/sbin/reboot) is done by the  #
# "mail" program. Therefore we parse the arguments in order   #
# to substitute those characters to nothing                   #
# This exploit is also outlined on BugTraq list               #
#    http://www.securityfocus.com/                            #
###############################################################

# substitute all "`","$(",")" to nothing
# first patch has been specific to Bash2 .. 
#   receiver=${RECEIPIENT//\`/}
#   receiver=${receiver//\$\(/}
#   receiver=${receiver//\)/}
#   sender=${SENDER//\`/}
#   sender=${sender//\$\(/}
#   sender=${sender//\)/}
#
# this should work on all systems, however needs "sed" ...
receiver=`echo ${RECEIPIENT} | ${sed} -e "s/[\\\`\\\\\$\(\)]//g"`
sender=`echo ${SENDER} | ${sed} -e "s/[\\\`\\\\\$\(\)]//g"`

if [ "$sender" != "$2" -o "$receiver" != "$7" ] ; then
       cat <<EOF | ${mail} -s "AMaViS Intrusion???" ${mailto}
       
############################################################
   $7 or $2 is not a valid Email address
   (changed to $receiver and $sender)!
############################################################

EOF
fi

TERM=vt100
export TERM      # required for DrSolomon

if [ "x${do_syslog}" = "xyes" ]
then 
  ${logger} -i -p ${syslog_level} -t ${scanscriptname} execution started
fi

## I know there is mktemp(1) to securely create a file/directory
## But: switch "-d" (create directory) is not supported on all
## systems .. anyone know why ?
mkdir -p ${tmpdir}

## when using a post 8.8.8 sendmail, subprocesses are run under receipient
## UID .. so 'chown' can not be done .. should be obsolete after all 
## when using securetar and zipsecure ...
## chown nobody ${tmpdir}
chmod 700 ${tmpdir}
cat >${tmpdir}/receivedmail
mkdir ${tmpdir}/unpacked

## commented out - see above...
# chown nobody ${tmpdir}/unpacked

METAMAIL_TMPDIR=${tmpdir}/unpacked
export METAMAIL_TMPDIR

echo xxxxxxxxxxxxxxxxxx`date`xxxxxxxxxxxxxxxxxxxxxxx >${tmpdir}/logfile
echo ${scanscriptname} called $* >>${tmpdir}/logfile
echo FROM: ${sender} >>/${tmpdir}/logfile
echo TO: ${receiver} >>/${tmpdir}/logfile

## first check for "metamail" ... some people have not had this installed
## and complained about empty directories ..

if [ "x${metamail}" != "x" ] && [ -x ${metamail} ]
then
  ${metamail} -r -q -x -w ${tmpdir}/receivedmail > /dev/null 2>&1
else
  echo "WARNING! Could not decode mailfile (no metamail)" | log_error
  echo "--> neither decode/detach, nor scanning done !" | log_error
fi

###############################################
# for each file in unpacked, unpack zip, tar, #
#      and binhex archives recursively:       #
###############################################
cd ${tmpdir}/unpacked
doneit=0
maxlevel=0

while ${test} ${doneit} -eq 0 -a ${maxlevel} -lt 20
do
  echo maxlevel: ${maxlevel} >>${tmpdir}/logfile
  doneit=1
  for E in `${find} . -print | grep -v "^\.$"`
  do

################### test for Self-extracting files ##################
    ${file} $E | ${fgrep} ${grep_quiet_args} "executable (EXE)"
    if ${test} $? -eq 0
    then
      ## self extracting PKZip archive ?
      ${fgrep} ${grep_quiet_args} "PK" $E
      if ${test} $? -eq 0
      then
        if [ "x${unzip}" != "x" ] && [ -x ${unzip} ]
        then
          if [ "x${zipsecure}" != "x" ] && [ -x ${zipsecure} ]
          then
            echo Unziping self extracting $E >> ${tmpdir}/logfile
            pid=$$
            cat $E | ${zipsecure} > secure.${pid}.zip
            ${unzip} secure.${pid}.zip >>${tmpdir}/logfile 2>&1
            if ${test} $? -eq 0
            then
              rm $E
            fi
            rm secure.${pid}.zip
          else
            echo "WARNING! unZIPing not secure (no zipsecure)" | log_error
            echo "--> no unZIPing done !" | log_error
          fi
        else
          echo "WARNING! Don't know how to handle $E (no unzip)" | log_error
        fi
        doneit=0
      fi
      ## self extracting RAR archive ?
      ${fgrep} ${grep_quiet_args} "RAR" $E
      if ${test} $? -eq 0
      then
        if [ "x${unrar}" != "x" ] && [ -x ${unrar} ]
        then
          echo UnRARing self extracting $E >> ${tmpdir}/logfile
          ${unrar} e -y $E
          if ${test} $? -eq 0
          then
            rm $E
          fi
        else
          echo "WARNING! Don't know how to handle $E (no unrar)" | log_error
        fi
        doneit=0
      fi
      ## self extracting LHA archive ?
      ${fgrep} ${grep_quiet_args} "LHA" $E
      if ${test} $? -eq 0
      then
        if [ "x${lha}" != "x" ] && [ -x ${lha} ]
        then
          echo Lharcing self extractin $E >> ${tmpdir}/logfile
          ${lha} efq $E
          if ${test} $? -eq 0
          then
            rm $E
          fi
        else
          echo "WARNING! Don't know how to handle $E (no unlha)" | log_error
        fi
        doneit=0
      fi
    fi
	  
#################### test for zip file ##############################

    ${file} $E | ${fgrep} ${grep_quiet_args} "Zip archive data"
    if ${test} $? -eq 0
    then
      if [ "x${unzip}" != "x" ] && [ -x ${unzip} ]
      then
       if [ "x${zipsecure}" != "x" ] && [ -x ${zipsecure} ]
       then
        echo Unziping $E >> ${tmpdir}/logfile
        pid=$$      
        cat $E | ${zipsecure} > secure.${pid}.zip
        ${unzip} secure.${pid}.zip >>${tmpdir}/logfile 2>&1
        rm $E secure.${pid}.zip
       else
         echo "WARNING! unZIPing not secure (no zipsecure)" | log_error
         echo "--> no unZIPing done !" | log_error
       fi
      else
        echo "WARNING! Don't know how to handle $E (no unzip)" | log_error
      fi
      doneit=0
    fi

######################### test for tar archive ######################

    ${file} $E | ${fgrep} ${grep_quiet_args} "tar archive"
    if ${test} $? -eq 0
    then
     if [ "x${tar}" != "x" ] && [ -x ${tar} ]
     then
      if [ "x${securetar}" != "x" ] && [ -x ${securetar} ]
      then
        echo Untaring $E >> ${tmpdir}/logfile
        cat $E | ${securetar} -q | ${tar} xvf - >>${tmpdir}/logfile 2>&1
        rm $E
      else
        echo "WARNING! unTARing not secure (no securetar)" | log_error
        echo "--> no unTARing done !" | log_error
      fi        
     else
      echo "WARNING! Don't know how to handle $E (no tar)" | log_error
     fi
     doneit=0
    fi

######################## test for compressed file ###################

    ${file} $E | ${fgrep} ${grep_quiet_args} "compress'd"
    if ${test} $? -eq 0
    then
     if [ "x${uncompress}" != "x" ] && [ -x ${uncompress} ]
     then
      echo Uncompressing $E: move to compr.${maxlevel}.Z first >> ${tmpdir}/logfile
      mv $E compr.${maxlevel}.Z
      ${uncompress} compr.${maxlevel}.Z
     else
      echo "WARNING! Don't know how to handle $E (no uncompress)" | log_error
     fi
     doneit=0
    fi

###################### test for gziped file #########################

    ${file} $E | ${fgrep} ${grep_quiet_args} "gzip compressed data"
    if ${test} $? -eq 0
    then
     if [ "x${gunzip}" != "x" ] && [ -x ${gunzip} ]
     then
      echo Un-gzip-ing $E: move to gzip.${maxlevel}.gz first >> ${tmpdir}/logfile
      mv $E gzip.${maxlevel}.gz
      ${gunzip} gzip.${maxlevel}.gz
     else
      echo "WARNING! Don't know how to handle $E (no gunzip)" | log_error
     fi
     doneit=0
    fi

###################### test for bziped file #########################

    ${file} $E | ${fgrep} ${grep_quiet_args} -E "bzip2* compressed"
    if ${test} $? -eq 0
    then
      if [ "x${bunzip}" != "x" ] && [ -x ${bunzip} ]
      then
        echo Un-bzip-ping $E: move to bzip.${maxlevel}.bz2 first >> ${tmpdir}/logfile
	mv $E bzip.${maxlevel}.bz2
	${bunzip} bzip.${maxlevel}.bz2
      else
        echo "WARNING! Don't know how to handle $E (no bunzip2)" | log_error
      fi
      doneit=0
    fi

###################### test for RAR compressed file #########################

    ${file} $E | ${fgrep} ${grep_quiet_args} "RAR"
    if ${test} $? -eq 0
    then
      if [ "x${unrar}" != "x" ] && [ -x ${unrar} ]
      then
        echo UnRARing $E >> ${tmpdir}/logfile
        ${unrar} -e -y $E
      else
        echo "WARNING! Don't know how to handle $E (no unrar)" | log_error
      fi
      doneit=0
    fi

######################### test for arj archive ######################

    ${file} $E | ${fgrep} ${grep_quiet_args} "ARJ"
    if ${test} $? -eq 0
    then
      if [ "x${unarj}" != "x" ] && [ -x ${unarj} ]
      then
        echo UnARJing $E >> ${tmpdir}/logfile
        ${unarj} e $E
      else
        echo "WARNING! Don't know how to handle $E (no unarj)" | log_error
      fi
      doneit=0
    fi

######################### test for lha archive ######################

    ${file} $E | ${fgrep} ${grep_quiet_args} -i "LHA"
    if ${test} $? -eq 0
    then
      if [ "x${lha}" != "x" ] && [ -x ${lha} ]
      then
        echo UnLHArcing $E >> ${tmpdir}/logfile
        ${lha} e -fq $E
      else
        echo "WARNING! Don't know how to handle $E (no lha)" | log_error
      fi
      doneit=0
    fi

###################### test for ZOO compressed file #################

    ${file} $E | ${fgrep} ${grep_quiet_args} "Zoo"
    if ${test} $? -eq 0
    then
      if [ "x${zoo}" != "x" ] && [ -x ${zoo} ]
      then
        echo UnZOOing $E >> ${tmpdir}/logfile
        ${zoo} -extract  $E
        rm $E
      else
        echo "WARNING! Don't know how to handle $E (no zoo)" | log_error
      fi
      doneit=0
    fi

###################### test for arc compressed file #################

    ${file} $E | ${fgrep} ${grep_quiet_args} "ARC"
    if ${test} $? -eq 0
    then
      if [ "x${arc}" != "x" ] && [ -x ${arc} ]
      then
        echo UnARCing $E >> ${tmpdir}/logfile
        ${arc} eo  $E
        rm $E
      else
        echo "WARNING! Don't know how to handle $E (no arc)" | log_error
      fi
      doneit=0
    fi

###################### test for frozen compressed file #######################
								           
    ${file} $E | ${fgrep} ${grep_quiet_args} "frozen"
    if ${test} $? -eq 0
    then
      if [ "x${unfreeze}" != "x" ] && [ -x ${unfreeze} ]
      then
        echo Unfreezing $E >> ${tmpdir}/logfile
        ${unfreeze}  $E
      else
        echo "WARNING! Don't know how to handle $E (no freeze)" | log_error
      fi
      doneit=0
    fi

###################### test for binhex file #########################

    ${head} -4 $E | ${fgrep} ${grep_quiet_args} "(This file must be converted with BinHex 4.0)"
    if ${test} $? -eq 0
    then
      if [ "x${xbin}" != "x" ] && [ -x ${xbin} ]
      then
        echo Unpacking binhex file $E >> ${tmpdir}/logfile
        ${xbin} $E
        rm $E $E.info $E.rsrc
        mv $E.data $E
      else
        echo "WARNING! Don't know how to handle $E (no xbin)" | log_error
      fi
      doneit=0
    fi

################### test for uuencoded file #########################

    ${head} -n 1 $E | ${grep} ${grep_quiet_args} "begin [0-7][0-7][0-7]"
    if ${test} $? -eq 0
    then
      if [ "x${uudecode}" != "x" ] && [ -x ${uudecode} ]
      then
        echo Unpacking uuencoded file $E >> ${tmpdir}/logfile
        ${uudecode} --output-file=uudecode.${maxlevel} $E
        rm $E
      else
        echo "WARNING! Don't know how to handle $E (no uudecode)" | log_error
      fi
      doneit=0
    fi
  done
  maxlevel=`expr ${maxlevel} + 1`
done

echo Contents of ${tmpdir}/unpacked >> ${tmpdir}/logfile
ls -laR ${tmpdir}/unpacked >> ${tmpdir}/logfile

####################### done un-attaching ###########################

################## now actually scan extracts #######################

##########################  H+BEDV AntiVir ##########################

if [ "x${antivir}" != "x" ]
then 
  if [ "x${antivir}" != "x" ] && [ -x ${antivir} ]
  then
#   Scan all files recursively and append output + error msgs to logfile.
#   Do not redirect stdout to logfile since some ctrl characters are emitted.
#   Here stderr is redirected for testing purposes - but leaving it as is 
#   may not hurt anyway.  
   ${antivir} \* -s -ra -rf${tmpdir}/logfile ${tmpdir}/unpacked >/dev/null 2>> ${tmpdir}/logfile
    scanstatus0=$?
  else
    scanstatus0=0
  fi
else
  scanstatus0=0
fi

##########################  McAfee ##################################

if [ "x${uvscan}" != "x" ]
then 
  if [ "x${uvscan}" != "x" ] && [ -x ${uvscan} ]
  then
    if [ "x${uvscan_version}" = "x3" ]
    then
      ${uvscan} --recursive --summary --verbose ${tmpdir}/unpacked >> ${tmpdir}/logfile 2>&1
      scanstatus1=$?
      if [ ${scanstatus1} -eq 139 ]
      then
        echo "WARNING! it seems that ${uvscan} crashed while scanning for" | log_error
	echo "         viruses in ${tmpdir}/unpacked" | log_error
	echo "         139 is an unusual return value for uvscan" | log_error
	echo "         try to upgrade to uvscan 4.0.3 or higher" | log_error
      fi	
      scanstatus5=0
    else           ## Version 4.x
      ${uvscan} --secure -rv --summary ${tmpdir}/unpacked/ >> ${tmpdir}/logfile 2>&1
      scanstatus5=$?
      scanstatus1=0
    fi  
  else
    scanstatus1=0
    scanstatus5=0
  fi
else
  scanstatus1=0
  scanstatus5=0
fi

######################### old version of DrSolomon ##################

if [ "x${ufindvir}" != "x" ]
then 
  if [ "x${ufindvir}" != "x" ] && [ -x ${ufindvir} ] 
  then
    ${ufindvir} -doallfiles ${tmpdir}/unpacked >> ${tmpdir}/logfile 2>&1
    scanstatus2=$?
  else
    scanstatus2=0
  fi
else
  scanstatus2=0
fi

####################### new version of DrSolomon ####################

if [ "x${fvsco}" != "x" ]
then 
  if [ "x${fvsco}" != "x" ] && [ -x ${fvsco} ] 
  then
    ${fvsco} -autoexit -doallfiles ${tmpdir}/unpacked >> ${tmpdir}/logfile 2>&1
    scanstatus3=$?
  else
    scanstatus3=0
  fi
else
  scanstatus3=0
fi

####################### Sophos Anti Virus ####################
if [ "x${sophos}" != "x" ]
then 
  if [ "x${sophos}" != "x" ] && [ -x ${sophos} ] 
  then
    ${sophos} -nb -f -all -rec -ss -sc ${tmpdir}/unpacked >> ${tmpdir}/logfile 2>&1
    scanstatus4=$?
  else
    scanstatus4=0
  fi
else
  scanstatus4=0
fi

#####################  KasperskyLab AVP ####################
if [ "x${avp}" != "x" ]
 then
 if [ "x${avp}" != "x" ] && [ -x ${avp}]
  then
    # first go to AVP Dir (if I don't do it, AVP have segmentation fault
    #                      returncode:137)
    cd `dirname ${avp}`
    # AVP call without unpack, bootsect and other dos specific
    ${avp} /* /M /P /B /A path ${tmpdir}/unpacked >> ${tmpdir}/logfile 2>&1
    scanstatus6=$?
  else
    scanstatus6=0
  fi
else
 scanstatus6=0
fi
# return to working path
cd ${tmpdir}/unpacked
 
echo "H+BEDV AntiVir scanstatus0 is: ${scanstatus0}" >> ${tmpdir}/logfile
echo "Mcafee scanstatus1 is: ${scanstatus1}" >> ${tmpdir}/logfile
echo "Dr. Solomon (old) scanstatus2 is: ${scanstatus2}" >> ${tmpdir}/logfile
echo "Dr. Solomon (new) scanstatus3 is: ${scanstatus3}" >> ${tmpdir}/logfile
echo "Sophos Sweep scanstatus4 is: ${scanstatus4}" >> ${tmpdir}/logfile
echo "NAI Virus Scan 4.x scanstatus5 is: ${scanstatus5}" >> ${tmpdir}/logfile
echo "KasperskyLab AVP scanstatus6 is: ${scanstatus6}" >> ${tmpdir}/logfile
echo "" >> ${tmpdir}/logfile

# -----------------------------------------------------------------------
# NAI VirusScan (uvscan) return codes (${scanstatus1}):
# -----------------------------------------------------------------------
# as of version 3.x documentation "uvscan (1)":
# - - - - - - - - - - - - - - - - - - - - - - - 
#
#   0  Scan succeeded, no viruses found.
#   1  Scan succeeded, one or more infections found.
#   3  Scan  succeeded,  one  or  more  infections  found,
#      cleaning  attempted  without error.  Please see the
#      note about cleaning that  follows  (section  header
#      CLEANING).
#      The  following are normally non-fatal errors.  Uvscan only
#      exits on encountering one of  these  if  exit-on-error  is
#      set.
#
#   128  Error stating file.
#   129  Wrong file type error.
#   130  Child forced to exit.
#   131  Child reported an error.
#   132  Child exited for unknown reason.
#   133  Directory access error.
#   134  Path name too long.
#   135  Input buffer allocation error.
#
#  These are all fatal errors.  Uvscan will exit immediately.
#  These usually indicate a system  error  (possibly  due  to
#  lack of resources like memory) or an internal problem that
#  prevents Uvscan from operating properly.
#
#   192  Abstract IO structure initialization failure.
#   193  Global engine initialization failure.
#   194  Engine instance initialization failure.
#   195  Error setting compression flag.
#   196  Error reading virus list.
#   197  Error opening input list.
#   198  Queue creation error.
#   199  Fork error.
#
# -----------------------------------------------------------------------
# NAI VirusScan (uvscan) return codes (${scanstatus5}):
# -----------------------------------------------------------------------
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# as of version 4.x documentation "uvscan.pdf" or "unix403.pdf":
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#    0  No errors occured; no viruses were found.
#    2  Driver integrity check failed.
#    6  A general problem.
#    8  Could not find a driver.
#   10  A virus was found in memory.
#   13  One or more viruses or hostile objects were found.
#   15  VirusScan self-check failed; it may be infected or damaged.
#  102  User quit via ESC-X, ^C or Exit button.
#
#  Exit code 102 occurs where the scan encounters an unespected error, such as
#  denied access or memory shortage. On these occasions, the scan exits
#  immediately and does not finish the scan.
#


# -----------------------------------------------------------------------
# Sophos Sweep Return Codes (${scanstatus4}) : 
# -----------------------------------------------------------------------
# Bernhard Nowotny <nowotny@sigma-c.de> writes:
# Error codes returned by SWEEP (thanks to christian.weber@sophos.com):
#  SWEEP returns error codes if there is an error or if a virus is found
#  SWEEP returns:
#    0  If no errors are encountered and no viruses are found
#    1  If the user interrupts the execution by pressing ESC
#    2  If some error preventing further execution is discovered, or if
#       compressed files have been found when using the -WC command line 
#       qualifier
#    3  If viruses or virus fragments are discovered
#
#  A different set of error codes will be returned if SWEEP is run with the 
#  -eec command line qualifier.
#    0  If no errors are encountered and no viruses are found
#    8  If survivable errors have occured
#   12  If compressed files have been found and decompressed
#   16  If compressed files have been found and not decompressed
#   20  If viruses have been found and disinfected
#   24  If viruses have been found and not disinfected
#   28  If viruses have been found in memory
#   32  If there has been an integrity check failure
#   36  If unsurvivable errors have occured
#   40  If execution has been interrupted

if ${test} \
   ${scanstatus0} -eq 1 \
   -o ${scanstatus1} -eq 1 \
   -o ${scanstatus1} -eq 3 \
   -o ${scanstatus2} -ne 0 \
   -o ${scanstatus3} -ne 0 \
   -o ${scanstatus4} -eq 3 \
   -o ${scanstatus5} -eq 13 \
   -o ${scanstatus5} -eq 10 \
   -o ${scanstatus6} -eq 4
then


############ A virus was found: Move the mail. ######################

  echo Virus FOUND Sent notification to ${mailto} >> ${tmpdir}/logfile
  mkdir -p ${virusmailsdir}
  mv ${tmpdir}/receivedmail ${virusmailsdir}/virus$$
  chmod 400 ${virusmailsdir}/virus$$
  echo The attached mail has been found to contain a virus >${tmpdir}/virusmail
  echo Originally $0 "$@" >>${tmpdir}/virusmail
  echo The mail has been stored as ${virusmailsdir}/virus$$ >> ${tmpdir}/virusmail
  mkdir -p ${var_log}/${scanscriptname}
  cat ${tmpdir}/logfile >>${var_log}/${scanscriptname}/logfile
  cat ${tmpdir}/virusmail ${tmpdir}/logfile | ${mail} -s "FOUND VIRUS IN MAIL $*" ${mailto}

################### send a mail back to sender ######################

cat <<EOF| ${mail} -s "VIRUS IN YOUR MAIL TO ${receiver}" ${sender}

                   V I R U S  A L E R T

  Our viruschecker found a VIRUS in your email to "${receiver}".
           We stopped delivery of this email!

    Now it is on you to check your system for viruses           

  For further information about this viruschecker see:
               http://aachalon.de/AMaViS/
        AMaViS - A Mail Virus Scanner, licenced GPL

EOF

if [ "${scanscriptname}" != "qmail-remote" ] ; then
############### send a mail to the addressee ########################

cat <<EOF| ${mail} -s "VIRUS IN A MAIL FOR YOU FROM ${sender}" ${receiver}

                   V I R U S  A L E R T

  Our viruschecker found a VIRUS in a mail from 
     "${sender}"
  to you.
  
  Delivery of the email was stopped!
  
  Please contact your system administrator for details

EOF
fi

if [ "x${usingqmail}" != "x" ]; then
    # Stop all other delivery mechanisms
    cd /var/tmp && rm -rf ${tmpdir} ;
    if [ "${scanscriptname}" = "scanmails" ] ; then
       # Assume we were called by qmail-local
       exit 99 ;
    else
       if [ "${scanscriptname}" = "qmail-remote" ] ; then
           echo "Message was found to contain virus."
       fi
       exit 0 ;
    fi
fi

##################### No virus, send as usual #######################

else
  echo No virus found - good >> ${tmpdir}/logfile
  if [ "x${deliver}" != "x" ] && [ -x ${deliver} ] ; then
    if [ "x$x_header" = "xyes" ] && [ "x${formail}" != "x" ] && [ -x ${formail} ] ; then
      if [ "x${usingqmail}" != "x" ]; then
        # If invoked as anything other than "scanmails", invoke the real
	# program else fall thru to exit
	if [ "${scanscriptname}" != "scanmails" ] ; then
	  cat ${tmpdir}/receivedmail |\
	    ${formail} -f \
	                -A "${X_Header_String}" \
	    |  ${scanscriptname}-real "$@"
	fi    
      else    
        cat ${tmpdir}/receivedmail |\
            ${formail} -f \
                       -A "${X_Header_String}" \
        | ${deliver} "$@"
      fi
    else 
      if [ "x${usingqmail}" != "x" ]; then
        # If invoked as anything other than "scanmails", invoke the real
	# program else fall thru to exit
	if [ "${scanscriptname}" != "scanmails" ] ; then
	  ${scanscriptname}-real "$@" < ${tmpdir}/receivedmail
	fi  
      else  
        ${deliver} "$@" <${tmpdir}/receivedmail
      fi	
    fi 
  else
    pid=$$
    echo "WARNING! No local delivery program available." | log_error
    echo "ABORT! dumping mail to /var/tmp/dead.letter.${pid}" | log_error
    # simply copy mail should be enough ..
    cp ${tmpdir}/receivedmail /var/tmp/dead.letter.${pid}
    # chmod r/o to user
    chmod 0600 /var/tmp/dead.letter.${pid}
  fi

  if [ "x${do_log}" = "xyes" ]
  then
    mkdir -p ${var_log}/${scanscriptname}
    cat ${tmpdir}/logfile >> ${var_log}/${scanscriptname}/logfile
  fi
fi

############################# clean up ##############################
cd /var/tmp
rm -rf ${tmpdir}

if [ "x${do_syslog}" = "xyes" ]
then
  ${logger} -i -p ${syslog_level} -t ${scanscriptname} terminating
fi
  
# set exit code for Qmail
exit 0
