New \grammartoken markup, similar to \token but allowed everywhere.
[python/dscho.git] / Lib / telnetlib.py
blob3731be7dee0709294bbde17c981123fda3c949d8
1 """TELNET client class.
3 Based on RFC 854: TELNET Protocol Specification, by J. Postel and
4 J. Reynolds
6 Example:
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..
15 >>>
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
26 when it is closed).
28 Bugs:
29 - may hang when connection is slow in the middle of an IAC sequence
31 To do:
32 - option negotiation
33 - timeout should be intrinsic to the connection object instead of an
34 option on one of the read calls only
36 """
39 # Imported modules
40 import sys
41 import socket
42 import select
44 __all__ = ["Telnet"]
46 # Tunable parameters
47 DEBUGLEVEL = 0
49 # Telnet protocol defaults
50 TELNET_PORT = 23
52 # Telnet protocol characters (don't change)
53 IAC = chr(255) # "Interpret As Command"
54 DONT = chr(254)
55 DO = chr(253)
56 WONT = chr(252)
57 WILL = chr(251)
58 theNULL = chr(0)
61 class Telnet:
63 """Telnet interface class.
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.
71 Don't try to reopen an already connected instance.
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.
78 read_until(expected, [timeout])
79 Read until the expected string has been seen, or a timeout is
80 hit (default is no timeout); may block.
82 read_all()
83 Read all data until EOF; may block.
85 read_some()
86 Read at least one byte or EOF; may block.
88 read_very_eager()
89 Read all data available already queued or on the socket,
90 without blocking.
92 read_eager()
93 Read either data already queued or some data available on the
94 socket, without blocking.
96 read_lazy()
97 Read all data in the raw queue (processing it first), without
98 doing any socket I/O.
100 read_very_lazy()
101 Reads all data in the cooked queue, without doing any socket
102 I/O.
106 def __init__(self, host=None, port=0):
107 """Constructor.
109 When called without arguments, create an unconnected instance.
110 With a hostname argument, it connects the instance; a port
111 number is optional.
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)
125 def open(self, host, port=0):
126 """Connect to a host.
128 The optional second argument is the port number, which
129 defaults to the standard telnet port (23).
131 Don't try to reopen an already connected instance.
134 self.eof = 0
135 if not port:
136 port = TELNET_PORT
137 self.host = host
138 self.port = port
139 msg = "getaddrinfo returns an empty list"
140 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
150 if not self.sock:
151 raise socket.error, msg
153 def __del__(self):
154 """Destructor -- close the connection."""
155 self.close()
157 def msg(self, msg, *args):
158 """Print a debug message, when the debug level is > 0.
160 If extra arguments are present, they are substituted in the
161 message using the standard string formatting operator.
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
171 def set_debuglevel(self, debuglevel):
172 """Set the debug level.
174 The higher it is, the more debug output you get (on sys.stdout).
177 self.debuglevel = debuglevel
179 def close(self):
180 """Close the connection."""
181 if self.sock:
182 self.sock.close()
183 self.sock = 0
184 self.eof = 1
186 def get_socket(self):
187 """Return the socket object used internally."""
188 return self.sock
190 def fileno(self):
191 """Return the fileno() of the socket object used internally."""
192 return self.sock.fileno()
194 def write(self, buffer):
195 """Write a string to the socket, doubling any IAC characters.
197 Can block if the connection is blocked. May raise
198 socket.error if the connection is closed.
201 if IAC in buffer:
202 buffer = buffer.replace(IAC, IAC+IAC)
203 self.msg("send %s", `buffer`)
204 self.sock.send(buffer)
206 def read_until(self, match, timeout=None):
207 """Read until a given string is encountered or until timeout.
209 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.
214 n = len(match)
215 self.process_rawq()
216 i = self.cookedq.find(match)
217 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()
230 i = self.cookedq.find(match, i)
231 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()
238 def read_all(self):
239 """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
248 def read_some(self):
249 """Read at least one byte of cooked data unless EOF is hit.
251 Return '' if EOF is hit. Block if no data is immediately
252 available.
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
263 def read_very_eager(self):
264 """Read everything that's possible without blocking in I/O (eager).
266 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.
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()
277 def read_eager(self):
278 """Read readily available data.
280 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.
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()
291 def read_lazy(self):
292 """Process and return data that's already in the queues (lazy).
294 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.
299 self.process_rawq()
300 return self.read_very_lazy()
302 def read_very_lazy(self):
303 """Return any data available in the cooked queue (very lazy).
305 Raise EOFError if connection closed and no data available.
306 Return '' if no cooked data available otherwise. Don't block.
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
315 def process_rawq(self):
316 """Transfer from raw queue to cooked queue.
318 Set self.eof when connection is closed. Don't block unless in
319 the midst of an IAC sequence.
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))
344 self.sock.send(IAC + DONT + opt)
345 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
351 def rawq_getchar(self):
352 """Get next char from raw queue.
354 Block if no data is immediately available. Raise EOFError
355 when connection is closed.
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
369 def fill_rawq(self):
370 """Fill raw queue from exactly one recv() system call.
372 Block if no data is immediately available. Set self.eof when
373 connection is closed.
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
386 def sock_avail(self):
387 """Test whether data is available on the socket."""
388 return select.select([self], [], [], 0) == ([self], [], [])
390 def interact(self):
391 """Interaction function, emulates a very dumb telnet client."""
392 if sys.platform == "win32":
393 self.mt_interact()
394 return
395 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)
412 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)
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()
435 def expect(self, list, timeout=None):
436 """Read until one from a list of a regular expressions matches.
438 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.
443 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.
447 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).
452 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.
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)
486 def test():
487 """Test program for telnetlib.
489 Usage: python telnetlib.py [-d] ... [host [port]]
491 Default host is localhost; default port is 23.
494 debuglevel = 0
495 while sys.argv[1:] and sys.argv[1] == '-d':
496 debuglevel = debuglevel+1
497 del sys.argv[1]
498 host = 'localhost'
499 if sys.argv[1:]:
500 host = sys.argv[1]
501 port = 0
502 if sys.argv[2:]:
503 portstr = sys.argv[2]
504 try:
505 port = int(portstr)
506 except ValueError:
507 port = socket.getservbyname(portstr, 'tcp')
508 tn = Telnet()
509 tn.set_debuglevel(debuglevel)
510 tn.open(host, port)
511 tn.interact()
512 tn.close()
514 if __name__ == '__main__':
515 test()