diff --git a/asrc-server.py b/asrc-server.py index aa329d7..7ec77d5 100755 --- a/asrc-server.py +++ b/asrc-server.py @@ -33,6 +33,7 @@ import sys, os, socket, socketserver, threading, time +from include import argparser, comm class ThreadedRequestHandler(socketserver.StreamRequestHandler): @@ -50,14 +51,14 @@ class ThreadedRequestHandler(socketserver.StreamRequestHandler): print("Client connected: " + str(self.client_address)) # send motd - self.request.sendall(comm.motd(MOTD) + "\n", ENCODING)) + self.request.sendall(bytes((comm.motd(MOTD) + "\n"), ENCODING)) # Receive data self.data = str(self.rfile.readline().strip(), ENCODING) # content handler self.request.sendall(bytes( - comm.handler(str(self.client_address), self.data), ENCODING)) + comm.command(str(self.client_address), self.data), ENCODING)) class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): @@ -68,7 +69,6 @@ def main(): # import global settings global VERBOSITY, HOST, PORT, TIMEOUT, ENCODING - from include import argparser, comm comm.init(ServerVersion, ProtocolVersion, VERBOSITY, aliases) @@ -76,20 +76,6 @@ def main(): parser = argparser args = parser.parse(ServerVersion, ProtocolVersion) - # look for pid file - if os.path.exists("pid"): - # remove, ... - if args.delete_pid_file: os.remove("pid") - # ... ignore ... - elif args.allow_multiple_instances: pass - # ... or exit - else: - print( - "\npid file already exists\n"\ - "If the server didn't shut down correctly, "\ - "just delete this file or pass -n\n"\ - "If you want to start multiple instances, pass -m\n") - return 1 # set settings if command line options are given if args.host: HOST = args.host @@ -98,16 +84,25 @@ def main(): if args.encoding: ENCODING = args.encoding if args.verbosity: VERBOSITY = args.verbosity - # write pid file - pidf = open("pid", 'w') - pidf.write(str(os.getpid())) - pidf.close() print("aSRC Server\n"\ "Server version: " + ServerVersion + "\n"\ "Protocol version: " + ProtocolVersion + "\n\n"\ "To stop the server, press Ctrl-C\n") + # look for pid file + if os.path.exists("pid"): + # ignore ... + if args.delete_pid_file or args.allow_multiple_instances: pass + # ... or exit + else: + print( + "\npid file already exists\n"\ + "If the server didn't shut down correctly, "\ + "just delete this file or pass -n\n"\ + "If you want to start multiple instances, pass -m\n") + return 1 + try: if VERBOSITY >= 1: print("Initializing server...") # Create server @@ -123,9 +118,19 @@ def main(): ServerThread.daemon = True ServerThread.start() + # look for pid file again ... + if os.path.exists("pid"): + # ... and remove it if -n is given + if args.delete_pid_file: os.remove("pid") + # write pid file + pidf = open("pid", 'w') + pidf.write(str(os.getpid())) + pidf.close() + + # do nothing further while True: - time.sleep(10) + time.sleep(60) # exit if Ctrl-C is pressed except KeyboardInterrupt: diff --git a/include/__init__.py b/include/__init__.py index 6ff74a1..c891f96 100644 --- a/include/__init__.py +++ b/include/__init__.py @@ -1,2 +1,3 @@ from .argparser import argparser from .comm import comm +from .statuscodes import statuscodes diff --git a/include/comm.py b/include/comm.py index 24b1479..52cc7ad 100644 --- a/include/comm.py +++ b/include/comm.py @@ -1,119 +1,135 @@ # includes/comm.py # # module version: 0.0.20130426 +# for protocol versions 0.2.20130423 and later # -import statuscodes +from .statuscodes import statuscodes class comm: - - aliases = dict() - server_version = "" - protocol_version = "" - verbosity = 0 - - # initializes global settings - def init(ServerVersion, ProtocolVersion, Verbosity, Aliases): - - aliases = Aliases - server_version = ServerVersion - protocol_version = ProtocolVersion - verbosity = Verbosity - - def header(statuscode, AdditionalHeaderLines = ""): - """ - returns the header - """ - - ret =\ - "{BEGIN}\n"\ - "asrcp" + protocol_version + "\n"\ - statuscode + " " + statuscodes.description[statuscodes] + "\n"\ - "ServerVersion:" + server_version + "\n" - if AdditionalHeaderLines != "": ret += AdditionalHeaderLines + "\n" - ret += "\n\n" - - return ret - - # returns the motd - def motd(motd): - """ - builds and returns a motd package - """ - - ret = motd - - return ret - - # handles the content - def command(client_address, data): - """ - processes a command - """ - - ret = "" - - # Look if the received message is an - # valid alias or a predefined command - - # if it's 'version', return the server and protocol version - if data == "version": - - if verbosity >= 2: print("Got valid service command from" - + str(client_address) + ": ", data) - - ret = ret +\ - "202 Valid Service Command\n"\ - "002 Version\n"\ - "ServerVersion:" + server_version + "\n"\ - "ProtocolVersion:" + protocol_version + "\n" - - # if it's 'help', give a little help - elif data == 'help': - - if verbosity >= 2: print("Got valid command from" - + str(client_address) + ": ", data) - - # send status code - ret = ret + "202 Valid Service Command\n\n" - - # send the list of aliases - ret = ret + "Aviable aliases:\n" - for i in aliases.keys(): - ret = ret + str(i) + "\n" - - # if it's a valid userdefined command - elif data in aliases: - - # send status code - ret = ret + "201 Valid Command\n\n" - - # ohmagawd! a debug message!!1! - if verbosity >= 2: print("Got valid command from" - + str(client_address) + ": ", data) - - # execute the aliased command - g_dict, l_dict = {}, {} - exec(str(aliases[data]), g_dict, l_dict) - - # send may contain data to send to the client - if l_dict["send"]: - content = str(l_dict["send"]).replace('{', '\{') - content = content.replace('}', '\}') - - ret = ret + content + "\n" - - # ALL IS LOST!!1! this has to be invalid! - else: - - # send status code - ret = ret + "203 Invalid Command\n" - - if verbosity >= 2: print("Got invalid command from", - str(client_address), ": ", data) - - ret = ret + "{END}\n" - - return ret \ No newline at end of file + + # some settings + aliases = dict() + server_version = "" + protocol_version = "" + verbosity = 0 + + # initializes global settings + def init(ServerVersion, ProtocolVersion, Verbosity, Aliases): + """ + makes settings aviable in this class + """ + global aliases, server_version, protocol_version, verbosity + aliases = Aliases + server_version = ServerVersion + protocol_version = ProtocolVersion + verbosity = Verbosity + + # builds an header + def header(CodeList, AdditionalHeaderLines = ""): + """ + returns the header with one ore mode given status codes + and optional additional header lines + """ + ret =\ + "{BEGIN}\n"\ + "asrcp" + protocol_version + "\n" + for i in range(0, len(CodeList)): + ret += CodeList[int(i)] + " " +\ + statuscodes.description['s' + CodeList[int(i)]] + "\n" + ret += "ServerVersion: " + server_version + "\n" +\ + AdditionalHeaderLines + "\n\n" + return ret + + # formats a massage + def encode_message(text): + """ + formats a massage, replaces some things + """ + return text.replace('{', '\{').replace('}', '\}') + + # "deformats" a message + def decode_message(text): + """ + removes replacements in a message + """ + return text.replace('\{', '{').replace('\}', '}') + + # returns the motd + def motd(motd): + """ + builds and returns a motd package + """ + return comm.header(['202', '003']) + comm.encode_message(motd) + + # handles the content + def command(client_address, data): + """ + processes a command + """ + ret = "" + + # Look if the received message is an + # valid alias or a predefined command + + # if it's 'version', return the server and protocol version + if data == "version": + + if verbosity >= 2: print("Got valid service command from" + + str(client_address) + ": ", data) + + ret = ret +\ + "202 Valid Service Command\n"\ + "002 Version\n"\ + "ServerVersion:" + server_version + "\n"\ + "ProtocolVersion:" + protocol_version + "\n" + + # if it's 'help', give a little help + elif data == 'help': + + if verbosity >= 2: print("Got valid command from" + + str(client_address) + ": ", data) + + # send status code + ret = ret + "202 Valid Service Command\n\n" + + # send the list of aliases + ret = ret + "Aviable aliases:\n" + for i in aliases.keys(): + ret = ret + str(i) + "\n" + + # if it's a valid userdefined command + elif data in aliases: + + # send status code + ret = ret + "201 Valid Command\n\n" + + # ohmagawd! a debug message!!1! + if verbosity >= 2: print("Got valid command from" + + str(client_address) + ": ", data) + + # execute the aliased command + g_dict, l_dict = {}, {} + exec(str(aliases[data]), g_dict, l_dict) + + # send may contain data to send to the client + if l_dict["send"]: + content = str(l_dict["send"]).replace('{', '\{') + content = content.replace('}', '\}') + + ret = ret + content + "\n" + + # ALL IS LOST!!1! this has to be invalid! + else: + + # send status code + ret = ret + "203 Invalid Command\n" + + if verbosity >= 2: print("Got invalid command from", + str(client_address), ": ", data) + + ret = ret + "{END}\n" + + return ret \ No newline at end of file diff --git a/include/statuscodes.py b/include/statuscodes.py index b106ffc..378ceb9 100644 --- a/include/statuscodes.py +++ b/include/statuscodes.py @@ -1,37 +1,44 @@ +# include/statuscodes.py +# +# module version: 1.0.20130426 +# for protocol versions 0.2.20130423 and later +# + + class statuscodes: description = dict( # 000 - 400 server side # 000 information - 001 = "OK", - 002 = "Version", - 003 = "MOTD", + s001 = "OK", + s002 = "Version", + s003 = "MOTD", # 100 authentication and maintenance - 101 = "Challenge", - 102 = "Success", - 103 = "Failure", - 104 = "To Many Tries", + s101 = "Challenge", + s102 = "Success", + s103 = "Failure", + s104 = "To Many Tries", # 200 command - 201 = "Valid", - 202 = "Valid Service Command", - 203 = "Invalid", - 204 = "Failure", - 205 = "Continue", + s201 = "Valid", + s202 = "Valid Service Command", + s203 = "Invalid", + s204 = "Failure", + s205 = "Continue", # 300 server - 301 = "Unhandled Exception", - 302 = "Shutting Down", - 303 = "Restarting", - 304 = "Encoding Error", - 305 = "SSL Error", + s301 = "Unhandled Exception", + s302 = "Shutting Down", + s303 = "Restarting", + s304 = "Encoding Error", + s305 = "SSL Error", # 500 - 900 client side # 500 information - 501 = "OK", - 502 = "Version", + s501 = "OK", + s502 = "Version", # 600 authentication and maintenance - 601 = "Response", - 602 = "Failure", + s601 = "Response", + s602 = "Failure", # 700 command - 701 = "Reqiuest", - 702 = "Cancel", + s701 = "Reqiuest", + s702 = "Cancel", # 800 client - 801 = "SSL Error" + s801 = "SSL Error" )