'''
avg module, version 0.5.2

(c) 2003-2004 Jan ONDREJ (SAL) <ondrejj(at)salstar.sk>
                                                                                
 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 2 of the License, or
 (at your option) any later version.

'''

from avlib import *
import socket,re,string

__all__=['avgd']

class avgd(ascanner):
  '''
  avgd realscanner
  
  Usage: avgd([[[params],connto],chroot])

  Where: params is a string which defines command line parameters,
           like -arc, -heur, -rt, ... see man page for avgscan
           By default "-arc -heur -rt" is used now.
         connto is a tuple of host,port of avgd, by default ('localhost',55555)
         chroot is an string in which sagator is running, if avgd
           is not running in this chroot

  This scanners is a realscanner, which can be used to scan
  for viruses. It uses AVGd (a deamonized linux version of AVG7).

  To start AVGd in chroot, move all neccessary files into your chroot,
  and change following line in init.d/avgd from:
    daemon $AVG_HOME/avgscan -d
  to:
    daemon chroot /var/spool/vscan $AVG_HOME/avgscan -d
  or similiar.
  '''
  name='avgd()'
  def __init__(self,params='-arc -rt -heur',connto=('localhost',55555),chroot=''):
      self.params=params
      self.connto=connto
      self.chroot=chroot
  def scanfile(self,files,dir=''):
      level,detected,virlist=0.0,'',[]
      s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
      socket_settimeout(s,120)
      try:
        s.connect(self.connto)
      except socket.error,(ec,es):
        debug.echo(2,"ERROR: avgd(): ",es)
        raise
      f=s.makefile('rw',512)
      while not re.search("^220 ",f.readline()):
        pass
      s.sendall("PARM "+self.params+"\n")
      l=f.readline()
      if not re.search("^200 ",l):
        raise ScannerError,'Protocol error: '+l
      for fn in files:
        s.sendall("SCAN "+self.chroot+fn+'\n')
        l=f.readline()
        debug.echo(4,self.name+": ",l.rstrip())
        if re.search("^200 ",l):
          pass
        elif re.search("^403 ",l):
          virlist.append(fn+': '+l+'\n')
          reg1=re.search("^403 File .* infected: +(Virus identified|Could be infected) +(.*)$",l)
          if reg1:
            if reg1.group(1)[0]=='V':
              level+=1
            else:
              level+=0.9
            if detected=='':
              detected=reg1.group(2).strip()
        else:
          raise ScannerError,l
      s.sendall("QUIT\n")
      l=f.readline()
      if not re.search("^221",l):
        debug.echo(1,"avgd(): AVG returned wrong exit code for QUIT: ",l)
      f.close()
      s.shutdown(2)
      s.close()
      return level,detected,virlist
