#!/bin/sh
#
# Copyright (c) 2013 M:tier Ltd.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# Author: Antoine Jacoutot <antoine@mtier.org>

# TODO
# https://stable.mtier.org/vuxml/53.xml
# check for pkg.conf installpath and/or PKG_PATH
# extend usage() with doc from web

### user defined variables
OPENUP_URL='https://stable.mtier.org/openup'
PKG_CERT_URL='https://stable.mtier.org/mtier.cert'
PKG_CERT_REGEX='M:Tier Ltd. OpenBSD Stable Updates'
### end of user defined variables

# do not change this!!!
OPENUP_VERSION=0
OPENUP_MINREL=53

error() {
	echo -n "*** ERROR: $@"
}

usage() {
	echo "usage: ${0##*/} [-SUn]" >&2
	exit 1
}

check_unsup() {
	if [ "${tag}" == -!(stable) ]; then
		error "XXX -current is a no-no"
		exit 1
	fi

	if [ "$(echo ${version} | tr -d '.')" -lt "${OPENUP_MINREL}" ]; then
		error "XXX release ${version} is a no-no (non-fatal)"
	fi
}

get_cert() {
	local _CERT

	if [ -r /etc/ssl/pkgca.pem ]; then
		openssl x509 -noout -in /etc/ssl/pkgca.pem -issuer 2>/dev/null | \
			grep -q "${PKG_CERT_REGEX}" && return
	fi

	echo "===> Downloading certificate"
	_CERT=$(mktemp -p ${TMPDIR:=/tmp} pkg_cert.XXXXXXXXXX) || exit 1
	ftp -Vo ${_CERT} ${PKG_CERT_URL}
	if [ $? -ne 0 ]; then
		error "XXX could not download certificate; it's a no-no"
		rm -f ${_CERT}
		exit 1
	fi

	echo "===> Installing certificate"
	[[ -z ${DRYRUN} ]] && cat ${_CERT} >>/etc/ssl/pkgca.pem
	[ $? -eq 0 ] && echo "successfully added certificate to /etc/ssl/pkgca.pem"
	rm -f ${_CERT}
}

update_self() {
	local _F _N

	echo "===> Checking for openup(8) update"
	_F=$(mktemp -p ${TMPDIR:=/tmp} pkg_cert.XXXXXXXXXX) || exit 1
	ftp -Vo ${_F} ${OPENUP_URL}
	if [ $? -ne 0 ]; then
		error "XXX could not check for openup update; it's a no-no (non-fatal)"
		return 1
	fi

	_N=$(grep -Eo '^OPENUP_VERSION=.*' ${_F} | awk -F '=' '{ print $2 }')
	[[ -n "${_N}" ]] && \
		if [ "${OPENUP_VERSION}" -lt "${_N}" ]; then
			echo "===> Updating openup(8) from version ${OPENUP_VERSION} to version ${_N}"
			[[ -z "${DRYRUN}" ]] && cat ${_F} >${MEESA}
			[ $? -eq 0 ] && \
				rm -f ${_F}
				echo "successfully updated openup(8) to version ${_N}, restarting myself" && \
				${MEESA} -U $@
				exit $?
		fi
	rm -f ${_F}
}

update_binpatches() {
	local _BP=$(pkg_info -Q binpatch$(echo $version | tr -d '.')-$(arch -s) | sed 's/.[^-]*$//' | sort -u)

	if [ -n "$_BP" ]; then
		echo "===> Updating binpatch(es)"
		pkg_add ${pkg_opt} ${_BP}
	fi
}

update_pkg() {
	echo "===> Updating package(s)"
	pkg_add -u ${pkg_opt}
}

update_fw() {
	echo "===> Updating firmware(s)"
	fw_update ${fw_opt}
}

while getopts 'SUn' arg; do
	case ${arg} in
	S)	NOSIG=1; pkg_opt="${pkg_opt} -D nosig" ;;
	U)	NOSELFUPDATE=1 ;;
	n)	DRYRUN=1; pkg_opt="${pkg_opt} -n -D nosig"; fw_opt="-n" ;;
	*)	usage ;;
	esac
done
[ $# = $(($OPTIND-1)) ] || usage

if [ "$(id -u)" -ne 0 ]; then
	error "need root privileges to run this script"
	usage
fi

MEESA=$(readlink -f $0)

# magic taken from fw_update(1)
set -- $(sysctl -n kern.version | sed 's/^OpenBSD \([0-9]\.[0-9]\)\([^ ]*\).*/\1 \2/;q')
version=$1
tag=$2

[[ -z $NOSELFUPDATE ]] && update_self
check_unsup
[[ -z $NOSIG ]] && get_cert
update_binpatches
update_pkg
update_fw
