1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
#!/usr/bin/perl
#
# mailloop.monitor - sends email to mailboxes that are expected to send
# the mail back to the sender. Probably not hard to do with procmail, etc.
# I've only used a reflector agent for Lotus Notes. Instead of "hosts" in
# a hostgroup, use email addresses you want to send bounce tests to. The
# code still refers to these as hosts.
#
# You can use as many addresses as you'd like, but you'll need to use a
# unique from address for each hostgroup that calls this monitor, because
# it eats all the mail this running copy of the monitor didn't send.
# Otherwise, previously delayed mail might lay around forever.
#
# The monitor then polls a POP3 account for the mail it sent. Don't use
# that mailbox for anything else, the monitor will delete all your mail!
# I'm not kidding, I didn't say "might", it *will*.
#
# This monitor assumes the local sendmail knows how to get the mail to
# the the first relay in the loop you're testing. It also assumes that
# the last host knows to deliver mail sent to the configured from
# address so that it shows up in the POP server we poll.
#
# Takes 5 options:
# -d Debug Mode. Not really compatible with normal mon scheduling,
# because it doesn't log to syslog or anything, just print to STDOUT.
# You'll have to call the monitor by hand to use this option.
# Mostly helpful to debug your POP/SMTP setup.
#
# -f Set the from address, this option will also set the POP user to
# all the bits before the '@'. So, don't do any wild aliasing...
#
# -p Set the POP password. Defaults to null password
#
# -s Set the POP server. Defaults to localhost.
#
# -t Standard monitor timeout option.
#
#
# $Id: mailloop.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $
#
# Copyright 2000 Shared Medical Systems, Inc.
# Author: Bill Smargiassi
# Email: william.smargiassi@smed.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
use Getopt::Std;
use Mail::Sendmail;
use POSIX;
use Mail::POP3Client;
sub dbgprint {
my ($str) = @_;
print $str, "\n" if $DEBUG;
}
# "check sum of tests left", not to be confused with a checksum :)
sub checksum {
my $sum;
$sum = 0;
foreach $id (keys %check) {
$sum += $check{$id};
}
dbgprint "sum is " . $sum;
return $sum;
}
sub diefailures {
my $hosts, @parts;
$hosts = '';
foreach $id (keys %check) {
if ($check{$id}) {
@parts = split(/ /, $id);
$hosts .= $parts[0];
}
}
dbgprint "hosts is " . $hosts;
print $hosts, "\n";
exit 1;
}
getopts("df:p:s:t:");
$Timeout = $opt_t || 900;
$hostname = `hostname`;
$fromaddr = "mailloop\@$hostname";
# popname is inferred from fromaddr if set with -f opt
$popname = 'mailloop';
if ($opt_f) {
$fromaddr = $opt_f;
@parts = split(/\@/, $opt_f);
$popname = $parts[0];
}
$poppass = $opt_p || 'mailloop';
$popserv = $opt_s || 'localhost';
$DEBUG = $opt_d || 0;
dbgprint "Timeout = $Timeout";
$failures = "";
foreach $reflect (@ARGV) {
# Send some mail to the reflector address
$id = "$reflect " . strftime("%Y%m%d%H%M%S", localtime(time));
dbgprint "Sending mail: $id";
%mail = ( To => $reflect,
From => $fromaddr,
Message => "REFL: $id"
);
# remember the id for later POP retrieval
$check{$id} = 1;
if (sendmail %mail) { }
else { $failures .= "Error sending mail: $Mail::Sendmail::error " }
}
dbgprint "Done sending mail";
if ($failures) {die $failures}
local $SIG{TERM} = \&diefailures;
$starttime = time;
# look for replies
$pop = new Mail::POP3Client( USER => $popname,
PASSWORD => $poppass,
HOST => $popserv,
DEBUG => $DEBUG);
while(checksum()) {
if ((time - $starttime) > $Timeout) {
diefailures();
}
sleep(30);
dbgprint "Logging in...";
$pop->Connect;
dbgprint "There are " . $pop->Count . " messages";
for ($i = 1; $i <= $pop->Count; $i++) {
$id = "";
@lines = split(/\n/, $pop->Body($i));
foreach $line (@lines) {
dbgprint $line;
if ($line =~ m/REFL: (\S+ \d+)/g) {
$id = $1;
dbgprint "Found: $id";
}
}
$check{$id} = 0;
$pop->Delete($i);
}
dbgprint "Logging out";
$pop->Close;
}
exit 0;
|