#!/bin/sh mkdir -p ~/.gosh data=~/.gosh/data hist=~/.gosh/history type=~/.gosh/type # selector, host, port fetch() { printf '%s\n' "$2" | grep -q '[a-z]' || return 1 printf '%s\r\n' "$1" | nc "$2" "$3" > "$data" 2>/dev/null } # type, selector, host, port metafetch() { fetch "$2" "$3" "$4" || return 1 printf '%s\n' "$1" > "$type" printf '%s%s\t%s\t%s\t%s\r\n' \ "$1" "$(date -Is)" "$2" "$3" "$4" >> "$hist" } gophermap_transform() { awk -F '\t' ' /^i/ { printf("\t%s\n", substr($1, 2)) } /^[^i.]/ { printf("%d\t%s\n", ++n, substr($1, 2)) } ' } view() { local viewer case "$(cat "$type")" in 0) less -E -X "$data";; 1) gophermap_transform < "$data" | less -E -X;; *) printf '? ' trap 'echo; return 1' INT read viewer || echo trap - INT [ "$viewer" ] || return 1 sh -c "$viewer" < "$data" ;; esac } # type, filename, number follow() { local line sep chr1 sltr host port [ "$1" = 1 ] || return 1 line="$(grep '^[^i.]' "$2" 2>/dev/null | sed -n "$3p" | tr -d '\r')" [ "$line" ] || return 1 sep="$(printf '\t')" chr1="$(printf '%s\n' "$line" | cut -c1)" sltr="$(printf '%s\n' "$line" | cut -d"$sep" -f2)" host="$(printf '%s\n' "$line" | cut -d"$sep" -f3)" port="$(printf '%s\n' "$line" | cut -d"$sep" -f4)" metafetch "$chr1" "$sltr" "$host" "$port" } back() { printf '$-1,$m0\nwq\n' | ed "$hist" >/dev/null follow 1 "$hist" 1 && view } while : do printf '> ' trap 'echo; continue' INT read -r cmd || break trap - INT case "$cmd" in q ) exit;; '') view;; b ) back;; * ) if printf '%s\n' "$cmd" | grep -q '^[1-9][0-9]*$' then follow "$(cat "$type")" "$data" "$cmd" && view else metafetch 1 '' "$cmd" 70 && view fi ;; esac done printf '\n'