summaryrefslogtreecommitdiffstats
path: root/Demo/pysvr/pysvr.py
blob: a62fc5c013dd0a88df7bc00a6ba7bb420a915b43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#! /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()