#!/opt/perl/bin/perl

#######################################################################
# Author: Shawn M. Emery
# Date  : 10/15/97
# Program: gather.pl
#
# Revision History:
#
# 10/15/97 : Bind and send to client agents through sockets.
# 11/1/97  : Output statistics to file.
# 11/4/97  : Integrate web server specific statistics.
# 11/20/97 : Implement prediction algorithm based on stats.
#######################################################################

use Socket;
use Sys::Hostname;
use IO::Socket;

&configureInterface();

&receiveMsg();

sub configureInterface
{
	$iaddr = gethostbyname(hostname());

	#print "iaddr: $iaddr\n";

	$proto = getprotobyname('udp');

	# Make sure /etc/services has the wlb udp entry
	$port = getservbyname('wlb', 'udp');

	$paddr = sockaddr_in($port, $iaddr);

	socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) or die "socket: $!";

	bind(SOCKET, $paddr)												or die "bind: $!";
}

sub receiveMsg
{

	$rin = "";

	local ($done = 0);

	vec($rin, fileno(SOCKET), 1) = 1;

	while(select ($rout = $rin, undef, undef, undef) && !$done)
		{

		#print "Received Message!\n";

		($clientpaddr = recv(SOCKET, $buff, 128, 0)) or die "recv: $!";

		($clientport, $clientiaddr) = sockaddr_in($clientpaddr);

		$clientname = gethostbyaddr($clientiaddr, AF_INET);

		#print "\n\nMessage from $clientname\n";

		&processMsg($clientname, $buff);

		}

	print STDOUT "Done receiving messages: rout: $rout\n";

}

sub processMsg
{

	local($client, $message) = @_;

	local($weight);

	@messageArray = split(/:/, $message);

	$type = $messageArray[0];

	#print "messageArray: @messageArray\n";

	#print "type: $type\n";

	if ($type eq "data")
		{
		$cpuUsage = $messageArray[2];
		#print "cpuUsage: $cpuUsage\n";

		$avgPing = $messageArray[4];
		#print "avgPing: $messageArray[4]\n";

		$runQueue = $messageArray[6];
		#print "runQueue: $messageArray[6]\n";

		$swapOut = $messageArray[8];
		#print "swapOut: $messageArray[8]\n";

		$rps = $messageArray[10];
		#print "rps: $messageArray[10]\n";

		$busy = $messageArray[12];
		#print "busy: $messageArray[12]\n";

		$idle = $messageArray[14];
		#print "idle: $messageArray[14]\n";

		$weight = calcWeight($client, $cpuUsage, $avgPing, $runQueue, $swapOut, 
			$rps, $busy, $idle);

		#print "Weight: $weight\n";

		&outputFile($client, $weight, $cpuUsage, $avgPing, $runQueue, $swapOut, 
			$rps, $busy, $idle);
		}
	elsif($type eq "alarm")
		{
		}
	else
		{
		print STDERR "Unknown packet $type received by server\n";
		}

}

sub calcWeight
{
  local($host, $cu, $ap, $rq, $so, $rps, $b, $i) = @_;

	local($weight);

	$weight = 0;

	if ($rq <= 30) { $weight += 19.6*((30-$rq)/30); }

	$weight += 19.58*($cu/100);

	if ($ap <= 400) { $weight += 17.24*((400-$ap)/400); }

	$weight += 19.64*($rps/10);

	if ($so <= 200) { $weight += 4.23*((200-$so)/200); }

	$weight += 19.68*($i/20);

	$weight = int $weight;

	return $weight;
}

sub outputFile
{

  local($host, $w, $cu, $ap, $rq, $so, $rps, $b, $i) = @_;

  local ($found = 0, $cont = 0, $newString = "");

  open(STATFILE, "</tmp/statFile") or $cont = 1;

  open(TEMPFILE, ">/tmp/tempFile") || print STDERR "Can't open tempFile";

  while(!$cont && ($line = <STATFILE>))
    {
		chomp ($line);

		$_ = $line;
		
    if(/$host/)
      {
      $found = 1;
		
      $newLine = join(":", $host, $w, $cu, $ap, $rq, $so, $rps, $b, $i);

			$newString .= "$newLine\n"; 
      }
    else
      {
			$newString .= "$line\n";
      }
    }
  if(!$found)
    {
    $newLine = join(":", $host, $w, $cu, $ap, $rq, $so, $rps, $b, $i);

		$newString .= "$newLine\n";
    }

	print TEMPFILE $newString;

  close STATFILE;

  close TEMPFILE;

  rename ("/tmp/tempFile", "/tmp/statFile");
}
