# Listen on a socket
# on a connect, force md5 authentication based on password for the profile
# on unsuccessful authentication: disconnect, and log attempt
# on successful authentication: log the connection,
#                               create new wrapper object and
#                               proceed to its main loop

# need a thread for each wrapper so we can listen: this is the main loop
# upon creation of a wrapper; register itself with the CLI
#      this allows the CLI to send messages down the pipe from CLI.CLI.output()
from threading import *
import socket
import sys
import os
import traceback

class listener(Thread):
    def __init__(self, cli):
        Thread.__init__(self)
        self.setDaemon(1)
        self.cli = cli
        self.running = 0
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def run(self):
        self.socket.bind(('',50000))
        self.running = 1
        while(self.running != 0):
            # accept incoming stuff and create new socket wrappers
            self.socket.listen(1)
            conn, addr = self.socket.accept()
            if(self.cli != None):
                a = wrapper(self.cli, conn)
                a.start()
            else:
                return


class wrapper(Thread):
    def __init__(self, cli, socket):
        Thread.__init__(self)
        self.cli = cli
        self.setDaemon(1)
        self.socket = socket
        self.running = 0
        self.debug = 0
        # register with CLI
        cli.addSocketWrapper(self)

    def logDebug(self,s):
        self.cli.output(s)

    def sendData(self, s):
        self.socket.send(s)

    def disconnect(self):
        self.cli.removeSocketWrapper(self)
        self.cli = None
        self.socket.close()


    def run(self):
        self.running = 1
        self.debug = 0
        while(self.running):
            try:
                data = self.socket.recv(4096)
                while (data and self.socket):
                    if(self.cli == None):
                        break
                    self.cli.executeCommand(data)
                    data = self.socket.recv(4096)
                    if(self.debug and data):
                        self.logDebug("Recv from sw :> " + data)
            except:
                a,b,c = sys.exc_info()
                if(b[0] == 4):
                    continue
                if(self.debug):
                    self.cli.output("Receive Exception\n")
                    traceback.print_exc()
                    print "a is ", a
                    print "b is ", b
                    print
                if(self.running):
                    self.running = 0
            self.running = 0
        self.socket.close()
        self.cli.removeSocketWrapper(self)
        self.running = 0

