#!/usr/bin/perl -w
#
# sprobe_learn          --crb3 14may03/05feb04/02Apr07
#
# spamprobe script, to teach spamprobe about local mail
#
# --crb3 14may03        first full working version
# --crb3 13jun03        add in option-switches
# --crb3 16jun03        added logging to maillog
# --crb3 05feb04        switchable gzipping
# --crb3 02Apr07        cleanup options, add help
#
$debug=0;       # temp chattiness       --crb3 27jun03
$safety=0;
$chatty=0;
$shutup=0;
$killdup=1;     # true: delete sp2m/new, sp2m/cur after training

$gzipem=0;      # true: gzip /sp2m/qrm/* before moving to /qrt

$spamprobe="/usr/local/bin/spamprobe";
$dumper="/home/sp2m/Maildir/qrt";
$myname$0;
$myname =~ s/^.+\/// if(index($myname,'/')>-1);
$logger="/usr/bin/logger";              # this works in linux
$loglvl="alert";        # log in /var/log/maillog at qmail's verbosity

$basedir="/home";
$onlyuser="*";
$onlydir="*";
$onlytype="*";


while(defined($ARGV[0]) and index($ARGV[0],'-')==0){
  $arg=shift(@ARGV);                    # get any the switches
  $key=lc(substr($arg,1,1));            # get no-arg switches first
  substr($arg,0,2)="";
  if($key eq "v"){                      # verbose?
    $chatty ^= 1;
    next;
  }elsif($key eq "q"){                  # silent running?
    $shutup^=1;
    next;
  }elsif($key eq "k"){                  # kill dupes after use?
    $killdup^=1;
    next;
  }elsif($key eq "S"){                  # safety mode : pretend loudly
    $safety^=1;
    next;
  }elsif($key eq "D"){                  # debug: enable leftover tracers
    $debug^=1;
    next;
  }elsif($key eq '?'){
    print <<EOT;
  sprobe_learn  script to teach spamprobe about local mail --crb3 14may03/05feb04
        sprobe_learn [options]
   Options:
      -b /path          base of Maildir users (default: /home)
      -d dir            do only this Maildir dir (*=all)
      -k                toggle: kill dupes after use? (1=yes)
      -D                toggle: enable ad-hoc debug tracers
      -S                toggle: safety mode. pretend loudly. (off)
      -t type           spam / good only (*=all)
      -u user           only this user's stuff (*=all)
      -v                toggle: script gets more chatty
      -q                toggle: script gets silent unless error
EOT
    exit(0);
  }
  $arg =~ s/^\=//;                      # handles switch=arg
    $arg=shift(@ARGVif($arg eq "" and ($ARGV[0] !~ /^\-\w/) );
#                     # handles space-separated switch/arg
  if($key eq "b"){                      # base dir:/home, /var/vpopmail/users
    $basedir=$arg;                      #  default is /home
  }elsif($key eq "u"){                  # specify one user's stuff
    $onlyuser=$arg;
  }elsif($key eq "d"){                  # only do this dir
    $onlydir=$arg;
  }elsif($key eq "t"){                  # only do spam/good
    $onlytype=$arg;
  }else{
    warn "$0: unrecognized option -$key $arg\n";
  }
}
#
# switches all parsed, now grab anything left on the commandline.
#
$basedir = $ARGV[0if defined $ARGV[0];
$onlyuser = $ARGV[1if defined $ARGV[1];
$onlydir = $ARGV[2if defined $ARGV[2];
$onlytype = $ARGV[3if defined $ARGV[3];

print "$0: basedir $basedir user $onlyuser dir $onlydir type $onlytype\n"
        if (!$shutup);

if($onlyuser eq "*"){
  chdir $basedir;
  for(<*>){
    next unless -d;
    $hdir = $_;

    print "$hdir:\n" if ($chatty && !$shutup);

    learnem("qrm","spam");
    learnem("new","good");
    learnem("cur","good");
    learnem("sav","good");
  #  learnem("hld","good");     # a dir that's out of the way...
    learnem("arc","good");
  }
}else{                          # just one user's Maildirs
  chdir $basedir;
  $hdir = $onlyuser;
  if($onlydir eq "*"){          # dir not given: do all likely
    learnem("qrm","spam");
    learnem("new","good");
    learnem("cur","good");
    learnem("sav","good");
    learnem("arc","good");
  }else{
    if($onlytype eq "*"){       # type not given; deduce from subdir name
      if($onlydir eq "qrm" or $onlydir eq "spam"){
        learnem($onlydir,"spam");
      }else{                    # they're in /crap? use 4 args.
        learnem($onlydir,"good");
      }
    }else{                      # type is specified: use it (can be 'remove')
      learnem($onlydir,$onlytype);
    }
  }
}
# learnem.
# per-dir loop, shoves every mail in specified subdir in SpamProbe's
# face. 'type' is how SpamProbe should regard each email, as good or spam.
#
sub learnem {
  my($sdir,$type)=(@_);

  if(-d "$basedir/$hdir/Maildir/$sdir"){
    $msg="learning $type in $basedir/$hdir/Maildir/$sdir...\n";
    print $msg if ($chatty && !$shutup);
    loggit($msg);

    chdir "$basedir/$hdir/Maildir/$sdir";
    for(<*>){
      next unless -f;
      $mail=$_;
      if($mail =~ /\.gz$/){
        `gunzip $mail`;
        $mail =~ s/\.gz$//;
      }
      if($safety or $chatty){
        print "$spamprobe $type -M $mail\n";
      }
      unless($safety){
        `$spamprobe remove -M $mail`;   # --crb3 30jul04
        `$spamprobe $type -M $mail`;
        loggit("  $mail\n");
      }
      unless($sdir eq "new" or $sdir eq "cur"){
        if($gzipem){
          `gzip $mail`;
          $mail .= '.gz';
        }
      }
      if(defined($dumperand $sdir eq "qrm"){
        print "xeq in $sdir: mv $mail $dumper\n" if $debug;
        `mv $mail $dumper`;
      }
      if($hdir eq "sp2m" and ($sdir eq "new" or $sdir eq "cur"and $killdup){
        print "xeq in $sdir: rm -f $mail\n" if $debug;
        `rm -f $mail`;
      }
    }
    chdir $basedir;
  }else{
    print "no dir at $basedir/$hdir/Maildir/$sdir!\n"
        if ($chatty && !$shutup);
  }
}

sub loggit {
  my $logmsg = shift(@_);

  CORE::system("$logger -p mail.$loglvl -t $myname \"$logmsg\"");
}
Grab a
gzipped
copy
here
 
Syntax highlighting using Syntax::Highlight::Engine::Kate