commit 6626fecca9809d6b0868c695ab3144bafa8f3e1d
Author: phoebos <ben@bvnf.space>
Date: Fri, 19 Nov 2021 18:55:50 +0000
initial
Diffstat:
A | README | | | 10 | ++++++++++ |
A | UNLICENSE | | | 24 | ++++++++++++++++++++++++ |
A | geminidsh | | | 68 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/README b/README
@@ -0,0 +1,10 @@
+this is a basic gemini server written in ~50 lines of POSIX sh.
+no, you don't want to use it.
+
+doesn't do:
+* TLS or networking (use inetd(8))
+* chrooting or sandboxing
+* CGI
+* redirections
+* virtual hosts
+* lang parameter support
diff --git a/UNLICENSE b/UNLICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
diff --git a/geminidsh b/geminidsh
@@ -0,0 +1,68 @@
+#!/bin/sh -e
+
+ROOTDIR=/var/www/gemini
+
+while getopts d: name; do
+ case "$name" in
+ d) ROOTDIR="$OPTARG" ;;
+ ?) printf "usage: %s [-d rootdir]\n" "$0" >&2
+ exit 1 ;;
+esac
+done
+
+cd "$ROOTDIR"
+
+cr="$(printf "\r")"
+read -r line
+case "$line" in
+ gemini://*$cr) ;;
+ *) printf "59 Bad Request\n"
+ exit 1 ;;
+esac
+
+# strip gemini:// prefix
+line=${line##gemini://}
+# strip \r suffix
+line=${line%$cr}
+
+set -f
+IFS=/
+# shellcheck disable=2086
+set -- $line
+unset IFS
+set +f
+HOSTNAME=$1
+shift
+
+while [ "$#" -gt 1 ]; do
+ if [ -d "$1" ]; then
+ cd "$1"
+ shift
+ continue
+ elif [ -f "$1" ] ; then break
+ else
+ printf "50 Not Found\r\n"
+ exit 1
+ fi
+done
+
+# assume index.gmi if not specified
+if [ -d "$1" ]; then
+ cd "$1"
+ set -- "index.gmi"
+fi
+
+# now $1 is the requested file.
+file="$1"
+
+if [ ! -f "$file" ] || [ ! -r "$file" ]; then
+ printf "50 Not Found\r\n"
+ exit 1
+fi
+
+# TODO: use /etc/mime.types
+mimetype="text/plain"
+case "$file" in *.gmi) mimetype="text/gemini" ;; esac
+
+printf "20 %s\r\n" "$mimetype"
+cat "$file"