Blame once/get_updates.sh

ec0f88
#!/bin/sh
ec0f88
ec0f88
set -eu
ec0f88
ec0f88
trap update_failure 1 2 EXIT
ec0f88
ec0f88
# before we begin...
ec0f88
mb_path="$PATH"
ec0f88
mb_script="$0"
ec0f88
mb_success=no
ec0f88
mb_obtain=no
493d95
mb_state=true
2ddf27
mb_opt="${1:-}"
2ddf27
2ddf27
if [ "${mb_opt}" = '--mpackage' ]; then
2ddf27
	mb_mpackage="${mb_opt}"
2ddf27
	mb_dlopt="${2:-}"
2ddf27
else
2ddf27
	mb_dlopt="${mb_opt}"
2ddf27
	mb_mpackage="${2:-}"
2ddf27
fi
ec0f88
ec0f88
error_msg()
ec0f88
{
ec0f88
	printf '%s\n' "$@" >&2
ec0f88
}
ec0f88
ec0f88
warning_msg()
ec0f88
{
ec0f88
	printf '%s\n' "$@" >&2
ec0f88
}
ec0f88
ec0f88
update_failure()
ec0f88
{
ec0f88
	if [ _$mb_success = _yes ]; then
ec0f88
		return 0
ec0f88
	fi
ec0f88
ec0f88
	printf 'update info: exiting due to an error.\n' >&3
ec0f88
ec0f88
	exit 2
ec0f88
}
ec0f88
ec0f88
ec0f88
update_needed()
ec0f88
{
ec0f88
	trap '' EXIT
ec0f88
	mb_success=yes
ec0f88
	exit 1
ec0f88
}
ec0f88
ec0f88
ec0f88
update_success()
ec0f88
{
ec0f88
	trap '' EXIT
ec0f88
	mb_success=yes
ec0f88
	exit 0
ec0f88
}
ec0f88
ec0f88
obtain_remote_file()
ec0f88
{
ec0f88
	pathname="$1"
ec0f88
ec0f88
	case "$mb_vendor" in
e9df40
		/ )
e9df40
			;;
e9df40
ec0f88
		/* )
ec0f88
			cp -p "${mb_vendor}/${pathname}" \
ec0f88
				"${pathname}"
ec0f88
			;;
ec0f88
ec0f88
		https://* )
ec0f88
			wget "${mb_vendor}/${pathname}"       \
ec0f88
				--output-document="${pathname}"  \
8794af
				--no-check-certificate
8794af
				;;
ec0f88
ec0f88
		* )
ec0f88
			error_msg "Invalid prefix in path argument ${pathname}"
ec0f88
			update_failure
ec0f88
			;;
ec0f88
	esac
ec0f88
}
ec0f88
ec0f88
# logging
6b9f4e
exec 3>> /updates/update.log
ec0f88
ec0f88
# previous state
ec0f88
if [ -f /updates/update.pending ]; then
ec0f88
	rm /updates/update.pending
ec0f88
	update_needed
ec0f88
fi
ec0f88
ec0f88
# vendor server location
ec0f88
mb_vendor=$(cat /etc/vendor.host)
ec0f88
ec0f88
# obtain list of advertised updates
ec0f88
obtain_remote_file /updates/updates.sha256
2ddf27
2ddf27
if [ "${mb_mpackage}" = '--mpackage' ]; then
2ddf27
	mb_tarballs=$(cut -d' ' -f3 /updates/updates.sha256 | grep 'updater.tar.gz' || true)
2ddf27
else
2ddf27
	mb_tarballs=$(cut -d' ' -f3 /updates/updates.sha256)
2ddf27
fi
ec0f88
ec0f88
# simple argument parsing
ec0f88
if [ "${mb_dlopt}" = '--obtain-tarballs' ]; then
ec0f88
	mb_obtain=yes
ec0f88
fi
ec0f88
ec0f88
# compare against local state
ec0f88
for tarball in ${mb_tarballs:-}; do
ec0f88
	printf 'checking local status of %s...\n' $tarball >&3
ec0f88
ec0f88
	if ! [ -f /updates/$tarball ]; then
3535ad
		if [ -f /tarballs/$tarball ]; then
3535ad
			if ! [ -f /tarballs/$tarball.sha256 ]; then
3535ad
				sha256sum /tarballs/$tarball > /tarballs/$tarball.sha256
3535ad
			fi
3535ad
3535ad
			mb_remotesig=$(grep $tarball /updates/updates.sha256 | cut -d' ' -f1)
3535ad
			mb_localsig=$(cat /tarballs/$tarball.sha256 | cut -d' ' -f1)
3535ad
3535ad
			printf '\tremote signature: %s\n' $mb_remotesig >&3
3535ad
			printf '\tcached signature: %s\n' $mb_localsig >&3
3535ad
3535ad
			if [ $mb_localsig != $mb_remotesig ]; then
493d95
				mb_state=false
493d95
3535ad
				printf '\tsignatures do not match, download needed.\n' >&3
3535ad
3535ad
				if [ $mb_obtain = no ]; then
3535ad
					update_needed
3535ad
				else
3535ad
					mb_needed=yes
3535ad
				fi
3535ad
			else
3535ad
				printf '\tsignatures match, installed tarball is already up-to-date.\n' >&3
3535ad
				mb_needed=no
3535ad
			fi
ec0f88
		else
3535ad
			printf '\t/updates/%s does not exist, download needed.\n' $tarball >&3
3535ad
3535ad
			if [ $mb_obtain = no ]; then
3535ad
				update_needed
3535ad
			else
3535ad
				mb_needed=yes
3535ad
			fi
ec0f88
		fi
ec0f88
	else
493d95
		mb_state=false
493d95
ec0f88
		printf '\t/updates/%s found, checking signatures...\n' $tarball >&3
ec0f88
ec0f88
		if ! [ -f /updates/$tarball.sha256 ]; then
ec0f88
			sha256sum /updates/$tarball > /updates/$tarball.sha256
ec0f88
		fi
ec0f88
ec0f88
		mb_remotesig=$(grep $tarball /updates/updates.sha256 | cut -d' ' -f1)
ec0f88
		mb_localsig=$(cat /updates/$tarball.sha256 | cut -d' ' -f1)
ec0f88
ec0f88
		printf '\tremote signature: %s\n' $mb_remotesig >&3
ec0f88
		printf '\tlocal  signature: %s\n' $mb_localsig >&3
ec0f88
ec0f88
		if [ $mb_localsig != $mb_remotesig ]; then
ec0f88
			printf '\tsignatures do not match, download needed.\n' >&3
ec0f88
ec0f88
			if [ $mb_obtain = no ]; then
ec0f88
				update_needed
ec0f88
			else
ec0f88
				mb_needed=yes
ec0f88
			fi
ec0f88
		else
ec0f88
			printf '\tsignatures match, local tarball is already up-to-date.\n' >&3
ec0f88
			mb_needed=no
ec0f88
		fi
ec0f88
	fi
ec0f88
ec0f88
	if [ $mb_needed = yes ]; then
ec0f88
		printf '\tattempting to download %s...\n' ${mb_vendor}/updates/$tarball >&3
ec0f88
ec0f88
		obtain_remote_file /updates/$tarball
ec0f88
		sha256sum /updates/$tarball > /updates/$tarball.sha256
ec0f88
ec0f88
		mb_remotesig=$(grep $tarball /updates/updates.sha256 | cut -d' ' -f1)
ec0f88
		mb_localsig=$(cat /updates/$tarball.sha256 | cut -d' ' -f1)
ec0f88
ec0f88
		printf '\tremote signature: %s\n' $mb_remotesig >&3
ec0f88
		printf '\tlocal  signature: %s\n' $mb_localsig >&3
ec0f88
ec0f88
		if [ $mb_localsig != $mb_remotesig ]; then
ec0f88
			printf 'signatures do not match, aborting.\n' >&3
ec0f88
			update_failure
ec0f88
		else
ec0f88
			printf '\t/local tarball is now up-to-date.\n' >&3
ec0f88
		fi
ec0f88
	fi
ec0f88
ec0f88
	printf '\n' >&3
ec0f88
done
ec0f88
493d95
# already up-to-date?
493d95
if [ "${mb_dlopt}" = '--check-state' ]; then
493d95
	if [ $mb_state = true ]; then
493d95
		update_success
493d95
	else
493d95
		update_needed
493d95
	fi
493d95
fi
493d95
ec0f88
# status
ec0f88
touch /updates/update.pending
ec0f88
ec0f88
# all done
ec0f88
update_success