blob: b200fade480f2229d558d3e6be8ebb93eb685df5 [file] [log] [blame]
Guido van Rossum5c8b9911997-07-19 21:00:47 +00001#! /usr/bin/env python
2
3"""A multi-threaded telnet-like server that gives a Python prompt.
4
5This is really a prototype for the same thing in C.
6
7Usage: pysvr.py [port]
8
Guido van Rossumeca991d1997-07-19 21:13:53 +00009For security reasons, it only accepts requests from the current host.
10This can still be insecure, but restricts violations from people who
11can log in on your machine. Use with caution!
12
Guido van Rossum5c8b9911997-07-19 21:00:47 +000013"""
14
15import sys, os, string, getopt, thread, socket, traceback
16
Guido van Rossum4117e541998-09-14 16:44:15 +000017PORT = 4000 # Default port
Guido van Rossum5c8b9911997-07-19 21:00:47 +000018
19def main():
20 try:
Guido van Rossum4117e541998-09-14 16:44:15 +000021 opts, args = getopt.getopt(sys.argv[1:], "")
22 if len(args) > 1:
Collin Winter6f2df4d2007-07-17 20:59:35 +000023 raise getopt.error("Too many arguments.")
Guido van Rossumb940e112007-01-10 16:19:56 +000024 except getopt.error as msg:
Guido van Rossum4117e541998-09-14 16:44:15 +000025 usage(msg)
Guido van Rossum5c8b9911997-07-19 21:00:47 +000026 for o, a in opts:
Guido van Rossum4117e541998-09-14 16:44:15 +000027 pass
Guido van Rossum5c8b9911997-07-19 21:00:47 +000028 if args:
Guido van Rossum4117e541998-09-14 16:44:15 +000029 try:
30 port = string.atoi(args[0])
Guido van Rossumb940e112007-01-10 16:19:56 +000031 except ValueError as msg:
Guido van Rossum4117e541998-09-14 16:44:15 +000032 usage(msg)
Guido van Rossum5c8b9911997-07-19 21:00:47 +000033 else:
Guido van Rossum4117e541998-09-14 16:44:15 +000034 port = PORT
Guido van Rossum5c8b9911997-07-19 21:00:47 +000035 main_thread(port)
36
37def usage(msg=None):
38 sys.stdout = sys.stderr
39 if msg:
Collin Winter6f2df4d2007-07-17 20:59:35 +000040 print(msg)
41 print("\n", __doc__, end=' ')
Guido van Rossum5c8b9911997-07-19 21:00:47 +000042 sys.exit(2)
43
44def main_thread(port):
45 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
46 sock.bind(("", port))
47 sock.listen(5)
Collin Winter6f2df4d2007-07-17 20:59:35 +000048 print("Listening on port", port, "...")
Guido van Rossum5c8b9911997-07-19 21:00:47 +000049 while 1:
Guido van Rossum4117e541998-09-14 16:44:15 +000050 (conn, addr) = sock.accept()
51 if addr[0] != conn.getsockname()[0]:
52 conn.close()
Collin Winter6f2df4d2007-07-17 20:59:35 +000053 print("Refusing connection from non-local host", addr[0], ".")
Guido van Rossum4117e541998-09-14 16:44:15 +000054 continue
55 thread.start_new_thread(service_thread, (conn, addr))
56 del conn, addr
Guido van Rossum5c8b9911997-07-19 21:00:47 +000057
58def service_thread(conn, addr):
59 (caddr, cport) = addr
Collin Winter6f2df4d2007-07-17 20:59:35 +000060 print("Thread %s has connection from %s.\n" % (str(thread.get_ident()),
61 caddr), end=' ')
Guido van Rossum5c8b9911997-07-19 21:00:47 +000062 stdin = conn.makefile("r")
63 stdout = conn.makefile("w", 0)
64 run_interpreter(stdin, stdout)
Collin Winter6f2df4d2007-07-17 20:59:35 +000065 print("Thread %s is done.\n" % str(thread.get_ident()), end=' ')
Guido van Rossum5c8b9911997-07-19 21:00:47 +000066
67def run_interpreter(stdin, stdout):
68 globals = {}
69 try:
Guido van Rossum4117e541998-09-14 16:44:15 +000070 str(sys.ps1)
Guido van Rossum5c8b9911997-07-19 21:00:47 +000071 except:
Guido van Rossum4117e541998-09-14 16:44:15 +000072 sys.ps1 = ">>> "
Guido van Rossum5c8b9911997-07-19 21:00:47 +000073 source = ""
74 while 1:
Guido van Rossum4117e541998-09-14 16:44:15 +000075 stdout.write(sys.ps1)
76 line = stdin.readline()
77 if line[:2] == '\377\354':
78 line = ""
79 if not line and not source:
80 break
81 if line[-2:] == '\r\n':
82 line = line[:-2] + '\n'
83 source = source + line
84 try:
85 code = compile_command(source)
Guido van Rossumb940e112007-01-10 16:19:56 +000086 except SyntaxError as err:
Guido van Rossum4117e541998-09-14 16:44:15 +000087 source = ""
88 traceback.print_exception(SyntaxError, err, None, file=stdout)
89 continue
90 if not code:
91 continue
92 source = ""
93 try:
94 run_command(code, stdin, stdout, globals)
Guido van Rossumb940e112007-01-10 16:19:56 +000095 except SystemExit as how:
Guido van Rossum4117e541998-09-14 16:44:15 +000096 if how:
97 try:
98 how = str(how)
99 except:
100 how = ""
101 stdout.write("Exit %s\n" % how)
102 break
Guido van Rossum5c8b9911997-07-19 21:00:47 +0000103 stdout.write("\nGoodbye.\n")
104
105def run_command(code, stdin, stdout, globals):
Guido van Rossum4117e541998-09-14 16:44:15 +0000106 save = sys.stdin, sys.stdout, sys.stderr
107 try:
108 sys.stdout = sys.stderr = stdout
109 sys.stdin = stdin
110 try:
Georg Brandl7cae87c2006-09-06 06:51:57 +0000111 exec(code, globals)
Guido van Rossumb940e112007-01-10 16:19:56 +0000112 except SystemExit as how:
Collin Winter6f2df4d2007-07-17 20:59:35 +0000113 raise SystemExit(how).with_traceback(sys.exc_info()[2])
Guido van Rossum4117e541998-09-14 16:44:15 +0000114 except:
115 type, value, tb = sys.exc_info()
116 if tb: tb = tb.tb_next
117 traceback.print_exception(type, value, tb)
118 del tb
119 finally:
120 sys.stdin, sys.stdout, sys.stderr = save
Guido van Rossum5c8b9911997-07-19 21:00:47 +0000121
122from code import compile_command
123
124main()