#!/usr/bin/perl 

# Title:         process_monitor.pl
# DESCRIPTION:   Find the zobie, and list their parents
# Reference:  Oreilly, Perl for Sysadmins, pg 116. 
#             Source:  perldoc -m Proc::ProcessTable
#             Perldoc: perldoc  Proc::ProcessTable

####################################################################
# Load Modules
use Proc::ProcessTable ;
use Term::ANSIColor;
####################################################################
# Clear The Screen
system (clear);
####################################################################
# Creates a new ProcessTable object reference called $server.
$server = new Proc::ProcessTable;
####################################################################
#fields:
#           --Returns a list of the field names supported by the
#           module on the current architecture.
#my @server_fields= $server->fields();
#print "Supported Fileds: @server_fields\n";
####################################################################
#table:
#           --Reads the process table and returns a reference to an
#             array of Proc::ProcessTable::Process objects.
#           --Attributes of a process object are returned by accessors 
#             named for the attribute.
$server_proctable = $server->table();
####################################################################
# Get process count by dereferencing the array reference holding the process table 
$process_count = @$server_proctable;
print "Total of:\t",color("yellow"),"$process_count processes.",color("reset"),"\n";
####################################################################
# Find the zombie
foreach $process ( @$server_proctable ){
  if ( $process->state =~ "defunct" ){
    #
    # make a refernce list of defunct processes
    #
    push  ( @$server_defunct, $process );
    #
    # push the parent pid onto an array of parent pids
    #
    #debug code# print "Adding to parent pid array:",$process->ppid,"\n";
    push ( @parent_pids, $process->ppid );
   }
   
}    
####################################################################
# Print the results
#
print color ("green"),"####################################################################",color("reset"),"\n",
                      "List zobie processes: \n"; 
&print_stuff( \@$server_defunct );
####################################################################
# Find the unique parents of defunced process
my %seen=();
foreach $pid ( @parent_pids ){
        push ( @parent_pids_unique, $pid ) unless $seen{$item}++;	
}
$number=@parent_pids_unique;
print "Number of unique Parent Pids:\t$number\t\n";
print "Unique Parent Pids:\n";
foreach $parent_pid (@parent_pids_unique){
  print color("yellow"),"\t$parent_pid",color("reset"),"\n";
}
####################################################################
# Print results:
sub print_stuff {
  $ar = shift;
  $FORMAT = "%-6s %-6s %-10s %-8s %-25s %s\n";
  printf($FORMAT, "PID", "PPID", "TTY", "STAT", "START", "COMMAND");
  print color ("red");
  foreach $process ( @$ar ){
    printf($FORMAT,
           $process->pid,
	   $process->ppid,
           $process->ttydev,
           $process->state,
           scalar(localtime($process->start)),
           $process->cmndline);
   } 
   print color ("reset"); 
}
