#!/usr/bin/python

'''sgfilter - sagator's filer daemon client

(c) 2005-2008 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.
'''

import sys,socket,getopt,shutil
from version import *

SERVER=('127.0.0.1',27)
mail_from='vscan@'+socket.gethostname()
rcpt_to='vscan@'+socket.gethostname()
JUST_EXIT_CODE=False
SAFE=True

try:
  opts,files=getopt.gnu_getopt(sys.argv[1:],'h:p:cx',
    ['help','host=','port=','codes','non-safe'])
except getopt.GetoptError,(msg,opt):
  print "Error:",msg
  sys.exit(1)

for key,value in opts:
  if key=='--help':
    print "SgFilter for SAGATOR %s-%s" % (VERSION,RELEASE)
    print ""
    print "Usage: sgfilter [options...] [filename]"
    print ""
    print "Params: --help           this help"
    print "        --host hostname  sagator's filterd() hostname"
    print "        --port X         sagator's filterd() port number"
    print "        --codes -c       exit code=1 for spam, 0 for clean or error"
    print "        --non-safe -x    disable safe fallback"
    print "        filename         filename to scan (stdin is used, when"
    print "                         no filename is defined)"
    sys.exit(0)
  elif key in ('--host','-h'):
    SERVER=(value,SERVER[1])
  elif key in ('--port','-p'):
    SERVER=(SERVER[0],int(value))
  elif key in ('--codes','-c'):
    JUST_EXIT_CODE=True
  elif key in ('--non-safe','-x'):
    SAFE=False

if files:
  f=open(files[0],'r')
else:
  f=sys.stdin

if __name__ == '__main__':
  try:
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect(SERVER)
    s.sendall('MAIL FROM: %s\r\n' % mail_from)
    s.sendall('RCPT TO: %s\r\n' % rcpt_to)
    # skip bad mailbox firstline
    firstline = f.readline()
    if firstline[:5]=='From ':
      data = f.read()
    else:
      data = firstline+f.read()
      firstline = ''
    s.sendall('DATA %d\r\n' % len(data))
    s.sendall(data)
    f=s.makefile('rw',0)
    status=f.readline()
    if status[:3]=='551': # drop
      sys.exit(0) # return silently
    elif status[:3]=='550': # reject
      if JUST_EXIT_CODE:
        print status.rstrip()
        sys.exit(1)
    elif status[0]!='2': # non clean, temp_fail or unknown
      if not SAFE:
        print status.rstrip()
        sys.exit(64)
    # clean or SAFE or without exit code forcing
    sys.stdout.write(firstline)
    shutil.copyfileobj(f, sys.stdout, 1024*1024)
  except socket.error, err:
    print "ERROR:", err
    sys.exit(65)
