cpython/Demo/pysvr/pysvr.py

125 lines
3.3 KiB
Python
Raw Normal View History

1997-07-19 21:00:47 +00:00
#! /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!
1997-07-19 21:00:47 +00:00
"""
import sys, os, string, getopt, thread, socket, traceback
1998-09-14 16:44:15 +00:00
PORT = 4000 # Default port
1997-07-19 21:00:47 +00:00
def main():
try:
1998-09-14 16:44:15 +00:00
opts, args = getopt.getopt(sys.argv[1:], "")
if len(args) > 1:
raise getopt.error, "Too many arguments."
1997-07-19 21:00:47 +00:00
except getopt.error, msg:
1998-09-14 16:44:15 +00:00
usage(msg)
1997-07-19 21:00:47 +00:00
for o, a in opts:
1998-09-14 16:44:15 +00:00
pass
1997-07-19 21:00:47 +00:00
if args:
1998-09-14 16:44:15 +00:00
try:
port = string.atoi(args[0])
except ValueError, msg:
usage(msg)
1997-07-19 21:00:47 +00:00
else:
1998-09-14 16:44:15 +00:00
port = PORT
1997-07-19 21:00:47 +00:00
main_thread(port)
def usage(msg=None):
sys.stdout = sys.stderr
if msg:
1998-09-14 16:44:15 +00:00
print msg
1997-07-19 21:00:47 +00:00
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, "..."
1997-07-19 21:00:47 +00:00
while 1:
1998-09-14 16:44:15 +00:00
(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
1997-07-19 21:00:47 +00:00
def service_thread(conn, addr):
(caddr, cport) = addr
print "Thread %s has connection from %s.\n" % (str(thread.get_ident()),
1998-09-14 16:44:15 +00:00
caddr),
1997-07-19 21:00:47 +00:00
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:
1998-09-14 16:44:15 +00:00
str(sys.ps1)
1997-07-19 21:00:47 +00:00
except:
1998-09-14 16:44:15 +00:00
sys.ps1 = ">>> "
1997-07-19 21:00:47 +00:00
source = ""
while 1:
1998-09-14 16:44:15 +00:00
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
1997-07-19 21:00:47 +00:00
stdout.write("\nGoodbye.\n")
def run_command(code, stdin, stdout, globals):
1998-09-14 16:44:15 +00:00
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
1997-07-19 21:00:47 +00:00
from code import compile_command
main()