#! /usr/bin/env python2.7 # -*- coding: utf-8 -*- """ A lookup server that uses threads to handle multiple clients at a time. Called from the ped-interface (forms.py) """ import select import pexpect import socket import sys import re import os import threading import time class Server(object): def __init__(self): self.host = '' self.port = 9000 self.backlog = 5 self.size = 1024 self.server = None self.threads = [] fstdir = "/opt/smi/sme/bin" lo = "/usr/bin/lookup" logfile = "/var/log/lserv.log" f = open(logfile, 'a') fst = fstdir + "/ped-sme.fst" self.lookup = lo + " -flags mbTT -utf8 " + fst #print self.lookup self.look = pexpect.spawn(self.lookup) self.look.logfile = f # Lock for the lookup process self.lock = threading.Lock() def open_socket(self): try: self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Reuse socket in case of server timeout while in TIME_WAIT self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.bind((self.host,self.port)) self.server.listen(5) except socket.error, (value,message): if self.server: self.server.close() print "Could not open socket: " + message sys.exit(1) def run(self): self.open_socket() input = [self.server,sys.stdin] running = 1 while running: inputready,outputready,exceptready = select.select(input,[],[]) for s in inputready: if s == self.server: # handle the server socket c = Client(self.server.accept(),self.look,self.lock) c.start() self.threads.append(c) time.sleep(1) self.server.close() for c in self.threads: c.join() class Client(threading.Thread): def __init__(self,(client,address),look,lock): threading.Thread.__init__(self) self.client = client self.address = address self.size = 1024 self.look=look self.lock=lock self.lookup2cg = " | /usr/local/bin/lookup2cg" # NOTE: Just in case you need to see data from the client only # def clientLog(self, msg): # with open('/var/log/lserv.client.log', 'a') as LOG: # LOG.writelines([msg + '\n']) def run(self): running = 1 while running: data = self.client.recv(self.size) # NOTE: for testing, uncomment. Log is destroyed with each new # client though # self.clientLog(repr(data)) data = data.strip() if not data: self.client.close() running = 0 continue elif data == '\x04': # Client sends ^D, close, rather than waiting for more input # TODO: handle ^C? self.client.close() running = 0 continue data2=data # clean the data for command line c = """;<>*|`&$!#()[]{}:@\"\r""".split() for a in c: data = data.replace(a,'') # Take out non-breaking space. Try to avoid errors. try: data2 = data.decode('utf-8') data2 = data2.replace(unichr(160),"") data = data2.encode('utf8') except UnicodeDecodeError: # If something cannot be decoded, better to quit. self.client.send("error") self.client.close() except Exception, e: #data = data.encode('utf-8') #f.write("Not utf-8: " + data) self.client.send("error") running = 0 continue #data = re.sub(r'[^\wáŋčžšđŧÁŊĐÁŠŦŽČ_- åäöÅÄÖæøÆØ]+', '',data, re.U) # if the data contained only special characters, return the original data. if not data: self.client.send("error") continue # quit with q if ( data.strip() == 'q' or data == 'Q'): self.client.close() running = 0 continue data = data.strip()+ "\n" #f = open('/var/log/lserv.log', 'a') self.lock.acquire() #f.write("input: "+ data) #f.write("\n") self.look.sendline(data) index = self.look.expect(['\r?\n\r?\n','ERROR',pexpect.EOF, pexpect.TIMEOUT]) #If there is an error, then restart the lookup process if index ==1 or index==2 or index==3: try: self.look.read_nonblocking(timeout=1) except: self.client.send("error") self.client.send("error") self.lock.release() continue if index ==0: self.lock.release() result = self.look.before #f.write("analysis for:" + data + " " + result) #f.write("\n") #f.close() # hack for removing the stderr from lookup 0%>>>>>>100% ... result = result.replace('100%','') result = result.replace('0%','') lstring ="" for r in result.splitlines(): res = r.rstrip('>').lstrip('>') if res.rstrip().lstrip(): lstring = lstring + res + "\n" cg_call = "echo \"" + lstring + "\"" + self.lookup2cg #print "jee", cg_call try: anl = os.popen(cg_call).readlines() analyzed = "" for a in anl: analyzed = analyzed + a self.client.send(analyzed) except: self.client.send("error") if __name__ == "__main__": s = Server() s.run() # vim: set ts=4 sw=4 tw=0 syntax=python expandtab: