#!/usr/bin/perl
# ------------------------------------------------------------------------------------
#  Project       : hcl
#  File          : hcldmidecodeinfo
#  Author        : Keerthan Muthurasa <kmuthurasa at mandriva dot com>
#  Created On    : Mon Aug 27 11:15:03 2007
#  Purpose       : Collect data about hardware ,using dmidecode tool and format data 
#                  in an xml format file.
# -------------------------------------------------------------------------------------

use strict;
use Switch;

if(scalar(@ARGV) != 1)
{
	print"hcldmidecodeinfo [number]\n";
	print "number:class\n
   	  0:bios\n
          1:system\n
          2:base board\n
          3:chassis\n
          4:processor\n
          7:cache\n
          8:port\n
          9:slot\n
	 10:on board device\n
	 17:memory\n
	 30:distribution\n
	 31:kernel\n
	 32:monitor\n";
	exit 1;
}

my %file = (
   	  0   =>"bios.xml",
          1   =>"system.xml",
          2   =>"base_board.xml",
          3   =>"chassis.xml",
          4   =>"processor.xml",
	  7   =>"cache.xml",
          8   =>"port.xml",
          9   =>"slot.xml",
	  10  =>"on_bord_device.xml",
	  17  =>"memory.xml",
	  30  =>"distribution.xml",
	  31  =>"kernel.xml",
	  32  =>"monitor.xml"
);
my $choice=$ARGV[0];
my $startflag=0;
my $flag = 0;
my $flagcpt=0;
my $endflag=0;
my $start=0;
my $start_count	= 0;
my @pile;
my @indent;
my $exist = 0;
my $path = "/tmp/report";
if(-e "$path/$file{$choice}"){$exist=1}

my $pid=open(PROC,"-|");
if($pid)
{	open(OFIL,">>$path/$file{$choice}");
	while(<PROC>)
	{
		switch ($choice)
		{
			case 0 {dmidecode("characteristic",$_) if($exist==0)}
			case 1 {dmidecode("",$_) if($exist==0)} 
			case 2 {dmidecode("",$_) if($exist==0)}
			case 3 {dmidecode("",$_) if($exist==0)}
			case 4
		 	{
			 
				if(/^.*Flags:.*/){$startflag=1;$flagcpt=0};
				$flag = 0 if(/^\t.*/);
				if(/^\t\t.*/ && $startflag){$flag=1;$flagcpt++};
				if($flagcpt > 0 && $flag == 0){$endflag=1;$flagcpt=0}
				else{$endflag = 0};
				processor($flag,$endflag,$_);
		 	}
			case 7 {dmidecode("supported_sram_type",$_) if($exist ==0)}
			case 8 {dmidecode("",$_) if($exist ==0)}
			case 9 {dmidecode("characteristic",$_) if($exist ==0)}	
			case 10{dmidecode("",$_) if($exist ==0)}
			case 17{dmidecode("",$_) if($exist ==0)}
			case 30
			{
				if($exist == 0)
				{
					$_=~s/\(Official\).*for/:/;
					my @split=split(":",$_);
					$split[0]=trim($split[0]);
					$split[1]=trim($split[1]);
					print OFIL "<distribution>$split[0]</distribution>\n";
					print OFIL "<architecture>$split[1]</architecture>\n";
				}
			}
			case 31
			{
				if($exist == 0 )
				{
					$_=trim($_);
					print OFIL "<kernel>$_</kernel>\n";
				}
			}
			case 32
			{
				if($exist == 0 )
				{
					$_=trim($_);
					if(/^Section "Monitor".*/i){$start=1;print OFIL "<monitor>\n"}
					if($start==1)
					{
						if($_ !~ /^Section "Monitor".*/i)
						{
			
							my @split=split(" ",$_);
							$split[1]=~s/"//;
							print OFIL "<description>$split[1]</description>\n" if(/^.*Identifier.*/i);
							print OFIL "<vendor>$split[1]</vendor>\n" if(/^.*VendorName.*/i);
							print OFIL "<model>$split[1]</vendor>\n" if(/^.*ModelName.*/i);
							print OFIL "<horizontal_sync>$split[1]</horizontal_sync>\n" if(/^.*HorizSync.*/i);
							print OFIL "<vertical_refresh>$split[1]</vertical_refresh>\n" if(/^.*VertRefresh.*/i);
						}
					}
					if(/^.*EndSection.*/i && $start==1){ $start=0;print OFIL "</monitor>\n"}
				}
			}
		}
	}

	if($choice == 0 || $choice == 1 || $choice == 2 || $choice == 3 ||$choice == 7 ||$choice == 8 || $choice == 9 || $choice == 17)
	{
		for(my $cpt = scalar(@pile);$cpt > 0;$cpt--)
		{
			print OFIL pop(@indent)."<\\".pop(@pile).">\n";
		}
		close(OFIL);
	}
}
else
{
	if($choice == 30 || $choice == 32)
	{
		if($choice == 30)
		{
			exec("cat /etc/mandriva-release");
			exit 1;
		}
		else
		{
			exec("cat /etc/X11/xorg.conf");
			exit 1;
		}
	}
	elsif($choice == 31)
	{
		exec("uname -r");
		exit 1;
	}
	else
	{
		exec("dmidecode -t $choice");
		exit 1;
	}
}

sub trim($)
{
	my $string = shift;
	$string =~ s/^\s+//;
	$string =~ s/\s+$//;
	return $string;

}

sub processor
{
	my ($flag_,$eflag,$line) = @_;
	my @data = split(': ',$line);
		$data[0]=trim($data[0]);
		$data[1]=trim($data[1]);
		$data[1]=~ s/\n//;

	print OFIL "<family>$data[1]</family>\n" if($line =~ /^.*Family:.*/);
	print OFIL "<flags>\n" if($line =~ /^.*Flags:.*/);
	
	if($flag)
	{
		$line =trim($line);
		$line =~ s/\n$//;
		print OFIL "\t<flag>$line</flag>\n";
	}
	
	print OFIL "</flags>\n" if($eflag);
	print OFIL "<socket>$data[1]</socket>\n" if($line =~ /^.*Upgrade:.*/);

}

sub dmidecode
{
	my($subtag,$line)=@_;
	if($line =~ m/^$/)
	{
		$flag = 0;
		$start_count = 1;

		while(scalar(@pile) > 0)
		{
			print OFIL pop(@indent)."</".pop(@pile).">\n";
		}
	}

	if($start_count == 1)
	{
		$flag++;
	}
	if ($flag > 2)
	{

		if($line !~ m/^\t/)
		{
			$line =~ s/ /_/g;
			$line =~ s/\n$//g;
			$line = trim($line);
			$line =lc($line);
			print OFIL "<$line>\n";
			push(@pile,$line);
			push(@indent,"");
		}
		
		if($line =~ m/^\t\t/)
		{
			$line =~ s/\n//g;
			$line = trim($line);	
			print OFIL "\t\t<$subtag>$line<\\$subtag>\n";
		}
		if($line =~ m/^\t/)
		{
			if($indent[scalar(@indent)-1] eq "\t")
			{
				print OFIL pop(@indent)."<\\".pop(@pile).">\n";
			}
		
			$line = trim($line);
			$line =~ s/\n$//g;
			my @split =split(':',$line);
			$split[0] =~ s/ /_/g;
			$split[0] =lc($split[0]);
			$split[1] = trim($split[1]);
			if($split[1] ne "")
			{
				print OFIL "\t<$split[0]>$split[1]<\\$split[0]>\n";
			}
			else
			{
				print OFIL "\t<$split[0]>\n";
				push(@pile,$split[0]);
				push(@indent,"\t");
			}
		}
	}

}



