python-2.5.2/win32/Lib/telnetlib.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     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 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):
       
   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 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)
       
   209 
       
   210     def open(self, host, port=0):
       
   211         """Connect to a host.
       
   212 
       
   213         The optional second argument is the port number, which
       
   214         defaults to the standard telnet port (23).
       
   215 
       
   216         Don't try to reopen an already connected instance.
       
   217 
       
   218         """
       
   219         self.eof = 0
       
   220         if not port:
       
   221             port = TELNET_PORT
       
   222         self.host = host
       
   223         self.port = port
       
   224         msg = "getaddrinfo returns an empty list"
       
   225         for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
       
   226             af, socktype, proto, canonname, sa = res
       
   227             try:
       
   228                 self.sock = socket.socket(af, socktype, proto)
       
   229                 self.sock.connect(sa)
       
   230             except socket.error, msg:
       
   231                 if self.sock:
       
   232                     self.sock.close()
       
   233                 self.sock = None
       
   234                 continue
       
   235             break
       
   236         if not self.sock:
       
   237             raise socket.error, msg
       
   238 
       
   239     def __del__(self):
       
   240         """Destructor -- close the connection."""
       
   241         self.close()
       
   242 
       
   243     def msg(self, msg, *args):
       
   244         """Print a debug message, when the debug level is > 0.
       
   245 
       
   246         If extra arguments are present, they are substituted in the
       
   247         message using the standard string formatting operator.
       
   248 
       
   249         """
       
   250         if self.debuglevel > 0:
       
   251             print 'Telnet(%s,%d):' % (self.host, self.port),
       
   252             if args:
       
   253                 print msg % args
       
   254             else:
       
   255                 print msg
       
   256 
       
   257     def set_debuglevel(self, debuglevel):
       
   258         """Set the debug level.
       
   259 
       
   260         The higher it is, the more debug output you get (on sys.stdout).
       
   261 
       
   262         """
       
   263         self.debuglevel = debuglevel
       
   264 
       
   265     def close(self):
       
   266         """Close the connection."""
       
   267         if self.sock:
       
   268             self.sock.close()
       
   269         self.sock = 0
       
   270         self.eof = 1
       
   271         self.iacseq = ''
       
   272         self.sb = 0
       
   273 
       
   274     def get_socket(self):
       
   275         """Return the socket object used internally."""
       
   276         return self.sock
       
   277 
       
   278     def fileno(self):
       
   279         """Return the fileno() of the socket object used internally."""
       
   280         return self.sock.fileno()
       
   281 
       
   282     def write(self, buffer):
       
   283         """Write a string to the socket, doubling any IAC characters.
       
   284 
       
   285         Can block if the connection is blocked.  May raise
       
   286         socket.error if the connection is closed.
       
   287 
       
   288         """
       
   289         if IAC in buffer:
       
   290             buffer = buffer.replace(IAC, IAC+IAC)
       
   291         self.msg("send %r", buffer)
       
   292         self.sock.sendall(buffer)
       
   293 
       
   294     def read_until(self, match, timeout=None):
       
   295         """Read until a given string is encountered or until timeout.
       
   296 
       
   297         When no match is found, return whatever is available instead,
       
   298         possibly the empty string.  Raise EOFError if the connection
       
   299         is closed and no cooked data is available.
       
   300 
       
   301         """
       
   302         n = len(match)
       
   303         self.process_rawq()
       
   304         i = self.cookedq.find(match)
       
   305         if i >= 0:
       
   306             i = i+n
       
   307             buf = self.cookedq[:i]
       
   308             self.cookedq = self.cookedq[i:]
       
   309             return buf
       
   310         s_reply = ([self], [], [])
       
   311         s_args = s_reply
       
   312         if timeout is not None:
       
   313             s_args = s_args + (timeout,)
       
   314             from time import time
       
   315             time_start = time()
       
   316         while not self.eof and select.select(*s_args) == s_reply:
       
   317             i = max(0, len(self.cookedq)-n)
       
   318             self.fill_rawq()
       
   319             self.process_rawq()
       
   320             i = self.cookedq.find(match, i)
       
   321             if i >= 0:
       
   322                 i = i+n
       
   323                 buf = self.cookedq[:i]
       
   324                 self.cookedq = self.cookedq[i:]
       
   325                 return buf
       
   326             if timeout is not None:
       
   327                 elapsed = time() - time_start
       
   328                 if elapsed >= timeout:
       
   329                     break
       
   330                 s_args = s_reply + (timeout-elapsed,)
       
   331         return self.read_very_lazy()
       
   332 
       
   333     def read_all(self):
       
   334         """Read all data until EOF; block until connection closed."""
       
   335         self.process_rawq()
       
   336         while not self.eof:
       
   337             self.fill_rawq()
       
   338             self.process_rawq()
       
   339         buf = self.cookedq
       
   340         self.cookedq = ''
       
   341         return buf
       
   342 
       
   343     def read_some(self):
       
   344         """Read at least one byte of cooked data unless EOF is hit.
       
   345 
       
   346         Return '' if EOF is hit.  Block if no data is immediately
       
   347         available.
       
   348 
       
   349         """
       
   350         self.process_rawq()
       
   351         while not self.cookedq and not self.eof:
       
   352             self.fill_rawq()
       
   353             self.process_rawq()
       
   354         buf = self.cookedq
       
   355         self.cookedq = ''
       
   356         return buf
       
   357 
       
   358     def read_very_eager(self):
       
   359         """Read everything that's possible without blocking in I/O (eager).
       
   360 
       
   361         Raise EOFError if connection closed and no cooked data
       
   362         available.  Return '' if no cooked data available otherwise.
       
   363         Don't block unless in the midst of an IAC sequence.
       
   364 
       
   365         """
       
   366         self.process_rawq()
       
   367         while not self.eof and self.sock_avail():
       
   368             self.fill_rawq()
       
   369             self.process_rawq()
       
   370         return self.read_very_lazy()
       
   371 
       
   372     def read_eager(self):
       
   373         """Read readily available data.
       
   374 
       
   375         Raise EOFError if connection closed and no cooked data
       
   376         available.  Return '' if no cooked data available otherwise.
       
   377         Don't block unless in the midst of an IAC sequence.
       
   378 
       
   379         """
       
   380         self.process_rawq()
       
   381         while not self.cookedq and not self.eof and self.sock_avail():
       
   382             self.fill_rawq()
       
   383             self.process_rawq()
       
   384         return self.read_very_lazy()
       
   385 
       
   386     def read_lazy(self):
       
   387         """Process and return data that's already in the queues (lazy).
       
   388 
       
   389         Raise EOFError if connection closed and no data available.
       
   390         Return '' if no cooked data available otherwise.  Don't block
       
   391         unless in the midst of an IAC sequence.
       
   392 
       
   393         """
       
   394         self.process_rawq()
       
   395         return self.read_very_lazy()
       
   396 
       
   397     def read_very_lazy(self):
       
   398         """Return any data available in the cooked queue (very lazy).
       
   399 
       
   400         Raise EOFError if connection closed and no data available.
       
   401         Return '' if no cooked data available otherwise.  Don't block.
       
   402 
       
   403         """
       
   404         buf = self.cookedq
       
   405         self.cookedq = ''
       
   406         if not buf and self.eof and not self.rawq:
       
   407             raise EOFError, 'telnet connection closed'
       
   408         return buf
       
   409 
       
   410     def read_sb_data(self):
       
   411         """Return any data available in the SB ... SE queue.
       
   412 
       
   413         Return '' if no SB ... SE available. Should only be called
       
   414         after seeing a SB or SE command. When a new SB command is
       
   415         found, old unread SB data will be discarded. Don't block.
       
   416 
       
   417         """
       
   418         buf = self.sbdataq
       
   419         self.sbdataq = ''
       
   420         return buf
       
   421 
       
   422     def set_option_negotiation_callback(self, callback):
       
   423         """Provide a callback function called after each receipt of a telnet option."""
       
   424         self.option_callback = callback
       
   425 
       
   426     def process_rawq(self):
       
   427         """Transfer from raw queue to cooked queue.
       
   428 
       
   429         Set self.eof when connection is closed.  Don't block unless in
       
   430         the midst of an IAC sequence.
       
   431 
       
   432         """
       
   433         buf = ['', '']
       
   434         try:
       
   435             while self.rawq:
       
   436                 c = self.rawq_getchar()
       
   437                 if not self.iacseq:
       
   438                     if c == theNULL:
       
   439                         continue
       
   440                     if c == "\021":
       
   441                         continue
       
   442                     if c != IAC:
       
   443                         buf[self.sb] = buf[self.sb] + c
       
   444                         continue
       
   445                     else:
       
   446                         self.iacseq += c
       
   447                 elif len(self.iacseq) == 1:
       
   448                     # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
       
   449                     if c in (DO, DONT, WILL, WONT):
       
   450                         self.iacseq += c
       
   451                         continue
       
   452 
       
   453                     self.iacseq = ''
       
   454                     if c == IAC:
       
   455                         buf[self.sb] = buf[self.sb] + c
       
   456                     else:
       
   457                         if c == SB: # SB ... SE start.
       
   458                             self.sb = 1
       
   459                             self.sbdataq = ''
       
   460                         elif c == SE:
       
   461                             self.sb = 0
       
   462                             self.sbdataq = self.sbdataq + buf[1]
       
   463                             buf[1] = ''
       
   464                         if self.option_callback:
       
   465                             # Callback is supposed to look into
       
   466                             # the sbdataq
       
   467                             self.option_callback(self.sock, c, NOOPT)
       
   468                         else:
       
   469                             # We can't offer automatic processing of
       
   470                             # suboptions. Alas, we should not get any
       
   471                             # unless we did a WILL/DO before.
       
   472                             self.msg('IAC %d not recognized' % ord(c))
       
   473                 elif len(self.iacseq) == 2:
       
   474                     cmd = self.iacseq[1]
       
   475                     self.iacseq = ''
       
   476                     opt = c
       
   477                     if cmd in (DO, DONT):
       
   478                         self.msg('IAC %s %d',
       
   479                             cmd == DO and 'DO' or 'DONT', ord(opt))
       
   480                         if self.option_callback:
       
   481                             self.option_callback(self.sock, cmd, opt)
       
   482                         else:
       
   483                             self.sock.sendall(IAC + WONT + opt)
       
   484                     elif cmd in (WILL, WONT):
       
   485                         self.msg('IAC %s %d',
       
   486                             cmd == WILL and 'WILL' or 'WONT', ord(opt))
       
   487                         if self.option_callback:
       
   488                             self.option_callback(self.sock, cmd, opt)
       
   489                         else:
       
   490                             self.sock.sendall(IAC + DONT + opt)
       
   491         except EOFError: # raised by self.rawq_getchar()
       
   492             self.iacseq = '' # Reset on EOF
       
   493             self.sb = 0
       
   494             pass
       
   495         self.cookedq = self.cookedq + buf[0]
       
   496         self.sbdataq = self.sbdataq + buf[1]
       
   497 
       
   498     def rawq_getchar(self):
       
   499         """Get next char from raw queue.
       
   500 
       
   501         Block if no data is immediately available.  Raise EOFError
       
   502         when connection is closed.
       
   503 
       
   504         """
       
   505         if not self.rawq:
       
   506             self.fill_rawq()
       
   507             if self.eof:
       
   508                 raise EOFError
       
   509         c = self.rawq[self.irawq]
       
   510         self.irawq = self.irawq + 1
       
   511         if self.irawq >= len(self.rawq):
       
   512             self.rawq = ''
       
   513             self.irawq = 0
       
   514         return c
       
   515 
       
   516     def fill_rawq(self):
       
   517         """Fill raw queue from exactly one recv() system call.
       
   518 
       
   519         Block if no data is immediately available.  Set self.eof when
       
   520         connection is closed.
       
   521 
       
   522         """
       
   523         if self.irawq >= len(self.rawq):
       
   524             self.rawq = ''
       
   525             self.irawq = 0
       
   526         # The buffer size should be fairly small so as to avoid quadratic
       
   527         # behavior in process_rawq() above
       
   528         buf = self.sock.recv(50)
       
   529         self.msg("recv %r", buf)
       
   530         self.eof = (not buf)
       
   531         self.rawq = self.rawq + buf
       
   532 
       
   533     def sock_avail(self):
       
   534         """Test whether data is available on the socket."""
       
   535         return select.select([self], [], [], 0) == ([self], [], [])
       
   536 
       
   537     def interact(self):
       
   538         """Interaction function, emulates a very dumb telnet client."""
       
   539         if sys.platform == "win32":
       
   540             self.mt_interact()
       
   541             return
       
   542         while 1:
       
   543             rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
       
   544             if self in rfd:
       
   545                 try:
       
   546                     text = self.read_eager()
       
   547                 except EOFError:
       
   548                     print '*** Connection closed by remote host ***'
       
   549                     break
       
   550                 if text:
       
   551                     sys.stdout.write(text)
       
   552                     sys.stdout.flush()
       
   553             if sys.stdin in rfd:
       
   554                 line = sys.stdin.readline()
       
   555                 if not line:
       
   556                     break
       
   557                 self.write(line)
       
   558 
       
   559     def mt_interact(self):
       
   560         """Multithreaded version of interact()."""
       
   561         import thread
       
   562         thread.start_new_thread(self.listener, ())
       
   563         while 1:
       
   564             line = sys.stdin.readline()
       
   565             if not line:
       
   566                 break
       
   567             self.write(line)
       
   568 
       
   569     def listener(self):
       
   570         """Helper for mt_interact() -- this executes in the other thread."""
       
   571         while 1:
       
   572             try:
       
   573                 data = self.read_eager()
       
   574             except EOFError:
       
   575                 print '*** Connection closed by remote host ***'
       
   576                 return
       
   577             if data:
       
   578                 sys.stdout.write(data)
       
   579             else:
       
   580                 sys.stdout.flush()
       
   581 
       
   582     def expect(self, list, timeout=None):
       
   583         """Read until one from a list of a regular expressions matches.
       
   584 
       
   585         The first argument is a list of regular expressions, either
       
   586         compiled (re.RegexObject instances) or uncompiled (strings).
       
   587         The optional second argument is a timeout, in seconds; default
       
   588         is no timeout.
       
   589 
       
   590         Return a tuple of three items: the index in the list of the
       
   591         first regular expression that matches; the match object
       
   592         returned; and the text read up till and including the match.
       
   593 
       
   594         If EOF is read and no text was read, raise EOFError.
       
   595         Otherwise, when nothing matches, return (-1, None, text) where
       
   596         text is the text received so far (may be the empty string if a
       
   597         timeout happened).
       
   598 
       
   599         If a regular expression ends with a greedy match (e.g. '.*')
       
   600         or if more than one expression can match the same input, the
       
   601         results are undeterministic, and may depend on the I/O timing.
       
   602 
       
   603         """
       
   604         re = None
       
   605         list = list[:]
       
   606         indices = range(len(list))
       
   607         for i in indices:
       
   608             if not hasattr(list[i], "search"):
       
   609                 if not re: import re
       
   610                 list[i] = re.compile(list[i])
       
   611         if timeout is not None:
       
   612             from time import time
       
   613             time_start = time()
       
   614         while 1:
       
   615             self.process_rawq()
       
   616             for i in indices:
       
   617                 m = list[i].search(self.cookedq)
       
   618                 if m:
       
   619                     e = m.end()
       
   620                     text = self.cookedq[:e]
       
   621                     self.cookedq = self.cookedq[e:]
       
   622                     return (i, m, text)
       
   623             if self.eof:
       
   624                 break
       
   625             if timeout is not None:
       
   626                 elapsed = time() - time_start
       
   627                 if elapsed >= timeout:
       
   628                     break
       
   629                 s_args = ([self.fileno()], [], [], timeout-elapsed)
       
   630                 r, w, x = select.select(*s_args)
       
   631                 if not r:
       
   632                     break
       
   633             self.fill_rawq()
       
   634         text = self.read_very_lazy()
       
   635         if not text and self.eof:
       
   636             raise EOFError
       
   637         return (-1, None, text)
       
   638 
       
   639 
       
   640 def test():
       
   641     """Test program for telnetlib.
       
   642 
       
   643     Usage: python telnetlib.py [-d] ... [host [port]]
       
   644 
       
   645     Default host is localhost; default port is 23.
       
   646 
       
   647     """
       
   648     debuglevel = 0
       
   649     while sys.argv[1:] and sys.argv[1] == '-d':
       
   650         debuglevel = debuglevel+1
       
   651         del sys.argv[1]
       
   652     host = 'localhost'
       
   653     if sys.argv[1:]:
       
   654         host = sys.argv[1]
       
   655     port = 0
       
   656     if sys.argv[2:]:
       
   657         portstr = sys.argv[2]
       
   658         try:
       
   659             port = int(portstr)
       
   660         except ValueError:
       
   661             port = socket.getservbyname(portstr, 'tcp')
       
   662     tn = Telnet()
       
   663     tn.set_debuglevel(debuglevel)
       
   664     tn.open(host, port)
       
   665     tn.interact()
       
   666     tn.close()
       
   667 
       
   668 if __name__ == '__main__':
       
   669     test()