You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
3.5 KiB
189 lines
3.5 KiB
#!/bin/sh
|
|
|
|
##
|
|
## === gosher ===
|
|
##
|
|
## gosher is a simple gopher server in a POSIX shell script:
|
|
##
|
|
## $ ./gosher [<PORT> [<GOPHERDIR>]
|
|
##
|
|
## If PORT is not specified, the default is 70. If GOPHERDIR is not
|
|
## specified, "./" is assumed
|
|
##
|
|
##
|
|
## (c) 2018 Vincenzo 'KatolaZ' Nicosia <katolaz@freaknet.org>
|
|
##
|
|
##
|
|
|
|
######################
|
|
|
|
##
|
|
## If the script is called with basename "gosher", launch the netcat
|
|
## server...
|
|
##
|
|
|
|
##
|
|
## NETCAT: the netcat command to use, and any additional option
|
|
##
|
|
### Original netcat
|
|
##NETCAT="nc.traditional"
|
|
##
|
|
### ncat (from nmap)
|
|
##NETCAT="ncat"
|
|
##
|
|
### Openbsd netcat
|
|
NETCAT="nc.openbsd"
|
|
|
|
##
|
|
## STYLE: The way in which netcat will talk to gosher_serve
|
|
##
|
|
### fork with "-c" (Does *not* work with OpenBSD netcat!!!!!)
|
|
#STYLE='fork'
|
|
##
|
|
### use named pipes (Does *not* work with original netcat!!!!!)
|
|
STYLE='pipe'
|
|
|
|
OPREFIX=/tmp/outf_
|
|
IPREFIX=/tmp/inf_
|
|
|
|
DEBUG=
|
|
#DEBUG=yes
|
|
|
|
|
|
[ -n "$DEBUG" ] && {
|
|
set -e
|
|
set -x
|
|
}
|
|
|
|
|
|
## function
|
|
cleanup(){
|
|
[ -n "$INF" ] && [ -p "$INF" ] && rm -f ${INF}
|
|
exit 1
|
|
}
|
|
|
|
MYNAME=$(basename $0)
|
|
|
|
if [ -z "${MYNAME#gosher}" ]; then
|
|
## we are called as gosher -- launch the server
|
|
|
|
PORT=${1:-70}
|
|
GOPHERDIR=${2:-"./"}
|
|
|
|
trap cleanup 0 HUP INT TRAP TERM QUIT
|
|
|
|
INF=${IPREFIX}$$
|
|
[ "$STYLE" = "pipe" ] && {
|
|
mkfifo -m 600 $INF
|
|
while [ 1 -eq 1 ]; do
|
|
./gosher_serve ${GOPHERDIR} <$INF | ${NETCAT} -vvvvv -l -p ${PORT} >$INF
|
|
done
|
|
rm -f $INF
|
|
exit 0
|
|
}
|
|
[ "$STYLE" = 'fork' ] && {
|
|
while [ 1 -eq 1 ]; do
|
|
${NETCAT} -vv -l -p $PORT -c "~/gosher_serve ${GOPHERDIR}"
|
|
done
|
|
exit 0
|
|
}
|
|
echo "Error!!! wrong STYLE specified!!!" >&2
|
|
exit 1
|
|
fi
|
|
|
|
|
|
######################
|
|
|
|
##
|
|
## ...otherwise, serve a request
|
|
##
|
|
|
|
|
|
## function
|
|
invalid_selector(){
|
|
sel="$1"
|
|
echo "3Error: Invalid selector: \"$sel\""
|
|
printf ".\r\n"
|
|
exec 1>&-
|
|
exec 2>&-
|
|
exit 1
|
|
}
|
|
|
|
## function
|
|
serve_selector(){
|
|
sel="$1"
|
|
|
|
cat "${sel}"
|
|
echo "$0: selector $sel served -- exiting " >&2
|
|
exec 1>&-
|
|
exec 2>&-
|
|
exit 0
|
|
}
|
|
|
|
|
|
### transform a .gph file into a gophermap
|
|
## function
|
|
serve_index(){
|
|
IDX=$1
|
|
IFS='
|
|
'
|
|
while read line; do
|
|
rline=$(echo $line | sed -r -e 's/\r//g')
|
|
case $rline in
|
|
'['*)
|
|
echo $rline | sed -r -e 's/\[//g;s/\]//g;s/\|/\t/g;s/\t//;s/$/\r/g'
|
|
;;
|
|
t*)
|
|
echo $rline | cut -c 2-
|
|
;;
|
|
*)
|
|
echo $line
|
|
esac
|
|
done < $IDX
|
|
printf ".\r\n"
|
|
exec 1>&-
|
|
exec 2>&-
|
|
exit 0
|
|
}
|
|
|
|
|
|
|
|
GOPHERDIR=${1:-"./"}
|
|
|
|
read selector
|
|
|
|
selector=$(echo $selector | sed -r 's:\$.*::g;s:\r::g' )
|
|
|
|
[ -n "$DEBUG" ] && {
|
|
echo "iGOPHERDIR: ${GOPHERDIR}"
|
|
echo "iselector: \"${selector}\""
|
|
}
|
|
|
|
case $selector in
|
|
/?*|"")
|
|
RP1=$(realpath "${GOPHERDIR}"/"${selector}" || "")
|
|
[ $? -eq 0 ] || invalid_selector "$selector"
|
|
RP2=$(realpath "${GOPHERDIR}")"${selector}"
|
|
[ $? -eq 0 ] || invalid_selector "$selector"
|
|
[ -n "$DEBUG" ] && {
|
|
echo "iRP1: ${RP1}"
|
|
echo "iRP2: ${RP2}"
|
|
}
|
|
|
|
if [ "${RP1}" = "${RP2}" ]; then
|
|
if [ -f "${RP1}" ]; then
|
|
serve_selector "${RP1}"
|
|
elif [ -d "${RP1}" ]; then
|
|
[ -f "${RP1}/gophermap" ] && serve_selector "${RP1}/gophermap"
|
|
[ -f "${RP1}/index.gph" ] && serve_index "${RP1}/index.gph"
|
|
fi
|
|
fi
|
|
invalid_selector "$selector"
|
|
;;
|
|
*)
|
|
[ -f "${GOPHERDIR}/gophermap" ] && serve_selector "${GOPHERDIR}/gophermap"
|
|
[ -f "${GOPHERDIR}/index.gph" ] && serve_index "${GOPHERDIR}/index.gph"
|
|
invalid_selector "/"
|
|
;;
|
|
esac
|
|
|
|
|