#!/bin/sh
#
# Find missing firmware files requested by the kernel, and install the
# binary packages with the files from the non-free section.

tmpdir=$(mktemp -d)
cd $tmpdir || exit 1

dist=$(lsb_release -cs)
arch=$(dpkg --print-architecture)
mirror=http://cdn.debian.net/debian

# Find firmware files requested by kernel drivers
# Perhaps it is better to use /dev/.udev/firmware-missing/?
fwfiles=$(dmesg |grep "firmware: requesting"|rev|awk '{print $1}'|rev|sort -u)

if [ -z "$fwfiles" ] ; then
    echo "info: did not find any firmware files requested by the kernel in dmesg.  exiting"
    exit
fi
echo "info: kernel drivers requested extra firmware:" $fwfiles


url="$mirror/dists/$dist/Contents-$arch.gz"
echo "info: fetching $url"
GET $url | gunzip | grep ^lib/firmware > Fw-Contents-$arch 

echo "info: locating packages with the requested firmware files"
binpkginfos=""
binpkgs=""
for fwfile in $fwfiles ; do
    fwfilere=$(echo $fwfile | sed -e 's%/%\\/%g' -e 's/\./\\./g')
    binpkginfo="$(awk "/^lib\/firmware\/$fwfilere/ {print \$2}" Fw-Contents-$arch)"
    if [ -z "$binpkginfo" ] ; then
	# Special case for b43 where the firmware is undistributable
	# by Debian.
	# FIXME verify that this is the correct of the three firmware
	# packages for b43.
	if echo $fwfile |grep -q b43-open ; then
	    binpkgs="firmware-b43-installer $binpkgs"
	fi
    else
	binpkginfos="$binpkginfos $binpkginfo"
    fi
done

binpkgs="$(
for binpkginfo in $binpkginfos ; do
    echo $binpkginfo |  while IFS=/ read section srcpkg binpkg ; do
        echo $binpkg
# Enable the non-free section if it is needed
	if [ non-free = "$section" ] ; then 
	    cat <<EOF > /etc/apt/sources.list.d/auto-addfirmware.list
deb $mirror $dist non-free
deb-src $mirror $dist non-free
EOF
	fi
    done
done) $binpkgs"

# Fetch updated package lists
echo "info: Updating APT sources after adding non-free APT source"
apt-get update > /dev/null

# Install firmware packages
echo "info: trying to install $binpkgs"
apt-get install -y $binpkgs

cd /
rm -rf $tmpdir
