#!/usr/bin/perl
# <pre>
#
# filter for pine 3.93 and newer for decoding pgp mails
# use this with the following in your .pinerc:
# display-filters=_BEGINNING("-----BEGIN PGP")_ /home/roland/bin/pgpdecode
#
# add the command line option -dontask to pgpdecode, if you do not want to be 
# asked whether to run pgp on the mail or not.
#
# $Id: pgpdecode,v 1.8 1997/03/19 13:59:37 roland Exp $
#
# 21.03.96 Roland Rosenfeld <roland@spinnaker.rhein.de> 
# 23.03.96 $TMPFILE moved to $PGPPATH.
# 17.05.96 total rewrite in perl; many new features
# 27.08.96 corrected code for adding new keys
# 19.11.96 ask whether to run pgp before running it
# 25.11.96 some compatibility fixes
# 02.02.97 stty option configurable (Hoss Firooznia <hfir@math.rochester.edu>)

umask 077;

$stty="/bin/stty";             # where to find a stty, which supports -cbreak
                               # or raw/-raw
$sttyopt="cbreak";             # if your stty does not understand -cbreak
                               # try raw here.

$tmpdir = $ENV{'PGPPATH'};     # this offers more security than /tmp 
if ($tmpdir =~ /^$/) {
    $tmpdir = $ENV{'HOME'};    # if not set $PGPPATH try $HOME as tmp-dir
}

$pgpout = "$tmpdir/pgpout$$";
$pgperr = "$tmpdir/pgperr$$";

if (! (@ARGV[0] =~ /dontask/i) ) {  # option -dontask given?
    # no -dontask:
    print STDERR "Message uses PGP, do you wish to run PGP on it? [Y/n] ";
    system("$stty $sttyopt < /dev/tty");  # read char without pressing RETURN
    open (IN, "</dev/tty");
    $runpgp=getc(IN);                     # read exactly one keystroke from tty
    close IN;
    system("$stty -$sttyopt < /dev/tty"); # reset tty to normal 

    if ($runpgp =~ /n/i) {  # pressed n or N (everything else means Yes)
        # do not run pgp but print mail to stdout
        while (<>) { 
            print;
        }
        exit;
    }
    # when we did not exit, user wants to run pgp now.
} else {
    # -dontask set:
    shift;  # otherwise pgp seems to be confused.
}

#
# Now let us start the real decoder
#

$pgpfound=1;

while ($pgpfound) {

    while (($_=<>) && !(/^-----BEGIN PGP/)) {
        print $_;
    }
    if (/^-----BEGIN PGP/) {
        $pgpfound=1;
    } else {
        $pgpfound=0;
    }
    
    if (/^-----BEGIN PGP PUBLIC KEY BLOCK-----$/) {
        $pgpkeyblock .= $_;
        while (($_=<>) && !(/^-----END PGP PUBLIC KEY BLOCK-----$/)) {
            $pgpkeyblock .= $_;
        }
        $pgpkeyblock .= $_;
        
        open(SAVEOUT, ">&STDOUT");
        open(SAVEERR, ">&STDERR");
        open(STDOUT, ">$pgpout") || &abort("Can't redirect stdout to $pgpout");
        open(STDERR, "| tee $pgperr 1>&2") || &abort("Can't redirect stderr");
	open(TMP,">$tmpdir/pgpadd$$") || &abort("Can't export key to temp file");
	print TMP $pgpkeyblock;
	close(TMP);
        open(PGP, "|pgpk -a $tmpdir/pgpadd$$") || &abort("Can't execute pgp");
        close(PGP);
	unlink("$tmpdir/pgpadd$$") || &abort("Can't delete temp key file");
        close(STDOUT);
        close(STDERR);
        open(STDOUT, ">&SAVEOUT");
        open(STDERR, ">&SAVEERR");
        open(PGPERR, "<$pgperr") || &abort("Can't read $pgperr");

        while (<PGPERR>) {
            print "| $_";
        }
        close(PGPERR);
        unlink $pgperr;

        open(PGPOUT, "<$pgpout") || &abort("Can't read $pgpout");
        while (<PGPOUT>) {
            print ": $_";
        }
        close(PGPOUT);
        unlink $pgpout;
       
    } elsif (/^-----BEGIN PGP( SIGNED)? MESSAGE-----$/) {
        $pgpmessage .= $_;
        $pgpheader = $_;

        while (($_=<>) && !(/^-----END PGP (MESSAGE|SIGNATURE)-----$/)) {
            $pgpmessage .= $_;
        }
        $pgpmessage .= $_;
        
        open(SAVEOUT, ">&STDOUT");
        open(SAVEERR, ">&STDERR");
        open(STDOUT, ">$pgpout") || &abort("Can't redirect stdout");
        open(STDERR, "| tee $pgperr 1>&2") || &abort("Can't redirect stderr");
        open(PGP, "|pgpv -f") || &abort("Can't execute pgp");
        print PGP $pgpmessage;
        close(PGP);
        close(STDOUT);
        close(STDERR);
        open(STDOUT, ">&SAVEOUT");
        open(STDERR, ">&SAVEERR");
        
        open(PGPERR, "<$pgperr") || &abort("Can't read $pgperr");
        while (<PGPERR>) {
            print "| $_";
        }
        close(PGPERR);
        unlink $pgperr;

        print "|\n| $pgpheader|\n";

        open(PGPOUT, "<$pgpout") || &abort("Can't read $pgpout");
        while (<PGPOUT>) {
            print $_;
        }
        close(PGPOUT);
        unlink $pgpout;
        
        $pgpheader =~ s/BEGIN/END/;
        print "\n|\n| $pgpheader|\n\n";
    }
}

exit;

sub abort {
    local ($message) = @_;
    unlink $pgpout;
    unlink $pgperr;
    die $message
}

