dumb scripts by acdw

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