#! /usr/bin/perl 
#
# This updated version of the rtas_dump script will
# do everything the original rtas_dump script does except
# it does it cleaner and without as many cmdline options.
#
# Copyright (C) 2004 International Business Machines
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Author: Nathan Fontenot <nfont@linux.vnet.ibm.com>
# 

use vars qw/ %opt /;

use Getopt::Long;
use File::Basename;

$re_decode = $ENV{RTAS_EVENT_DECODE} || "/usr/sbin/rtas_event_decode";

#
# usage statement
#
sub usage()
{
	print "Usage: rtas_dump [OPTIONS]\n";
	print "Dump the contents of an RTAS event, by default RTAS events\n";
	print "are read from stdin unless the -f flag is used.\n\n";
	print " -d         debug flag, passed through to rtas_event_decode\n";
	print " -f <FILE>  dump the RTAS events from <FILE>\n";
	print " -h         print this message and exit\n";
	print " -n <NUM>   only dump RTAS event number <NUM>\n";
	print " -v         dump the entire RTAS event, not just the header\n";
	print " -w <width> set the output character width\n";
	
	exit 1;
}

#
# Read in the contents of an RTAS event and invoke rtas_event_decode on it.
#
sub handle_rtas_event()
{
	my ($event_no) = @_;

	$re_decode_args = "$re_decode_args -n $event_no";
	
	# create the pipe to rtas_event_decode
	open EVENT_DECODE, "| $re_decode $re_decode_args";

	while(<$fh>) {
		($crud, $data) = split (/RTAS/);
		$rtas_str = $rtas_str . "RTAS" . $data;
		if (/RTAS event end/) {
			print EVENT_DECODE $rtas_str;
			$rtas_str = "";
			last;
		}
	}

	close EVENT_DECODE;
}

#
# Main
#
my $PSERIES_PLATFORM = dirname(__FILE__) . "/pseries_platform";

my $perldumpenv='perl -MData::Dumper -e '."'".
    '\$Data::Dumper::Terse=1;print Dumper(\%ENV);'."'";

eval '%ENV=('.$1.')' if `bash -c "
        . $PSERIES_PLATFORM;
        $perldumpenv"`
    =~ /^\s*\{(.*)\}\s*$/mxs;

if ($ENV{'platform'} == $ENV{'PLATFORM_UNKNOWN'} || $ENV{'platform'} == $ENV{'PLATFORM_POWERNV'}) {
	print "rtas_dump: is not supported on the $ENV{'platform_name'} platform\n";
	exit 1;
}

# process cmdline args
Getopt::Long::Configure("bundling");
GetOptions("help|h"     => \$help_flag,
           "dump_raw|d" => \$debug_flag,
           "file|f=s"   => \$filename,
           "n=i"        => \$event_no,
	   "w=i"        => \$width,
           "verbose|v+" => \$verbose) or usage();
           
usage() if $help_flag;

# make sure the rtas_event_decode application is available
-e $re_decode or die "File $re_decode does not exist and is needed by rtas_dump.\n";

-x $re_decode or die "File $re_decode is not executable.\n";

# get a reference to our input filehandle
if ($filename) {
	if (-e $filename) {
		open INPUT_FILE, $filename;
		$fh = \*INPUT_FILE;
		$close_input_file = 1;
	} else {
		print "File $filename does not exist\n" ;
		return -1;
	}
} else {
	$fh = \*STDIN;
}

# create the arg list to rtas_event_decode
$re_decode_args = "$re_decode_args -d" if $debug_flag;
$re_decode_args = "$re_decode_args -v" if $verbose;
$re_decode_args = "$re_decode_args -w $width" if $width;

while (<$fh>) {
	if (/RTAS event begin/) { 
		# found the beginning of an RTAS event, process it.
		($crud, $data) = split (/RTAS:/);
		($this_event_no, $d) = split (' ', $data);
		if ($event_no) {
			if ($event_no == $this_event_no) {
				$rtas_str = $rtas_str . "RTAS:" . $data;
				&handle_rtas_event($this_event_no);
			}
		} else {
			$rtas_str = $rtas_str . "RTAS:" . $data;
			&handle_rtas_event($this_event_no);
		}

		next;
	}
}

if ($close_input_file) {
	close INPUT_FILE;
}
