Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
e36f7356
Kaydet (Commit)
e36f7356
authored
Kas 01, 1993
tarafından
Guido van Rossum
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Major rewrite with new read_* interfaces
üst
0b26a19a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
295 additions
and
155 deletions
+295
-155
telnetlib.py
Demo/cwilib/telnetlib.py
+295
-155
No files found.
Demo/cwilib/telnetlib.py
Dosyayı görüntüle @
e36f7356
# Telnet client library
# A TELNET client class. Based on RFC 854: TELNET Protocol
# Specification, by J. Postel and J. Reynolds
# Example:
#
# >>> from telnetlib import Telnet
# >>> tn = Telnet('voorn.cwi.nl', 79) # connect to finger port
# >>> tn.write('guido\r\n')
# >>> print tn.read_all()
# Login name: guido In real life: Guido van Rossum
# Office: M353, x4127 Home phone: 020-6225521
# Directory: /ufs/guido Shell: /usr/local/bin/esh
# On since Oct 28 11:02:16 on ttyq1
# Project: Multimedia Kernel Systems
# No Plan.
# >>>
#
# Note that read() won't read until eof -- it just reads some data
# (but it guarantees to read at least one byte unless EOF is hit).
#
# It is possible to pass a Telnet object to select.select() in order
# to wait until more data is available. Note that in this case,
# read_eager() may return '' even if there was data on the socket,
# because the protocol negotiation may have eaten the data.
# This is why EOFError is needed 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
# Imported modules
import
socket
import
select
import
string
import
regsub
# Tunable parameters
TIMEOUT
=
30.0
DEBUGLEVEL
=
1
DEBUGLEVEL
=
0
# Telnet protocol defaults
TELNET_PORT
=
23
...
...
@@ -24,158 +58,264 @@ WILL = chr(251)
class
Telnet
:
# Constructor
def
__init__
(
self
,
host
,
port
):
self
.
debuglevel
=
DEBUGLEVEL
self
.
host
=
host
if
not
port
:
port
=
TELNET_PORT
self
.
port
=
port
self
.
timeout
=
TIMEOUT
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
sock
.
connect
((
self
.
host
,
self
.
port
))
self
.
rawq
=
''
self
.
irawq
=
0
self
.
cookedq
=
''
# Destructor
def
__del__
(
self
):
self
.
close
()
# Print debug message
def
msg
(
self
,
msg
,
*
args
):
if
self
.
debuglevel
>
0
:
print
'TELNET:'
,
msg
%
args
# Set debug level
def
set_debuglevel
(
self
,
debuglevel
):
self
.
debuglevel
=
debuglevel
# Set time-out on certain reads
def
set_timeout
(
self
,
timeout
):
self
.
timeout
=
float
(
timeout
)
# Explicit close
def
close
(
self
):
if
self
.
sock
:
self
.
sock
.
close
()
self
.
sock
=
None
# Return socket (e.g. for select)
def
get_socket
(
self
):
return
self
.
sock
# Return socket's fileno (e.g. for select)
def
fileno
(
self
):
return
self
.
sock
.
fileno
()
# Write a string to the socket, doubling any IAC characters
def
write
(
self
,
buffer
):
if
IAC
in
buffer
:
buffer
=
regsub
.
gsub
(
IAC
,
IAC
+
IAC
,
buffer
)
self
.
sock
.
send
(
buffer
)
# Read until a given string is encountered or until timeout
def
read_until
(
self
,
match
):
## self.msg('read_until(%s)' % `match`)
n
=
len
(
match
)
self
.
process_rawq
()
i
=
string
.
find
(
self
.
cookedq
,
match
)
if
i
<
0
:
i
=
max
(
0
,
len
(
self
.
cookedq
)
-
n
)
self
.
fill_cookedq
()
i
=
string
.
find
(
self
.
cookedq
,
match
,
i
)
if
i
>=
0
:
i
=
i
+
n
buf
=
self
.
cookedq
[:
i
]
self
.
cookedq
=
self
.
cookedq
[
i
:]
## self.msg('read_until(%s) -> %s' % (`match`, `buf`))
return
buf
while
select
.
select
([
self
],
[],
[],
self
.
timeout
)
==
\
([
self
],
[],
[]):
i
=
max
(
0
,
len
(
self
.
cookedq
)
-
n
)
self
.
fill_rawq
()
self
.
process_rawq
()
i
=
string
.
find
(
self
.
cookedq
,
match
,
i
)
if
i
>=
0
:
i
=
i
+
n
buf
=
self
.
cookedq
[:
i
]
self
.
cookedq
=
self
.
cookedq
[
i
:]
## self.msg('read_until(%s) -> %s' %
## (`match`, `buf`))
return
buf
buf
=
self
.
cookedq
self
.
cookedq
=
''
## self.msg('read_until(%s) -> %s' % (`match`, `buf`))
return
buf
# Constructor
def
__init__
(
self
,
host
,
*
args
):
if
not
args
:
port
=
TELNET_PORT
else
:
if
len
(
args
)
>
1
:
raise
TypeError
,
'too many args'
port
=
args
[
0
]
if
not
port
:
port
=
TELNET_PORT
self
.
debuglevel
=
DEBUGLEVEL
self
.
host
=
host
self
.
port
=
port
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
sock
.
connect
((
self
.
host
,
self
.
port
))
self
.
rawq
=
''
self
.
irawq
=
0
self
.
cookedq
=
''
self
.
eof
=
0
# Destructor
def
__del__
(
self
):
self
.
close
()
# Debug message
def
msg
(
self
,
msg
,
*
args
):
if
self
.
debuglevel
>
0
:
print
'Telnet(
%
s,
%
d):'
%
(
self
.
host
,
self
.
port
),
msg
%
args
# Set debug level
def
set_debuglevel
(
self
,
debuglevel
):
self
.
debuglevel
=
debuglevel
# Explicit close
def
close
(
self
):
if
self
.
sock
:
self
.
sock
.
close
()
self
.
sock
=
None
self
.
eof
=
1
# Return socket (e.g. for select)
def
get_socket
(
self
):
return
self
.
sock
# Return socket's fileno (e.g. for select)
def
fileno
(
self
):
return
self
.
sock
.
fileno
()
# Write a string to the socket, doubling any IAC characters
# Might block if the connection is blocked
# May raise socket.error if the connection is closed
def
write
(
self
,
buffer
):
if
IAC
in
buffer
:
buffer
=
regsub
.
gsub
(
IAC
,
IAC
+
IAC
,
buffer
)
self
.
sock
.
send
(
buffer
)
# The following read_* methods exist:
# Special case:
# - read_until() reads until a string is encountered or a timeout is hit
# These may block:
# - read_all() reads all data until EOF
# - read_some() reads at least one byte until EOF
# These may do I/O but won't block doing it:
# - read_very_eager() reads all data available on the socket
# - read_eager() reads either data already queued or some data
# available on the socket
# These don't do I/O:
# - read_lazy() reads all data in the raw queue (processing it first)
# - read_very_lazy() reads all data in the cooked queue
# Read everything that's possible without really blocking
def
read_now
(
self
):
self
.
fill_cookedq
()
buf
=
self
.
cookedq
self
.
cookedq
=
''
## self.msg('read_now() --> %s' % `buf`)
# Read until a given string is encountered or until timeout
# Raise EOFError if connection closed and no cooked data available
# Return '' if no cooked data available otherwise
def
read_until
(
self
,
match
,
*
args
):
if
not
args
:
timeout
=
None
else
:
if
len
(
args
)
>
1
:
raise
TypeError
,
'too many args'
timeout
=
args
[
0
]
n
=
len
(
match
)
self
.
process_rawq
()
i
=
string
.
find
(
self
.
cookedq
,
match
)
if
i
>=
0
:
i
=
i
+
n
buf
=
self
.
cookedq
[:
i
]
self
.
cookedq
=
self
.
cookedq
[
i
:]
return
buf
s_reply
=
([
self
],
[],
[])
s_args
=
s_reply
if
timeout
is
not
None
:
s_args
=
s_args
+
(
timeout
,)
while
not
self
.
eof
and
apply
(
select
.
select
,
s_args
)
==
s_reply
:
i
=
max
(
0
,
len
(
self
.
cookedq
)
-
n
)
self
.
fill_rawq
()
self
.
process_rawq
()
i
=
string
.
find
(
self
.
cookedq
,
match
,
i
)
if
i
>=
0
:
i
=
i
+
n
buf
=
self
.
cookedq
[:
i
]
self
.
cookedq
=
self
.
cookedq
[
i
:]
return
buf
return
self
.
read_very_lazy
()
# Read all data until EOF
# Block until connection closed
def
read_all
(
self
):
self
.
process_rawq
()
while
not
self
.
eof
:
self
.
fill_rawq
()
self
.
process_rawq
()
buf
=
self
.
cookedq
self
.
cookedq
=
''
return
buf
# Read at least one byte of cooked data unless EOF is hit
# Return '' if EOF is hit
# Block if no data is immediately available
def
read_some
(
self
):
self
.
process_rawq
()
while
not
self
.
cookedq
and
not
self
.
eof
:
self
.
fill_rawq
()
self
.
process_rawq
()
buf
=
self
.
cookedq
self
.
cookedq
=
''
return
buf
# Read everything that's possible without blocking in I/O (eager)
# Raise EOFError if connection closed and no cooked data available
# Return '' if no cooked data available otherwise
# Don't block unless in the midst of an IAC sequence
def
read_very_eager
(
self
):
self
.
process_rawq
()
while
not
self
.
eof
and
self
.
sock_avail
():
self
.
fill_rawq
()
self
.
process_rawq
()
return
self
.
read_very_lazy
()
# Read readily available data
# Raise EOFError if connection closed and no cooked data available
# Return '' if no cooked data available otherwise
# Don't block unless in the midst of an IAC sequence
def
read_eager
(
self
):
self
.
process_rawq
()
while
not
self
.
cookedq
and
not
self
.
eof
and
self
.
sock_avail
():
self
.
fill_rawq
()
self
.
process_rawq
()
return
self
.
read_very_lazy
()
# Process and return data that's already in the queues (lazy)
# Raise EOFError if connection closed and no data available
# Return '' if no cooked data available otherwise
# Don't block unless in the midst of an IAC sequence
def
read_lazy
(
self
):
self
.
process_rawq
()
return
self
.
read_very_lazy
()
# Return any data available in the cooked queue (very lazy)
# Raise EOFError if connection closed and no data available
# Return '' if no cooked data available otherwise
# Don't block
def
read_very_lazy
(
self
):
buf
=
self
.
cookedq
self
.
cookedq
=
''
if
not
buf
and
self
.
eof
and
not
self
.
rawq
:
raise
EOFError
,
'telnet connection closed'
return
buf
# Transfer from raw queue to cooked queue
# Set self.eof when connection is closed
# Don't block unless in the midst of an IAC sequence
def
process_rawq
(
self
):
buf
=
''
try
:
while
self
.
rawq
:
c
=
self
.
rawq_getchar
()
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
(
c
))
self
.
sock
.
send
(
IAC
+
WONT
+
opt
)
elif
c
in
(
WILL
,
WONT
):
opt
=
self
.
rawq_getchar
()
self
.
msg
(
'IAC
%
s
%
d'
,
c
==
WILL
and
'WILL'
or
'WONT'
,
ord
(
c
))
else
:
self
.
msg
(
'IAC
%
s not recognized'
%
`c`
)
except
EOFError
:
# raised by self.rawq_getchar()
pass
self
.
cookedq
=
self
.
cookedq
+
buf
# Get next char from raw queue
# Block if no data is immediately available
# Raise EOFError when connection is closed
def
rawq_getchar
(
self
):
if
not
self
.
rawq
:
self
.
fill_rawq
()
if
self
.
eof
:
raise
EOFError
c
=
self
.
rawq
[
self
.
irawq
]
self
.
irawq
=
self
.
irawq
+
1
if
self
.
irawq
>=
len
(
self
.
rawq
):
self
.
rawq
=
''
self
.
irawq
=
0
return
c
# Fill raw queue from exactly one recv() system call
# Block if no data is immediately available
# Set self.eof when connection is closed
def
fill_rawq
(
self
):
if
self
.
irawq
>=
len
(
self
.
rawq
):
self
.
rawq
=
''
self
.
irawq
=
0
# The buffer size should be fairly small so as to avoid quadratic
# behavior in process_rawq() above
buf
=
self
.
sock
.
recv
(
50
)
self
.
eof
=
(
not
buf
)
self
.
rawq
=
self
.
rawq
+
buf
# Test whether data is available on the socket
def
sock_avail
(
self
):
return
select
.
select
([
self
],
[],
[],
0
)
==
([
self
],
[],
[])
# Fill cooked queue without blocking
def
fill_cookedq
(
self
):
self
.
process_rawq
()
while
select
.
select
([
self
],
[],
[],
0
)
==
([
self
],
[],
[]):
self
.
fill_rawq
()
if
not
self
.
rawq
:
raise
EOFError
self
.
process_rawq
()
# Transfer from raw queue to cooked queue
def
process_rawq
(
self
):
# There is some silliness going on here in an attempt
# to avoid quadratic behavior with large inputs...
buf
=
''
while
self
.
rawq
:
c
=
self
.
rawq_getchar
()
if
c
!=
IAC
:
buf
=
buf
+
c
if
len
(
buf
)
>=
44
:
## self.msg('transfer: %s' % `buf`)
self
.
cookedq
=
self
.
cookedq
+
buf
buf
=
''
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
(
c
))
self
.
sock
.
send
(
IAC
+
WONT
+
opt
)
elif
c
in
(
WILL
,
WONT
):
opt
=
self
.
rawq_getchar
()
self
.
msg
(
'IAC
%
s
%
d'
,
c
==
WILL
and
'WILL'
or
'WONT'
,
ord
(
c
))
else
:
self
.
msg
(
'IAC
%
s not recognized'
%
`c`
)
## self.msg('transfer: %s' % `buf`)
self
.
cookedq
=
self
.
cookedq
+
buf
# Get next char from raw queue, blocking if necessary
def
rawq_getchar
(
self
):
if
not
self
.
rawq
:
self
.
fill_rawq
()
if
self
.
irawq
>=
len
(
self
.
rawq
):
raise
EOFError
c
=
self
.
rawq
[
self
.
irawq
]
self
.
irawq
=
self
.
irawq
+
1
if
self
.
irawq
>=
len
(
self
.
rawq
):
self
.
rawq
=
''
self
.
irawq
=
0
return
c
# Fill raw queue
def
fill_rawq
(
self
):
if
self
.
irawq
>=
len
(
self
.
rawq
):
self
.
rawq
=
''
self
.
irawq
=
0
buf
=
self
.
sock
.
recv
(
50
)
## self.msg('fill_rawq(): %s' % `buf`)
self
.
rawq
=
self
.
rawq
+
buf
# Test program
# Usage: test [-d] ... [host [port]]
def
test
():
import
sys
,
string
,
socket
,
select
debuglevel
=
0
while
sys
.
argv
[
1
:]
and
sys
.
argv
[
1
]
==
'-d'
:
debuglevel
=
debuglevel
+
1
del
sys
.
argv
[
1
]
host
=
'localhost'
if
sys
.
argv
[
1
:]:
host
=
sys
.
argv
[
1
]
port
=
0
if
sys
.
argv
[
2
:]:
portstr
=
sys
.
argv
[
2
]
try
:
port
=
string
.
atoi
(
portstr
)
except
string
.
atoi_error
:
port
=
socket
.
getservbyname
(
portstr
,
'tcp'
)
tn
=
Telnet
(
host
,
port
)
tn
.
set_debuglevel
(
debuglevel
)
while
1
:
rfd
,
wfd
,
xfd
=
select
.
select
([
tn
,
sys
.
stdin
],
[],
[])
if
sys
.
stdin
in
rfd
:
line
=
sys
.
stdin
.
readline
()
tn
.
write
(
line
)
if
tn
in
rfd
:
try
:
text
=
tn
.
read_eager
()
except
EOFError
:
print
'*** Connection closed by remote host ***'
break
if
text
:
sys
.
stdout
.
write
(
text
)
sys
.
stdout
.
flush
()
tn
.
close
()
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