#! /usr/bin/env python
import os, string, select, syslog
import audit, traceback
import AuditMsg
import subprocess, signal
import glob
from socket import *

HUP=False
def huphandler(signum, frame):
    global HUP
    HUP=True

class audit_dispatcher:
    def __init__(self, server_address):
        self.data = []
        self.outList=[]
        self.auSock=socket(AF_UNIX,SOCK_STREAM)
        if os.path.exists(server_address):
            os.remove(server_address)
        self.auSock.bind(server_address)
        self.auSock.listen(5)
        self.inList=[0, self.auSock]
        
    def add(self, msg):
        self.data.append(msg)
        
    def process(self):
        if len(self.data) > 0:
            msg=self.data.pop(0)
            for s in self.outList:
                try:
                    s.send(msg.binary())
                except IOError,e:
                    syslog.syslog("IOError exception %s" % (e))
                    s.close()
                    self.outList.remove(s)
                except error,e:
                    syslog.syslog("Socket error %s" % (e))
                    s.close()
                    self.outList.remove(s)
            return 0
        else:
            return 500

    def run(self):
        global HUP
        sleep=500
        while True:
            try:
                input,output, err = select.select(self.inList,[], self.outList, sleep)
                for s in input:
                    if s == 0:
                        msg = AuditMsg.AuditMsg()                    
                        if not msg.read_from_fd(0):
                            syslog.syslog("Connection closing")
                            return
                        self.add(msg)
                        sleep=0

                    if s == self.auSock:
                        c,address=self.auSock.accept()
                        self.outList.append(c)

                for s in err:
                    if s in self.outList:
                        s.close()
                        self.outList.remove(s)

                sleep=self.process()

            except select.error, e:
                if e[0] == 4:
                    if HUP:
                        syslog.syslog("HUP signal")
                        HUP=False
                else:
                    syslog.syslog("select exception %s " % e)
                    return

            except TypeError, e:
                syslog.syslog("Type exception %s " % e)
                syslog.syslog(traceback.format_exc())
                return
                
try:
    syslog.openlog("audispd")
    syslog.syslog("starting audispd")
    signal.signal(signal.SIGHUP, huphandler)
    dispatcher=audit_dispatcher("/var/run/audit_events")
    dispatcher.run()

except IOError,e:
    syslog.syslog("IOError exception %s" % e)
    syslog.syslog(traceback.format_exc())

except Exception, e:
    syslog.syslog("Unexpected exception %s " % e)
    syslog.syslog(traceback.format_exc())
   
except:
    syslog.syslog("Caught Exception")
    syslog.syslog(traceback.format_exc())
