Annotation of openbsd/fw_update/fw_install.sh, Revision 1.6
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.1 afresh1 63: set -A _KERNV -- $( scan_dmesg '/^OpenBSD \([1-9][0-9]*\.[0-9]\)\([^ ]*\) .*/ { s//\1 \2/p; q; }' )
64: VNAME=${_KERNV[0]}
65: OSDIR=$VNAME
66: if ((${#_KERNV[*]} > 1)) && [ "$_KERNV[1]" = "-current" -o "$_KERNV[1]" = "-beta" ]; then
67: OSDIR=snapshots
68: fi
69:
70: FWURL=http://firmware.openbsd.org/firmware/${OSDIR}
71: PKGDIR=${DESTDIR}/var/db/pkg
72: PATTERNS="file:${0%/*}/firmware_patterns"
73:
74: drivers=$(
75: last=''
76: ftp -D "Detecting" -Vmo- $PATTERNS |
77: while read d m; do
1.5 afresh1 78: grep=grep
1.1 afresh1 79: [ "$last" = "$d" ] && continue
80: [ "$m" ] || m="^$d[0-9][0-9]* at "
1.5 afresh1 81: [ "$m" = "${m#^}" ] && grep=fgrep
1.3 afresh1 82: $grep -q "$m" /var/run/dmesg.boot || continue
1.1 afresh1 83: echo $d
84: last=$d
85: done
86: )
87:
88: if [ -z "$drivers" ]; then
89: echo "No devices found which need firmware files to be downloaded." >&2
90: exit 0
91: fi
92:
93: tmpdir=${DESTDIR}/tmp/fw_update
94: [ -e "$tmpdir" ] && rm -rf "$tmpdir"
95: mkdir -p "$tmpdir"
96: cd "$tmpdir"
97:
98: # TODO: Drop privs during fetch and verify
99: ftp -D Get -Vm "$FWURL/SHA256.sig"
100:
101: # Probably should bundle the firmware sigfile on the installer,
102: # although we can just get it from the recently installed system.
103: if [ "$DESTDIR" ]; then
104: sigfile=$( sed -n '/^untrusted comment: verify with \(.*\)$/ { s//\1/p; q; }' SHA256.sig )
105: if [ ! -e "/etc/signify/$sigfile" ] \
106: && [ -e "${DESTDIR}/etc/signify/$sigfile" ]; then
107: cp -a "${DESTDIR}/etc/signify/$sigfile" "/etc/signify/$sigfile"
108: fi
109: fi
110:
111: signify -Ve -x SHA256.sig -m - < SHA256.sig > SHA256
112:
113: for d in $drivers; do
114: firmware=$( sed -n "s/.*(\($d-firmware-.*\.tgz\)).*/\1/p" SHA256 )
115: installed=$( installed_firmware $d )
116:
117: for i in $installed; do
118: if [ "$firmware" = "$i.tgz" ]; then
119: echo "Firmware for $d already installed ($installed)"
120: continue 2
121: fi
122: done
123:
124: mkdir $d
125:
126: # TODO: Drop privs during fetch and verify
127: ftp -D "Get/Verify" -Vmo- "$FWURL/$firmware" | sha256 -bph "$d/h" > "$firmware"
128: fgrep -qx "SHA256 ($firmware) = $(<$d/h)" SHA256
129:
130: # TODO: Check hash for files before deleting
131: if [ "$installed" ] && [ -e "${PKGDIR}/$installed/+CONTENTS" ]; then
132: echo "Uninstalling $installed"
133: cwd=${PKGDIR}/$installed
134:
135: remove="${cwd}/+CONTENTS ${cwd}"
136:
137: while read c g; do
138: case $c in
139: @cwd) cwd=$g
140: ;;
141: @*) continue
142: ;;
143: *) remove="$cwd/$c $remove"
144: ;;
145: esac
146: done < "${PKGDIR}/$installed/+CONTENTS"
147:
148: for r in $remove ; do
149: if [ -d "$r" ]; then
150: # Try hard not to actually remove recursively
151: # without rmdir on the install media.
152: [ "$r/*" = $( echo "$r"/* ) ] && rm -rf "$r"
153: else
154: rm -f "$r"
155: fi
156: done
157: fi
158:
159: # TODO: Add some details about the install to +CONTENTS like pkg_add
160: # TODO: Or, maybe we save the firmware someplace and make pkg_add reinstall
161: echo "Installing $firmware"
162: tar -zxphf "$firmware" -C /etc "firmware/*"
163: mkdir -p ${PKGDIR}/${firmware%.tgz}/
164: tar -zxphf "$firmware" -C "${PKGDIR}/${firmware%.tgz}" "+*"
1.4 afresh1 165: ed -s "${PKGDIR}/${firmware%.tgz}/+CONTENTS" <<EOL
1.1 afresh1 166: /^@comment pkgpath/ -1a
167: @option manual-installation
168: @option firmware
169: @comment install-script
170: .
171: w
172: EOL
173: done
174:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>