gc (2126B) [raw]
1 #!/bin/sh 2 # gc -- gopher client 3 die() { 4 echo "$*" 1>&2 5 exit 1 6 } 7 8 [ -z "$1" ] && die "usage: gc URL" 9 10 pretty() { 11 awk -F" " " 12 /^[^01i\.]/ { sub(\"^.\", \"\", \$1); printf \" ???| %s\\n\", \$1 } 13 /^i/ { sub(\"^i\", \"\", \$1); printf \" | %s\\n\", \$1 } 14 /^0/ { sub(\"^0\", \"\", \$1); links[n++] = sprintf(\"%s/0%s\", \$3, \$2); printf \"%2d TXT| %s\\n\", n, \$1 } 15 /^1/ { sub(\"^1\", \"\", \$1); links[n++] = sprintf(\"%s/1%s\", \$3, \$2); printf \"%2d DIR| %s\\n\", n, \$1 } 16 END { 17 printf \"\" > \"$LINKS\" 18 for (i=0; i < length(links); i++) { 19 printf \"[%d]: %s\\n\", i + 1, links[i] >>\"$LINKS\" 20 } 21 } 22 " 23 } 24 25 parseurl() { 26 bare=${URL##gopher://} 27 host=${bare%%/*} 28 target=${bare##$host} 29 } 30 31 catlike() { 32 parseurl 33 case "$target" in 34 /0/*) echo "${target##/0}" | nc "$host" 70 ;; 35 /1/*) echo "${target##/1}" | nc "$host" 70 | pretty ;; 36 *) echo "$target" | nc "$host" 70 | pretty ;; # TODO: handle other types? 37 esac 38 } 39 40 goto() { 41 printf "goto> " 42 read -r URL 43 } 44 45 graburl() { 46 N="$1" 47 link=$(grep "^\[$N\]:" "$LINKS") 48 URL=${link##\[*\]: } 49 } 50 51 ui() { 52 while [ -n "$URL" ]; do 53 parseurl 54 case "$target" in 55 /0/*) echo "${target##/0}" | nc "$host" 70 | ${PAGER:-less} ;; 56 /1/*) echo "${target##/1}" | nc "$host" 70 | pretty ;; 57 *) echo "$target" | nc "$host" 70 | pretty ;; # TODO: handle other types? 58 esac 59 60 URL="" 61 while true; do 62 printf "> " 63 read -r opt 64 case $opt in 65 [0-9]*) graburl "$opt" && if [ -n "$URL" ]; then break; else echo "no such link"; fi ;; 66 l*) cat "$LINKS" ;; 67 g*) goto ; break ;; 68 h*) cat <<EOM ;; 69 NUM -- go to this target 70 g[oto] -- specify new URL 71 h[elp] -- print this message 72 l[ist] -- list targets 73 q[uit] -- quit 74 EOM 75 q*) break;; 76 *) echo "no such command; 'h' for help, 'q' to quit" ;; 77 esac 78 done 79 done 80 } 81 82 URL=$1 83 LINKS=$(mktemp) 84 85 if ! tty >/dev/null; then 86 catlike 87 else 88 ui 89 fi 90 91 rm -f "$LINKS"