Hello there! You are currently visiting gopherspace through a
proxy. To learn more about gopher and how to browse it, read this.
______________________________________________________________________

#!/bin/sh

# Downloads a gopher file or directory to the current directory
# Only uses port 70 for now, as I've never seen a gopher server
# use anything else.
#
# If called on a directory, it will download all of the urls that
# link to files within the directory or at deeper levels.
#
# So for example if a directory has a gophermap that links to stuff
# on other servers or outside the directory, they will be ignored.
#
# Warning: this overwrites files without any prompt

me=`basename "$0"`
if [ "$#" -ne 1 ]; then
echo "usage: $me gopher://domain.abc/path/to/file"
exit
fi

pushd () {
command pushd "$@" > /dev/null
}

popd () {
command popd "$@" > /dev/null
}

selfpath="$0"
url="$1"

url="${url#*//}" # strip protocol

domain=$(domain "gopher://$url")
path="/${url#*/}" # strip domain

echo $path

map="$(mktemp)"
echo "$path" | nc $domain 70 > "$map"

cat "$map" |
{
# we need these brackets do to everything in the subshell and
# retain the value of $quit

quit=0

while read line
do
# this is not a gophermap, therefore use the output as a
# single file download
if ! [[ $line =~ ^[0135789ghiIds\;cM.].*$ ]]
then
filename="$(basename "$path")"
cp "$map" "$filename"
quit=1
break
fi
done

if [[ $quit -eq 1 ]]; then
exit
fi

cat "$map" | while read line
do
# these are all the prefixes for filetypes and directories
if [[ $line =~ ^[0159ghIds\;cM].*$ ]]
then
split=()
IFS=$'\t' read -r -a split <<< "$line"

# the link name becomes the selector if the selector is
# omitted
selector="${split[0]}"

if [[ "${split[1]}" ]]; then
selector="${split[1]}"
fi

# no domain means current domain
# ignore urls outside current domain
if ! [[ "${split[2]}" ]] || \
[[ "${split[2]}" = "$domain" ]]
then
isdir=0
if [[ $line =~ ^[1].*$ ]]
then
isdir=1
fi

# extract relative path by removing $path from the
# selector
relative="$(echo $selector | sed -e "s|$path||g")"

# Recurse directory or download file if the file is
# at a deeper level than the current directory
case $selector/ in
$path*)
[[ $isdir -eq 1 ]] && \
mkdir -p "./$relative" && \
pushd "./$relative"

# !!!! recursion !!!!
$selfpath "$(echo "$url/$relative" | \
sed -e 's|//|/|g')"

[[ $isdir -eq 1 ]] && popd
;;
esac
fi
# end domain check
fi
# end type check
done
}
# end cat "$map"