cl-gopher
2023-10-21
Gopher protocol library
cl-gopher
cl-gopher is a Common Lisp library for interacting with the Gopher protocol.
It is suitable for building both clients and servers, and provides a sample client.
cl-gopher has been tested and confirmed to work with:
- SBCL 1.4.6
- ClozureCL Version 1.11.5/v1.11.5
- ECL 16.1.3
Installation
cl-gopher
is now available through quicklisp!
CL-USER> (ql:quickload 'cl-gopher)
If you want to use the source from this repo, rather than that distributed with quicklisp:
Make sure that the source is somewhere that asdf or quicklisp can find it. If you're not using quicklisp, consult the .asd file for required dependencies.
If you are using quicklisp, all dependencies should be available through it, and so automatically resolved.
CL-USER> (ql:quickload 'cl-gopher)
To load "cl-gopher":
Load 1 ASDF system:
cl-gopher
; Loading "cl-gopher"
[package cl-gopher].....
(CL-GOPHER)
Basic Usage
Note: This documentation assumes you know a bit about the gopher protocol, and doesn't cover the protocol's basic workings.
Most of the functions and classes have documentation strings attached to them. For better descriptions of the functions in the library, see that documentation.
Gopher Lines
The main class this library deals with is the GOPHER-LINE
.
A GOPHER-LINE
represents a gopher menu item, (analogous to a html link)
GOPHER-LINE
has a number of subclasses, depending on the type of the gopher link.
Lines can be created directly with MAKE-INSTANCE
, by parsing gopher URIs
with PARSE-GOPHER-URI
, by reading lines from a stream
(e.g. to a server speaking the gopher protocol) with READ-GOPHER-LINE
,
or by converting from an alist with GOPHER-LINE-FROM-ALIST
.
Once you have a line, you have the ability to:
- Retrieve the content it links to with
GET-LINE-CONTENTS
(contents explained more below) - Write the line out to a stream according to Gopher protocol with
WRITE-GOPHER-LINE
- Convert the line to and from an alist format with
GOPHER-LINE-TO-ALIST
,
GOPHER-LINE-FROM-ALIST
, GOPHER-LINES-TO-ALIST
and GOPHER-LINES-FROM-ALIST
.
This is useful if you want to READ
lines from a file, or WRITE
lines to a file.
- Display the line in a human-readable way with
DISPLAY-LINE
orDISPLAY-LINES
- Download the raw content bytes of a link's target to a file with
DOWNLOAD-FILE
There are several other minor util functions that accept a GOPHER-LINE
as an argument.
Contents
The other major class family in the library is the SELECTOR-CONTENTS
class and subclasses.
Instances of these classes are returned from GET-LINE-CONTENTS
, and represent the various
kinds of content that Gopher URIs can link to.
The classes currently are:
SUBMENU-CONTENTS
- Contents of a Gopher menu. Its one slot,lines
, is a list of
GOPHER-LINE
contained in the menu.
TEXT-FILE-CONTENTS
- Contents of a text file. Its one slot,lines
, contains a list
of human-readable text lines from the text document.
HTML-FILE-CONTENTS
- Contains the content of an html page as a single string in slot
content-string
BINARY-FILE-CONTENTS
- Contains the binary contents of a file such as an image or
executable in the slot content-array
, and the name of the file in file-name
All that is provided by the for working with contents objects are the slot accessors, and
a generic function, DISPLAY-CONTENTS
, which displays a contents object in human-readable
format.
Quick Examples:
To get the contents of a gopher URI, Try the following:
CL-USER> (cl-gopher:display-contents
(cl-gopher:get-line-contents
(cl-gopher:parse-gopher-uri "gopher://sdf.org/")))
cl-gopher includes a simple text browser client to exemplify the use of the library. You can test it with:
CL-USER> (cl-gopher:text-browser)
Welcome to the SDF Public Access UNIX System .. est. 1987
Official Site of the Internet Gopher Club Underground Syndicate
We offer FREE and inexpensive memberships for people interested
in the UNIX system and internetworking. Personal GOPHERSPACE
is available to all users as well as hundreds of UNIX utilities,
games and networking utilities. We are a federally recognized
non-profit 501(c)7 organization and we are supported entirely
by donations and membership dues. ssh://sdf.org
11 SUBMENU SDF PHLOGOSPHERE (226 phlogs)
12 SUBMENU SDF GOPHERSPACE (1119 ACTIVE users)
13 SUBMENU SDF GOPHERSPACE (1371 AGED users)
14 SUBMENU SDF GOPHERSPACE (373 ANCIENT users)
15 SUBMENU SDF Frequently Asked Questions (FAQ)
16 SUBMENU SDF Accredited University Courses
17 SUBMENU Software and Documentation for various computers
18 SEARCH-LINE GopherSpace SEARCH Engine
19 SUBMENU Floodgap's GOPHERSPACE
____________________________________________________________________________
Gophered by Gophernicus/97 on NetBSD/amd64 8.0_BETA
Select a line number, or "help".
>
Example showing how to get and display the contents of a gopher uri:
CL-USER> (cl-gopher:display-contents
(cl-gopher:get-line-contents
(cl-gopher:parse-gopher-uri "sdf.org")))
Welcome to the SDF Public Access UNIX System .. est. 1987
Official Site of the Internet Gopher Club Underground Syndicate
We offer FREE and inexpensive memberships for people interested
in the UNIX system and internetworking. Personal GOPHERSPACE
is available to all users as well as hundreds of UNIX utilities,
games and networking utilities. We are a federally recognized
non-profit 501(c)7 organization and we are supported entirely
by donations and membership dues. ssh://sdf.org
11 SUBMENU SDF PHLOGOSPHERE (226 phlogs)
12 SUBMENU SDF GOPHERSPACE (1119 ACTIVE users)
13 SUBMENU SDF GOPHERSPACE (1371 AGED users)
14 SUBMENU SDF GOPHERSPACE (373 ANCIENT users)
15 SUBMENU SDF Frequently Asked Questions (FAQ)
16 SUBMENU SDF Accredited University Courses
17 SUBMENU Software and Documentation for various computers
18 SEARCH-LINE GopherSpace SEARCH Engine
19 SUBMENU Floodgap's GOPHERSPACE
____________________________________________________________________________
Gophered by Gophernicus/97 on NetBSD/amd64 8.0_BETA
A very basic example of how a server could use the library. Assume remote-sock is a socket connected to a client:
CL-USER> (let ((lines (list
(make-instance 'cl-gopher:text-file
:hostname "myserver.org"
:port 70
:selector "/Welcome.txt"
:display-string "Welcome to myserver.org!")
(make-instance 'cl-gopher:submenu
:hostname "myserver.org"
:port 70
:selector "/Documents"
:display-string "View myserver.org's documents."))))
(mapcar (lambda (gl) (cl-gopher:write-gopher-line gl :stream (usocket:socket-stream remote-sock))) lines)
(write-line "." (usocket:socket-stream remote-sock))
(force-output (usocket:socket-stream remote-sock)))
Output sent to remote:
0Welcome to myserver.org! /Welcome.txt myserver.org 70
1View myserver.org's documents. /Documents myserver.org 70