<?php // -*-php-*-

#############################################################################
#                                                                           #
# This script was initially developed by Lonely Planet for internal use     #
# and has kindly been made available to the Open Source community for       #
# redistribution and further development under the terms of the             #
# GNU General Public License v3: http://www.gnu.org/licenses/gpl.html       #
#                                                                           #
#############################################################################
#                                                                           #
# This script is supplied 'as-is', in the hope that it will be useful, but  #
# neither Lonely Planet nor the authors make any warranties or guarantees   #
# as to its correct operation, including its intended function.             #
#                                                                           #
# Or in other words:                                                        #
#       Test it yourself, and make sure it works for YOU.                   #
#                                                                           #
#############################################################################
# Author: George Hansper       e-mail:  George.Hansper@lonelyplanet.com.au  #
#############################################################################

$wiki_page = "/nagios/cgi-bin/status.cgi?host=";
$hwinfo_dir = "/var/www/html/hwinfo";

$all_hosts = array();

$heading = array("IP","Vendor","Model","Service Tag",
	"n CPUs","Model","Speed","L2 Cache","FSB",
	"Total RAM","ECC/non-ECC","Memory Slots free",
	"Disk Sizes","RAID Info",
	"OS","arch","Kernel","Packages","DRAC/ILO",
	);

$safe_mode_exec_dir = "/usr/lib64/nagios/plugins";
putenv("PATH=$PATH:/usr/lib64/nagios/plugins");

$stale_if_older_seconds = 60 * 60 * 24;
// ------------------------------------------------------------------------
// ---------- You should not need to modify anything below here -----------
// ------------------------------------------------------------------------

if (is_dir($hwinfo_dir)) {
    if ($hwinfo_dh = opendir($hwinfo_dir)) {
	while (($file = readdir($hwinfo_dh)) !== false) {
	    $hwinfo_file = $hwinfo_dir . "/" . $file;
	    if ( filetype($hwinfo_file) == "file" ) {
		$all_hosts[count($all_hosts)] = $file;
	    }
	    //echo "filename: $file : filetype: " .  . "\n";
	}
	closedir($hwinfo_dh);
    }
}

foreach ($all_hosts as $host ) {
	$hwinfo_file = $hwinfo_dir . "/" . $host;
	$hwinfo_fh = fopen($hwinfo_file, "r");
	$hwinfo_str[$host] = fread($hwinfo_fh, filesize($hwinfo_file));
	fclose($hwinfo_fh);
	$hwinfo[$host] = preg_split ( "/\",\"/", trim($hwinfo_str[$host],"\"\n\r"));
	$stat = stat($hwinfo_file);
	$hwinfo_mtime[$host]=$stat['mtime'];
}

// Fix up columns for backwards compatability
$hwinfo_split = array();
foreach ($all_hosts as $host ) {
	#$hwinfo_split[$host] = preg_split ( "/\",\"/", trim($hwinfo_str[$host],"\"\n\r"));
	for ( $i=0 ; $i < count($hwinfo[$host]); $i++ ) {
		if ( $heading[$i] == "arch" && ! preg_match("/^(x86|i.86)[^\s]*/", $hwinfo[$host][$i]) ) {
			# No arch field, insert a dummy
			array_splice($hwinfo[$host],$i,0,"&nbsp;");
		}
		if ( $heading[$i] == "Kernel" && ! preg_match("/^([0-9]|package)/", $hwinfo[$host][$i]) ) {
			# No kernel field, insert a dummy
			array_splice($hwinfo[$host],$i,0,"&nbsp;");
		}
	}
	$hwinfo_split[$host] = $hwinfo[$host];
	#echo implode(" , ",$hwinfo_split[$host]) . "\n";
}

$sort_order = split(",",$_GET['sort']);

function sort_cmp($a, $b)
	{
	global $sort_order;
	global $hwinfo;
	global $heading;
	#echo "a=$a b=$b\n";
	foreach( $sort_order as $col ) {
		#echo "<br>$a $b Order $col >". $heading[$col-1] ."< "  .$hwinfo[$a][$col-1]." <=> $col ".$hwinfo[$b][$col-1]."\n";
		if( $col == 'name' ) {
			if( $a != $b ) {
				return(strcasecmp($a,$b));
			}
		} elseif ( $col == 'domain' ) {
				#echo sprintf("<br>%s <=> %s\n",strstr($a,'.'),strstr($b,'.'));
				$dom_a = implode(".",array_reverse(split("\.",$a)));
				$dom_b = implode(".",array_reverse(split("\.",$b)));
				#echo sprintf("<br>%s <=> %s\n",$dom_a,$dom_b);
				return(strcasecmp($dom_a,$dom_b));
		} elseif ( $col != "" && ( $heading[$col-1] == 'IP' || $heading[$col-1] == 'Kernel' || preg_match("/DRAC/", $heading[$col-1]) == 1 ) ) {
				$col--;
				#echo sprintf("<br>%s <=> %s\n",$hwinfo[$a][$col],$hwinfo[$b][$col]);
				$ip_a = split("\.|-",$hwinfo[$a][$col]);
				$ip_b = split("\.|-",$hwinfo[$b][$col]);
				$ip_a[0] = preg_replace("/.*=/","",$ip_a[0]);
				$ip_b[0] = preg_replace("/.*=/","",$ip_b[0]);
				for( $i=0; $i<=3; $i++) {
					#echo sprintf("<br>%d %s <=> %s = ",$i,$ip_a[$i] , $ip_b[$i]);
					if( $ip_a[$i] < $ip_b[$i] ) {
						#echo "-1\n";
						return(-1);
					} elseif( $ip_a[$i] > $ip_b[$i] ) {
						#echo "1\n";
						return(1);
					}
					#echo "0\n";
				}
				#echo sprintf("<br>%s <=> %s\n",$ip_a,$ip_b);
				if( $hwinfo[$a][$col] !=  $hwinfo[$b][$col] ) {
					return(strcasecmp($hwinfo[$a][$col],$hwinfo[$b][$col]));
				}
		} else {
			if ( $col != "" ) {
				$col--;
				if( $hwinfo[$a][$col] !=  $hwinfo[$b][$col] ) {
					if ( preg_match("/^[0-9]+[^0-9]*$/",$hwinfo[$a][$col]) && preg_match("/^[0-9]+[^0-9]*$/",$hwinfo[$b][$col] ) ) {
						// Do numeric comparison if feasible
						return( $hwinfo[$a][$col] - $hwinfo[$b][$col] );
					} else {
						return(strcasecmp($hwinfo[$a][$col],$hwinfo[$b][$col]));
					}
				}
			}
		}
	}
	# all other things being 'equal', sort by name
	return(strcasecmp($a,$b));
}

usort($all_hosts,'sort_cmp');
#echo implode("\n<br>",$all_hosts) . "\n";

#sort($all_hosts);
#echo "sort $sort_order[0] $sort_order[1]\n";
#$http_query_string = HttpQueryString.new($global=true);
#$query()=$http_query_string.toArray();

#if( $_SERVER[QUERY_STRING] == "csv" ) {
#echo "csv = $_GET[csv]\n";
if ( array_key_exists('csv', $_GET) ) {
	output_as_csv($all_hosts);
} elseif ( array_key_exists('dell', $_GET) ) {
	output_as_dell_csv($all_hosts);
} else {
	output_as_html($all_hosts);
}

function output_as_html($all_hosts)
	{
	global $wiki_page;
	#global $hwinfo_dir;
	global $hwinfo_str;
	global $hwinfo_mtime;
	global $heading;
	global $hwinfo_split;
	global $stale_if_older_seconds;
	$format = array(
		"n CPUs" => " ALIGN=CENTER",
		"Vendor" => " NOWRAP",
		"Model" => " NOWRAP",
		"Service Tag" => " ALIGN=CENTER",
		"Speed" => " NOWRAP ALIGN=RIGHT",
		"L2 Cache" => " NOWRAP ALIGN=RIGHT",
		"FSB" => " NOWRAP ALIGN=RIGHT",
		"Total RAM" => " NOWRAP ALIGN=RIGHT",
		"Installed Modules" => " NOWRAP",
		"Memory Slots free" => " NOWRAP ALIGN=CENTER",
		"Disk Sizes" => " NOWRAP",
		"RAID Info" => " NOWRAP",
		"arch" => " NOWRAP",
		"Kernel" => " NOWRAP",
		"Packages" => " NOWRAP",
		"OS" => " NOWRAP",
		"" => " NOWRAP",
		);
	?>
<HTML>
<HEAD>
<TITLE>Hardware Information list</TITLE>
<style type="text/css">
tr.l5 { background-color:#F0FFFF; }
tr.offline { color:#808080; }
tr.l5offline { background-color:#F0FFFF; color:#808080; }
a.offline { text-decoration: line-through; color:#808080; font-weight:normal }
a.l5offline { background-color:#F0FFFF; color:#808080; text-decoration: line-through; font-weight:normal }
</style>
<style type="text/css">
</style>
</HEAD>
<BODY>
<H1>Hardware Information list</H1>
<P>
<TABLE BORDER=2 CELLPADDING=2>
<TR>
    <TH COLSPAN=2>Host</TH>
    <TH COLSPAN=3>Motherboard Info</TH>
    <TH COLSPAN=5>CPU Info</TH>
    <TH COLSPAN=3>Memory Info</TH>
    <TH COLSPAN=2>Disk Info</TH>
    <TH COLSPAN=4>Software</TH>
    <TH COLSPAN=1>Remote Management</TH>
<TR>
	<TH><A href="?sort=name">Name</A>&nbsp;.&nbsp;<A href="?sort=domain">domain</A></TH>
<?php
	$n=1;
	foreach ( $heading as $th ) {
		echo "    <TH><A href=\"?sort=$n\">$th</A></TH>\n";
		$n++;
	}
?>
<TR>
<?php

	$line_count=0;
	foreach ($all_hosts as $host ) {
		#$hwinfo_file = $hwinfo_dir . "/" . $host;
		#$hwinfo_fh = fopen($hwinfo_file, "r");
		#$hwinfo_str = fread($hwinfo_fh, filesize($hwinfo_file));
		#fclose($hwinfo_fh);

		$txt_class="";
		if ( ++$line_count % 5 == 0 ) {
			$txt_class .= "l5";
		}
		if ( time() - $hwinfo_mtime[$host] > $stale_if_older_seconds ) {
			$txt_class .= "offline";
		}
		if ( $txt_class != "" ) {
			$txt_class= " class='$txt_class'";
		}
		$hwinfo = $hwinfo_split[$host];
		#$hwinfo = preg_split ( "/\",\"/", trim($hwinfo_str[$host],"\"\n\r"));
		echo "<TR$txt_class title=\"$host\">\n    <TH><a$txt_class href=\"", $wiki_page, $host, "\">$host</a></TH>\n";
		for ( $i=0 ; $i < count($hwinfo); $i++ ) {
			if ( $hwinfo[$i] == "" ) {
				$hwinfo[$i] = "&nbsp;";
			}
			if ( ! isset($format[$heading[$i]]) ) {
				$format[$heading[$i]] = "";
			}
			if ( $heading[$i] == "DRAC/ILO" && preg_match("/not available/", $hwinfo[$i]) ) {
				$hwinfo[$i] = "&nbsp;";
			} elseif ( $heading[$i] == "OS" ) {
				$hwinfo[$i] = preg_replace("/ *\([a-z0-9 ]*\) *$/i","",$hwinfo[$i],1);
				$hwinfo[$i] = preg_replace("/ release/i","",$hwinfo[$i],1);
				$hwinfo[$i] = preg_replace("/Red Hat Enterprise Linux( Server| ES)? */i","RHEL ",$hwinfo[$i],1);
			} elseif ( $heading[$i] == "Vendor" ) {
				$hwinfo[$i] = preg_replace("/ *Corporation/i","",$hwinfo[$i],1);
			} elseif ( $heading[$i] == "Installed Modules" || $heading[$i] == "Memory Slots free" ) {
				$n_slots = preg_match_all("@/@",$hwinfo[$i],$dummy) +1 ;
				$n_free = preg_match_all("@/0@",$hwinfo[$i],$dummy);

				$hwinfo[$i] = "$n_free of $n_slots";
			} elseif ( $heading[$i] == "Disk Sizes" ) {
				// $hwinfo[$i] = preg_replace("/^(.{30}([^ /]{0,6})?).*/","\${1}...",$hwinfo[$i],1);;
				$hwinfo[$i] = preg_replace("/^(.{36})...*/","\${1}...",$hwinfo[$i],1);;
			}
			echo "    <TD" . $format[$heading[$i]] . ">" . $hwinfo[$i] ."</TD>\n";
		}
		

	if ( 0 == 1 ) {
		echo "<TR>\n    <TH><a href=\"http://", $wiki_page, $host, "\">$host</a></TH>\n";
		$hwinfo_str = exec("check_nrpe -H $host -t 120 -c check_hwinfo");
		$hwinfo_str = preg_replace("@http:(//|\\\\\\\\)@i","",$hwinfo_str);
		// echo $hwinfo_str;
		$hw_types = preg_split ( "/[][]+/", $hwinfo_str);
		$mb_info = explode( ":", $hw_types[1]) ;
		for($i=0; $i<3; $i++ ) {
			if ( $mb_info[$i] == "" ) {
				 $mb_info[$i] = "&nbsp;";
			}
			echo "    <TD NOWRAP>$mb_info[$i]</TD>\n";
		}
		$cpu_info = explode( ":", $hw_types[2]) ;
		for($i=0; $i<5; $i++ ) {
			if ( $cpu_info[$i] == "" ) {
				 $cpu_info[$i] = "&nbsp;";
			}
			if ( $i==0 ) {		// ncpus
				$align="ALIGN=CENTER";
			} elseif ( $i == 2 || $i == 3 || $i == 4) { // MHz, L2 Cache, FSB
				$align="ALIGN=RIGHT";
			} else {
				$align="";
			}
			echo "    <TD NOWRAP $align>$cpu_info[$i]</TD>\n";
		}
		$mem_info = explode( ":", $hw_types[3]) ;
		for($i=0; $i<3; $i++ ) {
			if ( $mem_info[$i] == "" ) {
				 $mem_info[$i] = "&nbsp;";
			}
			if ( $i==0 || $i == 1 ) {	// Total RAM, ECC
				$align="ALIGN=RIGHT";
			} elseif ( $i == 2 ) {		// installed modules
				$align="";
				$mem_info[$i] = preg_replace("@/@"," - ",$mem_info[$i]);
			} else {
				$align="";
			}
			echo "    <TD NOWRAP $align>$mem_info[$i]</TD>\n";
		}
		$disk_info = explode( ":", $hw_types[4]) ;
		for($i=0; $i<count($disk_info); $i++ ) {
			if ( $disk_info[$i] == "" ) {
				 $disk_info[$i] = "&nbsp;";
			}
			echo "    <TD NOWRAP>$disk_info[$i]</TD>\n";
		}
		// echo "    <TD NOWRAP>$hw_types[4]</TD>\n";
		$os_info = explode( ":", $hw_types[5]) ;
		for($i=0; $i<count($os_info); $i++ ) {
			if ( $os_info[$i] == "" ) {
				 $os_info[$i] = "&nbsp;";
			}
			echo "    <TD NOWRAP>$os_info[$i]</TD>\n";
		}
	}
	}

	if( $safe_mode ) {
		echo "<P>safe_mode=$safe_mode";
	}
	?>
</TABLE>
<P>Last Updated: <?php echo `date` ?>
</BODY>
</HTML>

<?php
} // end function output_as_html()

function output_as_csv($all_hosts)
	{
	#global $hwinfo_dir;
	global $hwinfo_str;

	// Replace content-type header
	header("Content-Type: text/plain",true);
	header("Content-Disposition: filename=hwinfo.csv",true);

	echo "Host, IP, Motherboard Info,,, CPU Info,,,,, Memory Info,,, Disk Info,\n";
	echo "\"\",Vendor, Model, Service Tag, n CPUs, Model, Speed, L2 Cache, FSB, Total RAM, ECC/non-ECC, Installed Modules, Disk Information\n";

	foreach ($all_hosts as $host ) {
		#$hwinfo_file = $hwinfo_dir . "/" . $host;
		#$hwinfo_fh = fopen($hwinfo_file, "r");
		#$hwinfo = fread($hwinfo_fh, filesize($hwinfo_file));
		#fclose($hwinfo_fh);
		echo "\"$host\"," .$hwinfo_str[$host];
	}

//	if (is_dir($hwinfo_dir)) {
//	    if ($hwinfo_dh = opendir($hwinfo_dir)) {
//		while (($file = readdir($hwinfo_dh)) !== false) {
//		    $all_hosts[count($all_hosts)] = $file;
//		    $hwinfo_file = $hwinfo_dir . "/" . $file;
//		    if ( filetype($hwinfo_file) == "file" ) {
//			$hwinfo_fh = fopen($hwinfo_file, "r");
//			$hwinfo = fread($hwinfo_fh, filesize($hwinfo_file));
//			fclose($hwinfo_fh);
//			echo "\"$file\"," .$hwinfo;
//		    }
//		    //echo "filename: $file : filetype: " .  . "\n";
//		}
//		closedir($hwinfo_dh);
//	    }
//	}

//	echo "Last Updated: " . `date` . "\n";
} // end function output_as_csv()
function output_as_dell_csv($all_hosts)
	{
	#global $hwinfo_dir;
	global $hwinfo_split;
	global $hwinfo_mtime;
	global $heading;

	// Replace content-type header
	header("Content-Type: text/plain",true);
	header("Content-Disposition: filename=dell_my_systems_and_peripherals.csv",true);

	echo "Service Tag,System Description\n";
	foreach ($all_hosts as $host ) {
		$hwinfo = $hwinfo_split[$host];
		for ( $i=0 ; $i < count($hwinfo); $i++ ) {
			if ( $heading[$i] == "Vendor" ) {
				$vendor = $hwinfo[$i];
			} elseif ( $heading[$i] == "Service Tag" ) {
				$service_tag = $hwinfo[$i];
			}
		}
		
		#echo "$host $vendor $service_tag\n";
		if( preg_match('/^[Dd][Ee][Ll][Ll]/',$vendor) == 1 ) {
			if ( time() - $hwinfo_mtime[$host] < 60 * 60 * 24 * 7 ) {
				// if host has been up in the last 7 days
				echo "$service_tag,$host\n";
			}
		}
	}

} // end function output_as_dell_csv()
?>
