require Getopt::Long;
use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG WIFSTOPPED WSTOPSIG);
-require Mail::Header;
+require MIME::Head; # inherits Mail::Header
require Mail::Address;
require File::Basename;
require Mail::Alias;
my $sendmail_orig=(-x ($_="/usr/sbin/sendmail-orig") ? $_ : "/usr/sbin/sendmail");
my $HOME="/home/short";
# Mail-Alias-1.12 defaults to "/etc/mail/aliases" which does not exist on RedHat sendmail-8.12.5-7
-my @addr_addon=(Mail::Alias->new("/etc/aliases")->exists($_="sentout") ? ($_) : ());
+# Mail-Alias-1.12 will clutter $_ !
+my @addr_addon=(Mail::Alias->new("/etc/aliases")->exists("sentout") ? ("sentout") : ());
my $opt_F;
+my $is_pgp;
sub FromAddress
{
my($rcpt,$iserror)=@_;
+ my $phrase=(defined $opt_F ? $opt_F : "Jan Kratochvil");
+ {
+ last if !$is_pgp;
+ last if $iserror;
+ local *F;
+ local $_;
+ my $filename="$HOME/.gnupg/options";
+ open F,$filename or do { warn "Open \"$filename\": $!"; last; };
+ local $/="\n";
+ my @keys=map((/^\s*default-key\s+(\S+)\s*$/),<F>);
+ @keys==1 or do { warn "Found ".scalar(@keys)." 'default-key's in your \"$filename\", ignoring"; last; };
+ close F or warn "Close \"$filename\": $!";
+ my $default_key=$keys[0];
+ $default_key=~/^[[:xdigit:]]{8}$/ or do { warn "Invalid 'default-key', ignoring: $default_key"; last; };
+ return Mail::Address->new(
+ $phrase,
+ 'pgp-'.uc($default_key).'@jankratochvil.net',
+ );
+ }
+ # !$is_pgp or fallback
return Mail::Address->new(
- (defined $opt_F ? $opt_F : "Jan Kratochvil"),
+ $phrase,
(!$iserror ? 'rcpt' : 'rcpterr')
.'-'
.(defined($rcpt->user()) ? $rcpt->user() : "NOUSER")
# RedHat sendmail-8.9.3-20/src/main.c/main()/\Qif (FullName != NULL)\E
# for $opt_F is implemented by Mail::Address in our &FromAddress
-my $head=Mail::Header->new(\*STDIN);
-# We may (=will) change the contents and send it multiple times
-if (defined(my $msgid=$head->get("Message-ID"))) {
- $head->delete("Message-ID");
- $head->replace("X-LaceMail-sendmail-Message-ID",$msgid);
- }
+my $head=MIME::Head->new(\*STDIN);
# options leave in @ARGV, addresses to @addr:
my @args=@ARGV; # temporary
@ARGV=(); # options
# now $from_headername contains the header name to be replaced w/substituted value
}
+# to be utilized later by &FromAddress
+$is_pgp=(1
+ && do { local $_=$head->mime_attr("Content-Type"); $_ && ~m#^multipart/(?:signed|encrypted)$#; }
+ && do { local $_=$head->mime_attr("Content-Type.protocol"); $_ && ~m#^application/pgp\b#; }
+ );
+
my $exitcode=0;
-my @rcpts=(@addr ? @addr : (undef())); # !defined($rcpt) if we have no recipients
+# !defined($rcpt) if we have no recipients
+# make the list unique to prevent dupes being normally filtered by sendmail(8)
+# one '{' is block-wrapper, another '{' is hash-indirection!
+# hash keys are just strings, never refs!
+# unify the list as Mail::Address instances
+my @rcpts=(!@addr ? (undef()) : values(%{{ map({
+ my $obj=$_;
+ $obj=parseone $obj if !ref $obj;
+ (!defined $obj ? () : (lc($obj->address())=>$obj));
+ } @addr) }}));
+
my $stdin_body=(@rcpts<=1 ? undef() : do { # store input data only if it will be used multiple times
local $/=undef();
<STDIN>;
if (defined $rcpt) { # !defined($rcpt) if we have no recipients
local $_;
- if (!ref $rcpt) {
- $rcpt=parseone $rcpt;
- next if !defined $rcpt;
- }
$opt_f=FromAddress($rcpt,1)->address() if !defined $opt_f;
$head->replace($from_headername,FromAddress($rcpt,0)->format()) if $from_headername;
}
sendmail_orig_exec() if !$pid; # child
}
$head->print(\*SENDMAIL);
- print SENDMAIL "\n"; # Mail::Header->print() eats the empty line but it doesn't print it
+ print SENDMAIL "\n"; # MIME::Head->print() eats the empty line but it doesn't print it
if (defined($stdin_body)) {
print SENDMAIL $stdin_body;
}