/Demo/pysvr/pysvr.py

http://unladen-swallow.googlecode.com/ · Python · 124 lines · 101 code · 11 blank · 12 comment · 29 complexity · 11bb11b1092bb86e948f45952879f99b MD5 · raw file

  1. #! /usr/bin/env python
  2. """A multi-threaded telnet-like server that gives a Python prompt.
  3. This is really a prototype for the same thing in C.
  4. Usage: pysvr.py [port]
  5. For security reasons, it only accepts requests from the current host.
  6. This can still be insecure, but restricts violations from people who
  7. can log in on your machine. Use with caution!
  8. """
  9. import sys, os, string, getopt, thread, socket, traceback
  10. PORT = 4000 # Default port
  11. def main():
  12. try:
  13. opts, args = getopt.getopt(sys.argv[1:], "")
  14. if len(args) > 1:
  15. raise getopt.error, "Too many arguments."
  16. except getopt.error, msg:
  17. usage(msg)
  18. for o, a in opts:
  19. pass
  20. if args:
  21. try:
  22. port = string.atoi(args[0])
  23. except ValueError, msg:
  24. usage(msg)
  25. else:
  26. port = PORT
  27. main_thread(port)
  28. def usage(msg=None):
  29. sys.stdout = sys.stderr
  30. if msg:
  31. print msg
  32. print "\n", __doc__,
  33. sys.exit(2)
  34. def main_thread(port):
  35. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  36. sock.bind(("", port))
  37. sock.listen(5)
  38. print "Listening on port", port, "..."
  39. while 1:
  40. (conn, addr) = sock.accept()
  41. if addr[0] != conn.getsockname()[0]:
  42. conn.close()
  43. print "Refusing connection from non-local host", addr[0], "."
  44. continue
  45. thread.start_new_thread(service_thread, (conn, addr))
  46. del conn, addr
  47. def service_thread(conn, addr):
  48. (caddr, cport) = addr
  49. print "Thread %s has connection from %s.\n" % (str(thread.get_ident()),
  50. caddr),
  51. stdin = conn.makefile("r")
  52. stdout = conn.makefile("w", 0)
  53. run_interpreter(stdin, stdout)
  54. print "Thread %s is done.\n" % str(thread.get_ident()),
  55. def run_interpreter(stdin, stdout):
  56. globals = {}
  57. try:
  58. str(sys.ps1)
  59. except:
  60. sys.ps1 = ">>> "
  61. source = ""
  62. while 1:
  63. stdout.write(sys.ps1)
  64. line = stdin.readline()
  65. if line[:2] == '\377\354':
  66. line = ""
  67. if not line and not source:
  68. break
  69. if line[-2:] == '\r\n':
  70. line = line[:-2] + '\n'
  71. source = source + line
  72. try:
  73. code = compile_command(source)
  74. except SyntaxError, err:
  75. source = ""
  76. traceback.print_exception(SyntaxError, err, None, file=stdout)
  77. continue
  78. if not code:
  79. continue
  80. source = ""
  81. try:
  82. run_command(code, stdin, stdout, globals)
  83. except SystemExit, how:
  84. if how:
  85. try:
  86. how = str(how)
  87. except:
  88. how = ""
  89. stdout.write("Exit %s\n" % how)
  90. break
  91. stdout.write("\nGoodbye.\n")
  92. def run_command(code, stdin, stdout, globals):
  93. save = sys.stdin, sys.stdout, sys.stderr
  94. try:
  95. sys.stdout = sys.stderr = stdout
  96. sys.stdin = stdin
  97. try:
  98. exec code in globals
  99. except SystemExit, how:
  100. raise SystemExit, how, sys.exc_info()[2]
  101. except:
  102. type, value, tb = sys.exc_info()
  103. if tb: tb = tb.tb_next
  104. traceback.print_exception(type, value, tb)
  105. del tb
  106. finally:
  107. sys.stdin, sys.stdout, sys.stderr = save
  108. from code import compile_command
  109. main()