/Demo/sockets/telnet.py

http://unladen-swallow.googlecode.com/ · Python · 109 lines · 78 code · 9 blank · 22 comment · 30 complexity · ee5fd211b72e51d5c347cc98848768c9 MD5 · raw file

  1. #! /usr/bin/env python
  2. # Minimal interface to the Internet telnet protocol.
  3. #
  4. # It refuses all telnet options and does not recognize any of the other
  5. # telnet commands, but can still be used to connect in line-by-line mode.
  6. # It's also useful to play with a number of other services,
  7. # like time, finger, smtp and even ftp.
  8. #
  9. # Usage: telnet host [port]
  10. #
  11. # The port may be a service name or a decimal port number;
  12. # it defaults to 'telnet'.
  13. import sys, posix, time
  14. from socket import *
  15. BUFSIZE = 1024
  16. # Telnet protocol characters
  17. IAC = chr(255) # Interpret as command
  18. DONT = chr(254)
  19. DO = chr(253)
  20. WONT = chr(252)
  21. WILL = chr(251)
  22. def main():
  23. host = sys.argv[1]
  24. try:
  25. hostaddr = gethostbyname(host)
  26. except error:
  27. sys.stderr.write(sys.argv[1] + ': bad host name\n')
  28. sys.exit(2)
  29. #
  30. if len(sys.argv) > 2:
  31. servname = sys.argv[2]
  32. else:
  33. servname = 'telnet'
  34. #
  35. if '0' <= servname[:1] <= '9':
  36. port = eval(servname)
  37. else:
  38. try:
  39. port = getservbyname(servname, 'tcp')
  40. except error:
  41. sys.stderr.write(servname + ': bad tcp service name\n')
  42. sys.exit(2)
  43. #
  44. s = socket(AF_INET, SOCK_STREAM)
  45. #
  46. try:
  47. s.connect((host, port))
  48. except error, msg:
  49. sys.stderr.write('connect failed: ' + repr(msg) + '\n')
  50. sys.exit(1)
  51. #
  52. pid = posix.fork()
  53. #
  54. if pid == 0:
  55. # child -- read stdin, write socket
  56. while 1:
  57. line = sys.stdin.readline()
  58. s.send(line)
  59. else:
  60. # parent -- read socket, write stdout
  61. iac = 0 # Interpret next char as command
  62. opt = '' # Interpret next char as option
  63. while 1:
  64. data = s.recv(BUFSIZE)
  65. if not data:
  66. # EOF; kill child and exit
  67. sys.stderr.write( '(Closed by remote host)\n')
  68. posix.kill(pid, 9)
  69. sys.exit(1)
  70. cleandata = ''
  71. for c in data:
  72. if opt:
  73. print ord(c)
  74. s.send(opt + c)
  75. opt = ''
  76. elif iac:
  77. iac = 0
  78. if c == IAC:
  79. cleandata = cleandata + c
  80. elif c in (DO, DONT):
  81. if c == DO: print '(DO)',
  82. else: print '(DONT)',
  83. opt = IAC + WONT
  84. elif c in (WILL, WONT):
  85. if c == WILL: print '(WILL)',
  86. else: print '(WONT)',
  87. opt = IAC + DONT
  88. else:
  89. print '(command)', ord(c)
  90. elif c == IAC:
  91. iac = 1
  92. print '(IAC)',
  93. else:
  94. cleandata = cleandata + c
  95. sys.stdout.write(cleandata)
  96. sys.stdout.flush()
  97. try:
  98. main()
  99. except KeyboardInterrupt:
  100. pass