Gary Funck wrote:

Looks good, below, but a couple of procmail/perl suggestions ...

(snip)


Above, the '< 500000' check, I believe, exceeds spamc/spamd's
maximum limit of 250000, so you might want to bring that in a bit. I see
you're using 100000 in the spamc invocation.



Yea, the < 500000 is just kind of a sanity check.. belt and suspenders thing. I figured that I'll short-circuit real large email from even checking the nospam.pl list. There's really no reason to have the procmail test different than the spamc limit, just left it there since the spamc limit does its job.


I'll bring it down to match... might as well avoid calling spamc if it's not going to do anything.

The script:

#!/usr/bin/perl
#
# nospam.pl -- accept username as option,
#              check a list of names, see if
#              user wants spam scanning or not
#              0 = skip scanning
#              nonzero = scan (fail "safe" so that
#                        majority of users are scanned)
# [EMAIL PROTECTED]

$userfile="/etc/spamassassin/exempt";
$found="false";



More typical Perl style would be to use 1/0 for true/false.

I used the long name for readability... since I'm not returning the value itself. Old habit from when I used to do "#define true 1" :-)



$user=$ARGV[0];

open USERS,$userfile or die "unable to open $userfile $!\n";
while (<USERS>) {
        next if ( /^#/ );
        if ( /^$user$/ ) {
                $found="true";
                last;
        };
};


Since user-ids should be considered case insentitive, you might want to
lowercase your user-id,
   $user = lc $ARGV[0];
and make sure that your list of exempt users is all lower-case as well.
The you can modify the check above to just do a straight string comparison
rather than a regex. You'll need to 'chomp' the line first to discard the
newline:

open USERS,$userfile or die "unable to open $userfile $!\n";
while (<USERS>) {
         chomp;
         next if ( /^#/ );
         return 1 if ($user eq $_);
};


I guess I was assuming that the $LOGNAME will be the correct case, and that we'll enter the correct username. I do like the string comparason better, though.


If your list gets big and you don't want to go to a more complicated
set up using DB files, you might take a look at John Connover's useful
flat file search utility:
http://www.johncon.com/ndex/

Using a DBM wouldn't be bad as far as complexity. Would actually simplify the lookup:

dbmopen %exempt, $exempt_file or die "blah blah $!";

if (defined $exempt{$user}) {
        return 1;
} else {
        return 0;
};

(to add to the list would be something like: perl -e 'dbmopen %exempt, /etc/spamassassin/exempt; $exempt{"someuser"} = 1; dbmclose %exempt' script as necessary...)

If the list gets huge, or if the volume gets large enough (more likely to happen, and more likely to impact performance), I'm thinking that I'll have to seperate into two parts, spamd/spamc style. The daemon portion would just hold the exempt list in memory (well, I'd store it as a perl hash).

I haven't profiled the code at all, but I'd guess that the overhead of opening the exemption list, along with just starting up the program, is much greater than searching the list. Sure it's an O(n) search, but the list's size is quite small.

Thanks for the input!

--Rich




Reply via email to