#!/usr/bin/perl
#
# $Id$
#
# Alternative: sha256sum -b
use strict;
use Getopt::Std;
use File::Find;
use IO::Handle;
use IO::Uncompress::Gunzip;
use Digest::SHA qw(sha256);
use MIME::Base64;
use Benno::Config;
my $VERSION = '2.10.3';

my %opts;
getopts('hsVc:',\%opts);

if ($opts{V}) {
    print "benno-digest version $VERSION\n";
    exit 0;
}

$opts{h}    && help_exit();
my $repo = pop @ARGV;
$repo    || help_exit();

my $xmlconf = $opts{c} || '/etc/benno/benno.xml';
$main::BennoXML = new Benno::Config($xmlconf);
my @secretheader = $main::BennoXML->get_secretheader;

if (-d $repo) {
    use warnings;
    find({wanted => \&process_archive, no_chdir => 1}, $repo);
}
else {
    check_file($repo,@secretheader,1) || exit 99;
}


### SUBS ###
sub process_archive
{
    my ($mailfile) = @_;
    my $filename = $File::Find::name;
    my $dirname  = $File::Find::dir;

    if (-d $filename)  { return undef; }     # directory

    eval {
        print "$filename: ";
        check_file($filename,@secretheader);
    };
    if ($@) {
        print STDERR $@;
    }
}


sub check_file
{
    my ($repofile,$singlefile) = @_;
    my ($basename) = $repofile =~ m!([^/]+)(\..{3})$!;

    next if -d $repofile;

    my $fh;
    if ($repofile =~ /\.gz$/) {
        $fh = new IO::Uncompress::Gunzip $repofile or die "Cannot open $repofile: $!\n";
    }
    else {
       $fh = IO::File->new($repofile,'r')          or die "Cannot open $repofile: $!\n";
    }

    my $buffer;
    my $in_meta   = 1;
    my $in_header = 1;
    while (my $line = $fh->getline) {
        if ($line =~ /^\R/) { $in_header = 0; }
        if ($in_meta) {
            if ($line =~ /^(X-REAL-RCPTTO|X-REAL-MAILFROM|Sender|Recipient|Size|Date|Timezone|===== Hash):/) {
                next;
            }
        }
        $in_meta = 0;
        if ($in_header) {
            my ($header,$value) = $line =~ /^(\S+):(.*)$/;
            if (grep /^$header$/, @{secretheader}) {
                next;
            }
        }

        $buffer .= $line;
    }
    my $ctx = Digest::SHA->new('256');
    my $digest = $ctx->add($buffer)->hexdigest;
    my $filedigest = uc $digest;

    print "$filedigest\n";

    return 0;
}


sub help_exit
{
    print "Usage: benno-digest [-c <xmlconfig>] <mailfile|repository>\n";
    print "\n";
    print "Prints the digest of the given <mailfile> or the mailfiles in <repository>\n";
    print "\n";
    print "  -c <xmlconfig>     xml config file (default: /etc/benno/benno.xml)\n";
    print "  -s                 skip secret headers in checksum calculation\n";
    print "  -V                 print version\n";
    exit 0;
}
