#!/usr/bin/perl -w

use strict;

use File::Copy;
use Getopt::Long;

use Debian::debsigs::debsigsmain;

sub processfile($);
sub cleanup($; $);
sub copyfiles();
sub syntax($);
sub version();

my ($showhelp, $showversion);
Getopt::Long::Configure('no_ignore_case');
GetOptions ('help|h' => \$showhelp,
	    'version|V' => \$showversion);

version() if $showversion;
syntax(0) if $showhelp;
exit(0) if $showhelp || $showversion;

syntax(1) unless @ARGV;

# What we need to add:

my $KEY = 'E435EC07';
my $KEYTYPE = 'origin';
my $KEYRING = '/usr/local/debsigs/origin-secring.gpg';
my $TMPDIR = "/tmp/debsigs-installer.$$";
my $COUNTER = 0;

my $file;

my %copyfiles;

mkdir($TMPDIR, 0700) or die
  "Couldn't mkdir $TMPDIR: $!";

foreach $file (@ARGV) {
  $COUNTER++;
  processfile($file);
}

copyfiles();
cleanup($TMPDIR);
exit(0);

sub processfile($) {
  my ($file) = shift @_;

  my $TMPFILE = "$TMPDIR/file-$COUNTER.deb";

  # Copy the file to $TMPDIR.

  copy($file, $TMPFILE) or die
    "Couldn't copy file to $TMPFILE: $!";

  # Add the signature to it.

  (system("debsigs", "-K", $KEYRING,
          "--default-key=$KEY", "--sign=$KEYTYPE", $TMPFILE) == 0) or die
            "Error signing!";

  # Now verify the result.

  if (system("debsig-verify", "-q", $TMPFILE) != 0) {
    print STDERR "Error validating $file!\n";
    cleanup($TMPDIR, $TMPFILE);
    exit(2);
  }

  # We're OK here, so flag the file for copying.

  $copyfiles{$TMPFILE} = $file;
}

sub cleanup($; $) {
  my ($dir, $file) = @_;

  # Let them pass in a file to unlink too, in case it's being
  # called before being added to %copyfiles.


  if (defined($file)) {
    # print STDERR "Deleting $file\n";
    unlink($file);
  }

  foreach $file (keys %copyfiles) {
    # print STDERR "Deleting $file\n";
    unlink($file);
  }

  # print STDERR "Removing $dir\n";
  rmdir($dir);

}

sub copyfiles() {
  my ($source, $dest);

  foreach $source (keys %copyfiles) {
    copy($source, $copyfiles{$source}) or die
      "Couldn't copy $source to " . $copyfiles{$source} . ": $!";
  #  print STDERR "Copied $source to " . $copyfiles{$source} . "\n";
  }
}

sub syntax($) {
  my ($err) = @_;
  my $s = "Usage: debsigs-installer file...\n";

  if ($err) {
    print STDERR "$s";
    exit(1);
  } else {
    print "$s";
  }
}

sub version() {
  print "debsigs-installer $Debian::debsigs::debsigsmain::VERSION\n";
}

__END__

=head1 NAME

debsigs-installer - process signatures in .deb packages

=head1 SYNOPSIS

B<debsigs-installer> file [file...]

=head1 DESCRIPTION

B<debsigs-installer> is designed to be called in an automated fashion from
an installer.  It is given one or more files on the command line.  For each
file, it will apply the origin signature and make sure that the resulting
package verifies (it will fail to verify if it is missing one of the other
required signatures).  It will try its best to do either an all or nothing
approach; that is, if there is a problem with any .deb, all of them will be
unmodified and error code is returned.  It can assure this for all except
system call failures (can't copy files, etc.)  If success is returned, all
files should be assumed to have succeeded.  If failure is returned, all
files should be assumed to have failed.

=head1 OPTIONS

None.

=head1 BUGS

This program isn't finished yet.  It uses hard-coded values for the key ID,
key type (see debsigs(1)), keyring file, and temporary directory.

=head1 AUTHOR

John Goerzen <jgoerzen@progenylinux.com>

=head1 SEE ALSO

debsig-verify(1), gpg(1)

=cut
