PyXR

c:\python24\lib \ telnetlib.py



0001 """TELNET client class.
0002 
0003 Based on RFC 854: TELNET Protocol Specification, by J. Postel and
0004 J. Reynolds
0005 
0006 Example:
0007 
0008 >>> from telnetlib import Telnet
0009 >>> tn = Telnet('www.python.org', 79)   # connect to finger port
0010 >>> tn.write('guido\r\n')
0011 >>> print tn.read_all()
0012 Login       Name               TTY         Idle    When    Where
0013 guido    Guido van Rossum      pts/2        <Dec  2 11:10> snag.cnri.reston..
0014 
0015 >>>
0016 
0017 Note that read_all() won't read until eof -- it just reads some data
0018 -- but it guarantees to read at least one byte unless EOF is hit.
0019 
0020 It is possible to pass a Telnet object to select.select() in order to
0021 wait until more data is available.  Note that in this case,
0022 read_eager() may return '' even if there was data on the socket,
0023 because the protocol negotiation may have eaten the data.  This is why
0024 EOFError is needed in some cases to distinguish between "no data" and
0025 "connection closed" (since the socket also appears ready for reading
0026 when it is closed).
0027 
0028 To do:
0029 - option negotiation
0030 - timeout should be intrinsic to the connection object instead of an
0031   option on one of the read calls only
0032 
0033 """
0034 
0035 
0036 # Imported modules
0037 import sys
0038 import socket
0039 import select
0040 
0041 __all__ = ["Telnet"]
0042 
0043 # Tunable parameters
0044 DEBUGLEVEL = 0
0045 
0046 # Telnet protocol defaults
0047 TELNET_PORT = 23
0048 
0049 # Telnet protocol characters (don't change)
0050 IAC  = chr(255) # "Interpret As Command"
0051 DONT = chr(254)
0052 DO   = chr(253)
0053 WONT = chr(252)
0054 WILL = chr(251)
0055 theNULL = chr(0)
0056 
0057 SE  = chr(240)  # Subnegotiation End
0058 NOP = chr(241)  # No Operation
0059 DM  = chr(242)  # Data Mark
0060 BRK = chr(243)  # Break
0061 IP  = chr(244)  # Interrupt process
0062 AO  = chr(245)  # Abort output
0063 AYT = chr(246)  # Are You There
0064 EC  = chr(247)  # Erase Character
0065 EL  = chr(248)  # Erase Line
0066 GA  = chr(249)  # Go Ahead
0067 SB =  chr(250)  # Subnegotiation Begin
0068 
0069 
0070 # Telnet protocol options code (don't change)
0071 # These ones all come from arpa/telnet.h
0072 BINARY = chr(0) # 8-bit data path
0073 ECHO = chr(1) # echo
0074 RCP = chr(2) # prepare to reconnect
0075 SGA = chr(3) # suppress go ahead
0076 NAMS = chr(4) # approximate message size
0077 STATUS = chr(5) # give status
0078 TM = chr(6) # timing mark
0079 RCTE = chr(7) # remote controlled transmission and echo
0080 NAOL = chr(8) # negotiate about output line width
0081 NAOP = chr(9) # negotiate about output page size
0082 NAOCRD = chr(10) # negotiate about CR disposition
0083 NAOHTS = chr(11) # negotiate about horizontal tabstops
0084 NAOHTD = chr(12) # negotiate about horizontal tab disposition
0085 NAOFFD = chr(13) # negotiate about formfeed disposition
0086 NAOVTS = chr(14) # negotiate about vertical tab stops
0087 NAOVTD = chr(15) # negotiate about vertical tab disposition
0088 NAOLFD = chr(16) # negotiate about output LF disposition
0089 XASCII = chr(17) # extended ascii character set
0090 LOGOUT = chr(18) # force logout
0091 BM = chr(19) # byte macro
0092 DET = chr(20) # data entry terminal
0093 SUPDUP = chr(21) # supdup protocol
0094 SUPDUPOUTPUT = chr(22) # supdup output
0095 SNDLOC = chr(23) # send location
0096 TTYPE = chr(24) # terminal type
0097 EOR = chr(25) # end or record
0098 TUID = chr(26) # TACACS user identification
0099 OUTMRK = chr(27) # output marking
0100 TTYLOC = chr(28) # terminal location number
0101 VT3270REGIME = chr(29) # 3270 regime
0102 X3PAD = chr(30) # X.3 PAD
0103 NAWS = chr(31) # window size
0104 TSPEED = chr(32) # terminal speed
0105 LFLOW = chr(33) # remote flow control
0106 LINEMODE = chr(34) # Linemode option
0107 XDISPLOC = chr(35) # X Display Location
0108 OLD_ENVIRON = chr(36) # Old - Environment variables
0109 AUTHENTICATION = chr(37) # Authenticate
0110 ENCRYPT = chr(38) # Encryption option
0111 NEW_ENVIRON = chr(39) # New - Environment variables
0112 # the following ones come from
0113 # http://www.iana.org/assignments/telnet-options
0114 # Unfortunately, that document does not assign identifiers
0115 # to all of them, so we are making them up
0116 TN3270E = chr(40) # TN3270E
0117 XAUTH = chr(41) # XAUTH
0118 CHARSET = chr(42) # CHARSET
0119 RSP = chr(43) # Telnet Remote Serial Port
0120 COM_PORT_OPTION = chr(44) # Com Port Control Option
0121 SUPPRESS_LOCAL_ECHO = chr(45) # Telnet Suppress Local Echo
0122 TLS = chr(46) # Telnet Start TLS
0123 KERMIT = chr(47) # KERMIT
0124 SEND_URL = chr(48) # SEND-URL
0125 FORWARD_X = chr(49) # FORWARD_X
0126 PRAGMA_LOGON = chr(138) # TELOPT PRAGMA LOGON
0127 SSPI_LOGON = chr(139) # TELOPT SSPI LOGON
0128 PRAGMA_HEARTBEAT = chr(140) # TELOPT PRAGMA HEARTBEAT
0129 EXOPL = chr(255) # Extended-Options-List
0130 NOOPT = chr(0)
0131 
0132 class Telnet:
0133 
0134     """Telnet interface class.
0135 
0136     An instance of this class represents a connection to a telnet
0137     server.  The instance is initially not connected; the open()
0138     method must be used to establish a connection.  Alternatively, the
0139     host name and optional port number can be passed to the
0140     constructor, too.
0141 
0142     Don't try to reopen an already connected instance.
0143 
0144     This class has many read_*() methods.  Note that some of them
0145     raise EOFError when the end of the connection is read, because
0146     they can return an empty string for other reasons.  See the
0147     individual doc strings.
0148 
0149     read_until(expected, [timeout])
0150         Read until the expected string has been seen, or a timeout is
0151         hit (default is no timeout); may block.
0152 
0153     read_all()
0154         Read all data until EOF; may block.
0155 
0156     read_some()
0157         Read at least one byte or EOF; may block.
0158 
0159     read_very_eager()
0160         Read all data available already queued or on the socket,
0161         without blocking.
0162 
0163     read_eager()
0164         Read either data already queued or some data available on the
0165         socket, without blocking.
0166 
0167     read_lazy()
0168         Read all data in the raw queue (processing it first), without
0169         doing any socket I/O.
0170 
0171     read_very_lazy()
0172         Reads all data in the cooked queue, without doing any socket
0173         I/O.
0174 
0175     read_sb_data()
0176         Reads available data between SB ... SE sequence. Don't block.
0177 
0178     set_option_negotiation_callback(callback)
0179         Each time a telnet option is read on the input flow, this callback
0180         (if set) is called with the following parameters :
0181         callback(telnet socket, command, option)
0182             option will be chr(0) when there is no option.
0183         No other action is done afterwards by telnetlib.
0184 
0185     """
0186 
0187     def __init__(self, host=None, port=0):
0188         """Constructor.
0189 
0190         When called without arguments, create an unconnected instance.
0191         With a hostname argument, it connects the instance; a port
0192         number is optional.
0193 
0194         """
0195         self.debuglevel = DEBUGLEVEL
0196         self.host = host
0197         self.port = port
0198         self.sock = None
0199         self.rawq = ''
0200         self.irawq = 0
0201         self.cookedq = ''
0202         self.eof = 0
0203         self.iacseq = '' # Buffer for IAC sequence.
0204         self.sb = 0 # flag for SB and SE sequence.
0205         self.sbdataq = ''
0206         self.option_callback = None
0207         if host is not None:
0208             self.open(host, port)
0209 
0210     def open(self, host, port=0):
0211         """Connect to a host.
0212 
0213         The optional second argument is the port number, which
0214         defaults to the standard telnet port (23).
0215 
0216         Don't try to reopen an already connected instance.
0217 
0218         """
0219         self.eof = 0
0220         if not port:
0221             port = TELNET_PORT
0222         self.host = host
0223         self.port = port
0224         msg = "getaddrinfo returns an empty list"
0225         for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
0226             af, socktype, proto, canonname, sa = res
0227             try:
0228                 self.sock = socket.socket(af, socktype, proto)
0229                 self.sock.connect(sa)
0230             except socket.error, msg:
0231                 if self.sock:
0232                     self.sock.close()
0233                 self.sock = None
0234                 continue
0235             break
0236         if not self.sock:
0237             raise socket.error, msg
0238 
0239     def __del__(self):
0240         """Destructor -- close the connection."""
0241         self.close()
0242 
0243     def msg(self, msg, *args):
0244         """Print a debug message, when the debug level is > 0.
0245 
0246         If extra arguments are present, they are substituted in the
0247         message using the standard string formatting operator.
0248 
0249         """
0250         if self.debuglevel > 0:
0251             print 'Telnet(%s,%d):' % (self.host, self.port),
0252             if args:
0253                 print msg % args
0254             else:
0255                 print msg
0256 
0257     def set_debuglevel(self, debuglevel):
0258         """Set the debug level.
0259 
0260         The higher it is, the more debug output you get (on sys.stdout).
0261 
0262         """
0263         self.debuglevel = debuglevel
0264 
0265     def close(self):
0266         """Close the connection."""
0267         if self.sock:
0268             self.sock.close()
0269         self.sock = 0
0270         self.eof = 1
0271         self.iacseq = ''
0272         self.sb = 0
0273 
0274     def get_socket(self):
0275         """Return the socket object used internally."""
0276         return self.sock
0277 
0278     def fileno(self):
0279         """Return the fileno() of the socket object used internally."""
0280         return self.sock.fileno()
0281 
0282     def write(self, buffer):
0283         """Write a string to the socket, doubling any IAC characters.
0284 
0285         Can block if the connection is blocked.  May raise
0286         socket.error if the connection is closed.
0287 
0288         """
0289         if IAC in buffer:
0290             buffer = buffer.replace(IAC, IAC+IAC)
0291         self.msg("send %r", buffer)
0292         self.sock.sendall(buffer)
0293 
0294     def read_until(self, match, timeout=None):
0295         """Read until a given string is encountered or until timeout.
0296 
0297         When no match is found, return whatever is available instead,
0298         possibly the empty string.  Raise EOFError if the connection
0299         is closed and no cooked data is available.
0300 
0301         """
0302         n = len(match)
0303         self.process_rawq()
0304         i = self.cookedq.find(match)
0305         if i >= 0:
0306             i = i+n
0307             buf = self.cookedq[:i]
0308             self.cookedq = self.cookedq[i:]
0309             return buf
0310         s_reply = ([self], [], [])
0311         s_args = s_reply
0312         if timeout is not None:
0313             s_args = s_args + (timeout,)
0314         while not self.eof and select.select(*s_args) == s_reply:
0315             i = max(0, len(self.cookedq)-n)
0316             self.fill_rawq()
0317             self.process_rawq()
0318             i = self.cookedq.find(match, i)
0319             if i >= 0:
0320                 i = i+n
0321                 buf = self.cookedq[:i]
0322                 self.cookedq = self.cookedq[i:]
0323                 return buf
0324         return self.read_very_lazy()
0325 
0326     def read_all(self):
0327         """Read all data until EOF; block until connection closed."""
0328         self.process_rawq()
0329         while not self.eof:
0330             self.fill_rawq()
0331             self.process_rawq()
0332         buf = self.cookedq
0333         self.cookedq = ''
0334         return buf
0335 
0336     def read_some(self):
0337         """Read at least one byte of cooked data unless EOF is hit.
0338 
0339         Return '' if EOF is hit.  Block if no data is immediately
0340         available.
0341 
0342         """
0343         self.process_rawq()
0344         while not self.cookedq and not self.eof:
0345             self.fill_rawq()
0346             self.process_rawq()
0347         buf = self.cookedq
0348         self.cookedq = ''
0349         return buf
0350 
0351     def read_very_eager(self):
0352         """Read everything that's possible without blocking in I/O (eager).
0353 
0354         Raise EOFError if connection closed and no cooked data
0355         available.  Return '' if no cooked data available otherwise.
0356         Don't block unless in the midst of an IAC sequence.
0357 
0358         """
0359         self.process_rawq()
0360         while not self.eof and self.sock_avail():
0361             self.fill_rawq()
0362             self.process_rawq()
0363         return self.read_very_lazy()
0364 
0365     def read_eager(self):
0366         """Read readily available data.
0367 
0368         Raise EOFError if connection closed and no cooked data
0369         available.  Return '' if no cooked data available otherwise.
0370         Don't block unless in the midst of an IAC sequence.
0371 
0372         """
0373         self.process_rawq()
0374         while not self.cookedq and not self.eof and self.sock_avail():
0375             self.fill_rawq()
0376             self.process_rawq()
0377         return self.read_very_lazy()
0378 
0379     def read_lazy(self):
0380         """Process and return data that's already in the queues (lazy).
0381 
0382         Raise EOFError if connection closed and no data available.
0383         Return '' if no cooked data available otherwise.  Don't block
0384         unless in the midst of an IAC sequence.
0385 
0386         """
0387         self.process_rawq()
0388         return self.read_very_lazy()
0389 
0390     def read_very_lazy(self):
0391         """Return any data available in the cooked queue (very lazy).
0392 
0393         Raise EOFError if connection closed and no data available.
0394         Return '' if no cooked data available otherwise.  Don't block.
0395 
0396         """
0397         buf = self.cookedq
0398         self.cookedq = ''
0399         if not buf and self.eof and not self.rawq:
0400             raise EOFError, 'telnet connection closed'
0401         return buf
0402 
0403     def read_sb_data(self):
0404         """Return any data available in the SB ... SE queue.
0405 
0406         Return '' if no SB ... SE available. Should only be called
0407         after seeing a SB or SE command. When a new SB command is
0408         found, old unread SB data will be discarded. Don't block.
0409 
0410         """
0411         buf = self.sbdataq
0412         self.sbdataq = ''
0413         return buf
0414 
0415     def set_option_negotiation_callback(self, callback):
0416         """Provide a callback function called after each receipt of a telnet option."""
0417         self.option_callback = callback
0418 
0419     def process_rawq(self):
0420         """Transfer from raw queue to cooked queue.
0421 
0422         Set self.eof when connection is closed.  Don't block unless in
0423         the midst of an IAC sequence.
0424 
0425         """
0426         buf = ['', '']
0427         try:
0428             while self.rawq:
0429                 c = self.rawq_getchar()
0430                 if not self.iacseq:
0431                     if c == theNULL:
0432                         continue
0433                     if c == "\021":
0434                         continue
0435                     if c != IAC:
0436                         buf[self.sb] = buf[self.sb] + c
0437                         continue
0438                     else:
0439                         self.iacseq += c
0440                 elif len(self.iacseq) == 1:
0441                     'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
0442                     if c in (DO, DONT, WILL, WONT):
0443                         self.iacseq += c
0444                         continue
0445 
0446                     self.iacseq = ''
0447                     if c == IAC:
0448                         buf[self.sb] = buf[self.sb] + c
0449                     else:
0450                         if c == SB: # SB ... SE start.
0451                             self.sb = 1
0452                             self.sbdataq = ''
0453                         elif c == SE:
0454                             self.sb = 0
0455                             self.sbdataq = self.sbdataq + buf[1]
0456                             buf[1] = ''
0457                         if self.option_callback:
0458                             # Callback is supposed to look into
0459                             # the sbdataq
0460                             self.option_callback(self.sock, c, NOOPT)
0461                         else:
0462                             # We can't offer automatic processing of
0463                             # suboptions. Alas, we should not get any
0464                             # unless we did a WILL/DO before.
0465                             self.msg('IAC %d not recognized' % ord(c))
0466                 elif len(self.iacseq) == 2:
0467                     cmd = self.iacseq[1]
0468                     self.iacseq = ''
0469                     opt = c
0470                     if cmd in (DO, DONT):
0471                         self.msg('IAC %s %d',
0472                             cmd == DO and 'DO' or 'DONT', ord(opt))
0473                         if self.option_callback:
0474                             self.option_callback(self.sock, cmd, opt)
0475                         else:
0476                             self.sock.sendall(IAC + WONT + opt)
0477                     elif cmd in (WILL, WONT):
0478                         self.msg('IAC %s %d',
0479                             cmd == WILL and 'WILL' or 'WONT', ord(opt))
0480                         if self.option_callback:
0481                             self.option_callback(self.sock, cmd, opt)
0482                         else:
0483                             self.sock.sendall(IAC + DONT + opt)
0484         except EOFError: # raised by self.rawq_getchar()
0485             self.iacseq = '' # Reset on EOF
0486             self.sb = 0
0487             pass
0488         self.cookedq = self.cookedq + buf[0]
0489         self.sbdataq = self.sbdataq + buf[1]
0490 
0491     def rawq_getchar(self):
0492         """Get next char from raw queue.
0493 
0494         Block if no data is immediately available.  Raise EOFError
0495         when connection is closed.
0496 
0497         """
0498         if not self.rawq:
0499             self.fill_rawq()
0500             if self.eof:
0501                 raise EOFError
0502         c = self.rawq[self.irawq]
0503         self.irawq = self.irawq + 1
0504         if self.irawq >= len(self.rawq):
0505             self.rawq = ''
0506             self.irawq = 0
0507         return c
0508 
0509     def fill_rawq(self):
0510         """Fill raw queue from exactly one recv() system call.
0511 
0512         Block if no data is immediately available.  Set self.eof when
0513         connection is closed.
0514 
0515         """
0516         if self.irawq >= len(self.rawq):
0517             self.rawq = ''
0518             self.irawq = 0
0519         # The buffer size should be fairly small so as to avoid quadratic
0520         # behavior in process_rawq() above
0521         buf = self.sock.recv(50)
0522         self.msg("recv %r", buf)
0523         self.eof = (not buf)
0524         self.rawq = self.rawq + buf
0525 
0526     def sock_avail(self):
0527         """Test whether data is available on the socket."""
0528         return select.select([self], [], [], 0) == ([self], [], [])
0529 
0530     def interact(self):
0531         """Interaction function, emulates a very dumb telnet client."""
0532         if sys.platform == "win32":
0533             self.mt_interact()
0534             return
0535         while 1:
0536             rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
0537             if self in rfd:
0538                 try:
0539                     text = self.read_eager()
0540                 except EOFError:
0541                     print '*** Connection closed by remote host ***'
0542                     break
0543                 if text:
0544                     sys.stdout.write(text)
0545                     sys.stdout.flush()
0546             if sys.stdin in rfd:
0547                 line = sys.stdin.readline()
0548                 if not line:
0549                     break
0550                 self.write(line)
0551 
0552     def mt_interact(self):
0553         """Multithreaded version of interact()."""
0554         import thread
0555         thread.start_new_thread(self.listener, ())
0556         while 1:
0557             line = sys.stdin.readline()
0558             if not line:
0559                 break
0560             self.write(line)
0561 
0562     def listener(self):
0563         """Helper for mt_interact() -- this executes in the other thread."""
0564         while 1:
0565             try:
0566                 data = self.read_eager()
0567             except EOFError:
0568                 print '*** Connection closed by remote host ***'
0569                 return
0570             if data:
0571                 sys.stdout.write(data)
0572             else:
0573                 sys.stdout.flush()
0574 
0575     def expect(self, list, timeout=None):
0576         """Read until one from a list of a regular expressions matches.
0577 
0578         The first argument is a list of regular expressions, either
0579         compiled (re.RegexObject instances) or uncompiled (strings).
0580         The optional second argument is a timeout, in seconds; default
0581         is no timeout.
0582 
0583         Return a tuple of three items: the index in the list of the
0584         first regular expression that matches; the match object
0585         returned; and the text read up till and including the match.
0586 
0587         If EOF is read and no text was read, raise EOFError.
0588         Otherwise, when nothing matches, return (-1, None, text) where
0589         text is the text received so far (may be the empty string if a
0590         timeout happened).
0591 
0592         If a regular expression ends with a greedy match (e.g. '.*')
0593         or if more than one expression can match the same input, the
0594         results are undeterministic, and may depend on the I/O timing.
0595 
0596         """
0597         re = None
0598         list = list[:]
0599         indices = range(len(list))
0600         for i in indices:
0601             if not hasattr(list[i], "search"):
0602                 if not re: import re
0603                 list[i] = re.compile(list[i])
0604         while 1:
0605             self.process_rawq()
0606             for i in indices:
0607                 m = list[i].search(self.cookedq)
0608                 if m:
0609                     e = m.end()
0610                     text = self.cookedq[:e]
0611                     self.cookedq = self.cookedq[e:]
0612                     return (i, m, text)
0613             if self.eof:
0614                 break
0615             if timeout is not None:
0616                 r, w, x = select.select([self.fileno()], [], [], timeout)
0617                 if not r:
0618                     break
0619             self.fill_rawq()
0620         text = self.read_very_lazy()
0621         if not text and self.eof:
0622             raise EOFError
0623         return (-1, None, text)
0624 
0625 
0626 def test():
0627     """Test program for telnetlib.
0628 
0629     Usage: python telnetlib.py [-d] ... [host [port]]
0630 
0631     Default host is localhost; default port is 23.
0632 
0633     """
0634     debuglevel = 0
0635     while sys.argv[1:] and sys.argv[1] == '-d':
0636         debuglevel = debuglevel+1
0637         del sys.argv[1]
0638     host = 'localhost'
0639     if sys.argv[1:]:
0640         host = sys.argv[1]
0641     port = 0
0642     if sys.argv[2:]:
0643         portstr = sys.argv[2]
0644         try:
0645             port = int(portstr)
0646         except ValueError:
0647             port = socket.getservbyname(portstr, 'tcp')
0648     tn = Telnet()
0649     tn.set_debuglevel(debuglevel)
0650     tn.open(host, port)
0651     tn.interact()
0652     tn.close()
0653 
0654 if __name__ == '__main__':
0655     test()
0656 

Generated by PyXR 0.9.4
SourceForge.net Logo