#!/usr/bin/perl # ----------------------------------------- # # SCack.pl v1.1 # # ----------------------------------------- # # ------------------------------------------------------------------------------------------- # # Function: # Spamcop auto-ack treatment: # - changes www.spamcop.net "finish reporting" links back to members.spamcop.net links # so the links can be used by members *without* using cookie-login; # - puts treated mails in special mailbox; any other mails (should not occur) go to # default account # # Requirements: # - main account mailbox (or "catchall") # - separate mailbox [1] that corresponds to the address SpamCop sends its auto-ack mails to # - separate mailbox [2] to receive the "fixed" auto-ack emails # - all mailboxes of "mbox format" with all mails in a single mailbox file # - set up your client to retrieve from mailbox [2] instead of [1] # # Configuration: # See section Start Configuration ... End Configuration below # # Usage (commandline): # # perl path/to/SCack.pl path/to/inbox path/to/outbox # # e.g., perl usr/local/bin/SCack.pl var/mail/mb12345 var/mail/autoack # inbox should correspond to the address SpamCop sends the auto-ack mails *to* # outbox would be a special mailbox created to receive the 'doctored' mails # Or, if you make the script executable: # # path/to/SCack.pl path/to/inbox path/to/outbox # # this makes it easier to implement it via crontab; then it becomes: # # $HOME/path/to/SCack.pl $HOME/path/to/inbox $HOME/path/to/outbox # # Copyright 2004 Marjolein Katsma (http://banspam.javawoman.com/); # feel free to adapt and distribute as long as original copyright is acknowledged and # instructions remain intact. # Developed and tested on FreeBSD; should work on other *nixes; locking may require # some adaptation on Windows. # # Version history: # 1.0 - 2004-02-25 - original release # 1.1 - 2004-03-04 - added extra SC outgoing server # 1.2 - 2004-03-25 - added extra SC outgoing server # # ------------------------------------------------------------------------------------------- # # Start Configuration ---------------------- # 1) adapt path on first line to point to location where your Perl executable lives # e.g, /usr/bin/perl or /usr/local/bin/perl # 2) adapt variable(s) below; between here and the End Configuration mark # $validack = '\(vmx1\.spamcop\.net \[206\.14\.107\.113\]\)|vmx2\.spamcop\.net.*?\[206\.14\.107\.117\]|\(victor1\.ironport\.com \[206\.14\.107\.102\]\)'; # RE for string to occur in a header to recognize whether # it's really a valid SpamCop auto-ack report; # make sure this matches the server *your* SpamCop # auto-ack reports are sent from; # escape () [] and . and use *single* quotes around the string! $catchall = 'path/to/catchall'; # location of default or "catchall" mailbox; # e.g., var/mail/account # mails that are *not* valid SpamCop auto-ack reports # (see above) are put here # # End Configuration ------------------------ # Start Data preparation ------------------- $inbox = $ARGV[0]; # get name of inbox to be processed from command line $outbox = $ARGV[1]; # get name of outbox to be written to from command line # End Data Preparation --------------------- # Main process ---------------------------------------------------------------------- open(INBOX, "+< $inbox") or die $!; # open the auto-ack inbox (input) - must exist flock(INBOX, 2) or die "can't flock $inbox: $!"; $content = 0; # assume auto-ack inbox empty $report = 0; # assume not reporting mail @mail = (); # init mail array if ($_ = ) { # if there is input push(@mail, $_); # write line to mail array $content = 1; # remember auto-ack inbox not empty } while () { # as long as there are more lines if (m/^From /) { # new mail: each mail starts with pseudo header 'From ' # write current array to mailbox &arr2mailbox; $report = 0; # assume new mail is not reporting mail push(@mail, $_); # add line to mail array } else { # check and record whether it's a valid reporting mail (origin SC mailserver) if (m/$validack/o) { $report = 1; } # if it's a valid auto-ack mail: change reporting links if ($report == 1) { s/members use cookie-login please!/LINK CHANGED to use members.spamcop.net!/; s%http://www\.spamcop\.net/sc\?id=%http://members.spamcop.net/sc?id=%; } push(@mail, $_); # add line to mail array } } if ($content) { # if auto-ack inbox was not empty # finish writing array to output &arr2mailbox; # empty input mailbox close(INBOX); # close auto-ack inbox unlink $inbox; # remove auto-ack inbox open(INBOX, "> $inbox"); # create new empty auto-ack inbox } close(INBOX); # close auto-ack inbox close(OUTBOX); # close output reporting mailbox # Subroutines ------------------------------------------------------------------------ # write current array to a mailbox sub arr2mailbox { if ($report == 1) { # valid auto-ack mail # write array to OUTBOX &arr2file ($outbox); } else { # not a reporting email (should not occur!) # write array to DEFAULT &arr2file ($catchall); } } # append mail array to specified mailbox file sub arr2file { my $mailbox = shift(@_); # get name of mailbox file my $line; # open and lock output open(MAILBOX, ">> $mailbox"); # open the mailbox (append) flock(MAILBOX, 2) or die "can't flock $mailbox: $!"; # lock file # write array to MAILBOX foreach $line (@mail) { print MAILBOX $line; } # close output close (MAILBOX); # close mailbox # re-initialize array @mail = (); # clear mail array (zero elements) }