diff options
author | Ori Bernstein <ori@eigenstate.org> | 2021-06-14 00:00:37 +0000 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2021-06-14 00:00:37 +0000 |
commit | a73a964e51247ed169d322c725a3a18859f109a3 (patch) | |
tree | 3f752d117274d444bda44e85609aeac1acf313f3 /sys/src/cmd/python/Demo/sockets/gopher.py | |
parent | e64efe273fcb921a61bf27d33b230c4e64fcd425 (diff) |
python, hg: tow outside the environment.
they've served us well, and can ride off into the sunset.
Diffstat (limited to 'sys/src/cmd/python/Demo/sockets/gopher.py')
-rwxr-xr-x | sys/src/cmd/python/Demo/sockets/gopher.py | 347 |
1 files changed, 0 insertions, 347 deletions
diff --git a/sys/src/cmd/python/Demo/sockets/gopher.py b/sys/src/cmd/python/Demo/sockets/gopher.py deleted file mode 100755 index cd7665936..000000000 --- a/sys/src/cmd/python/Demo/sockets/gopher.py +++ /dev/null @@ -1,347 +0,0 @@ -#! /usr/bin/env 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 not port: - port = DEF_PORT - elif 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: %r)' % (line,) - continue - if len(parts) > 4: - print '(Extra info from server: %r)' % (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:', repr(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(repr(i+1), 3) + ':', description, - if typename.has_key(typechar): - print typename[typechar] - else: - print '<TYPE=' + repr(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(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(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:', repr(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', repr(selector) - if type(port) <> type(''): - port = repr(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(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 - 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 - 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 repr(cmd), ':', msg - return None - print 'Piping through', repr(cmd), '...' - return p - if savefile[0] == '~': - savefile = os.path.expanduser(savefile) - try: - f = open(savefile, 'w') - except IOError, msg: - print repr(savefile), ':', msg - return None - print 'Saving to', repr(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() |