Last modified: 2021-08-30 20:04

Implementation Notes

gc shall not only be a working gopher+ client but also a prototype to allow to modify the source and test experimental features. gawk is not too difficult (I guess) but some documentation of the source code might also help understanding it. This document describes some of gc's internals and it should be helpful when you look into the code to e.g. understand what is going on or add your own stuff to it.

For a description of gc's interface features see gc Explained.

Naming of Functions

My gawk scripts tend to grow over time and sooner or later it is difficult to says to which group a function belongs. (Other languages address with classes or using multiple source files.) To help organizing the code's structure I used name prefixes for the function groups.

Prefix Function related to ...
gi_ Processing Gopher items
m_ MIME-types and handlers
f_ File I/O
net_ Network functions
g_ Gopher directories
b_ Bookmarks
h_ History
do_ User interactions

Source Code Hints

do_command() is the program's main loop: it reads user commands and executes. do_get() is its entry point to fetch items.

do_get()
  if (isQuery)
      read query

  if (net_get_item() not successful)
      return

  if (item[CONTENT] ~ /\/gopher/)
      g_parse_directory()
  else if (item[CONTENT] ~ /text\//)
      do_display()
  else
      do_display()

do_display() shows either a text using less -iXF, looks up and call a handler application from /etc/mailcap or asks for a filename to save the item.

g_parse_directory() reads directory items into the array dir[]. It has two dimension: The first is the item's number in the directory and the second refers to an attrbute. E.g. dir[2, "attr"] is the Gopher+ information if the seccond item.

g_parse_directory()
  if (reply is not Gopher+)
      read Gopher0 directory
  else
      read Gopher+ response

  if (not Gopher+)
      scan the directory for an autoload item

  compute the prev-next list

Parsing the Gopher+ data is actually done in g_parse_plus_information(). It detects links by scanning the tabs andd assigns numbers to them, which are display when e.g. the plus command is used.

Networking

net_get_item() is the central function that implements network protocols for gopher/+, gemini and http/s. It does that with if/else statements which makes it difficult to understand. I plan to distribute the code to three functions (on for each protocol).

The upper half of net_get_item() deals with getting the item from the server and the lower is about content-type determination, choosing any applying a handler for text/* types.