--- nfo/perl/libs/Mail/Audit/Dispatch.pm 2003/01/22 07:55:43 1.3 +++ nfo/perl/libs/Mail/Audit/Dispatch.pm 2003/01/30 23:20:21 1.5 @@ -5,10 +5,17 @@ # with the Perl-module "Mail::Audit" # available from CPAN. # -# $Id: Dispatch.pm,v 1.3 2003/01/22 07:55:43 joko Exp $ +# $Id: Dispatch.pm,v 1.5 2003/01/30 23:20:21 root Exp $ # # ============================================================ # $Log: Dispatch.pm,v $ +# Revision 1.5 2003/01/30 23:20:21 root +# + fixed and enhanced +# +# Revision 1.4 2003/01/22 17:58:21 root +# + fixed and enhanced many things +# - refactored code to Data::Code +# # Revision 1.3 2003/01/22 07:55:43 joko # + replaced '$HOME' with '$self->{settings}->{HOME}' # @@ -33,19 +40,20 @@ use strict; # don't use warnings; -use base qw( DesignPattern::Object ); +use base qw( + DesignPattern::Object + DesignPattern::Bridge +); +# DesignPattern::Object::Logger use Mail::Audit; use Data::Dumper; -use org::netfrag::shortcuts qw( now ); - - -my $LOG = 1; # writes reports to logfile -my $self->{options}->{VERBOSE} = 1; # writes reports to STDOUT -my $self->{options}->{TRACE} = 1; # writes contents of messages to logfile +use Data::Code::Symbol qw( export_symbols ); +use Data::Storage::Handler::File qw( a2f ); +use org::netfrag::shortcuts qw( now get_chomped run_cmd ); sub _init { @@ -54,12 +62,12 @@ $self->_override_options(); $self->_init_settings(); $self->_override_settings(); - $self->_run(); + #$self->_run(); } sub _init_options { my $self = shift; - foreach (qw( base rules LOG VERBOSE TRACE )) { + foreach (qw( user base rules LOG VERBOSE TRACE mode newsgroup )) { $self->{options}->{$_} = $self->{$_}; } } @@ -70,24 +78,27 @@ $self->{options}->{base} ||= $ENV{PWD}; } -# - - - - - - - - - - - - - - - - - - - - -# -# targets -# -# declare and initialize some variables -# these are mostly base paths -# mail should be delivered to -# -# - - - - - - - - - - - - - - - - - - - - sub _init_settings { my $self = shift; - $self->{settings}->{USER} = $ENV{USER}; - $self->{settings}->{HOME} = $self->{options}->{base}; + $self->{settings}->{USER} = $self->{options}->{user} if $self->{options}->{user}; + $self->{settings}->{USER} ||= ''; + $self->{settings}->{USER} ||= $ENV{USER}; + + $self->{settings}->{HOME} = '../var/spool/mail/' . $self->{settings}->{USER}; + $self->{settings}->{HOME} = $self->{options}->{base} if $self->{options}->{base}; + + $self->_init_settings_paths(); +} + +sub _init_settings_paths { + my $self = shift; $self->{settings}->{MAILDIR} = "$self->{settings}->{HOME}/Mail"; - $self->{settings}->{RULESFILE} = "$self->{settings}->{HOME}/.dispatchmailrc.pm"; + #$self->{settings}->{RULESFILE} = "$self->{settings}->{HOME}/.dispatchmailrc.pm"; + $self->{settings}->{RULESFILE} = "$self->{settings}->{HOME}/.dispatchmailrc"; #$self->{settings}->{LOCKFILE} = "$self->{settings}->{HOME}/.procmail.lockfile"; $self->{settings}->{LOCKFILE} = "$self->{settings}->{HOME}/.dispatchmail.lockfile"; $self->{settings}->{LOGFILE} = "$self->{settings}->{MAILDIR}/.dispatchmail.log"; + $self->{settings}->{ERRLOG} = ".dispatchmail-errors.log"; $self->{settings}->{DEFAULT} = "$self->{settings}->{MAILDIR}/Inbox"; } @@ -98,9 +109,7 @@ $self->{options}->{rules} if $self->{options}->{rules}; # change logfile $self->{settings}->{LOGFILE} = - "recievemail-emerg.log" if (! -e $self->{settings}->{MAILDIR}); - - $self->{settings}->{USER} ||= ''; + $self->{settings}->{ERRLOG} if (! -e $self->{settings}->{MAILDIR}); } @@ -109,28 +118,28 @@ # main # - - - - - - - - - - - - - - - - - - - - -sub _run { +sub run { my $self = shift; + $self->{options}->{mode} ||= 'recieve'; + my $call = '_' . $self->{options}->{mode}; + # "jump" into processing of new incoming mail and get a "handler" to this mail $self->{incoming} = Mail::Audit->new(); -} + my $result = $self->$call(@_); + return $result; - sub traceEntry { - my $self = shift; - s2f('-' x 40 . ' TRACE ' . '-' x 10); - s2f("From: " . gchomp($self->{incoming}->from)); - s2f("To: " . gchomp($self->{incoming}->to)); - s2f("Subject: " . gchomp($self->{incoming}->subject)); - s2f('-' x 40 . ' TRACE ' . '-' x 10); - } +} +sub _recieve { + my $self = shift; + # 0.a. pre flight tracing my $now = now(); - report("$0 running at $now for user '$USER'."); - traceEntry() if $self->{options}->{TRACE}; + $self->report("$now - $0 running for user '$self->{settings}->{USER}'."); + $self->traceEntry() if $self->{options}->{TRACE}; # 0.b. pre flight checks @@ -138,31 +147,32 @@ # check if $self->{settings}->{HOME} exists if (! -e $self->{settings}->{MAILDIR}) { - my $msg = "delivery failed, base directory $self->{settings}->{MAILDIR} does not exist"; - report($msg); - forward_delivery(); + my $msg = "ERROR: Delivery failed, base directory '$self->{settings}->{MAILDIR}' does not exist."; + $self->report($msg); + $self->forward_delivery(); } # 1. include rules or fallback # check if $self->{settings}->{RULESFILE} exists if (-f $self->{settings}->{RULESFILE}) { - report("Loading rules from \"$self->{settings}->{RULESFILE}\"."); + $self->report("RULES: Loading from \"$self->{settings}->{RULESFILE}\"."); require $self->{settings}->{RULESFILE}; } else { #die("$self->{settings}->{RULESFILE} doesn't exist"); - report("Configured rulesfile \"$self->{settings}->{RULESFILE}\" doesn't exist."); - forward_delivery(); + $self->report("Configured rulesfile \"$self->{settings}->{RULESFILE}\" doesn't exist."); + $self->forward_delivery(); } # 2. export required stuff to rules namespace - export_symbols(); + my @symbols = qw( jaccept report compareTarget accept copy ignore ); + export_symbols(\@symbols, 'rules'); # 3. run dispatcher - report("Running \"rules::dispatch\"."); - rules::dispatch(); + $self->report("RULES: Running Perl sub \"rules::dispatch\"."); + rules::dispatch($self); # 4. dispatcher didn't do anything - report("dispatcher could not apply any filter, using default delivery"); + $self->report("dispatcher could not apply any filter, using default delivery"); # the default-handler: simply accept all mails and route them to "/var/spool/mail" # $self->{incoming}->accept(); @@ -171,29 +181,47 @@ # $self->{incoming}->reject; # catch all mails and route them to a "DEFAULT"-inbox - jaccept($self->{settings}->{DEFAULT}); + $self->jaccept($self->{settings}->{DEFAULT}); + +} +sub _mail2news { + my $self = shift; + $self->report("MAIL2NEWS: $self->{options}->{newsgroup}"); + my $plugin = 'Newsgate'; + $self->load($plugin); + $self->$plugin($self->{options}->{newsgroup}); +} # - - - - - - - - - - - - - - - - - - - - # tracing & reporting # - - - - - - - - - - - - - - - - - - - - - sub s2f { - my $str = shift; - open(FH, '>>' . $self->{settings}->{LOGFILE}); - print FH $str, "\n"; - close(FH); + sub traceEntry { + my $self = shift; + $self->appendLog('-' x 40 . ' TRACE ' . '-' x 10); + $self->appendLog("From: " . get_chomped($self->{incoming}->from)); + $self->appendLog("To: " . get_chomped($self->{incoming}->to)); + $self->appendLog("Subject: " . get_chomped($self->{incoming}->subject)); + $self->appendLog('-' x 40 . ' TRACE ' . '-' x 10); + } + + sub appendLog { + my $self = shift; + my $msg = shift; + a2f($self->{settings}->{LOGFILE}, $msg); } sub report { + my $self = shift; my $msg = shift; # TODO: tracing, debugging - print $msg, "\n" if $self->{options}->{VERBOSE}; - if ($LOG) { - s2f($msg); + #print STDERR $msg, "\n" if $self->{options}->{VERBOSE}; + if ($self->{options}->{LOG}) { + $self->appendLog($msg); } } @@ -203,6 +231,7 @@ # - - - - - - - - - - - - - - - - - - - - sub compareTarget { + my $self = shift; my $pattern = shift; my $ok = 0; $ok = 1 if ($self->{incoming}->to =~ m/$pattern/); @@ -211,67 +240,72 @@ return $ok; } + sub accept_spool { + my $self = shift; + my $path = "/var/spool/mail/$self->{settings}->{USER}"; + $self->report("defaulting to spool delivery ($path)"); + $self->{incoming}->accept($path); + } + + sub forward_delivery { + my $self = shift; + $self->report("Forwarding delivery to next handler in queue (probably /var/spool/mail)."); + return $self->{incoming}->accept; + } + + sub jaccept { + my $self = shift; my $deliver_to = shift; - report("ACCEPT: $deliver_to"); + $self->report("ACCEPT: $deliver_to"); # check deliver_to path if (! -e $deliver_to) { - report("deliver_to path \"$deliver_to\" doesn't exist"); - forward_delivery(); - return; + my $good = 0; + $self->report("ERROR: TARGET Path/File doesn't exist."); + if ($self->{settings}->{AUTOCREATE_FOLDERS}) { + my $cmd = "touch $deliver_to"; + $self->report("TARGET: AUTOCREATE_FOLDERS is enabled: touching TARGET."); + #if (mkdir $deliver_to) { + run_cmd($cmd); + # re-test TARGET - for existance now + if (-e $deliver_to) { + $good = 1; + } else { + $self->report("ERROR: TARGET creation failed (command was: '$cmd')."); + } + } + if (!$good) { + $self->forward_delivery(); + return; + } } - $self->{incoming}->accept($deliver_to); + return $self->{incoming}->accept($deliver_to); } - sub accept_spool { - my $path = "/var/spool/mail/$USER"; - report("defaulting to spool delivery ($path)"); - $self->{incoming}->accept($path); - } - sub forward_delivery { - report("Forwarding delivery to next handler in queue (probably /var/spool/mail)."); - $self->{incoming}->accept; + sub accept { + my $self = shift; + return $self->jaccept(@_); } + sub copy { + my $self = shift; + my $plugin = shift; + my $deliver_to = shift; + + $self->report("COPY: $plugin: $deliver_to"); -# - - - - - - - - - - - - - - - - - - - - -# helper functions -# - - - - - - - - - - - - - - - - - - - - - -sub get_coderef { - my $codepack = shift; - my $method = shift; - $codepack || return '[error]'; - $method ||= ''; - $method && ($codepack .= '::'); - return eval '\&' . $codepack . $method . ';'; -} - -sub export_symbols { - # my $callpack = 'rules'; - # my @EXPORT = qw( incoming subject MAILDIR jaccept ); - # foreach my $sym (@EXPORT) { - no strict 'refs'; - # *{"${callpack}::$sym"} = get_coderef('main', $sym); - # } - { - no strict 'refs'; - *{"rules::jaccept"} = get_coderef('main', 'jaccept'); - *{"rules::report"} = get_coderef('main', 'report'); - *{"rules::compareTarget"} = get_coderef('main', 'compareTarget'); + $self->load($plugin); + return $self->$plugin($deliver_to); } - $rules::MAILDIR = $self->{settings}->{MAILDIR}; - $rules::incoming = $self->{incoming}; -} -sub gchomp { - my $str = shift; - chomp($str); - return $str; -} + sub ignore { + my $self = shift; + $self->report("IGNORE"); + return $self->{incoming}->ignore; + } 1;