ARCv2

 view release on metacpan or  search on metacpan

lib/Arc/Connection/Client.pm  view on Meta::CPAN

	}
	return !$this->{_error} && $this->{_authenticated};
}

## ends the connection.
## Tells the server that we want to end the conversation. (Userlevel)
## Protocol command: QUIT\r\n
##out> always true
##eg> $arc->Quit();
sub Quit
{
	my $this = shift;
	$this->_SendCommand("QUIT");
	$this->{_connection}->close();
	$this->{_connected} = 0;
	$this->{_expectedcmds} = qw();
	return 1;
}

## process a command.
## This function runs a command with STDIN and STDOUT as clients 
## in- and output control.
##in> ... (command and its parameters)
##out> true if successful, false if not. (IsError is set appropriatly)
##eg> $arc->ProcessCommand("whoami");
sub ProcessCommand
{
	my $this = shift;

	return unless $this->CommandStart(@_);

	STDOUT->autoflush(1);
	$this->_ReadWriteBinary(*STDIN,*STDOUT);

	return $this->CommandEnd();
}

## start an ARCv2 command
## This function starts the given ARCv2 Command and enables the Command* functions.
##in> ... (command and its parameters)
##out> true if successful, false if not. (IsError is set appropriatly)
##eg> if ($arc->CommandStart()) { ... }
sub CommandStart
{
	my $this = shift;
	return $this->_SetError("You are not authenticated.") unless $this->{_authenticated};
	return $this->_SetError("Already running a command.") if defined $this->{_cmdclientsock};
	return unless @_;
	return unless $this->_Cmd(@_);

	while (!$this->{_error} && (not defined $this->{_cmdclientsock}) && (my $cmd = $this->_RecvCommand()) ) {
		$this->_ProcessLine($cmd);
		last if $cmd eq "DONE";
	}
	return 1 if defined $this->{_cmdclientsock};
	return;
}

## write something to the command.
## Write something to the standard input of the command started by C<CommandStart>.
##in> ... (data)
##out> true if successful, false if not. (IsError is set appropriatly)
##eg> last unless $this->CommandWrite();
sub CommandWrite
{
	my $this = shift;
	return $this->_SetError("There is no command running.") unless defined $this->{_cmdclientsock};
	return unless @_;

	my $str = join("",@_);
	$str = $this->{_sasl}->encode($str);

	return $this->{_cmdclientsock}->syswrite($str);
}

## close the write part of the netsock.
## This function closes the write-part of the command connection.
##out> true if successful, false if not. (IsError is set appropriatly)
##eg> last unless $arc->CommandEOF();
sub CommandEOF
{
	my $this = shift;
	return $this->_SetError("There is no command running.") unless defined $this->{_cmdclientsock};

	return shutdown($this->{_cmdclientsock},1);
}

## read data from the Command connection.
##out> if successful the received data is returned, otherwise false.
##eg> while (my $data = $arc->CommandRead()) { ... }
sub CommandRead
{
	my $this = shift;
	return $this->_SetError("There is no command running.") unless defined $this->{_cmdclientsock};

	my $sel = new IO::Select ( $this->{_cmdclientsock} );
	my $buf;
	while ($sel->can_read($this->{timeout})) {
		return unless $this->{_cmdclientsock}->sysread($buf,1024);
		$buf = $this->{_sasl}->decode($buf);
		next unless $buf; # SASL incomplete decode
		return $buf;
	}
	return;
}

## end the command on the server side.
## Closes the command connection and ends the command.
##out> true if successful, false if not. (IsError is set appropriatly)
##eg> $arc->CommandEnd();
sub CommandEnd
{
	my $this = shift;
	return $this->_SetError("There is no command running.") unless defined $this->{_cmdclientsock};

	if ($this->{protocol} == 1) {
# encrypted protocol and command connection, don't lose synchronized sasl_de/encode
		$this->CommandEOF();
		while ($_ = $this->CommandRead()) { $this->_Debug("read text: ".$_); };
	}		

	$this->{_cmdclientsock}->close();
	$this->{_cmdclientsock} = undef;

	while (my $cmd = $this->_RecvCommand()) {
		last unless $this->_ProcessLine($cmd);
		last if $cmd eq "DONE";
	}

	return if $this->{_error};
	return 1;
}

return 1;



( run in 0.852 second using v1.01-cache-2.11-cpan-39bf76dae61 )