#!/usr/bin/perl

#
# De-spam e-mail against a system-wide list
#
# spamlist file has the following format:
#      flag check
#  Flags and checks are:
#      s   Site
#          sitename
#      b   Message Body
#          CRC bytecount MD5sum
#
$MODULES="/usr/lib/despam/modules";
$DEFAULTRC="/usr/lib/despam/despamrc";
$PATTERNS="/usr/lib/despam/despam.pat";
#$debug++;
$HOME = $ENV{"HOME"};
$DESPAMRC="$HOME/.despamrc";

open(MODLIST,"ls -1 $MODULES|");
@modlist = <MODLIST>;
chomp @modlist;
close(MODLIST);
unshift (@INC,"$MODULES");

if ( -e "$DESPAMRC" )
 {
  open(RCF,"$DESPAMRC");
  while (<RCF>)
   {
    if (/^#/)
     {}
    elsif (/^KnownBlockers:\s*/)
     {
     }
    elsif (/^DontBlockBy:\s*/)
     {
      $line = $';
if ($debug)
 {
      print STDERR "Not Blocking by $line\n";
 }
      @flags = split(/\s*,\s*/,$line);
      for ($i=0; $i < scalar(@flags); $i++)
       {
        $Dont{$flags[$i]} = 1;
       }
     }
    elsif (/^Accept/)
     {
      $line = $';
      ($module) = $line =~/\{*([^}]*)\}*:\s*/;
      $line = $';
      chop $line;
      @olist = split(/\s*,\s*/,$line);
      if (!$module)
       {
if ($debug)
 {
        print STDERR "Accepting $line for all modules.\n";
 }
        foreach $mod (@modlist)
         {
          foreach $over (@olist)
           {
            $Accept[$accptr++] = "$mod.*\\.$over(?:\..*)*";
           }
         }
       }
      else
       {
if ($debug)
 {
        print STDERR "Accepting $line for $module\n";
 }
        foreach $over (@olist)
         {
          $Accept[$accptr++] = "$module.*\.$over(?:\..*)*";
         }
       }
     } 
   }
  close(RCF);
 }

#
# Tempfile setup - copy STDIN to a tempfile for later use by pre-comp
#
$tmpfile = "/tmp/despam$$";
open(TMPF,">$tmpfile");
while(<STDIN>)
 {
  print TMPF;
 }
close(TMPF);

foreach $module (@modlist)
 {
  if (!$Dont{$module})
   {
    require "$module";
    eval "${module}::Setup(\"$tmpfile\")";
    open(PATS,"ls -1 $PATTERNS/$module.*|");
    undef @pats;
    @pats = <PATS>;
    close(PATS);
    chomp @pats;
    foreach $pat (@pats)
     {
      ($filename) = $pat =~ /$module\.(.*)/;
      $dopat = 1;
      foreach $accept (@Accept)
       {
        if ("$module.$filename" =~ /$accept/)
         {
          $dopat = 0;
          last;
         }
       }
      if ($dopat)
       {
if ($debug)
 {
        print "Evaluating: $pat\n";
 }
        $return = eval "${module}::Compare(\"$pat\")";
        if ($return)
         {
          &Exit($return);
         }
       }
     }
   }
 }
&Exit(0);

sub Exit
 {
  ($excode) = @_;
  unlink $tmpfile;
  exit $excode;
 }
