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

use File::Path;

sub usage {
  my($s) = shift;
  print "$s\n\n";
  print <<SUSAGE;
Usage: undebiff <package> <old-version> <new-version> <arch> [<deb>]
<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)
<deb> is the target deb

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

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

$dpackage = shift @ARGV;
$oldversion = shift @ARGV;
$newversion = shift @ARGV;
$arch = shift @ARGV;
$destdeb = shift @ARGV;

($destdeb) || ($destdeb = "$dpackage"."_$newversion"."_$arch.deb");
$debiff = "$dpackage"."_$oldversion"."_$newversion"."_$arch.debiff";
$srcdeb = "$dpackage"."_$oldversion"."_$arch.deb";


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


$workdir = "/tmp/undebiff.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 "ar p $debiff control.tar.xdelta> $cfilexdelta") 
  && (die "cannot get control.tar.xdelta file, debiff not ok?");
(system "ar p $debiff data.tar.xdelta> $dfilexdelta") 
  && (die "cannot get data.tar.xdelta file, debiff not ok?");


(system "xdelta patch $cfilexdelta $cfilesrc $cfiledest") 
  && (die "error calling xdelta - not installed?");
(system "xdelta patch $dfilexdelta $dfilesrc $dfiledest") 
  && (die "error calling xdelta");


(system "dpkg-deb --tar-build $cfiledest $dfiledest $destdeb") 
  && die "error creating ar archive \"$destdeb\"";

rmtree $workdir;

