#!/usr/bin/perl -w
#
# $Id: ProcChk,v 1.2 2001/12/24 20:27:01 cvs Exp $
#
# ProcChk: Checks if critical processes are running. If they aren't, 
# try to run it
#
# Miguel Armas <kuko@ulpgc.es>
#

#--------------------------------------------[ Initialization Section ]----

use strict;
use Getopt::Std;
use pifia;

#--------------------------------------------[ Configuration Section ]----- 
my $priority = "Emergency";
my $alarm = "ProcChk";
my $remind = <#$remind#>;        # Seconds

#--------------------------------------------[ Code Section ]----

# proactive flag indicates if we should take proactive measures, that is, 
# install/upgrade packages or just notify. Default is 0 but the global 
# variable proactive takes precedence
my $proactive='<#$proactive#>';

# Set a safe PATH
$ENV{'PATH'} = "/bin:/sbin:/usr/bin:/usr/sbin:/root/bin";

# Option declaration
use vars qw($opt_v $opt_n $opt_p $opt_q);
getopts('vnpq');

# Verbosity level. If not verbose, we shouldn't write any output unless 
# there is a problem. If quiet is set, we won't write ANY output (even if 
# there where errors). verbose has precedence
my $quiet = 1 if ($opt_q);
my $verbose = 1 if ($opt_v);
$quiet = 0 if ($verbose);

# proactive flag handling (parameter has precedence over global variable)
$proactive=1 if ($opt_p);
$proactive=0 if ($opt_n);

use vars qw(%lastnotify);

perseval {
   # Read object files
   my @procs = readObjectFiles($alarm);
   
   foreach my $line (@procs) {
      $line =~ /^(!?\w+)\s+(.*)$/;
      my ($proc,$cmd) = ($1,$2);
      my $error = 0;
      my $not = 0;
      if ($proc =~ /^!(.*)/) {
         $proc = $1;
         $not = 1;
      }
      if (((!pidof($proc)) && (!$not)) || ((pidof($proc) && ($not)))) {
         $error = 1;
         if ($cmd && $proactive) {
            for (my $i = 0; $i <= 3 ; $i++) {
               system("$cmd >/dev/null 2>&1");
               sleep 1; # give time to start
               last if (((pidof($proc)) && (!$not)) || 
                        ((!pidof($proc)) && ($not)) );
            }
         }
      }
      if ($error) {
         # See if we should send a notification
         if (!$quiet && needNotify($proc,$remind)) {
            if (pidof($proc)) {
               if ($not) {
                   print "FATAL: $proc was running, and could not be stopped\n";
               }
               else {
                   print "ERROR: $proc was down, but could be started\n";
               }
            } else {
               if ($not) {
                   print "ERROR: $proc was running, but could be stopped\n";
               }
               else {
                   print "FATAL: $proc was down, and could not be started\n";
               }
            }
            # Update last notification timestamp
            $lastnotify{$proc} = time();
         }
      }
   }
} preserve '%lastnotify';

# FUNCTION: pidof(process)
# DESCRIPTION: Gets the PID of a process
sub pidof {
   my $proc = shift;

   my $cmd = "ps ax | grep '$proc' | grep -v 'grep'";

   `$cmd`;
}
