1#! /usr/bin/env python
2
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
23IAC  = chr(255) # Interpret as command
24DONT = chr(254)
25DO   = chr(253)
26WONT = chr(252)
27WILL = chr(251)
28
29def main():
30    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))
55    except error, msg:
56        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:
80                    print ord(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
105
106try:
107    main()
108except KeyboardInterrupt:
109    pass
110