~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/telnetlib.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

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