Mailman
[posted 2001/04/19]
Here's another alarm script we wrote recently with a few interesting new twists:
///////////////////////////////////////////////////////////////////////////////
#if mailmanserver
MailmanAddressesChkWarning
init
status active
level warning
task "Report ill-formed Mailman addresses."
input file "=mmusers"
seps ":"
dat $list 1
dat $addr 2
begin // because this takes quite a while, and so as not to
// pester the mailman-owner (or list owners) too much,
// check on tuesdays only
if ! =tuesday
quit
fi
// we could send warning messages to the list owners, i.e.,
// =mailmsg(bad address\, please fix, $inlin, $list-owner\@egbdf)
// but list owners are often clueless and might not discern
// what's wrong with any given address (e.g., has whitespace);
// so we just uniformly report to mailman-owner; we don't
// report to both to avoid confusion
// eventually, we might invoke remove_members to
// remove bad addresses automatically, but for now it's
// best to let the mailman-owner do it (e.g., remove the
// bad address and add back a corrected address, where the
// correction is humanly obvious but hard to script)
# ifdef test
set $recipient = "pikt-test\@egbdf"
# elsedef
set $recipient = "mailman-owner\@egbdf"
// or: set $recipient = "$list-owner\@egbdf"
// or perhaps even send to one or the other depending
// on the clarity of the problem
# endifdef
rule // addresses with whitespace
if $addr =~ "[[:space:]]"
=outputmail $inlin
=mailmsg(bad address\, please fix, $inlin, $recipient)
next
fi
rule // addresses not of the form "foo@bar"
if #split($addr, "@") != 2
=outputmail $inlin
=mailmsg(bad address\, please fix, $inlin, $recipient)
next
fi
set $acct = $1
set $site = $2
rule // addresses of the form "@bar"
if $acct eq ""
=outputmail $inlin
=mailmsg(bad address\, please fix, $inlin, $recipient)
next
fi
rule // addresses not of the form "foo@bar.fly"; by implication,
// includes addresses of the form "foo@"
if #split($site, ".") !> 1
=outputmail $inlin
=mailmsg(bad address\, please fix, $inlin, $recipient)
next
fi
#endif // mailmanserver
///////////////////////////////////////////////////////////////////////////////
The file =mmusers (generated by the FindMailmanAddressesAdmin script; not shown) has contents like this:
... nyalumni:bill@newyork.net nyalumni:hillary@newyork.net faculty-visiting:lary@moscow.uppity.edu faculty-visiting:moe@moscow.uppity.edu faculty-visiting:curly@moscow.uppity.edu ...
If we find a bad address (i.e., one not of the general form "foo@bar.fly"), we possibly (depending on whether verbose is #define'd as TRUE; see the configs_samples/defines.cfg) send it, all at once in a single alert message, using
=outputmail $inlin
We send individual e-mail messages using
=mailmsg(bad address\, please fix, $inlin, $recipient)
where =mailmsg() is a new macro defined (in macros.cfg) as:
///////////////////////////////////////////////////////////////////////////////
mailmsg(S, M, R) // e-mail a one-line message (M) with subject (S)
// to recipient (R)
// sample use: =mailmsg(bad address, $inlin, $list\-owner)
=execwait "echo '(M)' | =mailx -s '(S)' (R)"
///////////////////////////////////////////////////////////////////////////////
Note the similarity to the =page() macro described earlier:
///////////////////////////////////////////////////////////////////////////////
page(M, R, H) // send a page message (M) to recipients (pager phone alias)
// (R) but only during hours (H)
// sample use: =page($host is sick/down,
=pagesysadmins, =allhours)
if (H)
=execwait "echo '(M)' | =mailx -s '(M)' (R)"
fi
///////////////////////////////////////////////////////////////////////////////
In the =mailmsg() call, we have to backslash the first comma, i.e., "bad address\, please fix", because otherwise we would be passing four arguments to the macro, but =mailmsg() only accepts three. Note, too, that in the macro call, we don't enclose text with quotes (""), given how we defined =mailmsg().
Since we optionally send all bad addresses in one e-mail message to this script's usual e-mail recipient (we have it set to pikt-warning), why have the separate =mailmsg() calls, sending one bad address e-mail at a time? The reason is that if we ever switch to sending to list owners, we need to discriminate between recipients on a case-by-case basis.
I hope this discussion is clear.
For more examples, see Developer's Notes.