exiacl.pl
changeset 22 e73bf6df70f0
parent 21 2dbba4511409
child 24 a7a73cba1342
equal deleted inserted replaced
21:2dbba4511409 22:e73bf6df70f0
     4 # $URL$
     4 # $URL$
     5 use constant USAGE => << '#'; 
     5 use constant USAGE => << '#'; 
     6 !ME! [options] [-- exim native options] 
     6 !ME! [options] [-- exim native options] 
     7 
     7 
     8     --[no]log	show the log output	[!$Cf->log!]
     8     --[no]log	show the log output	[!$Cf->log!]
     9     --[no]debug	show debug debug output	[!$Cf->debug!]
     9     --[no]debug	show debug output	[!$Cf->debug!]
    10 
    10 
    11     --from=s	from:			[!$Cf->from!]
    11     --from=s	from:			[!$Cf->from!]
    12     --to=s	to:			[!$Cf->to!]
    12     --to=s	to:			[!$Cf->to!]
    13 
    13 
    14     --Helo=s	HELO	   		[!$Cf->Helo!]
    14     --Helo=s	HELO	   		[!$Cf->Helo!]
    16     --To=s	RCPT TO: 		[!$Cf->To!]
    16     --To=s	RCPT TO: 		[!$Cf->To!]
    17 
    17 
    18     --src=s	src ip/name		[!$Cf->src!]
    18     --src=s	src ip/name		[!$Cf->src!]
    19     --dst=s	dst ip/name		[!$Cf->dst!]
    19     --dst=s	dst ip/name		[!$Cf->dst!]
    20 
    20 
       
    21     --au	user (-oMai)		[!$Cf->oMai!]
       
    22     --aa	authenticator (-oMaa)	[!$Cf->oMaa!]
       
    23     
    21     --exim=s	exim binary		[!$Cf->exim!]
    24     --exim=s	exim binary		[!$Cf->exim!]
    22     --config=s	exim config file	[!$Cf->config!]
    25     --config=s	exim config file	[!$Cf->config!]
    23     
    26 
    24     --[no]callout			[!$Cf->callout!]
    27     --[no]callout			[!$Cf->callout!]
    25 
    28 
    26     Environment used: $EXIM		[!$ENV{EXIM}!]
    29     Environment used: $EXIM		[!$ENV{EXIM}!]
    27                       $EXIM_CONF	[!$ENV{EXIM_CONF}!]
    30                       $EXIM_CONF	[!$ENV{EXIM_CONF}!]
    28 
    31 
    48 sub write_exim($@);
    51 sub write_exim($@);
    49 sub addr(@);
    52 sub addr(@);
    50 sub hostname() { chomp (my $h = `hostname -f`); return $h;  }
    53 sub hostname() { chomp (my $h = `hostname -f`); return $h;  }
    51 
    54 
    52 sub which($) { (map { -x "$_/$_[0]" && "$_/$_[0]" || () } split /:/, $ENV{PATH})[0] }
    55 sub which($) { (map { -x "$_/$_[0]" && "$_/$_[0]" || () } split /:/, $ENV{PATH})[0] }
    53 sub findExim() { which("exim") || which("exim4") }
    56 sub findExim() { $ENV{EXIM} || which("exim") || which("exim4") || undef }
    54 sub guessConfig($) { qx/$_[0] "-bV"/ =~ /^Configuration.*\sis\s+(\S+)/mi and return $1 }
    57 sub guessConfig() { $_ = findExim(); qx/$_ "-bV"/ =~ /^Configuration.*\sis\s+(\S+)/mi and return $1 }
    55 
    58 
    56 use constant ME => basename $0;
    59 use constant ME => basename $0;
    57 use constant HOSTNAME => hostname;
    60 use constant HOSTNAME => hostname;
    58 use constant CONFIG => (
    61 
       
    62 my $Cf = new AppConfig (
    59     { CASE => 1 },
    63     { CASE => 1 },
    60 
    64 
    61     log	    => { ARGS => "!",  DEFAULT => 1 },
    65     log	    => { ARGS => "!",  DEFAULT => 1 },
    62     debug   => { ARGS => "!",  DEFAULT => 0 },
    66     debug   => { ARGS => "!",  DEFAULT => 0 },
    63 
    67 
    69     To	    => { ARGS => "=s" },
    73     To	    => { ARGS => "=s" },
    70 
    74 
    71     src	    => { ARGS => "=s", DEFAULT => "172.20.1.8"  },
    75     src	    => { ARGS => "=s", DEFAULT => "172.20.1.8"  },
    72     dst	    => { ARGS => "=s"  },		    # exim primary_hostname
    76     dst	    => { ARGS => "=s"  },		    # exim primary_hostname
    73 
    77 
    74     exim    => { ARGS => "=s", DEFAULT => $ENV{EXIM} || findExim },
    78     au	    => { ARGS => "=s" },
    75     config  => { ARGS => "=s", DEFAULT => $ENV{EXIM_CONF} || guessConfig(findExim()),
    79     aa	    => { ARGS => "=s" },
    76 		 ALIAS => "C" },
    80 
       
    81     exim    => { ARGS => "=s", DEFAULT => findExim() },
       
    82     config  => { ARGS => "=s", DEFAULT => guessConfig(), ALIAS => "C" },
    77 
    83 
    78     callout =>	{ ARGS => "!", DEFAULT => 1 },
    84     callout =>	{ ARGS => "!", DEFAULT => 1 },
    79     help    => { ARGS => "!" },
    85     help    =>	{ ARGS => "!" },
    80 
    86 
    81 );
    87 ) or die;
    82 
    88 
    83 
       
    84 
       
    85 my $Cf;
       
    86 $Cf = new AppConfig CONFIG or die;
       
    87     $Cf->exim				    or die "No exim binary found\n";
    89     $Cf->exim				    or die "No exim binary found\n";
    88     $Cf->dst(addr(exim_option("primary_hostname")));
    90     $Cf->dst(addr(exim_option("primary_hostname")));
    89     #$Cf->getopt(qw(pass_through no_ignore_case)) or die $@;
    91     #$Cf->getopt(qw(pass_through no_ignore_case)) or die $@;
    90     $Cf->getopt(qw(no_ignore_case)) or die $@;
    92     $Cf->getopt(qw(no_ignore_case)) or die $@;
    91 
    93 
    94 
    96 
    95     $Cf->Helo(map { (my $x = $_) =~ s/[<>]//g; $x } (split/@/, $Cf->from||"")[1] || HOSTNAME)
    97     $Cf->Helo(map { (my $x = $_) =~ s/[<>]//g; $x } (split/@/, $Cf->from||"")[1] || HOSTNAME)
    96 	unless $Cf->Helo;
    98 	unless $Cf->Helo;
    97     $Cf->dst(addr(HOSTNAME))		    unless $Cf->dst;
    99     $Cf->dst(addr(HOSTNAME))		    unless $Cf->dst;
    98 
   100 
       
   101     $Cf->aa("LOGIN")			    unless $Cf->aa || !$Cf->au;
       
   102 
    99 
   103 
   100 
   104 
   101 MAIN: {
   105 MAIN: {
   102     die "Config file for exim not readable ".$Cf->config.": $!\n" if not -r $Cf->config;
   106     die "Config file for exim not readable ".$Cf->config.": $!\n" if not -r $Cf->config;
   103 
   107 
       
   108 
   104     my ($w, $r);
   109     my ($w, $r);
   105     my @cmd = ($Cf->exim, 
   110     my @cmd = ($Cf->exim, 
   106 	    -C => $Cf->config, 
   111 	    -C => $Cf->config, 
   107 	    -oMi => addr($Cf->dst),
   112 	    -oMi => addr($Cf->dst),
       
   113 	    ($Cf->au ? (-oMai => $Cf->au) : ()),
       
   114 	    ($Cf->aa ? (-oMaa => $Cf->aa) : ()),
   108 	    ($Cf->callout? "-bhc" : "-bh" ) => addr($Cf->src),
   115 	    ($Cf->callout? "-bhc" : "-bh" ) => addr($Cf->src),
   109 	    @ARGV);		    # remaining args are exim native
   116 	    @ARGV);		    # remaining args are exim native
   110 
   117 
   111     if ($Cf->help) {
   118     if ($Cf->help) {
   112 	($_ = USAGE) =~ s/!(.*?)!/eval $1||""/egs;
   119 	($_ = USAGE) =~ s/!(.*?)!/eval $1||""/egs;
   117     foreach (qw/from to src dst/) {
   124     foreach (qw/from to src dst/) {
   118 	$Cf->get($_) or $@ = join " ", $@, $_;
   125 	$Cf->get($_) or $@ = join " ", $@, $_;
   119     }
   126     }
   120     die ME.": Missing values: $@\n" if $@;
   127     die ME.": Missing values: $@\n" if $@;
   121 
   128 
   122     my $s = new IO::Select;
   129     # my $s = new IO::Select;
   123 
   130 
   124     print "**> @cmd\n";
   131     print "**> @cmd\n";
   125 
   132 
   126     open3($w, $r, undef, @cmd) or die "Can't run @cmd: $!\n";
   133     $SIG{PIPE} = sub { exit };
       
   134     my $pid = open3($w, $r, undef, @cmd) or die "Can't run @cmd: $!\n";
   127 
   135 
   128      read_exim $r;
   136      read_exim $r;
   129     write_exim $w, "EHLO ".$Cf->Helo."\n";
   137     write_exim $w, "EHLO ".$Cf->Helo."\n";
   130      read_exim $r;
   138      read_exim $r;
   131     write_exim $w, "MAIL FROM: ".$Cf->From."\n";
   139     write_exim $w, "MAIL FROM: ".$Cf->From."\n";
   159 	/^LOG/ and print and next if $Cf->log;
   167 	/^LOG/ and print and next if $Cf->log;
   160 	print and next if $Cf->debug;
   168 	print and next if $Cf->debug;
   161     } continue {
   169     } continue {
   162 	last if /^\d\d\d\s/;
   170 	last if /^\d\d\d\s/;
   163     }
   171     }
   164     exit if /^5/;
   172     exit if defined and /^[54]/;
   165 }
   173 }
   166 
   174 
   167 sub write_exim($@) {
   175 sub write_exim($@) {
   168     my $fh = shift;
   176     my $fh = shift;
   169     print "> ", @_;
   177     print "> ", @_;