1 """TELNET client class.
3 Based on RFC 854: TELNET Protocol Specification, by J. Postel and
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()
12 Login Name TTY Idle When Where
13 guido Guido van Rossum pts/2 <Dec 2 11:10> snag.cnri.reston..
17 Note 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.
20 It is possible to pass a Telnet object to select.select() in order to
21 wait until more data is available. Note that in this case,
22 read_eager() may return '' even if there was data on the socket,
23 because the protocol negotiation may have eaten the data. This is why
24 EOFError is needed in some cases to distinguish between "no data" and
25 "connection closed" (since the socket also appears ready for reading
29 - may hang when connection is slow in the middle of an IAC sequence
33 - timeout should be intrinsic to the connection object instead of an
34 option on one of the read calls only
48 # Telnet protocol defaults
51 # Telnet protocol characters (don't change)
52 IAC
= chr(255) # "Interpret As Command"
62 """Telnet interface class.
64 An instance of this class represents a connection to a telnet
65 server. The instance is initially not connected; the open()
66 method must be used to establish a connection. Alternatively, the
67 host name and optional port number can be passed to the
70 Don't try to reopen an already connected instance.
72 This class has many read_*() methods. Note that some of them
73 raise EOFError when the end of the connection is read, because
74 they can return an empty string for other reasons. See the
75 individual doc strings.
77 read_until(expected, [timeout])
78 Read until the expected string has been seen, or a timeout is
79 hit (default is no timeout); may block.
82 Read all data until EOF; may block.
85 Read at least one byte or EOF; may block.
88 Read all data available already queued or on the socket,
92 Read either data already queued or some data available on the
93 socket, without blocking.
96 Read all data in the raw queue (processing it first), without
100 Reads all data in the cooked queue, without doing any socket
105 def __init__(self
, host
=None, port
=0):
108 When called without arguments, create an unconnected instance.
109 With a hostname argument, it connects the instance; a port
113 self
.debuglevel
= DEBUGLEVEL
122 self
.open(host
, port
)
124 def open(self
, host
, port
=0):
125 """Connect to a host.
127 The optional second argument is the port number, which
128 defaults to the standard telnet port (23).
130 Don't try to reopen an already connected instance.
138 self
.sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
139 self
.sock
.connect((self
.host
, self
.port
))
142 """Destructor -- close the connection."""
145 def msg(self
, msg
, *args
):
146 """Print a debug message, when the debug level is > 0.
148 If extra arguments are present, they are substituted in the
149 message using the standard string formatting operator.
152 if self
.debuglevel
> 0:
153 print 'Telnet(%s,%d):' % (self
.host
, self
.port
),
159 def set_debuglevel(self
, debuglevel
):
160 """Set the debug level.
162 The higher it is, the more debug output you get (on sys.stdout).
165 self
.debuglevel
= debuglevel
168 """Close the connection."""
174 def get_socket(self
):
175 """Return the socket object used internally."""
179 """Return the fileno() of the socket object used internally."""
180 return self
.sock
.fileno()
182 def write(self
, buffer):
183 """Write a string to the socket, doubling any IAC characters.
185 Can block if the connection is blocked. May raise
186 socket.error if the connection is closed.
190 buffer = string
.replace(buffer, IAC
, IAC
+IAC
)
191 self
.msg("send %s", `
buffer`
)
192 self
.sock
.send(buffer)
194 def read_until(self
, match
, timeout
=None):
195 """Read until a given string is encountered or until timeout.
197 When no match is found, return whatever is available instead,
198 possibly the empty string. Raise EOFError if the connection
199 is closed and no cooked data is available.
204 i
= string
.find(self
.cookedq
, match
)
207 buf
= self
.cookedq
[:i
]
208 self
.cookedq
= self
.cookedq
[i
:]
210 s_reply
= ([self
], [], [])
212 if timeout
is not None:
213 s_args
= s_args
+ (timeout
,)
214 while not self
.eof
and apply(select
.select
, s_args
) == s_reply
:
215 i
= max(0, len(self
.cookedq
)-n
)
218 i
= string
.find(self
.cookedq
, match
, i
)
221 buf
= self
.cookedq
[:i
]
222 self
.cookedq
= self
.cookedq
[i
:]
224 return self
.read_very_lazy()
227 """Read all data until EOF; block until connection closed."""
237 """Read at least one byte of cooked data unless EOF is hit.
239 Return '' if EOF is hit. Block if no data is immediately
244 while not self
.cookedq
and not self
.eof
:
251 def read_very_eager(self
):
252 """Read everything that's possible without blocking in I/O (eager).
254 Raise EOFError if connection closed and no cooked data
255 available. Return '' if no cooked data available otherwise.
256 Don't block unless in the midst of an IAC sequence.
260 while not self
.eof
and self
.sock_avail():
263 return self
.read_very_lazy()
265 def read_eager(self
):
266 """Read readily available data.
268 Raise EOFError if connection closed and no cooked data
269 available. Return '' if no cooked data available otherwise.
270 Don't block unless in the midst of an IAC sequence.
274 while not self
.cookedq
and not self
.eof
and self
.sock_avail():
277 return self
.read_very_lazy()
280 """Process and return data that's already in the queues (lazy).
282 Raise EOFError if connection closed and no data available.
283 Return '' if no cooked data available otherwise. Don't block
284 unless in the midst of an IAC sequence.
288 return self
.read_very_lazy()
290 def read_very_lazy(self
):
291 """Return any data available in the cooked queue (very lazy).
293 Raise EOFError if connection closed and no data available.
294 Return '' if no cooked data available otherwise. Don't block.
299 if not buf
and self
.eof
and not self
.rawq
:
300 raise EOFError, 'telnet connection closed'
303 def process_rawq(self
):
304 """Transfer from raw queue to cooked queue.
306 Set self.eof when connection is closed. Don't block unless in
307 the midst of an IAC sequence.
313 c
= self
.rawq_getchar()
321 c
= self
.rawq_getchar()
324 elif c
in (DO
, DONT
):
325 opt
= self
.rawq_getchar()
326 self
.msg('IAC %s %d', c
== DO
and 'DO' or 'DONT', ord(c
))
327 self
.sock
.send(IAC
+ WONT
+ opt
)
328 elif c
in (WILL
, WONT
):
329 opt
= self
.rawq_getchar()
330 self
.msg('IAC %s %d',
331 c
== WILL
and 'WILL' or 'WONT', ord(c
))
333 self
.msg('IAC %s not recognized' % `c`
)
334 except EOFError: # raised by self.rawq_getchar()
336 self
.cookedq
= self
.cookedq
+ buf
338 def rawq_getchar(self
):
339 """Get next char from raw queue.
341 Block if no data is immediately available. Raise EOFError
342 when connection is closed.
349 c
= self
.rawq
[self
.irawq
]
350 self
.irawq
= self
.irawq
+ 1
351 if self
.irawq
>= len(self
.rawq
):
357 """Fill raw queue from exactly one recv() system call.
359 Block if no data is immediately available. Set self.eof when
360 connection is closed.
363 if self
.irawq
>= len(self
.rawq
):
366 # The buffer size should be fairly small so as to avoid quadratic
367 # behavior in process_rawq() above
368 buf
= self
.sock
.recv(50)
369 self
.msg("recv %s", `buf`
)
371 self
.rawq
= self
.rawq
+ buf
373 def sock_avail(self
):
374 """Test whether data is available on the socket."""
375 return select
.select([self
], [], [], 0) == ([self
], [], [])
378 """Interaction function, emulates a very dumb telnet client."""
379 if sys
.platform
== "win32":
383 rfd
, wfd
, xfd
= select
.select([self
, sys
.stdin
], [], [])
386 text
= self
.read_eager()
388 print '*** Connection closed by remote host ***'
391 sys
.stdout
.write(text
)
394 line
= sys
.stdin
.readline()
399 def mt_interact(self
):
400 """Multithreaded version of interact()."""
402 thread
.start_new_thread(self
.listener
, ())
404 line
= sys
.stdin
.readline()
410 """Helper for mt_interact() -- this executes in the other thread."""
413 data
= self
.read_eager()
415 print '*** Connection closed by remote host ***'
418 sys
.stdout
.write(data
)
422 def expect(self
, list, timeout
=None):
423 """Read until one from a list of a regular expressions matches.
425 The first argument is a list of regular expressions, either
426 compiled (re.RegexObject instances) or uncompiled (strings).
427 The optional second argument is a timeout, in seconds; default
430 Return a tuple of three items: the index in the list of the
431 first regular expression that matches; the match object
432 returned; and the text read up till and including the match.
434 If EOF is read and no text was read, raise EOFError.
435 Otherwise, when nothing matches, return (-1, None, text) where
436 text is the text received so far (may be the empty string if a
439 If a regular expression ends with a greedy match (e.g. '.*')
440 or if more than one expression can match the same input, the
441 results are undeterministic, and may depend on the I/O timing.
446 indices
= range(len(list))
448 if not hasattr(list[i
], "search"):
450 list[i
] = re
.compile(list[i
])
454 m
= list[i
].search(self
.cookedq
)
457 text
= self
.cookedq
[:e
]
458 self
.cookedq
= self
.cookedq
[e
:]
462 if timeout
is not None:
463 r
, w
, x
= select
.select([self
.fileno()], [], [], timeout
)
467 text
= self
.read_very_lazy()
468 if not text
and self
.eof
:
470 return (-1, None, text
)
474 """Test program for telnetlib.
476 Usage: python telnetlib.py [-d] ... [host [port]]
478 Default host is localhost; default port is 23.
482 while sys
.argv
[1:] and sys
.argv
[1] == '-d':
483 debuglevel
= debuglevel
+1
490 portstr
= sys
.argv
[2]
494 port
= socket
.getservbyname(portstr
, 'tcp')
496 tn
.set_debuglevel(debuglevel
)
501 if __name__
== '__main__':