blob: 4488386dd93992f2518f0f966eafd562b0b9f324 [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
9"""
10
11import sys, os, string, getopt, thread, socket, traceback
12
13OK_DOMAINS = [".cnri.reston.va.us", ".python.org"]
14
15PORT = 7585892 % 0xFFFF # == 49367
16
17def main():
18 try:
19 opts, args = getopt.getopt(sys.argv[1:], "")
20 if len(args) > 1:
21 raise getopt.error, "Too many arguments."
22 except getopt.error, msg:
23 usage(msg)
24 for o, a in opts:
25 pass
26 if args:
27 try:
28 port = string.atoi(args[0])
29 except ValueError, msg:
30 usage(msg)
31 else:
32 port = PORT
33 main_thread(port)
34
35def usage(msg=None):
36 sys.stdout = sys.stderr
37 if msg:
38 print msg
39 print "\n", __doc__,
40 sys.exit(2)
41
42def main_thread(port):
43 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
44 sock.bind(("", port))
45 sock.listen(5)
46 while 1:
47 (conn, addr) = sock.accept()
48 thread.start_new_thread(service_thread, (conn, addr))
49 del conn, addr
50
51def service_thread(conn, addr):
52 (caddr, cport) = addr
53 try:
54 host, aliases, ipaddrs = socket.gethostbyaddr(caddr)
55 except socket.error:
56 print "Don't know hostname for", caddr
57 return
58 if '.' not in host:
59 for a in aliases:
60 if '.' in a:
61 host = a
62 break
63 else:
64 print "Only a local name (%s) for %s" % (host, caddr)
65 return
66 i = string.find(host, '.')
67 domain = string.lower(host[i:])
68 if domain not in OK_DOMAINS:
69 print "Connection from", host, "not accepted"
70 return
71 print "Thread %s has connection from %s.\n" % (str(thread.get_ident()),
72 host),
73 stdin = conn.makefile("r")
74 stdout = conn.makefile("w", 0)
75 run_interpreter(stdin, stdout)
76 print "Thread %s is done.\n" % str(thread.get_ident()),
77
78def run_interpreter(stdin, stdout):
79 globals = {}
80 try:
81 str(sys.ps1)
82 except:
83 sys.ps1 = ">>> "
84 source = ""
85 while 1:
86 stdout.write(sys.ps1)
87 line = stdin.readline()
88 if line[:2] == '\377\354':
89 line = ""
90 if not line and not source:
91 break
92 if line[-2:] == '\r\n':
93 line = line[:-2] + '\n'
94 source = source + line
95 try:
96 code = compile_command(source)
97 except SyntaxError, err:
98 source = ""
99 traceback.print_exception(SyntaxError, err, None, file=stdout)
100 continue
101 if not code:
102 continue
103 source = ""
104 try:
105 run_command(code, stdin, stdout, globals)
106 except SystemExit, how:
107 if how:
108 try:
109 how = str(how)
110 except:
111 how = ""
112 stdout.write("Exit %s\n" % how)
113 break
114 stdout.write("\nGoodbye.\n")
115
116def run_command(code, stdin, stdout, globals):
117 save = sys.stdin, sys.stdout, sys.stderr
118 try:
119 sys.stdout = sys.stderr = stdout
120 sys.stdin = stdin
121 try:
122 exec code in globals
123 except SystemExit, how:
124 raise SystemExit, how, sys.exc_info()[2]
125 except:
126 type, value, tb = sys.exc_info()
127 if tb: tb = tb.tb_next
128 traceback.print_exception(type, value, tb)
129 del tb
130 finally:
131 sys.stdin, sys.stdout, sys.stderr = save
132
133from code import compile_command
134
135main()