version 1.21, 2003/11/03 10:39:24
|
version 1.25, 2003/11/04 11:52:06
|
Line 63 use lib ".";
|
Line 63 use lib ".";
|
use strict; # Because it's good practice. |
use strict; # Because it's good practice. |
use English; # Cause I like meaningful names. |
use English; # Cause I like meaningful names. |
use Getopt::Long; |
use Getopt::Long; |
use IO::Socket::UNIX; # To communicate with lonc. |
|
use LondConnection; |
use LondConnection; |
|
use IO::Poll qw(POLLRDNORM POLLWRNORM POLLIN POLLHUP POLLOUT); |
|
|
# File scoped variables: |
# File scoped variables: |
|
|
Line 73 my %hostshash; # Host table as a host
|
Line 73 my %hostshash; # Host table as a host
|
|
|
my $MyHost=""; # Host name to use as me. |
my $MyHost=""; # Host name to use as me. |
my $ForeignHostTab=""; # Name of foreign hosts table. |
my $ForeignHostTab=""; # Name of foreign hosts table. |
|
|
|
my $DefaultServerPort = 5663; # Default server port if standalone. |
my $ServerPort; # Port used to connect to lond. |
my $ServerPort; # Port used to connect to lond. |
|
|
|
my $TransitionTimeout = 5; # Poll timeout in seconds. |
|
|
|
|
|
# LondConnection::SetDebug(10); |
|
|
|
|
# |
# |
# prints out utility's command usage info. |
# prints out utility's command usage info. |
# |
# |
Line 112 USAGE
|
Line 120 USAGE
|
|
|
} |
} |
|
|
|
# |
|
# Make a direct connection to the lond in 'host'. The port is |
|
# gotten from the global variable: ServerPort. |
|
# Returns: |
|
# The connection or undef if one could not be formed. |
|
# |
sub MakeLondConnection { |
sub MakeLondConnection { |
my $host = shift; |
my $host = shift; |
return "junk"; |
|
|
my $Connection = LondConnection->new($host, $ServerPort); |
|
return return $Connection; |
|
} |
|
# |
|
# Process the connection state machine until the connection |
|
# becomes idle. This is used both to negotiate the initial |
|
# connection, during which the LondConnection sequences a rather |
|
# complex state machine and during the transaction itself |
|
# for a simpler set of transitions. |
|
# All we really need to be concerned with is whether or not |
|
# we're readable or writable and the final state: |
|
# |
|
# Parameter: |
|
# connection - Represents the LondConnection to be sequenced. |
|
# timeout - Maximum time to wait for readable/writable sockets. |
|
# in seconds. < 0 waits forever. |
|
# Return: |
|
# 'ok' - We got to idle ok. |
|
# 'error:msg' - An error occured. msg describes the error. |
|
# |
|
sub SequenceStateMachine { |
|
my $connection = shift; |
|
my $timeout = shift; |
|
|
|
my $Socket = $connection->GetSocket; |
|
my $returnstatus = "ok"; # optimist!!! |
|
my $error = 0; # Used to force early loop termination |
|
# damned perl has no break!!. |
|
my $state = $connection->GetState; |
|
|
|
while(($connection->GetState ne "Idle") && (!$error)) { |
|
# |
|
# Figure out what the connection wants. read/write and wait for it |
|
# or for the timeout. |
|
# |
|
my $wantread = $connection->WantReadable; |
|
my $poll = new IO::Poll; |
|
$poll->mask($Socket, => $wantread ? POLLIN : POLLOUT); |
|
$poll->poll($timeout); |
|
my $done = $poll->handles(); |
|
if(scalar($done) == 0) { # no handles ready... timeout!! |
|
$returnstatus = "error:"; |
|
$returnstatus .= "Timeout in state $state\n"; |
|
$error = 1; |
|
} else { |
|
my $status; |
|
$status = $wantread ? $connection->Readable : |
|
$connection->Writable; |
|
if($status != 0) { |
|
$returnstatus = "error:"; |
|
$returnstatus .= " I/O failed in state $state\n"; |
|
$error = 1; |
|
} |
|
} |
|
$state = $connection->GetState; |
|
} |
|
return $returnstatus; |
} |
} |
|
|
|
# |
|
# This function runs through the section of the connection |
|
# state machine that has to do with negotiating the startup |
|
# sequence with lond. The general strategy is to loop |
|
# until the connection state becomes idle or disconnected. |
|
# Disconnected indicates an error or rejection of the |
|
# connection at some point in the negotiation. |
|
# idle indicates a connection ready for a request. |
|
# The main loop consults the object to determine if it |
|
# wants to be writeable or readable, waits for that |
|
# condition on the socket (with timeout) and then issues |
|
# the appropriate LondConnection call. Note that |
|
# LondConnection is capable of doing everything necessary |
|
# to get to the initial idle state. |
|
# |
|
# |
|
# Parameters: |
|
# connection - A connection that has been created with |
|
# the remote lond. This connection should |
|
# be in the Connected state ready to send |
|
# the init sequence. |
|
# |
sub NegotiateStartup { |
sub NegotiateStartup { |
my $connection = shift; |
my $connection = shift; |
|
my $returnstatus = "ok"; # Optimistic!!. |
|
|
return "ok"; |
my $state = $connection->GetState; |
|
if($state ne "Connected") { |
|
print "Error: Initial lond connection state: $state should be Connected\n"; |
|
return "error"; |
|
} |
|
|
|
return SequenceStateMachine($connection, $TransitionTimeout); |
} |
} |
|
# |
|
# Perform a transaction with the remote lond. |
|
# Paramters: |
|
# connection - the connection object that represents |
|
# a LondConnection to the remote lond. |
|
# command - The request to send to the remote system. |
|
# Returns: |
|
# The 'reaction' of the lond to this command. |
|
# However if the connection to lond is lost during the transaction |
|
# or some other error occurs, the text "error:con_lost" is returned. |
|
# |
sub PerformTransaction { |
sub PerformTransaction { |
my $connection = shift; |
my $connection = shift; |
my $command = shift; |
my $command = shift; |
|
my $retval; # What we'll returnl. |
|
|
return "ok"; |
|
|
# Set up the connection to do the transaction then |
|
# do the I/O until idle or error. |
|
# |
|
$connection->InitiateTransaction($command); |
|
|
|
my $status = SequenceStateMachine($connection, $TransitionTimeout); |
|
if($status eq "ok") { |
|
$retval = $connection->GetReply; |
|
} else { |
|
$retval = $status; |
|
} |
|
|
|
return $retval; |
} |
} |
# |
# |
# Performs a transaction direct to a remote lond. |
# Performs a transaction direct to a remote lond. |
Line 147 sub subreply {
|
Line 272 sub subreply {
|
return "Connect Failed"; |
return "Connect Failed"; |
} |
} |
my $reply = NegotiateStartup($connection); |
my $reply = NegotiateStartup($connection); |
if($reply != "ok") { |
if($reply ne "ok") { |
return "connection negotiation failed"; |
return "connection negotiation failed"; |
} |
} |
my $reply = PerformTransaction($connection, $cmd); |
my $reply = PerformTransaction($connection, $cmd); |
Line 277 sub ReadConfig {
|
Line 402 sub ReadConfig {
|
$MyHost = $perlvar{lonHostID}; # Set hostname from vars. |
$MyHost = $perlvar{lonHostID}; # Set hostname from vars. |
$ServerPort = $perlvar{londPort}; |
$ServerPort = $perlvar{londPort}; |
} else { |
} else { |
my $hoststab = LondConnection::read_hosts($ForeignHostTab); |
|
%hostshash = %{$hoststab}; |
LondConnection::ReadForeignConfig($MyHost, $ForeignHostTab); |
$ServerPort = 5663; |
my $hoststab = LondConnection::read_hosts($ForeignHostTab); # we need to know too. |
} |
%hostshash = %{$hoststab}; |
|
$ServerPort = $DefaultServerPort; |
|
} |
|
|
} |
} |
# |
# |
# Determine if the target host is valid. |
# Determine if the target host is valid. |