Added rollup script that changes a timeline of directories into tgz files
authorRalph Ronnquist <rrq@rrq.au>
Tue, 1 Oct 2024 08:50:15 +0000 (18:50 +1000)
committerRalph Ronnquist <rrq@rrq.au>
Tue, 1 Oct 2024 08:50:15 +0000 (18:50 +1000)
timeliner-rollup [new file with mode: 0755]

diff --git a/timeliner-rollup b/timeliner-rollup
new file mode 100755 (executable)
index 0000000..ae5ff25
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# This is intended as an hourly cron script for rolling up timeliner
+# directories into tgz files. Each $DIR.tgz file contains only the
+# files in the $DIR directory tree that are not also contained in its
+# successor directory tree.
+
+# Specifically, since the timeliner creates the successive timeline
+# directory trees by hard-linking files, only files with inodes unique
+# to $DIR are packed into $DIR.tgz, while inodes also occurring in the
+# successor directory tree are ignored.
+#
+# The script is run with $BASE set for the directory that contains
+# timpliner directories to roll up. The script also ensures a file
+# lock on itself which is intended to block any possible run-in of a
+# later script execution on top of an ongoing execution.
+#
+# Normally the crontab entry invokes the script with a BASE
+# environment setting but without arguments. The script will then
+# re-execute itself in the $BASE directory with the directories
+# 2???-??-??/ on the command line.
+
+lsi() {
+    find "$1" -type f -print0 | xargs -0 ls -i
+}
+
+files() {
+    awk 'FNR == NR {L[$1 ""]="" $0 ; next} {delete L[$1 ""];next}
+         END { for (i in L) {print L[i]}}' <(lsi "$1") <(lsi "$2") | \
+            sed 's|^[^ ]* ||;\|^'"$1"'/|!d' | \
+            sort | tr '\012' '\000'
+}
+
+if [ -z "$BASE" ] ; then echo "BASE=... is required" >&2 ; exit 1 ; fi
+
+[ -z "$LOCKED" ] && exec env LOCKED=yes flock -E 0 -n "$0" "$0" "$@"
+
+cd "$BASE" || exit 1
+[ -z "$1" ] && exec "$0" $(ls -d 2???-??-??/)
+D="${1%/}"
+shift
+for X in "$@" ; do
+    X="${X%/}"
+    tar czf "$D.tgz" --null -T <(files "$D" "$X") || exit 1
+    rm -r "$D"
+    D="$X"
+done