exiacl.pl
changeset 11 2fdc6206e792
parent 10 59cd8ce44290
child 12 1f683c5eef8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/exiacl.pl	Fri Aug 19 13:10:19 2005 +0000
@@ -0,0 +1,175 @@
+#! /usr/bin/perl
+# © Heiko Schlittermann
+# $Id$
+# $URL$
+use constant USAGE => << '#'; 
+!ME! [options] [-- exim native options]
+
+    --[no]log	show the log output	[!$Cf->log!]
+    --[no]debug	show debug debug output	[!$Cf->debug!]
+
+    --from=s	from:			[!$Cf->from!]
+    --to=s	to:			[!$Cf->to!]
+
+    --Helo=s	HELO	   		[!$Cf->Helo!]
+    --From=s	MAIL FROM:		[!$Cf->From!]
+    --To=s	RCPT TO: 		[!$Cf->To!]
+
+    --src=s	src ip/name		[!$Cf->src!]
+    --dst=s	dst ip/name		[!$Cf->dst!]
+
+    --exim=s	exim binary		[!$Cf->exim!]
+    --config=s	exim config file	[!$Cf->config!]
+
+    $Id$
+    $URL$
+#
+
+
+use strict;
+use warnings;
+use AppConfig;
+use IPC::Open3;
+use IO::Select;
+use Socket;
+use File::Basename;
+
+
+sub exim_option($);
+sub read_exim($);
+sub write_exim($@);
+sub addr(@);
+sub hostname() { chomp (my $h = `hostname -f`); return $h;  }
+
+use constant ME => basename $0;
+use constant HOSTNAME => hostname;
+use constant CONFIG => (
+    { CASE => 1 },
+
+    log	    => { ARGS => "!",  DEFAULT => 1 },
+    debug   => { ARGS => "!",  DEFAULT => 0 },
+
+    from    => { ARGS => "=s" },
+    to	    => { ARGS => "=s" },
+
+    Helo    => { ARGS => "=s", ALIAS => "ehlo" },
+    From    => { ARGS => "=s" },
+    To	    => { ARGS => "=s" },
+
+    src	    => { ARGS => "=s", DEFAULT => "172.20.1.8"  },
+    dst	    => { ARGS => "=s"  },		    # exim primary_hostname
+
+    exim    => { ARGS => "=s", DEFAULT => $ENV{EXIM} || "exim" },
+    config  => { ARGS => "=s", DEFAULT => $ENV{EXIM_CONF} || "/etc/exim/exim.conf.t" , 
+		 ALIAS => "C" },
+
+    help    => { ARGS => "!" },
+
+);
+
+
+
+my $Cf;
+$Cf = new AppConfig CONFIG or die;
+    $Cf->dst(addr(exim_option("primary_hostname")));
+    $Cf->getopt(qw(pass_through no_ignore_case)) or die $@;
+
+    $Cf->From($Cf->from)		    unless $Cf->From;
+    $Cf->To($Cf->to)			    unless $Cf->To;
+
+    $Cf->Helo((split/@/, $Cf->from||"")[1] || HOSTNAME)	    
+					    unless $Cf->Helo;
+    $Cf->dst(addr(HOSTNAME))		    unless $Cf->dst;
+
+    $@ = "";
+    foreach (qw/from to src dst/) {
+	$Cf->get($_) or $@ = join " ", $@, $_;
+    }
+
+    die ME.": Missing values: $@\n" if $@;
+
+
+MAIN: {
+    die "Config file for exim not readable ".$Cf->config.": $!\n" if not -r $Cf->config;
+
+    my ($w, $r);
+    my @cmd = ($Cf->exim, 
+	    -C => $Cf->config, 
+	    -oMi => addr($Cf->dst),
+	    -bhc => addr($Cf->src),
+	    @ARGV);		    # remaining args are exim native
+
+    if ($Cf->help) {
+	($_ = USAGE) =~ s/!(.*?)!/eval $1||""/egs;
+	print; exit;
+    }
+
+    my $s = new IO::Select;
+
+    print "**> @cmd\n";
+
+    open3($w, $r, undef, @cmd) or die "Can't run @cmd: $!\n";
+
+     read_exim $r;
+    write_exim $w, "EHLO ".$Cf->Helo."\n";
+     read_exim $r;
+    write_exim $w, "MAIL FROM: ".$Cf->From."\n";
+     read_exim $r;
+    write_exim $w, "RCPT TO: ".$Cf->to."\n";
+     read_exim $r;
+    write_exim $w, "DATA\n";
+     read_exim $r;
+    write_exim $w, "From: ".$Cf->from."\n";
+    write_exim $w, "To: ".$Cf->to."\n";
+    write_exim $w, "Subject: Test\n";
+
+    if (not -t STDIN) {
+	write_exim $w, "\n";
+	while (<>) {
+	    write_exim $w, $_;
+	}
+    }
+
+    write_exim $w, "\n.\n";
+     read_exim $r;
+    write_exim $w, "QUIT\n";
+
+
+}
+
+sub read_exim($) {
+    my $fh = shift;
+    while (<$fh>) {
+	/^\d\d\d/ and print("< $_") and next;
+	/^LOG/ and print and next if $Cf->log;
+	print and next if $Cf->debug;
+    } continue {
+	last if /^\d\d\d\s/;
+    }
+    exit if /^5/;
+}
+
+sub write_exim($@) {
+    my $fh = shift;
+    print "> ", @_;
+    print $fh @_;
+}
+
+
+{
+    my %opts;
+sub exim_option($) {
+    my $opt = shift;
+    my $exim = $Cf->exim;
+    if (!%opts) {
+	%opts = map { chomp; /^(.*?)\s*=\s*(.*)/ ? ($1, $2) : (/no_(.*)/ ? ($1, 0) : ($_, 1)) } grep !/^\s*$/, `$exim -bP`;
+    }
+    $opts{$opt}
+} }
+
+
+sub addr(@) {
+    map { inet_ntoa scalar gethostbyname $_ } @_;
+}
+
+# vim:sts=4 sw=4 aw ai sm: