#!/bin/sh signature_key=3683C4B70CFA859F0173F2CCE0DD13EBFC7D5E3E # Copyright © 2024, 2025 Mattias Andrée (m@maandree.se) # # Copying and distribution of this script, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This script is offered as-is, # without any warranty. set -e fetchinfo () { printf '%s\n' "${relpage}" | \ sed 's/<[^>]*>//g' | \ sed 's/[[:space:]]\{1,\}/ /g' | \ sed 's/^ //' | \ sed 's/ $//' | \ grep "^$1:" || : } readinfo () { _line="$(fetchinfo "$@" | cut -d : -f 2- | sed 's/^ //')" test "$(printf '%s\n' "${_line}" | wc -l)" = 1 || return 1 printf '%s\n' "${_line}" } readmultiinfo () { _line="$(fetchinfo "$@" | cut -d : -f 2- | sed 's/^ //')" printf '%s\n' "${_line}" } checkhash_ () { _file="$1" _use="$2" _algorithm="$3" _expect="$(readmultiinfo "${_algorithm} checksum")" test -n "${_expect}" && which "${_use}" >/dev/null || return 1 _actual="$("${_use}" -- "${_file}" | cut -d ' ' -f 1)" test -n "${_actual}" || return 1 for _known in ${_expect}; do if test "${_actual}" = "${_known}"; then echo ok return 0 fi done printf '%s checksum for %s was not recognised\n' "${_algorithm}" "${_file}" >&2 echo bad } checkhash () { set +e _file="$1" printf '%s %s\n' \ sha224sum SHA224 \ sha256sum SHA256 \ sha384sum SHA384 \ sha512sum SHA512 \ sha512-224sum SHA512/224 \ sha512-256sum SHA512/256 \ sha3-224sum SHA3-224 \ sha3-256sum SHA3-256 \ sha3-384sum SHA3-384 \ sha3-512sum SHA3-512 \ b2sum BLAKE2b \ | ( _checked=0 _result=ok while read tool name; do _result="$(checkhash_ "${_file}" "${tool}" "${name}")" if test "${_result}" = ok; then _checked=1 elif test "${_result}" = bad; then _checked=1 _result=bad return 1 else : skipped fi done if test "${_checked}" = 0; then printf '%s\n' 'No supported checksum found' >&2 return 1 fi echo "${_result}" ) ret=$? set -e return $ret } signature_key="$(printf '%s\n' "${signature_key}" | tr -d ' ')" set -v package="$1" version="$2" if test -z "$version"; then version=latest fi sigkey="$(curl -L -- "https://maandree.se/.signkey")" if test ! "${sigkey}" = "${signature_key}"; then printf '\n\033[1m%s\033[m,' 'Expected signature keyfile seems to be out of date' >&2 printf ' %s' 'have a look at https://maandree.se/ to find the newest and verify that it' >&2 printf ' %s' 'has been signed by the previous key, continue until you find and old key' >&2 printf ' %s' 'in the signature chain that is signed by '"${signature_key}"' (or older' >&2 printf ' %s' 'that you trust). Once verified, update `signature_key` at the top of' >&2 printf ' %s' 'this file to be the newest key, which should be '"${sigkey}"', and' >&2 printf ' %s' 'import it into your key collection of PGP keys.' >&2 printf '\n' >&2 exit 1 fi relurl="https://maandree.se/rel/${package}/${version}.html" relpage="$(curl -L -- "${relurl}")" relpagesig="$(curl -L -- "${relurl}".sig)" sigtest="$(printf '%s\n' "${relpage}" | (printf '%s\n' "${relpagesig}" | gpg --status-fd=8 --verify - /dev/fd/9) 9<&0 8>&1 1>&2)" if ! printf '%s\n' "${sigtest}" | grep -q '^\[GNUPG:\] VALIDSIG'" ${sigkey} "; then printf '\n\033[1m%s\033[m\n' 'The release metadata page seems to be signed with an unexpected key.' >&2 exit 1 fi relversion="$(readinfo 'This version')" test -n "${relversion}" test "${version}" = latest || test "${relversion}" = "${version}" version="${relversion}" tarurls="$(readmultiinfo 'Tarball')" tarurls="$(echo "${tarurls}" | grep '\.tar\.gz$' || :)" test -n "${tarurls}" unpack='gzip -d | tar -x' tarext='tar.gz' tardir="${package}-${version}" tarfile="${package}-${version}.${tarext}" if test -f "${tarfile}"; then status="$(checkhash "${tarfile}")" test -n "${status}" test "${status}" = ok else downloaded=0 for tarurl in ${tarurls}; do if ! curl -L -- "${tarurl}" > "${tarfile}"; then rm -f -- "${tarfile}" continue fi downloaded=1 status="$(checkhash "${tarfile}")" test -n "${status}" test "${status}" = ok break done (( downloaded )) fi (fetchinfo 'License' ; fetchinfo '.* dependencies' ; fetchinfo '.* instruction' ; fetchinfo 'News') > new-relmeta if test -f relmeta; then diff -u relmeta new-relmeta fi mv new-relmeta relmeta actualtardir="$(gzip -d < "${tarfile}" | tar -t | head -n 1 | cut -d / -f 1)" quote () { printf '%s\n' | sed "s/'/'"'\\'"''/g" | sed '1s/^/'\'/ | sed '$s/$/'\'/ } if test ! "${actualtardir}" = "${tardir}"; then unpack="${unpack} && mv -- $(quote "${actualtardir}") $(quote "${tardir}")" fi unpack="(${unpack})" reldata="$(printf '%s = %s\n' \ VERSION "${version}" \ DVERSION "$(printf '%s\n' "${version}" | tr - .)" \ TARBALL "${tarfile}" \ DIRECTORY "${tardir}" \ UNPACK "${unpack}" \ )" if (! test -f release-data.mk) || printf '%s\n' "${reldata}" || diff - release-data.mk >/dev/null; then printf '%s\n' "${reldata}" > release-data.mk fi