, 2002, 2003Source code zipped w/ tools and other files
To make SPAMLESS™ work, you first have to edit your .forward file (use your username in place of "username"):
"|IFS=' ' && exec /usr/local/bin/procmail -f- || exit 75 #username"Then you need to edit your .procmailrc file:
#VERBOSE=ON ### ### Variables ### PATH=$HOME/bin:/usr/bin:/bin:/usr/local/bin MAILDIR=$HOME/Mail LOGFILE=$MAILDIR/log LOCKFILE=$HOME/.lockmail DEFAULT=/var/spool/mail/username NOCLOBBER= ### ### rules ### # first rule, don't send mail to a host that is telling # us that the spammer in question doesn't actually have an account there :0H * ^FROM_MAILER.* * ^X-SPAMLESS.* /dev/null :0H * ^FROM_MAILER.* * B ?? .*Subject: Unexpected Mail.* /dev/null # the section of "NOTs" ANDed together that allow # access by specific domain, partial name, subject line # by excluding from the script anthing that matches # these items :0Hc * !^Subject:.*hey::.* * !^From:.*myhost.com.* * !^From:.*newscientist.* * !^From:.*igc.org.* * !^From:.*palm.net.* * !^From:.*pot-tv.net.* | /home/username/spamless # endThen you have the SPAMLESS™ script itself:
#!/usr/bin/perl
$my_version="SPAMLESS 1.700";
# define some subroutines
$myargs=$ARGV[0];
if($myargs =~ "-i") { # alternate ini file
$myfilename=$ARGV[1];
}else{
$myfilename=spamless;
}
# clear junk from lines -- strip to one line
# usage string=linec(string)
#
sub linec{
$it=shift;
$itcheck=0;
while($itcheck ne $it){
$itcheck=$it;
$it =~ s/\s+/ /;
$it =~ s/[\000-\033]/ /;
$it =~ s/[ ][ ]+/ /;
}
return $it;
}
# make the time stamp for the logfile
#usage string=timeout()
#
sub timeout{
$to= ((localtime)[5]+1900) ;
$to= $to . "." . pn((localtime)[4]+1) . "." . pn((localtime)[3]) . "--" ;
$to= $to . pn((localtime)[2]) . ":" . pn((localtime)[1]) . ":" . pn((localtime)[0]);
return $to;
}
# pad a number to n digits
# usage string=padnum(number,n)
#
sub padnum{
my $retval;
my $inval=shift();
my $len=shift();
my $format="%0" . $len . "d";
$retval=sprintf $format , $inval;
return $retval;
}
# quick and dirty padnum 2
#
sub pn{
padnum(@_,2);
}
# clear out everything from an email address but the address
# usage string=mungereply(address)
#
sub mungereply{
my $val=shift;
chomp($val);
my $sv=q/ |"/; # split on space or quote
my @it=split($sv,$val);
my $retval='';
foreach $at (@it){
if($at =~ '@'){
$retval=$at; # the last @ in a line is
} # always the address
}
$retval=~ s/\<//; # clear out angle brackets
$retval=~ s/\>//;
@check=split("@",$retval);
$checklen=length($check[0]);
if($checklen>0){
return $retval;
} else {
return "BAD$retval";
}
}
# basic data buffer
@my_stdin="";
%INI;
open INIFILE, "< $myfilename.ini" or die "Can't open INI file $myfilename.ini\n";
while (<INIFILE>){
chomp();
if($_ =~ /^#/ || $_ =~ /^$/){next;}
@mystuff=split /\s*=\s*/, $_;
$INI{$mystuff[0]}=$mystuff[1];
}
close INIFILE;
# My Personal Info (from INI file)
$my_email=$INI{'EMAIL'};
$my_fullemail=$INI{'FULLEMAIL'};
# My Response Controls
$my_subject=$INI{'SUBJECT'};
$my_filter_subject=$INI{'FILTERSUBJECT'};
$my_exclude=$INI{'EXCLUDE'};
$my_autosubscribe=$INI{'AUTOSUBSCRIBE'};
# My directory and File Information
$my_homedir=$INI{'SPAMHOME'};
$my_logfile=$INI{'LOGFILE'};
$my_tempfile=$INI{'TEMPFILE'};
$my_errfile=$INI{'ERRFILE'};
$my_mail_cmd=$INI{'MAILCMD'};
$my_logthis="^(Subject:|Date:|From:|Reply-To:|To:)";
# Start the program
chdir($my_homedir);
$LOGFILE=">> $my_logfile";
$TEMPFILE="> $my_tempfile";
$ERRFILE=">> $my_errfile";
open LOGFILE or die;
open TEMPFILE or die;
$bad=0;
$sub="";
while(<STDIN>){
push @my_stdin, $_; #pack the data buffer
}
foreach $_ (@my_stdin){
if ($_ =~ /^Reply-To:/i && !$noreply)
{$reply_to=mungereply($_);}
if ($_ =~ /^From:/i && $reply_to eq '' && !$noreply)
{$reply_to=mungereply($_);}
if ($_ =~ /$my_logthis/i){
printf LOGFILE;
if($sub eq '' && $_ =~ /^Subject:/i ){
$sub=$_;
chomp($sub);
$sub=~s/^Subject: //i;
}
}
if ($_ eq "\n" ){$noreply=1;} # if we got the first empty line,
# there is no reply-to address
if ($reply_to =~ $my_exclude) { $bad = $bad | 1;}
if ($reply_to =~ $my_autosubscribe) { $bad = $bad | 2};
if ($_ =~ $my_subject) { $bad = $bad | 4;}
}
if (length($reply_to) < 6 || $reply_to =~ "^BAD") { $bad = $bad | 8;}
$sub = linec($sub);
$my_mail_template;
open MAIL_TEMPLATE, "$myfilename.template" or die "Can't Open Mail Template $myfilename.template\n";
while (<MAIL_TEMPLATE>){
$my_mail_template=$my_mail_template . $_;
}
close MAIL_TEMPLATE;
$my_mail_template =~ s/FULLEMAIL/$my_fullemail/g;
$my_mail_template =~ s/EMAIL/$my_email/g;
$my_mail_template =~ s/FILTERSUBJECT/$my_filter_subject/g;
$my_mail_template =~ s/YOURSUBJECT/$sub/g;
$my_mail_template =~ s/SUBJECT/$my_subject/g;
$my_mail_template =~ s/REPLY-TO/$reply_to/g;
$my_mail_template =~ s/SPAMLESS-VERSION/$my_version/g;
#print $my_mail_template;
print TEMPFILE $my_mail_template;
close TEMPFILE;
$sendit="$my_mail_cmd < $my_tempfile";
if($bad==0)
{
$tmp_results=`$sendit`;
$tmp_results=padnum($tmp_results,2);
$results="[SENT] [$tmp_results]";
}
else
{
if($bad & 1) { $code="BAD ";}
if($bad & 2) { $code=$code . "AUTO ";}
if($bad & 4) { $code=$code . "REDO ";}
if($bad & 8) { $code=$code . "NORT";}
$badprt=padnum($bad,2);
$results="\[$code\] [$badprt]";
}
$time_out=timeout();
$print_out="$time_out: $results to \<$reply_to\>from $ENV{'HOST'}";
if($bad != 0){
open ERRFILE or die "Oops, how do I report this???";
print ERRFILE "\n$print_out\n";
foreach $_ (@my_stdin){print ERRFILE;}
close ERRFILE;
}
printf LOGFILE $print_out . "\n\n";
close LOGFILE;
This code is copyleft under the GPL, and you are free to use
it in any way so long as you don't restrict access to it in
any way.
Here is the source code as a link
Here is the source code zipped with tools and other files as a link
So that's it. If you have questions, write me at:
writch
(leave the "Hey::" alone)
Visit my church, too: