#!/usr/bin/perl

use strict;
use POSIX;
use Getopt::Long;
use English qw(-no_match_vars);


#############
# Paramaters

my $yum_command = "/usr/bin/yum --assumeyes --nogpgcheck";
my $sender_command = "/usr/bin/zabbix_sender -c /etc/zabbix/zabbix_agent2.conf -i -";
my $timeout = 600;
my $key = "system.sw.updates.list";
my $yum_arguments = "";
my $debug = 0;
my $time = time;

GetOptions (
	"yum_command=s" => \$yum_command,
	"sender_command=s" => \$sender_command,
	"timeout=s" => \$timeout,
	"key=s" => \$key,
	"yum_arguments=s" => \$yum_arguments,
	"debug" => \$debug) or die("Error in command line arguments\n");

############
# Daemonize
sub Fork
{
    my $pid = fork;
    defined $pid or die "Can't fork: $!\n";
    $pid
}

if (!$debug) {
	Fork and exit;
	POSIX::setsid();
	my $pid = Fork;
	if ($pid) {
		print "check_updates($pid) started at ".(localtime)."\n";
		exit;
	}
  
	umask 0;
	chdir '/' or die "Can't chdir to /: $!\n";

	open STDIN , '<', '/dev/null';
	open STDOUT, '>', '/dev/null';
	open STDERR, '>', '/dev/null';
}

###############
# Set timeout alarm
alarm $timeout;
local $SIG{ALRM} = sub { die "Check was running too long ($timeout s).\n" };

##############
# RUN YUM

my $command = "$yum_command check-update $yum_arguments 2>&1";
print "Running $command\n";

my $OUTPUT_HANDLER;
my @updates;

my $pid = open $OUTPUT_HANDLER, q{-|}, $command or die( "Cannot list updates: $OS_ERROR" );
while (<$OUTPUT_HANDLER>) {
	my $line = $_;
        print $line;
        chomp $line;

        # some lines are wrapped and result and the second part
        # is erroneously interpreted as a new update
        next if ( $line =~ m/^[ ]/mxs );

        # The obsoleted packages are already listed
        last if ( $line =~ /^Obsoleting/imxs );

        # Lines to be ignored
        if (   $line =~ /^Last[ ]metadata[ ]expiration/imxs
            || $line =~ /^Loaded[ ]plugins:/imxs
            || $line =~ /^Loading[ ]mirror[ ]speeds/imxs
            || $line =~ /[ ].B\/s[ ][|][ ]/imxs
            || $line =~ /^No[ ]security[ ]updates/imxs
	    || $line =~ /^Updating[ ]Subscription[ ]Management[ ]repositories/imxs
            || $line =~
            /^Repository[ ]'.*' is missing name in configuration, using id/imxs
            || $line =~
            /^Security:[ ].*is[ ]an[ ]installed[ ]security[ ]update/imxs
            || $line =~
            /^Security:[ ].*is[ ]the[ ]currently[ ]running[ ]version/imxs
            || $line =~ /^Update[ ]notice/imxs
            || $line =~ /^You[ ]should/imxs
            || $line =~ /^If[ ]you[ ]are/imxs
            || $line =~ /^To[ ]help[ ]pinpoint[ ]the[ ]issue/imxs
            || $line =~ /You[ ]must[ ]run[ ]this[ ]command[ ]as[ ]root/imxs
            || $line =~ /^No[ ]packages[ ]needed/imxs 
	    || $line eq "")
        {
            	next;
        }

	# After and including "Uploading Enabled Repositories Report" the output can be ignored
        last if ( $line =~ /^Uploading[ ]Enabled[ ]Repositories[ ]Report/imxs );

        $line =~ s{[ ].*}{}mxs;
        push @updates, $line;
}

die("Error while closing pipe to rpm: $OS_ERROR") if ( !( close $OUTPUT_HANDLER ) && ( $OS_ERROR != 0 ) );

#############
# Make output

my $output = "{
  \"packages\" : [
".join(",\n",map { "    \"$_\"" } @updates)."
  ],
  \"time\" : $time
}
";

print "Output JSON:\n";
print $output."\n";

$output =~ s/\\/\\\\/g;
$output =~ s/"/\\"/g;
$output =~ s/\n//g;
$output =~ s/  //g;

$output = "- $key \"$output\"";

print "Output file for zabbix_sender:\n";
print $output."\n";

##################
# Sending to zabbix

print "Sending output file to $sender_command\n";
print `echo '$output' | $sender_command`;
die( "Cannot send updates: $OS_ERROR" ) if ($!);
