summary refs log tree commit diff
diff options
context:
space:
mode:
authorsternenseemann <sternenseemann@systemli.org>2021-03-11 14:54:49 +0000
committersternenseemann <sternenseemann@systemli.org>2021-03-11 14:54:49 +0000
commitbab45b2a520971d9e05a1e18664c84088861c5bc (patch)
tree829c615d04fdab01587dc7a6442231e0ea231dad
parentad8fffa2ef60a112767db3ee9c35fafb4edabc53 (diff)
Deploying to gh-pages from @ sternenseemann/spacecookie@c8ca5b7e6baa0f6d4b01ee441400316ff5ed2d68 🚀
-rw-r--r--index.html32
-rw-r--r--spacecookie-gophermap.5.html183
-rw-r--r--spacecookie.1.html162
-rw-r--r--spacecookie.json.5.html273
-rw-r--r--style.css394
5 files changed, 1044 insertions, 0 deletions
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..35b9e88
--- /dev/null
+++ b/index.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>spacecookie</title>
+    <link rel="stylesheet" type="text/css" href="style.css"/>
+  </head>
+  <body>
+    <div class="index-text">
+      <h1>spacecookie</h1>
+      <ul>
+<li><a href="https://github.com/sternenseemann/spacecookie">Source (GitHub)</a></li>
+<li><a href="https://code.sterni.lv/spacecookie">Source (Mirror)</a></li>
+</ul>
+<p>spacecookie is a gopher server daemon and library written in Haskell.</p>
+<p>Below you can find the user's documentation in the form of a few man pages.
+A more general overview of the software and installation instructions can be
+found in the
+<a href="https://github.com/sternenseemann/spacecookie/blob/master/README.md">README</a>.</p>
+<p>The developer's documentation for the bundled library is
+<a href="https://hackage.haskell.org/package/spacecookie">located on Hackage</a>.</p>
+
+      <h2>man pages</h2>
+      <ul>
+        <li><a href="spacecookie.1.html">spacecookie(1)</a></li>
+<li><a href="spacecookie.json.5.html">spacecookie.json(5)</a></li>
+<li><a href="spacecookie-gophermap.5.html">spacecookie-gophermap(5)</a></li>
+
+      </ul>
+    </div>
+  </body>
+</html>
diff --git a/spacecookie-gophermap.5.html b/spacecookie-gophermap.5.html
new file mode 100644
index 0000000..7b409db
--- /dev/null
+++ b/spacecookie-gophermap.5.html
@@ -0,0 +1,183 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <link rel="stylesheet" href="style.css" type="text/css" media="all"/>
+  <title>SPACECOOKIE-GOPHERMAP(5)</title>
+</head>
+<body>
+<table class="head">
+  <tr>
+    <td class="head-ltitle">SPACECOOKIE-GOPHERMAP(5)</td>
+    <td class="head-vol">File Formats Manual</td>
+    <td class="head-rtitle">SPACECOOKIE-GOPHERMAP(5)</td>
+  </tr>
+</table>
+<div class="manual-text">
+<section class="Sh">
+<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
+<code class="Nm">spacecookie-gophermap</code> &#x2014;
+<div class="Nd">gophermap file format supported by
+  <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a></div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
+A gophermap file allows to describe a gopher menu without the need to include
+  redundant information. The format supported by
+  <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> has originally
+  been introduced by Bucktooth and is supported by most popular gopher server
+  daemons like for example
+  <a class="Xr" href="https://manpages.debian.org/unstable/pygopherd.8.en.html">pygopherd(8)</a>.
+<p class="Pp">A gophermap file stored as
+    &#x2018;<code class="Li">.gophermap</code>&#x2019; in a directory under the
+    gopher root of <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a>
+    is parsed and used as a gopher menu instead of the automatically generated
+    default variant. This allows users to customize the directory listings by
+    specifying informational text, links to files, (other) directories, gopher
+    servers or protocols themselves.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="FORMAT"><a class="permalink" href="#FORMAT">FORMAT</a></h1>
+The format is plain text and line based. Both Unix and DOS style line endings
+  are allowed. <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a>
+  distinguishes between two, technically three types of lines:
+<dl class="Bl-tag">
+  <dt><b class="Sy">info lines</b></dt>
+  <dd>Info lines are lines of text in a gophermap which don't have any special
+      format requirements except that they may not contain any tab characters.
+    <p class="Pp"></p>
+    <div class="Bd Bd-indent"><code class="Li">Any text which may contain
+      anything but tabs.</code></div>
+    <p class="Pp">They are also rendered als plain text without any associated
+        links to gopher clients which support them. Info lines are technically
+        not part of the gopher protocol nor mentioned in RFC1436, but this
+        protocol extension is widely supported and generally used.</p>
+    <p class="Pp">The usual purpose is to display additional text, headings and
+        decorative elements which are not directly related to other resources
+        served via gopher:</p>
+    <div class="Bd Pp Bd-indent">
+    <pre>
++------------------------------+
+| Welcome to my Gopher Server! |
++------------------------------+
+
+Below you can find a collection of files I deemed
+interesting or useful enough to publish them.
+    </pre>
+    </div>
+    <p class="Pp">Empty lines are interpreted as info lines which have no
+        content.</p>
+  </dd>
+  <dt><b class="Sy">menu entries</b></dt>
+  <dd>Lines describing menu entries are of the following form. All spaces are
+      for readability only and must not be present in the actual format.
+      Everything in brackets may be omitted, the semantics of which are
+      explained below.
+    <p class="Pp"></p>
+    <div class="Bd Bd-indent"><code class="Li">gopherfiletypeNAME\t [SELECTOR
+      [\tSERVER [\tPORT]]]</code></div>
+    <dl class="Bl-tag">
+      <dt><i class="Em">gopherfiletype</i></dt>
+      <dd>File type character indicating the file type of the linked resource to
+          the client. See
+          <a class="Lk" href="https://tools.ietf.org/html/rfc1436#page-14">RFC1436</a>
+          for a list of valid file types. Additionally,
+          <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> supports
+          &#x2018;<code class="Li">i</code>&#x2019; which indicates an info line
+          and &#x2018;<code class="Li">h</code>&#x2019; which indicates an HTML
+          document.</dd>
+      <dt><i class="Em">NAME</i></dt>
+      <dd>Name of the linked resource which will show up as the text of the menu
+          entry. May contain any characters except newlines and tabs.
+          <i class="Em">NAME</i> must always be terminated by a tab.</dd>
+      <dt><i class="Em">SELECTOR</i></dt>
+      <dd>Gopher selector the entry should link to. Same restrictions in terms
+          of characters apply as for <i class="Em">NAME</i>, but there should
+          only be a tab character afterwards if another field is specified. If
+          it is omitted, the value of <i class="Em">NAME</i> is used. If the
+          <i class="Em">SELECTOR</i> starts with
+          &#x2018;<code class="Li">/</code>&#x2019;, it is interpreted as an
+          absolute path and given to the client as-is. If it starts with
+          &#x2018;<code class="Li">URL:</code>&#x2019;, it is assumed that it is
+          a link to another protocol and passed to the client without
+          modification (see below). In all other cases, it is assumed that the
+          selector is a relative path and is converted to an absolute path
+          before serving the menu to a client.
+        <p class="Pp">You can read more about
+            &#x2018;<code class="Li">URL:</code>&#x2019; links which are another
+            common gopher protocol extension in
+            <a class="Lk" href="http://gopher.quux.org:70/Archives/Mailing%20Lists/gopher/gopher.2002-02%7C/MBOX-MESSAGE/34">this
+            email from John Goerzen.</a></p>
+      </dd>
+      <dt><i class="Em">SERVER</i></dt>
+      <dd>Describes the server <i class="Em">SELECTOR</i> should be retrieved
+          from. Same character restrictions apply and it must come after a tab
+          character as well. If it is omitted, the hostname of the server
+          generating the menu is used.</dd>
+      <dt><i class="Em">PORT</i></dt>
+      <dd>Describes the port <i class="Em">SERVER</i> is running on. Must come
+          after a tab and is terminated by the end of the line or file. If this
+          field is left out, the server generating the menu uses its own
+        port.</dd>
+    </dl>
+  </dd>
+</dl>
+<p class="Pp">A gophermap file may contain any number of menu and info lines.
+    They are then converted to actual gopher protocol menu entries clients
+    understand line by line as described above.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="EXAMPLE"><a class="permalink" href="#EXAMPLE">EXAMPLE</a></h1>
+Tabs are marked with &#x2018;<code class="Li">^I</code>&#x2019; for clarity.
+<div class="Bd Pp Bd-indent">
+<pre>
+spacecookie
+===========
+
+Welcome to spacecookie's gopher page!
+
+Get a copy either by downloading the latest
+stable release or cloning the development version:
+
+hGitHub page^I	URL:https://github.com/sternenseemann/spacecookie/
+9latest tarball^I	/software/releases/spacecookie-0.3.0.0.tar.gz
+
+The following documentation resources should get you started:
+
+0README^I	README.md
+1man pages^I	manpages/
+
+Other gopher server daemons (the first link only works
+if this server is running on port 70):
+
+1pygopherd^I	/devel/gopher/pygopherd^I	gopher.quux.org
+1Bucktooth^I	/buck^I	gopher.floodgap.com^I	70
+</pre>
+</div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
+  ALSO</a></h1>
+<a class="Xr" href="https://manpages.debian.org/unstable/pygopherd.8.en.html">pygopherd(8)</a>,
+  <a class="Lk" href="gopher://gopher.floodgap.com/0/buck/dbrowse?faquse%201a">Bucktooth's
+  gophermap documentation</a> and
+  <a class="Lk" href="https://tools.ietf.org/html/rfc1436#page-14">the file type
+  list from RFC1436</a>.
+<p class="Pp"><a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a>,
+    <a class="Xr" href="./spacecookie.json.5.html">spacecookie.json(5)</a></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
+The <code class="Nm">spacecookie-gophermap</code> documentation has been written
+  by <span class="An">sternenseemann</span>,
+  <a class="Mt" href="mailto:sterni-spacecookie@systemli.org">sterni-spacecookie@systemli.org</a>.
+</section>
+</div>
+<table class="foot">
+  <tr>
+    <td class="foot-date">March 11, 2021</td>
+    <td class="foot-os">NixOS</td>
+  </tr>
+</table>
+</body>
+</html>
diff --git a/spacecookie.1.html b/spacecookie.1.html
new file mode 100644
index 0000000..53e904c
--- /dev/null
+++ b/spacecookie.1.html
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <link rel="stylesheet" href="style.css" type="text/css" media="all"/>
+  <title>SPACECOOKIE(1)</title>
+</head>
+<body>
+<table class="head">
+  <tr>
+    <td class="head-ltitle">SPACECOOKIE(1)</td>
+    <td class="head-vol">General Commands Manual</td>
+    <td class="head-rtitle">SPACECOOKIE(1)</td>
+  </tr>
+</table>
+<div class="manual-text">
+<section class="Sh">
+<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
+<code class="Nm">spacecookie</code> &#x2014;
+<div class="Nd">gopher server daemon</div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
+<table class="Nm">
+  <tr>
+    <td><code class="Nm">spacecookie</code></td>
+    <td>[<code class="Fl">--version</code>]
+      <var class="Ar">config.json</var></td>
+  </tr>
+</table>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
+<code class="Nm">spacecookie</code> is a simple to use gopher daemon for serving
+  static files. It is either invoked with the <code class="Fl">--version</code>
+  flag to print its version or with the path to its config file as the single
+  argument. The minimal config file needs to tell
+  <code class="Nm">spacecookie</code> about the directory to serve and the
+  server's name, i. e. the hostname or IP address the server is reachable
+  through. All configuration options, the format and default values are
+  explained in
+  <a class="Xr" href="./spacecookie.json.5.html">spacecookie.json(5)</a>.
+<p class="Pp">On startup, <code class="Nm">spacecookie</code> will check if it
+    has been started with systemd socket activation. If that's true, it will use
+    the socket passed from systemd, if not, it will setup the socket itself.
+    After that it will call
+    <a class="Xr" href="https://manpages.debian.org/unstable/setuid.2.en.html">setuid(2)</a>
+    to switch to a less privileged user if configured to do so and start
+    accepting incoming gopher requests on the socket. Note that using socket
+    activation eliminates the need for starting as a privileged user in the
+    first place because systemd will take care of the socket. The systemd
+    integration is explained in more detail in its own section.</p>
+<p class="Pp"><code class="Nm">spacecookie</code> will not fork itself to the
+    background or otherwise daemonize which can, however, be achieved using a
+    supervisor. Logs are always written to <b class="Sy">stderr</b> and can be
+    collected and rotated by another daemon or tool if desired.</p>
+<p class="Pp">Incoming requests are filtered: No files or directories outside
+    the served directory or that start with a dot may be accessed by clients.
+    Allowed files are returned to clients unfiltered. For directories,
+    <code class="Nm">spacecookie</code> checks if they contain a
+    &#x2018;<code class="Li">.gophermap</code>&#x2019; file: If they contain
+    one, it is used to generate the directory response, otherwise one is
+    generated automatically which involves guessing all file types from file
+    extensions. The default file type is
+    &#x2018;<code class="Li">0</code>&#x2019;, text file. The file format of the
+    &#x2018;<code class="Li">gophermap</code>&#x2019; files and its use are
+    explained in
+    <a class="Xr" href="./spacecookie-gophermap.5.html">spacecookie-gophermap(5)</a>.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SYSTEMD_INTEGRATION"><a class="permalink" href="#SYSTEMD_INTEGRATION">SYSTEMD
+  INTEGRATION</a></h1>
+<code class="Nm">spacecookie</code> optionally supports two systemd-specific
+  features: It acts as a <b class="Sy">notify</b> type service and supports
+  socket activation.
+<p class="Pp">If you are writing a
+    <a class="Xr" href="https://manpages.debian.org/unstable/systemd.service.5.en.html">systemd.service(5)</a>
+    file, be sure to use the &#x2018;<code class="Li">Type=notify</code>&#x2019;
+    directive which allows <code class="Nm">spacecookie</code> to tell systemd
+    when it has finished starting up and when it is stopping before actually
+    exiting.</p>
+<p class="Pp">For socket activation, create a
+    <a class="Xr" href="https://manpages.debian.org/unstable/systemd.socket.5.en.html">systemd.socket(5)</a>
+    file that starts the <code class="Nm">spacecookie</code> service. This has
+    several advantages: For one, it allows starting
+    <code class="Nm">spacecookie</code> on demand only and reducing the load on
+    server startup. Additionally it means that the daemon doesn't ever need to
+    be started as root because it won't need to setup a socket bound to a
+    well-known port. A thing to watch out for is to make sure that the settings
+    in <a class="Xr" href="./spacecookie.json.5.html">spacecookie.json(5)</a>
+    match the settings in the
+    <a class="Xr" href="https://manpages.debian.org/unstable/systemd.socket.5.en.html">systemd.socket(5)</a>
+    file: Specifically in &#x2018;<code class="Li">listen</code>&#x2019;,
+    &#x2018;<code class="Li">port</code>&#x2019; needs to match the settings in
+    the systemd configuration while &#x2018;<code class="Li">addr</code>&#x2019;
+    won't have any effect. As always
+    &#x2018;<code class="Li">hostname</code>&#x2019; has to be configured
+    correctly as well. <code class="Nm">spacecookie</code> doesn't run any
+    sanity checks comparing the socket from systemd with information from the
+    configuration (yet).</p>
+<p class="Pp">An example
+    <a class="Xr" href="https://manpages.debian.org/unstable/systemd.service.5.en.html">systemd.service(5)</a>
+    and
+    <a class="Xr" href="https://manpages.debian.org/unstable/systemd.socket.5.en.html">systemd.socket(5)</a>
+    file are provided in the <code class="Nm">spacecookie</code> source
+    distribution in the &#x2018;<code class="Li">etc</code>&#x2019;
+  directory.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
+  ALSO</a></h1>
+<a class="Xr" href="./spacecookie.json.5.html">spacecookie.json(5)</a>,
+  <a class="Xr" href="./spacecookie-gophermap.5.html">spacecookie-gophermap(5)</a>,
+  <a class="Xr" href="https://manpages.debian.org/unstable/systemd.service.5.en.html">systemd.service(5)</a>
+  and
+  <a class="Xr" href="https://manpages.debian.org/unstable/systemd.socket.5.en.html">systemd.socket(5)</a>.
+<p class="Pp">For writing custom gopher application using the spacecookie
+    library refer to the
+    <a class="Lk" href="https://hackage.haskell.org/package/spacecookie">API
+    documentation</a>.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="STANDARDS"><a class="permalink" href="#STANDARDS">STANDARDS</a></h1>
+By default, <code class="Nm">spacecookie</code> always behaves like a gopher
+  server as described in
+  <a class="Lk" href="https://tools.ietf.org/html/rfc1436">RFC1436</a>. However
+  users can configure <code class="Nm">spacecookie</code> to utilize common
+  protocol extensions like the &#x2018;<code class="Li">h</code>&#x2019; and
+  &#x2018;<code class="Li">i</code>&#x2019; types and
+  <a class="Lk" href="http://gopher.quux.org:70/Archives/Mailing%20Lists/gopher/gopher.2002-02%7C/MBOX-MESSAGE/34">URLs
+  to other protocols</a>.
+</section>
+<section class="Sh">
+<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
+<code class="Nm">spacecookie</code> has been written and documented by
+  <span class="An">sternenseemann</span>,
+  <a class="Mt" href="mailto:sterni-spacecookie@systemli.org">sterni-spacecookie@systemli.org</a>.
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SECURITY_CONSIDERATIONS"><a class="permalink" href="#SECURITY_CONSIDERATIONS">SECURITY
+  CONSIDERATIONS</a></h1>
+<code class="Nm">spacecookie</code> supports no migitations or attack surface
+  reduction measures other than automatically switching to a less privileged
+  user after binding. It is recommended to use this feature and to make use of
+  containering or sandboxing like for example
+  <a class="Xr" href="https://manpages.debian.org/unstable/systemd.exec.5.en.html">systemd.exec(5)</a>
+  supports.
+<p class="Pp">TLS-enabled gopher, like the
+    &#x2018;<code class="Li">gophers</code>&#x2019; protocol supported by
+    <a class="Xr" href="https://manpages.debian.org/unstable/curl.1.en.html">curl(1)</a>
+    is not natively supported by <code class="Nm">spacecookie</code> at this
+    time.</p>
+</section>
+</div>
+<table class="foot">
+  <tr>
+    <td class="foot-date">March 11, 2021</td>
+    <td class="foot-os">NixOS</td>
+  </tr>
+</table>
+</body>
+</html>
diff --git a/spacecookie.json.5.html b/spacecookie.json.5.html
new file mode 100644
index 0000000..dd207bf
--- /dev/null
+++ b/spacecookie.json.5.html
@@ -0,0 +1,273 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <link rel="stylesheet" href="style.css" type="text/css" media="all"/>
+  <title>SPACECOOKIE.JSON(5)</title>
+</head>
+<body>
+<table class="head">
+  <tr>
+    <td class="head-ltitle">SPACECOOKIE.JSON(5)</td>
+    <td class="head-vol">File Formats Manual</td>
+    <td class="head-rtitle">SPACECOOKIE.JSON(5)</td>
+  </tr>
+</table>
+<div class="manual-text">
+<section class="Sh">
+<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
+<code class="Nm">spacecookie.json</code> &#x2014;
+<div class="Nd">configuration file for
+  <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a></div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
+The <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> config file is
+  a JSON file which contains a single object. The allowed fields representing
+  individual settings and their effect are explained below.
+<section class="Ss">
+<h2 class="Ss" id="REQUIRED_SETTINGS"><a class="permalink" href="#REQUIRED_SETTINGS">REQUIRED
+  SETTINGS</a></h2>
+The following settings must be part of every configuration file as there is no
+  default or fallback value for them.
+<div class="Bd-indent">
+<dl class="Bl-tag">
+  <dt><b class="Sy">hostname</b></dt>
+  <dd>Describes the public server name
+      <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> is reachable
+      through, i. e. the address clients will use to connect to it. It will be
+      used to populate gopher menus with the correct server name, so follow up
+      requests from clients actually reach the correct server. For testing
+      purposes, it can be useful to set it to
+      &#x2018;<code class="Li">localhost</code>&#x2019;.
+    <p class="Pp">Type: string.</p>
+  </dd>
+  <dt><b class="Sy">root</b></dt>
+  <dd>Sets the the directory
+      <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> should serve
+      via gopher. All gopher requests will be resolved to files or directories
+      under that root. Files and directories will be served to users if no
+      component of the resolved path starts with a dot and they are readable for
+      the user <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> is
+      running as.
+    <p class="Pp">Type: string.</p>
+  </dd>
+</dl>
+</div>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="OPTIONAL_SETTINGS"><a class="permalink" href="#OPTIONAL_SETTINGS">OPTIONAL
+  SETTINGS</a></h2>
+The following settings are optional, meaning there is either a default value or
+  an obvious default behavior if they are not given.
+<div class="Bd-indent">
+<dl class="Bl-tag">
+  <dt><b class="Sy">listen</b></dt>
+  <dd>Describes the address and port
+      <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> should listen
+      on. Both aspects can be controlled individually by the two optional fields
+      described below.
+    <p class="Pp">Type: object.</p>
+    <div class="Bd-indent">
+    <dl class="Bl-tag">
+      <dt><b class="Sy">port</b></dt>
+      <dd>Port to listen on. The well-known port for gopher is
+          <span class="Ms">70</span>.
+        <p class="Pp">If
+            <a class="Xr" href="https://manpages.debian.org/unstable/systemd.socket.5.en.html">systemd.socket(5)</a>
+            activation is used, this setting will have no effect on the actual
+            port the socket is bound to since this is done by
+            <a class="Xr" href="https://manpages.debian.org/unstable/systemd.1.en.html">systemd(1)</a>.
+            It will then only be used to display the server's port in gopher
+            menus for subsequent requests, so make sure whatever is set here
+            matches what
+            <a class="Xr" href="https://manpages.debian.org/unstable/systemd.1.en.html">systemd(1)</a>
+            is doing.</p>
+        <p class="Pp">Type: number. Default:
+            &#x2018;<code class="Li">70</code>&#x2019;.</p>
+      </dd>
+      <dt><b class="Sy">addr</b></dt>
+      <dd>Address to listen and accept gopher requests on. In contrast to
+          <b class="Sy">hostname</b>, this option controls the socket setup and
+          not what is used in gopher menus. This option is especially useful to
+          limit the addresses
+          <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> will
+          listen on since it listens on all available addresses for incoming
+          requests by default, i. e. <b class="Sy">INADDR_ANY</b>. For example,
+          &#x2018;<code class="Li">::1</code>&#x2019; can be used to listen on
+          the link-local addresses only. This is especially useful if you are
+          setting up a onion service using
+          <a class="Xr" href="https://manpages.debian.org/unstable/tor.1.en.html">tor(1)</a>
+          and want to avoid leaking the server's identity.
+        <p class="Pp">When given,
+            <a class="Xr" href="https://manpages.debian.org/unstable/getaddrinfo.3.en.html">getaddrinfo(3)</a>
+            is used to resolve the given hostname or parse the given IP address
+            and <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a>
+            will only listen on the resulting address(es). Note that
+            <b class="Sy">IPV6_V6ONLY</b> is always disabled, so, if possible,
+            both the resulting v4 and v6 address will be used.</p>
+        <p class="Pp">If
+            <a class="Xr" href="https://manpages.debian.org/unstable/systemd.socket.5.en.html">systemd.socket(5)</a>
+            activation is used, this setting has no effect.</p>
+        <p class="Pp">Type: string.</p>
+      </dd>
+    </dl>
+    </div>
+  </dd>
+  <dt><b class="Sy">user</b></dt>
+  <dd>The name of the user spacecookie should run as. When this option is given
+      and not &#x2018;<code class="Li">null</code>&#x2019;,
+      <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> will call
+      <a class="Xr" href="https://manpages.debian.org/unstable/setuid.2.en.html">setuid(2)</a>
+      and
+      <a class="Xr" href="https://manpages.debian.org/unstable/setgid.2.en.html">setgid(2)</a>
+      after setting up its socket to switch to that user and their primary
+      group. Note that this is only necessary to set if
+      <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> is started
+      with root privileges in the first place as the binary shouldn't have the
+      setuid bit set. An alternative to starting the daemon as root, so it can
+      bind its socket to a well-known port, is to use
+      <a class="Xr" href="https://manpages.debian.org/unstable/systemd.1.en.html">systemd(1)</a>
+      socket activation. See the
+      <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> man page for
+      details on setting this up.
+    <p class="Pp">Warning: Errors related to switching user are not fatal,
+        <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> will only
+        log a warning if the
+        <a class="Xr" href="https://manpages.debian.org/unstable/setuid.2.en.html">setuid(2)</a>
+        call fails.</p>
+    <p class="Pp">Type: string. Default:
+        &#x2018;<code class="Li">null</code>&#x2019;.</p>
+  </dd>
+  <dt><b class="Sy">log</b></dt>
+  <dd>Allows to customize the logging output of
+      <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> to
+      <b class="Sy">stderr</b>.
+    <p class="Pp">Type: object.</p>
+    <div class="Bd-indent">
+    <dl class="Bl-tag">
+      <dt><b class="Sy">enable</b></dt>
+      <dd>Wether to enable logging.
+        <p class="Pp">Type: bool. Default:
+            &#x2018;<code class="Li">true</code>&#x2019;.</p>
+      </dd>
+      <dt><b class="Sy">hide-ips</b></dt>
+      <dd>Wether to hide IP addresses of clients in the log output. If enabled,
+          &#x2018;<code class="Li">[redacted]</code>&#x2019; is displayed
+          instead of client's IP addresses to avoid writing personal information
+          to disk.
+        <p class="Pp">Type: bool. Default:
+            &#x2018;<code class="Li">true</code>&#x2019;.</p>
+      </dd>
+      <dt><b class="Sy">hide-time</b></dt>
+      <dd>If this is set to &#x2018;<code class="Li">true</code>&#x2019;,
+          <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> will not
+          print timestamps at the beginning of every log line. This is useful if
+          you use an additional daemon or tool to take care of logs which
+          records timestamps automatically, like
+          <a class="Xr" href="https://manpages.debian.org/unstable/systemd.1.en.html">systemd(1)</a>.
+        <p class="Pp">Type: bool. Default:
+            &#x2018;<code class="Li">false</code>&#x2019;.</p>
+      </dd>
+      <dt><b class="Sy">level</b></dt>
+      <dd>Controls verbosity of logging. It is recommended to either use
+          &#x201C;warn&#x201D; or &#x201C;info&#x201D; since
+          &#x201C;error&#x201D; hides warnings that are indicative of
+          configuration issues.
+        <p class="Pp">Type: either &#x201C;error&#x201D;, &#x201C;warn&#x201D;
+            or &#x201C;info&#x201D;. Default: &#x201C;info&#x201D;.</p>
+      </dd>
+    </dl>
+    </div>
+  </dd>
+</dl>
+</div>
+</section>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="EXAMPLE"><a class="permalink" href="#EXAMPLE">EXAMPLE</a></h1>
+The following configuration equates to the default behavior of
+  <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> for all optional
+  settings, although it is much verboser than necessary.
+<div class="Bd Pp Bd-indent">
+<pre>
+{
+  &quot;hostname&quot; : &quot;localhost&quot;,
+  &quot;root&quot; : &quot;/srv/gopher&quot;,
+  &quot;listen&quot; : {
+    &quot;addr&quot; : &quot;::&quot;,
+    &quot;port&quot; : 70
+  },
+  &quot;user&quot; : null,
+  &quot;log&quot; : {
+    &quot;enable&quot; : true,
+    &quot;hide-ips&quot; : true,
+    &quot;hide-time&quot; : false,
+    &quot;level&quot; : &quot;info&quot;
+  }
+}
+</pre>
+</div>
+<p class="Pp">This configuration is suitable for running as an onion service: It
+    disables logging completely to not collect any kind of meta data about
+    user's and only listens on the link-local address to avoid leaking its
+    identity. We can also use a non-well-known port since
+    <a class="Xr" href="https://manpages.debian.org/unstable/tor.1.en.html">tor(1)</a>
+    allows free mapping from local to exposed ports, so
+    <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a> can be started
+    as a normal user.</p>
+<div class="Bd Pp Bd-indent">
+<pre>
+{
+  &quot;hostname&quot;: &quot;myonionservicehash.onion&quot;,
+  &quot;root&quot;: &quot;/srv/onion-gopher&quot;,
+  &quot;listen&quot;: {
+    &quot;addr&quot;: &quot;::1&quot;,
+    &quot;port&quot;: 7070
+  },
+  &quot;log&quot;: {
+    &quot;enable&quot;: false
+  }
+}
+</pre>
+</div>
+<p class="Pp">If you are not using socket activation for running a gopher server
+    on the well-known port for gopher, a config like this is apporpriate,
+    provided the user &#x2018;<code class="Li">gopher</code>&#x2019; exists:</p>
+<div class="Bd Pp Bd-indent">
+<pre>
+{
+  &quot;hostname&quot;: &quot;example.org&quot;,
+  &quot;root&quot;: &quot;/srv/gopher&quot;,
+  &quot;user&quot;: &quot;gopher&quot;
+}
+</pre>
+</div>
+<p class="Pp">For a
+    <a class="Xr" href="https://manpages.debian.org/unstable/systemd.socket.5.en.html">systemd.socket(5)</a>
+    based setup, the &#x2018;<code class="Li">user</code>&#x2019; field should
+    be omitted and <a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a>
+    started as the target user directly in the
+    <a class="Xr" href="https://manpages.debian.org/unstable/systemd.service.5.en.html">systemd.service(5)</a>
+    file.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
+  ALSO</a></h1>
+<a class="Xr" href="./spacecookie.1.html">spacecookie(1)</a>.
+</section>
+<section class="Sh">
+<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
+The <code class="Nm">spacecookie.json</code> documentation has been written by
+  <span class="An">sternenseemann</span>,
+  <a class="Mt" href="mailto:sterni-spacecookie@systemli.org">sterni-spacecookie@systemli.org</a>.
+</section>
+</div>
+<table class="foot">
+  <tr>
+    <td class="foot-date">March 11, 2021</td>
+    <td class="foot-os">NixOS</td>
+  </tr>
+</table>
+</body>
+</html>
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..bd89fe1
--- /dev/null
+++ b/style.css
@@ -0,0 +1,394 @@
+/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
+
+/* Document
+   ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+html {
+  line-height: 1.15; /* 1 */
+  -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+   ========================================================================== */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+  margin: 0;
+}
+
+/**
+ * Render the `main` element consistently in IE.
+ */
+
+main {
+  display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+
+/* Grouping content
+   ========================================================================== */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+  box-sizing: content-box; /* 1 */
+  height: 0; /* 1 */
+  overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+  font-family: monospace, monospace; /* 1 */
+  font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+   ========================================================================== */
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+  background-color: transparent;
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+  border-bottom: none; /* 1 */
+  text-decoration: underline; /* 2 */
+  text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+  font-family: monospace, monospace; /* 1 */
+  font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+  font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+/* Embedded content
+   ========================================================================== */
+
+/**
+ * Remove the border on images inside links in IE 10.
+ */
+
+img {
+  border-style: none;
+}
+
+/* Forms
+   ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: inherit; /* 1 */
+  font-size: 100%; /* 1 */
+  line-height: 1.15; /* 1 */
+  margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input { /* 1 */
+  overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+  text-transform: none;
+}
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+  -webkit-appearance: button;
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+  border-style: none;
+  padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+  outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+  padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ *    `fieldset` elements in all browsers.
+ */
+
+legend {
+  box-sizing: border-box; /* 1 */
+  color: inherit; /* 2 */
+  display: table; /* 1 */
+  max-width: 100%; /* 1 */
+  padding: 0; /* 3 */
+  white-space: normal; /* 1 */
+}
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+  vertical-align: baseline;
+}
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+  overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+  box-sizing: border-box; /* 1 */
+  padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+  -webkit-appearance: textfield; /* 1 */
+  outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+  -webkit-appearance: button; /* 1 */
+  font: inherit; /* 2 */
+}
+
+/* Interactive
+   ========================================================================== */
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+  display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+  display: list-item;
+}
+
+/* Misc
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 10+.
+ */
+
+template {
+  display: none;
+}
+
+/**
+ * Add the correct display in IE 10.
+ */
+
+[hidden] {
+  display: none;
+}
+body {
+  font-size: 1em;
+  line-height: 1.5;
+  font-family: serif;
+  background-color: #efefef;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  font-family: sans-serif;
+  font-size: 1em;
+  margin: 5px 0;
+}
+
+h1 {
+  margin-top: 0;
+}
+
+a:link, a:visited {
+  color: #3e7eff;
+}
+
+h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
+  text-decoration: none;
+}
+
+.manual-text, .index-text {
+  padding: 20px;
+  max-width: 800px;
+  background-color: white;
+  margin: 0 auto;
+}
+
+table.head, table.foot {
+  display: none;
+}
+
+.Nd {
+  display: inline;
+}
+
+/* use same as cheddar for man pages */
+pre {
+  padding: 16px;
+  background-color: #f6f8fa;
+}