#!/bin/sh
#
# Find missing firmware files requested by the kernel, and install the
# binary packages with the files from the non-free section.
#
# This script was copied from auto-addfirmware from the debian-edu-config
# package.

dist=$(lsb_release -cs)
arch=$(dpkg --print-architecture)
mirror=http://http.debian.net/debian
aptsourcelist=/etc/apt/sources.list.d/isenkram-autoinstall-firmware.list

add_contrib_nonfree() {
    cat <<EOF > $aptsourcelist
deb $mirror $dist contrib non-free
deb-src $mirror $dist contrib non-free
EOF
}

# Find firmware files requested by loaded kernel drivers.
for fwfile in $(for module in $(awk '{print $1}' /proc/modules) ; do modinfo $module 2>/dev/null |awk '/^firmware:/ {print $2}'; done|sort -u); do
    if [ ! -e /lib/firmware/$fwfile ] ; then
	fwfiles="${fwfiles:+$fwfiles }$fwfile"
    fi
done

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

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

cleanup() {
    cd /
    rm -rf $tmpdir
}

# "" is main in Wheezy.
for section in "" "contrib" "non-free"; do
    if [ -z "$section" ] ; then
	url="$mirror/dists/$dist/Contents-$arch.gz"
    else
	url="$mirror/dists/$dist/$section/Contents-$arch.gz"
    fi
    echo "info: fetching $url"
    GET $url | gunzip | grep ^lib/firmware > Fw-Contents-$arch$section
done

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.
	case "$fwfile" in
	    b43/*)
		add_contrib_nonfree
		binpkgs="${binpkgs:+$binpkgs }firmware-b43-installer"
		;;
	esac
    else
	binpkginfos="$binpkginfos $binpkginfo"
    fi
done

binpkgs="${binpkgs:+$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 ! LC_ALL=C apt-cache show $binpkg 2>&1 | \
               grep -q 'E: No packages found' \
           && ( [ non-free = "$section" ] \
               || [ contrib = "$section" ] ) ; then 
	    add_contrib_nonfree
	fi
    done
done)"

if [ -e $aptsourcelist ] ; then
    # Fetch updated package lists
    echo "info: Updating APT sources after adding non-free APT source"
    apt-get -qq update
fi

if [ "$binpkgs" ] ; then
    # Install firmware packages
    echo "info: trying to install $binpkgs"
    apt-get -qq install -y $binpkgs
else
    echo "info: No new firmware package with requested firmware detected."
fi
cleanup
