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
))
332 self
.sock
.send(IAC
+ DONT
+ opt
)
334 self
.msg('IAC %s not recognized' % `c`
)
335 except EOFError: # raised by self.rawq_getchar()
337 self
.cookedq
= self
.cookedq
+ buf
339 def rawq_getchar(self
):
340 """Get next char from raw queue.
342 Block if no data is immediately available. Raise EOFError
343 when connection is closed.
350 c
= self
.rawq
[self
.irawq
]
351 self
.irawq
= self
.irawq
+ 1
352 if self
.irawq
>= len(self
.rawq
):
358 """Fill raw queue from exactly one recv() system call.
360 Block if no data is immediately available. Set self.eof when
361 connection is closed.
364 if self
.irawq
>= len(self
.rawq
):
367 # The buffer size should be fairly small so as to avoid quadratic
368 # behavior in process_rawq() above
369 buf
= self
.sock
.recv(50)
370 self
.msg("recv %s", `buf`
)
372 self
.rawq
= self
.rawq
+ buf
374 def sock_avail(self
):
375 """Test whether data is available on the socket."""
376 return select
.select([self
], [], [], 0) == ([self
], [], [])
379 """Interaction function, emulates a very dumb telnet client."""
380 if sys
.platform
== "win32":
384 rfd
, wfd
, xfd
= select
.select([self
, sys
.stdin
], [], [])
387 text
= self
.read_eager()
389 print '*** Connection closed by remote host ***'
392 sys
.stdout
.write(text
)
395 line
= sys
.stdin
.readline()
400 def mt_interact(self
):
401 """Multithreaded version of interact()."""
403 thread
.start_new_thread(self
.listener
, ())
405 line
= sys
.stdin
.readline()
411 """Helper for mt_interact() -- this executes in the other thread."""
414 data
= self
.read_eager()
416 print '*** Connection closed by remote host ***'
419 sys
.stdout
.write(data
)
423 def expect(self
, list, timeout
=None):
424 """Read until one from a list of a regular expressions matches.
426 The first argument is a list of regular expressions, either
427 compiled (re.RegexObject instances) or uncompiled (strings).
428 The optional second argument is a timeout, in seconds; default
431 Return a tuple of three items: the index in the list of the
432 first regular expression that matches; the match object
433 returned; and the text read up till and including the match.
435 If EOF is read and no text was read, raise EOFError.
436 Otherwise, when nothing matches, return (-1, None, text) where
437 text is the text received so far (may be the empty string if a
440 If a regular expression ends with a greedy match (e.g. '.*')
441 or if more than one expression can match the same input, the
442 results are undeterministic, and may depend on the I/O timing.
447 indices
= range(len(list))
449 if not hasattr(list[i
], "search"):
451 list[i
] = re
.compile(list[i
])
455 m
= list[i
].search(self
.cookedq
)
458 text
= self
.cookedq
[:e
]
459 self
.cookedq
= self
.cookedq
[e
:]
463 if timeout
is not None:
464 r
, w
, x
= select
.select([self
.fileno()], [], [], timeout
)
468 text
= self
.read_very_lazy()
469 if not text
and self
.eof
:
471 return (-1, None, text
)
475 """Test program for telnetlib.
477 Usage: python telnetlib.py [-d] ... [host [port]]
479 Default host is localhost; default port is 23.
483 while sys
.argv
[1:] and sys
.argv
[1] == '-d':
484 debuglevel
= debuglevel
+1
491 portstr
= sys
.argv
[2]
495 port
= socket
.getservbyname(portstr
, 'tcp')
497 tn
.set_debuglevel(debuglevel
)
502 if __name__
== '__main__':