#! /bin/bash
set -e

# This "apply" script was automatically generated by
# dh_installkpatches from apply.tmpl $Revision: 1.30 $

# Environment variables that will impact this script:
# KPATCH_kdb
#    if set to a kernel version for which you have a kdb patch,
#    it will be used instead of the version for your kernel.

# TODO:
# * ${Kernel:versions} substvar

if ! [ -d kernel -a -d Documentation ]
then
    echo >&2 "Not in kernel top level directory. Exiting"
    exit 1
fi

ARCHITECTURE=`dpkg --print-installation-architecture`
KVERSIONS=(2.4.22 2.4.21 2.4.20 2.2.18)
PATCHFILES=("/usr/src/kernel-patches/i386/kdb/kdb-v4.3-2.4.22-i386-1.gz" "/usr/src/kernel-patches/i386/kdb/kdb-v4.3-2.4.21-i386-5.gz" "/usr/src/kernel-patches/i386/kdb/kdb-v4.3-2.4.20-i386-1.gz" "/usr/src/kernel-patches/i386/kdb/kdb-v1.5-2.2.18.gz")
DEBPATCHFILES=("" "" "" "")
STRIPLEVELS=(1 1 1 1)
DEPENDS=("kdbcore" "kdbcore" "kdbcore" "")

DECOMPRESSOR="zcat -f"
PATCH_OPTIONS="--ignore-whitespace --silent"

# This is informational only, used by lskpatches
DHPKPATCHES_VERSION=0.99.28

# Idempotence: stop with success if already applied
[ -f debian/APPLIED_${ARCHITECTURE}_kdb -o \
  -f debian/APPLIED_all_kdb ] && exit 0

TOPPATCHDIR=/usr/src/kernel-patches

# Get current kernel version number etc
VERSION=$(grep ^VERSION Makefile 2>/dev/null | \
	sed -e 's/[^0-9]*\([0-9]*\)/\1/')
PATCHLEVEL=$( grep ^PATCHLEVEL Makefile 2>/dev/null | \
	sed -e 's/[^0-9]*\([0-9]*\)/\1/')
SUBLEVEL=$(grep ^SUBLEVEL Makefile 2>/dev/null | \
	sed -e 's/[^0-9]*\([0-9]*\)/\1/')
EXTRAVERSION=$(grep ^EXTRAVERSION Makefile 2>/dev/null | \
	sed -e 's/EXTRAVERSION =[ 	]*\([^ 	]*\)$/\1/')
KERNELRELEASE=${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}

###

# Find the patchfile to use (kernel's version, or env-specified one)

IDX=

declare -i i=${#PATCHFILES[*]}-1
while [ $i -ge 0 ]
do
    v=${KVERSIONS[$i]}
    if [ -n "$KPATCH_kdb" -a "$v" = "$KPATCH_kdb" \
         -o "$v" = "$KERNELRELEASE" -o "$v" = all ]
    then
	IDX=$i
    fi
    i=i-1
done

# If a specified version was asked and it was not found, stop here
if [ -n "$KPATCH_kdb" -a ${KVERSIONS[$IDX]} != "$KPATCH_kdb" ]
then
    echo >&2 "Requested kernel version \`$KPATCH_kdb' not found for patch kdb"
    exit 1
fi

###

if [ "$IDX" ]
then

    echo >&2 "START applying patch \"Kernel debugger\""

    # Check for dependencies

    NEEDED_DEPS=
    for dep in ${DEPENDS[$IDX]}
    do
	if [ -x ${TOPPATCHDIR}/${ARCHITECTURE}/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}/apply/$dep ]
	then
	    NEEDED_DEPS="${ARCHITECTURE}/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}/apply/$dep $NEEDED_DEPS"
	elif [ -x ${TOPPATCHDIR}/all/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}/apply/$dep ]
	then
	    NEEDED_DEPS="all/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}/apply/$dep $NEEDED_DEPS"
	elif [ -x ${TOPPATCHDIR}/${ARCHITECTURE}/apply/$dep ]
	then
	    NEEDED_DEPS="${ARCHITECTURE}/apply/$dep $NEEDED_DEPS"
	elif [ -x ${TOPPATCHDIR}/all/apply/$dep ]
	then
	    NEEDED_DEPS="all/apply/$dep $NEEDED_DEPS"
	else
	    echo >&2 "ERROR: Patch dependency \`$dep' not found - aborting"
	    echo >&2 "END applying patch \"Kernel debugger\""
	    exit 1
	fi
    done

    # Apply them

    if [ "$NEEDED_DEPS" ]
    then
	echo >&2 "Ensuring the following patches are applied first: $NEEDED_DEPS"
	for apply in ${NEEDED_DEPS}
	do
	    ${TOPPATCHDIR}/$apply

	    # check something was applied
	    if [ ! -f debian/APPLIED_${ARCHITECTURE}_$dep -a \
		 ! -f debian/APPLIED_all_$dep ]
	    then
		echo >&2 "ERROR: patch dependency did not left a patch stamp (version mismatch ?) - aborting"
		echo >&2 "END applying patch \"Kernel debugger\""
		exit 1
	    fi
	done
	UNPATCHDEPS=$(echo ${NEEDED_DEPS} | sed s,/apply/,/unpatch/,g)
    fi

    ### Now for this patch

    KVERSION=${KVERSIONS[$IDX]}
    STRIPLEVEL=${STRIPLEVELS[$IDX]}

    # Before the kernel-patch-debian era, we had to check for
    # README.Debian.  Now we must check for version.Debian.
    if [ "${DEBPATCHFILES[$IDX]}" != '' -a \
	\( -r version.Debian -o -r README.Debian \) ]
    then
	PATCHFILE=${DEBPATCHFILES[$IDX]}
    else
	PATCHFILE=${PATCHFILES[$IDX]}
    fi

    echo >&2 "Testing whether \"Kernel debugger\" patch for $KVERSION applies (dry run):"
    # We must check that patchfile exists, or the pipe will return 0
    # even though $DECOMPRESSOR returns 1.  Damn shell semantics.
    if [ -r $PATCHFILE ] && $DECOMPRESSOR $PATCHFILE |
	    patch --force --dry-run $PATCH_OPTIONS -p$STRIPLEVEL
    then
	# Don't use --force on second run, there should be no need
	# for it.  If something requires interaction, it's likely
	# there is a bug somewhere, better catch it.
	if $DECOMPRESSOR $PATCHFILE |
		patch $PATCH_OPTIONS -p$STRIPLEVEL
	then
	    echo >&2 "\"Kernel debugger\" patch for $KVERSION succeeded"
	    echo >&2 "Removing empty files after patching:"
	    # make an exception for ./debian/ contents, and for
	    # files named APPLIED*, or else some stamp files may
	    # be caught too.
	    find .  -path ./debian -prune -o \
		    -type f -size 0 ! -name 'APPLIED*' -exec rm {} \; -print
	    echo >&2 "Done."

	    # keep enough infos for unpatching
	    mkdir -p debian
	    cat > 'debian/APPLIED_i386_kdb' <<EOF
PATCHFILE='$PATCHFILE'
STRIPLEVEL='$STRIPLEVEL'
DEPENDS='$UNPATCHDEPS'
EOF

	    # have this patch registered in doc-dir
	    mkdir -p debian/image.d
	    PKGNAME=`dpkg -S $PATCHFILE | cut -d: -f1`
	    PKGVERS=`grep-dctrl -n -P $PKGNAME -s Version -X /var/lib/dpkg/status`
	    cat > 'debian/image.d/register-kdb' <<EOF
#!/bin/sh

# This scripts documents the "Kernel debugger" kernel patch into the
# kernel-image package, as being applied to the kernel.

docdir=\${IMAGE_TOP}/usr/share/doc/kernel-image-\${version}

mkdir -p \${docdir}

(
    printf 'Kernel debugger (kdb)${KPATCH_kdb:+ for kernel ${KPATCH_kdb}},'
    echo ' from package $PKGNAME, version $PKGVERS'
) >> \${docdir}/applied-patches
EOF
	    chmod +x 'debian/image.d/register-kdb'
	else
	    # This should never happen, thanks to the dry-run
	    echo >&2 "ASSERTION FAILED - \"Kernel debugger\" patch for $KVERSION failed"
	    echo >&2 "END applying patch \"Kernel debugger\""
	    exit 1
	fi
    else
	echo >&2 "\"Kernel debugger\" patch for $KVERSION does not apply cleanly"
	exit 1
    fi
    echo >&2 "END applying patch \"Kernel debugger\""
else
    echo >&2 "WARNING: no \"Kernel debugger\" patch found for kernel version $KERNELRELEASE"
fi

###

exit 0
