geminidsh

POSIX sh gemini server
git clone git://bvnf.space/geminidsh.git
Log | Files | Refs | README

geminidsh (1009B)


      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     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"