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 "firstname.lastname@example.org"; 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:email@example.com nyalumni:firstname.lastname@example.org faculty-visiting:email@example.com faculty-visiting:firstname.lastname@example.org faculty-visiting:email@example.com ...
If we find a bad address (i.e., one not of the general form "firstname.lastname@example.org"), 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
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.