keith #
#!/bin/sh
# KEITH -- throw and catch files
# named for Keith Hernandez, the legend
# inspired by dozens, the legend:
# https://github.com/chrisman/knowledge/wiki/netcat#file-transfer
USAGE="Usage: keith "
PORT=1717 # Keith's number (twice)
OK=true
### Library functions
send() {
nc -w0 "$1" "$PORT"
}
tell() {
printf >&2 '== %s\n' "$*"
}
prompt() {
printf >&2 ':: %s: ' "$*"
read x
echo "$x"
}
ok() {
if $OK
then tell ok.
else tell not ok.
fi
}
cr_wait() {
prompt Press ENTER when ready
}
assert_catcher() {
nc -z "$1" "$PORT"
}
print_ip() {
if command -v ip >/dev/null 2>&1
then ip addr | grep inet
elif command -v ifconfig >/dev/null 2>&1
then ifconfig | grep inet
fi
}
### Public API
keith_init() {
if test -z "$1"
then IP="$(prompt Catcher IP address)"
else IP="$1"
fi
tell Run '`nc -l '$PORT' > keith`' on the catcher.
cr_wait
send "$IP" < "$(realpath "$0")" || OK=false
}
keith_throw() {
addr="$1"; shift
if ! assert_catcher "$addr"
then
tell Run '`keith catch`' on the catcher.
tell If keith is not installed, run '`keith init`' here.
cr_wait
fi
tar -c "$@" | send "$addr" || OK=false
}
keith_catch() {
print_ip >&2
tell Ready.
nc -l "$PORT" | tar -x || OK=false
}
### Entry point
main() {
# keith
cmd="$1"; shift
case "$cmd" in
(-h) echo >&2 "$USAGE" exit ;;
(t*) keith_throw "$@" ;;
(c*) keith_catch ;;
(i*) keith_init "$@" ;;
(*) echo >&2 "$USAGE"; exit 1 ;;
esac
}
test "$DEBUG" && set -x
main "$@"
ok