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