#! /usr/bin/perl -w

# prtdiag check module

# Version: $Revision: 0.1 $
# Author: Matt Selsky <selsky@columbia.edu>
# Date: $Date: 2003/01/31 09:24:42 $

# Copyright (c) 2003
# The Trustees of Columbia University in the City of New York
# Academic Information Systems
# 
# License restrictions apply, see doc/license.html for details.

use strict;
use FindBin;
use lib "$FindBin::Bin/../common";
use Survivor::Check;

my %argfmt = ("verbose" => "optional boolean default(0)");

my $sc = new Survivor::Check();

$sc->GetOpt(\%argfmt, \&PrtdiagValidate);

my $r = $sc->Exec( \&PrtdiagCheck);

exit($r);

sub PrtdiagValidate {
    return(MODEXEC_OK, 0, 'Prtdiag OK');
}

sub PrtdiagCheck {
    my $self = shift;
    my $host = shift;

    # We need to run as root
    unless($< == 0 || $> == 0) {
	return(MODEXEC_MISCONFIG, 0, 'Prtdiag must run as root');
    }

    # We require Sun uname since it supports the '-i' option
    my $UNAME = '/bin/uname';

    unless(-x $UNAME) {
	return(MODEXEC_MISCONFIG, 0, 'uname executable not found');
    }

    open(UNAME, "$UNAME -i 2>&1|");
    chomp(my $platform = <UNAME>);
    close(UNAME);

    my $PRTDIAG = "/usr/platform/${platform}/sbin/prtdiag";

    unless(-x $PRTDIAG) {
	return(MODEXEC_MISCONFIG, 0, 'prtdiag executable not found');
    }

    my $verbose = $self->Arg('verbose');

    # They just want the return code
    if(!$verbose) {
	system("$PRTDIAG -v 2>&1 1>/dev/null");

	my $exit_value  = $? >> 8;

	if ($exit_value == 0) {
	    return(MODEXEC_OK, 1, 'No failures or errors detected.');
	} elsif($exit_value == 1) {
	    return(MODEXEC_PROBLEM, 0, 'Failures or errors detected.');
	} elsif($exit_value == 2) {
	    return(MODEXEC_PROBLEM, 0, 'Internal prtdiag error occured.');
	} else {
	    return(MODEXEC_PROBLEM, 0, 'Unexpected prtdiag error occured.');
	}
    }

    # Try to give the user some details
    open(PRTDIAG, "$PRTDIAG -v 2>&1|");

    my($line, @msg);
    while( defined($line = <PRTDIAG>) ) {
	chomp $line;
	# FRU (Field Replaceable Units)
	if ($line =~ /^Failed Field Replaceable Units/) {
	    <PRTDIAG>; # eat line
	    # Grab left justified lines in the paragraph
	    my $subline;
	    while( defined ($subline = <PRTDIAG>) ) {
		chomp $subline;
		if ($subline =~ /^\S/) {
		    push @msg, $subline;
		} elsif (!length $subline) {
		    last;
		}
	    }
	} elsif ($line =~ /^Detected System Faults/) {
	    <PRTDIAG>; # eat line
	    # Grab left justified lines in the paragraph
	    my $subline;
	    while( defined ($subline = <PRTDIAG>) ) {
		chomp $subline;
		if ($subline =~ /^\S/) {
		    push @msg, $subline;
		} elsif (!length $subline) {
		    last;
		}
	    }
	} elsif ($line =~ / Environmental Status /) {
	    <PRTDIAG>; # eat line
	    # Look for front-panel status light problems
	    my $subline;
	    while( defined ($subline = <PRTDIAG>) ) {
		chomp $subline;
		if ($subline =~ /^WARNING/) {
		    my @colors = split(/\s+/, $subline);
		    if ($colors[2] ne 'OFF') {
			push @msg, 'Yellow warning light is on';
		    }
		}
	    }
	}
    }

    close(PRTDIAG);

    if (scalar @msg != 0) {
	return(MODEXEC_PROBLEM, 0, join('; ', @msg));
     } else {
	 return(MODEXEC_OK, 1, 'No failures or errors detected.');
     }
}
