X-Git-Url: https://git.jankratochvil.net/?p=PerlMail.git;a=blobdiff_plain;f=perlmail-accept;h=55bef4a30e6dd252c943dcd0bbef5ccb38ab0d1c;hp=9ba5cf57dea0b80d533a8a80b4f2b56805fc8674;hb=0c848de6fd9c35f1ec9640b3adbab036ce0a5a91;hpb=3ed0a9ec3b0f25730b258c20815dc1d7d44e7192 diff --git a/perlmail-accept b/perlmail-accept index 9ba5cf5..55bef4a 100755 --- a/perlmail-accept +++ b/perlmail-accept @@ -1,6 +1,22 @@ #! /usr/bin/perl -# -# $Id$ +# +# $Id$ +# Copyright (C) 2002-2003 Jan Kratochvil +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + use vars qw($VERSION); $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; }; @@ -10,7 +26,7 @@ use warnings; INIT { require Sys::Syslog; - Sys::Syslog::openlog("lacemail","pid","mail"); + Sys::Syslog::openlog("perlmail","pid","mail"); my @syslogging_stack; sub syslogging_on_save { @@ -27,13 +43,19 @@ INIT { } +use File::Basename; +BEGIN { + use lib $ENV{"PERLMAIL_BASEDIR"} || File::Basename::dirname($0); + use PerlMail::Config; + use PerlMail::Lib; + } + use Mail::Audit qw(MAPS); require IO::Handle; use Carp qw(cluck confess); use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG WIFSTOPPED WSTOPSIG); require POSIX; # for ceil use User::Utmp; -require File::Basename; use Getopt::Long; require Mail::Address; require MIME::Words; @@ -46,28 +68,19 @@ require HTTP::Cookies; require HTTP::Request; require LWP::UserAgent; use URI::Escape 'uri_escape'; +require WWW::SMS; -my $HOME="/home/lace"; -my $Mail="$HOME/Mail"; -my @ValidUsers=qw(root lace short kratochvil _local); -my $IdleMax=60; -my $MaxBodySMS=0x1000; # max bytes to pass to Lingua::EN::Squeeze -my $SMSmailError='short+err@ucw.cz'; -my $SMSwebRcpt='00420602431329'; -my $SMSmailRcpt=$SMSwebRcpt.'@sms.eurotel.cz'; -my $SMScontact=''; - -our($Message,$Audit,@AuditStored,$store_ignore,$store_ignorenewmail,$store_profile,$DoBell); -our(%audit_profile,@sms_squeezes,@alternates_host); # imported +our($Message,@AuditStored,$DoBell); my %alternates_host; # from @alternates_host +my %dnsbl_whitelist; # from @dnsbl_whitelist # from RedHat "procmail-3.22-5" # /i should be only $procmailFROM_DAEMON but how it can hurt to /i all? our $procmailTO_ =qr'^((Original-)?(Resent-)?(To|Cc|Bcc)|(X-Envelope|Apparently(-Resent)?)-To):(.*[^-a-zA-Z0-9_.])?'mio; our $procmailTO =qr'^((Original-)?(Resent-)?(To|Cc|Bcc)|(X-Envelope|Apparently(-Resent)?)-To):(.*[^a-zA-Z])?'mio; our $procmailFROM_DAEMON=qr'^(Mailing-List:|Precedence:.*(junk|bulk|list)|To: Multiple recipients of |(((Resent-)?(From|Sender)|X-Envelope-From):|>?From )([^>]*[^(.%@a-z0-9])?(Post(ma?(st(e?r)?|n)|office)|(send)?Mail(er)?|daemon|m(mdf|ajordomo)|n?uucp|LIST(SERV|proc)|NETSERV|o(wner|ps)|r(e(quest|sponse)|oot)|b(ounce|bs\.smtp)|echo|mirror|s(erv(ices?|er)|mtp(error)?|ystem)|A(dmin(istrator)?|MMGR|utoanswer))(([^).!:a-z0-9][-_a-z0-9]*)?[%@> ][^<)]*(\(.*\).*)?)?$([^>]|$))'mio; -our $procmailFROM_MAILER=qr'^(((Resent-)?(From|Sender)|X-Envelope-From):|>?From )[^>]*\b(Post(ma(st(er)?|n)|office)|(send)?Mail(er)?|daemon|mmdf|n?uucp|ops|r(esponse|oot)|(bbs\.)?smtp(error)?|s(erv(ices?|er)|ystem)|A(dmin(istrator)?|MMGR))(([^).!:a-z0-9][-_a-z0-9]*)?[%@> ][^<)]*(\(.*\).*)?)?$([^>]|$)'mio; +$procmailFROM_MAILER=qr'^(((Resent-)?(From|Sender)|X-Envelope-From):|>?From )[^>]*\b(Post(ma(st(er)?|n)|office)|(send)?Mail(er)?|daemon|mmdf|n?uucp|ops|r(esponse|oot)|(bbs\.)?smtp(error)?|s(erv(ices?|er)|ystem)|A(dmin(istrator)?|MMGR))(([^).!:a-z0-9][-_a-z0-9]*)?[%@> ][^<)]*(\(.*\).*)?)?$([^>]|$)'mio; # perl-5.8.0 does not cope w/original FROM_MAILER on the third '?' character # Thus we did '([^>]*[^(.%@a-z0-9])?' -> '[^>]*\b', I hope it is somehow similiar # original FROM_MAILER =qr'^(((Resent-)?(From|Sender)|X-Envelope-From):|>?From )([^>]*[^(.%@a-z0-9])?(Post(ma(st(er)?|n)|office)|(send)?Mail(er)?|daemon|mmdf|n?uucp|ops|r(esponse|oot)|(bbs\.)?smtp(error)?|s(erv(ices?|er)|ystem)|A(dmin(istrator)?|MMGR))(([^).!:a-z0-9][-_a-z0-9]*)?[%@> ][^<)]*(\(.*\).*)?)?$([^>]|$)'mio; @@ -75,6 +88,8 @@ our $procmailFROM_MAILER=qr'^(((Resent-)?(From|Sender)|X-Envelope-From):|>?From my $opt_mode; my $opt_smstest; # 1 or $smscount my $opt_idle; +my $opt_dry; +my $opt_single; sub process; @@ -87,7 +102,7 @@ sub stdin local $_; while (<>) { die "Invalid 'From ' line: $_" if $message eq "" && !/^From /; - if (/^From / && $message) { + if (!$opt_single && /^From / && $message) { process $message; $message=""; } @@ -97,7 +112,7 @@ sub stdin exit 0; } -# FIXME: separate 'lacemail'-transfer together with lacemail-submit away +# FIXME: separate 'perlmail'-transfer together with perlmail-submit away sub inetd { die "Excessive arguments" if @ARGV; @@ -116,8 +131,8 @@ sub inetd $length==($_=read STDIN,$message,$length) or confess "Got $_ out of required $length bytes"; $length==length $message or confess "False read return ".length($message)." instead of $length"; { - local *STDOUT; - local *STDERR; + local *STDOUT; # FIXME: fd's inherited by spawned processes are not closed this way! + local *STDERR; # FIXME: fd's inherited by spawned processes are not closed this way! local $DoBell=0; process $message; if ($DoBell) { @@ -140,6 +155,7 @@ sub bell sub useridle { + return 0 if ! -e "$HOME/away"; my %valid_users=map(($_=>1),@ValidUsers); my($idlebest,$linebest); for my $utmp (User::Utmp::getut(),{ "ut_line"=>"psaux" }) { @@ -244,129 +260,6 @@ my($smsi,$smscount)=@_; return ""; } -# FIXME: rewrite &send_cz_eurotel properly by own code -# patch for http://kiwi.ms.mff.cuni.cz/%7Etom/programming/src/sendsms.tar.gz/sendsms.pl -my $agent=LWP::UserAgent->new(); -$agent->agent("LaceMail $VERSION; contact=$SMScontact; "); -my($request1,$response1); # for &send_cz_eurotel -my($name,$value,$type,$disabled,$q2); - -# &send_cz_eurotel returns: error -# BEGIN http://kiwi.ms.mff.cuni.cz/%7Etom/programming/src/sendsms.tar.gz/sendsms.pl -sub parse_inputs -{ - my ($resp) = @_; - my @inputs; - my $ct; - my @c; - $ct=$resp->content(); - - @c=split '>', $ct; - grep { - if (/(]*)(>|$)/i) { - my $txt=$2, $name="", $value="", $type="x", $disabled=0; - my $ipoc; - if ($txt =~ /type="([^"]*)"/i) { $type=$1; } - elsif ($txt =~ /type=([^" ]*)[ >]/i) { $type=$1; } - if ($txt =~ /name="([^"]*)"/i) { $name=$1; } - elsif ($txt =~ /name=([^" ]*)[ >]/i) { $name=$1; } - if ($txt =~ /value="([^"]*)"/i) { $value=$1; } - elsif ($txt =~ /value=([^" ]*)[ >]/i) { $value=$1; } - if ($txt =~ /disabled/i) { $disabled=1; } - if ($name ne "" && $type ne "" && $type ne "button" && ! $disabled) - { - $ipoc=$#inputs; - $inputs[$ipoc+1][0]=$name; - $inputs[$ipoc+1][1]=$value; - } - } - 0; } @c; - return @inputs; -} - -sub make_query -{ - my (@inputs) = @_; - - my $i; - my $query = ""; - - for ($i=0; $i<=$#inputs; $i++) - { - my($q1, $q2); - if ($i>0) { $query="$query&"; } - $q1=uri_escape($inputs[$i][0]); - $q2=uri_escape($inputs[$i][1]); - $query="$query$q1=$q2"; - } - - #change @ and space back - $query=~ s/%20/+/g; - $query=~ s/%40/@/g; - return $query; -} - -sub send_cz_eurotel -{ - my ($id,$text,$mail,$directd) = @_; - my $src_url = "http://www2.eurotel.cz/sms/index.html"; - my @inputs; - my $query = ""; - my $cookie = HTTP::Cookies->new; - my $pref; - - #check if correct number - if (substr($id,0,5)!="00420") { return -1; } - $pref=substr($id,5,3); - if (!($pref eq "601" || $pref eq "602" || $pref eq "606" || $pref eq "607" || ($pref ge "720" && $pref le "729"))) { return -1; } - - #get form page, extract cookies - $request1=new HTTP::Request('GET', "$src_url?n_pagestyle=new"); - $response1=$agent->request($request1); - if ($response1->code != 200) { return -3; } - $cookie->extract_cookies($response1); - - #parse the form - @inputs=parse_inputs($response1); - - #fill the form - $inputs[2][1]=substr($id,5,3); - $inputs[3][1]=substr($id,8,6); - $inputs[4][1]=$mail; - - #direct display - $inputs[6][1]="sms"; - $inputs[6][1]="show" if ($directd>0); - - $inputs[7][1]=$text; - -# for ($i=0; $i<=$#inputs; $i++) { print "[$i] $inputs[$i][0] $inputs[$i][1]\n"; } - - #make query - $query=make_query(@inputs); - - #POST the form - my $header = new HTTP::Headers( - 'Content-Length' => length($query), - 'Content-Type' => 'application/x-www-form-urlencoded', - 'Accept' => '*/*', - 'Referer' => $src_url - ); - my $request2 = new HTTP::Request('POST',$src_url, $header, $query); - $cookie->add_cookie_header($request2); - my $response2 = $agent->request($request2); - - if ($response2->code != 200) { return -3; } - - #check for success - if ($response2->content() !~ /byla.*odesl.*na na SMS centrum/) - { - return -2; - } - return 0; -} -# END http://kiwi.ms.mff.cuni.cz/%7Etom/programming/src/sendsms.tar.gz/sendsms.pl - sub smslens { my($ignorenewmail,$smscount,%args)=@_; @@ -374,12 +267,11 @@ my($ignorenewmail,$smscount,%args)=@_; return map({ my $l=160; if (!$ignorenewmail) { # send by mail - $l-=length("Z emailu $SMSmailError: "); + $l-=length("Z emailu FIXME SMSmailError: "); $l-=length(smsbuild($_,$smscount)); } else { # send by web - $l-=length("Z WWW x/5: "); - $l-=length(smsbuild($_,POSIX::ceil($smscount/5))); + $l-=6; # 154 is the max length before split; why? } $l; } (0..$smscount-1)); @@ -395,7 +287,18 @@ my($squeezed,$smscount,@lens)=@_; $squeezed=~/^.{0,$len}/s; my $frag=$&; $squeezed=$'; - return 0 if send_cz_eurotel($SMSwebRcpt,$frag,"",0); + return 0 if 3!=@SMSwebRcpt; + local *F; + open F,"$HOME/priv/WWW-SMS-$SMSwebRcpt_username.pwd" or return 0; + my $pwd=; + chomp $pwd; + close F; + my $sms=WWW::SMS->new(@SMSwebRcpt,$frag,"username"=>$SMSwebRcpt_username,"passwd"=>$pwd); + for ($sms->gateways("sorted"=>"reliability")) { + last if $sms->send($_); + Sys::Syslog::syslog("warning","Web SMS send failed: %s",$WWW::SMS::Error); + my $void=$WWW::SMS::Error; # Prevent: Name "WWW::SMS::Error" used only once + } } return 1; } @@ -404,37 +307,16 @@ sub smssend_mail { my($squeezed,$smscount,@lens)=@_; - my $recalclen=0; - for ($smscount=0;$recalclennew("sendmail","-f","$SMSmailError"); - $mail->open({ - "To"=>$SMSmailRcpt, - "From"=>$SMSmailError, # no longer displayed anyway - "X-LaceMail-Version"=>$VERSION, - "X-LaceMail-Contact"=>$SMScontact, - }); - print $mail smsbuild($smsi,$smscount).$frag."\n"; - # FIXME: check errors - $mail->close(); - } - return 1; + return 0; } sub smssend { my($ignorenewmail,$smscount,%args)=@_; - my %aliases=muttrc_aliases(); - my $text=audit_sms( + my $text=PerlMail::Config::audit_sms( "subject"=>unmime($Audit->subject()), - "from"=>[ map({ $_=$_->address(); $_="\L$_"; $aliases{$_} || $_; } Mail::Address->parse(unmime($Audit->from()))) ], + "from"=>[ Mail::Address->parse(unmime($Audit->from())) ], "body"=>substr(body_simple(),0,$MaxBodySMS*(1+0.25*$smscount)), %args); my $texthead=""; @@ -526,17 +408,18 @@ my($folder,$profile,%args)=@_; $profile=$store_profile if !$profile; my %do=map({ (!/=/ ? ($_=>1) : ($`=>$')); } profile_eval($profile)); - Sys::Syslog::syslog("info","%s%s: %s: %s", + Sys::Syslog::syslog("info","%s%s%s: %s: %s", + (!$opt_dry ? "" : "--dry: "), (!$store_ignore ? "" : "IGNORED[$store_ignore]: "), map({ cut($_); } $folder,address_show(unmime($Audit->from())),unmime($Audit->subject())), ) - if $do{"syslog"}; + if $do{"syslog"} || $opt_dry; $folder=~s/;.*$//s; $folder="$Mail/".$' if $folder=~/^=/; push @AuditStored,$folder if $do{"did"}; - return if $store_ignore; + return if $store_ignore || $opt_dry; $DoBell++ if $do{"bell"}; - write_message($folder); + write_message($folder) or die; smssend_tryall $store_ignorenewmail,$do{"sms"},%args if $do{"sms"}; } @@ -559,6 +442,7 @@ sub write_message { my($folder)=@_; + return 1 if $opt_dry; # simulate OK local *F; open F,">>$folder" or do { warn "Append \"$folder\": $!"; return 0; }; { @@ -582,49 +466,48 @@ my($message)=@_; local $_=$_; my $save_=$_; + $message=~s/(\n)(From )/$1>$2/sg; local $Message=$message; - local $Audit=Mail::Audit->new( + # Cannot call 'local' for our-imported variable: + my $Audit_save=$Audit; + $Audit=Mail::Audit->new( "emergency"=>"$Mail/emergency", "data"=>[map("$_\n",split("\n",$message))], - "log"=>"$HOME/.lacemail.log", + "log"=>"$HOME/.perlmail.log", "loglevel"=>99, ); local @AuditStored=(); do { smssend 0,$opt_smstest; return; } if $opt_smstest; - write_message("$Mail/input"); - audit(); + write_message("$Mail/input") or die; + PerlMail::Config::audit(); warn 'Corrupted $_, repaired' if defined($save_)!=defined($_) || (defined($_) && $save_ ne $_); + # restore: + $Audit=$Audit_save; } # utility functions: # return: true (error-message or "1") if is spam -sub razor2 +sub spamassassin { - # razor-check has exit code 1 if NOT spam, code 0 if IS spam +my($cmd)=@_; + + $cmd||="$HOME/bin/spamassassin --exit-code"; + # spamassassin has exit code 1 if IS spam, code 0 if NOT spam local *CHILD; - local $SIG{"PIPE"}=sub { warn "razor2 gave me SIGPIPE: broken pipe"; }; + local $SIG{"PIPE"}=sub { warn "spamassassin gave me SIGPIPE: broken pipe"; }; # prevent Razor2's: Can't call method "log" on unblessed reference at Razor2/Client/Agent.pm line 212. local $ENV{"HOME"}=$HOME; - open CHILD,'|' - .'('.'(razor-check 2>&1;echo >&3 $?)' - .'|sed "s/^/razor-check: /"' - .'|logger -t "lacemail['.$$.']" -p mail.crit' - .') 3>&1' - .'|exit `cat`' + # 2>/dev/null to prevent error messages to corrupt inetd() output of perlmail-accept(1) + open CHILD,"|$cmd --mbox >/dev/null 2>/dev/null" or return 0; print CHILD $Message; - my $return; - { - local $/=undef(); - $return= || 1; - } - close CHILD; + my $return=close CHILD; return undef() if !WIFEXITED($?); return undef() if WIFSIGNALED($?); return undef() if WIFSTOPPED($?); - return undef() if WEXITSTATUS($?); - return $return; # is-spam + return 1 if WEXITSTATUS($?); # is-spam + return 0; # not-spam } # NOTE: returns undef() if !wantarray and the first header is unrecognized @@ -636,7 +519,8 @@ sub Received_for my($for)=($hdr=~/\bfor\s+\?\b/); return $for if !wantarray(); push @r,$for if $for; - my($from,$fromaddr)=($hdr=~/\bfrom\s+(\S+)\b.*?\[((?:\d{1,3}\.){3}\d{1,3})\]/); + my($from,$fromaddr)=($hdr=~/\bfrom\s+(?:(\S+)\b.*?)??\[((?:\d{1,3}\.){3}\d{1,3})\]/); + $from=$fromaddr if !defined $from; push @r,"$from:$fromaddr" if $from; } return @r; @@ -651,7 +535,9 @@ my($domain,$full,$timeout)=@_; $timeout||=30; # sec $Mail::Audit::MAPS::host=$domain; my @hosts=map({ s/^.*://; "[$_]"; } # strip DNS part - grep({ /^([^:@]*):/ && !$alternates_host{$1}; } (Received_for())) # leave only foreign hosts + grep({ /^([^:@]*):/ # $1 is DNS name, $' is IP address + && !$alternates_host{$1} # leave only foreign hosts + && !$dnsbl_whitelist{$'}; } (Received_for())) ); splice @hosts,1 if !$full && @hosts; # "&& @hosts" to prevent: WARN: splice() offset past end of array { @@ -665,75 +551,6 @@ my($domain,$full,$timeout)=@_; return Mail::Audit::rblcheck($self_faked,$timeout); } -our %muttrc_pending=(); -sub muttrc -{ -my($muttrc)=@_; - - $muttrc||="$HOME/.muttrc"; - $muttrc=~s/^\~/$HOME/; - do { warn "Looping muttrc, ignoring: $muttrc"; return (); } if $muttrc_pending{$muttrc}; - local $muttrc_pending{$muttrc}=1; - local *MUTTRC; - open MUTTRC,$muttrc or do { warn "open \"$muttrc\": $!"; return (); }; - local $/="\n"; - local $_; - my @r=(); - # far emulation mutt/init.c/mutt_parse_rc_line() - while () { - s/^[\s;]*//s; - s/[#;].*$//s; - s/\s*$//s; - next if !/^(\S+)\s*/s; - if ($1 eq "source") { - $_=$'; - do { warn "Wrong 'source' parameters at $muttrc:$.: $_"; next; } if !/^\S+$/; - push @r,muttrc($_); - next; - } - push @r,$_; - } - close MUTTRC or warn "close \"$muttrc\": $!"; - return wantarray() ? @r : join("",map("$_\n",@r)); -} - -my %mutteval_charmap=( # WARNING: Don't use "" or "0" here, see below for "|| warn"! - '\\'=>"\\", - 'r'=>"\r", - 'n'=>"\n", - 't'=>"\t", - 'f'=>"\f", - 'e'=>"\e", - ); -# mutt/init.c/mutt_extract_token() -sub mutteval -{ - local $_=$_[0]; - return $_ if !s/^"//; - do { warn "Missing trailing quote in: $_"; return $_; } if !s/"$//; - s/\\(.)/$mutteval_charmap{$1} || warn "Undefined '\\$1' sequence in: $_";/ges; - return $_; -} - -sub muttrc_get -{ -my(@headers)=@_; - - my @r=map({ (ref $_ ? $_ : qr/^\s*set\s+\Q$_\E\s*=\s*(.*?)\s*$/si); } @headers); - my %r=map(($_=>undef()),@r); - for (muttrc()) { - for my $ritem (@r) { - /$ritem/si or next; - $r{$ritem}=mutteval $1; - } - } - for my $var (grep { !defined($r{$_}) } @r) { - warn "Variable '$var' not found in muttrc"; - return undef(); - } - return wantarray() ? %r : $r{$r[0]}; -} - sub muttrc_aliases { my %r=(); @@ -742,26 +559,12 @@ sub muttrc_aliases for my $addrobj (Mail::Address->parse($')) { my $addr=$addrobj->address(); my $ref=\$r{"\L$addr"}; - $$ref=$key; # use always the last occurence to prefer nicks + $$ref=$key if !$$ref; # use always the first occurence to prefer nicks } } return %r; } -# FIXME: Unify -# BEGIN lacemail-sendmail -# return: Mail::Address instance or undef() -sub parseone -{ -my($line)=@_; - - return undef() if !defined $line; - my @r=Mail::Address->parse($line); - warn "Got ".scalar(@r)." addresses while wanting just one; when parsing: $line" if 1!=@r; - return $r[0]; -} -# END lacemail-sendmail - # FIXME: host may get multiple recipients and thus not showing "for <...>" # FIXME: muttrc_get("from") is too strict sub store_muttrc_alternates @@ -777,15 +580,10 @@ my($prefix,$profile)=@_; if $From!~/$alternates/si; for my $for (reverse Received_for()) { $for=~s/:.*$//; # strip IP address here - if ($Fromobj->user() ne "prog-mutt") { - next if lc($for) eq lc($From); - } - else { - my $forobj=parseone $for; - if ($forobj && $forobj->host()) { - # it is 'for' our primary address - next if lc($forobj->host()) eq lc($Fromobj->host()); # or 'return'? shouldn't matter - } + my $forobj=parseone $for; + if ($forobj && $forobj->host()) { + # it is 'for' our primary address + next if lc($forobj->host()) eq lc($Fromobj->host()); # or 'return'? shouldn't matter } next if !$alternates_host{lc $for} && $for!~/$alternatesre/si; store "$prefix\L$for",($profile || []); @@ -854,36 +652,29 @@ my($header,$map)=@_; $text=~s/\b\Q$from\E\b/$to/gsi; } return if $text eq $orig; - $Audit->put_header("X-LaceMail-header_remap-$header",$orig); + $Audit->put_header("X-PerlMail-header_remap-$header",$orig); $Audit->replace_header($header,$text); } # MAIN -my $basedir=File::Basename::dirname($0); $Getopt::Long::ignorecase=0; die "GetOptions error" if !Getopt::Long::GetOptions( "inetd" ,sub { $opt_mode=\&inetd; }, "stdin" ,sub { $opt_mode=\&stdin; }, + "single!" ,\$opt_single, + "dry" ,\$opt_dry, "smstest:s",sub { $opt_mode=\&stdin; $opt_smstest=($_[1] || 1); }, "idle!" ,\$opt_idle, "idletest" ,sub { syslogging_restore(); print((defined($_=useridle()) ? $_ : "")."\n"); exit 0; }, "muttrc" ,sub { syslogging_restore(); print scalar muttrc(); exit 0; }, - "d|basedir=s",\&basedir, ); # "Excessive arguments" checked in &inetd die "Missing mode" if !$opt_mode; -my $filenameMyAudit="$basedir/My-Audit.pm"; -open AUDIT,$filenameMyAudit or die "open \"$filenameMyAudit\": $!"; -{ - local $/=undef(); - eval or die "eval \"$filenameMyAudit\": $@"; - audit_init(); - %alternates_host=map((lc($_)=>1),@alternates_host); - } -close AUDIT or warn "close \"$filenameMyAudit\": $!"; +%alternates_host=map((lc($_)=>1),@alternates_host); +%dnsbl_whitelist=map(( $_ =>1),@dnsbl_whitelist); &$opt_mode(); die "NOTREACHED";