summaryrefslogtreecommitdiffstats
path: root/contrib/check_email_loop.pl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/check_email_loop.pl')
-rw-r--r--contrib/check_email_loop.pl268
1 files changed, 268 insertions, 0 deletions
diff --git a/contrib/check_email_loop.pl b/contrib/check_email_loop.pl
new file mode 100644
index 00000000..733406da
--- /dev/null
+++ b/contrib/check_email_loop.pl
@@ -0,0 +1,268 @@
1#!/usr/bin/perl
2#
3# (c)2000 Benjamin Schmid, blueshift@gmx.net (emergency use only ;-)
4# Copyleft by GNU GPL
5#
6#
7# check_email_loop Nagios Plugin
8#
9# This script sends a mail with a specific id in the subject via
10# an given smtp-server to a given email-adress. When the script
11# is run again, it checks for this Email (with its unique id) on
12# a given pop3 account and send another mail.
13#
14#
15# Example: check_email_loop.pl -poph=mypop -popu=user -pa=password
16# -smtph=mailer -from=returnadress@yoursite.com
17# -to=remaileradress@friend.com -pendc=2 -lostc=0
18#
19# This example will send eacht time this check is executed a new
20# mail to remaileradress@friend.com using the SMTP-Host mailer.
21# Then it looks for any back-forwarded mails in the POP3 host
22# mypop. In this Configuration CRITICAL state will be reached if
23# more than 2 Mails are pending (meaning that they did not came
24# back till now) or if a mails got lost (meaning a mail, that was
25# send later came back prior to another mail).
26#
27
28use Net::POP3;
29use Net::SMTP;
30use strict;
31use Getopt::Long;
32&Getopt::Long::config('auto_abbrev');
33
34# ----------------------------------------
35
36my $TIMEOUT = 120;
37my %ERRORS = ('UNKNOWN' , '-1',
38 'OK' , '0',
39 'WARNING', '1',
40 'CRITICAL', '2');
41
42my $state = "UNKNOWN";
43my ($sender,$receiver, $pophost, $popuser, $poppasswd, $smtphost);
44my ($poptimeout,$smtptimeout,$pinginterval)=(60,60,5);
45my ($lostwarn, $lostcrit,$pendwarn, $pendcrit);
46
47# Internal Vars
48my ($pop,$msgcount,@msglines,$statinfo,@messageids,$newestid);
49my ($matchcount,$statfile) = (0,"check_email_loop.stat");
50
51# Subs declaration
52sub usage;
53sub messagematchs;
54sub nsexit;
55
56# Just in case of problems, let's not hang Nagios
57$SIG{'ALRM'} = sub {
58 print ("ERROR: $0 Time-Out $TIMEOUT s \n");
59 exit $ERRORS{"UNKNOWN"};
60};
61alarm($TIMEOUT);
62
63
64# Evaluate Command Line Parameters
65my $status = GetOptions(
66 "from=s",\$sender,
67 "to=s",\$receiver,
68 "pophost=s",\$pophost,
69 "popuser=s",\$popuser,
70 "passwd=s",\$poppasswd,
71 "poptimeout=i",\$poptimeout,
72 "smtphost=s",\$smtphost,
73 "smtptimeout=i",\$smtptimeout,
74 "statfile=s",\$statfile,
75 "interval=i",\$pinginterval,
76 "lostwarr=i",\$lostwarn,
77 "lostcrit=i",\$lostcrit,
78 "pendwarn=i",\$pendwarn,
79 "pendcrit=i",\$pendcrit,
80 );
81usage() if ($status == 0 || ! ($pophost && $popuser && $poppasswd &&
82 $smtphost && $receiver && $sender ));
83
84# Try to read the ids of the last send emails out of statfile
85if (open STATF, "$statfile") {
86 @messageids = <STATF>;
87 chomp @messageids;
88 close STATF;
89}
90
91# Try to open statfile for writing
92if (!open STATF, ">$statfile") {
93 nsexit("Failed to open mail-ID database $statfile for writing",'CRITICAL');
94}
95
96# Ok - check if it's time to release another mail
97
98# ...
99
100# creating new serial id
101my $serial = time();
102$serial = "ID#" . $serial . "#$$";
103
104# sending new ping email
105my $smtp = Net::SMTP->new($smtphost,Timeout=>$smtptimeout)
106 || nsexit("SMTP connect timeout ($smtptimeout s)",'CRITICAL');
107($smtp->mail($sender) &&
108 $smtp->to($receiver) &&
109 $smtp->data() &&
110 $smtp->datasend("To: $receiver\nSubject: E-Mail Ping [$serial]\n\n".
111 "This is a automatically sended E-Mail.\n".
112 "It ist not intended for human reader.\n\n".
113 "Serial No: $serial\n") &&
114 $smtp->dataend() &&
115 $smtp->quit
116 ) || nsexit("Error delivering message",'CRITICAL');
117
118# no the interessting part: let's if they are receiving ;-)
119
120$pop = Net::POP3->new( $pophost,
121 Timeout=>$poptimeout)
122 || nsexit("POP3 connect timeout (>$poptimeout s, host: $pophost)",'CRITICAL');
123
124$msgcount=$pop->login($popuser,$poppasswd);
125
126$statinfo="$msgcount mails on POP3";
127
128nsexit("POP3 login failed (user:$popuser)",'CRITICAL') if (!defined($msgcount));
129
130# Count messages, that we are looking 4:
131while ($msgcount > 0) {
132 @msglines = @{$pop->get($msgcount)};
133
134 for (my $i=0; $i < scalar @messageids; $i++) {
135 if (messagematchsid(\@msglines,$messageids[$i])) {
136 $matchcount++;
137 # newest received mail than the others, ok remeber id.
138 $newestid = $messageids[$i] if ($messageids[$i] > $newestid || !defined $newestid);
139 $pop->delete($msgcount); # remove E-Mail from POP3 server
140 splice @messageids, $i, 1;# remove id from List
141 last; # stop looking in list
142 }
143 }
144
145 $msgcount--;
146}
147
148$pop->quit(); # necessary for pop3 deletion!
149
150# traverse through the message list and mark the lost mails
151# that mean mails that are older than the last received mail.
152if (defined $newestid) {
153 $newestid =~ /\#(\d+)\#/;
154 $newestid = $1;
155 for (my $i=0; $i < scalar @messageids; $i++) {
156 $messageids[$i] =~ /\#(\d+)\#/;
157 my $akid = $1;
158 if ($akid < $newestid) {
159 $messageids[$i] =~ s/^ID/LI/; # mark lost
160 }
161 }
162}
163
164# Write list to id-Database
165foreach my $id (@messageids) {
166 print STATF "$id\n";
167}
168print STATF "$serial\n"; # remember send mail of this session
169close STATF;
170
171# ok - count lost and pending mails;
172my @tmp = grep /^ID/, @messageids;
173my $pendingm = scalar @tmp;
174@tmp = grep /^LI/, @messageids;
175my $lostm = scalar @tmp;
176
177# Evaluate the Warnin/Crit-Levels
178if (defined $pendwarn && $pendingm > $pendwarn) { $state = 'WARNING'; }
179if (defined $lostwarn && $lostm > $lostwarn) { $state = 'WARNING'; }
180if (defined $pendcrit && $pendingm > $pendcrit) { $state = 'CRITICAL'; }
181if (defined $lostcrit && $lostm > $lostcrit) { $state = 'CRITICAL'; }
182
183if ((defined $pendwarn || defined $pendcrit || defined $lostwarn
184 || defined $lostcrit) && ($state eq 'UNKNOWN')) {$state='OK';}
185
186
187# Append Status info
188$statinfo = $statinfo . ", $matchcount mail(s) came back,".
189 " $pendingm pending, $lostm lost.";
190
191# Exit in a Nagios-compliant way
192nsexit($statinfo);
193
194# ----------------------------------------------------------------------
195
196sub usage {
197 print "check_email_loop 1.0 Nagios Plugin - Real check of a E-Mail system\n";
198 print "=" x 75,"\nERROR: Missing or wrong arguments!\n","=" x 75,"\n";
199 print "This script sends a mail with a specific id in the subject via an given\n";
200 print "smtp-server to a given email-adress. When the script is run again, it checks\n";
201 print "for this Email (with its unique id) on a given pop3 account and sends \n";
202 print "another mail.\n";
203 print "\nThe following options are available:\n";
204 print " -from=text email adress of send (for mail returnr on errors)\n";
205 print " -to=text email adress to which the mails should send to\n";
206 print " -pophost=text IP or name of the POP3-host to be checked\n";
207 print " -popuser=text Username of the POP3-account\n";
208 print " -passwd=text Password for the POP3-user\n";
209 print " -poptimeout=num Timeout in seconds for the POP3-server\n";
210 print " -smtphost=text IP oder name of the SMTP host\n";
211 print " -smtptimeout=num Timeout in seconds for the SMTP-server\n";
212 print " -statfile=text File to save ids of messages ($statfile)\n";
213# print " -interval=num Time (in minutes) that must pass by before sending\n"
214# print " another Ping-mail (gibe a new try);\n";
215 print " -lostwarn=num WARNING-state if more than num lost emails\n";
216 print " -lostcrit=num CRITICAL \n";
217 print " -pendwarn=num WARNING-state if more than num pending emails\n";
218 print " -pendcrit=num CRITICAL \n";
219 print " Options may abbreviated!\n";
220 print " LOST mails are mails, being sent before the last mail arrived back.\n";
221 print " PENDING mails are those, which are not. (supposed to be on the way)\n";
222 print "\nExample: \n";
223 print " $0 -poph=host -pa=pw -popu=popts -smtph=host -from=root\@me.com\n ";
224 print " -to=remailer\@testxy.com -lostc=0 -pendc=2\n";
225 print "\nCopyleft 19.10.2000, Benjamin Schmid\n";
226 print "This script comes with ABSOLUTELY NO WARRANTY\n";
227 print "This programm is licensed under the terms of the ";
228 print "GNU General Public License\n\n";
229 exit $ERRORS{"UNKNOWN"};
230}
231
232# ---------------------------------------------------------------------
233
234sub nsexit {
235 my ($msg,$code) = @_;
236 $code=$state if (!defined $code);
237 print "$code: $msg\n" if (defined $msg);
238 exit $ERRORS{$code};
239}
240
241# ---------------------------------------------------------------------
242
243sub messagematchsid {
244 my ($mailref,$id) = (@_);
245 my (@tmp);
246 my $match = 0;
247
248 # ID
249 $id =~ s/^LI/ID/; # evtl. remove lost mail mark
250 @tmp = grep /Subject: E-Mail Ping \[/, @$mailref;
251 chomp @tmp;
252 if (($tmp[0] =~ /$id/))
253 { $match = 1; }
254
255 # Sender:
256# @tmp = grep /^From:\s+/, @$mailref;
257# if (@tmp && $sender ne "")
258# { $match = $match && ($tmp[0]=~/$sender/); }
259
260 # Receiver:
261# @tmp = grep /^To: /, @$mailref;
262# if (@tmp && $receiver ne "")
263# { $match = $match && ($tmp[0]=~/$receiver/); }
264
265 return $match;
266}
267
268# ---------------------------------------------------------------------