Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
1da9c57c
Commit
1da9c57c
authored
Nov 04, 2002
by
Martin v. Löwis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Patch #630829: Don't block on IAC, process suboptions.
parent
a178cff9
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
93 additions
and
32 deletions
+93
-32
Doc/lib/libtelnetlib.tex
Doc/lib/libtelnetlib.tex
+8
-0
Lib/telnetlib.py
Lib/telnetlib.py
+82
-31
Misc/ACKS
Misc/ACKS
+1
-0
Misc/NEWS
Misc/NEWS
+2
-1
No files found.
Doc/lib/libtelnetlib.tex
View file @
1da9c57c
...
...
@@ -96,6 +96,14 @@ Return \code{''} if no cooked data available otherwise. This method
never blocks.
\end{methoddesc}
\begin{methoddesc}
{
read
_
sb
_
data
}{}
Return the data collected between a SB/SE pair (suboption begin/end).
The callback should access these data when it was invoked with a
\code
{
SE
}
command. This method never blocks.
\versionadded
{
2.3
}
\end{methoddesc}
\begin{methoddesc}
{
open
}{
host
\optional
{
, port
}}
Connect to a host.
The optional second argument is the port number, which
...
...
Lib/telnetlib.py
View file @
1da9c57c
...
...
@@ -25,9 +25,6 @@ EOFError is needed in some cases to distinguish between "no data" and
"connection closed" (since the socket also appears ready for reading
when it is closed).
Bugs:
- may hang when connection is slow in the middle of an IAC sequence
To do:
- option negotiation
- timeout should be intrinsic to the connection object instead of an
...
...
@@ -56,6 +53,8 @@ DO = chr(253)
WONT
=
chr
(
252
)
WILL
=
chr
(
251
)
theNULL
=
chr
(
0
)
SB
=
chr
(
250
)
SE
=
chr
(
240
)
# Telnet protocol options code (don't change)
# These ones all come from arpa/telnet.h
...
...
@@ -117,6 +116,7 @@ PRAGMA_LOGON = chr(138) # TELOPT PRAGMA LOGON
SSPI_LOGON
=
chr
(
139
)
# TELOPT SSPI LOGON
PRAGMA_HEARTBEAT
=
chr
(
140
)
# TELOPT PRAGMA HEARTBEAT
EXOPL
=
chr
(
255
)
# Extended-Options-List
NOOPT
=
chr
(
0
)
class
Telnet
:
...
...
@@ -161,10 +161,14 @@ class Telnet:
Reads all data in the cooked queue, without doing any socket
I/O.
read_sb_data()
Reads available data between SB ... SE sequence. Don't block.
set_option_negotiation_callback(callback)
Each time a telnet option is read on the input flow, this callback
(if set) is called with the following parameters :
callback(telnet socket, command (DO/DONT/WILL/WONT), option)
callback(telnet socket, command, option)
option will be chr(0) when there is no option.
No other action is done afterwards by telnetlib.
"""
...
...
@@ -185,6 +189,9 @@ class Telnet:
self
.
irawq
=
0
self
.
cookedq
=
''
self
.
eof
=
0
self
.
iacseq
=
''
# Buffer for IAC sequence.
self
.
sb
=
0
# flag for SB and SE sequence.
self
.
sbdataq
=
''
self
.
option_callback
=
None
if
host
is
not
None
:
self
.
open
(
host
,
port
)
...
...
@@ -250,6 +257,8 @@ class Telnet:
self
.
sock
.
close
()
self
.
sock
=
0
self
.
eof
=
1
self
.
iacseq
=
''
self
.
sb
=
0
def
get_socket
(
self
):
"""Return the socket object used internally."""
...
...
@@ -379,6 +388,18 @@ class Telnet:
if
not
buf
and
self
.
eof
and
not
self
.
rawq
:
raise
EOFError
,
'telnet connection closed'
return
buf
def
read_sb_data
(
self
):
"""Return any data available in the SB ... SE queue.
Return '' if no SB ... SE available. Should only be called
after seeing a SB or SE command. When a new SB command is
found, old unread SB data will be discarded. Don't block.
"""
buf
=
self
.
sbdataq
self
.
sbdataq
=
''
return
buf
def
set_option_negotiation_callback
(
self
,
callback
):
"""Provide a callback function called after each receipt of a telnet option."""
...
...
@@ -391,40 +412,70 @@ class Telnet:
the midst of an IAC sequence.
"""
buf
=
''
buf
=
[
''
,
''
]
try
:
while
self
.
rawq
:
c
=
self
.
rawq_getchar
()
if
c
==
theNULL
:
continue
if
c
==
"
\
021
"
:
continue
if
c
!=
IAC
:
buf
=
buf
+
c
continue
c
=
self
.
rawq_getchar
()
if
c
==
IAC
:
buf
=
buf
+
c
elif
c
in
(
DO
,
DONT
):
opt
=
self
.
rawq_getchar
()
self
.
msg
(
'IAC %s %d'
,
c
==
DO
and
'DO'
or
'DONT'
,
ord
(
opt
))
if
self
.
option_callback
:
self
.
option_callback
(
self
.
sock
,
c
,
opt
)
if
not
self
.
iacseq
:
if
c
==
theNULL
:
continue
if
c
==
"
\
021
"
:
continue
if
c
!=
IAC
:
buf
[
self
.
sb
]
=
buf
[
self
.
sb
]
+
c
continue
else
:
self
.
sock
.
sendall
(
IAC
+
WONT
+
opt
)
elif
c
in
(
WILL
,
WONT
):
opt
=
self
.
rawq_getchar
()
self
.
msg
(
'IAC %s %d'
,
c
==
WILL
and
'WILL'
or
'WONT'
,
ord
(
opt
))
if
self
.
option_callback
:
self
.
option_callback
(
self
.
sock
,
c
,
opt
)
self
.
iacseq
+=
c
elif
len
(
self
.
iacseq
)
==
1
:
'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
if
c
in
(
DO
,
DONT
,
WILL
,
WONT
):
self
.
iacseq
+=
c
continue
self
.
iacseq
=
''
if
c
==
IAC
:
buf
[
self
.
sb
]
=
buf
[
self
.
sb
]
+
c
else
:
self
.
sock
.
sendall
(
IAC
+
DONT
+
opt
)
else
:
self
.
msg
(
'IAC %d not recognized'
%
ord
(
c
))
if
c
==
SB
:
# SB ... SE start.
self
.
sb
=
1
self
.
sbdataq
=
''
elif
c
==
SE
:
self
.
sb
=
0
self
.
sbdataq
=
self
.
sbdataq
+
buf
[
1
]
buf
[
1
]
=
''
if
self
.
option_callback
:
# Callback is supposed to look into
# the sbdataq
self
.
option_callback
(
self
.
sock
,
c
,
NOOPT
)
else
:
# We can't offer automatic processing of
# suboptions. Alas, we should not get any
# unless we did a WILL/DO before.
self
.
msg
(
'IAC %d not recognized'
%
ord
(
c
))
elif
len
(
self
.
iacseq
)
==
2
:
cmd
=
self
.
iacseq
[
1
]
self
.
iacseq
=
''
opt
=
c
if
cmd
in
(
DO
,
DONT
):
self
.
msg
(
'IAC %s %d'
,
cmd
==
DO
and
'DO'
or
'DONT'
,
ord
(
opt
))
if
self
.
option_callback
:
self
.
option_callback
(
self
.
sock
,
cmd
,
opt
)
else
:
self
.
sock
.
sendall
(
IAC
+
WONT
+
opt
)
elif
cmd
in
(
WILL
,
WONT
):
self
.
msg
(
'IAC %s %d'
,
cmd
==
WILL
and
'WILL'
or
'WONT'
,
ord
(
opt
))
if
self
.
option_callback
:
self
.
option_callback
(
self
.
sock
,
cmd
,
opt
)
else
:
self
.
sock
.
sendall
(
IAC
+
DONT
+
opt
)
except
EOFError
:
# raised by self.rawq_getchar()
self
.
iacseq
=
''
# Reset on EOF
self
.
sb
=
0
pass
self
.
cookedq
=
self
.
cookedq
+
buf
self
.
cookedq
=
self
.
cookedq
+
buf
[
0
]
self
.
sbdataq
=
self
.
sbdataq
+
buf
[
1
]
def
rawq_getchar
(
self
):
"""Get next char from raw queue.
...
...
Misc/ACKS
View file @
1da9c57c
...
...
@@ -465,6 +465,7 @@ Steven Scott
Nick Seidenman
Fred Sells
Denis Severson
Ha Shao
Bruce Sherwood
Pete Shinners
Michael Shiplett
...
...
Misc/NEWS
View file @
1da9c57c
...
...
@@ -1707,7 +1707,8 @@ Library
-------
- telnetlib includes symbolic names for the options, and support for
setting an option negotiation callback.
setting an option negotiation callback. It also supports processing
of suboptions.
- The new C standard no longer requires that math libraries set errno to
ERANGE on overflow. For platform libraries that exploit this new
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment