#! /usr/bin/perl -w
use strict;

die "not in kernel top level directory"
  unless -d 'kernel' and -d 'Documentation';
our $TOPPATCHDIR='/usr/src/kernel-patches';
our $ARCHITECTURE=`dpkg --print-installation-architecture`;
chomp $ARCHITECTURE;
our $DECOMPRESSOR='zcat -f';
our $PATCH_OPTIONS='--ignore-whitespace --silent';
# This is informational only, used by lskpatches
our $magic = '
DHPKPATCHES_VERSION=0.100.0
';

our @DEPENDS;
for my $deps ("kdbcore", "kdbcore", "kdbcore") {
  my @deps = split (/\s+/, $deps);
  push @DEPENDS, \@deps;
}

our @KVERSIONS=("2.4.23", "2.4.22", "2.4.21");
our @PATCHFILES=("/usr/src/kernel-patches/diffs/kdb/kdb-v4.3-2.4.23-i386-1.gz", "/usr/src/kernel-patches/diffs/kdb/kdb-v4.3-2.4.22-i386-1.gz", "/usr/src/kernel-patches/diffs/kdb/kdb-v4.3-2.4.21-i386-5.gz");
our @DEBPATCHFILES=("", "", "");
our @STRIPLEVELS=("1", "1", "1");

exit 0
  if -f "debian/APPLIED_${ARCHITECTURE}_kdb" or
  -f "debian/APPLIED_all_kdb";
open (MAKEFILE, "Makefile");

my ($VERSION, $PATCHLEVEL, $SUBLEVEL, $EXTRAVERSION, $KERNELRELEASE);
while (<MAKEFILE>) {
  if (m/^VERSION\s*=\s*(\S*)/) { $VERSION = $1; next; };
  if (m/^PATCHLEVEL\s*=\s*(\S*)/) { $PATCHLEVEL = $1; next; };
  if (m/^SUBLEVEL\s*=\s*(\S*)/) { $SUBLEVEL = $1; next; };
  if (m/^EXTRAVERSION\s*=\s*(\S*)/) { $EXTRAVERSION = $1; last; };
}
close MAKEFILE;
$KERNELRELEASE="$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION";
our $IDX;

for (my $i=$#PATCHFILES; $i >= 0; $i--) {
  my $v=$KVERSIONS[$i];
  if (defined $ENV{KPATCH_kdb} && $v eq $ENV{KPATCH_kdb}
      or $v eq $KERNELRELEASE or $v eq 'all' ) {
    $IDX=$i;
  }
}

if (defined $ENV{KPATCH_kdb}
    and $KVERSIONS[$IDX] ne $ENV{KPATCH_kdb}) {
  print STDERR "Requested kernel version \`$ENV{KPATCH_kdb}' not found for patch kdb\n";
  exit 1;
} elsif (!defined $IDX) {
  print STDERR "No \"Kernel debugger\" patch found for kernel version $KERNELRELEASE\n";
  exit 1;
}
our $KVERSION=$KVERSIONS[$IDX];
our $STRIPLEVEL=$STRIPLEVELS[$IDX];

our $PATCHFILE;
if (defined $DEBPATCHFILES[$IDX] and
    (-r 'version.Debian' or -r 'README.Debian' )) {
  $PATCHFILE=$DEBPATCHFILES[$IDX];
} else {
  $PATCHFILE=$PATCHFILES[$IDX];
}

print STDERR "START applying patch \"Kernel debugger\"\n";

our @NEEDED_DEPS;
our @UNPATCHDEPS;
for my $dep (@{$DEPENDS[$IDX]}) {
  if (-x "${TOPPATCHDIR}/${ARCHITECTURE}/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}/apply/$dep" ) {
    push @NEEDED_DEPS, "${ARCHITECTURE}/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}/apply/$dep";
  } elsif (-x "${TOPPATCHDIR}/all/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}/apply/$dep") {
    push @NEEDED_DEPS, "all/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}/apply/$dep";
  } elsif (-x "${TOPPATCHDIR}/${ARCHITECTURE}/apply/$dep" ) {
    push @NEEDED_DEPS, "${ARCHITECTURE}/apply/$dep";
  } elsif (-x "${TOPPATCHDIR}/all/apply/$dep") {
    push @NEEDED_DEPS, "all/apply/$dep";
  } else {
    die "Patch dependency \`$dep' not found - aborting\n";
  }
}
use File::Basename;
if (@NEEDED_DEPS > 0) {
  print STDERR "Ensuring the following patches are applied first: ",
    join (' ', @NEEDED_DEPS), "\n";
  for my $applyscript (@NEEDED_DEPS) {
    my $dep = basename ($applyscript);
    system ("${TOPPATCHDIR}/$applyscript") == 0
      or die "Error running ${TOPPATCHDIR}/$applyscript";

    # check something was applied
    if (! -f "debian/APPLIED_${ARCHITECTURE}_$dep" and
        ! -f "debian/APPLIED_all_$dep") {
      die "Patch dependency did not left a patch stamp (version mismatch ?)\n";
    }

    $applyscript =~ s,/apply/,/unpatch/,;
    push @UNPATCHDEPS, $applyscript;
  }
}

print STDERR "Testing whether \"Kernel debugger\" patch for $KVERSION applies (dry run):\n";
die "\"Kernel debugger\" patch for $KVERSION not found" unless -r $PATCHFILE;

system ("$DECOMPRESSOR $PATCHFILE | " .
        "patch --force --dry-run $PATCH_OPTIONS -p$STRIPLEVEL") == 0
  or die "\"Kernel debugger\" patch for $KVERSION does not apply cleanly";
system("$DECOMPRESSOR $PATCHFILE | " .
       "patch $PATCH_OPTIONS -p$STRIPLEVEL") == 0
  or die "ASSERTION FAILED - \"Kernel debugger\" patch for $KVERSION failed";
print STDERR "\"Kernel debugger\" patch for $KVERSION succeeded\n";

print STDERR "Removing empty files:\n";
# make an exception for ./debian, or else the stamp files will go too.
system ('find . -path ./debian -prune -o ' .
        '-type f -size 0 ! -name "APPLIED*" -exec rm {} \; -print');
print STDERR "Done.\n";

system("mkdir -p debian");
open APPLIED, '>debian/APPLIED_i386_kdb'
  or die "cannot create debian/APPLIED_i386_kdb: $!";
print APPLIED <<EOF
PATCHFILE='$PATCHFILE'
STRIPLEVEL='$STRIPLEVEL'
EOF
;
print APPLIED "DEPENDS='", join (' ', @UNPATCHDEPS), "'\n";
close APPLIED;
system ("mkdir -p debian/image.d");
my $PKGNAME=`dpkg -S $PATCHFILE | cut -d: -f1`;
chomp $PKGNAME;
my $PKGVERS=`grep-dctrl -n -P $PKGNAME -s Version -X /var/lib/dpkg/status`;
chomp $PKGVERS;
open REGISTER, '>debian/image.d/register-kdb'
  or die "cannot createdebian/image.d/register-kdb: $!";
print REGISTER <<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)"
EOF
;
    print REGISTER "    printf 'for kernel $ENV{KPATCH_kdb},'\n"
      if defined $ENV{KPATCH_kdb};
print REGISTER <<EOF
    echo ' from package $PKGNAME, version $PKGVERS'
) >> \${docdir}/applied-patches
EOF
; close REGISTER;
chmod 0755, 'debian/image.d/register-kdb';

print STDERR "END applying patch \"Kernel debugger\"\n";
