💾 Archived View for gopher.zcrayfish.soy › 0 › irc › cheraxdestructor.sh captured on 2023-04-19 at 23:03:07.

View Raw

More Information

⬅️ Previous capture (2022-03-01)

➡️ Next capture (2024-03-21)

-=-=-=-=-=-=-

#! /bin/ash
#####Configuration section#####
#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
#The full path to the gophermap2gemini.awk script
readonly gophermap2gemini=/usr/local/bin/gophermap2gemini.awk
#Use curl, or use the gopher daemon directly
readonly usecurl=false
#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 -e pdf=P -e webp=I -e eml=m -e uue=6 -o utf-8 -w 74"
####End of configuration section, use caution if editing below this line####

### Export some environs to anything we run, could be useful
export REMOTE_HOST
export REMOTE_PORT
export REMOTE_ADDR="$REMOTE_HOST"
###

readonly baseurl="gemini://$fqdn"
#how many bytes are at the beginning of the URL?
readonly baseurllength="${#baseurl}"
#readonly baseurllength=$((${#baseurl}-1))

# Gather request
read -t 30 -r url badclient

####Request validation####
#Did we time out... If so just exit, gemini does not have a timeout code
test "$?" != "0" && exit
# Reject requests with garbage past the URL.
test ! -z "$badclient" && printf '%s\15\12' "59 BAD REQUEST; Garbage past URL in request." && exit
# See if request is for defined FQDN.
test "$(echo "$url" | head -c "$baseurllength")" != "$baseurl" && printf '%s\15\12' "59 BAD REQUEST; $baseurl URLs only please." && exit
####End of request validation####

# If it all looks good, find out what they want
filename=$(echo "$url" | tail -c +$((${#baseurl}+1)) | sed -e 's/%2c/,/gi' -e 's/%20/ /g' -e 's/\r$//g' -e 's/%3b/;/i')
#                                                                                                    ^ ^ ^ ^ ^ ^
#                                                                 curl fails without carriage return removal!!!!
filename2=$(echo "$filename" | tail -c +3)
readonly filename
# Extract query string, if present, and export it in case if non-gophernicus gopherd
QUERY_STRING="$(echo "$url" | grep "?" | cut -d? -f2-)"
export QUERY_STRING
export SEARCHREQUEST="$QUERY_STRING"

###WIP BELOW HERE####

    case "$filename" in
	/favicon.ico)
	    printf '%s\15\12' "51 NOT FOUND; favicon.ico" && exit;;
	/2*)
	    printf '%s\15\12' "50 PERMANENT FAILURE; gophertype 2 CCSO not supported" && exit;;
	/7*)
	    if [ -z "$QUERY_STRING" ]
	      then printf '%s\15\12' "10 This is a searchable gopher index. Enter search keywords"
	      else
                mimetype="20 text/gemini; "
                if [ "$usecurl" = "true" ] ; then
                  xyzzy="$(curl -q --disable -s --output - "gopher://$fqdn:$port$filename" | awk -f $gophermap2gemini | \
                         sed -e 's/=> gopher:\/\/'$fqdn':'$port'/=> gemini:\/\/'$fqdn'/g' )"
                else
                  # shellcheck disable=2086
                  xyzzy="$(echo "$filename2" | ${gopherd} ${gopherd_options} | awk -f $gophermap2gemini | \
                         sed -e 's/=> gopher:\/\/'$fqdn':'$port'/=> gemini:\/\/'$fqdn'/g' )"
                fi
	    fi
	    ;;
	###START OF DUMB / NON-INTELLIGENT GOPHER TYPES###
	/[04569IMPdghps]*)
	    case "$filename" in
		/0/stylesheet.css)
		    mimetype="20 text/css";;
		/0*)
		    mimetype="20 text/plain";;
		/4*)
		    mimetype="20 application/mac-binhex40";;
		/5*|/6*|/9*|/d*)
		    mimetype="20 application/octet-stream";;
		/I*.webp)
		    mimetype="20 image/webp";;
		/I*)
		    mimetype="20 image/jpeg";;
		/M*.mht|/M*.mhtml|/m*.mht|m*.mhtml)
		    mimetype="20 multipart/related";;
		/M*)
		    mimetype="20 message/rfc822";;
		/P*)
		    mimetype="20 application/pdf";;
		/g*)
		    mimetype="20 image/gif";;
		/h*|/H*)
		    mimetype="20 text/html";;
		/p*)
		    mimetype="20 image/png";;
		/s*.mp3)
		    mimetype="20 audio/mpeg";;
		/s*.m4a)
		    mimetype="20 video/mp4";;
		/s*)
		    mimetype="20 application/octet-stream";;
                /';'*.webm)
		    mimetype="20 video/webm";;
	    esac
	    #We now have enough information to pull in anything we're not converting to gemini markup
	    if [ "$usecurl" = "true" ] ; then
	      xyzzy="$(curl -q --disable -s --output - "gopher://$fqdn:$port$filename" | base64)"
	    else
	      # shellcheck disable=2086
	      xyzzy="$(echo "$filename2" | ${gopherd} ${gopherd_options} | base64)"
	    fi
	    isdumb="true"
	    ;;
        ###END OF DUMB / NON-INTELLIGENT GOPHER TYPES###
        *)
                #Convert gophermap to gemini markup
		mimetype="20 text/gemini; "
		if [ "$usecurl" = "true" ] ; then
                  xyzzy="$(curl -q --disable -s --output - "gopher://$fqdn:$port$filename" | awk -f $gophermap2gemini | \
		         sed -e 's/=> gopher:\/\/'$fqdn':'$port'/=> gemini:\/\/'$fqdn'/g' )"
		else
		  # shellcheck disable=2086
                  xyzzy="$(echo "$filename2" | ${gopherd} ${gopherd_options} | awk -f $gophermap2gemini | \
		         sed -e 's/=> gopher:\/\/'$fqdn':'$port'/=> gemini:\/\/'$fqdn'/g' )"
		fi
                    ;;
    esac

###OUTPUT SECTION###

#We'll use the output of curl to determine if gopher content is 404d
#Non gophermap content may be binary, base64 it so the shell can deal with it
if [ "$isdumb" = "true" ] ; then
  precontent=$(echo "$xyzzy" | base64 -d)
else
  precontent="$xyzzy"
fi

#See if there's an error
is40=$(echo "$precontent" | head -n1 | grep "Error: Access denied!")
is51=$(echo "$precontent" | head -n1 | grep "Error: File or directory not found!")

#Respond to any errors
if [ -n "$is40" ] ; then
  printf '%s\15\12' '40 TEMPORARY FAILURE; Error: Access denied!' && exit
fi

if [ -n "$is51" ] ; then
  printf '%s\15\12' '51 NOT FOUND; Error: File or directory not found!' && exit
fi

#If no errors, then we go here
printf '%s\15\12' "$mimetype"
if [ "$isdumb" = "true" ] ; then
  echo "$xyzzy" | base64 -d
else
  echo "$xyzzy"
fi