summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile5
-rw-r--r--forwarddown.in111
3 files changed, 115 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index b917e42..6dae642 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ backup@.timer
backup-progress
backup-statistics
fast-repair
+forwarddown
last-backups
remove-old-backups
man.commons
diff --git a/Makefile b/Makefile
index 4a7c599..761b72b 100644
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,7 @@ all: man.commons \
backup@.service backup@.timer \
backup-progress \
backup-statistics backup-statistics.1 \
+ forwarddown forwarddown.1 \
last-backups last-backups.1 \
remove-old-backups remove-old-backups.1
@@ -53,9 +54,9 @@ all: man.commons \
.PHONY: install dist clean
install: all
- install -D -m0755 -t $(DESTDIR)$(BINDIR) backup backup-progress backup-statistics last-backups remove-old-backups
+ install -D -m0755 -t $(DESTDIR)$(BINDIR) backup backup-progress backup-statistics forwarddown last-backups remove-old-backups
install -D -m0644 -t $(DESTDIR)$(LIBDIR)/systemd/system backup@.service backup@.timer
- install -D -m0644 -t $(DESTDIR)$(MANDIR)/man1 backup.1 backup-statistics.1 last-backups.1 remove-old-backups.1
+ install -D -m0644 -t $(DESTDIR)$(MANDIR)/man1 backup.1 backup-statistics.1 forwarddown.1 last-backups.1 remove-old-backups.1
install -D -m0644 -t $(DESTDIR)$(ETCDIR) backup.conf
install -D -m0755 -T sendmailadvanced.hook $(DESTDIR)$(ETCDIR)/sendmailadvanced.hooks/last-backups
diff --git a/forwarddown.in b/forwarddown.in
new file mode 100644
index 0000000..31b4487
--- /dev/null
+++ b/forwarddown.in
@@ -0,0 +1,111 @@
+#!/bin/bash
+
+[ -r "#ETCDIR#/backup.conf" ] && \
+ . "#ETCDIR#/backup.conf"
+
+usage()
+{
+ >&2 echo \
+'Usage: forwarddown key-id date backup-id1 backup-id2 ...
+Write encrypted, compressed tar from backed up files not newer than date to stdout.
+
+Options:
+ key-id key id of key to encrypt to
+ date backup should not be newer than the given date
+ backup-id[n] backups to restore
+#HELPTEXT# #'
+ [ -z "$1" ] && exit 1
+ exit $1
+}
+
+if [ $# -eq 1 ]; then
+ if [ "$1" == "--help" ]; then
+ usage 0
+ elif [ "$1" == "--version" ]; then
+ echo '#VERSION#'
+ exit
+ fi
+fi
+
+if [ $# -lt 3 ]; then
+ usage
+fi
+
+key_id=$(
+ printf '%s\n' "$1" \
+ | tr '[:lower:]' '[:upper:]'
+)
+shift
+
+if ! gpg --list-keys --with-colon "${key_id}" \
+| grep -qxF 'fpr:::::::::'"${key_id}"':'; then
+ >&2 printf 'Cannot find gpg key with fingerprint "%s"\n' "${key_id}"
+ usage
+fi
+
+if ! date=$(date -u '+%Y_%m_%d' -d"${1}"); then
+ >&2 printf 'Cannot parse date "%s"\n' "${1}"
+ usage
+fi
+shift
+
+forwarddown_dirs=()
+
+for backup_id in "$@"; do
+ if [ -z "${backups[${backup_id}]}" ]; then
+ >&2 printf 'backup id "%s" is unknown\n' "${backup_id}"
+ usage
+ fi
+ forwarddown_dirs+=("${backups[${backup_id}]## *}")
+done
+
+date=$(
+ {
+ find "${forwarddown_dirs[@]%% *}" -mindepth 1 -maxdepth 1 -type d -printf '0 %f\n'
+ printf '1 %s\n' "${date}"
+ } \
+ | sort -k2,2 -k1,1 \
+ | sed '
+ s/^0 //
+ t
+ /^1 / q
+ ' \
+ | uniq -c \
+ | sed '
+ s/^\s*'"${#forwarddown_dirs[@]}"'\s\+//
+ t
+ d
+ ' \
+ | tail -n1
+)
+
+transforms=(
+ $(
+ for backup_id in "$@"; do
+ printf -- '--transform=s@^%s/%s/@%s/%s/@\n' \
+ "${backups[${backup_id}]%% *}" \
+ "${date}" \
+ "${date}" \
+ "${backup_id}"
+ done
+ )
+)
+
+directories=(
+ $(
+ for backup_id in "$@"; do
+ printf '%s/%s/\n' \
+ "${backups[${backup_id}]%% *}" \
+ "${date}"
+ done
+ )
+)
+
+tar \
+ -c \
+ -f - \
+ --absolute-names \
+ "${transforms[@]}" \
+ "${directories[@]}" \
+| pigz --best -c - \
+| gpg -e -r "${key_id}" -o - -