#! /usr/bin/env python """A multi-threaded telnet-like server that gives a Python prompt. This is really a prototype for the same thing in C. Usage: pysvr.py [port] For security reasons, it only accepts requests from the current host. This can still be insecure, but restricts violations from people who can log in on your machine. Use with caution! """ import sys, os, string, getopt, thread, socket, traceback PORT = 4000 # Default port def main(): try: opts, args = getopt.getopt(sys.argv[1:], "") if len(args) > 1: raise getopt.error, "Too many arguments." except getopt.error, msg: usage(msg) for o, a in opts: pass if args: try: port = string.atoi(args[0]) except ValueError, msg: usage(msg) else: port = PORT main_thread(port) def usage(msg=None): sys.stdout = sys.stderr if msg: print msg print "\n", __doc__, sys.exit(2) def main_thread(port): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(("", port)) sock.listen(5) print "Listening on port", port, "..." while 1: (conn, addr) = sock.accept() if addr[0] != conn.getsockname()[0]: conn.close() print "Refusing connection from non-local host", addr[0], "." continue thread.start_new_thread(service_thread, (conn, addr)) del conn, addr def service_thread(conn, addr): (caddr, cport) = addr print "Thread %s has connection from %s.\n" % (str(thread.get_ident()), caddr), stdin = conn.makefile("r") stdout = conn.makefile("w", 0) run_interpreter(stdin, stdout) print "Thread %s is done.\n" % str(thread.get_ident()), def run_interpreter(stdin, stdout): globals = {} try: str(sys.ps1) except: sys.ps1 = ">>> " source = "" while 1: stdout.write(sys.ps1) line = stdin.readline() if line[:2] == '\377\354': line = "" if not line and not source: break if line[-2:] == '\r\n': line = line[:-2] + '\n' source = source + line try: code = compile_command(source) except SyntaxError, err: source = "" traceback.print_exception(SyntaxError, err, None, file=stdout) continue if not code: continue source = "" try: run_command(code, stdin, stdout, globals) except SystemExit, how: if how: try: how = str(how) except: how = "" stdout.write("Exit %s\n" % how) break stdout.write("\nGoodbye.\n") def run_command(code, stdin, stdout, globals): save = sys.stdin, sys.stdout, sys.stderr try: sys.stdout = sys.stderr = stdout sys.stdin = stdin try: exec code in globals except SystemExit, how: raise SystemExit, how, sys.exc_info()[2] except: type, value, tb = sys.exc_info() if tb: tb = tb.tb_next traceback.print_exception(type, value, tb) del tb finally: sys.stdin, sys.stdout, sys.stderr = save from code import compile_command main()