[Prev][Next][Index][Thread]
mailing list bounce manager
Go down 36 lines for the README.
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1996-08-28 23:29 EDT by <root@xxxxxxxxxxxxx>.
# Source directory was `/var/qmail/alias'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 2030 -rw-rw-r-- README
# 447 -rwxr-xr-x decbounces
# 1427 -rwxr-xr-x incbounces
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
echo 'WARNING: not restoring timestamps. Consider getting and'
echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
# ============= README ==============
if test -f 'README' && test X"$1" != X"-c"; then
echo 'x - skipping README (file already exists)'
else
echo 'x - extracting README (text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
Here's my qmail bounce manager, version 0.0. It's in the public domain.
This version (pretty clearly the first :) is mostly to give other
people a chance to run it. It's not finished software. Your comments
are solicited.
X
It consists of two Perl programs, decbounces, and incbounces.
X
The first, decbounces, gets mail sent to the mailing list. It decrements
everybody's bounce counter. To make sure that any program errors come
back to me, it's forwarded via a LIST-bounces address that's
subscribed to the list.
X
The second, incbounces, gets run whenever a bounce arrives at
LIST-owner-default. It increments the bouncer's counter by two. It
also deals with local qmail bounces, which contain a list of bouncing
addresses. If the bounce count gets up to fifty (chosen arbitrarily),
it forges an email message from them to LIST-request, unsubscribing
them.
X
Setup (assuming that you already have a list called LIST):
X
Create an alias LIST-bounce. Subscribe it to the list. Run decbounces
from it like this:
X |./decbounces .qmail-LIST
X
Create an alias LIST-owner-default. Run incbounces from it like this:
X |./incbounces LIST $EXT
X
Create a directory off the home directory called "bounces".
X
Weaknesses:
X
X o Some MTAs send delay warnings. These have to be filtered out by
X recognizing that they're a delay, not a bounce. If they weren't
X filtered out, then those users would be unsubscribed artificially
X early. Unfortunately, they're filtered out using a heuristic of
X matching against certain magic strings.
X
X o Compuserve sometimes sends two messages for each bounce, one for
X the reason and another to return the mail. They have the same
X message-id, so there's some hope of recognizing them.
X
X o The bounce counter system doesn't take the daily traffic of the
X list into account. Sometimes people will be gone for a week's
X vacation, regardless of the traffic on the list, and you would
X like for them to stay on the list for that whole week.
X
Russell Nelson
nelson@xxxxxxxxxx
X
SHAR_EOF
$shar_touch -am 0828232896 'README' &&
chmod 0664 'README' ||
echo 'restore of README failed'
shar_count="`wc -c < 'README'`"
test 2030 -eq "$shar_count" ||
echo "README: original size 2030, current size $shar_count"
fi
# ============= decbounces ==============
if test -f 'decbounces' && test X"$1" != X"-c"; then
echo 'x - skipping decbounces (file already exists)'
else
echo 'x - extracting decbounces (text)'
sed 's/^X//' << 'SHAR_EOF' > 'decbounces' &&
#!/usr/bin/perl
# Version 0.0. Put into the public domain by Russell Nelson, <nelson@xxxxxxxxxx>
X
while(<>) {
X chomp;
X s/@/=/;
X next if !/^&(.*)/;
X $fn = "bounces/$1";
X next if !-e $fn;
X open(HIST, "+<$fn") || die "Cannot open $fn even though it exists";
X flock(HIST, 2) || die "Cannot flock $fn";
X $count = <HIST>;
X if ($count == 1) {
X close(HIST);
X unlink($fn);
X } else {
X seek(HIST, 0, 0);
X print HIST ($count-1)."\n";
X close(HIST);
X }
}
SHAR_EOF
$shar_touch -am 0828230696 'decbounces' &&
chmod 0755 'decbounces' ||
echo 'restore of decbounces failed'
shar_count="`wc -c < 'decbounces'`"
test 447 -eq "$shar_count" ||
echo "decbounces: original size 447, current size $shar_count"
fi
# ============= incbounces ==============
if test -f 'incbounces' && test X"$1" != X"-c"; then
echo 'x - skipping incbounces (file already exists)'
else
echo 'x - extracting incbounces (text)'
sed 's/^X//' << 'SHAR_EOF' > 'incbounces' &&
#!/usr/bin/perl
# Version 0.0. Put into the public domain by Russell Nelson, <nelson@xxxxxxxxxx>
X
sub incaddr {
X $addr = shift;
X $fn = "bounces/$addr";
X if (-e $fn) {
X open(HIST, "+<$fn") || die "Cannot open $fn for read/write";
X flock(HIST, 2) || die "Cannot flock $fn";
X $count = <HIST>;
X seek(HIST, 0, 0);
X } else {
X open(HIST, ">$fn") || die "Cannot create $fn";
X flock(HIST, 2) || die "Cannot flock $fn";
X }
X $count += 2;
X print "incbounces: $addr is at $count\n";
X print HIST "$count\n";
X close(HIST);
X if ($count > 50) {
X $addr =~ s/=([^=]*)$/\@$1/;
X print "unsubscribing\n";
X open(MAIL, "|/var/qmail/bin/qmail-inject") || die "can't run qmail-inject";
X print MAIL "From: $addr\n".
X "To: quickcam-drivers-request\n".
X "Subject: unsubscribe due to excessive bounces\n" || die "can't write";
X close MAIL || die "qmail-inject returned an error";
X unlink $fn;
X }
}
X
$list = shift;
$_ = shift;
m/$list-owner-(.*)/ || die "doesn't match the list name";
$addr = $2;
if ($addr) {
X while(<>) {
X exit 0 if /THIS IS A WARNING MESSAGE ONLY/;
X exit 0 if /Subject: WARNING: message delayed at/;
X exit 0 if /Subject: Warning From uucp/;
X }
X incaddr($addr);
} else {
X $/="";
X $_=<>; # get rid of the email header.
X $_=<>; # get the QSBMF
X /^Hi. This is the/ || die "This is not a qmail bounce message";
X while(<>) {
X last if /^-/;
X /^<(.*)>/ || die "No recipient address";
X incaddr($1);
X }
}
SHAR_EOF
$shar_touch -am 0828231296 'incbounces' &&
chmod 0755 'incbounces' ||
echo 'restore of incbounces failed'
shar_count="`wc -c < 'incbounces'`"
test 1427 -eq "$shar_count" ||
echo "incbounces: original size 1427, current size $shar_count"
fi
exit 0
-russ <nelson@xxxxxxxxxx> http://www.crynwr.com/~nelson
Crynwr Software sells packet driver support | PGP ok
521 Pleasant Valley Rd. | +1 315 268 1925 voice | Corporations persuade;
Potsdam, NY 13676 | +1 315 268 9201 FAX | governments coerce.