#!/usr/local/bin/perl

#-------------------------------------------------------------------------
#--	adm.pl    -  A simple admin activator				--
#--									--
#--	To run, type   adm.pl [port-number]   at the shell prompt.	--
#--	Default port number is 8080.					--
#--									--
#-------------------------------------------------------------------------

#---------  Change as required  --------------

$ITTC_HOME = "/u/dabo/ITTC";
$admittc = "$ITTC_HOME/runtime/bin_sol26x86/admittc";

#---------------------------------------------

require "sys/socket.ph";
srand (time||$$);

#---  Define a friendly exit handler

$SIG{'KILL'} = $SIG{QUIT} = $SIG{INT} = 'exit_handler';
sub exit_handler {
    print "\n\n --- Admin script is dying ...\n\n";
    close(SOCKET);
    exit;
}

#---  Setup socket

$| = 1;
$proxy_port = shift(@ARGV);
$proxy_port = 8080 unless $proxy_port =~ /\d+/;

$socket_format = 'S n a4 x8';

&listen_to_port(SOCKET, $proxy_port);

$local_host = `hostname`;
chop($local_host);
$local_host_ip = (gethostbyname($local_host))[4];
print " --- Admin script running on $local_host port: $proxy_port \n\n";

#---  Loop forever taking requests as they come

while (1) {

#---  Wait for request

    print "\n\n --- Waiting to be of service ...\n";
    ($addr = accept(CHILD,SOCKET)) || die "accept $!";

    ($port,$inetaddr) = (unpack($socket_format,$addr))[1,2];
    @inetaddr = unpack('C4',$inetaddr);
    print "Connection from ", join(".", @inetaddr), "  port: $port \n\n";

# TODO:  Make sure connection is from localhost:  127.0.0.1

#---  Read first line of request and analyze it.

    $first = <CHILD>;
#    print $first;
    $method = ($first =~ m!(POST)!)[0];

#---  Check if method is POST.
    
    if ($method ne "POST") {
	while (<CHILD>) {
	    print $_;
	    last if ($_ =~ /^[\s\x00]*$/);
	}
	print "Invalid HTTP request from ", join(".", @inetaddr), "\n";
#	print CHILD "Content-Type: text/plain","\n\n";
	print CHILD "Not a valid POST request. Method = ", $method, "\n";
	close(CHILD);
	next;
    }

#---  Ignore junk part.

    while (<CHILD>) {
#	print $_;
	if ($_ =~ /Content-Length/i) {  
	  $content_len = ($_ =~ /:\s*(\d*)/)[0];
	}
	last if ($_ =~ /^[\s\x00]*$/);
    }

#---  Read POST data.

    read(CHILD, $buffer, $content_len);
#    print "Length: ", $content_len, "\n";
#    print $buffer, "\n\n";

    @pairs = split(/&/, $buffer);
    foreach $pair (@pairs) {
        ($name, $value) = split(/=/, $pair);
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
        $value =~ s/<!--(.|\n)*-->//g;
        $value =~ s/<([^>]|\n)*>//g;
        $INPUT{$name} = $value;
    }

    if ($INPUT{'Config'} eq "") {
      print "No config file supplied.\n";
      close (CHILD);
      next;
    }
    $params = "-c ".$INPUT{'Config'}." ";

    if ($INPUT{'password'} ne "") {
      $params = $params."-password ".$INPUT{'password'}." ";
    }
    
    if ($INPUT{'servers'} eq "") {
      print "Number of servers unspecified.\n";
      close (CHILD);
      next;
    }
    $params = $params." -n ".$INPUT{'servers'}." ";

    if ($INPUT{'all-or-one'} eq "all") {
      $all_or_one = "";
    } else {
      $all_or_one = $INPUT{'server-id'};
    }

    $action = $INPUT{'action'};

#   -------------------------------------
    if ($action eq "Activate server") {
      print STDOUT "Activating server(s) ", $all_or_one, "\n";

      $params = $params."-start $all_or_one ";

#   -------------------------------------
    } elsif ($action eq "Suspend server") {
      print STDOUT "Suspending server(s) ", $all_or_one, "\n";

      $params = $params."-suspend $all_or_one ";

#   -------------------------------------
    } elsif ($action eq "Shutdown server") {
      print STDOUT "Shuting down server(s) ", $all_or_one, "\n";

      $params = $params."-shutdown $all_or_one ";

#   -------------------------------------
    } elsif ($action eq "Corrupt server") {
      print STDOUT "Corrupting server(s) ", $all_or_one, "\n";

      $params = $params."-corrupt $all_or_one ";

#   -------------------------------------
    } elsif ($action eq "Generate a key") {
      print STDOUT "Generating a ", $INPUT{'threshold'}, " out of ", 
		$INPUT{'numservers'}, " key of size ", $INPUT{'keysize'}, 
		".\n";

      $keysize = substr($INPUT{'keysize'}, 0, index($INPUT{'keysize'},"."));
      $params = $params."-gen $keysize $INPUT{'threshold'} $INPUT{'keyname'} ";

#   -------------------------------------
    } elsif ($action eq "Refersh keys") {
      print STDOUT "Refreshing server ", $INPUT{'server-id'}, "\n";

      $params = $params."-refresh $INPUT{'keyname'} ";
    } 
#   -------------------------------------

    print STDOUT "\n $admittc $params\n\n";

    $status = system($admittc." ".$params);

#    print CHILD "Content-Type: text/html\n\n";

    if ($status) {
      print CHILD  "An error occured.  Sorry... \n";
      print STDOUT "An error occured.  Sorry... \n";
    } else {
      print CHILD  "Operation completed successfully. \n";
      print STDOUT "Operation completed successfully. \n";
    }
   
    close(CHILD);
}

#-------------------------------------------------------------------------
#--	listen_to_port(SOCKET, $port)					--
#--									--
#--	Create a socket that listens to a specific port			--
#-------------------------------------------------------------------------

sub listen_to_port {

    local ($port) = $_[1];

    local ($socket_format, $proto, $packed_port, $cur, $max_requests);

    $max_requests = 3;		# Max number of outstanding requests

    $socket_format = 'S n a4 x8';
    $proto = (getprotobyname('tcp'))[2];
    $packed_port = pack($socket_format, &AF_INET, $port, "\0\0\0\0");

    socket($_[0], &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
    bind($_[0], $packed_port) || die "bind: $!";
    listen($_[0], $max_requests) || die "listen: $!";

    $cur = select($_[0]);  
    $| = 1;				# Disable buffering on socket.
    select($cur);
    }





