"John P. Rouillard" <rouilj@cs.umb.edu> writes:
#
# In message <9406282124.AA13848@us4rmc.pko.dec.com>, Jim Reisert --
# MLO5-2/36A -- DTN 223-5747 28-Jun-1994 1724 writes:
#
# >I have 1.92. I'm using resend. Is there a way to handle bounces
# >automatically - i.e. if a message bounces, have MajorDomo automatically
# >move the address from the list to the bounces list? Or does it all have to
# >be done by hand (i.e. by sending a BOUNCE command to MajorDomo)?
#
# The short answer is no, sorry.
#
# (Standing out on limb) I claim there will never be a program invented
# that can decipher the crap that some mailers pass back as a bounced
# message. I have had numberous messages where the address that caused
# the bounce wasn't even given in the message. I had to resort to
# analyzing the Received: header lines to try to figure out what was
# going on.
#
# Not only that, but the multitude of formats for bounce messages is
# just rediculous. How may of us have <F1> keys on your keyboards that
# work right anyway. (The previous line was a reference to a thread on this
# list and the list-managers list about a certain mail program that said
# to hit <F1> to get more info about the bounced mail message.)
#
# -- John
# John Rouillard
#
# Senior Systems Consultant (SERL Project) University of Massachusetts at Boston
# rouilj@cs.umb.edu (preferred) Boston, MA, (617) 287-6480
# ==============================================================================
# My employers don't acknowledge my existence much less my opinions.
I used to think the same way, but now I'm not so sure... I'm up to
several _hundred_ bounces a day for Firewalls; I've _got_ to do
something...
I started looking at the bounces, and realized that some very large
fraction of them (80% or more) are generated by a handful of different
mailers (sendmail, sendmail v8, mmdf, etc.). I think that for any
list, a large percentage of the bounces are going to be generated by
your own mailer, as the result of host unknown or user unknown
problems when your mailer tried to send the message outbound.
I've started playing with the idea of an extensible system to deal
with bounces. Basicly, bounces would go to a perl script. The perl
script would be a framework that applied a series of "recognizer"
subroutines to the bounce. Each recognizer subroutine would be
written to recognize one particular bounce format, and to extract the
email addresses from that format. Each recognizer subroutine would be
in a seperate file in a particular directory; you could add more
routines just by adding files to the directory, and we could trade
them like trading cards, without having to modify the base program.
The base program would simply apply the various recognizer routines
until one of them signalled a match, and forward the message to the
list owner if none of them matched.
I've been thinking of having the base program, instead of immediately
bouncing the address in question, log the address to a file. Each
line in this file would list the problem address, the date/time it was
detected, which recognizer detected it, and the filename of the bounce
(I'd save each incoming bounced message in a seperate file, much like
a news spool or an MH folder, and flush them after a few days; that
way, I could go back and look at the bounce if I questioned one of the
recognizer actions). Then, nightly, I'd run something against this
log that decided who to bounce according to some policy (i.e., more
than N bounces, or bounces on more than N of the last M days, or
whatever).
I've written the basic code from the framework (i.e., it applies the
recognizers to a list of files, and tells you what recognizers matched
what addresses in which files, though not yet in the log format I
mentioned above) and a recognizer for sendmail v8, and the idea
appears workable. I'll append what I've got, so that maybe somebody
else can run with the idea; I don't know when I'll have time to work
on it further...
-Brent
--
Brent Chapman | Great Circle Associates | Call or email for info about
Brent@GreatCircle.COM | 1057 West Dana Street | upcoming Internet Security
+1 415 962 0841 | Mountain View, CA 94041 | Firewalls Tutorial dates
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: grok grok.dir
# Wrapped by brent@mycroft on Wed Jun 29 10:33:55 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'grok' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'grok'\"
else
echo shar: Extracting \"'grok'\" \(2308 characters\)
sed "s/^X//" >'grok' <<'END_OF_FILE'
X#!/usr/local/bin/perl
X
require("getopts.pl");
require("mailstuff.pl");
X
X# Comments on routines in mailstuff.pl:
X#
X# ParseMailHeader breaks out the header into an % array
X# indexed by a lower-cased keyword, e.g.
X# &ParseMailHeader(STDIN, *Array);
X# use $Array{'subject'}
X#
X# Note that some duplicate lines (like "Received:") will get joined
X# into a single entry in %Array; use @Array if you want them separate
X# $Array will contain the unprocessed header, with embedded
X# newlines
X# @Array will contain the header, one line per entry
X
X$folder = "+fo";
X$list = "firewalls";
X$scripts = <~/grok.dir>;
X
X$usage = "Usage: grok [-d dir] [-l list] [+folder]";
X&Getopts("d:l:") || die("$usage\nAborting");
X
X$| = 1;
X
if ($opt_d) {
X $scripts = $opt_d;
X}
X
if ($opt_l) {
X $list = $opt_l;
X}
X
if ($#ARGV == $[) {
X $folder = shift(@ARGV);
X if ($folder !~ /^\+.+/) {
X die("$usage\nAborting");
X }
X} elsif ($#ARGV > $[) {
X die("$usage\nAborting");
X}
X
print "# setup_scripts\n";
X&setup_scripts;
X
print "# mhpath\n";
X$dir = `mhpath $folder`;
X$dir =~ s/\n$//;
X
print "# files\n";
opendir(DIR, $dir) || die("opendir(DIR, \"$dir\"): $!\nAborting");
X
foreach (readdir(DIR)) {
X if (! /^\d+$/) {
X next;
X }
X push(@files, "$dir/$_");
X}
X
closedir(DIR);
X
X# print "# sort\n";
X# @msgs = sort msg_sort @files;
X
X@msgs = @files;
X
print "# process\n";
foreach (@msgs) {
X &process($_);
X}
X
sub msg_sort {
X local($at, $bt);
X
X $at = $a;
X $at =~ s,.*/,,;
X
X $bt = $b;
X $bt =~ s,.*/,,;
X
X return($at <=> $bt);
X}
X
sub setup_scripts {
X opendir(SCRIPTS, $scripts) || die("opendir(SCRIPTS, \"$scripts\"): $!");
X foreach (readdir(SCRIPTS)) {
X if (/^\./) { next; }
X push(@scripts, $_);
X require("$scripts/$_");
X }
X closedir(SCRIPTS);
X}
X
sub process {
X local($file) = shift;
X local(@r);
X local($n);
X
X undef(*hdrs);
X undef(%hdrs);
X undef($hdrs);
X undef(@hdrs);
X
X open(FILE, $file) || die("open(FILE, \"$file\"): $!");
X
X &ParseMailHeader(FILE, *hdrs);
X
X undef(@body);
X
X while (<FILE>) {
X push(@body, $_);
X }
X
X close(FILE);
X
X foreach (@scripts) {
X @r = &$_;
X if ($r[$[] eq "") {
X undef(@r);
X print "- $file $_\n";
X } else {
X print "+ $file $_\n";
X foreach $n (@r) {
X print "$n\n";
X }
X last;
X }
X }
X}
END_OF_FILE
if test 2308 -ne `wc -c <'grok'`; then
echo shar: \"'grok'\" unpacked with wrong size!
fi
chmod +x 'grok'
# end of 'grok'
fi
if test ! -d 'grok.dir' ; then
echo shar: Creating directory \"'grok.dir'\"
mkdir 'grok.dir'
fi
echo shar: End of shell archive.
exit 0
Follow-Ups:
|
|