geomyidae

A small C-based gopherd. (gopher://bitreich.org/1/scm/geomyidae)
git clone git://r-36.net/geomyidae
Log | Files | Refs | README | LICENSE

geomyidae.8 (15420B)


      1 .\" geomyidae.8 handcrafted in GNU groff -mdoc using nvi
      2 .\"
      3 .Dd March 17, 2021
      4 .Dt GEOMYIDAE 8
      5 .Os
      6 .
      7 .Sh NAME
      8 .Nm geomyidae
      9 .Nd a gopher daemon for Linux/BSD
     10 .
     11 .Sh SYNOPSIS
     12 .Nm
     13 .Bk -words
     14 .Op Fl 4
     15 .Op Fl 6
     16 .Op Fl c
     17 .Op Fl d
     18 .Op Fl e
     19 .Op Fl n
     20 .Op Fl s
     21 .Op Fl l Ar logfile
     22 .Op Fl v Ar loglevel
     23 .Op Fl b Ar base
     24 .Op Fl p Ar port
     25 .Op Fl o Ar sport
     26 .Op Fl u Ar user
     27 .Op Fl g Ar group
     28 .Op Fl h Ar host
     29 .Op Fl i Ar interface ...
     30 .Op Fl t Ar keyfile certfile
     31 .Ek
     32 .
     33 .Sh DESCRIPTION
     34 .Bd -filled
     35 .Nm
     36 is a daemon for serving the protocol specified in
     37 .Em RFC 1436
     38 (Gopher). Under 1000 lines of C by design, it is lightweight yet supports
     39 dynamic content, automatic file/directory indexing, logging and privilege
     40 separation.
     41 .Ed
     42 .
     43 .Sh IMPLEMENTATION
     44 .Bd -filled
     45 Installation is straightforward: grab the zipped tar file, expand it in
     46 an appropriate temp directory, change to the
     47 .Qq "../geomyidae-x.xx"
     48 directory, tweak the Makefile if desired (installs in
     49 .Qq "/usr/bin"
     50 by default), then run the
     51 .Sq "make ; make install"
     52 commands.  The resulting executable should be run by root.
     53 .Ed
     54 .
     55 .Ss Basic Installation and Startup:
     56 .Bd -literal
     57 
     58      $ wget ftp://bitreich.org/releases/geomyidae/geomyidae-$VERSION.tar.lz
     59      $ lzip -d geomyidae-$VERSION.tar.lz
     60      $ tar -xvf geomyidae-*.tar
     61      $ cd geomyidae-*
     62      $ make; sudo make install
     63      $ sudo mkdir -p /var/gopher
     64      $ sudo cp index.gph /var/gopher
     65      $ sudo geomyidae -l /var/log/geomyidae.log -b /var/gopher -p 70
     66      $ tail -f /var/log/geomyidae.log
     67 
     68      Use whatever gopher client you like (ie. sacc) to browse:
     69      $ sacc gopher://localhost
     70 .Ed
     71 .
     72 .Ss Running
     73 geomyidae should normally be started by root, although it can be started
     74 by a regular user provided that the base directory and its contents are owned
     75 by the same user.  geomyidae will only serve content within the base directory
     76 tree and will drop privileges to the
     77 .Fl u Ar user
     78 and
     79 .Fl g Ar group
     80 values if set.  See
     81 .Ic OPTIONS
     82 below for specifics.  Launching geomyidae automatically is best done via a UNIX
     83 run-time (rc.d) script; several sample rc.d scripts are included in the geomyidae
     84 source archive. Logging in geomyidae can be done through either logfiles
     85 or syslog.
     86 .
     87 .Sh OPTIONS
     88 geomyidae options and default settings:
     89 .Bl -tag -width Ds
     90 .
     91 .It Fl 4
     92 Only use IPv4.
     93 .
     94 .It Fl 6
     95 Only use IPv6.
     96 .
     97 .It Fl c
     98 Use
     99 .Xr chroot 2
    100 for the
    101 .Ar base
    102 directory (by default off).
    103 .
    104 .It Fl d
    105 Don't fork into background. If no log file is given, this implies logging to
    106 the standard output.
    107 .
    108 .It Fl e
    109 Disable execution of any CGI or DCGI script.
    110 .
    111 .It Fl n
    112 Don't perform reverse lookups.
    113 .
    114 .It Fl s
    115 Log using syslog for logging.
    116 .
    117 .It Fl l Ar logfile
    118 Specify file where log output is written (no default).
    119 .
    120 .It Fl v Ar loglevel
    121 Set the logging level (default: 47).
    122 .
    123 .Bd -literal
    124 Loglevels:
    125         0  - no logging
    126         1  - served plain files
    127         2  - directory listings
    128         4  - HTTP redirects
    129         8  - errors (e.g., not found)
    130         16 - client connections
    131         32 - gopher+ redirects
    132   e.g.:
    133         1 + 2 + 4 + 8 + 32 = 47
    134         (files + directories + HTTP + errors + gopher+)
    135 .Ed
    136 .
    137 .It Fl b Ar base
    138 Root directory to serve (default: /var/gopher).
    139 .
    140 .It Fl p Ar port
    141 Port geomyidae should listen on (default: 70).
    142 .
    143 .It Fl o Ar sport
    144 Port geomyidae displays within base directory (default: 70).
    145 Use in conjunction with
    146 .Ic -p
    147 for obfuscating actual port geomyidae is running on.
    148 .
    149 .It Fl u Ar user
    150 Sets the user to which privileges drop when geomyidae is ready
    151 to accept network connections (default: user geomyidae runs as).
    152 Helps improve security by reducing privileges during request
    153 processing.
    154 .
    155 .It Fl g Ar group
    156 Sets the group to which privileges drop when geomyidae is ready
    157 to accept network connections (default: group geomyidae runs as).
    158 Helps improve security by reducing privileges during request
    159 processing.
    160 .
    161 .It Fl h Ar host
    162 Host to use in directory listings (default: localhost).
    163 .
    164 .It Fl i Ar interface
    165 Defines the interface to which geomyidae binds to (default: 0.0.0.0).
    166 Multiple interfaces can be given.
    167 .
    168 .It Fl t Ar keyfile certfile
    169 Activate gopher TLS and use the private key
    170 .Ar keyfile
    171 and the public key
    172 .Ar certfile
    173 for TLS connections (if the feature is compiled in.) See ENCRYPTION ONLY
    174 support below.
    175 .El
    176 .
    177 .Sh FORMATTING
    178 .Bd -filled
    179 Structured Gopher space(s) can be created with geomyidae through the
    180 use of special indexing files of the form
    181 .Ic <name>.gph
    182 which, if present, geomyidae uses to format and/or filter the contents of
    183 the base directory (/var/gopher by default) and create gopher menus.
    184 However, index files are
    185 .Em not
    186 required: if no index.gph, index.cgi or index.dcgi
    187 file is found, geomyidae simply lists the directory
    188 contents in alphanumeric order.  In addition, a directory can utilize
    189 multiple index files to create a layered gopher environment without the
    190 use of sub-directories: ie. pictures.gph, music.gph, documents.gph could
    191 be "directories" within main.gph, yet all reside in /var/gopher along with
    192 their respective files (*.jpg, *.mp3, *.pdf for example).
    193 .Ed
    194 .
    195 .Ss Anatomy of an index.gph file
    196 A gph file consists of informational text and links. A link has the form:
    197 .Bl -inset -offset indent
    198 .It Ic [<type>|<desc>|<path>|<host>|<port>]
    199 .El
    200 .Pp
    201 where,
    202 .Bl -inset -offset indent
    203 .It Ic <type>
    204 = A valid gopher Item Type.
    205 .Pp
    206 Some common Gopher Types as defined in
    207 .Em RFC 1436
    208 :
    209 .
    210 .Bd -literal
    211  0   Item is a file.
    212  1   Gopher directory.
    213  3   Error.
    214  7   Item is an Index-Search server.
    215  8   Item points to a text-based telnet session.
    216  9   Binary file. Client reads until TCP connection closes!
    217  g   GIF format graphics file.
    218  I   Indeterminate image file. Client decides how to display.
    219 .Ed
    220 .Pp
    221 In addition, geomyidae provides these:
    222 .Bd -literal
    223  h   Item is a hypertext (HTTP) link.
    224  i   Informational Item (used for descriptive purposes).
    225 .Ed
    226 .
    227 .Bd -filled
    228 Unknown file types default to Type "9" (binary).
    229 .Ed
    230 .
    231 .It Ic <desc>
    232 = description of gopher item. Most printable characters should work.
    233 .
    234 .It Ic <path>
    235 = full or relative path to gopher item (base value is
    236 .Qq "/"
    237 ). Use the
    238 .Qq "Err"
    239 path for items not intended to be served.
    240 .
    241 .It Ic <host>
    242 = hostname or IP hosting the gopher item. Must be resolvable for the
    243 intended clients. If this is set to
    244 .Qq "server"
    245 , the server's hostname is used.
    246 .
    247 .It Ic <port>
    248 = TCP port number (usually 70).
    249 .
    250 If this is set to
    251 .Qq "port"
    252 , the default port of the server is used.
    253 .El
    254 .
    255 .Bd -filled
    256 Note: geomyidae doesn't require "informational" text to be formally
    257 Typed as "[i|...]"; any line
    258 .Em not
    259 beginning with "[" is treated as informational, greatly simplifying the
    260 formatting of index.gph files.  However, if a line begins with a "t", this
    261 "t" is left out.  This quirk is there to allow "informational" text lines
    262 beginning with a "[" to display.  For dynamically generated index files
    263 it may be desirable to either formally Type informational text or run
    264 it through a filter to add a second "t" - .ie sed 's/^t/&&/' .
    265 .Ed
    266 .Bd -filled
    267 Note 2: You can escape a pipe ("|") character in for example a
    268 .Em <desc>
    269 field by prepending a slash ("\\").
    270 .Ed
    271 .Bd -filled
    272 Note 3: The gph parser is very forgiving. If the link structure is not parsed
    273 correctly, then the original line is printed.
    274 .Ed
    275 .
    276 .Ss index.gph Example
    277 A root.gph file for a server running on host=frog.bog, port=70.  Note use
    278 of optional [i]nformational Item (line 2) for vertical space insertion:
    279 .Bd -literal -offset indent
    280 Welcome to Frog.bog
    281 [i||Err||]
    282 [0|About this server|about.txt|frog.bog|70]
    283 [0|Daily Log|/dtail.cgi|frog.bog|70]
    284 [1|Phlog: like a blog, but not|/PHLOG|frog.bog|70]
    285 [9|Some binary file|widget.exe|frog.bog|70]
    286 [I|Snowflake picture|snowflake.jpg|frog.bog|70]
    287 ttry our snowflakes!
    288 
    289 Links and Searches
    290 [1|Go to R-36.net|/|gopher.r-36.net|70]
    291 [h|Go to NetBSD.org|URL:http://netbsd.org|frog.bog|70]
    292 [7|Query US Weather by Zipcode|/weather.cgi?|frog.bog|70]
    293 [7|Search Veronica II|/v2/vs|gopher.floodgap.com|70]
    294 [8|Telnet to SDF Public Access Unix System|null|freeshell.org|23]
    295 .Ed
    296 .
    297 .Pp
    298 The above looks something like this in a text-based gopher client:
    299 .Pp
    300 .Bl -tag -width ".It Ic WIDTHS" -compact -offset indent
    301 .It Ic Welcome to Frog.bog
    302 .Pp
    303 .It Ic (FILE)
    304 About this server
    305 .It Ic (FILE)
    306 Daily Log
    307 .It Ic (DIR)
    308 Phlog: like a blog, but not
    309 .It Ic (BIN)
    310 Some binary file
    311 .It Ic (IMG)
    312 Snowflake picture
    313 .Pp
    314 try our snowflakes!
    315 .El
    316 .Pp
    317 .Bl -tag -width ".It Ic WIDTHS" -compact -offset indent
    318 .It Ic Links and Searches
    319 .It Ic (DIR)
    320 Go to R-36.net
    321 .It Ic (HTML)
    322 Go to NetBSD.org
    323 .It Ic (?)
    324 Query US Weather by Zipcode
    325 .It Ic (?)
    326 Search Veronica II
    327 .It Ic (TEL)
    328 Telnet to SDF Public Access Unix System
    329 .El
    330 .Sh DYNAMIC CONTENT (gopher CGI)
    331 .Bd -filled
    332 There are two options provided for dynamic content creation: standard CGI (
    333 .Ic .cgi
    334 ) and dynamic CGI
    335 (
    336 .Ic .dcgi
    337 ). Despite the names, both can accept input and generate dynamic content;
    338 the only difference is the latter re-formats it's output so it appears to
    339 the server as a standard geomyidae index (.gph) file. This makes the
    340 creation of on-the-fly gopher directories much easier (see examples).
    341 All scripts must be under the gopher root directory and be executable by
    342 the same user:group running geomyidae.  Consequently, it is best to use
    343 the -u and -g server options to avoid running as root.
    344 .Pp
    345 Both .cgi and .dcgi scripts have the same argument call structure (as seen by geomyidae):
    346 .Pp
    347 .D1  executable.[d]cgi $search $arguments $host $port
    348 .Pp
    349 where
    350 .Pp
    351 .D1 search = query string (type 7) or Qo Qc (type 0)
    352 .D1 arguments = string after Qo ? Qc in the path, the remaining path or Qo Qc
    353 .D1 host = server's hostname ("localhost" by default)
    354 .D1 port = server's port ("70" by default)
    355 .Pp
    356 All terms are tab-separated (per gopher protocol) which can cause some
    357 surprises depending on how a script is written.  See the CGI file (included
    358 in the geomyidae source archive) for further elaboration.
    359 .Pp
    360 For a special REST path case for the arguments, see the CGI file for the
    361 description.
    362 .Pp
    363 QUIRK: The original gopher client tried to be too intelligent. It is using
    364 gopher+ when you request some resource. When "search" is just the value "+",
    365 "!", "$" or empty, geomyidae will display a gopher+ redirect instead of invoking the
    366 script. Be careful to design your search script so the user is unlikely to
    367 enter those values. The designers of gopher+ did not think of classic gopher
    368 to survive. It survived gopher+.
    369 .Pp
    370 Additionally to the above arguments several environment variables are set.
    371 .Pp
    372 .Dl GATEWAY_INTERFACE = `CGI/1.1'
    373 .Dl PATH_INFO = script which is executed
    374 .Dl PATH_TRANSLATED = absolute path with script which is executed
    375 .Dl QUERY_STRING = arguments (See above.)
    376 .Dl SELECTOR = arguments (For backwards compatibility.)
    377 .Dl REQUEST = arguments (For backwards compatibility.)
    378 .Dl REMOTE_ADDR = IP of the client
    379 .Dl REMOTE_HOST = REMOTE_ADDR
    380 .Dl REQUEST_METHOD = `GET'
    381 .Dl SCRIPT_NAME = script which is executed
    382 .Dl SERVER_NAME = server's hostname
    383 .Dl SERVER_PORT = server's port
    384 .Dl SERVER_PROTOCOL = `gopher/1.0'
    385 .Dl SERVER_SOFTWARE = `geomyidae'
    386 .Dl X_GOPHER_SEARCH = search (See above.)
    387 .Dl SEARCHREQUEST = search (For backwards compatibility.)
    388 .Dl HTTPS and GOPHERS = set, if TLS is used
    389 .Pp
    390 .Ed
    391 .
    392 .Ss Some CGI Examples
    393 Note: these are a very simple examples with no fitness checks with respect
    394 to safety/security.
    395 .Pp
    396 ex. uptime.cgi - standard CGI, no queries
    397 .
    398 .Bd -literal -offset indent
    399 #!/bin/sh
    400 #  uptime.cgi - prints system uptime(1)
    401 /usr/bin/uptime
    402 exit 0
    403 .Ed
    404 .
    405 .Pp
    406 Call the above with the following index.gph entry:
    407 .Pp
    408 .D1 [0|System Uptime|/uptime.cgi|frog.bog|70]
    409 .Pp
    410 A search query request must have an item Type of "7" to be called
    411 from an index.gph file.  It also needs a "?" suffix in the <path>
    412 field:
    413 .Pp
    414 ex. hello.cgi - standard CGI with query
    415 .
    416 .Bd -literal -offset indent
    417 #!/bin/sh
    418 #  hello.cgi - welcome user
    419 NAME=$1
    420 HOSTNAME=$2
    421 echo ""
    422 echo Hello $NAME - welcome to $HOSTNAME
    423 exit 0
    424 .Ed
    425 .
    426 .Pp
    427 Call the above with the following index.gph entry:
    428 .Pp
    429 .D1 [7|Hello You - Please enter your name|/hello.cgi?FROG.bog|frog.bog|70]
    430 .
    431 .Pp
    432 And do a simple
    433 .Xr snarf 1
    434 query (note the inserted TAB):
    435 .Pp
    436 .D1 % snarf Qo gopher://frog.bog/7/hello.cgi?FROG.bog[TAB]Christoph Qc -
    437 .D1 Hello Christoph - welcome to FROG.bog
    438 .
    439 .Pp
    440 Dynamic CGI entries are similar to above except that the script
    441 needs to create output as described in the
    442 .Ic FORMATTING
    443 section:
    444 .Pp
    445 ex. jughead.dcgi - dynamic CGI script with query
    446 .
    447 .Bd -literal -offset indent
    448 #!/bin/sh
    449 # jughead.dcgi - jughead-like local gopher search
    450 KWRD="$1"
    451 ARCHIVE="/var/gopher/textfiles/"
    452 echo "[i|Search results for \\"${KWRD}\\":|Err||]"
    453 echo "[i||Err||]"
    454 # grep(1) recursive, case-insensitive KWRD search of ARCHIVE:
    455 for RESULT in $(/usr/bin/grep -i -l -m1 ${KWRD} -r $ARCHIVE)
    456 do
    457         DESC=$(/usr/bin/basename ${RESULT})
    458         PATH=$(echo "$RESULT" | /usr/bin/sed 's/^\\/var\\/gopher//')
    459         echo "[0|${DESC}|${PATH}|frog.bog|70]"
    460 done
    461 exit 0
    462 .Ed
    463 .
    464 .Pp
    465 Call the above with the following index.gph entry:
    466 .Pp
    467 .D1 [7|Search this Gopher|/jughead.dcgi?|frog.bog|70]
    468 .Pp
    469 A successful query might look like this:
    470 .Pp
    471 .Bl -tag -width Ds -compact -offset indent
    472 .It Search results for Qo fubar Qc :
    473 .Pp
    474 .It Ic (FILE)
    475 How_Things_Break.txt
    476 .It Ic (FILE)
    477 Origins_of_Words.txt
    478 .It Ic (FILE)
    479 Phrases_of_the_Ages.txt
    480 .El
    481 .
    482 .Pp
    483 Care should to be exercised to avoid creating miss-Typed entries, unwanted
    484 recursions, and/or unintended writes in the working directory.
    485 .Sh LOG FILES
    486 The log file (ie. /var/log/gopherd.log) has the following structure:
    487 .
    488 .Pp
    489 .Ic [<date>|<IP/Host>|<port>|<status>] <item path>
    490 .
    491 .Pp
    492 where,
    493 .
    494 .Bl -inset
    495 .It Ic <date>
    496 = access date and time (std 'date' format)
    497 .Pp
    498  ex.
    499 .Qq "2018-01-31 14:18:34 +0000"
    500 .It Ic <IP/Host>
    501 = client IP/Host served
    502 .Pp
    503 ex.
    504 .Qq "104.23.33.1"
    505 .It Ic <port>
    506 = client port served
    507 .Pp
    508 ex.
    509 .Qq "16857"
    510 .It Ic <status>
    511 = status of client request
    512 .Pp
    513 ex. - some common status entries:
    514 .It Qo serving Qc
    515 => a successful request
    516 .It Qo not found Qc
    517 => an unsuccessful request
    518 .It Qo HTTP redirect Qc
    519 => web link redirect (Type h)
    520 .It Qo dir listing Qc
    521 => unindexed directory listing
    522 .Pp
    523 .It Ic <item path>
    524 = full path to item served
    525 .Pp
    526 ex.
    527 .D1 Qo "/PICS/simple2.jpg" Qc for an image file
    528 .D1 Qo "/PICS" Qc for a directory access
    529 .El
    530 .
    531 .Sh ENCRYPTION ONLY
    532 If you set the sticky bit (chmod +t) on some file or directory, geomyidae
    533 will only serve it over an encrypted connection. There is the special
    534 case, that when the sticky bit is set on the
    535 .Ar base
    536 directory, all content will only be served over tls.
    537 .
    538 .Sh FILES
    539 README, LICENSE, CGI, index.gph, rc.d/, LINKS, gph/
    540 .
    541 .Sh SEE ALSO
    542 Links for further information on gopher:
    543 .Pp
    544 .D1 Pa gopher://gopher.floodgap.com
    545 .D1 Pa gopher://gopherproject.org
    546 .Sh STANDARDS
    547 .Em Internet RFC 1436
    548 .
    549 .Sh HISTORY
    550 .Bd -filled
    551 geomyidae started as a Linux/BSD port of the Plan 9 gopherd_P9 server.
    552 Originally called gopherd_BSD, the name was later changed to Geomyidae
    553 (latin), the taxonomic family of burrowing rodents known as "pocket
    554 gophers" which are in fact the true gophers. Due to inconsistencies
    555 and the UNIX culture, the name was changed to lowercase in 2010.
    556 .Ed
    557 .
    558 .Sh AUTHORS
    559 See LICENSE file for authors in the distribution.
    560 .
    561 .Sh LICENSE
    562 geomyidae is released under the MIT/X Consortium License.
    563 .
    564 .Sh BUGS
    565 Dynamic content functionality may vary across gopher clients.
    566 .
    567 .Ss "Reporting Bugs"
    568 Report bugs to:
    569 .An "Christoph Lohmann" Aq 20h@R-36.net