attached is the "diff -u" between mon 0.99.2-6 and the version which
david nolan sent to me. if someone would like to merge them into the
most recent -devel version, test it all to be sure it works, and then
post their results, then i'm sure it would be appreciated.

this is a matter of historical record which should be public. rather
than post his patched version to the mailing list for everyone to have a
gander at and do something with if they chose, he sent them only to me
(afaik), and since then i've been implicated as the reason why those
patches haven't been distributed to anyone else. i don't think that's
the right way to make progress, so i'm posting the diff between what he
sent to me and the closest release to it at the time, which is 0.99.2.

--- mon 2001-09-08 09:42:05.000000000 -0400
+++ /home/trockij/mon/patches/mon-nolan-2.0     2003-06-04 10:14:59.000000000 -0400
@@ -4,7 +4,7 @@
 #
 # Jim Trocki, [EMAIL PROTECTED]
 #
-# $Id: mon 1.27 Sat, 08 Sep 2001 09:42:05 -0400 trockij $
+# $Id: mon,v 2.0 2002/09/27 12:53:43 vitroth Exp $
 #
 # Copyright (C) 1998 Jim Trocki
 #
@@ -25,7 +25,7 @@
 #
 use strict;
 
-my $RCSID='$Id: mon 1.27 Sat, 08 Sep 2001 09:42:05 -0400 trockij $';
+my $RCSID='$Id: mon,v 2.0 2002/09/27 12:53:43 vitroth Exp $';
 my $AUTHOR='[EMAIL PROTECTED]';
 my $RELEASE='$ProjectVersion: mon-0-99-2.6 $';
 
@@ -65,6 +65,7 @@
 sub debug;
 sub debug_dir;
 sub dep_ok;
+sub dep_summary;
 sub depend;
 sub dhmstos;
 sub die_die;
@@ -184,7 +185,7 @@
 
 my ($FL_MONITOR, $FL_UPALERT,                  # alert type flags
        $FL_TRAP, $FL_TRAPTIMEOUT,
-       $FL_STARTUPALERT, $FL_TEST);
+       $FL_STARTUPALERT, $FL_TEST, $FL_REDISTRIBUTE);
 
 my $TRAP_PDU;
 my (%ALERTHASH, %MONITORHASH);                 # hash of pathnames for
@@ -198,7 +199,7 @@
 #
 # argument parsing
 #
-getopts ("fhlMSvda:A:b:B:c:D:i:L:m:O:o:p:P:r:s:t:", \%opt);
+getopts ("fhMSvda:A:b:B:c:D:i:l:L:m:O:o:p:P:r:s:t:", \%opt);
 
 #
 # these two things can be taken care of without
@@ -343,7 +344,18 @@
 #
 # load previously saved state
 #
-load_state ("disabled") if ($opt{"l"});
+if (exists $opt{"l"}) {
+    if ($opt{"l"}) {
+       # If -l was given an argument (all, disabled, opstatus, etc...)
+       # pass that to load_state
+       load_state($opt{"l"});
+    }else{
+       # Otherwise default to old behavior of just loading disabled 
hosts/services/groups
+       load_state("disabled");
+    }
+}
+
+
 
 syslog ('info', "mon server started");
 
@@ -369,7 +381,7 @@
            #
            # skip over disabled watch
            #
-           next if ($watch_disabled{$group} == 1);
+           next if (exists $watch_disabled{$group} && $watch_disabled{$group} == 1);
 
            foreach my $service (keys %{$watch{$group}}) {
 
@@ -384,7 +396,7 @@
                if ($sref->{"traptimeout"}) {
                    $sref->{"_trap_timer"} -= $t;
 
-                   if ($sref->{"_trap_timer"} <= 0 && $tm - $sref->{"_last_uptrap"} >
+                   if ($sref->{"_trap_timer"} <= 0 && $tm - $sref->{"_last_trap"} >
                                $sref->{"traptimeout"}) {
                        $sref->{"_trap_timer"} = $sref->{"traptimeout"};
                        handle_trap_timeout ($group, $service);
@@ -411,16 +423,18 @@
                {
                    if (!$CF{"MAXPROCS"} || $procs < $CF{"MAXPROCS"})
                    {
-                       if ($sref->{"exclude_period"} ne "" &&
-                               inPeriod (time, $sref->{"exclude_period"}))
+                       if (defined $sref->{"exclude_period"} 
+                           && $sref->{"exclude_period"} ne "" &&
+                           inPeriod (time, $sref->{"exclude_period"}))
                        {
                            debug (1, "not running $group,$service because of 
exclude_period\n");
                        }
 
-                       elsif ($sref->{"dep_behavior"} eq "m" &&
-                               $sref->{"depend"} ne "")
+                       elsif (($sref->{"dep_behavior"} eq "m" &&
+                               defined $sref->{"depend"} && $sref->{"depend"} ne "")
+                              || (defined $sref->{"monitordepend"} && 
$sref->{"monitordepend"} ne "")) 
                        {
-                           if (dep_ok ($sref))
+                           if (dep_ok ($sref, 'm'))
                            {
                                run_monitor ($group, $service);
                            }
@@ -509,9 +523,28 @@
     my $tmnow = time;
 
     #
+    # if redistribute it set, call it now
+    #
+    if ($sref->{"redistribute"} ne '') 
+    {
+       my ($fac, $args);
+       ($fac, $args) = split (/\s+/, $sref->{"redistribute"}, 2);
+       call_alert (
+                   group       => $group,
+                   service     => $service,
+                   output      => $output,
+                   retval      => $retval,
+                   flags       => $flags | $FL_REDISTRIBUTE,
+
+                   alert       => $fac,
+                   args        => $args,
+                  )
+    }
+
+    #
     # if the alarm is disabled, ignore it
     #
-    if ($sref->{"disable"} == 1)
+    if (defined $sref->{"disable"} && $sref->{"disable"} == 1)
     {
        syslog ("notice", "ignoring alert for $group,$service");
        return;
@@ -521,9 +554,9 @@
     # dependency check
     #
     if (!($flags & $FL_STARTUPALERT) &&
-           !($flags & $FL_UPALERT) &&
-           defined $sref->{"depend"} &&
-           $sref->{"dep_behavior"} eq "a")
+       !($flags & $FL_UPALERT) &&
+       ((defined $sref->{"depend"} && $sref->{"dep_behavior"} eq "a")
+        || (defined $sref->{"alertdepend"})))
     {
        if (!$sref->{"_depend_status"})
        {
@@ -543,7 +576,7 @@
     }
 
     my ($summary) = split("\n", $output);
-    $summary = "(NO SUMMARY)" if ($summary =~ /^\s*$/m);
+    $summary = "(NO SUMMARY)" if (!defined $summary || $summary =~ /^\s*$/m);
 
     #
     # check each time period for pending alerts
@@ -563,6 +596,7 @@
        #
        if (!$pref->{"no_comp_alerts"} && ($flags & $FL_UPALERT) && 
!$pref->{"_alert_sent"})
        {
+           syslog ('info', "$group/$service/$periodlabel: Suppressing upalert since 
no down alert was sent.");
            next;
        }
 
@@ -577,6 +611,7 @@
            if ($pref->{"numalerts"} &&
                     $pref->{"_alert_sent"} >= $pref->{"numalerts"})
            {
+               syslog ('info', "$group/$service/$periodlabel: Suppressing alert since 
numalerts is met.");
                next;
            }
 
@@ -596,15 +631,18 @@
                    )
                )
            {
-               syslog ("info", "not alerting for failure of $group/$service");
+               syslog ('info', "$group/$service/$periodlabel: Suppressing alert for 
now due to alertevery.");
+
                next;
-           }
+            } 
 
            #
            # alertafter NUM
            #
            if (defined $pref->{"alertafter_consec"})
            {
+               syslog ('info', "$group/$service/$periodlabel: Suppressing alert for 
now due to alertafter consecutive failures.") if ($sref->{"_consec_failures"} < 
$pref->{"alertafter_consec"});
+
                next if ($sref->{"_consec_failures"} < $pref->{"alertafter_consec"});
            }
 
@@ -616,6 +654,8 @@
                $pref->{'_1stfailtime'} = $tmnow if $pref->{'_1stfailtime'} == 0;
                if ($tmnow - $pref->{'_1stfailtime'} <= $pref->{'alertafterival'})
                {
+                   syslog ('info', "$group/$service/$periodlabel: Suppressing alert 
for now due to alertafter numval.");
+
                    next;
                }
            }
@@ -630,6 +670,8 @@
                if ($tmnow - $pref->{'_1stfailtime'} <= $pref->{'alertafterival'} &&
                    $pref->{"_failcount"} < $pref->{"alertafter"})
                {
+                   syslog ('info', "$group/$service/$periodlabel: Suppressing alert 
for now due to alertafter num timeval.");
+
                    next;
                }
 
@@ -648,6 +690,7 @@
 
                if ($pref->{"_failcount"} < $pref->{"alertafter"})
                {
+                   syslog ('info', "$group/$service/$periodlabel: Suppressing alert 
for now due to alertafter num timeval.");
                    next;
                }
            }
@@ -712,6 +755,7 @@
         {
             if( (($FL_TRAP | $flags) && ($FL_UPALERT & $flags)) ) {
                $pref->{"_alert_sent"} = 0;
+               $pref->{"_last_alert"} = 0;
             }
             else {
                 $pref->{"_alert_sent"}++;
@@ -972,7 +1016,7 @@
                $new_CF{"DEP_RECUR_LIMIT"} = $2;
 
            } elsif ($1 eq "dep_behavior") {
-               if ($2 ne "m" && $2 ne "a") {
+               if ($2 ne "m" && $2 ne "a" && $2 ne "hm") {
                    close (CFG);
                    return "cf error: unknown dependency behavior '$2', line 
$line_num";
                }
@@ -1163,6 +1207,7 @@
                $sref->{"service"} = $args;
                $sref->{"interval"} = undef;
                $sref->{"randskew"} = 0;
+               $sref->{"redistribute"} = "";
                $sref->{"dep_behavior"} = $DEP_BEHAVIOR;
                $sref->{"exclude_period"} = "";
                $sref->{"exclude_hosts"} = {};
@@ -1177,6 +1222,7 @@
                $sref->{"_last_failure"} = 0 if (!defined($sref->{"_last_failure"}));
                $sref->{"_last_success"} = 0 if (!defined($sref->{"_last_success"}));
                $sref->{"_last_trap"} = 0 if (!defined($sref->{"_last_trap"}));
+               $sref->{"_last_traphost"} = '' if 
(!defined($sref->{"_last_traphost"}));
                $sref->{"_exitval"} = "undef" if (!defined($sref->{"_exitval"}));
                $sref->{"_last_check"} = undef;
                $sref->{"_depend_status"} = undef;
@@ -1397,6 +1443,11 @@
                    # valid
                }
 
+               elsif ($var eq "redistribute")
+               { 
+                   # valid
+               }
+
                elsif ($var eq "allow_empty_group")
                {
                    # valid
@@ -1436,7 +1487,7 @@
                
                elsif ($var eq "dep_behavior")
                {
-                   if ($args ne "m" && $args ne "a")
+                   if ($args ne "m" && $args ne "a" && $args ne "hm")
                    {
                        close (CFG);
                        return "cf error: unknown dependency behavior '$args' (syntax: 
dep_behavior = {m|a}), line $line_num";
@@ -1448,6 +1499,21 @@
                    $args =~ s/SELF:/$watchgroup:/g;
                }
 
+               elsif ($var eq "alertdepend")
+               {
+                   $args =~ s/SELF:/$watchgroup:/g;
+               }
+
+               elsif ($var eq "monitordepend")
+               {
+                   $args =~ s/SELF:/$watchgroup:/g;
+               }
+
+               elsif ($var eq "hostdepend")
+               {
+                   $args =~ s/SELF:/$watchgroup:/g;
+               }
+
                elsif ($var eq "exclude_hosts")
                {
                    my $ex = {};
@@ -1458,10 +1524,13 @@
                    $args = $ex;
                }
 
-               elsif ($var eq "exclude_period" && inPeriod (time, $args) == -1)
-               {
-                   close (CFG);
-                   return "cf error: malformed exclude_period '$args' (the specified 
time period is not valid as per Time::Period::inPeriod), line $line_num";
+               elsif ($var eq "exclude_period") 
+                {
+                   if (inPeriod (time, $args) == -1)
+                   {
+                       close (CFG);
+                       return "cf error: malformed exclude_period '$args' (the 
specified time period is not valid as per Time::Period::inPeriod), line $line_num";
+                   }
                }
 
                else
@@ -1555,7 +1624,7 @@
     }
 
     $procs = 0;
-
+    save_state ("all") if ($keepstate);
     syslog ('info', "resetting, and re-reading configuration $CF{CF}");
 
     if ((my $err = read_cf ($CF{"CF"}, 1)) ne "") {
@@ -1569,7 +1638,7 @@
     $fdset_rbits = $fdset_ebits = '';
     set_last_test ();
     randomize_startdelay() if ($CF{"RANDSTART"});
-    load_state ("disabled") if ($keepstate);
+    load_state ("all") if ($keepstate);
     if ($CF{"DTLOGGING"}) {
        init_dtlog();
     }
@@ -1639,7 +1708,7 @@
     my ($fl);
 
     $fl = '';
-    fcntl ($fh, F_GETFL, $fl)          || return;
+    $fl = fcntl ($fh, F_GETFL, $fl)          || return;
     $fl |= O_NONBLOCK;
     fcntl ($fh, F_SETFL, $fl)          || return;
 
@@ -1768,6 +1837,7 @@
     $|=1;
     select (STDOUT);
 
+    $clients{$fno}->{"host"} = inet_ntoa($addr);
     $clients{$fno}->{"fhandle"} = $CLIENT;
     $clients{$fno}->{"user"} = undef;          # username if authenticated
     $clients{$fno}->{"timeout"} = $CF{"CLIENT_TIMEOUT"};
@@ -1868,7 +1938,7 @@
        # Check each for of authentication in order, and stop checking
        # as soon as we get a positive authentication result.
        foreach $authtype (@authtypes) {
-           if (defined auth ($authtype, $user, $pass)) {
+           if (defined auth ($authtype, $user, $pass, $clients{$cl}->{"host"})) {
                $is_auth = 1;
                last;
            }
@@ -1944,6 +2014,7 @@
                sock_write ($fh,  "$group $service not defined\n");
            } else {
                $watch{$group}->{$service}->{"_timer"} = 0;
+               $watch{$group}->{$service}->{"_next_check"} = 0;
            }
            sock_write ($fh,  "220 test monitor completed\n");
        
@@ -2152,7 +2223,7 @@
        # list status of all services
        #
        } elsif ($cmd eq "opstatus") {
-           if ($args eq "")
+           if (!defined $args || $args eq "")
            {
                foreach $group (keys %watch) {
                    foreach $service (keys %{$watch{$group}}) {
@@ -2202,11 +2273,12 @@
                }
            }
            foreach $group (keys %watch) {
-               if ($watch_disabled{$group} == 1) {
+               if (exists $watch_disabled{$group} && $watch_disabled{$group} == 1) {
                    sock_write ($fh,  "watch $group\n");
                }
                foreach $service (keys %{$watch{$group}}) {
-                   if ($watch{$group}->{$service}->{'disable'} == 1) {
+                   if (defined $watch{$group}->{$service}->{'disable'} 
+                       && $watch{$group}->{$service}->{'disable'} == 1) {
                        sock_write ($fh,  "watch $group service " .
                            "$service\n");
                    }
@@ -2417,7 +2489,7 @@
 
        } else {
            $sref->{"_ack"} = 1;
-           $sref->{"_ack_comment"} =
+           $sref->{"_ack_comment"} = $clients{$cl}->{"user"} . ": " .
                    un_esc_str ((parse_line ('\s+', 0, $comment))[0]);
            sock_write ($fh,  "220 ack completed\n");
        }
@@ -2542,7 +2614,7 @@
     # check auth
     #
     } elsif ($cmd eq "checkauth") {
-       split(' ',$args);
+       @_ = split(' ',$args);
        $cmd = $_[0];
        $user = $clients{$cl}->{"user"};
        #  Note that we call check_auth without syslogging here.
@@ -2573,6 +2645,9 @@
     my $summary        = esc_str ($sref->{"_last_summary"}, 1);
     my $detail = esc_str ($sref->{"_last_detail"}, 1);
     my $depend = esc_str ($sref->{"depend"}, 1);
+    my $hostdepend     = esc_str ($sref->{"hostdepend"}, 1);
+    my $monitordepend  = esc_str ($sref->{"monitordepend"}, 1);
+    my $alertdepend    = esc_str ($sref->{"alertdepend"}, 1);
     my $monitor        = esc_str ($sref->{"monitor"}, 1);
 
     my $comment;
@@ -2588,24 +2663,25 @@
        $alerts_sent += $sref->{"periods"}->{$period}->{"_alert_sent"};
     }
 
-    my $buf =
-       "group=$group" . 
-       " service=$service" .
-       " opstatus=$sref->{_op_status}" .
-       " last_opstatus=$sref->{_last_op_status}" .
-       " exitval=$sref->{_exitval}" .
-       " timer=$sref->{_timer}" .
-       " last_success=$sref->{_last_success}" .
-       " last_trap=$sref->{_last_trap}" .
-       " last_check=$sref->{_last_check}" .
-       " ack=$sref->{_ack}" .
-       " ackcomment='$comment'" .
-       " alerts_sent=$alerts_sent" .
-       " depstatus=" . int ($sref->{"_depend_status"}) .
-       " depend='$depend'" .
-       " monitor='$monitor'" .
-       " last_summary='$summary'" .
-       " last_detail='$detail'";
+    my $buf = "group=$group service=$service opstatus=$sref->{_op_status}";
+    $buf .= " last_opstatus=" . (defined $sref->{_last_op_status} ? 
$sref->{_last_op_status} : "");
+    $buf .= " exitval=" . (defined $sref->{_exitval} ? $sref->{_exitval} : "");
+    $buf .= " timer=" . (defined $sref->{_timer} ? $sref->{_timer} : "");
+    $buf .= " last_success=" . (defined $sref->{_last_success} ? 
$sref->{_last_success} : "");
+    $buf .= " last_trap=" . (defined $sref->{_last_trap} ? $sref->{_last_trap} : "");
+    $buf .= " last_traphost=" . (defined $sref->{_last_traphost} ? 
$sref->{_last_traphost} : "");
+    $buf .= " last_check=" . (defined $sref->{_last_check} ? $sref->{_last_check} : 
"");
+    $buf .= " ack=" . (defined $sref->{_ack} ? $sref->{_ack} : "");
+    $buf .= " ackcomment='$comment'";
+    $buf .= " alerts_sent=$alerts_sent";
+    $buf .= " depstatus=" . (defined $sref->{"_depend_status"} ? int 
($sref->{"_depend_status"}) : "");
+    $buf .= " depend='$depend'";
+    $buf .= " hostdepend='$hostdepend'";
+    $buf .= " monitordepend='$monitordepend'";
+    $buf .= " alertdepend='$alertdepend'";
+    $buf .= " monitor='$monitor'";
+    $buf .= " last_summary='$summary'";
+    $buf .= " last_detail='$detail'";
 
     $buf .= " last_failure=$sref->{_last_failure}"
        if ($sref->{"_last_failure"});
@@ -2722,6 +2798,7 @@
        exit (1);
     }
 
+    print N "Mon starting at ".localtime(time)."\n";
     if (!open(STDOUT, ">&N") ||
         !open (STDIN, "<&N") ||
        !open (STDERR, ">&N")) {
@@ -2738,7 +2815,7 @@
 sub debug {
     my ($level, @l) = @_;
 
-    return if ($level > $opt{"d"});
+    return if (!defined $opt{"d"} || $level > $opt{"d"});
 
     if ($opt{"d"} && !$opt{"f"}) {
        print STDERR @l;
@@ -2791,10 +2868,11 @@
 
        $sref->{"_last_checked"} = $tmnow;
 
-       if ($sref->{"depend"} ne "" &&
-               $sref->{"dep_behavior"} eq "a")
+       if ((defined $sref->{"depend"} && $sref->{"depend"} ne "" &&
+            $sref->{"dep_behavior"} eq "a") 
+           || (defined $sref->{"alertdepend"} && $sref->{"alertdepend"} ne ""))
        {
-           dep_ok ($sref);
+           dep_ok ($sref, 'a');
        }
 
        #
@@ -2833,7 +2911,7 @@
            # change interval if needed
            #
            if (defined ($sref->{"failure_interval"}) &&
-                       $sref->{"_old_interval"} == undef)
+                       !defined $sref->{"_old_interval"})
            {
                $sref->{"_old_interval"} = $sref->{"interval"};
                $sref->{"interval"} = $sref->{"failure_interval"};
@@ -2854,19 +2932,21 @@
                write_dtlog ($sref, $group, $service);
            }
 
+           set_op_status ($group, $service, $STAT_OK);
+
            #
            # if this service has just come back up and
            # we are paying attention to this event,
            # let someone know
            #
-           if (defined ($sref->{"_op_status"}) &&
-                   $sref->{"_op_status"} == $STAT_FAIL)
-           {
-               if (defined($sref->{"_upalert"}) && $tmnow - $sref->{"_first_failure"} 
>=
-                       $sref->{"upalertafter"})
-               {
-                   do_alert ($group, $service, $sref->{"_last_output"}, 0, 
$FL_UPALERT);
-               }
+           if (($sref->{"redistribute"} ne '') ||
+               ((defined ($sref->{"_op_status"})) &&
+                ($sref->{"_op_status"} == $STAT_FAIL) &&
+                (defined($sref->{"_upalert"})) && 
+                ($tmnow - $sref->{"_first_failure"} 
+                 >= $sref->{"upalertafter"})))
+            {
+                   do_alert ($group, $service, $ibufs{$runningpid{$p}}, 0, 
$FL_UPALERT);
            }
 
            $sref->{"_ack"} = 0;
@@ -2875,6 +2955,7 @@
            $sref->{"_last_failure"} = 0;
            $sref->{"_consec_failures"} = 0;
            my ($summary, $detail) = split("\n", $ibufs{$runningpid{$p}}, 2);
+           $sref->{"_failure_output"} = "";
            $sref->{"_last_summary"} = $summary;
            $sref->{"_last_detail"} = $detail;
 
@@ -2891,7 +2972,7 @@
            # change interval back to original
            #
            if (defined ($sref->{"failure_interval"}) &&
-                       $sref->{"_old_interval"} != undef)
+                       defined $sref->{"_old_interval"})
            {
                $sref->{"interval"} = $sref->{"_old_interval"};
                $sref->{"_old_interval"} = undef;
@@ -2899,7 +2980,6 @@
            }
 
            $sref->{"_last_success"} = $tmnow;
-           set_op_status ($group, $service, $STAT_OK);
        }
 
        #
@@ -3026,6 +3106,24 @@
            @ghosts = @g;
        }
 
+       #
+       # per-host dependencies
+       #
+       if ((defined $sref->{"depend"} && $sref->{"depend"} ne "" && 
$sref->{"dep_behavior"} eq 'hm')
+           || (defined $sref->{"hostdepend"} && $sref->{"hostdepend"} ne ""))
+       {
+           my @g = ();
+           my $sum = dep_summary($sref);
+
+           for (my $i=0; $i<@ghosts; $i++)
+           {
+               push (@g, $ghosts[$i])
+                   if (! grep /\Q$ghosts[$i]\E/, @$sum);
+           }
+
+           @ghosts = @g;
+       }
+
        @args = (quotewords ('\s+', 0, $monitor), @ghosts);
     }
 
@@ -3051,12 +3149,12 @@
            foreach $v (keys %{$sref->{"ENV"}}) {
                $ENV{$v} = $sref->{"ENV"}->{$v};
            }
-           $ENV{"MON_LAST_SUMMARY"} = $sref->{"_last_summary"};
-           $ENV{"MON_LAST_OUTPUT"} = $sref->{"_last_output"};
-           $ENV{"MON_LAST_FAILURE"} = $sref->{"_last_failure"};
-           $ENV{"MON_FIRST_FAILURE"} = $sref->{"_first_failure"};
-           $ENV{"MON_DEPEND_STATUS"} = $sref->{"_depend_status"};
-           $ENV{"MON_LAST_SUCCESS"} = $sref->{"_last_success"};
+           $ENV{"MON_LAST_SUMMARY"} = $sref->{"_last_summary"} if (defined 
$sref->{"_last_summary"});
+           $ENV{"MON_LAST_OUTPUT"} = $sref->{"_last_output"} if (defined 
$sref->{"_last_output"});
+           $ENV{"MON_LAST_FAILURE"} = $sref->{"_last_failure"} if (defined 
$sref->{"_last_failure"});
+           $ENV{"MON_FIRST_FAILURE"} = $sref->{"_first_failure"} if (defined 
$sref->{"_first_failure"});
+           $ENV{"MON_DEPEND_STATUS"} = $sref->{"_depend_status"} if (defined 
$sref->{"_depend_status"});
+           $ENV{"MON_LAST_SUCCESS"} = $sref->{"_last_success"} if (defined 
$sref->{"_last_success"});
            $ENV{"MON_STATEDIR"} = $CF{"STATEDIR"};
            $ENV{"MON_LOGDIR"} = $CF{"LOGDIR"};
            exec @args or syslog ('err', "could not exec '@args': $!")
@@ -3205,7 +3303,7 @@
     my $found = undef;
 
     foreach my $g (keys %groups) {
-       if ($cmd == 0) {
+       if ((!defined $cmd) || $cmd == 0) {
            if (grep (s/^$h$/*$h/, @{$groups{$g}}))
            {
                $found = 1;
@@ -3263,11 +3361,12 @@
                }
            }
            foreach $group (keys %watch) {
-               if ($watch_disabled{$group} == 1) {
+               if (exists $watch_disabled{$group} && $watch_disabled{$group} == 1) {
                    print STATE "disable watch $group\n";
                }
                foreach $service (keys %{$watch{$group}}) {
-                   if ($watch{$group}->{$service}->{'disable'} == 1) {
+                   if (defined $watch{$group}->{$service}->{'disable'} 
+                       && $watch{$group}->{$service}->{'disable'} == 1) {
                        print STATE "disable service $group $service\n";
                    }
                }
@@ -3281,10 +3380,19 @@
            }
            foreach $group (keys %watch) {
                foreach $service (keys %{$watch{$group}}) {
-                   print STATE "group=$group service=$service" .
-                       " op_status=$watch{$group}->{$service}->{_op_status}" .
-                       " failure_count=$watch{$group}->{$service}->{_failure_count}" .
-                       " alert_count=\n";
+                   print STATE "group=$group\tservice=$service";
+                   foreach my $var (qw(op_status failure_count alert_count 
last_success 
+                                       consec_failures last_failure first_failure 
last_summary 
+                                       last_detail ack ack_comment last_trap 
last_traphost exitval 
+                                       last_check last_op_status)) {
+                       print STATE "\t$var=" . 
esc_str($watch{$group}->{$service}->{"_$var"});
+                   }
+                   foreach my $periodlabel (keys 
%{$watch{$group}->{$service}->{periods}}) {
+                       foreach my $var (qw(last_alert alert_sent 1stfailtime 
failcount)) {
+                           print STATE "\t$periodlabel:$var=" . 
esc_str($watch{$group}->{$service}{periods}{$periodlabel}{"_$var"});
+                       }
+                   }
+                   print STATE "\n";
                }
            }
            close (STATE);
@@ -3301,7 +3409,7 @@
     my ($l, $cmd, $args, $group, $service, $what, $state);
 
     foreach $state (@states) {
-       if ($state eq "disabled") {
+       if ($state eq "disabled" || $state eq "all") {
            if (!open (STATE, "$CF{STATEDIR}/disabled")) {
                syslog ("err", "could not read state file: $!");
                next;
@@ -3329,6 +3437,32 @@
            syslog ("info", "state '$state' loaded");
            close (STATE);
        }
+
+       if ($state eq "opstatus" || $state eq "all") {
+           if (!open (STATE, "$CF{STATEDIR}/opstatus")) {
+               syslog ("err", "could not read state file: $!");
+               next;
+           }
+
+           while (defined ($l = <STATE>)) {
+               chomp $l;
+               my %opstatus = map{ /^(.*)=(.*)$/; $1 => $2} split (/\t/, $l,);
+               next unless (exists $opstatus{group} && exists 
$watch{$opstatus{group}} 
+                            && exists $opstatus{service} && exists 
$watch{$opstatus{group}}->{$opstatus{service}});
+
+               foreach my $op (keys %opstatus) {
+                   next if ($op eq 'group' || $op eq 'service');
+                   if ($op =~ /^(.*):(.*)$/) {
+                       next unless exists 
$watch{$opstatus{group}}->{$opstatus{service}}{periods}{$1};
+                       
$watch{$opstatus{group}}->{$opstatus{service}}{periods}{$1}{"_$2"} = 
un_esc_str($opstatus{$op});
+                   } else {
+                       $watch{$opstatus{group}}->{$opstatus{service}}{"_$op"} = 
un_esc_str($opstatus{$op});
+                   }
+               }
+           }
+           syslog ("info", "state '$state' loaded");
+           close (STATE);
+       }
     }
 }
 
@@ -3337,11 +3471,11 @@
 # authenticate a login
 #
 sub auth {
-    my ($type, $user, $plaintext) = @_;
+    my ($type, $user, $plaintext, $host) = @_;
     my ($pass, %u, $l, $u, $p);
 
 
-    if ($user eq "" || $plaintext eq "") {
+    if ($user eq "" || ($type ne 'trustlocal' && $plaintext eq "")) {
        syslog ('err', "an undef username or password supplied");
        return undef;
     }
@@ -3397,6 +3531,11 @@
        my $res = $pamh->pam_authenticate ;
        return undef if ($res != &Authen::PAM::PAM_SUCCESS) ;
        return 1;
+    } elsif ($type eq "trustlocal") {
+      # We're configured to trust all authentications from localhost
+      # i.e. cgi scripts are handling authentication themselves
+      return undef if ($host ne "127.0.0.1");
+      return 1;
     } else {
        syslog ('err', "authentication type '$type' not known");
     }
@@ -3471,13 +3610,16 @@
                # allow traps from all hosts
                #
 
-           } elsif ($host =~ /^[a-z]/ && ($host = gethostbyname ($host)) eq "") {
-               syslog ('err', "invalid host in $CF{AUTHFILE}, line $.");
-               next;
-           } elsif ($host =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ &&
-                       ($host = inet_aton ($host)) eq "") {
-               syslog ('err', "invalid host in $CF{AUTHFILE}, line $.");
-               next;
+           } elsif ($host =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
+               if (($host = inet_aton ($host)) eq "") {
+                   syslog ('err', "invalid host in $CF{AUTHFILE}, line $.");
+                   next;
+               }
+           } elsif ($host =~ /^[A-Z\d][[A-Z\.\d\-]*[[A-Z\d]+$/i) {
+               if (($host = inet_aton ($host)) eq "") {
+                   syslog ('err', "invalid host in $CF{AUTHFILE}, line $.");
+                   next;
+               }
            } else {
                syslog ('err', "invalid host in $CF{AUTHFILE}, line $.");
                next;
@@ -3485,9 +3627,10 @@
 
            if ($host ne "*")
            {
-               $host = inet_ntoa ($host);
+               $host = inet_ntoa ($host);              
            }
 
+           syslog ('notice', "Adding trap auth of: $host $user $password");
            $AUTHTRAPS{$host}{$user} = $password;
 
        } elsif ($sect eq "snmptrap") {
@@ -3742,7 +3885,13 @@
     
     else
     {
-       $traphost = $addr;
+       $traphost = $fromip;
+    }
+
+    if (!defined ($AUTHTRAPS{$traphost}))
+    {
+       syslog ('err', "received trap from unauthorized host: $fromip");
+       return undef;
     }
 
     if (defined ($AUTHTRAPS{$traphost}{"*"}))
@@ -3757,18 +3906,14 @@
        $trappass = $trap{"pas"};
     }
 
-    if (!defined ($AUTHTRAPS{$traphost}))
-    {
-       syslog ('err', "received trap from unauthorized host: $fromip");
-       return undef;
-    }
-
-    if ($trapuser ne "*" &&
+    if ($trapuser ne "*") {
+       if (!defined $AUTHTRAPS{$traphost}{$trapuser} ||
            crypt ($trappass, $AUTHTRAPS{$traphost}{$trapuser}) ne
-           $AUTHTRAPS{$traphost}{$trapuser})
-    {
-       syslog ('err', "received trap from unauthorized user $trapuser, host 
$traphost");
-       return undef;
+           $AUTHTRAPS{$traphost}{$trapuser}) 
+         {
+             syslog ('err', "received trap from unauthorized user $trapuser, host 
$traphost");
+             return undef;
+         }
     }
 
     #
@@ -3825,6 +3970,7 @@
     $sref->{"_last_trap"} = $time;
     $sref->{"_last_detail"} = $trap{"dtl"};
     $sref->{"_last_summary"} = $trap{"sum"};
+    $sref->{"_last_traphost"} = $fromip;
 
     if ($intended)
     {
@@ -3833,7 +3979,7 @@
 
     my $old_status = $sref->{"_op_status"};
 
-    syslog ('info', "trap $trap{typ} $trap{spc} from " .
+    syslog ('debug', "trap $trap{typ} $trap{spc} from " .
        "$fromip for $trap{grp} $trap{svc}, status $trap{sta}");
 
     my $group = $trap{"grp"};
@@ -3888,6 +4034,9 @@
        {
            set_op_status ($group, $service, $STAT_FAIL);
            $sref->{"_first_failure"} = $tm if ($sref->{"_op_status"} != $STAT_FAIL);
+           $sref->{"_consec_failures"}++;
+           $sref->{"_failure_count"}++;
+           $sref->{"_last_failure"} = $tmnow;
            $sref->{"_trap_duration_timer"} = $sref->{"trapduration"}
                if ($sref->{"trapduration"});
        }
@@ -3915,10 +4064,11 @@
     push @last_failures, "$trap{grp} $trap{svc}" .
        " $tm $trap{typ} $trap{spc} $trap{sum}";
 
-    if ($sref->{"depend"} ne "" &&
-           $sref->{"dep_behavior"} eq "a")
+    if ((defined $sref->{"depend"} && $sref->{"depend"} ne "" &&
+        $sref->{"dep_behavior"} eq "a")
+       || (defined $sref->{"alertdepend"} && $sref->{"alertdepend"} ne ""))
     {
-       dep_ok ($sref);
+       dep_ok ($sref, 'a');
     }
 
     #
@@ -3935,17 +4085,19 @@
 
         $flags = $FL_UPALERT;
 
-        if ( defined($sref->{"_upalert"}) ) {
-
-             if ( $tmnow - $sref->{"_first_failure"} <
-                  $sref->{"upalertafter"})
-             {
-                 $noalert++;
-             }
-        }
-        else {
-            $noalert++;
-        }
+        if ($sref->{"redistribute"} eq '') {
+           if ( defined($sref->{"_upalert"}) ) {
+           
+             if ( $tmnow - $sref->{"_first_failure"} <
+                $sref->{"upalertafter"})
+              {
+                 $noalert++;
+             }
+           }
+           else {
+                $noalert++;
+           }
+       }
     }
     #### else just fall through and send alert
 
@@ -3957,6 +4109,27 @@
            $FL_TRAP | $flags,
     ) unless ($noalert);
 
+    if ($trap{"spc"} == $STAT_OK) {
+        $sref->{"_last_success"} = $tmnow;
+       $sref->{"_ack"} = 0;
+       $sref->{"_ack_comment"} = '';
+       $sref->{"_first_failure"} = 0;
+       $sref->{"_last_failure"} = 0;
+       $sref->{"_consec_failures"} = 0;
+       $sref->{"_failure_output"} = "";
+       # Reset alertevery counters
+       foreach my $period (keys %{$sref->{"periods"}})
+       {
+           $sref->{"periods"}->{$period}->{"_last_alert"} = 0;
+           $sref->{"periods"}->{$period}->{"_alert_sent"} = 0;
+           $sref->{"periods"}->{$period}->{"_1stfailtime"} = 0;
+       }
+    } else {
+        $sref->{"_failure_output"} = $trap{"sum"} . $trap{"dtl"};
+    }
+    
+    $sref->{"_last_output"} = $trap{"sum"} . $trap{"dtl"};
+
     if( defined($sref->{"_intended"}) )
     {
         undef($sref->{"_intended"});
@@ -3974,7 +4147,9 @@
     $tmnow = time;
 
     my $sref = \%{$watch{$group}->{$service}};
+    dep_ok ($sref, 'a');
     $sref->{"_failure_count"}++;
+    $sref->{"_consec_failures"}++;
     $sref->{"_last_failure"} = $tmnow;
     $sref->{"_first_failure"} = $tmnow if ($sref->{"_op_status"} != $STAT_FAIL);
     set_op_status ($group, $service, $STAT_FAIL);
@@ -3984,7 +4159,7 @@
     push @last_failures, "$group $service $tm $sref->{_last_summary}";
     syslog ('crit', "failure for $last_failures[-1]");
 
-    do_alert ($group, $service, undef, undef, $FL_TRAPTIMEOUT);
+    do_alert ($group, $service, "trap timeout\n", -1, $FL_TRAPTIMEOUT);
 }
 
 
@@ -4172,6 +4347,20 @@
     #
     foreach my $group (keys %watch) {
        foreach my $service (keys %{$watch{$group}}) {
+           if ($watch{$group}->{$service}->{"redistribute"} ne '') {
+               my $alert = $watch{$group}->{$service}->{"redistribute"};
+               $found = 0;
+               foreach (@alertdirs) {
+                 if (-x "$_/$alert") {
+                     $ALERTHASH{$alert} = "$_/$alert"
+                       unless (defined $ALERTHASH{$alert});
+                     $found++;
+                 }
+               }
+               if (!$found) {
+                   syslog ('err', "$alert not found in one of ([EMAIL 
PROTECTED]@alertdirs])");
+               }
+           }       
            foreach my $period (keys %{$watch{$group}->{$service}->{"periods"}}) {
                foreach my $my_alert (
                        
@{$watch{$group}->{$service}->{"periods"}->{$period}->{"alerts"}},
@@ -4362,6 +4551,7 @@
     $FL_TRAPTIMEOUT = 8;
     $FL_STARTUPALERT = 16;
     $FL_TEST = 32;
+    $FL_REDISTRIBUTE = 64;
 
     #
     # specific trap types
@@ -4430,15 +4620,15 @@
     $sref->{"_timer"} = $sref->{"interval"}
        if ($sref->{"interval"});
 
+    $sref->{"_consec_failures"} = 0
+      if ($sref->{"_consec_failures"});
+       
     foreach my $period (keys %{$sref->{"periods"}}) {
        my $pref = \%{$sref->{"periods"}->{$period}};
 
        $pref->{"_last_alert"} = 0
            if ($pref->{"alertevery"});
        
-       $pref->{"_consec_failures"} = 0
-           if ($pref->{"alertafter_consec"});
-       
        $pref->{'_1stfailtime'} = 0
            if ($pref->{"alertafterival"});
     }
@@ -4506,7 +4696,7 @@
 
     my $tmnow = time;
     my ($summary) = split("\n", $args{"output"});
-    $summary = "(NO SUMMARY)" if ($summary =~ /^\s*$/m);
+    $summary = "(NO SUMMARY)" if (!defined $summary || $summary =~ /^\s*$/m);
 
     my $sref = \%{$watch{$args{"group"}}->{$args{"service"}}};
     my $pref;
@@ -4515,6 +4705,10 @@
        $pref = $args{"pref"};
     }
 
+    if (! defined $args{"args"}) {
+       $args{"args"} = '';
+    }
+
     my $alert = "";
     if (!defined $ALERTHASH{$args{"alert"}} ||
            ! -f $ALERTHASH{$args{"alert"}}) {
@@ -4570,16 +4764,16 @@
            $ENV{$v} = $sref->{"ENV"}->{$v};
        }
 
-       $ENV{"MON_LAST_SUMMARY"}        = $sref->{"_last_summary"};
-       $ENV{"MON_LAST_OUTPUT"}         = $sref->{"_last_output"};
-       $ENV{"MON_LAST_FAILURE"}        = $sref->{"_last_failure"};
-       $ENV{"MON_FIRST_FAILURE"}       = $sref->{"_first_failure"};
-       $ENV{"MON_LAST_SUCCESS"}        = $sref->{"_last_success"};
-       $ENV{"MON_DESCRIPTION"}         = $sref->{"description"};
-       $ENV{"MON_GROUP"}               = $args{"group"};
-       $ENV{"MON_SERVICE"}             = $args{"service"};
-       $ENV{"MON_RETVAL"}              = $args{"retval"};
-       $ENV{"MON_OPSTATUS"}            = $sref->{"_op_status"};
+       $ENV{"MON_LAST_SUMMARY"}        = $sref->{"_last_summary"} if (defined 
$sref->{"_last_summary"});
+       $ENV{"MON_LAST_OUTPUT"}         = $sref->{"_last_output"} if (defined 
$sref->{"_last_output"});
+       $ENV{"MON_LAST_FAILURE"}        = $sref->{"_last_failure"} if (defined 
$sref->{"_last_failure"});
+       $ENV{"MON_FIRST_FAILURE"}       = $sref->{"_first_failure"} if (defined 
$sref->{"_first_failure"});
+       $ENV{"MON_LAST_SUCCESS"}        = $sref->{"_last_success"} if (defined 
$sref->{"_last_success"});
+       $ENV{"MON_DESCRIPTION"}         = $sref->{"description"} if (defined 
$sref->{"description"});
+       $ENV{"MON_GROUP"}               = $args{"group"} if (defined $args{"group"});
+       $ENV{"MON_SERVICE"}             = $args{"service"} if (defined 
$args{"service"});
+       $ENV{"MON_RETVAL"}              = $args{"retval"} if (defined $args{"retval"});
+       $ENV{"MON_OPSTATUS"}            = $sref->{"_op_status"} if (defined 
$sref->{"_op_status"});
        $ENV{"MON_ALERTTYPE"}           = $alert_type;
        $ENV{"MON_STATEDIR"}            = $CF{"STATEDIR"};
        $ENV{"MON_LOGDIR"}              = $CF{"LOGDIR"};
@@ -4630,9 +4824,9 @@
     waitpid $pid, 0;
 
     #
-    # test alerts don't count
+    # test alerts and redistributions don't count
     #
-    return (1) if ($args{"flags"} & $FL_TEST);
+    return (1) if ($args{"flags"} & ($FL_TEST | $FL_REDISTRIBUTE));
 
     #
     # tally this alert
@@ -4683,7 +4877,7 @@
 # }
 #
 sub depend {
-    my ($depend, $depth) = @_;
+    my ($depend, $depth, $deptype) = @_;
     debug (1, "checking DEP [$depend]\n");
 
     if ($depth > $CF{"DEP_RECUR_LIMIT"}) {
@@ -4700,11 +4894,19 @@
 
        my $sref = \%{$watch{$group}->{$service}};
        my $depval = undef;
+       my $subdepend = "";
+       if (defined $sref->{"depend"} && $sref->{"dep_behavior"} eq $deptype) {
+           $subdepend = $sref->{"depend"};
+       } elsif ($deptype eq 'a' && defined $sref->{"alertdepend"}) {
+           $subdepend = $sref->{"alertdepend"};
+       } elsif ($deptype eq 'm' && defined $sref->{"monitordepend"}) {
+           $subdepend = $sref->{"monitordepend"};
+       } 
 
        #
        # disabled watches and services are counted as "passing"
        #
-       if ($watch_disabled{$group} || $sref->{"disable"} == 1)
+       if ((exists $watch_disabled{$group} && $watch_disabled{$group}) || (defined 
$sref->{"disable"} && $sref->{"disable"} == 1))
        {
            $depval = 1;
 
@@ -4712,7 +4914,7 @@
        # root dependency found
        #
        }
-       elsif ($sref->{"depend"} eq "")
+       elsif ($subdepend eq "")
        {
            debug (1, "  found root dep $group,$service\n");
 
@@ -4727,7 +4929,7 @@
            #
            # do it recursively
            #
-           my $dstatus = depend ($sref->{"depend"}, $depth + 1);
+           my $dstatus = depend ($subdepend, $depth + 1, $deptype);
            debug (1,
                "recur depth $depth returned $dstatus->{status},$dstatus->{depend}\n");
 
@@ -4783,8 +4985,19 @@
 sub dep_ok
 {
     my $sref = shift;
+    my $deptype = shift;
+    my $depend = "";
+    if (defined $sref->{"depend"} && $sref->{"dep_behavior"} eq $deptype) {
+       $depend = $sref->{"depend"};
+    } elsif ($deptype eq 'a' && defined $sref->{"alertdepend"}) {
+       $depend = $sref->{"alertdepend"};
+    } elsif ($deptype eq 'm' && defined $sref->{"monitordepend"}) {
+       $depend = $sref->{"monitordepend"};
+    }
 
-    my $s = depend ($sref->{"depend"}, 0);
+    return 1 unless ($depend ne "");
+
+    my $s = depend ($depend, 0, $deptype);
 
     if ($s->{"status"} eq "D")
     {
@@ -4810,6 +5023,38 @@
 
 
 #
+# returns undef on error
+#         otherwise a reference to a list summaries from all 
+#            DIRECT dependencies currently failing
+sub dep_summary 
+{
+    my $sref = shift;
+    my @sum;
+    my @deps = ();
+    
+    if (defined $sref->{"depend"} && $sref->{"dep_behavior"} eq "hm") {
+       @deps = ($sref->{"depend"} =~ /[a-zA-Z0-9_.-]+:[a-zA-Z0-9_.-]+/g);
+    } elsif (defined $sref->{"hostdepend"}) {
+       @deps = ($sref->{"hostdepend"} =~ /[a-zA-Z0-9_.-]+:[a-zA-Z0-9_.-]+/g);
+    }
+    
+    return [] if (! @deps);
+
+    foreach (@deps) {
+       my ($group, $service) = split /:/;
+       if (!(exists $watch{$group} && exists $watch{$group}->{$service})) {
+           return undef;
+       }
+       
+       if ($watch{$group}->{$service}{"_op_status"} == $STAT_FAIL) {
+           push @sum, $watch{$group}->{$service}{"_last_summary"};
+       }
+    }
+
+    return [EMAIL PROTECTED];
+}
+    
+#
 # convert a string to a hex-escaped string, returning
 # the escaped string.
 #
@@ -4824,7 +5069,7 @@
     my $inquotes = shift;
 
     my $escstr = "";
-
+    return $escstr if (!defined $str);
     for (my $i = 0; $i < length ($str); $i++)
     {
        my $c = substr ($str, $i, 1);
_______________________________________________
mon mailing list
[EMAIL PROTECTED]
http://linux.kernel.org/mailman/listinfo/mon

Reply via email to