| #! /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() |