summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2009-06-26 22:54:12 -0500
committerJesse Luehrs <doy@tozt.net>2009-06-26 22:54:12 -0500
commit71ef1a711e5a1ac2b896aefdd60231c1af518c62 (patch)
treeff9d35f0e5b742b9cd4a90b511a0c943b141a91f
downloadio-socket-telnet-halfduplex-71ef1a711e5a1ac2b896aefdd60231c1af518c62.tar.gz
io-socket-telnet-halfduplex-71ef1a711e5a1ac2b896aefdd60231c1af518c62.zip
initial commit
-rw-r--r--lib/IO/Socket/Telnet/HalfDuplex.pm53
1 files changed, 53 insertions, 0 deletions
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;