#!/bin/bash #set -eu # GLOBAL VARIABLES CAPSULE_DIR="" # PERCENT-ENCODING encode_precent_encoding(){ url=$(echo "$1"|awk '{gsub(/ /,"%20");print}') echo "$url" } decode_percent_encoding(){ echo "$1" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b" } # FILE FORMATING OPTIONS raw2gmi_print(){ printf "20 text/gemini\r\n" cat "$1" } raw2gmi_dump(){ echo '```' cat "$1" echo '```' } txt2gmi_print(){ printf "20 text/gemini\r\n" awk '{printf "%s\n\n",$0}' "$1" } txt2gmi_dump(){ awk '{printf "%s\n\n",$0}' "$1" } gmi2gmi_print(){ printf "20 text/gemini\r\n" cat "$1" } gmi2gmi_dump(){ cat "$1" } # PHARSING link2gmi(){ # Pharse a link indicated by "=>path [optional title]" # Parameter: string of the form "=>path [optional title]" line="$1" path=$(echo "${line:2}" | awk '{print $1}') path="$CAPSULE_DIR$path" # File if [[ -f "$path" ]]; then ext=$(echo "$path"|awk -F'.' '{print $NF}') case $ext in capsule) title=$(echo "${line:2}" | awk '{match($0,/ /);print substr($0,RSTART+1)}') title_enc=$(encode_precent_encoding "$title") echo "=>main.cgi?capsule=$path $title" ;; *) echo "=>$CAPSULE_DIR${line:2}" ;; esac fi # Directory if [[ -d "$path" ]]; then title=$(echo "${line:2}" | awk '{match($0,/ /);print substr($0,RSTART+1)}') title_enc=$(encode_precent_encoding "$title") echo "=>main.cgi?open=$path&title=$title_enc $title" fi # External link if [[ "${line:0:11}" == "=>gemini://" ]];then echo "$line" fi } dump2gmi(){ # Dump the content indicated by "<=path [optional title]" # Parameter: string of the form "<=path [optional title]" content=$(echo "${line:2}" | awk '{print $1}') content="$CAPSULE_DIR$content" # Directory if [[ -d "$content" ]]; then header=$(echo "${line:2}" | awk '{match($0,/ /);print substr($0,RSTART+1)}') if [[ "$header" != "" ]]; then echo "$header" fi while read item do ext=$(echo "${item}"|awk -F"." '{print $NF}') case $ext in txt) label=$(head -n1 "$content/$item"|awk -F':' '{print $2}') if [[ "$label" != "" ]]; then echo "=>main.cgi?print=$content/$item $label" else echo "=>main.cgi?print=$content/$item $item" fi ;; gmi) label=$(head -n1 "$content/$item" | awk '{print substr($0,2)}') echo "=>main.cgi?print=$content/$item $label" ;; text) label="$item" echo "=>main.cgi?print=$content/$item $label" ;; esac done < <(ls -1A "$content"|sort -r) else # File if [[ -f "$content" ]]; then header=$(echo "${line:2}" | awk '{match($0,/ /);print substr($0,RSTART+1)}') if [[ "$header" != "" ]]; then printf "$header\r\n" fi ext=$(echo "${content}"|awk -F"." '{print $NF}') case $ext in txt) txt2gmi_dump "$content" ;; gmi) gmi2gmi_dump "$content" ;; *) raw2gmi_dump "$content" ;; esac fi fi } # OPTIONS print_gmi(){ # Wehn QUERY_STRING="print=path" # Parameter: path path="$1" path_clean=$(decode_percent_encoding "$path") # Get file extension. ext=$(echo "$path"|awk -F"." '{print $NF}') case $ext in txt) txt2gmi_print "$path_clean" ;; gmi) gmi2gmi_print "$path_clean" ;; *) raw2gmi_print "$path_clean" ;; esac } open_gmi(){ # When QUERY_STRING="open=dir&title=title" # Parameters: dir title dir="$1" title="$2" dir_clean=$(decode_percent_encoding "$dir") title_clean=$(decode_percent_encoding "$title") printf "20 text/gemini\r\n" echo "# $title_clean" while read item do ext=$(echo "${item}"|awk -F"." '{print $NF}') case $ext in txt) label=$(head -n1 "$dir_clean/$item"|awk -F':' '{print $2}') ;; gmi) label=$(head -n1 "$dir_clean/$item") t="${label:2}" label="$t" ;; *) label="$item" ;; esac echo "=>main.cgi?print=$dir_clean/$item $label" done < <(ls -1A "$dir_clean") } # DEPLOY FUNCTIONS deploy_gmi(){ # Deploy gemini capsule # Parameter: .capsule file capsule="$1" printf "20 text/gemini\r\n" while IFS= read line do ## Link content indicated by "=>" if [[ "${line:0:2}" == "=>" ]]; then link2gmi "$line" fi # Dump the content indicated by "<=" if [[ "${line:0:2}" == "<=" ]]; then dump2gmi "$line" fi # Any other line if [[ "${line:0:2}" != "=>" ]] && [[ "${line:0:2}" != "<=" ]]; then echo "$line" fi done < "$capsule" } # DEPLY CAPSULE/GOPHERHOLE # Gemini if [[ "$SERVER_PROTOCOL" == "GEMINI" ]]; then # Print a file if QUERY_STRING="print=..." if [[ "${QUERY_STRING:0:5}" == "print" ]]; then path="${QUERY_STRING:6}" print_gmi "$path" else # Open a directory if QUERY_STRING="open=dir&title=title" if [[ "${QUERY_STRING:0:4}" == "open" ]]; then dir=$(echo "${QUERY_STRING:5}"|awk -F"&" '{print $1}') title=$(echo "${QUERY_STRING:5}"|awk -F"&" '{print substr($2,7)}') open_gmi "$dir" "$title" else # Deploy a specific capsule if QUERY_STRING="capsule=capsule" if [[ "${QUERY_STRING:0:7}" == "capsule" ]]; then capsule="${QUERY_STRING:8}" capsule_clean=$(decode_percent_encoding "${QUERY_STRING:8}") CAPSULE_DIR="$(dirname "$capsule_clean")" if [[ "$CAPSULE_DIR" != "" ]]; then CAPSULE_DIR="$CAPSULE_DIR/" fi deploy_gmi "$capsule_clean" else deploy_gmi "main.capsule" fi fi fi fi # Gopher GOPHER_DIR="/~filip/public_gemini" GOPHER_SERVER="tilde.club" GOPHER_PORT="70" if [[ "$SERVER_PROTOCOL" == "RFC1436" ]]; then printf "i+--------------------------------------------------------------+\t$GOPHER_SERVER\t$GOPHER_PORT\r\n" printf "i| ~~~~~~~~~~~~~~~~~ Greetings and welcome! ~~~~~~~~~~~~~~~~~~ |\t$GOPHER_SERVER\t$GOPHER_PORT\r\n" printf "i| You are accessing gemini://tilde.club/~filip via Gopher! |\t$GOPHER_SERVER\t$GOPHER_PORT\r\n" printf "i| Only a part of the capsule is avaliable here on Gopherspace. |\t$GOPHER_SERVER\t$GOPHER_PORT\r\n" printf "i+--------------------------------------------------------------+\t$GOPHER_SERVER\t$GOPHER_PORT\r\n" echo "" printf "1Gemlog - Notes and comments on various subjects\t$GOPHER_DIR/text/gemlog\t$GOPHER_SERVER\t$GOPHER_PORT\r\n" fi