~ubuntu-branches/ubuntu/precise/nagios-plugins/precise-proposed

« back to all changes in this revision

Viewing changes to contrib/check_email_loop.pl

  • Committer: Bazaar Package Importer
  • Author(s): Guido Trotter
  • Date: 2004-06-15 15:37:48 UTC
  • Revision ID: james.westby@ubuntu.com-20040615153748-pq7702qdzghqfcns
Tags: upstream-1.3.1.0
ImportĀ upstreamĀ versionĀ 1.3.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
28
use Net::POP3;
 
29
use Net::SMTP;
 
30
use strict;
 
31
use Getopt::Long;
 
32
&Getopt::Long::config('auto_abbrev');
 
33
 
 
34
# ----------------------------------------
 
35
 
 
36
my $TIMEOUT = 120;
 
37
my %ERRORS = ('UNKNOWN' , '-1',
 
38
              'OK' , '0',
 
39
              'WARNING', '1',
 
40
              'CRITICAL', '2');
 
41
 
 
42
my $state = "UNKNOWN";
 
43
my ($sender,$receiver, $pophost, $popuser, $poppasswd, $smtphost);
 
44
my ($poptimeout,$smtptimeout,$pinginterval)=(60,60,5);
 
45
my ($lostwarn, $lostcrit,$pendwarn, $pendcrit);
 
46
 
 
47
# Internal Vars
 
48
my ($pop,$msgcount,@msglines,$statinfo,@messageids,$newestid);
 
49
my ($matchcount,$statfile) = (0,"check_email_loop.stat");
 
50
 
 
51
# Subs declaration
 
52
sub usage;
 
53
sub messagematchs;
 
54
sub 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
};
 
61
alarm($TIMEOUT);
 
62
 
 
63
 
 
64
# Evaluate Command Line Parameters
 
65
my $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
                        );
 
81
usage() 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
 
85
if (open STATF, "$statfile") {
 
86
  @messageids = <STATF>;
 
87
  chomp @messageids;
 
88
  close STATF;
 
89
}
 
90
 
 
91
# Try to open statfile for writing 
 
92
if (!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
 
101
my $serial = time();
 
102
$serial = "ID#" . $serial . "#$$";
 
103
 
 
104
# sending new ping email
 
105
my $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
 
 
128
nsexit("POP3 login failed (user:$popuser)",'CRITICAL') if (!defined($msgcount));
 
129
 
 
130
# Count messages, that we are looking 4:
 
131
while ($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.
 
152
if (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
 
165
foreach my $id (@messageids) {
 
166
  print STATF  "$id\n";
 
167
}
 
168
print STATF "$serial\n";     # remember send mail of this session
 
169
close STATF;
 
170
 
 
171
# ok - count lost and pending mails;
 
172
my @tmp = grep /^ID/, @messageids;
 
173
my $pendingm = scalar @tmp;
 
174
@tmp = grep /^LI/, @messageids;
 
175
my $lostm = scalar @tmp; 
 
176
 
 
177
# Evaluate the Warnin/Crit-Levels
 
178
if (defined $pendwarn && $pendingm > $pendwarn) { $state = 'WARNING'; }
 
179
if (defined $lostwarn && $lostm > $lostwarn) { $state = 'WARNING'; }
 
180
if (defined $pendcrit && $pendingm > $pendcrit) { $state = 'CRITICAL'; }
 
181
if (defined $lostcrit && $lostm > $lostcrit) { $state = 'CRITICAL'; }
 
182
 
 
183
if ((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
 
192
nsexit($statinfo);
 
193
 
 
194
# ----------------------------------------------------------------------
 
195
 
 
196
sub 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
 
 
234
sub 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
 
 
243
sub 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
# ---------------------------------------------------------------------