Home | History | Annotate | Download | only in pysvr
      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()
    125