#!/usr/bin/perl # # Example script showing how to use Term::VT102 with Net::Telnet. Telnets to # localhost and dumps what Term::VT102 thinks should be on the screen. # use strict; use Net::Telnet qw(TELOPT_TTYPE); use Term::VT102; use HTML::FromANSI; use Continuity; use Time::HiRes qw(usleep); $| = 1; Continuity->new( port => 8080 )->loop; sub main { my $r = shift; my ($host, $port) = ('localhost', 23); my $t = new Net::Telnet ( 'Host' => $host, 'Port' => $port, 'Errmode' => 'return', 'Timeout' => 1, 'Output_record_separator' => '', ); die "failed to connect to $host:$port" if (not defined $t); $t->option_callback (\&opt_callback); $t->option_accept ('Do' => TELOPT_TTYPE); $t->suboption_callback (\&subopt_callback); $t->timeout(undef); my $vt = Term::VT102->new ( 'cols' => 80, 'rows' => 23, ); $vt->option_set ('LFTOCRLF', 1); $vt->option_set ('LINEWRAP', 1); $vt->callback_set ('OUTPUT', \&vt_output, $t); my ($telnetbuf, $io, $stdinbuf); my $html_vt = HTML::FromANSI->new( terminal_object => $vt ); $r->print(q| <html> <head> <style> body { background-color: black; } </style> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> function listenLoop() { $.getScript('/', function(){ listenLoop(); }); } var keychar; var keycode; $(function(){ $('#f').submit(function() { return false; }); $('#cmd').focus(); $('#cmd').keypress(function(event){ keychar = String.fromCharCode( event.charCode ? event.charCode : event.keyCode ); }); $('#cmd').keyup(function(event){ keycode = event.keyCode; $('#term').load('/',{keycode: keycode, keychar: keychar}); keycode = ''; keychar = ''; }); $('#term').load('/'); setInterval(function(){ $('#term').load('/'); }, 500); }); </script> </head> <body> <div id="term"></div> <form id="f"> <input id=cmd type=text name=cmd length=80> </form> <br><br> KEY: <span id="key"></span> </body> </html> |); $r->next; while (1) { print STDERR "Getting telnet buffer.\n"; #$telnetbuf = $t->get ('Timeout' => undef); $telnetbuf = $t->get ('Timeout' => 0); print STDERR "Got telnet buffer ($telnetbuf).\n"; #$telnetbuf = $t->get (); last if ($t->eof ()); print STDERR "Sending buffer to VT.\n"; $vt->process($telnetbuf);# if (defined $telnetbuf); print STDERR "Buffer sent to VT.\n"; $r->print($html_vt->html); $r->next; my $keycode = $r->param('keycode'); my $keychar = $r->param('keychar'); if($keycode || $keychar) { print STDERR "Keycode: $keycode\n"; print STDERR "Keychar: $keychar\n"; $keychar = undef if $keychar eq 'undefined'; my $v = $keychar || ($keycode ? chr($keycode) : ''); print STDERR "Sending '$v' to telnet\n"; $t->print($v); print STDERR "Sent '$v' to telnet\n"; # usleep(10); } } $t->close (); print "\n"; # Callback for "DO" handling - for Net::Telnet. # sub opt_callback { my ($obj,$opt,$is_remote,$is_enabled,$was_enabled,$buf_position) = @_; if ($opt == TELOPT_TTYPE and $is_enabled and !$is_remote) { # # Perhaps do something if we get TELOPT_TTYPE switched on? # } return 1; } # Callback for sub-option handling - for Net::Telnet. # sub subopt_callback { my ($obj, $opt, $parameters) = @_; my ($ors_old, $otm_old); # Respond to TELOPT_TTYPE with "I'm a VT102". # if ($opt == TELOPT_TTYPE) { $ors_old = $obj->output_record_separator (''); $otm_old = $obj->telnetmode (0); $obj->print ( "\xff\xfa", pack ('CC', $opt, 0), 'vt102', "\xff\xf0" ); $obj->telnetmode ($otm_old); $obj->output_record_separator ($ors_old); } return 1; } # Callback for OUTPUT events - for Term::VT102. # sub vt_output { my ($vtobject, $type, $arg1, $arg2, $private) = @_; if ($type eq 'OUTPUT') { $private->print ($arg1); } } } # EOF