The company I work for sends out alerts informing subscribers to the
online journals we host that there's a new issue. They'd been doing
this with a set of hideous scripts that perform much more database access
than necesary, and generate a large number of individual emails as a
result. On top of that, a non-trivial portion of these are undeliverable,
but the database is never updated, so the bad addresses get sent to
every time. (The previous admin here had even aliased postmaster to
/dev/null! Aiiigh!)
One of our customers wanted us to provide this service for them as
well, but was insistent on our using another mail list package to do
it. Well, I haven't spent years whipping Majordomo into shape for nothing;
I told them to give me a list of their requirements without specifying
how to do it, and I'd implement them.
When the requirements came through, the only thing that I couldn't already
handle was automatically uns*bscribing bad addresses. The customer wants
a ruthless approach - one bounce and unsub 'em, automatically. No manual
intervention, please. This ruled out the usual MD bounce method, but
did not give me an alternative, so I wrote one. I'm posting it in the
hopes it will help others in the same situation.
======================================================================
#!/usr/bin/perl
# bounce.pl
# Joe Hartley (joe.hartley@ingenta.com - work address
# jh@brainiac.com - permanent home address
# V1.0 - 27 July, 2001
#
#
# This script takes a majordomo list name and the approve_passwd for that
# list as arguments, then scans stdin (which is assumed to be a bounced
# majordomo post) for the invalid address, then unsubs that address from
# the majordomo list named.
#
# This script was designed to be part of the list-owner alias so that it
# can be invoked automatically when email bounces. Example:
# owner-foo-l: me@domain.com,"|/usr/local/majordomo/bounce.pl foo-l PhonyPW"
# Set this to the domain your majordomo runs under
$our_domain = "domain.com";
# Set this to the executable on your system
$mailer = "/bin/mail";
if ($ARGV[0]) {
$listname = $ARGV[0];
}
else {
die("No listname was specified!\n");
}
if ($ARGV[1]) {
$passwd = $ARGV[1];
}
else {
die("No password was specified for $listname!\n");
}
while (<STDIN>) {
chop;
if (/550/ || /554/) {
# We found the offending address.
# 550 is the code usually used to signify no user, but some MTAs
# (like Yahoo's) use 554.
@fields = split(/</);
while (@fields) {
$testline = pop(@fields);
$idx = index($testline, "@");
if ($idx != -1) {
$idx = index($testline, ">");
if ($idx != -1) {
# We found a closing angle bracket; this is a simple parse.
$addrline = substr($testline, 0, $idx);
}
else {
# In this case, we found the error code and an @ sign, but
# no closing bracket. This makes things more difficult, as
# the offending email address was not delimited by brackets.
# Let's break it up using the space as a delimiter, find the
# @ sign, and trim any trailing dots off the end of that line,
# since there seem to always be 3 dots after the address in
# these cases.
@f2 = split(/ /);
while (@f2) {
$t2 = pop(@f2);
$idx = index($t2, "@");
if ($idx != -1) {
$idx = index($t2, "...");
if ($idx != -1) {
$addrline = substr($t2, 0, $idx);
}
}
} # end while (@f2)
} # end else (no angle brackets)
push(@addrlist, $addrline);
} # end if(@ found in testline)
} # end while(@fields)
} # end if(550 || 554)
} # end while(<STDIN>)
# The list of addresses has been built; discard the duplicates.
# This is ugly; maybe later I'll think of a more elegant way to do this.
foreach $addr1 (@addrlist) {
$match = 0;
foreach $addr2 (@finallist) {
if ($addr1 eq $addr2) {
$match = 1;
}
}
if ($match == 0) {
# Only add addresses > 5 characters long; this stops us from trying
# to unsub an empty line.
if (length($addr1) > 5) {
push(@finallist, $addr1);
}
}
}
# Finally, send the email to majordomo
$result = open (MAIL,"|-");
die "Couldn't open pipe to mail subprocess" unless defined($result);
exec "$mailer majordomo\@$our_domain" or die "Couldn't exec mail"
if $result == 0;
for $addr (@finallist) {
print MAIL "approve $passwd unsubscribe $listname $addr\n";
}
close MAIL;
--
======================================================================
Joe Hartley - Senior Unix Admin - Dynamic Diagrams/ingenta
12 Bassett St., Providence, RI 02903 - vox 401.331-2014 x120
Joe.Hartley@ingenta.com - cell 401.338.9214
Without deviation from the norm, "progress" is not possible. - FZappa
|
|