xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/telnetlib.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
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