#!/usr/bin/perl -w
#
# $Id: APTChk,v 1.5 2002/06/22 18:33:31 cvs Exp $
#
# APTChk: Checks version of critical packages and optionally upgrades them
#
# Miguel Armas <kuko@ulpgc.es>
#

#--------------------------------------------[ Initialization Section ]----

use strict;
use Getopt::Std;
use pifia;

#--------------------------------------------[ Configuration Section ]----- 
my $priority = "Warning";
my $alarm = "APTChk";
# Package query command
my $pkgchk;
#if (ingroup('debian'))
$pkgchk = '/usr/bin/dkpg -s $pkgname | awk \'/Package/ { name = $2} /Version/ { gsub("-", " "); print name, $2" "$3 }\'';
#else
$pkgchk = '/bin/rpm -q --queryformat "%{name} %{version} %{release}" $pkgname';
#fi

#--------------------------------------------[ Code Section ]----

# proactive flag indicates if we should take proactive measures, that is, 
# install/upgrade packages or just notify. Default is 0 but the global 
# variable proactive takes precedence
my $proactive='<#$proactive#>';

# Set a safe PATH
$ENV{'PATH'} = "/bin:/sbin:/usr/bin:/usr/sbin:/root/bin";

# Option declaration
use vars qw($opt_v $opt_n $opt_p $opt_q);
getopts('vnpq');

# Verbosity level. If not verbose, we shouldn't write any output unless 
# there is a problem. If quiet is set, we won't write ANY output (even if 
# there where errors). verbose has precedence
my $quiet = 1 if ($opt_q);
my $verbose = 1 if ($opt_v);
$quiet = 0 if ($verbose);

# proactive flag handling (parameters has precedence over global variable)
$proactive=1 if ($opt_p);
$proactive=0 if ($opt_n);

# Flag to show that the situation was corrected (in the output)
my $corrected=($proactive ? "CORRECTED" : "");

# Output
my @output;

# update apt-get local database
print "############################ \n" if $verbose;
print "## Running apt-get update... \n" if $verbose;
print "############################ \n" if $verbose;
my $cmd;
if ($verbose) {
   $cmd = "apt-get -q update";
} else {
   $cmd = "apt-get -qq update >/dev/null 2>&1";
}
if (system($cmd)) {
   print "ERROR: apt-get update exited with errors \n";
   exit 1;
};

##
## Check packages to upgrade
##
if ($proactive) {
   # Upgrade packages
   print "############################ \n" if $verbose;
   print "## Running apt-get upgrade...\n" if $verbose;
   print "############################ \n" if $verbose;
   @output=`apt-get -q -y upgrade 2>&1`;
   if ($?) {
      print "ERROR: apt-get upgrade exited with errors \n";
      print @output;
      exit 1;
   }
   # OK, now see if we can get the upgraded package names
   if (my @pkgs=grep(/^\s\s\w+.*$/,@output)) {
      map {chomp} @pkgs;
      my $pkglist = join("",@pkgs);
      $pkglist =~ s/\s+/ /g;
      print "UPGRADED: $pkglist\n";
   }
}
else {
   # Just notify
   print "Running apt-get -s upgrade... \n" if $verbose;
   @output=`apt-get -s upgrade 2>&1`;
   if ($?) {
      print "ERROR: apt-get upgrade exited with errors \n";
      print @output;
      exit 1;
   }
   # OK, now see if we can get the upgraded package names
   if (my @pkgs=grep(/^\s\s\w+.*$/,@output)) {
      map {chomp} @pkgs;
      my $pkglist = join("",@pkgs);
      $pkglist =~ s/\s+/ /g;
      print "NEED TO UPGRADE: $pkglist\n";
   }
}

##
## Check package list
##
my @packages = readObjectFiles($alarm);

foreach my $pkg (@packages) {
   my ($pkgname,$pkgver,$pkgrel)=("??","??","??");
   my ($instname,$instver,$instrel)=("??","??","??");
   my @tmp;
   chomp($pkg);
   @tmp = split(/ +/,$pkg);
   $pkgname = $tmp[0] if $tmp[0];
   $pkgver  = $tmp[1] if $tmp[1];
   $pkgrel  = $tmp[2] if $tmp[2];
   my $totalchk = $pkgchk;
   $totalchk =~ s/\$pkgname/$pkgname/;
   my $inst = `$totalchk`;
   chomp $inst; 
   if ($inst =~ /not installed/ ) {
      print "$pkgname NOT INSTALLED. $corrected\n";
      system("apt-get -qq install $pkgname") if ($proactive);
   } 
   else {
      ($instname,$instver,$instrel) =  split(/ +/,$inst);
      if (($pkgver ne "??") && ($instver lt $pkgver)) {
	 print "$pkgname-$instver-$instrel installed. Needed: $pkgname-$pkgver-$pkgrel $corrected\n";
	 system("apt-get -qq install $pkgname") if ($proactive);
      }
      elsif (($instver eq $pkgver) && ($pkgrel ne "??") && ($instrel lt $pkgrel)) {
	 print "$pkgname-$instver-$instrel installed. Needed: $pkgname-$pkgver-$pkgrel $corrected\n";
	 system("apt-get -qq install $pkgname") if ($proactive);
      }
   }
}

