#!/opt/SUNWstade/bin/perl -I/opt/SUNWstade/lib
use System;
use strict;
use PPRO;
use Inventory;
use Mail;
use LockManager;
use Events;

  if ($ARGV[0] ne "-r") {
    print "Usage: patch_scheduler -r \n";
    exit(1);
  }
  System->set_home("/opt/SUNWstade");
  
  my($renv, $devs, $hosts, $notifs, $Config) = PDM::ConfigFile->read();

  exit if ($renv->{solution} ne "se2");
  
  System->set_renv($renv);
  
  my $FREQ   = $renv->{'ppro.update_freq'};  # D
  my $AUTO   = $renv->{'ppro.auto_update'};  # Y/N
  my $OUTPUT = "/var/tmp/pprosvc_storade/required_patches.xml";
  
  exit if (!$FREQ);

  my $lock  = LockManager->new();
  my $locki = $lock->exists("system", 1) || {};
  my $date  = Util->get_today();

  if ($locki->{info}) {
     # LOG to SUNWstade/log/cron_patch.log
     print "$date Conflict, system already reserved: $locki->{info}\n";
     exit 1;
  }
  my $mins = 6 * 60;  # 6 hours
  my $info = "revision|revision_maintenance|Automatic patch listing|$date|$mins|$$";
  my $rc   = $lock->lock("system", 60*60*6, 0, $info);

  if (!$rc) {
     print "$date Failed to reserver resource: $LockManager::ERR\n";
     exit 1;
  }
  
  my $trace = &run_command(PPRO->cli_path() . " -l -s storade");
  
  my ($l,$REPORT) ;

  if (!open(O, $OUTPUT)) {
    &log("ERR", "Cannot access $OUTPUT");
    $lock->unlock("system");
    exit(1);
  }
  while ($l = <O>) {
    $REPORT .= $l;
  }
  close(O);

  my $inv = Inventory->readInventory();
  my %IP;  # map devices by ipno

  foreach my $d (@{$inv->getDevices()}) {
     $IP{$d->{ipno}} = $d;
  }

  my($cnt, $email) = &parse($REPORT);
  my $DEL = "=============TRACE================";

  if ($cnt) {

     if ($AUTO ne "Y") {
       &log("$cnt patch(es) available");
       if ($#$notifs >= 0) {
          my $header = "";
	  if ($cnt ne "E") {
            $header = "The following $cnt patch(es) are required to be installed. Access the Service section of Storage A.D.E to install these patches manually.";
	  }

          my $text =<<EOF;
$header
$email
EOF

          $text =~ s/\n/<NL>/g;
          Events->saveEvent("PP0", $text);
       }
     } else {
       $trace .= &run_command(PPRO->cli_path() . " -i -n -s storade");

       &log("$cnt patch(es) installed");
       if ($#$notifs >= 0) {
          my $text =<<EOF;
Trying to install the following $cnt patch(es). Look at the trace for any install errors.
$email
$DEL
$trace
EOF

          $text =~ s/\n/<NL>/g;
          Events->saveEvent("PP1", $text);
       }
     }
  }
  $lock->unlock("system");
  exit(0);

  

# get patches,
# check for patches
# send email if found
# install -n if found,


sub parse {
  my($REPORT) = @_;
  my $ppro = PPRO->parse($REPORT);
  my ($cnt, $out);

  if ($ppro->{ERRORS}) {
     $out = $ppro->{ERRORS};
     $cnt = "E";
     return ($cnt, $out); 
  }

  foreach my $pp (@{$ppro->devices()}) {
      my $inv_d = $IP{$pp->key()};
      my $ip   = $pp->key();
      my $name = $inv_d->{name};
      my $type = lc($pp->type());
      my $dev  = $Config->deviceByIP($ip);
      my $P = $pp->patches();
      my $pout;
      foreach my $patch (@$P) {
         my $pid = $patch->{patchID};
         my $syn = $patch->{synopsis};
         my $err = $pp->error($patch->{error});
         $pout .= "    Error: " . $err->{message} . ": " . $err->{remedy} . "\n"
                        if ($err->{message});
         $pout .= "    $pid : $syn \n";
         $cnt++;
      }

      if ($type eq "sunos") {
        $type = "Service Processor";
      } elsif ($type eq "t4pp") {
	$type = "6020";
      }

      $out .= "Patches for $type:$name $dev->{ipno}: \n$pout" if ($pout);
  }
  return ($cnt, $out);
}

sub run_command {
  my($com) = @_;
  open(O , "$com 2>&1|");
  my ($trace ,$l);
  while ($l = <O> ) {
    $trace .= $l;
  }
  close(O);
  return $trace;
}


sub log {
  my($type, $t) = @_;

  my $today = Util->get_today();
  open(ERR, ">>/opt/SUNWstade/log/patch_scheduler.log");
  print ERR "$today $type $t\n";
  close(O);
}


