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