#!/usr/bin/perl -w
#
# Takes two .deb archives and creates a debiff
#
# requires the following software in the PATH:
#  * patched dpkg-deb(1) with --control-tarfile command
#  * xdelta(1) 
#  * ar(1)

use File::Path;

sub usage {
  my($s) = shift;
  print "$s\n\n";
  print <<SUSAGE;
Usage: debiff <package> <old-version> <new-version> <arch> [<debiff>]
<package> is the name of the package
<old-version> is the version of the old archive 
<new-version> is the version of the new archive
<arch> is the architecture (e.g. i386)
<debiff> is the target

In the current directory must be two files called 
<package>_<old-version>_<arch>.deb and
<package>_<new-version>_<arch>.deb. 
If <debiff> is not given, a file called 
<package>_<old-version>_<new-version>_<arch>.debiff will be created in the
current directory.
SUSAGE

  exit 1;
}
(@ARGV >= 4) || &usage("debiff expects at least 4 arguments.");
(@ARGV <= 5) || &usage("debiff expects at most 5 arguments.");

$dpackage = shift @ARGV;
$oldversion = shift @ARGV;
$newversion = shift @ARGV;
$arch = shift @ARGV;
$debiff = shift @ARGV;
$debiff || ($debiff = "$dpackage"."_$oldversion"."_$newversion"."_$arch.debiff");

$srcdeb = "$dpackage"."_$oldversion"."_$arch.deb";
$destdeb = "$dpackage"."_$newversion"."_$arch.deb";

(-f $srcdeb) || &usage("\"$srcdeb\" does not exist.");
(-f $destdeb) || &usage("\"$destdeb\" does not exist.");


$workdir = "/tmp/debiff.build.$$";
mkdir $workdir, 0700;

$cfilep = "$workdir/control.tar";
$dfilep = "$workdir/data.tar";

$cfilesrc =  "$cfilep.src";
$cfiledest = "$cfilep.dest";
$cfilexdelta = "$cfilep.xdelta";
$dfilesrc =  "$dfilep.src";
$dfiledest = "$dfilep.dest";
$dfilexdelta = "$dfilep.xdelta";

(system "dpkg-deb --control-tarfile $srcdeb > $cfilesrc") 
  && (die "cannot get control file, too old dpkg-deb version or not a .deb?");
(system "dpkg-deb --fsys-tarfile $srcdeb > $dfilesrc") 
  && (die "cannot get data file, problem with .deb?");
(system "dpkg-deb --control-tarfile $destdeb > $cfiledest") 
  && (die "cannot get control file, \"$destdeb\" not a .deb?");
(system "dpkg-deb --fsys-tarfile $destdeb > $dfiledest") 
  && (die "cannot get data file, problem with .deb?");

(system "xdelta delta -9 $cfilesrc $cfiledest > $cfilexdelta") 
  || (die "error calling xdelta - not installed?");
(system "xdelta delta -9 $dfilesrc $dfiledest > $dfilexdelta") 
  || (die "error calling xdelta");


$dcfile = "$workdir/debiff-control";
open DCFILE, ">$dcfile";
print DCFILE "Package: $dpackage\n";
print DCFILE "Old-Version: $oldversion\n";
print DCFILE "New-Version: $newversion\n\n";

print DCFILE "Architecture: $arch\n\n";

print DCFILE "XDelta-Files: control.tar.gz data.tar.gz\n";

close DCFILE;

unlink $debiff;
(system "ar qc $debiff $dcfile $cfilexdelta $dfilexdelta") 
  && die "error creating ar archive \"$debiff\"";


rmtree $workdir;


