agetar/agetar
2023-05-04 19:51:46 -04:00

98 lines
2.9 KiB
Bash
Executable file

#!/bin/sh
RED="$(printf '\033[38;5;9m')"
RESET="$(printf '\033[m')"
set -euf
BN="${0##*/}"
export POSIXLY_CORRECT=1
if [ "${NO_COLOR:-}" ]; then
RED="" RESET=""
fi
errecho() {
>&2 echo "$*$RESET"
}
fail() {
errecho "${RED}error: $BN: $RESET$*"
exit 1
}
_type() { type >/dev/null 2>&1 ; }
usage() {
cat >&2 <<-EOF
usage:
$BN -e (-r RECIPIENT | -R PATH)... [-a] [-o OUTPUT] [--] FILES...
$BN -e -p [-a] [-o OUTPUT] [--] FILES...
$BN -d [-i PATH]... [-o OUTPUT] [--] FILES...
options:
-e encrypt the input files to an output tar
-d decrypt the input tar to output files
-o OUTPUT encrypting: write output tar to OUTPUT. stdout if omitted
decrypting: directory to extract to. PWD if omitted
-a encrypt to a PEM encoded format
-p encrypt with a passphrase
-r RECIPIENT encrypt to the specified RECIPIENT. can be repeated
-R PATH encrypt to the recipients listed at PATH. can be repeated
-i PATH decrypt using the identity file at PATH. can be repeated
at least one FILE is required for both encrypting and decrypting
if multiple are present, each will be processed with the same identities
you probably want an OUTPUT when encrypting, even if it's not required
(age will yet at you for that anyway unless you also use -a)
most of these options are passed directly to age(1). see its man page for
more details.
EOF
}
AGEOPTS=
RECIPIENTS=
RECIPIENTS_FILES=
IDENTITIES=
while getopts :hedo:apr:R:i: OPT; do
case $OPT in
h) usage && exit 0 ;;
e) TYPE=e; AGEOPTS="$AGEOPTS -e" ;;
d) TYPE=d; AGEOPTS="$AGEOPTS -d" ;;
o) [ ! "${OUTPUT:-}" ] && OUTPUT="$OPTARG" || fail "don't specify output twice D:" ;;
a) AGEOPTS="$AGEOPTS -a" ;;
p) AGEOPTS="$AGEOPTS -p" ;;
r) RECIPIENTS="$RECIPIENTS -r '$(printf '%s' "$OPTARG" | sed -e "s/'/'\\\\''/g")'" ;;
R) RECIPIENTS_FILES="$RECIPIENTS_FILES -R '$(printf '%s' "$OPTARG" | sed -e "s/'/'\\\\''/g")'" ;;
i) IDENTITIES="$IDENTITIES -i '$(printf '%s' "$OPTARG" | sed -e "s/'/'\\\\''/g")'" ;;
*) ;;
esac
done
shift $((OPTIND - 1))
[ "$#" -lt 1 ] && usage && exit 1
[ ! "${TYPE:-}" ] && fail 'specify one of -e or -d'
TAR="$(mktemp)"
trap 'rm "$TAR"' INT HUP QUIT EXIT
if [ "$TYPE" = "e" ]; then
{ _type bsdtar && CMD="bsdtar -rL -f"; } || \
{ _type tar && CMD="tar -rh -f"; } || \
fail "can't find tar command!"
for f; do
if [ -f "$f" ] || [ -d "$f" ]; then
$CMD "$TAR" "$f" >/dev/null 2>&1
else
errecho "$f is not a regular file or directory! skipping..."
fi
done
eval 'age $AGEOPTS ${OUTPUT:+-o "$OUTPUT"} '"$RECIPIENTS $RECIPIENTS_FILES $IDENTITIES"' "$TAR"'
else
{ _type bsdtar && CMD="bsdtar -x -f"; } || \
{ _type tar && CMD="tar -x -f"; } || \
fail "can't find tar command!"
for f; do
eval 'age $AGEOPTS -o "$TAR" '"$RECIPIENTS $RECIPIENTS_FILES $IDENTITIES"' "$f"'
[ ! -d "${OUTPUT:="$PWD"}" ] && mkdir -p "$OUTPUT"
$CMD "$TAR" -C "$OUTPUT"
done
fi