#! /bin/sh

# vim:shiftwidth=4 softtabstop=4

export LANG=C

# Repackage the files from an installed kernel driver rpm for reuse
# with another kernel. The result is a new rpm package. Here is an example:
#
# $ rpm -qi novell-foo-0.0-2.6.11.4_20a-0
#Name        : novell-foo-0.0               Relocations: (not relocatable)
#Version     : 2.6.11.4_20a                      Vendor: (none)
#Release     : 0                             Build Date: Thu 21 Jul 2005 05:37:57 PM CEST
#Install date: Thu 28 Jul 2005 06:02:59 PM CEST      Build Host: blunzn.suse.de
#Group       : System/Kernel                 Source RPM: novell-foo-0.0-2.6.11.4_20a-0.src.rpm
#Size        : 11941                            License: GPL
#Signature   : (none)
#Summary     : An example module package
#Description :
#Driver test
#Distribution: (none)
# $ rpm -ql novell-foo-0.0-2.6.11.4_20a-0
# /lib/modules/2.6.11.4-20a-default
# /lib/modules/2.6.11.4-20a-default/updates2
# /lib/modules/2.6.11.4-20a-default/updates2/moo.ko
# /lib/modules/2.6.11.4-20a-smp
# /lib/modules/2.6.11.4-20a-smp/updates2
# /lib/modules/2.6.11.4-20a-smp/updates2/moo.ko
# /var/lib/YaST2/dt
# /var/lib/YaST2/dt/package
# /var/lib/YaST2/dt/package/novell-foo-0.0
#
# $ ./repackage-for-reuse novell-foo-0.0-2.6.11.4_20a-0 \
#       2.6.11.4-20a 2.6.11.4-21.7 > bar.rpm
# $ rpm -qp bar.rpm
# novell-foo-0.0-2.6.11.4_20a_for_2.6.11.4_21.7-0
# $ rpm -qip bar.rpm
#Name        : novell-foo-0.0               Relocations: (not relocatable)
#Version     : 2.6.11.4_20a_for_2.6.11.4_21.7       Vendor: (none)
#Release     : 0                             Build Date: Thu 28 Jul 2005 06:04:46 PM CEST
#Install date: (not installed)               Build Host: blunzn.suse.de
#Group       : System/Kernel                 Source RPM: novell-foo-0.0-2.6.11.4_20a_for_2.6.11.4_21.7-0.src.rpm
#Size        : 11941                            License: GPL
#Signature   : (none)
#Summary     : An example module package (repackaged)
#Description :
#Driver test
#Distribution: (none)
# $ rpm -qlp bar.rpm
# /lib/modules/2.6.11.4_21.7-default
# /lib/modules/2.6.11.4_21.7-default/updates2
# /lib/modules/2.6.11.4_21.7-default/updates2/moo.ko
# /lib/modules/2.6.11.4_21.7-smp
# /lib/modules/2.6.11.4_21.7-smp/updates2
# /lib/modules/2.6.11.4_21.7-smp/updates2/moo.ko
# /var/lib/YaST2/dt
# /var/lib/YaST2/dt/package
# /var/lib/YaST2/dt/package/novell-foo-0.0
#
# The new package also invokes depmod in its %post and %postun scripts.

usage() {
    echo "SYNOPSIS: ${0##*/} {old driver package name} {old kernelrelease} {new kernelrelease}" >&2
    echo -e "\tExample: ${0##*/} novell-foo-0.0-2.6.11.4_20a-0 \\" >&2
    echo -e "\t\t\t2.6.11.4-20a 2.6.11.4-21.7" >&2
    exit $1
}

options=`getopt -o h --long help,verbose,flavor: -- "$@"`

if [ $? -ne 0 ]
then
    usage 1
fi

eval set -- "$options"
while :; do
    case "$1" in
    --verbose)
	opt_verbose=1
	;;
    --flavor)
	opt_flavor=$2
	shift
	;;
    --help)
	usage 0
	;;
    --)
	shift
	break
	;;
    *)
	usage 1
	;;
    esac
    shift
done

if [ $# -ne 3 ]; then
    usage 1
fi

old_nvr=$1
old_version=$2
new_version=$3

tmpdir=$(mktemp -d /var/tmp/${0##*/}.XXXXXX)
trap "rm -rf $tmpdir" EXIT

tags="name release license group summary description distribution vendor"
macros="changelog changelog_date old_version new_version old_nvr flavor"

query=
for tag in $tags; do
    query="$query$tag=%{$tag:shescape}\n"
done
eval "$(rpm -q --qf "$query" "$old_nvr")"

summary=${summary% (repackaged)}
changelog="$(rpm -q --changelog "$old_nvr" \
	     | sed -e "s:':'\"'\"':g")"
changelog_date="$(date '+%a %b %d %Y')"
if [ -n "$opt_flavor" ]; then
    flavor=$opt_flavor
else
    flavor="%{nil}"
fi

subst="$(
    for tag in $tags $macros; do
	if [ "${!tag}" = "(none)" ]; then
	    echo "-e '/@$tag@/d'"
	else
	    x="${!tag}"
	    x="${x//'/'\"'\"'}"
	    x="${x//\//\\/}"
	    x="${x//$'\n'/\\n}"
	    echo "-e 's/@$tag@/$x/g'"
	fi
    done)"

awk '
specfile	{ print }
/^SPECFILE:/	{ specfile=1 }
' $0 \
| eval sed $subst \
> $tmpdir/reuse.spec

if [ -n "$opt_verbose" ]; then
    cat $tmpdir/reuse.spec >&2
fi

if [ -e /usr/bin/rpmbuild ]; then
    rpm=/usr/bin/rpmbuild
else
    rpm=/bin/rpm
fi

(
    [ -n "$opt_verbose" ] || exec 2> /dev/null
    exec 1>&2

    pwd=$PWD
    cd $tmpdir
    mkdir build
    cmd= $rpm --eval "%define _sourcedir $pwd" \
	      --eval "%define _srcrpmdir $pwd/src" \
	      --eval "%define _rpmdir $tmpdir" \
	      --eval "%define _builddir $tmpdir/build" \
	      --eval "%define _tmppath $tmpdir" \
	      -bb reuse.spec
    [ -n "$opt_verbose" ] || echo $cmd >&2
    $cmd
)

arch=$(uname -m | sed -e 's:i.86:i?86:')
shopt -s nullglob
set -- $tmpdir/$arch/$name-*.$arch.rpm
[ $# -eq 1 ] || exit 1
cat "$1"
exit $?

: <<'EOF'  # Make it so that /bin/sh will correctly parse this script
#=======================================================================

SPECFILE:
# Note: Lines that contain undefined at-foo-at macros are removed
#       in the macro-expansion pass.

%define old_version @old_version@
%define new_version @new_version@
%define flavor @flavor@

%define _old_version %(echo %old_version | sed -e 's:-:_:g')
%define _new_version %(echo %new_version | sed -e 's:-:_:g')

Name:         @name@
License:      @license@
Group:        @group@
Summary:      @summary@ (repackaged)
%if "%flavor" == ""
Version:      %{_old_version}_for_%{_new_version}
Requires:     kernel = %new_version
%else
%define _flavor %(echo "@flavor@" | sed -e 's:-:_:g')
Version:      %{_old_version}_%{flavor}_for_%{_new_version}_%{_flavor}
Requires:     kernel-%flavor = %new_version
%endif
Release:      @release@
BuildRoot:    %{_tmppath}/%{name}-%{version}-build
Vendor:       @vendor@
Distribution: @distribution@

%description
@description@

%prep
%setup -c -n dummy -T

%install
mkdir -p $RPM_BUILD_ROOT

exec 3>filelist
re="s/%old_version/%new_version/g"
re=${re//./\\.}
_re=${re//-/_}

rpm --query --dump @old_nvr@ \
| while read path size mtime md5sum mode owner group \
	   isconfig isdoc rdev symlink; do
    path2=$(echo "$path" | sed -e "$re" -e "$_re")
    flags=
    if [ "${mode:0:2}" = 04 ]; then
	mkdir -p $RPM_BUILD_ROOT$path2

	flags="%dir $flags"
    elif [ "${mode:0:2}" = 01 ]; then
	ln $path $RPM_BUILD_ROOT$path2

	if [ "$isconfig" -eq 1 ]; then
	    flags="%config(noreplace) $flags"
	elif [ "$isdoc" -eq 1 ]; then
	    flags="%doc $flags"
	fi
    # FIXME: handle symlinks and device special files as well...
    fi
    echo "$flags$path2" >&3
done
exec 3>-

set -- $(sed -e '\:^/lib/modules/:!d' \
	     -e 's:^/lib/modules/::' \
	     -e 's:/.*::' filelist \
	 | sort -u)
KERNELRELEASES=$*
for section in prein preun postin postun; do
    rpm --query --queryformat "%{$section}" @old_nvr@ \
    | sed -e "s:^(none)$::" \
	  -e "s:^\\(KERNELRELEASES=\\).*:\\1\"$KERNELRELEASES\":g" \
    > $section.sh
done

%pre -f prein.sh

%preun -f preun.sh

%post -f postin.sh

%postun -f postun.sh

%files -f filelist

%changelog
* @changelog_date@ - kernel-update-tool@suse.de

- Reuse this package from kernel %old_version for kernel %new_version.

@changelog@
