'''
Scanner client for sagator

(c) 2006-2016 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 *

__all__ = ['scanc']

class scanc(ascanner):
  '''
  Scanner daemon client.

  This scanner can be used to communicate with sagator's scanner daemon
  (scand() service). It is useful to run some scanners outside of chroot.
  
  Usage: scanc(scanner=None, addr='/tmp/scand.sock', prefix='/tmp/scand',
               timeout=60)
  
  Where: scanner is an scanner to use for recipient signature generator.
           You can leave it empty for many of scanners, but it is required
           for example for usrquota() scanner. It is good to define
           same scanners here as in scand() service.
         add is a string, which defines path to socket for communication
           with scanner daemon.
         prefix is a string, which defines directory and a part of
           filename to store scanned files, by default '/tmp/scand'
         timeout is an integer for socket timeout setting.
           Added in sagator-1.3.

  Example: scanc()
       or: scanc(usrquota('mydomain.sk'))

  New in version 0.8.0.
  '''
  name='scanc()'
  def __init__(self, scanner=None, addr='/tmp/scand.sock',
                     prefix='/tmp/scand', timeout=60):
      self.SCANNER = scanner
      self.addr = addr
      self.prefix = prefix+'/'
      self.hdr = '' #fromhdr()
      self.timeout = timeout
  def rcpt_signature(self,rcpt):
      if self.SCANNER:
        return '%s%s%s' \
          % (self.name[:-1], self.SCANNER.rcpt_signature(rcpt), self.name[-1])
      else:
        return self.name
  def scanbuffer(self, buffer, args={}):
      t = mktemp(self.prefix, '.eml', 'w', 0o600).autorm()
      t.f.write(buffer)
      t.f.close()
      s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
      socket_settimeout(s, self.timeout)
      s.connect(safe.fn(self.addr))
      s.sendall('MAIL_FROM %s\n' % mail.sender)
      for recip in mail.recip:
        s.sendall('RCPT_TO %s\n' % recip)
      s.sendall('SCANFILE %s\n' % t.name)
      f = s.makefile('rw')
      reply = f.readline()
      status = reply.strip('\r\n').split(" ", 1)
      debug.echo(5,"%s: reply status: %s" % (self.name, status))
      virlist = [reply]+f.readlines()
      f.close()
      s.close()
      try:
        return float(status[0]), status[1], virlist
      except IndexError:
        return float(status[0]), b'', virlist
      except ValueError:
        if len(status)>1:
          raise ScannerError(status[1])
      raise ScannerError('Unknonw reply: %s' % reply)
