From 71ef1a711e5a1ac2b896aefdd60231c1af518c62 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 26 Jun 2009 22:54:12 -0500 Subject: initial commit --- lib/IO/Socket/Telnet/HalfDuplex.pm | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 lib/IO/Socket/Telnet/HalfDuplex.pm diff --git a/lib/IO/Socket/Telnet/HalfDuplex.pm b/lib/IO/Socket/Telnet/HalfDuplex.pm new file mode 100644 index 0000000..2e8eb95 --- /dev/null +++ b/lib/IO/Socket/Telnet/HalfDuplex.pm @@ -0,0 +1,53 @@ +package IO::Socket::Telnet::HalfDuplex; +use base 'IO::Socket::Telnet'; + +sub new { + my $class = shift; + my %args = @_; + my $code = delete $args{code} || 99; + my $self = $class->SUPER::new(@_); + ${*{$self}}{code} = $code; + $self->telnet_simple_callback(\&telnet_negotiation); + return $self; +} + +sub read { + my $self = shift; + my $buffer; + + $self->do(chr(${*{$self}}{code})); + ${*{$self}}{got_pong} = 0; + + eval { + local $SIG{__DIE__}; + + while (1) { + my $b; + defined $self->recv($b, 4096, 0) and do { + $buffer .= $b; + die "got pong\n" if ${*{$self}}{got_pong}; + next; + }; + die "Disconnected from server: $!" unless $!{EINTR}; + } + }; + + die $@ if $@ !~ /^got pong\n/; + + return $buffer; +} + +sub telnet_negotiation { + my $self = shift; + my $option = shift; + + my $code = ${*{$self}}{code}; + if ($option =~ / $code$/) { + ${*{$self}}{got_pong} = 1; + return ''; + } + + return; +} + +1; -- cgit v1.2.3-54-g00ecf