#!/usr/bin/perl -w
use strict;

#
# PING (PING Is Not Ghost) / rc.multi
#
# Copyright(c) 2005-2015 EFFITEK
# Home page: PING (PING Is Not Ghost) http://ping.windowsdream.com/
#
# This script is intended to run on a PING Linux-live image. As for PING,
# Linux, GNU/GPL tools, etc. refer to specific licences.
# This script (rc.multi) has been written by Fabrice SCEMAMA (the Author),
# from Windowsdream.com. Email: natan@windowsdream.com .
#
# * Use it at your own risk. No warranty, no damage accountability.
# * Please, refer any bug / feature request to the Author.
#

# This script is to be run in background mode.
# It will look for partimage activity, and eject the cdrom
# when there's no more activity, this giving the multi-vol
# option a concrete sense in batch mode.

my $MYSELF = "rc.multi";
my $VERSION = "2.00";
my $VERSION_DATE = "2007-06-26";

my $TMPDIR = "/tmp";
my $LOG_FILE = "x.log";

my($PName, $Todo) = @ARGV;
exit unless(defined($PName) && $PName && defined($Todo) && $Todo);

LOG("\n");
LOG("* Starting ".$MYSELF." ".$VERSION." ".$VERSION_DATE."\n");
LOG("*\n");

LOG("* Safe start sleep (10)\n");
sleep(10);

LOG("* Monitoring [".$PName."]\n");

my $cnt = 0;
my(@PPID) = ();
my(@T) = (0, 60);

while(++ $cnt)
{
    my $NProcs = PNumber($PName);

    LOG("  Number of [".$PName."] ".($#PPID > -1 ? "[".join(", ", @PPID)."] ":"")
	."processes: [".$NProcs."]\n");

    if($NProcs == 0)
    {
	LOG("  [".$PName."] is not running any more. Exit.\n");
	last;
    }

    if($#PPID == -1)
    {
	@PPID = PPID($PName);
	LOG("  [".$PName."] has PIDs: [".join(", ", @PPID)."]\n");
    }

    if($#PPID > -1)
    {
	$T[$cnt % 2] = PTime2(@PPID);
    }
    else
    {
	$T[$cnt % 2] = PTime($PName);
    }
    LOG("  Cnt: [".$cnt."] -- T0: [".$T[0]."] -- T1: [".$T[1]."]\n");

    if(abs($T[1] - $T[0]) == 0)
    {
	LOG("    No process activity\n");
	LOG("    Cmd: [".$Todo."]\n");
	system($Todo);
    }

    LOG("    Sleeping 20 seconds\n");
    sleep(20);
}

LOG("* End of rc.multi\n");




# Retrieves the PIDs of a process of a certain name
#
sub PPID
{
    my($Proc) = shift;
    return(0) unless($Proc);

    my $out = `ps -ef|grep "$Proc"|grep -v grep|grep -v "$MYSELF"`;
    my(@lines) = split(/\n/, $out);
    #LOG("PPID() Out: [".$out."]\n");

    my(@PIDs) = ();
    foreach my $L (@lines)
    {
	my @f = split(/ +/, $L);
	if(defined($f[1]))
	{
	    $f[1] =~s/^\s*//;
	    $f[1] =~s/\s*$//;
	    push(@PIDs, $f[1]);
	}
    }
    return(@PIDs);
}


# Retrieves number of processes of a certain name
#
sub PNumber
{
    my($Proc) = shift;
    return(0) unless($Proc);

    my $out = `ps -ef|grep "$Proc"|grep -v grep|grep -v "$MYSELF"`;
    #LOG("PNumber() Out: [".$out."]\n");
    my(@lines) = split(/\n/, $out);

    return($#lines + 1);
}


# Retrieves total elapsed time by ALL processes of a certain name
#
sub PTime
{
    my($Proc) = shift;
    return(0) unless($Proc);

    my $out = `ps -ef|grep "$Proc"|grep -v grep|grep -v "$MYSELF"`;
    my(@lines) = split(/\n/, $out);
    #LOG("PTime() Out: [".$out."]\n");

    my $sum = 0;
    foreach my $L (@lines)
    {
	my @f = split(/ +/, $L);
	if(defined($f[6]))
	{
	    if($f[6] =~/:/)
	    {
		my(@ff) = split(/:/, $f[6]);
		$sum += $ff[0] * 60 + $ff[1] * 60 + $ff[2];
	    }
	}
    }
    return($sum);
}


# Retrieves total elapsed time by ALL processes of a certain PID
#
sub PTime2
{
    my(@PIDs) = @_;
    return(0) unless($#PIDs > -1);

    my $sum = 0;

    foreach my $PID (@PIDs)
    {
	my $out = `ps -ef|grep " $PID "|grep -v grep`;
	my(@lines) = split(/\n/, $out);
	#LOG("Ptime2() Out: [".$out."]\n");

	foreach my $L (@lines)
	{
	    my @f = split(/ +/, $L);
	    if(defined($f[6]))
	    {
		if($f[6] =~/:/)
		{
		    my(@ff) = split(/:/, $f[6]);
		    $sum += $ff[0] * 60 + $ff[1] * 60 + $ff[2];
		}
	    }
	}
    }

    return($sum);
}


sub LOG
{
    my $Say = shift;
    my $Now = Time();
    open(LOG, ">>".$TMDIR."/".$LOG_FILE);
    print LOG $$." ".$MYSELF." ".$Now."> ".$Say;
    close(LOG);
}



sub Time
{
    my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

    if($sec < 10){ $sec = "0".$sec; }
    if($min < 10){ $min = "0".$min; }
    if($hour < 10){ $hour = "0".$hour; }

    return($hour.":".$min.":".$sec);
}
