| Guido van Rossum | 260cc1a8 | 1992-08-10 10:48:14 +0000 | [diff] [blame] | 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(): | 
| Guido van Rossum | f82fef0 | 1993-12-17 14:45:06 +0000 | [diff] [blame] | 31 | 	if len(sys.argv) != 2: | 
 | 32 | 		sys.stderr.write('usage: telnet hostname\n') | 
 | 33 | 		sys.exit(2) | 
| Guido van Rossum | 260cc1a8 | 1992-08-10 10:48:14 +0000 | [diff] [blame] | 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: ' + `msg` + '\n') | 
 | 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') | 
| Guido van Rossum | dc3c53c | 1994-05-16 09:30:26 +0000 | [diff] [blame] | 75 | 			sys.exit(1) | 
| Guido van Rossum | 260cc1a8 | 1992-08-10 10:48:14 +0000 | [diff] [blame] | 76 | 		cleandata = '' | 
 | 77 | 		for c in data: | 
 | 78 | 			if opt: | 
 | 79 | 				print ord(c) | 
| Guido van Rossum | f82fef0 | 1993-12-17 14:45:06 +0000 | [diff] [blame] | 80 | ##				print '(replying: ' + `opt+c` + ')' | 
| Guido van Rossum | 260cc1a8 | 1992-08-10 10:48:14 +0000 | [diff] [blame] | 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:', `cleandata` | 
 | 105 |  | 
 | 106 | def child(s): | 
 | 107 | 	# read stdin, write socket | 
 | 108 | 	while 1: | 
 | 109 | 		line = sys.stdin.readline() | 
 | 110 | ##		print 'Got:', `line` | 
| Guido van Rossum | dc3c53c | 1994-05-16 09:30:26 +0000 | [diff] [blame] | 111 | 		if not line: break | 
| Guido van Rossum | 260cc1a8 | 1992-08-10 10:48:14 +0000 | [diff] [blame] | 112 | 		s.send(line) | 
 | 113 |  | 
 | 114 | main() |