SDF Gopher Tutorial

[From http://sdf.org/?tutorials/gopher]

Contents
   1. What is Gopher
   2. Creating your gopherspace
   3. Gopher log
   4. Dynamic content (moles)

What is Gopher?

  From: http://en.wikipedia.org/wiki/Gopher_(protocol)

    The Gopher protocol is a TCP/IP Application layer protocol
    designed for distributing, searching, and retrieving documents
    over the Internet [...]. The protocol offers some features not
    natively supported by the Web and imposes a much stronger
    hierarchy on information stored on it.

  You can find more info here:
    * FAQ > GOPHER
    * http://www.scn.org/~bkarger/gopher-manifesto
    * http://gopher.floodgap.com/overbite/relevance.html

Creating your Gopherspace

  You can use the command "mkgopher" (after you run it, type
  "setup" in the line "MKGOPHER> "; you can type "help" for more
  details) to create a directory in your $HOME called "gopher"
  (This directory is a link to /ftp/pub/users/$USER/ ). On it, you
  can put all the files you want to be available in your
  Gopherspace.

  You can use mkgopher to publish documents, create directories,
  etc. You can also manage your Gopherspace manually. If you decide
  to do so, remember that the server will not display your content
  if it is not already visible to everyone. That is, files need to
  world-readable (chmod o+r $HOME/gopher/yourfile), directories
  need also to be world executable (chmod o+rx
  $HOME/gopher/yourdir), etc. The gopher server (Gophernicus) will
  serve executable files under /cgi-bin and also gophermaps which
  have executable permission as gopher CGIs or "moles" (see
  below). In the case of gophermaps, this is likely to result in
  errors, so make sure your gophermaps do not have execute
  permission (chmod -x $HOME/gopher/yourdir/gophermap).

  The usual 'mkgopher -p' command has not yet been updated to
  reflect Gophernicus' permissions requirements. So you may need to
  reset your permissions for all files and directories in your
  gopher directory as noted above. The following two commands will
  revert all files to world-readable but non-executable, and all
  directories to world-readable but executable.

find ~/gopher -type f -print0 | xargs -0 chmod 644
find ~/gopher -type d -print0 | xargs -0 chmod 755

  You may need to manually add execute permissions to any dynamic
  gophermaps or files under /cgi-bin after runnig these two
  commands.

 Gophermap

  Note: You can view the sample gophermap that comes with
  Gophernicus here: README.Gophermap

  Say that you have "file1.txt", "file2.pdf", "file3.rtf" and "dir"
  in your Gopherspace ("dir" is a directory). That is,

$ ls -lF
drwxr-x---  2 $USER  nobody  512 Dec  2 10:15 dir/
-rw-r-----  1 $USER  nobody    6 Dec  2 10:14 file1.txt
-rw-r-----  1 $USER  nobody    6 Dec  2 10:14 file2.pdf
-rw-r-----  1 $USER  nobody    6 Dec  2 10:14 file3.rtf

  When you visit it, if there is no file named "gophermap" (yes,
  this file has no extension) you'll see a list of the files and
  the directory, like this:


                                 Gopher Menu

(DIR) dir
(FILE) file1.txt
(FILE) file2.pdf
(FILE) file3.rtf

  If there is a gophermap file, the server will parse it and will
  present the content as you specified in gophermap.

  The gophermap syntax is:

XSome text here<TAB>/path/to/content<TAB>example.org<TAB>N

  where the first character ("X" in the example) is an "itemtype"
  (more below), "Some text here" is the text that you want to be
  displayed, <TAB> is a tab character, "/path/to/content" is the
  location of the content, "example.org" is the server where the
  content is located and the last character ("N" in the example) is
  the server port (usually it's 70). Content after the second <TAB>
  is optional if you are linking to content in your Gopherspace.

  The "itemtype" is one of these characters:

  Itemtype             Content
  0        Text file
  1        Directory
  2        CSO name server
  3        Error
  4        Mac HQX filer
  5        PC binary
  6        UNIX uuencoded file
  7        Search server
  8        Telnet Session
  9        Binary File
  c        Calendar (not in 2.06)
  e        Event (not in 2.06)
  g        GIF image
  h        HTML, Hypertext Markup Language
  i        "inline" text type
  s        Sound
  I        Image (other than GIF)
  M        MIME multipart/mixed message
  T        TN3270 Session/

   Gophermap example

  OK, let's say that you want to display a welcome message, a
  description for "file1.txt", "file2.pdf"and "dir", a link to an
  external server, a link to an http URL. Your gophermap should be
  like this:

Welcome to my Gopherspace!

0My text file   file1.txt
9My pdf file    file2.pdf
1My dir dir

0Why is Gopher Still Relevant?  /gopher/relevance.txt   gopher.floodgap.com 70
hAn http link   URL:http://sdf.lonestar.org/

  Remember the gophermap syntax? Then be careful about tab
  characters. In the example above, there are some <TAB>s. For
  instance, the third line is

0My text file<TAB>file1.txt

  while the seventh is

0Why is Gopher Still Relevant?<TAB>/gopher/relevance.txt<TAB>gopher.floodgap.com <TAB>70

  How come the pdf file has an itemtype 9? Well, not every kind of
  file has its own itemtype, so you can use one that makes more
  sense.

  Even if you don't need a blank line as the second line of your
  document, you can find this useful as there is a known Lynx bug
  that makes it display the second line together with the first
  (you can find a patch for this here:
  gopher://sdf.lonestar.org/0/users/bulibuta/openbsd/patches/lynx-gopher-
  newline.patch).

  This is (more or less) the output you'll see if you use a
  gophermap like the one in the example above:

                                 Gopher Menu

      Welcome to my Gopherspace!

(FILE) My text file
(BIN) My pdf file
(DIR) My dir

(FILE) Why is Gopher Still Relevant?
(HTML) An http link

Gopher log

  A gopher log ("glog" or "phlog") is similar to a blog, but on
  gopherspace. You can create your phlog and add it to the
  phlogosphere.

  Maintaining a glog consists basically (but not necessarily) in
  creating an entry (in your log directory) and modifying your
  phlog gophermap so that the new entry is displayed with its
  creation date. There's a script that you can run on SDF called
  "mkgopherentry" (located in /sys/sdf/bin/mkgopherentry) that will
  allow you to do exactly that. It will also extract the first
  paragraph from the entry and will add it on the gophermap with a
  "Continued..." link that will point to the full post. Creating an
  entry is as simple as: mkgopherentry title textfile

  where the 2 arguments are self-explaining.

  Say that you have two entries in your diary. If you use
  "mkgopherentry", they will appear like:

--This is my second post!--
   Tuesday, December 01th, 2009
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Cras eros turpis, tristique semper aliquet sit amet,
hendrerit vel enim. Integer pulvinar leo in dolor posuere
blandit.
Continued...


--First post--
   Monday, November 30th, 2009
First entry in my gopher log at SDF.
Continued...

 Other glog/phlog software

  There are some software authored by SDF members that you could
  find useful if you want to maintain a gopher log.

  germ
         gopher://sdf.lonestar.org/1/users/wt/soft/my/germ/

  slerm
         gopher://sdf.org/0/users/slugmax/about-slerm.txt
         gopher://sdf.org/9/users/slugmax/code/slerm-1.8.tgz
         http://slugmax.tx0.org/slerm-1.8.tgz

  glog
         gopher://sdf.lonestar.org/0/users/yargo/scripts/glog.sh

  mkphlog
         gopher://sdf.lonestar.org/1/users/octotep/scripts/mkphlog/

  phlogit
         gopher://sdf.org/0/users/slugmax/code/phlogit.txt

  tirph
         gopher://sdf.org/1/users/papa/tirph

  ugo
         gopher://sdf.lonestar.org/1/users/chr/scripts/ugo/

  You can find more resources in the "Glogging/Phlogging" section
  at gopher://sdf.lonestar.org/1/users/wt/soft/gopher.

Dynamic content (gopher CGIs or moles)

  The server used by SDF (Gophernicus) is able to serve
  "moles". Moles are executable files under /cgi-bin that are
  processed by the server as CGIs. This means that you can write a
  script, that the server will execute and it will present the data
  that your mole dumps to standard output. With moles you don't
  have to declare a content type header.  Moles get arguments from
  the address used to access the document and can be accessed with
  whatever itemtype makes sense for the kind of output the mole
  generates.

  You can code moles with the language(s) you are comfortable and
  can use on SDF. Below we will see some examples using shell
  scripts.

 Mole examples

  Remember that your moles need to be executable (and readable) by
  everyone, and under /cgi-bin. So you will have to do: chmod 755
  YOURSCRIPT.cgi

   fortune.cgi

  The following example will generate a random fortune:
#!/bin/sh
/usr/pkg/games/fortune

  Easy enough, isn't it? As it is raw text, you can access it using am
  itemtype = 0, that is:
  gopher://sdf.lonestar.org/0/users/YOUR-USERNAME/cgi-bin/fortune.cgi

  Did you notice that "fortune" was called with a full path? OK,
  that's because the server's path is
  "PATH=/sbin:/bin:/usr/sbin:/usr/bin". That means that if you call
  a program without a path, the server will search in "/sbin",
  "/bin", "/usr/sbin" and "/usr/bin". There's no "/usr/pkg/games",
  or other path in the server's $PATH (eventually, you can add a
  path of your choice with, e.g., PATH=$PATH:/usr/pkg/games).

   ls.cgi

  The following example will generate a list of files on a
  specified directory. It will be possible to sort the content
  alphabetically or by modification time, based on how you access
  the script.

#!/bin/sh

directory=/ftp/pub/users/YOUR-USERNAME
rel_dir=/users/YOUR-USERNAME
server=sdf.lonestar.org
port=70

# The internal field separator is set to be a newline
IFS='
'

if [ -n "$1" -a "$1" = 'date' ] ; then
   ls_arg=t
fi

for i in $(ls -l${ls_arg} $directory) ; do

   content=$(echo "$i" | awk '{ print $9}')
   date=$(echo "$i" | awk '{ print $6,$7,$8}')

   if [ -z "$content" ] ; then
       continue
   fi

   if [ -d $directory/$i ] ; then
       itemtype=1
   else
       itemtype=0
   fi

   echo "$itemtype$content ($date) $rel_dir    $server $port"
done


  Note that the "echo..." line is

echo "$itemtype$content ($date)<TAB>$rel_dir<TAB>$server<TAB>$port"

  If you go to
  gopher://sdf.lonestar.org/1/users/YOUR-USERNAME/cgi-bin/ls.cgi,
  you will see a list of your files sorted alphabetically. If you
  access your mole as
  gopher://sdf.lonestar.org/1/users/YOUR-USERNAME/cgi-bin/ls.cgi?date,
  then you'll see your files/directories sorted by modification
  time.

   figlet.cgi

  You can add some interactivity by using the itemtype 7. This
  itemtype is intended to make it possible to type some characters
  in a search field in your browser. However, you can use it to
  make it possible to pass arguments to your scripts. The following
  example will use some text you digit in the search field and will
  pass it through the program "figlet".

#!/bin/sh
IFS='
'

for line in $(/usr/pkg/bin/figlet "$@") ; do
   echo "i$line"  # This is itemtype=i + text
done

  When you access the script via
  gopher://sdf.lonestar.org/7/users/YOUR-USERNAME/cgi-bin/figlet.cgi
  , your browser will ask you to input some text (the way it ask
  depends on the browser), then it will show your text as figlet
  transforms it.

  The "i" in the "echo..." line is important here. Indeed, the
  document is been accessed with an itemtype "7" (but the same
  applies for itemtype "1"), so the document should be structured
  similarly to gophermaps. It's not a gophermap, though. That's why
  you need to explicitily state the line should be displayed as
  simple (or "inline") text.

 Caveat

  Besides what was said in the last paragraph of the "figlet.cgi"
  example, there's also another thing to stress. In that example
  (as with anything that will be served as a virtual directory or
  with an itemtype 1 or 7), content won't be displayed if you
  access your script via floodgap proxy (and maybe others). In this
  case you will need to "format" the output of your script. Luckily
  this is very easy. For instance, in the figlet.cgi example you
  will need to modify the "echo ..." line this way: echo
  "i$i<TAB><TAB>error.host<TAB>1" where <TAB> is a tab character
  (you should already know this!)C and "error.host" and "1" are,
  respectively, a fake server and port number (you could also have
  written "fake" instead of "error.host" and "300" instead of "1").

  $Id: gopher.html,v 1.19 2017/05/08 17:21:40 slugmax Exp $