def __init__(self, clientSocket, xmlHandler, isMain): """ Initialize a client handler. @param clientSocket Socket to communicate with a client with. @param xmlHandler XML Database object. @param isMain Set to True if this server runs as the main server, otherwise False. """ self.clientSocket = clientSocket; self.xmlHandler = xmlHandler; self.isMain = isMain; # Let other tasklets go first. #schedule(); # Talk with our client. try: self.handle(); except socket.error, e: # Socket error occurred. Log.logPrint("Socket error while handling client: %s" % str(e), "WOWd.log");
def handle(self): """ Interpret incoming packets. """ # Receive up to 512 bytes of data. data = self.clientSocket.recv(512); data = data.rstrip(); if data == "": Log.logPrint("Client closed socket before we could handle him.", "WOWd.log"); return; print "Received",data; # Retrieve the command. input = [ arr.strip() for arr in data.split(" ") ]; command = input[0].upper().replace(":", ""); try: input[1] = data[data.find(" "):]; except: pass; # Find and handle the command. if command == "QRY": # Incoming query. resultList = self.xmlHandler.query(input[1]); for line in resultList: self.printLine(line); stackless.tasklet(Log.recordHit)(); elif command == "AQRY": # Incoming administration query. resultList = self.xmlHandler.query(input[1], True); for line in resultList: self.printLine(line); stackless.tasklet(Log.recordHit)(); elif command == "ADD": # Incoming addition to the database. if self.isMain: # Attempt to add the record. result = self.xmlHandler.add(input[1]); if result: self.printLine("Successfully added."); self.triggerDistribute(); stackless.tasklet(Log.recordHit)("ADD"); else: self.printLine("ERROR: Record already exists."); else: self.printLine("Only the primary server can change records."); elif command == "UPD": # Incoming update to a record. if self.isMain: data = [ arr.strip() for arr in input[1].split('|') ]; record = self.xmlHandler.createRecord(data, True); result = self.xmlHandler.update(record.getID(), record); if result: self.printLine("OK"); self.triggerDistribute(); stackless.tasklet(Log.recordHit)("UPD"); else: self.printLine("Target not found."); else: self.printLine("Only the primary server can change records."); elif command == "DEL": # Delete a record. if self.isMain: result = self.xmlHandler.delete(input[1]); if result: self.printLine("OK"); self.triggerDistribute(); stackless.tasklet(Log.recordHit)("DEL"); else: self.printLine("ERROR: Record doesn't exist!"); else: self.printLine("Only the primary server can change records."); elif command == "DEPTLIST": # Return a list of departments. result = self.xmlHandler.getDepartments(); for department in result: self.printLine(department); elif command == "DEPTADD": # Add a department. if self.isMain: result = self.xmlHandler.addDepartment(input[1]); if not result: self.printLine("ERROR: That department already exists!"); else: self.printLine("Department successfully added."); else: self.printLine("This server cannot modify records, try a different one."); elif command == "DEPTUPD": # Update a department. if self.isMain: chachachachanges = input[1].split("|"); result = self.xmlHandler.modifyDepartment(chachachachanges[0], chachachachanges[1]); if not result: self.printLine("ERROR: That department already exists!"); else: self.printLine("Department successfully updated."); else: self.printLine("This server cannot modify records, try a different one."); elif command == "DEPTDEL": # Remove a department. if self.isMain: result = self.xmlHandler.deleteDepartment(input[1].strip()); if not result: self.printLine("ERROR: That department doesn't exist!"); else: self.printLine("Department successfully deleted."); else: self.printLine("This server cannot delete records, try a different one."); elif command == "PING": # Just ping it, fox! self.printLine("PONG"); elif command == "HIT": queries = self.xmlHandler.getHits("QRY"); self.printLine(queries); elif command == "HITALL": hits = self.xmlHandler.getHits("ALL"); for arr in hits: line = "%s %s" % (arr[0], arr[1]); self.printLine(line); elif command == "MAIN": if self.isMain: self.printLine("1"); else: self.printLine("0"); elif command == "UHIT": queries = self.xmlHandler.getHits("UPD"); self.printLine(queries); elif command == "AHIT": queries = self.xmlHandler.getHits("ADD"); self.printLine(queries); elif command == "DHIT": queries = self.xmlHandler.getHits("DEL"); self.printLine(queries); elif command == "MAIL": # Forward a mail message to the IT department. mail = input[1].split("|"); mailer = MailMessage(mail[0], mail[1], mail[2], mail[3], "Feedback (" + mail[2] + ")"); if not mailer.mail(): self.printLine("An error occurred while trying to send your mail. Try again later."); line = "A feedback e-mail failed from %s (%s)." % (mail[0], mail[1]); logPrint(line); else: self.printLine("Your message was sent successfully."); line = "A feedback e-mail was sent from %s (%s)." % (mail[0], mail[1]); logPrint(line); elif command == "VER": # Version of the WOW client. self.printLine(self.xmlHandler.version); elif command == "SETVER": # Set the version of the WOW client. if self.isMain: self.xmlHandler.version = input[1]; self.printLine("Version set."); else: self.printLine("Not main server."); elif command.startswith("GETFILE"): # Retrieve a file logPrint("Main server is sending the database file..."); size = int(data.split("\n")[1]); data = self.getfile(size); # Now get sha1sum and check it against the server. sum = self.xmlHandler.checksum(data); self.printLine(sum); response = self.clientSocket.recv(8).strip(); doLoad = True; if response == "NO": # File transfer failed. Try one more time. data = self.getfile(size); sum = self.xmlHandler.checksum(data); if sum != response: # Two file transfers failed in a row. # This server will e-mail the IT staff with an error. # Until then, hold existing data in memory. doLoad = False; errorMessage = "An error occurred during a file transfer from the main server to this one. "; errorMessage += "The checksum did not match on two attempts. "; errorMessage += "Please check the main server and other servers."; try: errorMail = MailMessage(self.socketModule.gethostname(), self.socketModule.gethostbyname(self.socketModule.gethostname()), "ERROR", errorMessage, "SERVER ERROR"); if not errorMail.mail(): # The checksum failed and the mailer failed. logPrint("File transfer failed and mail notification failed."); except self.socketModule.error, e: logPrint("Attempted to mail error notification but failed with error: %s" % (str(e))); if doLoad: logPrint("Received new file from main. Checksum: %s" % (sum)); f = open(self.xmlHandler.getDefaultFile(), "w"); f.write(data); f.close(); self.xmlHandler.load();