blob: 038036ffc65bd5bd11f3b321c1a061f36d29aca7 [file] [log] [blame]
Guido van Rossumf06ee5f1996-11-27 19:52:01 +00001#! /usr/bin/env python
Guido van Rossum22825e81991-07-01 18:32:32 +00002
3# Minimal interface to the Internet telnet protocol.
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
16import sys, posix, time
17from socket import *
18
19BUFSIZE = 1024
20
21# Telnet protocol characters
22
Tim Peterse6ddc8b2004-07-18 05:56:09 +000023IAC = chr(255) # Interpret as command
Guido van Rossum22825e81991-07-01 18:32:32 +000024DONT = chr(254)
25DO = chr(253)
26WONT = chr(252)
27WILL = chr(251)
28
29def main():
Tim Peterse6ddc8b2004-07-18 05:56:09 +000030 host = sys.argv[1]
31 try:
32 hostaddr = gethostbyname(host)
33 except error:
34 sys.stderr.write(sys.argv[1] + ': bad host name\n')
35 sys.exit(2)
36 #
37 if len(sys.argv) > 2:
38 servname = sys.argv[2]
39 else:
40 servname = 'telnet'
41 #
42 if '0' <= servname[:1] <= '9':
43 port = eval(servname)
44 else:
45 try:
46 port = getservbyname(servname, 'tcp')
47 except error:
48 sys.stderr.write(servname + ': bad tcp service name\n')
49 sys.exit(2)
50 #
51 s = socket(AF_INET, SOCK_STREAM)
52 #
53 try:
54 s.connect((host, port))
Guido van Rossumb940e112007-01-10 16:19:56 +000055 except error as msg:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000056 sys.stderr.write('connect failed: ' + repr(msg) + '\n')
57 sys.exit(1)
58 #
59 pid = posix.fork()
60 #
61 if pid == 0:
62 # child -- read stdin, write socket
63 while 1:
64 line = sys.stdin.readline()
65 s.send(line)
66 else:
67 # parent -- read socket, write stdout
68 iac = 0 # Interpret next char as command
69 opt = '' # Interpret next char as option
70 while 1:
71 data = s.recv(BUFSIZE)
72 if not data:
73 # EOF; kill child and exit
74 sys.stderr.write( '(Closed by remote host)\n')
75 posix.kill(pid, 9)
76 sys.exit(1)
77 cleandata = ''
78 for c in data:
79 if opt:
Collin Winter6f2df4d2007-07-17 20:59:35 +000080 print(ord(c))
Tim Peterse6ddc8b2004-07-18 05:56:09 +000081 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):
Collin Winter6f2df4d2007-07-17 20:59:35 +000088 if c == DO: print('(DO)', end=' ')
89 else: print('(DONT)', end=' ')
Tim Peterse6ddc8b2004-07-18 05:56:09 +000090 opt = IAC + WONT
91 elif c in (WILL, WONT):
Collin Winter6f2df4d2007-07-17 20:59:35 +000092 if c == WILL: print('(WILL)', end=' ')
93 else: print('(WONT)', end=' ')
Tim Peterse6ddc8b2004-07-18 05:56:09 +000094 opt = IAC + DONT
95 else:
Collin Winter6f2df4d2007-07-17 20:59:35 +000096 print('(command)', ord(c))
Tim Peterse6ddc8b2004-07-18 05:56:09 +000097 elif c == IAC:
98 iac = 1
Collin Winter6f2df4d2007-07-17 20:59:35 +000099 print('(IAC)', end=' ')
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000100 else:
101 cleandata = cleandata + c
102 sys.stdout.write(cleandata)
103 sys.stdout.flush()
Guido van Rossum22825e81991-07-01 18:32:32 +0000104
105
106try:
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000107 main()
Guido van Rossum22825e81991-07-01 18:32:32 +0000108except KeyboardInterrupt:
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000109 pass