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