1 | #! /usr/bin/env python
|
---|
2 |
|
---|
3 | """A multi-threaded telnet-like server that gives a Python prompt.
|
---|
4 |
|
---|
5 | This is really a prototype for the same thing in C.
|
---|
6 |
|
---|
7 | Usage: pysvr.py [port]
|
---|
8 |
|
---|
9 | For security reasons, it only accepts requests from the current host.
|
---|
10 | This can still be insecure, but restricts violations from people who
|
---|
11 | can log in on your machine. Use with caution!
|
---|
12 |
|
---|
13 | """
|
---|
14 |
|
---|
15 | import sys, os, string, getopt, thread, socket, traceback
|
---|
16 |
|
---|
17 | PORT = 4000 # Default port
|
---|
18 |
|
---|
19 | def 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 |
|
---|
37 | def usage(msg=None):
|
---|
38 | sys.stdout = sys.stderr
|
---|
39 | if msg:
|
---|
40 | print msg
|
---|
41 | print "\n", __doc__,
|
---|
42 | sys.exit(2)
|
---|
43 |
|
---|
44 | def main_thread(port):
|
---|
45 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
---|
46 | sock.bind(("", port))
|
---|
47 | sock.listen(5)
|
---|
48 | print "Listening on port", port, "..."
|
---|
49 | while 1:
|
---|
50 | (conn, addr) = sock.accept()
|
---|
51 | if addr[0] != conn.getsockname()[0]:
|
---|
52 | conn.close()
|
---|
53 | print "Refusing connection from non-local host", addr[0], "."
|
---|
54 | continue
|
---|
55 | thread.start_new_thread(service_thread, (conn, addr))
|
---|
56 | del conn, addr
|
---|
57 |
|
---|
58 | def service_thread(conn, addr):
|
---|
59 | (caddr, cport) = addr
|
---|
60 | print "Thread %s has connection from %s.\n" % (str(thread.get_ident()),
|
---|
61 | caddr),
|
---|
62 | stdin = conn.makefile("r")
|
---|
63 | stdout = conn.makefile("w", 0)
|
---|
64 | run_interpreter(stdin, stdout)
|
---|
65 | print "Thread %s is done.\n" % str(thread.get_ident()),
|
---|
66 |
|
---|
67 | def run_interpreter(stdin, stdout):
|
---|
68 | globals = {}
|
---|
69 | try:
|
---|
70 | str(sys.ps1)
|
---|
71 | except:
|
---|
72 | sys.ps1 = ">>> "
|
---|
73 | source = ""
|
---|
74 | while 1:
|
---|
75 | 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)
|
---|
86 | except SyntaxError, err:
|
---|
87 | 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)
|
---|
95 | except SystemExit, how:
|
---|
96 | if how:
|
---|
97 | try:
|
---|
98 | how = str(how)
|
---|
99 | except:
|
---|
100 | how = ""
|
---|
101 | stdout.write("Exit %s\n" % how)
|
---|
102 | break
|
---|
103 | stdout.write("\nGoodbye.\n")
|
---|
104 |
|
---|
105 | def run_command(code, stdin, stdout, globals):
|
---|
106 | save = sys.stdin, sys.stdout, sys.stderr
|
---|
107 | try:
|
---|
108 | sys.stdout = sys.stderr = stdout
|
---|
109 | sys.stdin = stdin
|
---|
110 | try:
|
---|
111 | exec code in globals
|
---|
112 | except SystemExit, how:
|
---|
113 | raise SystemExit, how, sys.exc_info()[2]
|
---|
114 | 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
|
---|
121 |
|
---|
122 | from code import compile_command
|
---|
123 |
|
---|
124 | main()
|
---|