#!/bin/bash programName="${0##*/}" defaultArchiveLocation="https://brltty.app/archive/Canute" defaultArchiveName="canute-controller.tar.gz" showUsageSummary() { cat <&2 "${programName}: ${message}" } logTask() { local message="${1}" "${quietMode}" || programMessage "${message}" } syntaxError() { local message="${1}" programMessage "${message}" exit 2 } semanticError() { local message="${1}" programMessage "${message}" exit 3 } executeHostCommand() { if "${testMode}" then programMessage "executing host command: ${*}" else "${@}" fi } downloadFile() { local file="${1}" executeHostCommand curl --output "${file}" --silent --show-error --get --location -- "${archiveLocation}/${file}" } needTemporaryDirectory() { [ -n "${TMPDIR}" -a -d "${TMPDIR}" -a -r "${TMPDIR}" -a -w "${TMPDIR}" -a -x "${TMPDIR}" ] || export TMPDIR="/tmp" temporaryDirectory="$(mktemp -d "${TMPDIR}/${programName}.$(date +"%Y%m%d-%H%M%S").XXXXXX")" } removeTemporaryDirectory() { set +e cd / rm -f -r -- "${temporaryDirectory}" } showUsage=false quietMode=false testMode=false archiveLocation="${defaultArchiveLocation}" archiveName="${defaultArchiveName}" while getopts ":hqta:l:" option do case "${option}" in h) showUsage=true;; q) quietMode=true;; t) testMode=true;; a) archiveName="${OPTARG}";; l) archiveLocation="${OPTARG}";; :) syntaxError "missing operand: -${OPTARG}";; \?) syntaxError "unrecognized option: -${OPTARG}";; *) syntaxError "unimplemented option: -${option}";; esac done shift $((OPTIND - 1)) [ "${#}" -eq 0 ] || syntaxError "too many parameters" "${showUsage}" && { showUsageSummary exit 0 } [ -n "${archiveName}" ] || syntaxError "archive name not specified" [ -n "${archiveLocation}" ] || archiveLocation="." tarDecompressionOption="" case "${archiveName}" in *.tgz) tarDecompressionOption="--gzip";; *.tar) tarDecompressionOption="";; *.tar.bz2) tarDecompressionOption="--bzip2";; *.tar.gz) tarDecompressionOption="--gzip";; *.tar.xz) tarDecompressionOption="--xz";; *) semanticError "unrecognized archive file extension: ${archiveName}";; esac [ -f "/usr/bin/raspi-config" ] || semanticError "not Raspbian" "${testMode}" || [ "$(id -u)" -eq 0 ] || semanticError "not executing as root" "${testMode}" && quietMode=false set -e archiveScheme="${archiveLocation%%:*}" [ "${archiveScheme}" = "${archiveLocation}" ] || { # the location contains a colon so it might have a scheme [ "${archiveScheme}" != "${archiveScheme#*/}" ] || { # the scheme doesn't contain a slash [ -n "${archiveScheme}" ] || syntaxError "empty archive location sheme: ${archiveLocation}" # yes it actually is a scheme needTemporaryDirectory trap removeTemporaryDirectory exit executeHostCommand cd "${temporaryDirectory}" logTask "downloading archive" downloadFile "${archiveName}" archiveLocation="." } } archivePath="${archiveLocation}/${archiveName}" "${testMode}" || { [ -e "${archiveLocation}" ] || semanticError "directory not found: ${archiveLocation}" [ -d "${archiveLocation}" ] || semanticError "not a directory: ${archiveLocation}" [ -x "${archiveLocation}" ] || semanticError "directory not searchable: ${archiveLocation}" [ -e "${archivePath}" ] || semanticError "archive not found: ${archivePath}" [ -f "${archivePath}" ] || semanticError "not a file: ${archivePath}" [ -r "${archivePath}" ] || semanticError "archive not readable: ${archivePath}" } logTask "unpacking archive" executeHostCommand tar --extract ${tarDecompressionOption} --absolute-names --file "${archivePath}" --directory "/" logTask "setting up system" setupCommand=("/brltty/current/libexec/canute-setup" -A) if "${testMode}" then setupCommand+=(-t -v -v) testMode=false elif "${quietMode}" then setupCommand+=(-q) fi executeHostCommand "${setupCommand[@]}" exit 0