package WebAdmin;

# Services for admin server<->web server communication

use ZeusOS;

# ----------------------------------------------------------
# Usage: host port command errormsg
#
# Sends message to webserver (must be done from webadmin machine so
# communication key can be found).
#
# Returns result string, or undef, in which case errormsg (arg4) is
# filled in with the reason.

sub command {
    my( $host, $port, $command ) = @_;  # arg 4 is error string

    my( $commkey, $buf, $response, $hostip );
    my( $commfile ) = "$ENV{ZEUSHOME}/webadmin/conf/commkey";

    $commkey = "";
    
    # Resolve hostname to ip address
    if( ! ($hostip = gethostbyname( $host )) )  {
	$_[3] = "Unable to resolve $host";
	return;
    }
    
    # If there is a communication key in $ZEUSHOME/webadmin/conf/commkey
    # open and read that
    if( -f $commfile ) {
	local $/;
	local *F;

	if( !open( F, $commfile )) {
	    $_[3] = "Unable to open communication key file: $commfile: $!";
	    return;
	}
	$commkey = scalar <F> || "";
	close F;
	$commkey =~ tr/\t\r\n//d;
    }
    
    # Now open socket connection
    local *S;
    if( !socket( S, $ZeusOS::AF_INET, 
		$ZeusOS::SOCK_STREAM, $ZeusOS::IPPROTO_TCP )) {
	$_[3] = "socket() failed: $!";
	return;
    }

    # Now do network communication
    eval {
	# Set a local timeout, and attempt the following code
	local $SIG{ALRM} = sub { die "operation timeout\n" };

        if( $_[4] ) { alarm( $_[4] ) } else { alarm( 60 ) };
	
	connect( S, ZeusOS::pack_sockaddr_in( $port, $hostip )) or
	    die "connect() failed: $!\n";
	
	$command = $commkey."\t".$command;
	syswrite( S, $command, length( $command )) or 
	    die "syswrite() failed: $!\n";
	
	while( sysread( S, $buf, 1024 )) { $response .= $buf; }
	
	alarm( 0 );
    };

    if( $@ ) {
	# the eval failed in some way, set the response code to undef
	# and the error variable appropriately
	$response = undef;
	$_[3] = $@;
    }
    
    close( S );
    return $response;
}

1;

