summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xonce/get_updates.sh162
1 files changed, 162 insertions, 0 deletions
diff --git a/once/get_updates.sh b/once/get_updates.sh
new file mode 100755
index 0000000..2f6485b
--- /dev/null
+++ b/once/get_updates.sh
@@ -0,0 +1,162 @@
+#!/bin/sh
+
+set -eu
+
+trap update_failure 1 2 EXIT
+
+# before we begin...
+mb_path="$PATH"
+mb_script="$0"
+mb_success=no
+mb_obtain=no
+mb_dlopt="${1:-}"
+
+error_msg()
+{
+ printf '%s\n' "$@" >&2
+}
+
+warning_msg()
+{
+ printf '%s\n' "$@" >&2
+}
+
+update_failure()
+{
+ if [ _$mb_success = _yes ]; then
+ return 0
+ fi
+
+ printf 'update info: exiting due to an error.\n' >&3
+
+ exit 2
+}
+
+
+update_needed()
+{
+ trap '' EXIT
+ mb_success=yes
+ exit 1
+}
+
+
+update_success()
+{
+ trap '' EXIT
+ mb_success=yes
+ exit 0
+}
+
+obtain_remote_file()
+{
+ pathname="$1"
+
+ case "$mb_vendor" in
+ /* )
+ cp -p "${mb_vendor}/${pathname}" \
+ "${pathname}"
+ ;;
+
+ https://* )
+ wget "${mb_vendor}/${pathname}" \
+ --output-document="${pathname}" \
+ --no-check-certificate \
+ 2>/dev/null
+ ;;
+
+ * )
+ error_msg "Invalid prefix in path argument ${pathname}"
+ update_failure
+ ;;
+ esac
+}
+
+# logging
+exec 3> /updates/update.log
+
+# previous state
+if [ -f /updates/update.pending ]; then
+ rm /updates/update.pending
+ update_needed
+fi
+
+# vendor server location
+mb_vendor=$(cat /etc/vendor.host)
+
+# obtain list of advertised updates
+obtain_remote_file /updates/updates.sha256
+mb_tarballs=$(cut -d' ' -f3 /updates/updates.sha256)
+
+# simple argument parsing
+if [ "${mb_dlopt}" = '--obtain-tarballs' ]; then
+ mb_obtain=yes
+fi
+
+# compare against local state
+for tarball in ${mb_tarballs:-}; do
+ printf 'checking local status of %s...\n' $tarball >&3
+
+ if ! [ -f /updates/$tarball ]; then
+ printf '\t/updates/%s does not exist, download needed.\n' $tarball >&3
+
+ if [ $mb_obtain = no ]; then
+ update_needed
+ else
+ mb_needed=yes
+ fi
+ else
+ printf '\t/updates/%s found, checking signatures...\n' $tarball >&3
+
+ if ! [ -f /updates/$tarball.sha256 ]; then
+ sha256sum /updates/$tarball > /updates/$tarball.sha256
+ fi
+
+ mb_remotesig=$(grep $tarball /updates/updates.sha256 | cut -d' ' -f1)
+ mb_localsig=$(cat /updates/$tarball.sha256 | cut -d' ' -f1)
+
+ printf '\tremote signature: %s\n' $mb_remotesig >&3
+ printf '\tlocal signature: %s\n' $mb_localsig >&3
+
+ if [ $mb_localsig != $mb_remotesig ]; then
+ printf '\tsignatures do not match, download needed.\n' >&3
+
+ if [ $mb_obtain = no ]; then
+ update_needed
+ else
+ mb_needed=yes
+ fi
+ else
+ printf '\tsignatures match, local tarball is already up-to-date.\n' >&3
+ mb_needed=no
+ fi
+ fi
+
+ if [ $mb_needed = yes ]; then
+ printf '\tattempting to download %s...\n' ${mb_vendor}/updates/$tarball >&3
+
+ obtain_remote_file /updates/$tarball
+ sha256sum /updates/$tarball > /updates/$tarball.sha256
+
+ mb_remotesig=$(grep $tarball /updates/updates.sha256 | cut -d' ' -f1)
+ mb_localsig=$(cat /updates/$tarball.sha256 | cut -d' ' -f1)
+
+ printf '\tremote signature: %s\n' $mb_remotesig >&3
+ printf '\tlocal signature: %s\n' $mb_localsig >&3
+
+ if [ $mb_localsig != $mb_remotesig ]; then
+ printf 'signatures do not match, aborting.\n' >&3
+ update_failure
+ else
+ printf '\t/local tarball is now up-to-date.\n' >&3
+ fi
+ fi
+
+ printf '\n' >&3
+done
+
+# status
+touch /updates/update.pending
+
+# all done
+update_success