#!/usr/cs/bin/perl
@Machines = (
	"adder: Interactive Server<br><a href=http://www.sun.com/microelectronics/stp1020a/datasheet/>50MHz SuperSPARC</a> 10",
	"cobra: Interactive Server<br>360MHz UltraSPARC II",
	"mamba: Interactive Server<br>360MHz UltraSPARC II",
	"viper: Interactive Server<br>360MHz UltraSPARC II",
	"altair: Compute Server<br><a href=http://www.sun.com/microelectronics/stp1030a/datasheet/>167MHz UltraSPARC</a> 1",
	"alto: Compute Server<br><a href=http://www.sun.com/microelectronics/stp1030a/datasheet/>167MHz UltraSPARC</a> 1",
	"casper: Compute Server<br><a href=http://www.sun.com/microelectronics/stp1030a/datasheet/>167MHz UltraSPARC</a> 1",
	"univac: Compute Server<br><a href=http://www.sun.com/microelectronics/stp1030a/datasheet/>167MHz UltraSPARC</a> 1",
	"ace: Compute Server<br><a href=http://www.sun.com/microelectronics/stp1020a/datasheet/>50MHz SuperSPARC</a> 20",
	"edvac: Compute Server<br><a href=http://www.sun.com/microelectronics/stp1020a/datasheet/>50MHz SuperSPARC</a> 20",
	"whirlwind: Compute Server<br><a href=http://www.sun.com/microelectronics/stp1020a/datasheet/>50MHz SuperSPARC</a> 20",
	"apollo: File Server<br><a href=http://www.sun.com/microelectronics/stp1020a/datasheet/>50MHz SuperSPARC</a> 10",
	"www: Web Server<br><a href=http://www.sun.com/microelectronics/stp1020a/datasheet/>50MHz SuperSPARC</a> 10");
@tips = (
	"Do not run CPU-intensive jobs on the interactive servers. The compute
	servers are better-suited for these tasks.",
	"Use /tmp or /usr/tmp for I/O when using the compute servers. These are
	on local disks that can be accessed faster.",
	"The /tmp directories local to a specific machine are erased whenever
	the machine goes down.",
	"Multiple jobs on a single-CPU compute server compete with each other and
	degrade their own performance. Run multiple jobs on multi-CPU machines.",
	"Using -pipe when compiling with GCC opens memory-to-memory pipes
	between compiler stages, rather than temporary files. This reduces
	compile time by reducing file I/O.",
	"Users may run at most 2 jobs on a compute server, with a maximum of 4
	jobs on all compute servers.",
	"The Sun \"CC\" and \"cc\" compilers have many options for optimising
	programs. Run \"CC -flags\" or \"cc -flags\" to find out more.",
	"If you run 4 compute jobs, please don't use all 4 UltraSPARCs. Leave
	one open for other people.",
	"To get faster compiles, use \"gmake -j 4\" on a multi-CPU compute
	server. It will run up to 4 simultaneous compilations, if 4
	dependencies are simultaneously satisfied.",
	"Use \"purify\" to help find memory leaks and memory-related errors.
	Simply link your code with the command \"purify\" as the first thing on
	the command line.",
	"Use \"quantify\" to help you determine where your program spends all its
	time executing. Re-link your program with \"quantify\" as the first
	thing on the command line. It will show you call-graphs and execution
	times per function.",
	"The department has recently bought new, updated C and C++ compilers
	for Solaris. They include a graphical debugger named \"debugger\" and
	many new options.",
	"Use a debugger. vi + printf != debugger.",
	"Edit your code on an interactive server, not a compute server.",
	"Compile and run your code on a compute server, not an interactive server.");
@config = ("8fbc8f", "b5a642", "cococo", "d8bfd8", "d9d9f3", "ebc79e", "ffffff");
$histtimes = 25;
srand; @appendage = @oldtimes = ();
open(OLD, "/users/an4m/public_html/usage.html");
@oldtimes = <OLD>;
close(OLD);
@oldtimes = reverse((reverse(@oldtimes))[0..$#Machines+1]);
$nowtime = `/usr/bin/date +"%R %A, %B %d, %Y"`;
$backcolour = $config[rand(@config)];
@readings = split(/\s+/, @oldtimes[$#oldtimes]);
pop(@oldtimes); shift(@readings); pop(@readings); shift(@readings);
for ($j = $histtimes-$#readings-1; $j > 0; $j--) { unshift(@readings, "--"); }
for ($j = $#readings-$histtimes+1; $j > 0; $j--) { shift(@readings); }
@oldtimes[$#Machines+1] = "<!--\tREADINGS"; shift(@readings);
foreach $j (@readings) { @oldtimes[$#Machines+1] .= "\t$j"; }
open(NEW, "> /users/an4m/public_html/.usage.html.$$");
print NEW "<html><head><style type=\"text/css\">\n<!--\n.tight {"
	. "margin-top:-15;margin-bottom:-15;padding-top:-15;padding-bottom:-15;"
	. "border-top-width:-15;border-bottom-width:-15;}\n"
	. "-->\n</style><title>Department Computer Usage</title>"
    . "<meta http-equiv=\"pragma\" content=\"nocache\">"
    . "<meta http-equiv=\"refresh\" content=\"149; url=usage.html\"></head>"
    . "<body bgcolor=#$backcolour><center><h1>Current CPU Usage</h1>"
    . "<small>Last update: <i>$nowtime</i>; Next update: <i>5 minutes later"
	. "</i></small><hr><table width=100%><tr><td align=center><b>"
	. "<font size=-1>MACHINE</font></b></td>";
chop($nowtime); $nowtime =~ s/ .*//g;
@oldtimes[$#Machines+1] .= "\t$nowtime\t-->\n";
$secondrow = "<tr><td align=center width=3%><font size=-1><i>$readings[0]</i>"
	. "<br><code><b>&nbsp;&nbsp;H<br>U&nbsp;I<br>S&nbsp;S<br>A&nbsp;T<br>"
	. "G&nbsp;O<br>E&nbsp;R<br>&nbsp;&nbsp;Y</b></code><br>"
	. "<i>$nowtime</i></font></td>";
$thirdrow = "<tr><td align=center><b><font size=-1>Jobs/CPU</font></b></td>";
for ($i = 0; $i <= $#Machines; $i++)
{
	($mach, $type) = split(/: /, @Machines[$i]);
	print NEW "<td align=center width=7%><a href=#$mach>$mach</a></td>";
	eval
	{
		local $SIG{ALRM} = sub { die "DEAD"; };
		alarm 20;
		@output = `/users/an4m/bin/usage $mach 2> /dev/null`;
		alarm 0;
	};
	if ($@ =~ /DEAD/)
		{ @output[0] = ":0 :0 :0\n"; @output[3] = "Oops! $mach doesn't respond!\n"; }
	($junk, $cpu, $load, $total) = split(/ *: */, @output[0]);
	$back = ($cpu <= 50)
		? sprintf("bgcolor=#%02xff00", int(0xff*$cpu/50))
		: sprintf("bgcolor=#ff%02x00", 0xff-int(0xff*($cpu-50)/50));
	$secondrow .= "<td align=left width=7% $back>";
	@times = split(/\s+/, @oldtimes[$i]); shift(@times); pop(@times); shift(@times);
	for ($j = $histtimes-$#times-1; $j > 0; $j--) { unshift(@times, "0"); }
	for ($j = $#times-$histtimes+1; $j > 0; $j--) { shift(@times); }
	@oldtimes[$i] = "<!--\t$mach"; shift(@times);
	foreach $j (@times)
	{
		$secondrow .= "<hr class=tight noshade size=5 align=left width=$j>";
		@oldtimes[$i] .= "\t$j";
	}
	@oldtimes[$i] .= "\t$cpu\t-->\n";
	$secondrow .= "<hr class=tight noshade size=5 align=left width=$cpu></td>";
	$thirdrow .= "<td align=center width=7%>$load/$total</td>";
	shift(@output); shift(@output); shift(@output);
	push(@appendage, "<table width=90% border><tr><td align=center width=25%>"
		. "<a name=$mach></a><a href=telnet://$mach.cs.virginia.edu><h2>"
		. "$mach</h2></a><font size=-1>$type</font></td><td><table width=100%>"
		. "<tr><th align=right width=25%><font size=-1>User</font></th>"
		. "<th align=center width=25%><font size=-1>#Jobs</font></th>"
		. "<th align=right width=25%><font size=-1>%CPU</font></th>"
		. "<th align=right width=25%><font size=-1>Memory</font></th></tr>"
		. "<tr><td colspan=4><hr></td></tr>");
	foreach $line (@output)
	{
		$_ = $line; s/^\s+//;
		($user, $jobs, $percpu, $memory) = split;
		if ($user ne "Oops!")
			{ $user = "<a href=http://www.cs.virginia.edu/~$user/>$user</a>";}
		push(@appendage, "<tr><td align=right width=25%>$user</td>"
		               . "<td align=center width=25%>$jobs</td>"
		               . "<td align=right width=25%>$percpu</td>"
		               . "<td align=right width=25%>$memory</td></tr>");
	}
	push(@appendage, "</table></td><td width=15%><table width=100%>"
		. "<tr><td align=right width=50%>%CPU</td><td align=right width=50%>$cpu</td></tr>"
		. "<tr><td align=right width=50%>Load</td><td align=right width=50%>$load</td></tr>"
		. "<tr><td align=right width=50%>#CPU</td><td align=right width=50%>$total</td></tr>"
		. "</table></td></tr></table>");
}
print NEW "</tr>$secondrow</tr>$thirdrow</tr><th colspan=".($#Machines+3).">"
	. "<a href=http://www.cs.virginia.edu/~csadmin/hardware/printers/livestats.html>"
	. "Live Printer Status</a></th></table><hr><i>$tips[rand(@tips)]</i><hr>";
foreach $line (@appendage) { print NEW $line; }
# print NEW "<hr><i>$tips[rand(@tips)]</i><hr><h1>Current Disk Usage</h1>"
	# . "<table width=90% border=3><tr><td><table width=100%>"
    # . "<tr><td align=center width=10%><font size=-1>Server</font></td>"
    # . "<td align=center width=7%><font size=-1>Disk</font></td>"
    # . "<td align=center width=7%><font size=-1>%Used</font></td>"
    # . "<td align=left width=76%><font size=-1>Residents</font></td></tr>";
# @output = `/users/an4m/bin/disk 2> /dev/null`;
# shift(@output);
# foreach $line (@output)
# {
	# $_ = $line; s/^\s+//; @components = split;
	# print NEW "<tr><td align=center width=10%>$components[0]</td>"
		# . "<td align=center width=7%>$components[1]</td>"
		# . "<td align=center width=7%>$components[2]</td>"
		# . "<td align=left width=76%><font size=-2>";
	# shift(@components); shift(@components); shift(@components);
	# foreach $user (@components)
		# { print NEW "<a href=mailto:$user\@cs.virginia.edu>$user</a> " }
	# print NEW "</font></td></tr>";
# }
# print NEW "</table></td></tr></table>";
print NEW "<hr></center><small>Maintained by <a href=mailto:nuts\@virginia.edu>Nuts</a></small></body></html>\n";
foreach $line (@oldtimes) { print NEW $line; }
close(NEW);
system("mv", "/users/an4m/public_html/.usage.html.$$", "/users/an4m/public_html/usage.html");
