Serve Gopher requests under inetd(8)
This project is a Dusk package that is designed to be called by
inetd(8) and serve Gopher requests.
The package isn't designed to be very configurable, but rather to have a source code simple enough that it can easily be adapted to your needs.
This code is available from Dusk OS' files folder or as a Git repository (without SSL) at:
To build this project, you need:
make will download Dusk OS and compile the package using its
Usermode. The end result in a standalone
dkgopherd executable with
hostname is a string of the host name of the server and defaults to
"localhost". It is used for automatic directory listings.
This program reads a selector one character at a time from standard input
LF (or any control character, really...) is encountered and
then spits the appropriate response to standard output. Them, we exit.
Determining the appropriate response is done by treating the selector as a
path and searching for that path in its
BASEDIR (by default,
If the selector is empty, it becomes
index. If it's found, the contents of the
file is yielded. If the path doesn't exist, we yield "not found".
If the selector correspond to a directory, we auto-generate an index by
iterating over its contents, ignoring all elements beginning with a
In this listing, we differentiate between the "text" type and the "bin" type
through a predetermined list of file extensions for text files, by default
".txt" and ".md".
Every request is logged to syslog under the
ftp facility. On many
syslog.conf defaults, this will mean that the log appears in
inetd.conf line could look like this:
gopher stream tcp nowait:100 root /usr/libexec/dkgopherd dkgopherd example.com
Being designed for
inetd has this nice side effect that for testing, one can
simply call the executable directly and type the request in.
We read standard input in nonblocking mode so that it's possible to apply a timeout. This way, we avoid the problem of TCP connections lingering forever if the other end never terminates the request or close the connection.
The timeout is applied per character, that is, it resets as soon as we receive
something. This timeout is 10 seconds. This makes interactive requests with
possible while keeping us relatively safe from "slow requests" attacks.
The contents of standard input cannot be trusted and could be malicious. To protect the host against malicious requests, these mechanisms have been put in place.
chroot(2) itself in
BASEDIR to prevent a malicious path from
accessing files outside it.
TGTUSER (by default