changes for 3.0
[monitor.git] / telnetlib.py
1 """TELNET client class.
2
3 Based on RFC 854: TELNET Protocol Specification, by J. Postel and
4 J. Reynolds
5
6 Example:
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()
12 Login       Name               TTY         Idle    When    Where
13 guido    Guido van Rossum      pts/2        <Dec  2 11:10> snag.cnri.reston..
14
15 >>>
16
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.
19
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).
27
28 To do:
29 - option negotiation
30 - timeout should be intrinsic to the connection object instead of an
31   option on one of the read calls only
32
33 """
34
35
36 # Imported modules
37 import sys
38 import socket
39 import select
40
41 __all__ = ["Telnet"]
42
43 # Tunable parameters
44 DEBUGLEVEL = 0
45
46 # Telnet protocol defaults
47 TELNET_PORT = 23
48
49 # Telnet protocol characters (don't change)
50 IAC  = chr(255) # "Interpret As Command"
51 DONT = chr(254)
52 DO   = chr(253)
53 WONT = chr(252)
54 WILL = chr(251)
55 theNULL = chr(0)
56
57 SE  = chr(240)  # Subnegotiation End
58 NOP = chr(241)  # No Operation
59 DM  = chr(242)  # Data Mark
60 BRK = chr(243)  # Break
61 IP  = chr(244)  # Interrupt process
62 AO  = chr(245)  # Abort output
63 AYT = chr(246)  # Are You There
64 EC  = chr(247)  # Erase Character
65 EL  = chr(248)  # Erase Line
66 GA  = chr(249)  # Go Ahead
67 SB =  chr(250)  # Subnegotiation Begin
68
69
70 # Telnet protocol options code (don't change)
71 # These ones all come from arpa/telnet.h
72 BINARY = chr(0) # 8-bit data path
73 ECHO = chr(1) # echo
74 RCP = chr(2) # prepare to reconnect
75 SGA = chr(3) # suppress go ahead
76 NAMS = chr(4) # approximate message size
77 STATUS = chr(5) # give status
78 TM = chr(6) # timing mark
79 RCTE = chr(7) # remote controlled transmission and echo
80 NAOL = chr(8) # negotiate about output line width
81 NAOP = chr(9) # negotiate about output page size
82 NAOCRD = chr(10) # negotiate about CR disposition
83 NAOHTS = chr(11) # negotiate about horizontal tabstops
84 NAOHTD = chr(12) # negotiate about horizontal tab disposition
85 NAOFFD = chr(13) # negotiate about formfeed disposition
86 NAOVTS = chr(14) # negotiate about vertical tab stops
87 NAOVTD = chr(15) # negotiate about vertical tab disposition
88 NAOLFD = chr(16) # negotiate about output LF disposition
89 XASCII = chr(17) # extended ascii character set
90 LOGOUT = chr(18) # force logout
91 BM = chr(19) # byte macro
92 DET = chr(20) # data entry terminal
93 SUPDUP = chr(21) # supdup protocol
94 SUPDUPOUTPUT = chr(22) # supdup output
95 SNDLOC = chr(23) # send location
96 TTYPE = chr(24) # terminal type
97 EOR = chr(25) # end or record
98 TUID = chr(26) # TACACS user identification
99 OUTMRK = chr(27) # output marking
100 TTYLOC = chr(28) # terminal location number
101 VT3270REGIME = chr(29) # 3270 regime
102 X3PAD = chr(30) # X.3 PAD
103 NAWS = chr(31) # window size
104 TSPEED = chr(32) # terminal speed
105 LFLOW = chr(33) # remote flow control
106 LINEMODE = chr(34) # Linemode option
107 XDISPLOC = chr(35) # X Display Location
108 OLD_ENVIRON = chr(36) # Old - Environment variables
109 AUTHENTICATION = chr(37) # Authenticate
110 ENCRYPT = chr(38) # Encryption option
111 NEW_ENVIRON = chr(39) # New - Environment variables
112 # the following ones come from
113 # http://www.iana.org/assignments/telnet-options
114 # Unfortunately, that document does not assign identifiers
115 # to all of them, so we are making them up
116 TN3270E = chr(40) # TN3270E
117 XAUTH = chr(41) # XAUTH
118 CHARSET = chr(42) # CHARSET
119 RSP = chr(43) # Telnet Remote Serial Port
120 COM_PORT_OPTION = chr(44) # Com Port Control Option
121 SUPPRESS_LOCAL_ECHO = chr(45) # Telnet Suppress Local Echo
122 TLS = chr(46) # Telnet Start TLS
123 KERMIT = chr(47) # KERMIT
124 SEND_URL = chr(48) # SEND-URL
125 FORWARD_X = chr(49) # FORWARD_X
126 PRAGMA_LOGON = chr(138) # TELOPT PRAGMA LOGON
127 SSPI_LOGON = chr(139) # TELOPT SSPI LOGON
128 PRAGMA_HEARTBEAT = chr(140) # TELOPT PRAGMA HEARTBEAT
129 EXOPL = chr(255) # Extended-Options-List
130 NOOPT = chr(0)
131
132 class Telnet:
133
134     """Telnet interface class.
135
136     An instance of this class represents a connection to a telnet
137     server.  The instance is initially not connected; the open()
138     method must be used to establish a connection.  Alternatively, the
139     host name and optional port number can be passed to the
140     constructor, too.
141
142     Don't try to reopen an already connected instance.
143
144     This class has many read_*() methods.  Note that some of them
145     raise EOFError when the end of the connection is read, because
146     they can return an empty string for other reasons.  See the
147     individual doc strings.
148
149     read_until(expected, [timeout])
150         Read until the expected string has been seen, or a timeout is
151         hit (default is no timeout); may block.
152
153     read_all()
154         Read all data until EOF; may block.
155
156     read_some()
157         Read at least one byte or EOF; may block.
158
159     read_very_eager()
160         Read all data available already queued or on the socket,
161         without blocking.
162
163     read_eager()
164         Read either data already queued or some data available on the
165         socket, without blocking.
166
167     read_lazy()
168         Read all data in the raw queue (processing it first), without
169         doing any socket I/O.
170
171     read_very_lazy()
172         Reads all data in the cooked queue, without doing any socket
173         I/O.
174
175     read_sb_data()
176         Reads available data between SB ... SE sequence. Don't block.
177
178     set_option_negotiation_callback(callback)
179         Each time a telnet option is read on the input flow, this callback
180         (if set) is called with the following parameters :
181         callback(telnet socket, command, option)
182             option will be chr(0) when there is no option.
183         No other action is done afterwards by telnetlib.
184
185     """
186
187     def __init__(self, host=None, port=0, timeout=None):
188         """Constructor.
189
190         When called without arguments, create an unconnected instance.
191         With a hostname argument, it connects the instance; a port
192         number and connect timeout is optional.
193
194         """
195         self.debuglevel = DEBUGLEVEL
196         self.host = host
197         self.port = port
198         self.sock = None
199         self.rawq = ''
200         self.irawq = 0
201         self.cookedq = ''
202         self.eof = 0
203         self.iacseq = '' # Buffer for IAC sequence.
204         self.sb = 0 # flag for SB and SE sequence.
205         self.sbdataq = ''
206         self.option_callback = None
207         if host is not None:
208             self.open(host, port, timeout)
209
210     def open(self, host, port=0, timeout=None):
211         """Connect to a host.
212
213         The optional second argument is the port number, which
214         defaults to the standard telnet port (23). The optional third
215         argument is a timeout in seconds; if None, the default timeout
216         of the underlying socket will be used.
217
218         Don't try to reopen an already connected instance.
219
220         """
221         self.eof = 0
222         if not port:
223             port = TELNET_PORT
224         self.host = host
225         self.port = port
226         msg = "getaddrinfo returns an empty list"
227         for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
228             af, socktype, proto, canonname, sa = res
229             try:
230                 self.sock = socket.socket(af, socktype, proto)
231                 if timeout is not None:
232                     self.sock.settimeout(timeout)
233                 self.sock.connect(sa)
234             except socket.error, msg:
235                 if self.sock:
236                     self.sock.close()
237                 self.sock = None
238                 continue
239             break
240         if not self.sock:
241             raise socket.error, msg
242
243     def __del__(self):
244         """Destructor -- close the connection."""
245         self.close()
246
247     def msg(self, msg, *args):
248         """Print a debug message, when the debug level is > 0.
249
250         If extra arguments are present, they are substituted in the
251         message using the standard string formatting operator.
252
253         """
254         if self.debuglevel > 0:
255             print 'Telnet(%s,%d):' % (self.host, self.port),
256             if args:
257                 print msg % args
258             else:
259                 print msg
260
261     def set_debuglevel(self, debuglevel):
262         """Set the debug level.
263
264         The higher it is, the more debug output you get (on sys.stdout).
265
266         """
267         self.debuglevel = debuglevel
268
269     def close(self):
270         """Close the connection."""
271         if self.sock:
272             self.sock.close()
273         self.sock = 0
274         self.eof = 1
275         self.iacseq = ''
276         self.sb = 0
277
278     def get_socket(self):
279         """Return the socket object used internally."""
280         return self.sock
281
282     def fileno(self):
283         """Return the fileno() of the socket object used internally."""
284         return self.sock.fileno()
285
286     def write(self, buffer):
287         """Write a string to the socket, doubling any IAC characters.
288
289         Can block if the connection is blocked.  May raise
290         socket.error if the connection is closed.
291
292         """
293         if IAC in buffer:
294             buffer = buffer.replace(IAC, IAC+IAC)
295         self.msg("send %s", `buffer`)
296         self.sock.sendall(buffer)
297
298     def read_until(self, match, timeout=None):
299         """Read until a given string is encountered or until timeout.
300
301         When no match is found, return whatever is available instead,
302         possibly the empty string.  Raise EOFError if the connection
303         is closed and no cooked data is available.
304
305         """
306         n = len(match)
307         self.process_rawq()
308         i = self.cookedq.find(match)
309         if i >= 0:
310             i = i+n
311             buf = self.cookedq[:i]
312             self.cookedq = self.cookedq[i:]
313             return buf
314         s_reply = ([self], [], [])
315         s_args = s_reply
316         if timeout is not None:
317             s_args = s_args + (timeout,)
318         while not self.eof and select.select(*s_args) == s_reply:
319             i = max(0, len(self.cookedq)-n)
320             self.fill_rawq()
321             self.process_rawq()
322             i = self.cookedq.find(match, i)
323             if i >= 0:
324                 i = i+n
325                 buf = self.cookedq[:i]
326                 self.cookedq = self.cookedq[i:]
327                 return buf
328         return self.read_very_lazy()
329
330     def read_all(self):
331         """Read all data until EOF; block until connection closed."""
332         self.process_rawq()
333         while not self.eof:
334             self.fill_rawq()
335             self.process_rawq()
336         buf = self.cookedq
337         self.cookedq = ''
338         return buf
339
340     def read_some(self):
341         """Read at least one byte of cooked data unless EOF is hit.
342
343         Return '' if EOF is hit.  Block if no data is immediately
344         available.
345
346         """
347         self.process_rawq()
348         while not self.cookedq and not self.eof:
349             self.fill_rawq()
350             self.process_rawq()
351         buf = self.cookedq
352         self.cookedq = ''
353         return buf
354
355     def read_very_eager(self):
356         """Read everything that's possible without blocking in I/O (eager).
357
358         Raise EOFError if connection closed and no cooked data
359         available.  Return '' if no cooked data available otherwise.
360         Don't block unless in the midst of an IAC sequence.
361
362         """
363         self.process_rawq()
364         while not self.eof and self.sock_avail():
365             self.fill_rawq()
366             self.process_rawq()
367         return self.read_very_lazy()
368
369     def read_eager(self):
370         """Read readily available data.
371
372         Raise EOFError if connection closed and no cooked data
373         available.  Return '' if no cooked data available otherwise.
374         Don't block unless in the midst of an IAC sequence.
375
376         """
377         self.process_rawq()
378         while not self.cookedq and not self.eof and self.sock_avail():
379             self.fill_rawq()
380             self.process_rawq()
381         return self.read_very_lazy()
382
383     def read_lazy(self):
384         """Process and return data that's already in the queues (lazy).
385
386         Raise EOFError if connection closed and no data available.
387         Return '' if no cooked data available otherwise.  Don't block
388         unless in the midst of an IAC sequence.
389
390         """
391         self.process_rawq()
392         return self.read_very_lazy()
393
394     def read_very_lazy(self):
395         """Return any data available in the cooked queue (very lazy).
396
397         Raise EOFError if connection closed and no data available.
398         Return '' if no cooked data available otherwise.  Don't block.
399
400         """
401         buf = self.cookedq
402         self.cookedq = ''
403         if not buf and self.eof and not self.rawq:
404             raise EOFError, 'telnet connection closed'
405         return buf
406
407     def read_sb_data(self):
408         """Return any data available in the SB ... SE queue.
409
410         Return '' if no SB ... SE available. Should only be called
411         after seeing a SB or SE command. When a new SB command is
412         found, old unread SB data will be discarded. Don't block.
413
414         """
415         buf = self.sbdataq
416         self.sbdataq = ''
417         return buf
418
419     def set_option_negotiation_callback(self, callback):
420         """Provide a callback function called after each receipt of a telnet option."""
421         self.option_callback = callback
422
423     def process_rawq(self):
424         """Transfer from raw queue to cooked queue.
425
426         Set self.eof when connection is closed.  Don't block unless in
427         the midst of an IAC sequence.
428
429         """
430         buf = ['', '']
431         try:
432             while self.rawq:
433                 c = self.rawq_getchar()
434                 if not self.iacseq:
435                     if c == theNULL:
436                         continue
437                     if c == "\021":
438                         continue
439                     if c != IAC:
440                         buf[self.sb] = buf[self.sb] + c
441                         continue
442                     else:
443                         self.iacseq += c
444                 elif len(self.iacseq) == 1:
445                     'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
446                     if c in (DO, DONT, WILL, WONT):
447                         self.iacseq += c
448                         continue
449
450                     self.iacseq = ''
451                     if c == IAC:
452                         buf[self.sb] = buf[self.sb] + c
453                     else:
454                         if c == SB: # SB ... SE start.
455                             self.sb = 1
456                             self.sbdataq = ''
457                         elif c == SE:
458                             self.sb = 0
459                             self.sbdataq = self.sbdataq + buf[1]
460                             buf[1] = ''
461                         if self.option_callback:
462                             # Callback is supposed to look into
463                             # the sbdataq
464                             self.option_callback(self.sock, c, NOOPT)
465                         else:
466                             # We can't offer automatic processing of
467                             # suboptions. Alas, we should not get any
468                             # unless we did a WILL/DO before.
469                             self.msg('IAC %d not recognized' % ord(c))
470                 elif len(self.iacseq) == 2:
471                     cmd = self.iacseq[1]
472                     self.iacseq = ''
473                     opt = c
474                     if cmd in (DO, DONT):
475                         self.msg('IAC %s %d',
476                             cmd == DO and 'DO' or 'DONT', ord(opt))
477                         if self.option_callback:
478                             self.option_callback(self.sock, cmd, opt)
479                         else:
480                             self.sock.sendall(IAC + WONT + opt)
481                     elif cmd in (WILL, WONT):
482                         self.msg('IAC %s %d',
483                             cmd == WILL and 'WILL' or 'WONT', ord(opt))
484                         if self.option_callback:
485                             self.option_callback(self.sock, cmd, opt)
486                         else:
487                             self.sock.sendall(IAC + DONT + opt)
488         except EOFError: # raised by self.rawq_getchar()
489             self.iacseq = '' # Reset on EOF
490             self.sb = 0
491             pass
492         self.cookedq = self.cookedq + buf[0]
493         self.sbdataq = self.sbdataq + buf[1]
494
495     def rawq_getchar(self):
496         """Get next char from raw queue.
497
498         Block if no data is immediately available.  Raise EOFError
499         when connection is closed.
500
501         """
502         if not self.rawq:
503             self.fill_rawq()
504             if self.eof:
505                 raise EOFError
506         c = self.rawq[self.irawq]
507         self.irawq = self.irawq + 1
508         if self.irawq >= len(self.rawq):
509             self.rawq = ''
510             self.irawq = 0
511         return c
512
513     def fill_rawq(self):
514         """Fill raw queue from exactly one recv() system call.
515
516         Block if no data is immediately available.  Set self.eof when
517         connection is closed.
518
519         """
520         if self.irawq >= len(self.rawq):
521             self.rawq = ''
522             self.irawq = 0
523         # The buffer size should be fairly small so as to avoid quadratic
524         # behavior in process_rawq() above
525         buf = self.sock.recv(50)
526         self.msg("recv %s", `buf`)
527         self.eof = (not buf)
528         self.rawq = self.rawq + buf
529
530     def sock_avail(self):
531         """Test whether data is available on the socket."""
532         return select.select([self], [], [], 0) == ([self], [], [])
533
534     def interact(self):
535         """Interaction function, emulates a very dumb telnet client."""
536         if sys.platform == "win32":
537             self.mt_interact()
538             return
539         while 1:
540             rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
541             if self in rfd:
542                 try:
543                     text = self.read_eager()
544                 except EOFError:
545                     print '*** Connection closed by remote host ***'
546                     break
547                 if text:
548                     sys.stdout.write(text)
549                     sys.stdout.flush()
550             if sys.stdin in rfd:
551                 line = sys.stdin.readline()
552                 if not line:
553                     break
554                 self.write(line)
555
556     def mt_interact(self):
557         """Multithreaded version of interact()."""
558         import thread
559         thread.start_new_thread(self.listener, ())
560         while 1:
561             line = sys.stdin.readline()
562             if not line:
563                 break
564             self.write(line)
565
566     def listener(self):
567         """Helper for mt_interact() -- this executes in the other thread."""
568         while 1:
569             try:
570                 data = self.read_eager()
571             except EOFError:
572                 print '*** Connection closed by remote host ***'
573                 return
574             if data:
575                 sys.stdout.write(data)
576             else:
577                 sys.stdout.flush()
578
579     def expect(self, list, timeout=None):
580         """Read until one from a list of a regular expressions matches.
581
582         The first argument is a list of regular expressions, either
583         compiled (re.RegexObject instances) or uncompiled (strings).
584         The optional second argument is a timeout, in seconds; default
585         is no timeout.
586
587         Return a tuple of three items: the index in the list of the
588         first regular expression that matches; the match object
589         returned; and the text read up till and including the match.
590
591         If EOF is read and no text was read, raise EOFError.
592         Otherwise, when nothing matches, return (-1, None, text) where
593         text is the text received so far (may be the empty string if a
594         timeout happened).
595
596         If a regular expression ends with a greedy match (e.g. '.*')
597         or if more than one expression can match the same input, the
598         results are undeterministic, and may depend on the I/O timing.
599
600         """
601         re = None
602         list = list[:]
603         indices = range(len(list))
604         for i in indices:
605             if not hasattr(list[i], "search"):
606                 if not re: import re
607                 list[i] = re.compile(list[i])
608         while 1:
609             self.process_rawq()
610             for i in indices:
611                 m = list[i].search(self.cookedq)
612                 if m:
613                     e = m.end()
614                     text = self.cookedq[:e]
615                     self.cookedq = self.cookedq[e:]
616                     return (i, m, text)
617             if self.eof:
618                 break
619             if timeout is not None:
620                 r, w, x = select.select([self.fileno()], [], [], timeout)
621                 if not r:
622                     break
623             self.fill_rawq()
624         text = self.read_very_lazy()
625         if not text and self.eof:
626             raise EOFError
627         return (-1, None, text)
628
629
630 def test():
631     """Test program for telnetlib.
632
633     Usage: python telnetlib.py [-d] ... [host [port]]
634
635     Default host is localhost; default port is 23.
636
637     """
638     debuglevel = 0
639     while sys.argv[1:] and sys.argv[1] == '-d':
640         debuglevel = debuglevel+1
641         del sys.argv[1]
642     host = 'localhost'
643     if sys.argv[1:]:
644         host = sys.argv[1]
645     port = 0
646     if sys.argv[2:]:
647         portstr = sys.argv[2]
648         try:
649             port = int(portstr)
650         except ValueError:
651             port = socket.getservbyname(portstr, 'tcp')
652     tn = Telnet()
653     tn.set_debuglevel(debuglevel)
654     tn.open(host, port)
655     tn.interact()
656     tn.close()
657
658 if __name__ == '__main__':
659     test()