blob: 329909b686bca53682a0c8c1756fed65d48d38e5 [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 Rossumeca991d1997-07-19 21:13:53 +000017PORT = 4000 # Default port
Guido van Rossum5c8b9911997-07-19 21:00:47 +000018
19def main():
20 try:
21 opts, args = getopt.getopt(sys.argv[1:], "")
22 if len(args) > 1:
23 raise getopt.error, "Too many arguments."
24 except getopt.error, msg:
25 usage(msg)
26 for o, a in opts:
27 pass
28 if args:
29 try:
30 port = string.atoi(args[0])
31 except ValueError, msg:
32 usage(msg)
33 else:
34 port = PORT
35 main_thread(port)
36
37def usage(msg=None):
38 sys.stdout = sys.stderr
39 if msg:
40 print msg
41 print "\n", __doc__,
42 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)
Guido van Rossumeca991d1997-07-19 21:13:53 +000048 print "Listening on port", port, "..."
Guido van Rossum5c8b9911997-07-19 21:00:47 +000049 while 1:
50 (conn, addr) = sock.accept()
51 thread.start_new_thread(service_thread, (conn, addr))
52 del conn, addr
53
54def service_thread(conn, addr):
55 (caddr, cport) = addr
Guido van Rossumeca991d1997-07-19 21:13:53 +000056 if caddr != socket.gethostbyname(socket.gethostname()):
57 print "Connection from", caddr, "not accepted."
Guido van Rossum5c8b9911997-07-19 21:00:47 +000058 return
59 print "Thread %s has connection from %s.\n" % (str(thread.get_ident()),
Guido van Rossumeca991d1997-07-19 21:13:53 +000060 caddr),
Guido van Rossum5c8b9911997-07-19 21:00:47 +000061 stdin = conn.makefile("r")
62 stdout = conn.makefile("w", 0)
63 run_interpreter(stdin, stdout)
64 print "Thread %s is done.\n" % str(thread.get_ident()),
65
66def run_interpreter(stdin, stdout):
67 globals = {}
68 try:
69 str(sys.ps1)
70 except:
71 sys.ps1 = ">>> "
72 source = ""
73 while 1:
74 stdout.write(sys.ps1)
75 line = stdin.readline()
76 if line[:2] == '\377\354':
77 line = ""
78 if not line and not source:
79 break
80 if line[-2:] == '\r\n':
81 line = line[:-2] + '\n'
82 source = source + line
83 try:
84 code = compile_command(source)
85 except SyntaxError, err:
86 source = ""
87 traceback.print_exception(SyntaxError, err, None, file=stdout)
88 continue
89 if not code:
90 continue
91 source = ""
92 try:
93 run_command(code, stdin, stdout, globals)
94 except SystemExit, how:
95 if how:
96 try:
97 how = str(how)
98 except:
99 how = ""
100 stdout.write("Exit %s\n" % how)
101 break
102 stdout.write("\nGoodbye.\n")
103
104def run_command(code, stdin, stdout, globals):
105 save = sys.stdin, sys.stdout, sys.stderr
106 try:
107 sys.stdout = sys.stderr = stdout
108 sys.stdin = stdin
109 try:
110 exec code in globals
111 except SystemExit, how:
112 raise SystemExit, how, sys.exc_info()[2]
113 except:
114 type, value, tb = sys.exc_info()
115 if tb: tb = tb.tb_next
116 traceback.print_exception(type, value, tb)
117 del tb
118 finally:
119 sys.stdin, sys.stdout, sys.stderr = save
120
121from code import compile_command
122
123main()