summaryrefslogtreecommitdiffstats
path: root/Demo/pysvr/pysvr.py
blob: 4488386dd93992f2518f0f966eafd562b0b9f324 (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
125
126
127
128
129
130
131
132
133
134
135
#! /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]

"""

import sys, os, string, getopt, thread, socket, traceback

OK_DOMAINS = [".cnri.reston.va.us", ".python.org"]

PORT = 7585892 % 0xFFFF			# == 49367

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)
    while 1:
	(conn, addr) = sock.accept()
	thread.start_new_thread(service_thread, (conn, addr))
	del conn, addr

def service_thread(conn, addr):
    (caddr, cport) = addr
    try:
	host, aliases, ipaddrs = socket.gethostbyaddr(caddr)
    except socket.error:
	print "Don't know hostname for", caddr
	return
    if '.' not in host:
	for a in aliases:
	    if '.' in a:
		host = a
		break
	else:
	    print "Only a local name (%s) for %s" % (host, caddr)
	    return
    i = string.find(host, '.')
    domain = string.lower(host[i:])
    if domain not in OK_DOMAINS:
	print "Connection from", host, "not accepted"
	return
    print "Thread %s has connection from %s.\n" % (str(thread.get_ident()),
						   host),
    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()