#!/usr/bin/perl

# monProcs  (c) Copyright 1998 Mark Black 

# NOTE:  If you modify this code, you MUST change the version to
#        something over 100 to prevent it being replaced by future
#        versions of this script. 
$version = 2 ;

# monProcs
# This script is called to monitor running processes
# Outputs status to stdout in the form  status:info
# status can be 0 or 1.  1 = success, 0 = fail
#          OUTPUT:
#                   1:      - Success
#                   0:info  - Failure
#	   Input args:
#                   -v      - Print script version number
#		    -i      - Instance.  This tells MATd if there is
#		              an instance of the parameter it wishes
#                             to monitor.  Code returns number of 
#                             instances.
#
#         Note:  Exit status of script should always be  0, anything
#	         else indicates an error in the monitoring script.

$inp = "" ;
foreach $i (0 .. $#ARGV) {
   $inp .= "@ARGV[$i] " ;
}
chop($inp) ;

# Output the version if requested
if($inp eq "-v") {
    print "$version\n" ;
    exit(0) ;
}

if($inp eq "-i") {
    print "1:\n" ;
    exit(0) ;
} 

# Discover OS type and set variables for OS type
chop($os = `uname -s`) ;

if($os eq "Linux") {
    @procs = `/bin/ps -auxww` ;
} elsif($os eq "SunOS") {
    chop($ver = `uname -r`) ;
    ($major, $minor) = split(/\./, $ver) ;
    if($major == 5) {
	@procs = `/usr/ucb/ps -auxww` ;
    } else {
	@procs = `/usr/bin/ps -auxww` ;
    }
} elsif(($os eq "IRIX") | ($os eq "IRIX64"))  {
    @procs = `/bin/ps -elf` ;
} elsif($os eq "HP-UX") {
    @procs = `/bin/ps -elf` ;
}

# Read in the user/process file
open(DATA, $inp) || die "ERROR:  Process file not found.\n" ;
@datain = <DATA> ;

# Return value for calling process (0=Okay)
$retval = 0 ;
$outstr = "" ;

# Scan through all the user/processes, and find matches in the current process list
foreach $index (0 .. $#datain ) {
    $line = @datain[$index] ;
    # The following removes unrequired characters (newlines)
    $line =~ s/(.*)\n/$1/ ;

    ($cuser, $cproc, $restart) = split(/\s+/, $line, 3) ;

    if($cuser ne "#") {
	# Look through the current process list for the process
	$found = 0 ;
	foreach $in (0 .. $#procs ) {
	    $proc = @procs[$in] ;
	    ($user, $a1, $a2, $a3, $a4, $a5, $a6, $a7, $a8, $a9, $process) = split(/\s+/, $proc) ;
	    if($user eq $cuser) {
		if($process eq $cproc) {
		    # Process Found, ie no error
		    $found = 1 ;
		}
	    }
	}
	if($found == 0) {
	    $retval = -1 ;
	    if($restart ne "") {
		# Try to restart the process
		if( -e $restart && -r $restart ) {
		    $outstr .= "Trying to restart $cproc as $cuser.  " ;
		    if($child = fork) {
			# Set the UID and run process
			($rn, $rp, $ruid, $rest) = getpwnam($cuser) ;
			$> = $ruid ;
			$< = $ruid ;
			`$restart 2>/dev/null 1>/dev/null&` ;
			exit 0 ;
		    } else {
			# Parent code:  continue
		    }

		} else {
		    # Restart file is not readable
		    $outstr .= "Cannot restart $cproc with $restart.  Check permissions.  " ;
		}
	    } else {
		$outstr .= "User $cuser process $cproc has died!  " ;
	    }
	}
    }
}

if($retval == 0) {
    # Normal exit
    print("1:\n") ;
} else {
    # Process failed
    print("0:$outstr\n") ;
}


exit $retval ;







