home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Demo / pysvr / pysvr.py < prev    next >
Text File  |  1997-07-19  |  3KB  |  125 lines

  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.