#!/usr/bin/python

'''
sagator's logwatch script
(c) 2003-2005 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,re,os,time

def kilomega(x,v='B'):
    if x>=1024*1024:
      return "%1.4f M%s" % (x/1024.0/1024.0,v)
    elif x>=1024:
      return "%1.4f k%s" % (x/1024.0,v)
    else:
      return "%1.4f %s " % (x,v)

def hodminsec(t):
    return "%d:%02d:%02d" % (t/60/60,t/60%60,t%60)

class a:
  connect=0
  count,bytes=0,0
  time=0
  found={}
  found_bytes={}
  clean,clean_bytes=0,0
  infected,infected_bytes=0,0
  spam,spam_bytes=0,0
  errors=0
  erra={}
  warnings=0
  warna={}

try:
  DATE_RANGE=os.environ['LOGWATCH_DATE_RANGE']
except KeyError:
  DATE_RANGE='today'

# regular expressions
base='^ *([0-9]+): '
reg_conn=re.compile(base+
  'Connection from: ').search
reg_stats=re.compile(base+
  'STATS: ([0-9.]+) seconds, ([0-9]+) bytes, status: (.*)$').search
if DATE_RANGE=='yesterday':
  searchdate=time.strftime("%a %b %e ..:..:.. %Y", 
    time.localtime(time.time()-86400))
elif DATE_RANGE=='today':
  searchdate=time.strftime("%a %b %e ..:..:.. %Y")
elif DATE_RANGE=='all':
  searchdate='... ... .. ..:..:.. ....'
reg_aconn=re.compile(base+'Connection from: ').search
reg_conn=re.compile(base+'Connection from: .* at ('+searchdate+')').search
reg_exit=re.compile(base+'Child exited ... pid,status: .([0-9]*),').search
reg_err=re.compile(base+'([-a-zA-Z_()]*): *(ERROR|WARNING)[: ]*(.*)$').search

pids={}
while True:
  line=sys.stdin.readline()
  # EOF?
  if not line:
    break
  # add a new PID into DB
  rconn=reg_aconn(line)
  if rconn:
    reg1=reg_conn(line)
    if reg1:
      a.connect+=1
      pids[reg1.group(1)]=reg1.group(2)
    else:
      # It is a new connection from this pid, but not for date range
      # If in pids, remove it.
      try:
        del pids[rconn.group(1)]
      except KeyError:
        pass
  # remove PID from DB if exited
  reg2=reg_exit(line)
  if reg2:
    try:
      del pids[reg2.group(2)]
    except:
      pass
  reg=reg_err(line)
  if reg:
    # is this PID in DB?
    if not pids.has_key(reg.group(1)):
      continue
    # is it an ERROR or WARNING?
    if reg.group(3)=="ERROR":
      # error
      a.errors+=1
      try:
        a.erra[reg.group(4)]+=1
      except KeyError:
        a.erra[reg.group(4)]=1
    else:
      # warning
      a.warnings+=1
      try:
        a.warna[reg.group(4)]+=1
      except KeyError:
        a.warna[reg.group(4)]=1
  reg=reg_stats(line)
  if reg:
    # is this PID in DB?
    if not pids.has_key(reg.group(1)):
      continue
    a.count+=1
    a.time+=float(reg.group(2))
    bytes=reg.group(3)
    name=reg.group(4)
    a.bytes+=int(bytes)
    if (len(name)>55) and (name[:4]!='SPAM'):
      # error?
      a.errors+=1
      try:
        a.erra[name]+=1
      except KeyError:
        a.erra[name]=1
    elif name=='CLEAN':
      a.clean+=1
      a.clean_bytes+=int(bytes)
    else:
      if name[:4]=='SPAM':
        a.spam+=1
        a.spam_bytes+=int(bytes)
      else:
        a.infected+=1
        a.infected_bytes+=int(bytes)
      try:
        a.found[name]+=1
        a.found_bytes[name]+=int(bytes)
      except KeyError:
        a.found[name]=1
        a.found_bytes[name]=int(bytes)

#print '\n--------------------- SAGATOR -----------------------\n'

if a.count>0:
  print 'Total:               %6d [       %12s]' % \
    (a.count,kilomega(a.bytes))
  if a.bytes==0: a.bytes=0.00001
  print 'Clean:               %6d [%3d%% = %12s]' % \
    (a.clean,a.clean_bytes*100/a.bytes,kilomega(a.clean_bytes))
  print 'Viruses:             %6d [%3d%% = %12s]' % \
    (a.infected,a.infected_bytes*100/a.bytes,kilomega(a.infected_bytes))
  print 'Spams:               %6d [%3d%% = %12s]' % \
    (a.spam,a.spam_bytes*100/a.bytes,kilomega(a.spam_bytes))
  print 'Consumed time:     %8s' % (hodminsec(a.time))
  print 'Connections:         %6d' % (a.connect)

  keys=a.found.keys()
  if keys:
    keys.sort()
    print ''
    #print '%-55s %6d [%12s]' % \
    #  ('Viruses/spams found:',a.infected+a.spam,kilomega(a.infected_bytes+a.spam_bytes))
    for k in keys:
      print '%6d [%12s]: %s' % (a.found[k],kilomega(a.found_bytes[k]),k)

  if a.errors>0:
    print '\nErrors: %d' % a.errors
    for k,v in a.erra.items():
      print "%5d: %s" % (v,k)
  if a.warnings>0:
    print '\nWarnings: %d' % a.warnings
    for k,v in a.warna.items():
      print "%5d: %s" % (v,k)

#print '\n--------------------- SAGATOR -----------------------\n'
