blob: 3731be7dee0709294bbde17c981123fda3c949d8 [file] [log] [blame]
Guido van Rossumb9b50eb1997-12-24 21:07:04 +00001"""TELNET client class.
2
3Based on RFC 854: TELNET Protocol Specification, by J. Postel and
4J. Reynolds
5
6Example:
7
8>>> from telnetlib import Telnet
9>>> tn = Telnet('www.python.org', 79) # connect to finger port
10>>> tn.write('guido\r\n')
11>>> print tn.read_all()
12Login Name TTY Idle When Where
13guido Guido van Rossum pts/2 <Dec 2 11:10> snag.cnri.reston..
Tim Petersb90f89a2001-01-15 03:26:36 +000014
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000015>>>
16
17Note that read_all() won't read until eof -- it just reads some data
18-- but it guarantees to read at least one byte unless EOF is hit.
19
20It is possible to pass a Telnet object to select.select() in order to
21wait until more data is available. Note that in this case,
22read_eager() may return '' even if there was data on the socket,
23because the protocol negotiation may have eaten the data. This is why
24EOFError is needed in some cases to distinguish between "no data" and
25"connection closed" (since the socket also appears ready for reading
26when it is closed).
27
28Bugs:
29- may hang when connection is slow in the middle of an IAC sequence
30
31To do:
32- option negotiation
Guido van Rossumccb5ec61997-12-24 22:24:19 +000033- timeout should be intrinsic to the connection object instead of an
34 option on one of the read calls only
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000035
36"""
37
38
39# Imported modules
Guido van Rossumccb5ec61997-12-24 22:24:19 +000040import sys
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000041import socket
42import select
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000043
Skip Montanaro40fc1602001-03-01 04:27:19 +000044__all__ = ["Telnet"]
45
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000046# Tunable parameters
47DEBUGLEVEL = 0
48
49# Telnet protocol defaults
50TELNET_PORT = 23
51
52# Telnet protocol characters (don't change)
53IAC = chr(255) # "Interpret As Command"
54DONT = chr(254)
55DO = chr(253)
56WONT = chr(252)
57WILL = chr(251)
58theNULL = chr(0)
59
60
61class Telnet:
62
63 """Telnet interface class.
64
65 An instance of this class represents a connection to a telnet
66 server. The instance is initially not connected; the open()
67 method must be used to establish a connection. Alternatively, the
68 host name and optional port number can be passed to the
69 constructor, too.
70
71 Don't try to reopen an already connected instance.
72
73 This class has many read_*() methods. Note that some of them
74 raise EOFError when the end of the connection is read, because
75 they can return an empty string for other reasons. See the
76 individual doc strings.
77
78 read_until(expected, [timeout])
79 Read until the expected string has been seen, or a timeout is
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000080 hit (default is no timeout); may block.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000081
82 read_all()
83 Read all data until EOF; may block.
84
85 read_some()
86 Read at least one byte or EOF; may block.
87
88 read_very_eager()
89 Read all data available already queued or on the socket,
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000090 without blocking.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000091
92 read_eager()
93 Read either data already queued or some data available on the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000094 socket, without blocking.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000095
96 read_lazy()
97 Read all data in the raw queue (processing it first), without
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000098 doing any socket I/O.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000099
100 read_very_lazy()
101 Reads all data in the cooked queue, without doing any socket
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000102 I/O.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000103
104 """
105
106 def __init__(self, host=None, port=0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000107 """Constructor.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000108
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000109 When called without arguments, create an unconnected instance.
110 With a hostname argument, it connects the instance; a port
111 number is optional.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000112
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000113 """
114 self.debuglevel = DEBUGLEVEL
115 self.host = host
116 self.port = port
117 self.sock = None
118 self.rawq = ''
119 self.irawq = 0
120 self.cookedq = ''
121 self.eof = 0
122 if host:
123 self.open(host, port)
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000124
125 def open(self, host, port=0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000126 """Connect to a host.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000127
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000128 The optional second argument is the port number, which
129 defaults to the standard telnet port (23).
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000130
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000131 Don't try to reopen an already connected instance.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000132
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000133 """
134 self.eof = 0
135 if not port:
136 port = TELNET_PORT
137 self.host = host
138 self.port = port
Martin v. Löwis2ad25692001-07-31 08:40:21 +0000139 msg = "getaddrinfo returns an empty list"
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000140 for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
141 af, socktype, proto, canonname, sa = res
142 try:
143 self.sock = socket.socket(af, socktype, proto)
144 self.sock.connect(sa)
145 except socket.error, msg:
146 self.sock.close()
147 self.sock = None
148 continue
149 break
Martin v. Löwisa43c2f82001-07-24 20:34:08 +0000150 if not self.sock:
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000151 raise socket.error, msg
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000152
153 def __del__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000154 """Destructor -- close the connection."""
155 self.close()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000156
157 def msg(self, msg, *args):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000158 """Print a debug message, when the debug level is > 0.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000159
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000160 If extra arguments are present, they are substituted in the
161 message using the standard string formatting operator.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000162
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000163 """
164 if self.debuglevel > 0:
165 print 'Telnet(%s,%d):' % (self.host, self.port),
166 if args:
167 print msg % args
168 else:
169 print msg
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000170
171 def set_debuglevel(self, debuglevel):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000172 """Set the debug level.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000173
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000174 The higher it is, the more debug output you get (on sys.stdout).
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000175
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000176 """
177 self.debuglevel = debuglevel
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000178
179 def close(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000180 """Close the connection."""
181 if self.sock:
182 self.sock.close()
183 self.sock = 0
184 self.eof = 1
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000185
186 def get_socket(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000187 """Return the socket object used internally."""
188 return self.sock
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000189
190 def fileno(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000191 """Return the fileno() of the socket object used internally."""
192 return self.sock.fileno()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000193
194 def write(self, buffer):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000195 """Write a string to the socket, doubling any IAC characters.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000196
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000197 Can block if the connection is blocked. May raise
198 socket.error if the connection is closed.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000199
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000200 """
201 if IAC in buffer:
Eric S. Raymond6b8c5282001-02-09 07:10:12 +0000202 buffer = buffer.replace(IAC, IAC+IAC)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000203 self.msg("send %s", `buffer`)
204 self.sock.send(buffer)
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000205
206 def read_until(self, match, timeout=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000207 """Read until a given string is encountered or until timeout.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000208
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000209 When no match is found, return whatever is available instead,
210 possibly the empty string. Raise EOFError if the connection
211 is closed and no cooked data is available.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000212
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000213 """
214 n = len(match)
215 self.process_rawq()
Eric S. Raymond6b8c5282001-02-09 07:10:12 +0000216 i = self.cookedq.find(match)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000217 if i >= 0:
218 i = i+n
219 buf = self.cookedq[:i]
220 self.cookedq = self.cookedq[i:]
221 return buf
222 s_reply = ([self], [], [])
223 s_args = s_reply
224 if timeout is not None:
225 s_args = s_args + (timeout,)
226 while not self.eof and apply(select.select, s_args) == s_reply:
227 i = max(0, len(self.cookedq)-n)
228 self.fill_rawq()
229 self.process_rawq()
Eric S. Raymond6b8c5282001-02-09 07:10:12 +0000230 i = self.cookedq.find(match, i)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000231 if i >= 0:
232 i = i+n
233 buf = self.cookedq[:i]
234 self.cookedq = self.cookedq[i:]
235 return buf
236 return self.read_very_lazy()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000237
238 def read_all(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000239 """Read all data until EOF; block until connection closed."""
240 self.process_rawq()
241 while not self.eof:
242 self.fill_rawq()
243 self.process_rawq()
244 buf = self.cookedq
245 self.cookedq = ''
246 return buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000247
248 def read_some(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000249 """Read at least one byte of cooked data unless EOF is hit.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000250
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000251 Return '' if EOF is hit. Block if no data is immediately
252 available.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000253
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000254 """
255 self.process_rawq()
256 while not self.cookedq and not self.eof:
257 self.fill_rawq()
258 self.process_rawq()
259 buf = self.cookedq
260 self.cookedq = ''
261 return buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000262
263 def read_very_eager(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000264 """Read everything that's possible without blocking in I/O (eager).
Tim Petersb90f89a2001-01-15 03:26:36 +0000265
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000266 Raise EOFError if connection closed and no cooked data
267 available. Return '' if no cooked data available otherwise.
268 Don't block unless in the midst of an IAC sequence.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000269
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000270 """
271 self.process_rawq()
272 while not self.eof and self.sock_avail():
273 self.fill_rawq()
274 self.process_rawq()
275 return self.read_very_lazy()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000276
277 def read_eager(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000278 """Read readily available data.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000279
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000280 Raise EOFError if connection closed and no cooked data
281 available. Return '' if no cooked data available otherwise.
282 Don't block unless in the midst of an IAC sequence.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000283
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000284 """
285 self.process_rawq()
286 while not self.cookedq and not self.eof and self.sock_avail():
287 self.fill_rawq()
288 self.process_rawq()
289 return self.read_very_lazy()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000290
291 def read_lazy(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000292 """Process and return data that's already in the queues (lazy).
Tim Petersb90f89a2001-01-15 03:26:36 +0000293
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000294 Raise EOFError if connection closed and no data available.
295 Return '' if no cooked data available otherwise. Don't block
296 unless in the midst of an IAC sequence.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000297
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000298 """
299 self.process_rawq()
300 return self.read_very_lazy()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000301
302 def read_very_lazy(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000303 """Return any data available in the cooked queue (very lazy).
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000304
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000305 Raise EOFError if connection closed and no data available.
306 Return '' if no cooked data available otherwise. Don't block.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000307
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000308 """
309 buf = self.cookedq
310 self.cookedq = ''
311 if not buf and self.eof and not self.rawq:
312 raise EOFError, 'telnet connection closed'
313 return buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000314
315 def process_rawq(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000316 """Transfer from raw queue to cooked queue.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000317
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000318 Set self.eof when connection is closed. Don't block unless in
319 the midst of an IAC sequence.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000320
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000321 """
322 buf = ''
323 try:
324 while self.rawq:
325 c = self.rawq_getchar()
326 if c == theNULL:
327 continue
328 if c == "\021":
329 continue
330 if c != IAC:
331 buf = buf + c
332 continue
333 c = self.rawq_getchar()
334 if c == IAC:
335 buf = buf + c
336 elif c in (DO, DONT):
337 opt = self.rawq_getchar()
338 self.msg('IAC %s %d', c == DO and 'DO' or 'DONT', ord(c))
339 self.sock.send(IAC + WONT + opt)
340 elif c in (WILL, WONT):
341 opt = self.rawq_getchar()
342 self.msg('IAC %s %d',
343 c == WILL and 'WILL' or 'WONT', ord(c))
Guido van Rossum823eb4b2000-05-02 14:32:11 +0000344 self.sock.send(IAC + DONT + opt)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000345 else:
346 self.msg('IAC %s not recognized' % `c`)
347 except EOFError: # raised by self.rawq_getchar()
348 pass
349 self.cookedq = self.cookedq + buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000350
351 def rawq_getchar(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000352 """Get next char from raw queue.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000353
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000354 Block if no data is immediately available. Raise EOFError
355 when connection is closed.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000356
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000357 """
358 if not self.rawq:
359 self.fill_rawq()
360 if self.eof:
361 raise EOFError
362 c = self.rawq[self.irawq]
363 self.irawq = self.irawq + 1
364 if self.irawq >= len(self.rawq):
365 self.rawq = ''
366 self.irawq = 0
367 return c
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000368
369 def fill_rawq(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000370 """Fill raw queue from exactly one recv() system call.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000371
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000372 Block if no data is immediately available. Set self.eof when
373 connection is closed.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000374
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000375 """
376 if self.irawq >= len(self.rawq):
377 self.rawq = ''
378 self.irawq = 0
379 # The buffer size should be fairly small so as to avoid quadratic
380 # behavior in process_rawq() above
381 buf = self.sock.recv(50)
382 self.msg("recv %s", `buf`)
383 self.eof = (not buf)
384 self.rawq = self.rawq + buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000385
386 def sock_avail(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000387 """Test whether data is available on the socket."""
388 return select.select([self], [], [], 0) == ([self], [], [])
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000389
390 def interact(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000391 """Interaction function, emulates a very dumb telnet client."""
Guido van Rossum82eae9e1998-12-23 23:04:17 +0000392 if sys.platform == "win32":
393 self.mt_interact()
394 return
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000395 while 1:
396 rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
397 if self in rfd:
398 try:
399 text = self.read_eager()
400 except EOFError:
401 print '*** Connection closed by remote host ***'
402 break
403 if text:
404 sys.stdout.write(text)
405 sys.stdout.flush()
406 if sys.stdin in rfd:
407 line = sys.stdin.readline()
408 if not line:
409 break
410 self.write(line)
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000411
Guido van Rossum82eae9e1998-12-23 23:04:17 +0000412 def mt_interact(self):
413 """Multithreaded version of interact()."""
414 import thread
415 thread.start_new_thread(self.listener, ())
416 while 1:
417 line = sys.stdin.readline()
418 if not line:
419 break
420 self.write(line)
421
422 def listener(self):
423 """Helper for mt_interact() -- this executes in the other thread."""
424 while 1:
425 try:
426 data = self.read_eager()
427 except EOFError:
428 print '*** Connection closed by remote host ***'
429 return
430 if data:
431 sys.stdout.write(data)
432 else:
433 sys.stdout.flush()
434
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000435 def expect(self, list, timeout=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000436 """Read until one from a list of a regular expressions matches.
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000437
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000438 The first argument is a list of regular expressions, either
439 compiled (re.RegexObject instances) or uncompiled (strings).
440 The optional second argument is a timeout, in seconds; default
441 is no timeout.
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000442
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000443 Return a tuple of three items: the index in the list of the
444 first regular expression that matches; the match object
445 returned; and the text read up till and including the match.
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000446
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000447 If EOF is read and no text was read, raise EOFError.
448 Otherwise, when nothing matches, return (-1, None, text) where
449 text is the text received so far (may be the empty string if a
450 timeout happened).
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000451
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000452 If a regular expression ends with a greedy match (e.g. '.*')
453 or if more than one expression can match the same input, the
454 results are undeterministic, and may depend on the I/O timing.
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000455
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000456 """
457 re = None
458 list = list[:]
459 indices = range(len(list))
460 for i in indices:
461 if not hasattr(list[i], "search"):
462 if not re: import re
463 list[i] = re.compile(list[i])
464 while 1:
465 self.process_rawq()
466 for i in indices:
467 m = list[i].search(self.cookedq)
468 if m:
469 e = m.end()
470 text = self.cookedq[:e]
471 self.cookedq = self.cookedq[e:]
472 return (i, m, text)
473 if self.eof:
474 break
475 if timeout is not None:
476 r, w, x = select.select([self.fileno()], [], [], timeout)
477 if not r:
478 break
479 self.fill_rawq()
480 text = self.read_very_lazy()
481 if not text and self.eof:
482 raise EOFError
483 return (-1, None, text)
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000484
485
486def test():
487 """Test program for telnetlib.
488
489 Usage: python telnetlib.py [-d] ... [host [port]]
490
491 Default host is localhost; default port is 23.
492
493 """
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000494 debuglevel = 0
495 while sys.argv[1:] and sys.argv[1] == '-d':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000496 debuglevel = debuglevel+1
497 del sys.argv[1]
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000498 host = 'localhost'
499 if sys.argv[1:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000500 host = sys.argv[1]
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000501 port = 0
502 if sys.argv[2:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000503 portstr = sys.argv[2]
504 try:
505 port = int(portstr)
506 except ValueError:
507 port = socket.getservbyname(portstr, 'tcp')
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000508 tn = Telnet()
509 tn.set_debuglevel(debuglevel)
510 tn.open(host, port)
511 tn.interact()
512 tn.close()
513
514if __name__ == '__main__':
515 test()