Net-Doveadm
view release on metacpan or search on metacpan
lib/Net/Doveadm.pm view on Meta::CPAN
return $self if !$self->_do_handshake();
}
$self->_flush_request_queue();
return $self;
}
sub _validate_command_pieces {
my ($username, $command_ar) = @_;
for my $piece ($username, @$command_ar) {
if ($piece =~ tr<\t\x0a><>) {
die Net::Doveadm::X->create('Generic', "Invalid string in command: â$pieceâ");
}
}
return;
}
#----------------------------------------------------------------------
=head2 $RESULT = I<OBJ>->receive()
Looks for a response to a previously-sent command. If such a response is
ready,
it will be returned as an array reference; otherwise, undef is returned.
Note that, if the server handshake is not yet complete, this will
attempt to finish that before actually trying to retrieve a message.
=cut
sub receive {
my ($self) = @_;
if (!$self->{'_handshake_done'}) {
return undef if !$self->_do_handshake();
# If we just finished the handshake, then send any pending requests
# before we see about responses to them.
$self->_flush_request_queue();
}
if ( !@{ $self->{'_requests'} } && !$self->{'_sent_requests'} ) {
die Net::Doveadm::X->create('Generic', "No requests pending!");
}
$self->{'_line1'} ||= $self->_read_line() or return undef;
$self->{'_line2'} ||= $self->_read_line() or return undef;
$self->{'_sent_requests'}--;
my ($line1, $line2) = delete @{$self}{'_line1', '_line2'};
if ($line2 ne '+') {
die Net::Doveadm::X->create('Response', "Error: $line2 ($line1)");
}
return [ split m<\t>, $line1, -1 ];
}
#----------------------------------------------------------------------
sub _flush_request_queue {
my ($self) = @_;
while ($self->_write($self->{'_requests'}[0])) {
shift @{ $self->{'_requests'} };
$self->{'_sent_requests'}++;
}
return;
}
sub _do_handshake {
my ($self) = @_;
if (!$self->{'_sent_hello'}) {
$self->_write( [ 'VERSION', 'doveadm-server', 1, 0 ] );
$self->{'_sent_hello'} = 1;
return undef;
}
$self->{'_received_hello'} ||= $self->_read_line() or return undef;
if ($self->{'_received_hello'} eq '+') {
$self->{'_handshake_done'} = 1;
for my $key ( qw( username password ) ) {
if ($self->{"_$key"}) {
warn "â$keyâ submitted, but server says unneeded.";
}
}
}
elsif ($self->{'_received_hello'} eq '-') {
if (!$self->{'_authn_sent'}) {
$self->_send_authn();
$self->{'_authn_sent'} = 1;
return undef;
}
$self->{'_received_authn'} ||= $self->_read_line() or return undef;
if ($self->{'_received_authn'} eq '+') {
$self->{'_handshake_done'} = 1;
}
else {
die Net::Doveadm::X->create('Authn', "Failed authn: â$self->{'_received_authn'}â");
}
}
return 1;
}
sub _send_authn {
( run in 0.592 second using v1.01-cache-2.11-cpan-71847e10f99 )