#! /bin/ash
#####Configuration section#####
readonly PATH=/usr/lib/restricted/bin:/usr/bin
#The fqdn variable defines the hostname of the gopher server you'll be proxying to gemini.
readonly fqdn=gopher.zcrayfish.soy
#The port variable defines the TCP port of the gopher server you'll be proxying to gemini.
readonly port=70
#Use curl, or use the gopher daemon directly
usecurl=true
#full path to gopher daemon
readonly gopherd=/usr/sbin/gophernicus
#command options to pass to the gopher daemon
readonly gopherd_options="-h $fqdn -nv -nf -np -f /srv/gopher/filters -o utf-8 -l /var/log/gopher.access.log -T 300"
####End of configuration section, use caution if editing below this line####
#pull in the entire request and toss it into the gopherrequest variable
IFS= read -t 30 -r gopherrequest
#function to handle clients that don't support gophertype w
typew () {
printf '\xEF\xBB\xBF'
printf '%s\15\12' "Your gopher client does not support gophertype w." \
"the URL that your gopher client should have sent you to is:" \
"$1"
}
#function to handle clients that don't support the hURL hack.
hURL () {
printf '\xEF\xBB\xBF'
printf '%s\15\12' '<?xml version="1.0" encoding="UTF-8"?>' \
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"' \
' "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' \
'<html xmlns="
http://www.w3.org/1999/xhtml">' \
'<head>' \
' <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />' \
" <meta http-equiv=\"refresh\" content=\"1;URL=$1\" />" \
" <meta http-equiv=\"location\" content=\"$1\" />" \
" <title>Redirect to: $1</title>" \
'</head>' \
'<body>' \
'<p>You are following a link from gopher to another URL or protocol.' \
'You should be automatically taken to the site shortly.' \
"If you don't get sent there, please use the URL below to get there:</p>" \
"<p><a href=\"$1\">$1</a></p>" \
'</body></html>'
}
#This is where the magic happens, see if the request matches a client that doesn't know what to do with type w
#or with hURL.
case "$gopherrequest" in
http://*|https://*|ftp://*|irc://*|ircs://*|mailto:*)
#w3m converts the query string initiator into tab...
typew "$gopherrequest" | sed -e 's/ /?/g'
;;
whttp://*|whttps://*|wftp://*|wirc://*|wircs://*|wmailto:*)
#the cuts here are because some clients prepend the gophertype to the request.
#Fun fact: some older servers expected this behavior!
typew "$(echo "$gopherrequest" | cut -b 2- | sed -e 's/ /?/g')"
;;
w/http://*|w/https://*|w/ftp://*|w/irc://*|w/ircs://*|w/mailto:*)
typew "$(echo "$gopherrequest" | cut -b 3- | sed -e 's/ /?/g')"
;;
URL:http://*|URL:https://*|URL:ftp://*|URL:irc://*|URL:ircs://*|URL:mailto:*)
#for hURLs, don't encode : and completely drop CR and LF.
#dropping CRLF in one go breaks w3m.
hURL "$(echo "$gopherrequest" | cut -b 5- | urlencode | sed -e 's/%3A/:/g' -e 's/%0D//g' -e 's/%0A//g')"
;;
/URL:http://*|/URL:https://*|/URL:ftp://*|/URL:irc://*|/URL:ircs://*|/URL:mailto:*)
hURL "$(echo "$gopherrequest" | cut -b 6- | urlencode | sed -e 's/%3A/:/g' -e 's/%0D//g' -e 's/%0A//g')"
;;
h/URL:http://*|h/URL:https://*|h/URL:ftp://*|h/URL:irc://*|h/URL:ircs://*|h/URL:mailto:*)
hURL "$(echo "$gopherrequest" | cut -b 7- | urlencode | sed -e 's/%3A/:/g' -e 's/%0D//g' -e 's/%0A//g')"
;;
*)
export REMOTE_HOST
export REMOTE_PORT
export REMOTE_ADDR="$REMOTE_HOST"
if [ "$usecurl" = "true" ] ; then
#We use /0 in the URL to make it valid for curl; ditto for the tab removal and the carriage return removal.
#Many versions of curl fail with ZERO output if the URL contains a carriage return.
gopherrequestsanitized="$(echo "$gopherrequest" | sed -e 's/ /?/g' -e 's/\r$//g')"
gopherurl="gopher://$fqdn:$port/0$gopherrequestsanitized"
curl -q --disable -s --output - "$gopherurl"
else
echo "$gopherrequest" | ${gopherd} ${gopherd_options}
fi
;;
esac
exit