diff --git a/asrc-server.py b/asrc-server.py index b65105f..516e42d 100755 --- a/asrc-server.py +++ b/asrc-server.py @@ -25,7 +25,7 @@ # aSRC (Aliased Server Remote Control) # - SERVER - # -# program version: 0.0.0.20130423 +# program version: 0.0.0.20130424 # protocol version: 0.2.20130423 # # @@ -39,75 +39,75 @@ def motd(): return MOTD -def content(client_address, data): - ret = "" +#def content(client_address, data): + #ret = "" - ret = ret + - "{BEGIN}\n"\ - "asrcp" + ProtocolVersion + "\n" + #ret = ret +\ + #"{BEGIN}\n"\ + #"asrcp" + ProtocolVersion + "\n" - # Look if the received message is an - # valid alias or a predefined command + ## 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 it's 'version', return the server and protocol version + #if data == "version": - if DEBUGLEVEL >= 2: print("Got valid service command from" - + str(client_address) + ": ", data) + #if VERBOSITY >= 2: print("Got valid service command from" + #+ str(client_address) + ": ", data) - ret = ret + - "202 Valid Service Command\n"\ - "002 Version\n"\ - "ServerVersion:" + ServerVersion + "\n"\ - "ProtocolVersion:" + ProtocolVersion + "\n" + #ret = ret +\ + #"202 Valid Service Command\n"\ + #"002 Version\n"\ + #"ServerVersion:" + ServerVersion + "\n"\ + #"ProtocolVersion:" + ProtocolVersion + "\n" - # if it's 'help', give a little help - elif data == 'help': + ## if it's 'help', give a little help + #elif data == 'help': - if DEBUGLEVEL >= 2: print("Got valid command from" - + str(client_address) + ": ", data) + #if VERBOSITY >= 2: print("Got valid command from" + #+ str(client_address) + ": ", data) - # send status code - ret = ret + "202 Valid Service Command\n\n" + ## 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" + ## 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: + ## if it's a valid userdefined command + #elif data in aliases: - # send status code - ret = ret + "201 Valid Command\n\n" + ## send status code + #ret = ret + "201 Valid Command\n\n" - # ohmagawd! a debug message!!1! - if DEBUGLEVEL >= 2: print("Got valid command from" - + str(client_address) + ": ", data) + ## 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) + ## 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('}', '\}') + ## 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" + #ret = ret + content + "\n" - # ALL IS LOST!!1! this has to be invalid! - else: + ## ALL IS LOST!!1! this has to be invalid! + #else: - # send status code - ret = ret + "203 Invalid Command\n" + ## send status code + #ret = ret + "203 Invalid Command\n" - if DEBUGLEVEL >= 2: print("Got invalid command from", - str(client_address), ": ", data) + #if VERBOSITY >= 2: print("Got invalid command from", + #str(client_address), ": ", data) - ret = ret + "{END}\n" + #ret = ret + "{END}\n" - return ret + #return ret class ThreadedRequestHandler(socketserver.StreamRequestHandler): @@ -118,7 +118,7 @@ class ThreadedRequestHandler(socketserver.StreamRequestHandler): self.timeout = TIMEOUT # Print a line with the adress of the connected client - if DEBUGLEVEL >=3: + if VERBOSITY >=3: print("Client connected: " + str(self.client_address)) # send header line 1 @@ -133,7 +133,8 @@ class ThreadedRequestHandler(socketserver.StreamRequestHandler): # content handler self.request.sendall(bytes( - content(str(self.client_address), self.data), ENCODING)) + content.handler(str(self.client_address), self.data, aliases, + ServerVersion, ProtocolVersion, VERBOSITY), ENCODING)) class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): @@ -141,17 +142,46 @@ class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): def main(): + from include import argparser, content + + parser = argparser + args = parser.parse(ServerVersion, ProtocolVersion) + + if os.path.exists("pid"): + if args.delete_pid_file: os.remove("pid") + elif args.allow_multiple_instances: pass + 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 + + print(args) + + if args.host: HOST = args.host + if args.port: PORT = args.port + if args.timeout: TIMEOUT = args.timeout + 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") + "Server version: " + ServerVersion + "\n"\ + "Protocol version: " + ProtocolVersion + "\n\n"\ + "To stop the server, press Ctrl-C\n") try: - if DEBUGLEVEL >= 1: print("Initializing server...") + if VERBOSITY >= 1: print("Initializing server...") # Create server server = ThreadedTCPServer((HOST, PORT), ThreadedRequestHandler) - if DEBUGLEVEL >= 1: print("Starting server on", + if VERBOSITY >= 1: print("Starting server on", server.server_address[0], "port", server.server_address[1], "...") # Start a thread with the server -- that thread will then start one # more thread for each request @@ -160,21 +190,23 @@ def main(): # Exit the server thread when the main thread terminates ServerThread.daemon = True ServerThread.start() + while True: time.sleep(10) except KeyboardInterrupt: print("\nGot Ctrl-C, shutting down server...") - try: server.shutdown() + try: + server.shutdown() + os.remove("pid") except: print("Failed to shutdown server correctly, "\ "socket may be still in use or wasn't even started:", sys.exc_info()) - except: - print("\nAn error occured:\n", sys.exc_info(), "\n") + #except: + # print("\nAn error occured:\n", sys.exc_info(), "\n") - - if DEBUGLEVEL >= 3: input("Press Enter to continue\n") + if VERBOSITY >= 3: input("Press Enter to continue\n") return 0 @@ -193,8 +225,8 @@ if __name__ == '__main__': HOST = '127.0.0.1' PORT = 24642 - # Timeout of a connection in seconds - obviously still doesn't work... - TIMEOUT = 4 + # Timeout of a connection in seconds - still doesn't work obviously... + TIMEOUT = 15 # Encoding to be used when communicating with a client ENCODING = 'utf-8' @@ -236,7 +268,7 @@ send = subprocess.check_output(["ping", "-c 2", "fanir.de"]) # Verbosity of logging. # Can be from 0 (only default output) to 3 (debug messages) - DEBUGLEVEL = 3 + VERBOSITY = 3 ############## diff --git a/doc/protocol_reference.odt b/doc/protocol_reference.odt index 174b91b..f5be414 100644 Binary files a/doc/protocol_reference.odt and b/doc/protocol_reference.odt differ diff --git a/include/__init__.py b/include/__init__.py new file mode 100644 index 0000000..174e139 --- /dev/null +++ b/include/__init__.py @@ -0,0 +1,2 @@ +from .argparser import argparser +from .content import content diff --git a/include/argparser.py b/include/argparser.py new file mode 100644 index 0000000..517ebf6 --- /dev/null +++ b/include/argparser.py @@ -0,0 +1,78 @@ +# includes/argparser.py +# +# module version: 1.0.20130424 +# + + +class argparser: + + def parse(program_version, protocol_version): + import argparse + + parser = argparse.ArgumentParser( + description = "The server side of the "\ + "aliased server remote control", + add_help = False) + + + parser.add_argument( + "--help", + action = "help", + help = "show this help message and exit") + + parser.add_argument( + "--version", + action = "version", + version = "Server version: " + program_version +\ + " / Protocol version: " + protocol_version) + + grp_pid_file_failure = parser.add_mutually_exclusive_group() + grp_pid_file_failure.add_argument( + "-n", + "--delete-pid-file", + action = "store_true", + help = "deletes the pid file and starts the server") + + grp_pid_file_failure.add_argument( + "-m", + "--allow-multiple-instances", + action = "store_true", + help = "ignores the pid file and starts the server. "\ + "Will not create another pid file.") + + parser.add_argument( + "-v", + "--verbosity", + type = int, + choices = range(0, 4), + # default = -1, + help = "increase output verbosity. Can be from 0 "\ + "(only default output) to 3 (debug messages).") + + parser.add_argument( + "-h", + "--host", + # default = -1, + help = "IP or hostname (use 0.0.0.0 for all interfaces) on which "\ + "the server should listen") + + parser.add_argument( + "-p", + "--port", + # default = -1, + help = "the port on which the server should listen") + + parser.add_argument( + "-t", + "--timeout", + # default = -1, + help = "timeout of a connection in seconds - still "\ + "doesn't work obviously...") + + parser.add_argument( + "-e", + "--encoding", + # default = -1, + help = "encoding to be used when communicating with clients") + + return parser.parse_args() diff --git a/include/content.py b/include/content.py new file mode 100644 index 0000000..79a4545 --- /dev/null +++ b/include/content.py @@ -0,0 +1,78 @@ +# includes/content.py +# +# module version: 0.0.20130424 +# + + +class content: + + # handler the content + def handler(client_address, data, aliases, server_version, protocol_version, verbosity): + ret = "" + + ret = ret +\ + "{BEGIN}\n"\ + "asrcp" + protocol_version + "\n" + + # 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