#!/bin/bash
#
# Generate Supplements: lines for the kernel-firmware package, by looking at
# the firmware: and alias: fields of kernel modules.

USAGE="find <firmware directory> | $0 --find-supplements [kernel directory | kernel.rpm]
$0 --kill-duplicates <firmware directory> [kernel directory | kernel.rpm]"
usage()
{
	echo "Usage: $USAGE" >&2
	exit 1
}

get_kernel_dir()
{
	# default to the running or last installed kernel
	if test -z "$kernel"; then
		if test -d "/lib/modules/$(uname -r)/kernel"; then
			kernel="$_"
			return
		fi
		local pkg=$(rpm -q --qf '%{buildtime} %{n}-%{v}-%{r}\n' \
			kernel-default kernel-desktop kernel-pae | sort -rn |
			head -n1 | cut -d' ' -f 2)
		if test -n "$pkg"; then
			kernel=$(rpm -ql "$pkg" | \
				grep -m1 '^/lib/modules/[2-9][^/]*/kernel$')
		fi
		if test -d "$kernel"; then
			return
		fi
		echo "No kernel found" >&2
		usage
	fi
	# /lib/modules/$version ?
	if test -d "$kernel/kernel"; then
		kernel="$_"
		return
	fi
	# just $version ?
	if test -d "/lib/modules/$kernel/kernel"; then
		kernel="$_"
		return
	fi
	# a kernel rpm?
	case "$kernel" in
	*.rpm)
		mkdir "$tmp/kernel"
		rpm2cpio "$kernel" | (cd "$tmp/kernel"; cpio -id --quiet)
		kernel=($tmp/kernel/lib/modules/*/kernel)
		kernel=${kernel[0]}
		return
	esac
	usage
}

trap 'rm -rf "$tmp"' EXIT
tmp=$(mktemp -d)

case "$1" in
--find-supplements)
	kernel=$2
	cat >"$tmp/filelist"
	if test ! -s "$tmp/filelist"; then
		usage
	fi
	get_kernel_dir
	echo "Using $kernel" >&2
	find "$kernel" -name '*.ko' -type f | while read ko; do
		if grep -qFf <(/sbin/modinfo -F firmware "$ko") \
							"$tmp/filelist"; then
			echo "$ko"
		fi
	done | sort | \
	RPMBUILD_SPECFILE=/dev/null /usr/lib/rpm/find-supplements.ksyms | \
	sed 's/^modalias(kernel-[^:]*:/modalias(/' # strip the kernel-$flavor: prefix
	;;
--kill-duplicates)
	firmware=$2
	kernel=$3
	get_kernel_dir
	kernel=${kernel/\/lib\/modules\//\/lib\/firmware\/}
	kernel=${kernel%/kernel}
	echo "Using $kernel" >&2
	find "$firmware" -type f -printf '%P\n' | while read f; do
		if cmp -s "$kernel/$f" "$firmware/$f"; then
			rm -v "$_"
		fi
	done
	;;
*)
	usage
esac




