[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.