Annotation of openbsd/fw_update/fw_install.sh, Revision 1.7
1.1 afresh1 1: #!/bin/ksh
2: set -e
3:
4: scan_dmesg() {
5: # no bsort for now
6: sed -n "$1" /var/run/dmesg.boot
7: }
8:
9: installed_firmware() {
10: for fw in ${PKGDIR}/$1-firmware*; do
11: [ -e "$fw" ] || continue
12: echo ${fw##*/}
13: done
14: }
15:
1.6 afresh1 16: # do_as, unpriv, and unpriv2 are from install.sub
17:
18: # Run a command ($2+) as unprivileged user ($1).
19: # Take extra care that after "cmd" no "user" processes exist.
20: #
21: # Optionally:
22: # - create "file" and chown it to "user"
23: # - after "cmd", chown "file" back to root
24: #
25: # Usage: do_as user [-f file] cmd
26: do_as() {
27: (( $# >= 2 )) || return
28:
29: local _file _rc _user=$1
30: shift
31:
32: if [[ $1 == -f ]]; then
33: _file=$2
34: shift 2
35: fi
36:
37: if [[ -n $_file ]]; then
38: >$_file
39: chown "$_user" "$_file"
40: fi
41:
42: doas -u "$_user" "$@"
43: _rc=$?
44:
45: while doas -u "$_user" kill -9 -1 2>/dev/null; do
46: echo "Processes still running for user $_user after: $@"
47: sleep 1
48: done
49:
50: [[ -n $_file ]] && chown root "$_file"
51:
52: return $_rc
53: }
54:
55: unpriv() {
56: do_as _sndio "$@"
57: }
58:
59: unpriv2() {
60: do_as _file "$@"
61: }
62:
1.7 ! afresh1 63: VNAME=$(sysctl -n kern.osrelease)
! 64: VERSION="${VNAME%.*}${VNAME#*.}"
! 65: FWDIR="$VNAME"
1.1 afresh1 66:
1.7 ! afresh1 67: HTTP_FWDIR=$FWDIR
! 68: set -- $(scan_dmesg "/^OpenBSD $VNAME\([^ ]*\).*$/s//\1/p")
! 69: [[ $1 == -!(stable) ]] && HTTP_FWDIR=snapshots
! 70:
! 71: FWURL=http://firmware.openbsd.org/firmware/${HTTP_FWDIR}
! 72: FWPUB_KEY=${DESTDIR}/etc/signify/openbsd-${VERSION}-fw.pub
1.1 afresh1 73: PKGDIR=${DESTDIR}/var/db/pkg
74: PATTERNS="file:${0%/*}/firmware_patterns"
75:
76: drivers=$(
77: last=''
78: ftp -D "Detecting" -Vmo- $PATTERNS |
79: while read d m; do
1.5 afresh1 80: grep=grep
1.1 afresh1 81: [ "$last" = "$d" ] && continue
82: [ "$m" ] || m="^$d[0-9][0-9]* at "
1.5 afresh1 83: [ "$m" = "${m#^}" ] && grep=fgrep
1.3 afresh1 84: $grep -q "$m" /var/run/dmesg.boot || continue
1.1 afresh1 85: echo $d
86: last=$d
87: done
88: )
89:
90: if [ -z "$drivers" ]; then
91: echo "No devices found which need firmware files to be downloaded." >&2
92: exit 0
93: fi
94:
95: tmpdir=${DESTDIR}/tmp/fw_update
96: [ -e "$tmpdir" ] && rm -rf "$tmpdir"
97: mkdir -p "$tmpdir"
98: cd "$tmpdir"
99:
100: # TODO: Drop privs during fetch and verify
101: ftp -D Get -Vm "$FWURL/SHA256.sig"
102:
103: # Probably should bundle the firmware sigfile on the installer,
104: # although we can just get it from the recently installed system.
105: if [ "$DESTDIR" ]; then
106: sigfile=$( sed -n '/^untrusted comment: verify with \(.*\)$/ { s//\1/p; q; }' SHA256.sig )
107: if [ ! -e "/etc/signify/$sigfile" ] \
108: && [ -e "${DESTDIR}/etc/signify/$sigfile" ]; then
109: cp -a "${DESTDIR}/etc/signify/$sigfile" "/etc/signify/$sigfile"
110: fi
111: fi
112:
113: signify -Ve -x SHA256.sig -m - < SHA256.sig > SHA256
114:
115: for d in $drivers; do
116: firmware=$( sed -n "s/.*(\($d-firmware-.*\.tgz\)).*/\1/p" SHA256 )
117: installed=$( installed_firmware $d )
118:
119: for i in $installed; do
120: if [ "$firmware" = "$i.tgz" ]; then
121: echo "Firmware for $d already installed ($installed)"
122: continue 2
123: fi
124: done
125:
126: mkdir $d
127:
128: # TODO: Drop privs during fetch and verify
129: ftp -D "Get/Verify" -Vmo- "$FWURL/$firmware" | sha256 -bph "$d/h" > "$firmware"
130: fgrep -qx "SHA256 ($firmware) = $(<$d/h)" SHA256
131:
132: # TODO: Check hash for files before deleting
133: if [ "$installed" ] && [ -e "${PKGDIR}/$installed/+CONTENTS" ]; then
134: echo "Uninstalling $installed"
135: cwd=${PKGDIR}/$installed
136:
137: remove="${cwd}/+CONTENTS ${cwd}"
138:
139: while read c g; do
140: case $c in
141: @cwd) cwd=$g
142: ;;
143: @*) continue
144: ;;
145: *) remove="$cwd/$c $remove"
146: ;;
147: esac
148: done < "${PKGDIR}/$installed/+CONTENTS"
149:
150: for r in $remove ; do
151: if [ -d "$r" ]; then
152: # Try hard not to actually remove recursively
153: # without rmdir on the install media.
154: [ "$r/*" = $( echo "$r"/* ) ] && rm -rf "$r"
155: else
156: rm -f "$r"
157: fi
158: done
159: fi
160:
161: # TODO: Add some details about the install to +CONTENTS like pkg_add
162: # TODO: Or, maybe we save the firmware someplace and make pkg_add reinstall
163: echo "Installing $firmware"
164: tar -zxphf "$firmware" -C /etc "firmware/*"
165: mkdir -p ${PKGDIR}/${firmware%.tgz}/
166: tar -zxphf "$firmware" -C "${PKGDIR}/${firmware%.tgz}" "+*"
1.4 afresh1 167: ed -s "${PKGDIR}/${firmware%.tgz}/+CONTENTS" <<EOL
1.1 afresh1 168: /^@comment pkgpath/ -1a
169: @option manual-installation
170: @option firmware
171: @comment install-script
172: .
173: w
174: EOL
175: done
176:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>