#!/bin/bash
name="mktar-batch"
version="1.1"
read -r -d '' help_message <<-EOF
Archive utility for scripting
Usage: mktar-batch [--compress=ALGO] [--encrypt=ALGO [--passphrase PASS]] [--checksum=ALGO] [--name OUTFILE] INFILES
Options:
--compress=ALGO compress archive
--checksum=ALGO create checksum
--encrypt=ALGO encrypt archive
-h, --help print this message
-n FILE, --name FILE name of backup file
-p PASS, --passphrase PASS passphase for encryption
-v, --verbose show additional messages
-V, --version print version number and exit
Compress algorithms and their ALGO codes:
n/a none or no
GZip gzip or gz
xz zx
ZStd zstd or zst
bzip2 bz2
Checksum algorithms and their ALGO codes:
n/a none or no
SHA1 sha1
SHA256 sha256
Encrypt algorithms and their ALGO codes:
n/a none or no
GPG gpg
age age
EOF
# TODO: add support for compress algorithms:
# WinRAR rar
# Ren'Py rpa
# PKZip zip
# 7-Zip 7z
source /usr/local/lib/mylib.bash
source /usr/local/lib/archive.bash
archive_fn=""
checksum=-1
compress=-1
encrypt=-1
passphrase=""
positional=()
verbose=0
while [[ $# -gt 0 ]]; do
case $1 in
--compress=no|--compress=none|--compress=0)
debug_msg "Setting compress option to 0 (=none)"
compress=0
shift
;;
--compress=gz|--compress=gzip|--compress=1)
debug_msg "Setting compress option to 1 (=gzip)"
compress=1
shift
;;
--compress=xz|--compress=2)
debug_msg "Setting compress option to 2 (=xz)"
compress=2
shift
;;
--compress=zst|--compress=zstd|--compress=3)
debug_msg "Setting compress option to 3 (=zstd)"
compress=3
shift
;;
--compress=bz2|--compress=bzip2|--compress=4)
debug_msg "Setting compress option to 4 (=bzip2))"
compress=4
shift
;;
--compress=*)
attempted_compression="$(/usr/bin/printf "%s\n" "$1" | sed -e 's/^.*=//' )"
error_msg "Bad compress option '${attempted_compression}'"
;;
--checksum=no|--checksum=none|--checksum=0)
debug_msg "Setting checksum option to 0 (=none)"
checksum=0
shift
;;
--checksum=sha1|--checksum=1)
debug_msg "Setting checksum option to 1 (=sha1)"
checksum=1
shift
;;
--checksum=sha256|--checksum=2)
debug_msg "Setting checksum option to 2 (=sha256)"
checksum=2
shift
;;
--checksum=*)
attempted_checksum="$(/usr/bin/printf "%s\n" "$1" | sed -e 's/^.*=//' )"
error_msg "Bad checksum option '${attempted_checksum}'"
;;
--encrypt=no|--encrypt=none|--encrypt=0)
debug_msg "Setting encrypt option to 0 (=none)"
encrypt=0
shift
;;
--encrypt=gpg|--encrypt=1)
debug_msg "Setting encrypt option to 1 (=gpg)"
encrypt=1
shift
;;
--encrypt=age|--encrypt=2)
debug_msg "Setting encrypt option to 2 (=age)"
encrypt=2
shift
;;
--encrypt=*)
attempted_encryption="$(/usr/bin/sed -e 's/^.*=//' <<<"$1")"
error_msg "Bad encrypt option '${attempted_encryption}'"
;;
-h|--help)
help_msg
shift
;;
-n|--name)
debug_msg "Setting output filename to ${2}"
archive_fn="$2"
shift; shift
;;
-p|--passphrase)
passphrase="$2"
shift; shift
;;
-v|--verbose)
verbose=1
shift
;;
-V|--version)
version_msg
;;
*)
debug_msg "Argument '${1}' added to positional array"
positional+=("$1")
shift
;;
esac
done
# construct archive action
if [[ "$compress" -eq 1 ]]; then
archive_action="tar.gz"
elif [[ "$compress" -eq 2 ]]; then
archive_action="tar.xz"
elif [[ "$compress" -eq 3 ]]; then
archive_action="tar.zst"
elif [[ "$compress" -eq 4 ]]; then
archive_action="tar.bz2"
else
archive_action="tar"
fi
if [[ "$encrypt" -eq 1 ]]; then
archive_action="${archive_action}.gpg"
elif [[ "$encrypt" -eq 2 ]]; then
archive_action="${archive_action}.age"
fi
# construct checksum action
if [[ "$checksum" -eq 1 ]]; then
checksum_action="sha1"
elif [[ "$checksum" -eq 2 ]]; then
checksum_action="sha256"
fi
# construct checksum filename
checksum_fn="$(fn_basename "$archive_fn").${checksum_action}"
# check checksum files
if [[ "$checksum" -ge 1 ]]; then
if contains "$checksum_fn" "${positional[@]}"; then
error_msg "checksum '${checksum_fn}' cannot be an input file"
elif ! prompt_overwrite "checksum_fn"; then
error_msg "checksum '${checksum_fn}' cannot be overwritten"
fi
fi
# check passphrase
if [[ "$encrypt" -ge 1 && -z "$passphrase" ]]; then
error_msg "No passphrase given"
fi
if ! archive --archive=$archive_action --name "$archive_fn" --passphrase "$passphrase" "${positional[@]}"; then
exit 1
fi
code=0
if [[ "$checksum" -ge 1 ]]; then
case "$checksum_action" in
sha1)
if ! /usr/bin/sha1sum "$archive_fn" | /usr/bin/awk '{print $1}' > "$checksum_fn"; then
code=1
fi
;;
sha256)
if ! /usr/bin/sha256sum "$archive_fn" | /usr/bin/awk '{print $1}' > "$checksum_fn"; then
code=1
fi
;;
esac
fi
exit "$code"