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
4d67cdcf
Commit
4d67cdcf
authored
Oct 25, 1992
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial revision
parent
5ea4c8ea
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
347 additions
and
0 deletions
+347
-0
Demo/sockets/gopher.py
Demo/sockets/gopher.py
+347
-0
No files found.
Demo/sockets/gopher.py
0 → 100755
View file @
4d67cdcf
#! /usr/local/bin/python
# A simple gopher client.
#
# Usage: gopher [ [selector] host [port] ]
import
string
import
sys
import
os
import
socket
# Default selector, host and port
DEF_SELECTOR
=
''
DEF_HOST
=
'gopher.micro.umn.edu'
DEF_PORT
=
70
# Recognized file types
T_TEXTFILE
=
'0'
T_MENU
=
'1'
T_CSO
=
'2'
T_ERROR
=
'3'
T_BINHEX
=
'4'
T_DOS
=
'5'
T_UUENCODE
=
'6'
T_SEARCH
=
'7'
T_TELNET
=
'8'
T_BINARY
=
'9'
T_REDUNDANT
=
'+'
T_SOUND
=
's'
# Dictionary mapping types to strings
typename
=
{
'0'
:
'<TEXT>'
,
'1'
:
'<DIR>'
,
'2'
:
'<CSO>'
,
'3'
:
'<ERROR>'
,
\
'4'
:
'<BINHEX>'
,
'5'
:
'<DOS>'
,
'6'
:
'<UUENCODE>'
,
'7'
:
'<SEARCH>'
,
\
'8'
:
'<TELNET>'
,
'9'
:
'<BINARY>'
,
'+'
:
'<REDUNDANT>'
,
's'
:
'<SOUND>'
}
# Oft-used characters and strings
CRLF
=
'
\
r
\
n
'
TAB
=
'
\
t
'
# Open a TCP connection to a given host and port
def
open_socket
(
host
,
port
):
if
type
(
port
)
==
type
(
''
):
port
=
string
.
atoi
(
port
)
s
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
s
.
connect
((
host
,
port
))
return
s
# Send a selector to a given host and port, return a file with the reply
def
send_request
(
selector
,
host
,
port
):
s
=
open_socket
(
host
,
port
)
s
.
send
(
selector
+
CRLF
)
s
.
shutdown
(
1
)
return
s
.
makefile
(
'r'
)
# Get a menu in the form of a list of entries
def
get_menu
(
selector
,
host
,
port
):
f
=
send_request
(
selector
,
host
,
port
)
list
=
[]
while
1
:
line
=
f
.
readline
()
if
not
line
:
print
'(Unexpected EOF from server)'
break
if
line
[
-
2
:]
==
CRLF
:
line
=
line
[:
-
2
]
elif
line
[
-
1
:]
in
CRLF
:
line
=
line
[:
-
1
]
if
line
==
'.'
:
break
if
not
line
:
print
'(Empty line from server)'
continue
typechar
=
line
[
0
]
parts
=
string
.
splitfields
(
line
[
1
:],
TAB
)
if
len
(
parts
)
<
4
:
print
'(Bad line from server:'
,
`line`
,
')'
continue
if
len
(
parts
)
>
4
:
print
'(Extra info from server:'
,
parts
[
4
:],
')'
parts
.
insert
(
0
,
typechar
)
list
.
append
(
parts
)
f
.
close
()
return
list
# Get a text file as a list of lines, with trailing CRLF stripped
def
get_textfile
(
selector
,
host
,
port
):
list
=
[]
get_alt_textfile
(
selector
,
host
,
port
,
list
.
append
)
return
list
# Get a text file and pass each line to a function, with trailing CRLF stripped
def
get_alt_textfile
(
selector
,
host
,
port
,
func
):
f
=
send_request
(
selector
,
host
,
port
)
while
1
:
line
=
f
.
readline
()
if
not
line
:
print
'(Unexpected EOF from server)'
break
if
line
[
-
2
:]
==
CRLF
:
line
=
line
[:
-
2
]
elif
line
[
-
1
:]
in
CRLF
:
line
=
line
[:
-
1
]
if
line
==
'.'
:
break
if
line
[:
2
]
==
'..'
:
line
=
line
[
1
:]
func
(
line
)
f
.
close
()
# Get a binary file as one solid data block
def
get_binary
(
selector
,
host
,
port
):
f
=
send_request
(
selector
,
host
,
port
)
data
=
f
.
read
()
f
.
close
()
return
data
# Get a binary file and pass each block to a function
def
get_alt_binary
(
selector
,
host
,
port
,
func
,
blocksize
):
f
=
send_request
(
selector
,
host
,
port
)
while
1
:
data
=
f
.
read
(
blocksize
)
if
not
data
:
break
func
(
data
)
# A *very* simple interactive browser
# Browser main command, has default arguments
def
browser
(
*
args
):
selector
=
DEF_SELECTOR
host
=
DEF_HOST
port
=
DEF_PORT
n
=
len
(
args
)
if
n
>
0
and
args
[
0
]:
selector
=
args
[
0
]
if
n
>
1
and
args
[
1
]:
host
=
args
[
1
]
if
n
>
2
and
args
[
2
]:
port
=
args
[
2
]
if
n
>
3
:
raise
RuntimeError
,
'too many args'
try
:
browse_menu
(
selector
,
host
,
port
)
except
socket
.
error
,
msg
:
print
'Socket error:'
,
msg
sys
.
exit
(
1
)
except
KeyboardInterrupt
:
print
'
\
n
[Goodbye]'
# Browse a menu
def
browse_menu
(
selector
,
host
,
port
):
list
=
get_menu
(
selector
,
host
,
port
)
while
1
:
print
'----- MENU -----'
print
'Selector:'
,
`selector`
print
'Host:'
,
host
,
' Port:'
,
port
print
for
i
in
range
(
len
(
list
)):
item
=
list
[
i
]
typechar
,
description
=
item
[
0
],
item
[
1
]
print
string
.
rjust
(
`i+1`
,
3
)
+
':'
,
description
,
if
typename
.
has_key
(
typechar
):
print
typename
[
typechar
]
else
:
print
'<TYPE='
+
`typechar`
+
'>'
print
while
1
:
try
:
str
=
raw_input
(
'Choice [CR == up a level]: '
)
except
EOFError
:
print
return
if
not
str
:
return
try
:
choice
=
string
.
atoi
(
str
)
except
string
.
atoi_error
:
print
'Choice must be a number; try again:'
continue
if
not
0
<
choice
<=
len
(
list
):
print
'Choice out of range; try again:'
continue
break
item
=
list
[
choice
-
1
]
typechar
=
item
[
0
]
[
i_selector
,
i_host
,
i_port
]
=
item
[
2
:
5
]
if
typebrowser
.
has_key
(
typechar
):
browserfunc
=
typebrowser
[
typechar
]
try
:
browserfunc
(
i_selector
,
i_host
,
i_port
)
except
(
IOError
,
socket
.
error
):
print
'***'
,
sys
.
exc_type
,
':'
,
sys
.
exc_value
else
:
print
'Unsupported object type'
# Browse a text file
def
browse_textfile
(
selector
,
host
,
port
):
x
=
None
try
:
p
=
os
.
popen
(
'${PAGER-more}'
,
'w'
)
x
=
SaveLines
().
init
(
p
)
get_alt_textfile
(
selector
,
host
,
port
,
x
.
writeln
)
except
IOError
,
msg
:
print
'IOError:'
,
msg
if
x
:
x
.
close
()
f
=
open_savefile
()
if
not
f
:
return
x
=
SaveLines
().
init
(
f
)
try
:
get_alt_textfile
(
selector
,
host
,
port
,
x
.
writeln
)
print
'Done.'
except
IOError
,
msg
:
print
'IOError:'
,
msg
x
.
close
()
# Browse a search index
def
browse_search
(
selector
,
host
,
port
):
while
1
:
print
'----- SEARCH -----'
print
'Selector:'
,
`selector`
print
'Host:'
,
host
,
' Port:'
,
port
print
try
:
query
=
raw_input
(
'Query [CR == up a level]: '
)
except
EOFError
:
print
break
query
=
string
.
strip
(
query
)
if
not
query
:
break
if
'
\
t
'
in
query
:
print
'Sorry, queries cannot contain tabs'
continue
browse_menu
(
selector
+
TAB
+
query
,
host
,
port
)
# "Browse" telnet-based information, i.e. open a telnet session
def
browse_telnet
(
selector
,
host
,
port
):
if
selector
:
print
'Log in as'
,
`selector`
if
type
(
port
)
<>
type
(
''
):
port
=
`port`
sts
=
os
.
system
(
'set -x; exec telnet '
+
host
+
' '
+
port
)
if
sts
:
print
'Exit status:'
,
sts
# "Browse" a binary file, i.e. save it to a file
def
browse_binary
(
selector
,
host
,
port
):
f
=
open_savefile
()
if
not
f
:
return
x
=
SaveWithProgress
().
init
(
f
)
get_alt_binary
(
selector
,
host
,
port
,
x
.
write
,
8
*
1024
)
x
.
close
()
# "Browse" a sound file, i.e. play it or save it
def
browse_sound
(
selector
,
host
,
port
):
browse_binary
(
selector
,
host
,
port
)
# Dictionary mapping types to browser functions
typebrowser
=
{
'0'
:
browse_textfile
,
'1'
:
browse_menu
,
\
'4'
:
browse_binary
,
'5'
:
browse_binary
,
'6'
:
browse_textfile
,
\
'7'
:
browse_search
,
\
'8'
:
browse_telnet
,
'9'
:
browse_binary
,
's'
:
browse_sound
}
# Class used to save lines, appending a newline to each line
class
SaveLines
:
def
init
(
self
,
f
):
self
.
f
=
f
return
self
def
writeln
(
self
,
line
):
self
.
f
.
write
(
line
+
'
\
n
'
)
def
close
(
self
):
sts
=
self
.
f
.
close
()
if
sts
:
print
'Exit status:'
,
sts
# Class used to save data while showing progress
class
SaveWithProgress
:
def
init
(
self
,
f
):
self
.
f
=
f
return
self
def
write
(
self
,
data
):
sys
.
stdout
.
write
(
'#'
)
sys
.
stdout
.
flush
()
self
.
f
.
write
(
data
)
def
close
(
self
):
print
sts
=
self
.
f
.
close
()
if
sts
:
print
'Exit status:'
,
sts
# Ask for and open a save file, or return None if not to save
def
open_savefile
():
try
:
savefile
=
raw_input
(
\
'Save as file [CR == don
\
'
t save; |pipeline or ~user/... OK]: '
)
except
EOFError
:
print
return
None
savefile
=
string
.
strip
(
savefile
)
if
not
savefile
:
return
None
if
savefile
[
0
]
==
'|'
:
cmd
=
string
.
strip
(
savefile
[
1
:])
try
:
p
=
os
.
popen
(
cmd
,
'w'
)
except
IOError
,
msg
:
print
`cmd`
,
':'
,
msg
return
None
print
'Piping through'
,
`cmd`
,
'...'
return
p
if
savefile
[
0
]
==
'~'
:
savefile
=
os
.
path
.
expanduser
(
savefile
)
try
:
f
=
open
(
savefile
,
'w'
)
except
IOError
,
msg
:
print
`savefile`
,
':'
,
msg
return
None
print
'Saving to'
,
`savefile`
,
'...'
return
f
# Test program
def
test
():
if
sys
.
argv
[
4
:]:
print
'usage: gopher [ [selector] host [port] ]'
sys
.
exit
(
2
)
elif
sys
.
argv
[
3
:]:
browser
(
sys
.
argv
[
1
],
sys
.
argv
[
2
],
sys
.
argv
[
3
])
elif
sys
.
argv
[
2
:]:
try
:
port
=
string
.
atoi
(
sys
.
argv
[
2
])
selector
=
''
host
=
sys
.
argv
[
1
]
except
string
.
atoi_error
:
selector
=
sys
.
argv
[
1
]
host
=
sys
.
argv
[
2
]
port
=
''
browser
(
selector
,
host
,
port
)
elif
sys
.
argv
[
1
:]:
browser
(
''
,
sys
.
argv
[
1
])
else
:
browser
()
# Call the test program as a main program
test
()
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