File: [local] / openbsd / fw_update / fw_install.sh (download)
Revision 1.7, Thu Oct 14 02:00:02 2021 UTC (2 years, 8 months ago) by afresh1
Branch: MAIN
Changes since 1.6: +9 -7 lines
Set variables more like install.sub
That should make converting this to a function that runs from install.sub
easier
|
#!/bin/ksh
set -e
scan_dmesg() {
# no bsort for now
sed -n "$1" /var/run/dmesg.boot
}
installed_firmware() {
for fw in ${PKGDIR}/$1-firmware*; do
[ -e "$fw" ] || continue
echo ${fw##*/}
done
}
# do_as, unpriv, and unpriv2 are from install.sub
# Run a command ($2+) as unprivileged user ($1).
# Take extra care that after "cmd" no "user" processes exist.
#
# Optionally:
# - create "file" and chown it to "user"
# - after "cmd", chown "file" back to root
#
# Usage: do_as user [-f file] cmd
do_as() {
(( $# >= 2 )) || return
local _file _rc _user=$1
shift
if [[ $1 == -f ]]; then
_file=$2
shift 2
fi
if [[ -n $_file ]]; then
>$_file
chown "$_user" "$_file"
fi
doas -u "$_user" "$@"
_rc=$?
while doas -u "$_user" kill -9 -1 2>/dev/null; do
echo "Processes still running for user $_user after: $@"
sleep 1
done
[[ -n $_file ]] && chown root "$_file"
return $_rc
}
unpriv() {
do_as _sndio "$@"
}
unpriv2() {
do_as _file "$@"
}
VNAME=$(sysctl -n kern.osrelease)
VERSION="${VNAME%.*}${VNAME#*.}"
FWDIR="$VNAME"
HTTP_FWDIR=$FWDIR
set -- $(scan_dmesg "/^OpenBSD $VNAME\([^ ]*\).*$/s//\1/p")
[[ $1 == -!(stable) ]] && HTTP_FWDIR=snapshots
FWURL=http://firmware.openbsd.org/firmware/${HTTP_FWDIR}
FWPUB_KEY=${DESTDIR}/etc/signify/openbsd-${VERSION}-fw.pub
PKGDIR=${DESTDIR}/var/db/pkg
PATTERNS="file:${0%/*}/firmware_patterns"
drivers=$(
last=''
ftp -D "Detecting" -Vmo- $PATTERNS |
while read d m; do
grep=grep
[ "$last" = "$d" ] && continue
[ "$m" ] || m="^$d[0-9][0-9]* at "
[ "$m" = "${m#^}" ] && grep=fgrep
$grep -q "$m" /var/run/dmesg.boot || continue
echo $d
last=$d
done
)
if [ -z "$drivers" ]; then
echo "No devices found which need firmware files to be downloaded." >&2
exit 0
fi
tmpdir=${DESTDIR}/tmp/fw_update
[ -e "$tmpdir" ] && rm -rf "$tmpdir"
mkdir -p "$tmpdir"
cd "$tmpdir"
# TODO: Drop privs during fetch and verify
ftp -D Get -Vm "$FWURL/SHA256.sig"
# Probably should bundle the firmware sigfile on the installer,
# although we can just get it from the recently installed system.
if [ "$DESTDIR" ]; then
sigfile=$( sed -n '/^untrusted comment: verify with \(.*\)$/ { s//\1/p; q; }' SHA256.sig )
if [ ! -e "/etc/signify/$sigfile" ] \
&& [ -e "${DESTDIR}/etc/signify/$sigfile" ]; then
cp -a "${DESTDIR}/etc/signify/$sigfile" "/etc/signify/$sigfile"
fi
fi
signify -Ve -x SHA256.sig -m - < SHA256.sig > SHA256
for d in $drivers; do
firmware=$( sed -n "s/.*(\($d-firmware-.*\.tgz\)).*/\1/p" SHA256 )
installed=$( installed_firmware $d )
for i in $installed; do
if [ "$firmware" = "$i.tgz" ]; then
echo "Firmware for $d already installed ($installed)"
continue 2
fi
done
mkdir $d
# TODO: Drop privs during fetch and verify
ftp -D "Get/Verify" -Vmo- "$FWURL/$firmware" | sha256 -bph "$d/h" > "$firmware"
fgrep -qx "SHA256 ($firmware) = $(<$d/h)" SHA256
# TODO: Check hash for files before deleting
if [ "$installed" ] && [ -e "${PKGDIR}/$installed/+CONTENTS" ]; then
echo "Uninstalling $installed"
cwd=${PKGDIR}/$installed
remove="${cwd}/+CONTENTS ${cwd}"
while read c g; do
case $c in
@cwd) cwd=$g
;;
@*) continue
;;
*) remove="$cwd/$c $remove"
;;
esac
done < "${PKGDIR}/$installed/+CONTENTS"
for r in $remove ; do
if [ -d "$r" ]; then
# Try hard not to actually remove recursively
# without rmdir on the install media.
[ "$r/*" = $( echo "$r"/* ) ] && rm -rf "$r"
else
rm -f "$r"
fi
done
fi
# TODO: Add some details about the install to +CONTENTS like pkg_add
# TODO: Or, maybe we save the firmware someplace and make pkg_add reinstall
echo "Installing $firmware"
tar -zxphf "$firmware" -C /etc "firmware/*"
mkdir -p ${PKGDIR}/${firmware%.tgz}/
tar -zxphf "$firmware" -C "${PKGDIR}/${firmware%.tgz}" "+*"
ed -s "${PKGDIR}/${firmware%.tgz}/+CONTENTS" <<EOL
/^@comment pkgpath/ -1a
@option manual-installation
@option firmware
@comment install-script
.
w
EOL
done