#!/usr/bin/perl
# cpanel - aotofixer/check_hung_services          Copyright(c) 2014 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

BEGIN { unshift @INC, '/usr/local/cpanel'; }

use Cpanel::OSSys ();

my @services = (
    {
        'user' => 'root',
        'proc' => 'pkgacct'
    },
    {
        'user' => 'root',
        'proc' => 'cpbackup'
    },
    {
        'user' => 'root',
        'proc' => 'upcp'
    },
    {
        'user' => 'root',
        'proc' => 'cPanel Update'
    },
);

my @ps_command = ( '/bin/ps', '-eo', 'pid,user,etime,command' );
if ( Cpanel::OSSys::get_system() =~ m/freebsd/i ) {
    @ps_command = ( '/bin/ps', '-axo', 'pid,user,etime,command' );
}

my $ps;
my @psout;

open( my $ps_fh, '-|' ) || exec(@ps_command);
while ( my $line = readline($ps_fh) ) {
    chomp $line;
    push @psout, $line;
}
close($ps_fh);

foreach my $service_ref (@services) {
    my $service = $service_ref->{'proc'};
    my $user    = $service_ref->{'user'};
    foreach my $line (@psout) {
        next if ( $line !~ m/^\s*\d+\s+\Q$user\E\s+/ || $line !~ /[^^]$service/ );
        $line =~ s/^\s+//g;
        my ( $ps_pid, $ps_user, $elapsed_time, $ps_command ) = split( /\s+/, $line, 4 );

        next if ( !$ps_pid );

        next if $elapsed_time !~ m/^(\d+)-(\d+)/;
        my $days  = $1;
        my $hours = $2;

        $ps_command =~ s/\s*$//g;    # display cleanup

        if ( $days >= 1 ) {
            my $exe;
            if ( -e '/proc/' . $ps_pid . '/exe' ) {
                $exe = readlink( '/proc/' . $ps_pid . '/exe' );
            }
            else {
                $exe = readlink( '/proc/' . $ps_pid . '/file' );
            }
            next if ( $exe !~ m/perl/ );
            print "$ps_command with pid $ps_pid running as user $ps_user has been running more more than a day! Day(s): $days Hour(s): $hours\n";
            kill( 15, $ps_pid );
            sleep(3);
            kill( 9, $ps_pid );
        }
    }
}
