home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl_ste.zip / Net / Telnet.pm < prev    next >
Text File  |  1997-03-15  |  80KB  |  3,056 lines

  1. package Net::Telnet;
  2. require 5.002;
  3.  
  4. ## User documentation in POD format at bottom of file.  Search for =head
  5.  
  6. use strict;
  7.  
  8. ## Module import. 
  9. use Exporter ();
  10. use Socket qw(AF_INET SOCK_STREAM inet_aton sockaddr_in);
  11.  
  12. ## Base classes.
  13. use vars qw(@ISA);
  14. @ISA = qw(Exporter);
  15. if (eval 'require IO::Socket') {
  16.     push @ISA, 'IO::Socket::INET';
  17. }
  18. else {
  19.     require FileHandle;
  20.     push @ISA, 'FileHandle';
  21. }
  22.  
  23. ## Global variables.
  24. use vars qw($VERSION $Default_blksize);
  25. $VERSION = "3.00";
  26. $Default_blksize = 8192;
  27.  
  28.  
  29. ########################### Public Methods ###########################
  30.  
  31.  
  32. sub new {
  33.     my($class) = @_;
  34.     my(
  35.        $fh_open,
  36.        $host,
  37.        $self,
  38.        %args,
  39.        );
  40.  
  41.     ## Create a new object with defaults.
  42.     $self = $class->SUPER::new;
  43.     $ {*$self}{net_telnet} = {
  44.     bin_mode     => '',
  45.     blksize      => $Default_blksize,
  46.     buf          => '',
  47.     cmd_prompt   => '/[$%#>] $/',
  48.     eofile       => 1,
  49.     errormode    => 'die',
  50.     errormsg     => '',
  51.     fdmask       => '',
  52.     host         => 'localhost',
  53.     inputlog     => '',
  54.     last_line    => '',
  55.     maxbufsize   => 1024 * 1024,
  56.     dumplog      => '',
  57.     num_wrote    => 0,
  58.     ofs          => '',
  59.     opened       => '',
  60.     ors          => "\n",
  61.     outputlog    => '',
  62.     port         => 23,
  63.     pushback_buf => '',
  64.     rs           => "\n",
  65.     telnet_mode  => 1,
  66.     time_out     => 10,
  67.     timedout     => '',
  68.     unsent_opts  => '',
  69.     };
  70.  
  71.     ## Parse the args.
  72.     if (@_ == 2) {  # one positional arg given
  73.     $host = $_[1];
  74.     }
  75.     elsif (@_ > 2) {  # named args given
  76.     ## Get the named args.
  77.     (undef, %args) = @_;
  78.  
  79.     ## Parse the errmode named arg first.
  80.     foreach (keys %args) {
  81.         $self->errmode($args{$_})
  82.         if /^-?errmode$/i;
  83.     }
  84.     
  85.     ## Parse all other named args.
  86.     foreach (keys %args) {
  87.         if (/^-?binmode$/i) {
  88.         $self->binmode($args{$_});
  89.         }
  90.         elsif (/^-?dump_log$/i) {
  91.         $self->dump_log($args{$_});
  92.         }
  93.         elsif (/^-?errmode$/i) {
  94.         next;
  95.         }
  96.         elsif (/^-?fhopen$/i) {
  97.         $fh_open = $args{$_};
  98.         }
  99.         elsif (/^-?host$/i) {
  100.         $host = $args{$_};
  101.         }
  102.         elsif (/^-?input_log$/i) {
  103.         $self->input_log($args{$_});
  104.         }
  105.         elsif (/^-?input_record_separator$/i) {
  106.         $self->input_record_separator($args{$_});
  107.         }
  108.         elsif (/^-?output_log$/i) {
  109.         $self->output_log($args{$_});
  110.         }
  111.         elsif (/^-?output_record_separator$/i) {
  112.         $self->output_record_separator($args{$_});
  113.         }
  114.         elsif (/^-?port$/i) {
  115.         $self->port($args{$_})
  116.             or return;
  117.         }
  118.         elsif (/^-?prompt$/i) {
  119.         $self->prompt($args{$_})
  120.             or return;
  121.         }
  122.         elsif (/^-?telnetmode$/i) {
  123.         $self->telnetmode($args{$_});
  124.         }
  125.         elsif (/^-?timeout$/i) {
  126.         $self->timeout($args{$_});
  127.         }
  128.         else {
  129.         $self->error('usage: Net::Telnet->new(' .
  130.                  '[Binmode => $mode,] ' .
  131.                  '[Dump_Log => $filename,] ' .
  132.                  '[Errmode => $errmode,] ' .
  133.                  '[Fhopen => $filehandle,] ' .
  134.                  '[Host => $host,] ' .
  135.                  '[Input_log => $file,] ' .
  136.                  '[Input_record_separator => $char,] ' .
  137.                  '[Output_log => $file,] ' .
  138.                  '[Output_record_separator => $char,] '.
  139.                  '[Port => $port,] [Prompt => $matchop,] ' .
  140.                  '[Telnetmode => $mode,] ' .
  141.                  '[Timeout => $secs,])');
  142.         }
  143.     }
  144.     }
  145.  
  146.     if (defined $fh_open) {  # user wants us to attach to existing filehandle
  147.     $self->fhopen($fh_open)
  148.         or return;
  149.     }
  150.     elsif (defined $host) {  # user want us to open a connection to host
  151.     $self->host($host)
  152.         or return;
  153.     $self->open
  154.         or return;
  155.     }
  156.  
  157.     $self;
  158. } # end sub new
  159.  
  160.  
  161. sub DESTROY {
  162. } # end sub DESTROY
  163.  
  164.  
  165. sub binmode {
  166.     my($self, $mode) = @_;
  167.     my(
  168.        $prev,
  169.        $stream,
  170.        );
  171.  
  172.     ## With no args, turn on binary mode.
  173.     if (@_ < 2) {
  174.     $mode = 1;
  175.     }
  176.     else {
  177.     defined $mode or $mode = '';
  178.     }
  179.  
  180.     $stream = $ {*$self}{net_telnet};
  181.     $prev = $stream->{bin_mode};
  182.     $stream->{bin_mode} = $mode;
  183.     $prev;
  184. } # end sub binmode
  185.  
  186.  
  187. sub break {
  188.     my($self) = @_;
  189.     my $stream = $ {*$self}{net_telnet};
  190.     $stream->{timedout} = '';
  191.     return if $stream->{eofile};
  192.     local $stream->{rs} = '';
  193.  
  194.     $self->print("\xff\xf3");
  195. } # end sub break
  196.  
  197.  
  198. sub close {
  199.     my($self) = @_;
  200.     my $stream = $ {*$self}{net_telnet};
  201.  
  202.     $stream->{eofile} = 1;
  203.     $stream->{opened} = '';
  204.     close $self
  205.     if defined fileno($self);
  206.  
  207.     1;
  208. } # end sub close
  209.  
  210.  
  211. sub cmd {
  212.     my($self, @args) = @_;
  213.     my(
  214.        $arg,
  215.        $firstpos,
  216.        $lastpos,
  217.        $lines,
  218.        $orig_errmode,
  219.        $orig_prompt,
  220.        $orig_timeout,
  221.        $output,
  222.        $output_ref,
  223.        $prompt,
  224.        $rs,
  225.        $rs_len,
  226.        $timeout,
  227.        @cmd,
  228.        );
  229.  
  230.     ## Init vars.
  231.     $output = [];
  232.     $timeout = $self->timeout;
  233.     $self->timed_out('');
  234.     return if $self->eof;
  235.  
  236.     ## Parse args.
  237.     if (@_ == 2) {  # one positional arg given
  238.     push @cmd, $_[1];
  239.     }
  240.     elsif (@_ > 2) {  # named args given
  241.     ## Parse the named args.
  242.     while (($_, $arg) = splice @args, 0, 2) {
  243.         if (/^-?output$/i) {
  244.         $output_ref = $arg;
  245.         if (defined($output_ref) and ref($output_ref) eq "ARRAY") {
  246.             $output = $output_ref;
  247.         }
  248.         }
  249.         elsif (/^-?prompt$/i) {
  250.         $prompt = $arg;
  251.         }
  252.         elsif (/^-?string$/i) {
  253.         push @cmd, $arg;
  254.         }
  255.         elsif (/^-?timeout$/i) {
  256.         $timeout = &_parse_timeout($arg);
  257.         }
  258.         else {
  259.         return $self->error('usage: $obj->cmd(',
  260.                     '[Output => $ref,] ',
  261.                     '[Prompt => $match,] ',
  262.                     '[String => $string,] ',
  263.                     '[Timeout => $secs,])');
  264.         }
  265.     }
  266.     }
  267.  
  268.     ## Override some user settings.
  269.     $orig_errmode = $self->errmode('return');
  270.     $orig_timeout = $self->timeout(&_endtime($timeout));
  271.     $orig_prompt  = $self->prompt($prompt) if defined $prompt;
  272.     $self->errmsg('');
  273.  
  274.     ## Send command and wait for the prompt.
  275.     $self->print(@cmd)
  276.     and ($lines) = $self->waitfor($self->prompt);
  277.  
  278.     ## Restore user settings.
  279.     $self->errmode($orig_errmode);
  280.     $self->timeout($orig_timeout);
  281.     $self->prompt($orig_prompt) if defined $orig_prompt;
  282.  
  283.     ## Check for failure.
  284.     return $self->error("command timed-out") if $self->timed_out;
  285.     return $self->error($self->errmsg) if $self->errmsg ne '';
  286.     return if $self->eof;
  287.  
  288.     ## Split on record terminator while maintaining terminator in output.
  289.     $firstpos = 0;
  290.     $rs = $self->input_record_separator;
  291.     $rs_len = length $rs;
  292.     while (($lastpos = index($lines, $rs, $firstpos)) > -1) {
  293.     push(@$output,
  294.          substr($lines, $firstpos, $lastpos - $firstpos + $rs_len));
  295.     $firstpos = $lastpos + $rs_len;
  296.     }
  297.  
  298.     if ($firstpos < length $lines) {
  299.     push @$output, substr($lines, $firstpos);
  300.     }
  301.  
  302.     ## Get rid of echo back command.
  303.     shift @$output;
  304.     unless (@$output) {
  305.     @$output = ('');
  306.     }
  307.  
  308.     ## Return command output via named arg, if requested.
  309.     if (defined $output_ref) {
  310.     if (ref($output_ref) eq "SCALAR") {
  311.         $$output_ref = join '', @$output;
  312.     }
  313.     elsif (ref($output_ref) eq "HASH") {
  314.         %$output_ref = @$output;
  315.     }
  316.     }
  317.     
  318.     wantarray ? @$output : 1;
  319. } # end sub cmd
  320.  
  321.  
  322. sub dump_log {
  323.     my($self, $name) = @_;
  324.     my(
  325.        $fh,
  326.        $stream,
  327.        );
  328.  
  329.     $stream = $ {*$self}{net_telnet};
  330.     $fh = $stream->{dumplog};
  331.  
  332.     if (@_ >= 2) {
  333.     $fh = &_fname_to_handle($self, $name);
  334.     $stream->{dumplog} = $fh;
  335.     }
  336.  
  337.     $fh;
  338. } # end sub dump_log
  339.  
  340.  
  341. sub eof {
  342.     my($self) = @_;
  343.  
  344.     $ {*$self}{net_telnet}{eofile};
  345. } # end sub eof
  346.  
  347.  
  348. sub errmode {
  349.     my($self, $mode) = @_;
  350.     my(
  351.        $prev,
  352.        $stream,
  353.        );
  354.  
  355.     $stream = $ {*$self}{net_telnet};
  356.     $prev = $stream->{errormode};
  357.  
  358.     if (@_ >= 2) {
  359.     ## Set the error mode.
  360.     defined $mode or $mode = '';
  361.     if (ref($mode) eq 'CODE') {
  362.         $stream->{errormode} = $mode;
  363.     }
  364.     elsif (ref($mode) eq 'ARRAY') {
  365.         unless (ref($mode->[0]) eq 'CODE') {
  366.         &_carp($self,
  367.                'bad errmode: first item in list must be a code ref');
  368.         $mode = 'die';
  369.         }
  370.         $stream->{errormode} = $mode;
  371.     }
  372.     elsif ($mode =~ /^return$/i) {
  373.         $stream->{errormode} = 'return';
  374.     }
  375.     else {
  376.         $stream->{errormode} = 'die';
  377.     }
  378.     }
  379.  
  380.     $prev;
  381. } # end sub errmode
  382.  
  383.  
  384. sub errmsg {
  385.     my($self, @errmsgs) = @_;
  386.     my(
  387.        $prev,
  388.        $stream,
  389.        );
  390.  
  391.     $stream = $ {*$self}{net_telnet};
  392.     $prev = $stream->{errormsg};
  393.  
  394.     if (@_ >= 2) {
  395.     $stream->{errormsg} = join '', @errmsgs;
  396.     }
  397.  
  398.     $prev;
  399. } # end sub errmsg
  400.  
  401.  
  402. sub error {
  403.     my($self, @errmsg) = @_;
  404.     my(
  405.        $errmsg,
  406.        $func,
  407.        $mode,
  408.        $stream,
  409.        @args,
  410.        );
  411.  
  412.     $stream = $ {*$self}{net_telnet};
  413.  
  414.     if (@_ >= 2) {
  415.     ## Put error message in the object.
  416.     $errmsg = join '', @errmsg;
  417.     $stream->{errormsg} = $errmsg;
  418.  
  419.     ## Do the error action as described by error mode.
  420.     $mode = $stream->{errormode};
  421.     if (ref($mode) eq 'CODE') {
  422.         &$mode($errmsg);
  423.         return;
  424.     }
  425.     elsif (ref($mode) eq 'ARRAY') {
  426.         ($func, @args) = @$mode;
  427.         &$func(@args);
  428.         return;
  429.     }
  430.     elsif ($mode =~ /^return$/i) {
  431.         return;
  432.     }
  433.     else {  # die
  434.         if ($errmsg =~ /\n$/) {
  435.         die $errmsg;
  436.         }
  437.         else {
  438.         ## Die and append caller's line number to message.
  439.         &_croak($self, $errmsg);
  440.         }
  441.     }
  442.     }
  443.     else {
  444.     return $stream->{errormsg} ne '';
  445.     }
  446. } # end sub error
  447.  
  448.  
  449. sub fhopen {
  450.     my($self, $fh) = @_;
  451.     my(
  452.        $blksize,
  453.        $fd,
  454.        $stream,
  455.        );
  456.  
  457.     {
  458.     no strict 'refs';
  459.     $fd = fileno $fh;
  460.     }
  461.  
  462.     ## Ensure associated filehandle is already open.
  463.     return $self->error("fhopen filehandle isn't already open")
  464.     unless defined $fd;
  465.  
  466.     ## Ensure object is closed.
  467.     $self->close;
  468.  
  469.     ## Associate the object with already open filehandle.
  470.     open $self, "+<&=$fd"
  471.     or return $self->error("problem attaching to fhopen filehandle: $!");
  472.     $self->autoflush;
  473.  
  474.     ## Re-initialize the object.
  475.     $stream = $ {*$self}{net_telnet};
  476.     $blksize = (stat $self)[11];
  477.     $stream->{blksize} = $blksize || $Default_blksize;
  478.     $stream->{buf} = '';
  479.     $stream->{eofile} = '';
  480.     vec($stream->{fdmask}='', fileno($self), 1) = 1;
  481.     $stream->{host} = '';
  482.     $stream->{last_line} = '';
  483.     $stream->{num_wrote} = '';
  484.     $stream->{opened} = 1;
  485.     $stream->{pushback_buf} = '';
  486.     $stream->{timedout} = '';
  487.     $stream->{unsent_opts} = '';
  488.     1;
  489. } # end sub fhopen
  490.  
  491.  
  492. sub get {
  493.     my($self, %args) = @_;
  494.     my(
  495.        $endtime,
  496.        $line,
  497.        $stream,
  498.        $timeout,
  499.        );
  500.  
  501.     ## Init vars.
  502.     $stream = $ {*$self}{net_telnet};
  503.     $timeout = $stream->{time_out};
  504.     $stream->{timedout} = '';
  505.     return if $stream->{eofile};
  506.  
  507.     ## Parse the named args.
  508.     foreach (keys %args) {
  509.     if (/^-?timeout$/i) {
  510.         $timeout = &_parse_timeout($args{$_});
  511.     }
  512.     else {
  513.         return $self->error('usage: $obj->get([Timeout => $secs,])');
  514.     }
  515.     }
  516.  
  517.     ## Set wall time when we time out.
  518.     $endtime = &_endtime($timeout);
  519.  
  520.     ## Try to send any waiting option negotiation.
  521.     if (length $stream->{unsent_opts}) {
  522.     &_flush_opts($self, $stream);
  523.     }
  524.  
  525.     ## Try to read just the waiting data using return error mode.
  526.     {
  527.     local $stream->{errormode} = 'return';
  528.     $stream->{errormsg} = '';
  529.     &_fillbuf($self, $stream, 0);
  530.     }
  531.  
  532.     ## We're done if we timed-out and timeout value is set to "poll".
  533.     return if $stream->{timedout} and defined($timeout) and $timeout == 0;
  534.  
  535.     ## We're done if we hit an error other than timing out.
  536.     return $self->error($stream->{errormsg})
  537.     if $stream->{errormsg} and ! $stream->{timedout};
  538.  
  539.  
  540.     ## If buffer is still empty, try to read according to user's timeout.
  541.     if (! length $stream->{buf}) {
  542.     &_fillbuf($self, $stream, $endtime)
  543.         or do {
  544.         return if $stream->{timedout};
  545.  
  546.         ## We've reached end-of-file.
  547.         $self->close;
  548.         return;
  549.         };
  550.     }
  551.  
  552.     ## Extract chars from buffer.
  553.     $line = $stream->{buf};
  554.     $stream->{buf} = '';
  555.  
  556.     $line;
  557. } # end sub get
  558.  
  559.  
  560. sub getline {
  561.     my($self, %args) = @_;
  562.     my(
  563.        $endtime,
  564.        $len,
  565.        $line,
  566.        $offset,
  567.        $pos,
  568.        $stream,
  569.        $timeout,
  570.        );
  571.  
  572.     ## Init vars.
  573.     $stream = $ {*$self}{net_telnet};
  574.     $timeout = $stream->{time_out};
  575.     $stream->{timedout} = '';
  576.     return if $stream->{eofile};
  577.  
  578.     ## Parse the named args.
  579.     foreach (keys %args) {
  580.     if (/^-?timeout$/i) {
  581.         $timeout = &_parse_timeout($args{$_});
  582.     }
  583.     else {
  584.         return $self->error('usage: $obj->getline([Timeout => $secs,])');
  585.     }
  586.     }
  587.  
  588.     ## Set wall time when we time out.
  589.     $endtime = &_endtime($timeout);
  590.  
  591.     ## Try to send any waiting option negotiation.
  592.     if (length $stream->{unsent_opts}) {
  593.     &_flush_opts($self, $stream);
  594.     }
  595.  
  596.     ## Keep reading into buffer until end-of-line is read.
  597.     $offset = 0;
  598.     while (($pos = index($stream->{buf}, $stream->{rs}, $offset)) == -1) {
  599.     $offset = length $stream->{buf};
  600.     &_fillbuf($self, $stream, $endtime)
  601.         or do {
  602.         return if $stream->{timedout};
  603.  
  604.         ## We've reached end-of-file.
  605.         $self->close;
  606.         if (length $stream->{buf}) {
  607.             return $stream->{buf};
  608.         }
  609.         else {
  610.             return;
  611.         }
  612.         };
  613.     }
  614.  
  615.     ## Extract line from buffer.
  616.     $len = $pos + length $stream->{rs};
  617.     $line = substr($stream->{buf}, 0, $len);
  618.     substr($stream->{buf}, 0, $len) = '';
  619.  
  620.     $line;
  621. } # end sub getline
  622.  
  623.  
  624. sub getlines {
  625.     my($self) = @_;
  626.     my(
  627.        $len,
  628.        $line,
  629.        $pos,
  630.        $stream,
  631.        @lines,
  632.        );
  633.  
  634.     $stream = $ {*$self}{net_telnet};
  635.  
  636.     ## Fill buffer and get first line.
  637.     $line = getline(@_)
  638.     or return;
  639.     push @lines, $line;
  640.     
  641.     ## Extract subsequent lines from buffer.
  642.     while (($pos = index($stream->{buf}, $stream->{rs})) != -1) {
  643.     $len = $pos + length $stream->{rs};
  644.     push @lines, substr($stream->{buf}, 0, $len);
  645.     substr($stream->{buf}, 0, $len) = '';
  646.     }
  647.  
  648.     @lines;
  649. } # end sub getlines
  650.  
  651.  
  652. sub host {
  653.     my($self, $host) = @_;
  654.     my(
  655.        $prev,
  656.        $stream,
  657.        );
  658.  
  659.     $stream = $ {*$self}{net_telnet};
  660.     $prev = $stream->{host};
  661.  
  662.     if (@_ >= 2) {
  663.     unless (defined $host and length $host) {
  664.         $host = 'localhost';
  665.     }
  666.     $stream->{host} = $host;
  667.     }
  668.  
  669.     $prev;
  670. } # end sub host
  671.  
  672.  
  673. sub input_log {
  674.     my($self, $name) = @_;
  675.     my(
  676.        $fh,
  677.        $prev,
  678.        $stream,
  679.        );
  680.  
  681.     $stream = $ {*$self}{net_telnet};
  682.     $prev = $stream->{inputlog};
  683.  
  684.     if (@_ >= 2) {
  685.     $fh = &_fname_to_handle($self, $name);
  686.     $stream->{inputlog} = $fh;
  687.     }
  688.  
  689.     $prev;
  690. } # end sub input_log
  691.  
  692.  
  693. sub input_record_separator {
  694.     my($self, $rs) = @_;
  695.     my(
  696.        $prev,
  697.        $stream,
  698.        );
  699.  
  700.     $stream = $ {*$self}{net_telnet};
  701.     $prev = $stream->{rs};
  702.  
  703.     if (@_ >= 2) {
  704.     defined $rs or $rs = '';
  705.     $stream->{rs} = $rs;
  706.     }
  707.  
  708.     $prev;
  709. } # end sub input_record_separator
  710.  
  711.  
  712. sub lastline {
  713.     my($self, $line) = @_;
  714.     my(
  715.        $prev,
  716.        $stream,
  717.        );
  718.  
  719.     $stream = $ {*$self}{net_telnet};
  720.     $prev = $stream->{last_line};
  721.  
  722.     if (@_ >= 2) {
  723.     defined $line or $line = '';
  724.     $stream->{last_line} = $line;
  725.     }
  726.  
  727.     $prev;
  728. } # end sub lastline
  729.  
  730.  
  731. sub login {
  732.     my($self) = @_;
  733.     my(
  734.        $cmd_prompt,
  735.        $endtime,
  736.        $error,
  737.        $match,
  738.        $orig_errmode,
  739.        $orig_timeout,
  740.        $passwd,
  741.        $prematch,
  742.        $reset,
  743.        $timeout,
  744.        $usage,
  745.        $username,
  746.        %args,
  747.        );
  748.  
  749.     ## Init vars.
  750.     $timeout = $self->timeout;
  751.     $self->timed_out('');
  752.     return if $self->eof;
  753.     $cmd_prompt = $self->prompt;
  754.     $usage = 'usage: $obj->login(Name => $name, Password => $password, ' .
  755.     '[Prompt => $match,] [Timeout => $secs,])';
  756.  
  757.     if (@_ == 3) {  # just username and passwd given
  758.     $username = $_[1];
  759.     $passwd = $_[2];
  760.     }
  761.     else {  # named args given
  762.     ## Get the named args.
  763.     (undef, %args) = @_;
  764.  
  765.     ## Parse the named args.
  766.     foreach (keys %args) {
  767.         if (/^-?name$/i) {
  768.         $username = $args{$_};
  769.         defined($username)
  770.             or $username = "";
  771.         }
  772.         elsif (/^-?pass/i) {
  773.         $passwd = $args{$_};
  774.         defined($passwd)
  775.             or $passwd = "";
  776.         }
  777.         elsif (/^-?prompt$/i) {
  778.         $cmd_prompt = $args{$_};
  779.         defined $cmd_prompt
  780.             or $cmd_prompt = '';
  781.         return $self->error("bad match operator: ",
  782.                     "opening delimiter missing: $cmd_prompt")
  783.             unless ($cmd_prompt =~ m(^\s*/)
  784.                 or $cmd_prompt =~ m(^\s*m\s*\W));
  785.         }
  786.         elsif (/^-?timeout$/i) {
  787.         $timeout = &_parse_timeout($args{$_});
  788.         }
  789.         else {
  790.         return $self->error($usage);
  791.         }
  792.     }
  793.     }
  794.  
  795.     return $self->error($usage)
  796.     unless defined($username) and defined($passwd);
  797.  
  798.     ## Override these user set-able values.
  799.     $endtime = &_endtime($timeout);
  800.     $orig_timeout = $self->timeout($endtime);
  801.     $orig_errmode = $self->errmode('return');
  802.     
  803.     ## Create a subroutine to reset to original values.
  804.     $reset
  805.     = sub {
  806.         $self->errmode($orig_errmode);
  807.         $self->timeout($orig_timeout);
  808.         1;
  809.     };
  810.  
  811.     ## Create a subroutine to generate an error for user.
  812.     $error
  813.     = sub {
  814.         my($errmsg) = @_;
  815.  
  816.         &$reset;
  817.         if ($self->timed_out) {
  818.         return $self->error($errmsg);
  819.         }
  820.         elsif ($self->eof) {
  821.         return $self->error($errmsg, ": ", $self->lastline);
  822.         }
  823.         else {
  824.         return $self->error($self->errmsg);
  825.         }
  826.     };
  827.  
  828.     ## Wait for login prompt.
  829.     $self->waitfor(-match => '/login[: ]*$/i',
  830.            -match => '/username[: ]*$/i')
  831.     or return &$error("login timed-out waiting for login prompt");
  832.  
  833.     ## Send login name.
  834.     $self->print($username)
  835.     or return &$error("login disconnected");
  836.  
  837.     ## Wait for password prompt.
  838.     $self->waitfor(-match => '/password[: ]*$/i')
  839.     or return &$error("login timed-out waiting for password prompt");
  840.  
  841.     ## Send password.
  842.     $self->print($passwd)
  843.     or return &$error("login disconnected");
  844.  
  845.     ## Wait for command prompt or another login prompt.
  846.     ($prematch, $match) = $self->waitfor(-match => $cmd_prompt,
  847.                      -match => '/login[: ]*$/i')
  848.     or return &$error("login timed-out waiting for command prompt");
  849.     
  850.     ## Reset to orig values.
  851.     &$reset;
  852.  
  853.     ## It's a bad login if we got another login prompt.
  854.     return $self->error("login failed: bad name or password")
  855.     if $match =~ /login[: ]*$/i or $match =~ '/username[: ]*$/i';
  856.  
  857.     1;
  858. } # end sub login
  859.  
  860.  
  861. sub max_buffer_length {
  862.     my($self, $maxbufsize) = @_;
  863.     my(
  864.        $minbufsize,
  865.        $prev,
  866.        $stream,
  867.        );
  868.  
  869.     $stream = $ {*$self}{net_telnet};
  870.     $prev = $stream->{maxbufsize};
  871.     $minbufsize = 512;
  872.  
  873.     if (@_ >= 2) {
  874.     ## Ensure a valid max length.
  875.     unless (defined $maxbufsize) {
  876.         $maxbufsize = $minbufsize;
  877.     }
  878.  
  879.     ## Test for non-numeric or negative values.
  880.     eval {
  881.         local $^W = 1;
  882.         local $SIG{'__WARN__'} = sub { die "non-numeric\n" };
  883.         $maxbufsize *= 1;
  884.     };
  885.     if ($@ or $maxbufsize < $minbufsize) {
  886.         $maxbufsize = $minbufsize;
  887.     }
  888.     
  889.     $stream->{maxbufsize} = $maxbufsize;
  890.     }
  891.  
  892.     $prev;
  893. } # end sub max_buffer_length
  894.  
  895.  
  896. sub open {
  897.     my($self) = @_;
  898.     my(
  899.        $blksize,
  900.        $connected,
  901.        $errno,
  902.        $host,
  903.        $ip_addr,
  904.        $port,
  905.        $stream,
  906.        $timeout,
  907.        %args,
  908.        );
  909.  
  910.     ## Init vars.
  911.     $stream = $ {*$self}{net_telnet};
  912.     $timeout = $stream->{time_out};
  913.     $stream->{timedout} = '';
  914.  
  915.     if (@_ == 2) {  # one positional arg given
  916.     $self->host($_[1]);
  917.     }
  918.     elsif (@_ > 2) {  # named args given
  919.     ## Get the named args.
  920.     (undef, %args) = @_;
  921.  
  922.     ## Parse the named args.
  923.     foreach (keys %args) {
  924.         if (/^-?host$/i) {
  925.         $self->host($args{$_});
  926.         }
  927.         elsif (/^-?port$/i) {
  928.         $self->port($args{$_})
  929.             or return;
  930.         }
  931.         elsif (/^-?timeout$/i) {
  932.         $timeout = &_parse_timeout($args{$_});
  933.         }
  934.         else {
  935.         return $self->error('usage: $obj->open([Host => $host,] ',
  936.                     '[Port => $service,] ',
  937.                     '[Timeout => secs,])');
  938.         }
  939.     }
  940.     }
  941.  
  942.     ## Get host and port.
  943.     $host = $self->host;
  944.     $port = $self->port;
  945.  
  946.     ## Ensure object is already closed.
  947.     $self->close;
  948.  
  949.     ## Don't use a timeout if we can't use the alarm signal.
  950.     unless (&_have_alarm) {
  951.     $timeout = undef;
  952.     }
  953.  
  954.     if (defined $timeout) {  # use a timeout
  955.     ## Ensure a valid timeout value for alarm.
  956.     if ($timeout < 1) {
  957.         $timeout = 1;
  958.     }
  959.     $timeout = int($timeout + 1.5);
  960.     
  961.     ## Connect to server, timing out if it takes too long.
  962.     eval {
  963.         ## Turn on timer.
  964.         local $SIG{ALRM} = sub { die "timed-out\n" };
  965.         alarm $timeout;
  966.  
  967.         ## Lookup server's IP address.
  968.         $ip_addr = inet_aton $host
  969.         or die "unknown remote host: $host\n";
  970.  
  971.         ## Create a socket and attach the filehandle to it.
  972.         socket $self, AF_INET, SOCK_STREAM, 0
  973.         or die "problem creating socket: $!\n";
  974.  
  975.         ## Open connection to server.
  976.         $connected = connect $self, sockaddr_in($port, $ip_addr)
  977.         or die "problem connecting to \"$host\", port $port: $!\n";
  978.     };
  979.     alarm 0;
  980.  
  981.     ## Check for error.
  982.     if ($@ =~ /^timed-out$/) {  # time out failure
  983.         $stream->{timedout} = 1;
  984.         $self->close;
  985.         if (! $ip_addr) {
  986.         return $self->error("unknown remote host: $host: ",
  987.                     "name lookup timed-out");
  988.         }
  989.         else {
  990.         return $self->error("problem connecting to \"$host\", ",
  991.                     "port $port: connection timed-out");
  992.         }
  993.     }
  994.     elsif ($@) {  # hostname lookup or connect failure
  995.         $self->close;
  996.         chomp $@;
  997.         return $self->error($@);
  998.     }
  999.     }
  1000.     else {  # don't use a timeout
  1001.     ## Lookup server's IP address.
  1002.     $ip_addr = inet_aton $host
  1003.         or return $self->error("unknown remote host: $host");
  1004.  
  1005.     ## Create a socket and attach the filehandle to it.
  1006.     socket $self, AF_INET, SOCK_STREAM, 0
  1007.         or return $self->error("problem creating socket: $!");
  1008.  
  1009.     ## Open connection to server.
  1010.     connect $self, sockaddr_in($port, $ip_addr)
  1011.         or do {
  1012.         $errno = "$!";
  1013.         $self->close;
  1014.         return $self->error("problem connecting to \"$host\", ",
  1015.                     "port $port: $errno");
  1016.         };
  1017.     }
  1018.  
  1019.     $self->autoflush;
  1020.     $blksize = (stat $self)[11];
  1021.     $stream->{blksize} = $blksize || $Default_blksize;
  1022.     $stream->{buf} = '';
  1023.     $stream->{eofile} = '';
  1024.     vec($stream->{fdmask}='', fileno($self), 1) = 1;
  1025.     $stream->{last_line} = '';
  1026.     $stream->{num_wrote} = '';
  1027.     $stream->{opened} = 1;
  1028.     $stream->{pushback_buf} = '';
  1029.     $stream->{timedout} = '';
  1030.     $stream->{unsent_opts} = '';
  1031.     1;
  1032. } # end sub open
  1033.  
  1034.  
  1035. sub output_field_separator {
  1036.     my($self, $ofs) = @_;
  1037.     my(
  1038.        $prev,
  1039.        $stream,
  1040.        );
  1041.  
  1042.     $stream = $ {*$self}{net_telnet};
  1043.     $prev = $stream->{ofs};
  1044.  
  1045.     if (@_ >= 2) {
  1046.     defined $ofs or $ofs = '';
  1047.     $stream->{ofs} = $ofs;
  1048.     }
  1049.  
  1050.     $prev;
  1051. } # end sub output_field_separator
  1052.  
  1053.  
  1054. sub output_log {
  1055.     my($self, $name) = @_;
  1056.     my(
  1057.        $fh,
  1058.        $prev,
  1059.        $stream,
  1060.        );
  1061.  
  1062.     $stream = $ {*$self}{net_telnet};
  1063.     $prev = $stream->{outputlog};
  1064.  
  1065.     if (@_ >= 2) {
  1066.     $fh = &_fname_to_handle($self, $name);
  1067.     $stream->{outputlog} = $fh;
  1068.     }
  1069.  
  1070.     $prev;
  1071. } # end sub output_log
  1072.  
  1073.  
  1074. sub output_record_separator {
  1075.     my($self, $ors) = @_;
  1076.     my(
  1077.        $prev,
  1078.        $stream,
  1079.        );
  1080.  
  1081.     $stream = $ {*$self}{net_telnet};
  1082.     $prev = $stream->{ors};
  1083.  
  1084.     if (@_ >= 2) {
  1085.     defined $ors or $ors = '';
  1086.     $stream->{ors} = $ors;
  1087.     }
  1088.  
  1089.     $prev;
  1090. } # end sub output_record_separator
  1091.  
  1092.  
  1093. sub port {
  1094.     my($self, $port) = @_;
  1095.     my(
  1096.        $prev,
  1097.        $service,
  1098.        $stream,
  1099.        );
  1100.  
  1101.     $stream = $ {*$self}{net_telnet};
  1102.     $prev = $stream->{port};
  1103.  
  1104.     if (@_ >= 2) {
  1105.     return $self->error("bad port number: 0")
  1106.         unless defined $port and $port;
  1107.  
  1108.     ## Convert service to a port number.
  1109.     if ($port !~ /^\d+$/) {  # port isn't all digits
  1110.         $service = $port;
  1111.         $port = getservbyname($service, 'tcp')
  1112.         or return $self->error("unknown TCP service: $service");
  1113.     }
  1114.  
  1115.     $stream->{port} = $port;
  1116.     }
  1117.  
  1118.     $prev;
  1119. } # end sub port
  1120.  
  1121.  
  1122. sub print {
  1123.     my($self) = shift;
  1124.     my(
  1125.        $data,
  1126.        $endtime,
  1127.        $fh,
  1128.        $len,
  1129.        $nfound,
  1130.        $nwrote,
  1131.        $offset,
  1132.        $ready,
  1133.        $stream,
  1134.        $timed_out,
  1135.        $timeout,
  1136.        );
  1137.  
  1138.     $stream = $ {*$self}{net_telnet};
  1139.     $stream->{timedout} = '';
  1140.     $stream->{num_wrote} = 0;
  1141.     return $self->error("print failed: handle is closed")
  1142.     unless $stream->{opened};
  1143.  
  1144.     ## Try to send any waiting option negotiation.
  1145.     if (length $stream->{unsent_opts}) {
  1146.     &_flush_opts($self, $stream);
  1147.     }
  1148.  
  1149.     ## Add field and record separators.
  1150.     $data = join($stream->{ofs}, @_) . $stream->{ors};
  1151.  
  1152.     ## If requested, log the output.
  1153.     if ($stream->{outputlog}) {
  1154.     local $\ = '';
  1155.     $fh = $stream->{outputlog};
  1156.     $fh->print($data);
  1157.     }
  1158.  
  1159.     ## Convert newlines to carriage-return and newline.
  1160.     $data =~ s(\n)(\r\n)g
  1161.     unless $stream->{bin_mode};
  1162.  
  1163.     $offset = 0;
  1164.     $len = length $data;
  1165.     $endtime = &_endtime($stream->{time_out});
  1166.     while ($len) {
  1167.     ## Set how long to wait for output ready.
  1168.     ($timed_out, $timeout) = &_timeout_interval($endtime);
  1169.     if ($timed_out) {
  1170.         $stream->{timedout} = 1;
  1171.         return $self->error("print timed-out");
  1172.     }
  1173.  
  1174.     ## Wait for output ready.
  1175.     $nfound = select '', $ready=$stream->{fdmask}, '', $timeout;
  1176.     if ($nfound > 0) {  # data can be written
  1177.         if ($nwrote = syswrite $self, $data, $len, $offset) {
  1178.         ## If requested, display network traffic.
  1179.         ($stream->{dumplog})
  1180.             and &_dump_data('>', $stream->{dumplog},
  1181.                     \$data, $offset, $nwrote);
  1182.  
  1183.         $stream->{num_wrote} += $nwrote;
  1184.         $offset += $nwrote;
  1185.         $len -= $nwrote;
  1186.         next;
  1187.         }
  1188.         elsif (! defined $nwrote) {  # write failed
  1189.         next if $! =~ /^Interrupted/;
  1190.         
  1191.         $stream->{opened} = '';
  1192.         return $self->error("unexpected write error: $!");
  1193.         }
  1194.         else {  # zero chars written
  1195.         $stream->{opened} = '';
  1196.         return $self->error("unexpected zero length write error: $!");
  1197.         }
  1198.     }
  1199.     elsif ($nfound < 0) {  # select failure
  1200.         next if $! =~ /^Interrupted/;
  1201.  
  1202.         ## Failure equates to eof.
  1203.         $stream->{opened} = '';
  1204.         return $self->error("unexpected write error: $!");
  1205.     }
  1206.     else {  # timed-out
  1207.         $stream->{timedout} = 1;
  1208.         return $self->error("print timed-out");
  1209.     }
  1210.     }
  1211.  
  1212.     1;
  1213. } # end sub print
  1214.  
  1215.  
  1216. sub print_length {
  1217.     my($self) = @_;
  1218.  
  1219.     $ {*$self}{net_telnet}{num_wrote};
  1220. } # end sub print_length
  1221.  
  1222.  
  1223. sub prompt {
  1224.     my($self, $prompt) = @_;
  1225.     my(
  1226.        $prev,
  1227.        $stream,
  1228.        );
  1229.  
  1230.     $stream = $ {*$self}{net_telnet};
  1231.     $prev = $stream->{cmd_prompt};
  1232.  
  1233.     ## Parse args.
  1234.     if (@_ == 2) {
  1235.     defined $prompt or $prompt = '';
  1236.     return $self->error("bad match operator: ",
  1237.                 "opening delimiter missing: $prompt")
  1238.         unless $prompt =~ m(^\s*/) or $prompt =~ m(^\s*m\s*\W);
  1239.  
  1240.     $stream->{cmd_prompt} = $prompt;
  1241.     }
  1242.     elsif (@_ > 2) {
  1243.     return $self->error('usage: $obj->prompt($match_op)');
  1244.     }
  1245.  
  1246.     $prev;
  1247. } # end sub prompt
  1248.  
  1249.  
  1250. sub telnetmode {
  1251.     my($self, $mode) = @_;
  1252.     my(
  1253.        $prev,
  1254.        $stream,
  1255.        );
  1256.  
  1257.     ## With no args, turn on telnet mode.
  1258.     if (@_ < 2) {
  1259.     $mode = 1;
  1260.     }
  1261.     else {
  1262.     defined $mode or $mode = '';
  1263.     }
  1264.  
  1265.     $stream = $ {*$self}{net_telnet};
  1266.     $prev = $stream->{telnet_mode};
  1267.     $stream->{telnet_mode} = $mode;
  1268.     $prev;
  1269. } # end sub telnetmode
  1270.  
  1271.  
  1272. sub timed_out {
  1273.     my($self, $value) = @_;
  1274.     my(
  1275.        $prev,
  1276.        $stream,
  1277.        );
  1278.  
  1279.     $stream = $ {*$self}{net_telnet};
  1280.     $prev = $stream->{timedout};
  1281.  
  1282.     if (@_ >= 2) {
  1283.     defined $value or $value = '';
  1284.     $stream->{timedout} = $value;
  1285.     }
  1286.  
  1287.     $prev;
  1288. } # end sub timed_out
  1289.  
  1290.  
  1291. sub timeout {
  1292.     my($self, $timeout) = @_;
  1293.     my(
  1294.        $prev,
  1295.        $stream,
  1296.        );
  1297.  
  1298.     $stream = $ {*$self}{net_telnet};
  1299.     $prev = $stream->{time_out};
  1300.  
  1301.     if (@_ >= 2) {
  1302.     $stream->{time_out} = &_parse_timeout($timeout);
  1303.     }
  1304.  
  1305.     $prev;
  1306. } # end sub timeout
  1307.  
  1308.  
  1309. sub waitfor {
  1310.     my($self, @args) = @_;
  1311.     my(
  1312.        $arg,
  1313.        $endtime,
  1314.        $len,
  1315.        $match,
  1316.        $match_op,
  1317.        $pos,
  1318.        $prematch,
  1319.        $search,
  1320.        $search_cond,
  1321.        $stream,
  1322.        $string,
  1323.        $timeout,
  1324.        @match_cond,
  1325.        @match_ops,
  1326.        @search_cond,
  1327.        @string_cond,
  1328.        @warns,
  1329.        );
  1330.  
  1331.     ## Init vars.
  1332.     $stream = $ {*$self}{net_telnet};
  1333.     $timeout = $stream->{time_out};
  1334.     $stream->{timedout} = '';
  1335.     return if $stream->{eofile};
  1336.     return unless @args;
  1337.  
  1338.     ## Code template used build conditional to match a string.
  1339.     ## Values between array elements must be supplied later.
  1340.     @string_cond =
  1341.     ('if (($pos = index $stream->{buf}, ', ') > -1) {
  1342.         $len = ', ';
  1343.         $prematch = substr $stream->{buf}, 0, $pos;
  1344.         $match = substr $stream->{buf}, $pos, $len;
  1345.         substr($stream->{buf}, 0, $pos + $len) = "";
  1346.         last;
  1347.     }');
  1348.  
  1349.     ## Code template used build conditional to match a pattern.
  1350.     ## Values between array elements must be supplied later.
  1351.     @match_cond =
  1352.     ('if ($stream->{buf} =~ ', ') {
  1353.         $prematch = $`;
  1354.         $match = $&;
  1355.         substr($stream->{buf}, 0, length($`) + length($&)) = "";
  1356.         last;
  1357.     }');
  1358.  
  1359.     ## Parse args.
  1360.     if (@_ == 2) {  # one positional arg given
  1361.     $arg = $_[1];
  1362.     return $self->error("bad match operator: ",
  1363.                 "opening delimiter missing: $arg")
  1364.         unless $arg =~ m(^\s*/) or $arg =~ m(^\s*m\s*\W);
  1365.  
  1366.     ## Fill in the blanks in the code template.
  1367.     push @match_ops, $arg;
  1368.     push @search_cond, join('', $match_cond[0], $arg, $match_cond[1]);
  1369.     }
  1370.     elsif (@_ > 2) {  # named args given
  1371.     ## Parse the named args.
  1372.     while (($_, $arg) = splice @args, 0, 2) {
  1373.         if (/^-?timeout$/i) {
  1374.         $timeout = &_parse_timeout($arg);
  1375.         }
  1376.         elsif (/^-?match$/i) {
  1377.         return $self->error("bad match operator: ",
  1378.                     "opening delimiter missing: $arg")
  1379.             unless $arg =~ m(^\s*/) or $arg =~ m(^\s*m\s*\W);
  1380.  
  1381.         ## Fill in the blanks in the code template.
  1382.         push @match_ops, $arg;
  1383.         push @search_cond, join('',
  1384.                     $match_cond[0], $arg, $match_cond[1]);
  1385.         }
  1386.         elsif (/^-?string$/i) {
  1387.         ## Fill in the blanks in the code template.
  1388.         $arg =~ s/'/\\'/g;  # quote ticks
  1389.         push @search_cond, join('',
  1390.                     $string_cond[0], "'$arg'",
  1391.                     $string_cond[1], length($arg),
  1392.                     $string_cond[2]);
  1393.         }
  1394.         else {
  1395.         return $self->error('usage: $obj->waitfor([Match => ',
  1396.                     '$match_op,] [String => $string,] ',
  1397.                     '[Timeout => $secs,])');
  1398.         }
  1399.     }
  1400.     }
  1401.  
  1402.     ## Construct conditional to check for requested string and pattern matches.
  1403.     ## Turn subsequent "if"s into "elsif".
  1404.     $search_cond = join "\n\tels", @search_cond;
  1405.  
  1406.     ## Construct loop to fill buffer until string/pattern, timeout, or eof.
  1407.     $search = join '', "
  1408.     while (1) {\n\t",
  1409.     $search_cond, '
  1410.     &_fillbuf($self, $stream, $endtime)
  1411.         or do {
  1412.         last if $stream->{timedout};
  1413.         $self->close;
  1414.         last;
  1415.         };
  1416.     }';
  1417.  
  1418.     ## Set wall time when we timeout.
  1419.     $endtime = &_endtime($timeout);
  1420.  
  1421.     ## Run the loop.
  1422.     {
  1423.     local $^W = 1;
  1424.     local $SIG{'__WARN__'} = sub { push @warns, @_ };
  1425.     local $stream->{errormode} = 'return';
  1426.     $stream->{errormsg} = '';
  1427.     eval $search;
  1428.     }
  1429.  
  1430.     ## Check for failure.
  1431.     return $self->error("pattern timed-out") if $stream->{timedout};
  1432.     return $self->error($stream->{errormsg}) if $stream->{errormsg} ne '';
  1433.     return if $stream->{eofile};
  1434.  
  1435.     ## Check for Perl syntax errors or warnings.
  1436.     if ($@ or @warns) {
  1437.     foreach $match_op (@match_ops) {
  1438.         &_match_check($self, $match_op)
  1439.         or return;
  1440.     }
  1441.     return $self->error($@) if $@;
  1442.     return $self->error(@warns) if @warns;
  1443.     }
  1444.  
  1445.     wantarray ? ($prematch, $match) : 1;
  1446. } # end sub waitfor
  1447.  
  1448.  
  1449. ######################## Private Subroutines #########################
  1450.  
  1451.  
  1452. sub _append_lineno {
  1453.     my($obj, @msgs) = @_;
  1454.     my(
  1455.        $class,
  1456.        $curr_pkg,
  1457.        $file,
  1458.        $i,
  1459.        $line,
  1460.        $pkg,
  1461.        %isa,
  1462.        @isa,
  1463.        );
  1464.  
  1465.  
  1466.     ## Create a boolean hash to test for isa.  Make sure current
  1467.     ## package and the object's class are members.
  1468.     $class = ref $obj;
  1469.     ($curr_pkg) = caller 1;
  1470.     @isa = eval "\@${class}::ISA";
  1471.     push @isa, $class, $curr_pkg;
  1472.     %isa = map {$_ => 1} @isa;
  1473.  
  1474.     ## Search back in call frames for a package that's not in isa.
  1475.     $i = 1;
  1476.     while (($pkg, $file , $line) = caller ++$i) {
  1477.     next if $isa{$pkg};
  1478.  
  1479.     return join('', @msgs, " at ", $file, " line ", $line, "\n");
  1480.     }
  1481.  
  1482.     ## If not found, choose outer most call frame.
  1483.     ($pkg, $file , $line) = caller --$i;
  1484.     join('', @msgs, " at ", $file, " line ", $line, "\n");
  1485. } # end sub _append_lineno
  1486.  
  1487.  
  1488. sub _carp {
  1489.     warn &_append_lineno(@_);
  1490. } # end sub _carp
  1491.  
  1492.  
  1493. sub _croak {
  1494.     die &_append_lineno(@_);
  1495. } # end sub _croak
  1496.  
  1497.  
  1498. sub _dump_data {
  1499.     my($direction, $fh, $data, $offset, $len) = @_;
  1500.     my(
  1501.        $addr,
  1502.        $hexvals,
  1503.        $line,
  1504.        );
  1505.  
  1506.     $addr = 0;
  1507.     $len = length($$data) - $offset
  1508.     unless defined $len;
  1509.     
  1510.     ## Print data in dump format.
  1511.     while ($len > 0) {
  1512.     ## Convert up to the next 16 chars to hex, padding w/ spaces.
  1513.     if ($len >= 16) {
  1514.         $line = substr $$data, $offset, 16;
  1515.     }
  1516.     else {
  1517.         $line = substr $$data, $offset, $len;
  1518.     }
  1519.     $hexvals = unpack('H*', $line);
  1520.     $hexvals .= ' ' x (32 - length $hexvals);
  1521.  
  1522.     ## Place in 16 columns, each containing two hex digits.
  1523.     $hexvals = sprintf("%s %s %s %s  " x 4,
  1524.                unpack('a2' x 16, $hexvals));
  1525.     
  1526.     ## For the ASCII column, change unprintable chars to a period.
  1527.     $line =~ s/[\000-\037,\177-\237]/./g;
  1528.  
  1529.     ## Print the line in dump format.
  1530.     printf($fh "%s 0x%5.5lx: %s%s\n", $direction, $addr, $hexvals, $line);
  1531.  
  1532.     $addr += 16;
  1533.     $offset += 16;
  1534.     $len -= 16;
  1535.     }
  1536.  
  1537.     1;
  1538. } # end sub _dump_data
  1539.  
  1540.  
  1541. sub _endtime {
  1542.     my($interval) = @_;
  1543.  
  1544.     ## Compute wall time when timeout occurs.
  1545.     if (defined $interval) {
  1546.     if ($interval >= $^T) {  # it's already an absolute time
  1547.         return $interval;
  1548.     }
  1549.     elsif ($interval > 0) {  # it's relative to the current time
  1550.         return int(time + 1.5 + $interval);
  1551.     }
  1552.     else {  # it's a one time poll
  1553.         return 0;
  1554.     }
  1555.     }
  1556.     else {  # there's no timeout
  1557.     return undef;
  1558.     }
  1559. } # end sub _endtime
  1560.  
  1561.  
  1562. sub _fillbuf {
  1563.     my($self, $s, $endtime) = @_;
  1564.     my(
  1565.        $fh,
  1566.        $firstpos,
  1567.        $lastpos,
  1568.        $len_w_sep,
  1569.        $len_wo_sep,
  1570.        $nextchar,
  1571.        $nfound,
  1572.        $nread,
  1573.        $offset,
  1574.        $pos,
  1575.        $pushback_len,
  1576.        $ready,
  1577.        $timed_out,
  1578.        $timeout,
  1579.        );
  1580.  
  1581.     return unless $s->{opened};
  1582.  
  1583.     while (1) {
  1584.     ## Ensure we haven't exceeded maximum buffer size.
  1585.     return $self->error("maximum input buffer length exceeded: ",
  1586.                 $s->{maxbufsize}, " bytes")
  1587.         unless length($s->{buf}) <= $s->{maxbufsize};
  1588.  
  1589.     ## Set how long to wait for input ready.
  1590.     ($timed_out, $timeout) = &_timeout_interval($endtime);
  1591.     if ($timed_out) {
  1592.         $s->{timedout} = 1;
  1593.         return $self->error("read timed-out");
  1594.     }
  1595.  
  1596.     ## Wait for input ready.
  1597.     $nfound = select $ready=$s->{fdmask}, '', '', $timeout;
  1598.     if ($nfound > 0) {  # data can be read
  1599.         ## Append any partially read telnet char sequence.
  1600.         $pushback_len = length $s->{pushback_buf};
  1601.         if ($pushback_len) {
  1602.         $s->{buf} .= $s->{pushback_buf};
  1603.         $s->{pushback_buf} = '';
  1604.         }
  1605.  
  1606.         ## Do the read.
  1607.         $offset = length $s->{buf};
  1608.         if ($nread = sysread $self, $s->{buf}, $s->{blksize}, $offset) {
  1609.         ## If requested, display network traffic.
  1610.         ($s->{dumplog})
  1611.             and &_dump_data('<', $s->{dumplog}, \$s->{buf}, $offset);
  1612.         
  1613.         ## Process any telnet commands in the data stream.
  1614.         if ($s->{telnet_mode}
  1615.             and index($s->{buf}, "\377", $offset - $pushback_len) > -1)
  1616.         {
  1617.             &_interpret_cmd($self, $s, $offset - $pushback_len);
  1618.         }
  1619.  
  1620.         ## Process carriage-return sequences in the data stream.
  1621.         $pos = $offset - $pushback_len;
  1622.         while (($pos = index($s->{buf}, "\r", $pos)) > -1) {
  1623.             $nextchar = substr($s->{buf}, $pos + 1, 1);
  1624.             if ($nextchar eq "\0") {
  1625.             ## Convert \r\0 to \r
  1626.             substr($s->{buf}, $pos + 1, 1) = '';
  1627.             }
  1628.             elsif ($nextchar eq "\n") {
  1629.             ## Convert \r\n to \n when not in binary mode.
  1630.             substr($s->{buf}, $pos, 1) = ''
  1631.                 unless $s->{bin_mode};
  1632.             }
  1633.             elsif (! length $nextchar) {
  1634.             $s->{pushback_buf} .= "\r";
  1635.             chop $s->{buf};
  1636.             }
  1637.  
  1638.             $pos++;
  1639.         }
  1640.         
  1641.         next if length $s->{buf} <= $offset;
  1642.  
  1643.         ## If requested, log the input.
  1644.         if ($s->{inputlog}) {
  1645.             local $\ = '';
  1646.             $fh = $s->{inputlog};
  1647.             $fh->print(substr $s->{buf}, $offset);
  1648.         }
  1649.  
  1650.         ## Save last line in the buffer.
  1651.         if (($lastpos = rindex $s->{buf}, $s->{rs}) > -1) {
  1652.             while (1) {
  1653.             ## Find beginning of line.
  1654.             $firstpos = rindex $s->{buf}, $s->{rs}, $lastpos - 1;
  1655.             if ($firstpos == -1) {
  1656.                 $offset = 0;
  1657.             }
  1658.             else {
  1659.                 $offset = $firstpos + length $s->{rs};
  1660.             }
  1661.  
  1662.             ## Determine length of line with and without separator.
  1663.             $len_wo_sep = $lastpos - $offset;
  1664.             $len_w_sep = $len_wo_sep + length $s->{rs};
  1665.  
  1666.             ## Save line if it's not blank.
  1667.             if (substr($s->{buf}, $offset, $len_wo_sep)
  1668.                 !~ /^\s*$/)
  1669.             {
  1670.                 $s->{last_line} = substr($s->{buf},
  1671.                              $offset,
  1672.                              $len_w_sep);
  1673.                 last;
  1674.             }
  1675.  
  1676.             last if $firstpos == -1;
  1677.  
  1678.             $lastpos = $firstpos;
  1679.             }
  1680.         }
  1681.  
  1682.         return 1;
  1683.         }
  1684.         elsif (! defined $nread) {  # read failed
  1685.         next if $! =~ /^Interrupted/;
  1686.         
  1687.         $s->{opened} = '';
  1688.         return $self->error("unexpected read error: $!");
  1689.         }
  1690.         else {  # read end-of-file
  1691.         $s->{opened} = '';
  1692.         return;
  1693.         }
  1694.     }
  1695.     elsif ($nfound < 0) {  # select failure
  1696.         next if $! =~ /^Interrupted/;
  1697.  
  1698.         ## Failure equates to eof.
  1699.         $s->{opened} = '';
  1700.         return $self->error("unexpected read error: $!");
  1701.     }
  1702.     else {  # timed-out
  1703.         $s->{timedout} = 1;
  1704.         return $self->error("read timed-out");
  1705.     }
  1706.     }
  1707. } # end sub _fillbuf
  1708.  
  1709.  
  1710. sub _flush_opts {
  1711.     my($self, $s) = @_;
  1712.     my(
  1713.        $option_chars,
  1714.        );
  1715.  
  1716.     ## Get option and clear the output buf.
  1717.     $option_chars = $s->{unsent_opts};
  1718.     $s->{unsent_opts} = '';
  1719.  
  1720.     ## Try to send options without waiting.
  1721.     {
  1722.     local $s->{errormode} = 'return';
  1723.     local $s->{time_out} = 0;
  1724.     local $s->{ors} = '';
  1725.     $self->print($option_chars)
  1726.         or do {
  1727.         ## Save chars not printed for later.
  1728.         substr($option_chars, 0, $self->print_length) = '';
  1729.         $s->{unsent_opts} .= $option_chars;
  1730.         };
  1731.     }
  1732.  
  1733.     1;
  1734. } # end sub _flush_opts
  1735.  
  1736.  
  1737. sub _fname_to_handle {
  1738.     my($self, $fh) = @_;
  1739.     my(
  1740.        $filename,
  1741.        );
  1742.  
  1743.     ## Default is off.
  1744.     if (!defined $fh or !length $fh) {
  1745.     return '';
  1746.     }
  1747.  
  1748.     ## Assume arg is a filename if it's not an open filehandle.
  1749.     no strict 'refs';
  1750.     if (!defined fileno($fh)) {
  1751.     $filename = $fh;
  1752.     $fh = &_new_handle();
  1753.     open $fh, ">$filename"
  1754.         or do {
  1755.         &_carp($self, "problem creating $filename: $!");
  1756.         return '';
  1757.         };
  1758.     }
  1759.  
  1760.     $fh->autoflush;
  1761.     $fh;
  1762. } # end sub _fname_to_handle
  1763.  
  1764.  
  1765. sub _have_alarm {
  1766.     eval {
  1767.     alarm 0;
  1768.     local $SIG{ALRM} = sub { die };
  1769.     };
  1770.  
  1771.     ! $@;
  1772. } # end sub _have_alarm
  1773.  
  1774.  
  1775. sub _interpret_cmd {
  1776.     my($self, $s, $offset) = @_;
  1777.     my(
  1778.        $endpos,
  1779.        $nextchar,
  1780.        $option,
  1781.        $pos,
  1782.        );
  1783.  
  1784.     ## Parse telnet commands in the data stream.
  1785.     $pos = $offset;
  1786.     while (($pos = index $s->{buf}, "\377", $pos) > -1) {  # unprocessed IAC
  1787.     $nextchar = substr $s->{buf}, $pos + 1, 1;
  1788.  
  1789.     ## Save command if it's only partially read.
  1790.     if (! length $nextchar) {
  1791.         $s->{pushback_buf} .= "\377";
  1792.         chop $s->{buf};
  1793.         last;
  1794.     }
  1795.  
  1796.     if ($nextchar eq "\377") {  # IAC is escaping "\377" char
  1797.         ## Remove escape char from data stream.
  1798.         substr($s->{buf}, $pos, 1) = '';
  1799.         $pos++;
  1800.     }
  1801.     elsif ($nextchar eq "\375" or $nextchar eq "\373" or
  1802.            $nextchar eq "\374" or $nextchar eq "\376") {  # opt negotiation
  1803.         $option = substr $s->{buf}, $pos + 2, 1;
  1804.  
  1805.         ## Save command if it's only partially read.
  1806.         if (! length $option) {
  1807.         $s->{pushback_buf} .= "\377" . $nextchar;
  1808.         chop $s->{buf};
  1809.         chop $s->{buf};
  1810.         last;
  1811.         }
  1812.  
  1813.         ## Remove command from data stream.
  1814.         substr($s->{buf}, $pos, 3) = '';
  1815.  
  1816.         ## Ignore all options except "DO" and "WILL".
  1817.         if ($nextchar eq "\375") {  # DO
  1818.         ## Indicate we "won't" do this option request.
  1819.         $s->{unsent_opts} .= "\377\374$option";
  1820.         }
  1821.         elsif ($nextchar eq "\373") {  # WILL
  1822.         ## Indicate we "don't" do this option request.
  1823.         $s->{unsent_opts} .= "\377\376$option";
  1824.         }
  1825.     }
  1826.     elsif ($nextchar eq "\372") {  # start of subnegotiation parameters
  1827.         ## Save command if it's only partially read.
  1828.         $endpos = index $s->{buf}, "\360", $pos;
  1829.         if ($endpos == -1) {
  1830.         $s->{pushback_buf} .= substr $s->{buf}, $pos;
  1831.         substr($s->{buf}, $pos) = '';
  1832.         last;
  1833.         }
  1834.         
  1835.         ## Ignore subnegotiation cmd.
  1836.         substr($s->{buf}, $pos, $endpos - $pos + 1) = '';
  1837.     }
  1838.     else {  # various two char telnet commands
  1839.         ## Ignore and remove command from data stream.
  1840.         substr($s->{buf}, $pos, 2) = '';
  1841.     }
  1842.     }
  1843.  
  1844.     ## Try to send any waiting option negotiation.
  1845.     if (length $s->{unsent_opts}) {
  1846.     &_flush_opts($self, $s);
  1847.     }
  1848.  
  1849.     1;
  1850. } # end sub _interpret_cmd
  1851.  
  1852.  
  1853. sub _match_check {
  1854.     my($self, $code) = @_;
  1855.     my $error;
  1856.     my @warns = ();
  1857.  
  1858.     ## Use eval to check for syntax errors or warnings.
  1859.     {
  1860.     local $^W = 1;
  1861.     local $SIG{'__WARN__'} = sub { push @warns, @_ };
  1862.     local $_ = '';
  1863.     eval "\$_ =~ $code;";
  1864.     }
  1865.     if ($@) {
  1866.     ## Remove useless lines numbers from message.
  1867.     ($error = $@) =~ s/ at \(eval \d+\) line \d+.?//;
  1868.     chomp $error;
  1869.     return $self->error("bad match operator: $error");
  1870.     }
  1871.     elsif (@warns) {
  1872.     ## Remove useless lines numbers from message.
  1873.     ($error = shift @warns) =~ s/ at \(eval \d+\) line \d+.?//;
  1874.     $error =~ s/ while "strict subs" in use//;
  1875.     chomp $error;
  1876.     return $self->error("bad match operator: $error");
  1877.     }
  1878.  
  1879.     1;
  1880. } # end sub _match_check
  1881.  
  1882.  
  1883. sub _new_handle {
  1884.     if ($INC{'IO/Handle.pm'}) {
  1885.     return IO::Handle->new;
  1886.     }
  1887.     else {
  1888.     require FileHandle;
  1889.     return FileHandle->new;
  1890.     }
  1891. } # end sub _new_handle
  1892.  
  1893.  
  1894. sub _parse_timeout {
  1895.     my($timeout) = @_;
  1896.  
  1897.     ## Ensure valid timeout.
  1898.     if (defined $timeout) {
  1899.     ## Test for non-numeric or negative values.
  1900.     eval {
  1901.         local $^W = 1;
  1902.         local $SIG{'__WARN__'} = sub { die "non-numeric\n" };
  1903.         $timeout *= 1;
  1904.     };
  1905.     if ($@) {  # timeout arg is non-numeric
  1906.         $timeout = undef;
  1907.     }
  1908.     elsif ($timeout < 0) {
  1909.         $timeout = undef;
  1910.     }
  1911.     }
  1912.  
  1913.     $timeout;
  1914. } # end sub _parse_timeout
  1915.  
  1916.  
  1917. sub _timeout_interval {
  1918.     my($endtime) = @_;
  1919.     my(
  1920.        $timeout,
  1921.        );
  1922.  
  1923.     ## Return timed-out boolean and timeout interval.
  1924.     if (defined $endtime) {
  1925.     ## Is it a one-time poll.
  1926.     return ('', 0) if $endtime == 0;
  1927.  
  1928.     ## Calculate the timeout interval.
  1929.     $timeout = $endtime - time;
  1930.  
  1931.     ## Did we already timeout.
  1932.     return (1, 0) unless $timeout > 0;
  1933.  
  1934.     return ('', $timeout);
  1935.     }
  1936.     else {  # there is no timeout
  1937.     return ('', undef);
  1938.     }
  1939. } # end sub _timeout_interval
  1940.  
  1941.  
  1942. ######################## Exported Constants ##########################
  1943.  
  1944.  
  1945. use vars qw(@EXPORT_OK);
  1946. @EXPORT_OK = qw(TELNET_IAC TELNET_DONT TELNET_DO TELNET_WONT
  1947.         TELNET_WILL TELNET_SB TELNET_GA TELNET_EL TELNET_EC
  1948.         TELNET_AYT TELNET_AO TELNET_IP TELNET_BREAK TELNET_DM
  1949.         TELNET_NOP TELNET_SE TELNET_EOR TELNET_ABORT
  1950.         TELNET_SUSP TELNET_EOF TELNET_SYNCH TELOPT_BINARY
  1951.         TELOPT_ECHO TELOPT_RCP TELOPT_SGA TELOPT_NAMS
  1952.         TELOPT_STATUS TELOPT_TM TELOPT_RCTE TELOPT_NAOL
  1953.         TELOPT_NAOP TELOPT_NAOCRD TELOPT_NAOHTS TELOPT_NAOHTD
  1954.         TELOPT_NAOFFD TELOPT_NAOVTS TELOPT_NAOVTD
  1955.         TELOPT_NAOLFD TELOPT_XASCII TELOPT_LOGOUT TELOPT_BM
  1956.         TELOPT_DET TELOPT_SUPDUP TELOPT_SUPDUPOUTPUT
  1957.         TELOPT_SNDLOC TELOPT_TTYPE TELOPT_EOR TELOPT_TUID
  1958.         TELOPT_OUTMRK TELOPT_TTYLOC TELOPT_3270REGIME
  1959.         TELOPT_X3PAD TELOPT_NAWS TELOPT_TSPEED TELOPT_LFLOW
  1960.         TELOPT_LINEMODE TELOPT_XDISPLOC TELOPT_OLD_ENVIRON
  1961.         TELOPT_AUTHENTICATION TELOPT_ENCRYPT
  1962.         TELOPT_NEW_ENVIRON TELOPT_EXOPL SLC_SYNCH SLC_BRK
  1963.         SLC_IP SLC_AO SLC_AYT SLC_EOR SLC_ABORT SLC_EOF
  1964.         SLC_SUSP SLC_EC SLC_EL SLC_EW SLC_RP SLC_LNEXT SLC_XON
  1965.         SLC_XOFF SLC_FORW1 SLC_FORW2
  1966.         );
  1967.  
  1968. sub TELNET_IAC        {255};    # interpret as command:
  1969. sub TELNET_DONT        {254};    # you are not to use option
  1970. sub TELNET_DO        {253};    # please, you use option
  1971. sub TELNET_WONT        {252};    # I won't use option
  1972. sub TELNET_WILL        {251};    # I will use option
  1973. sub TELNET_SB        {250};    # interpret as subnegotiation
  1974. sub TELNET_GA        {249};    # you may reverse the line
  1975. sub TELNET_EL        {248};    # erase the current line
  1976. sub TELNET_EC        {247};    # erase the current character
  1977. sub TELNET_AYT        {246};    # are you there
  1978. sub TELNET_AO        {245};    # abort output--but let prog finish
  1979. sub TELNET_IP        {244};    # interrupt process--permanently
  1980. sub TELNET_BREAK    {243};    # break
  1981. sub TELNET_DM        {242};    # data mark--for connect. cleaning
  1982. sub TELNET_NOP        {241};    # nop
  1983. sub TELNET_SE        {240};    # end sub negotiation
  1984. sub TELNET_EOR        {239};    # end of record (transparent mode)
  1985. sub TELNET_ABORT    {238};    # Abort process
  1986. sub TELNET_SUSP        {237};    # Suspend process
  1987. sub TELNET_EOF        {236};    # End of file: EOF is already used...
  1988. sub TELNET_SYNCH    {242};    # for telfunc calls
  1989.  
  1990. sub TELOPT_BINARY      {0};    # 8-bit data path
  1991. sub TELOPT_ECHO          {1};    # echo
  1992. sub TELOPT_RCP          {2};    # prepare to reconnect
  1993. sub TELOPT_SGA          {3};    # suppress go ahead
  1994. sub TELOPT_NAMS          {4};    # approximate message size
  1995. sub TELOPT_STATUS      {5};    # give status
  1996. sub TELOPT_TM          {6};    # timing mark
  1997. sub TELOPT_RCTE          {7};    # remote controlled transmission and echo
  1998. sub TELOPT_NAOL          {8};    # negotiate about output line width
  1999. sub TELOPT_NAOP          {9};    # negotiate about output page size
  2000. sub TELOPT_NAOCRD      {10}; # negotiate about CR disposition
  2001. sub TELOPT_NAOHTS      {11}; # negotiate about horizontal tabstops
  2002. sub TELOPT_NAOHTD      {12}; # negotiate about horizontal tab disposition
  2003. sub TELOPT_NAOFFD      {13}; # negotiate about formfeed disposition
  2004. sub TELOPT_NAOVTS      {14}; # negotiate about vertical tab stops
  2005. sub TELOPT_NAOVTD      {15}; # negotiate about vertical tab disposition
  2006. sub TELOPT_NAOLFD      {16}; # negotiate about output LF disposition
  2007. sub TELOPT_XASCII      {17}; # extended ascic character set
  2008. sub TELOPT_LOGOUT      {18}; # force logout
  2009. sub TELOPT_BM          {19}; # byte macro
  2010. sub TELOPT_DET          {20}; # data entry terminal
  2011. sub TELOPT_SUPDUP      {21}; # supdup protocol
  2012. sub TELOPT_SUPDUPOUTPUT      {22}; # supdup output
  2013. sub TELOPT_SNDLOC      {23}; # send location
  2014. sub TELOPT_TTYPE      {24}; # terminal type
  2015. sub TELOPT_EOR          {25}; # end or record
  2016. sub TELOPT_TUID          {26}; # TACACS user identification
  2017. sub TELOPT_OUTMRK      {27}; # output marking
  2018. sub TELOPT_TTYLOC      {28}; # terminal location number
  2019. sub TELOPT_3270REGIME      {29}; # 3270 regime
  2020. sub TELOPT_X3PAD      {30}; # X.3 PAD
  2021. sub TELOPT_NAWS          {31}; # window size
  2022. sub TELOPT_TSPEED      {32}; # terminal speed
  2023. sub TELOPT_LFLOW      {33}; # remote flow control
  2024. sub TELOPT_LINEMODE      {34}; # Linemode option
  2025. sub TELOPT_XDISPLOC      {35}; # X Display Location
  2026. sub TELOPT_OLD_ENVIRON      {36}; # Old - Environment variables
  2027. sub TELOPT_AUTHENTICATION {37}; # Authenticate
  2028. sub TELOPT_ENCRYPT      {38}; # Encryption option
  2029. sub TELOPT_NEW_ENVIRON      {39}; # New - Environment variables
  2030. sub TELOPT_EXOPL     {255}; # extended-options-list
  2031.  
  2032. sub SLC_SYNCH           {1};
  2033. sub SLC_BRK           {2};
  2034. sub SLC_IP           {3};
  2035. sub SLC_AO           {4};
  2036. sub SLC_AYT           {5};
  2037. sub SLC_EOR           {6};
  2038. sub SLC_ABORT           {7};
  2039. sub SLC_EOF           {8};
  2040. sub SLC_SUSP           {9};
  2041. sub SLC_EC          {10};
  2042. sub SLC_EL          {11};
  2043. sub SLC_EW          {12};
  2044. sub SLC_RP          {13};
  2045. sub SLC_LNEXT          {14};
  2046. sub SLC_XON          {15};
  2047. sub SLC_XOFF          {16};
  2048. sub SLC_FORW1          {17};
  2049. sub SLC_FORW2          {18};
  2050.  
  2051. 1;
  2052. __END__;
  2053.  
  2054.  
  2055. ########################### Documentation ############################
  2056.  
  2057.  
  2058. =head1 NAME
  2059.  
  2060. Net::Telnet - interact with TELNET port or other TCP ports
  2061.  
  2062. =head1 SYNOPSIS
  2063.  
  2064.     use Net::Telnet ();
  2065.     see METHODS section below
  2066.  
  2067. =head1 DESCRIPTION
  2068.  
  2069. Net::Telnet allows you to make client connections to a TCP port and do
  2070. network I/O, especially with a port using the TELNET protocol.  Simple
  2071. I/O methods such as print, get, and getline are provided.  More
  2072. sophisticated interactive features are provided because connecting to
  2073. a TELNET port ultimately means communicating with a program designed
  2074. for human interaction.  Some interactive features include the ability
  2075. to specify a timeout and to wait for patterns to appear in the input
  2076. stream, such as the prompt from a command interpreter.
  2077.  
  2078. This example prints who's logged-on to the remote host sparky:
  2079.  
  2080.     $sparky = new Net::Telnet (Host => "sparky",
  2081.                                Timeout => 10,
  2082.                                Prompt => '/[$%#>] $/');
  2083.     $sparky->login($username, $passwd);
  2084.     @lines = $sparky->cmd("/usr/bin/who");
  2085.     print @lines;
  2086.     $sparky->close;
  2087.  
  2088. Methods B<login()> and B<cmd()> use the prompt setting in the object
  2089. to determine when a login or command is complete.  If the prompt
  2090. doesn't match, it's likely those commands will timeout.
  2091.  
  2092. Other reasons to use this class than strictly with a TELNET port are:
  2093.  
  2094. =over 2
  2095.  
  2096. =item *
  2097.  
  2098. You're not familiar with sockets and you want a simple way to make
  2099. client connections to TCP services.
  2100.  
  2101. =item *
  2102.  
  2103. You want to be able to specify your own time-out while connecting,
  2104. reading, or writing.
  2105.  
  2106. =item *
  2107.  
  2108. You're communicating with an interactive program at the other end of
  2109. some socket or pipe and you want to wait for certain patterns to
  2110. appear.
  2111.  
  2112. =back
  2113.  
  2114. B<Please note> some important differences with most other Perl I/O
  2115. calls.  All input is buffered, while all output is flushed.  The
  2116. output record separator for B<print()> is set to B<\n> by default, so
  2117. there's no need to append all your commands with a newline.  See
  2118. B<output_record_separator()> to change the default.  In the input
  2119. stream, each sequence of B<\r\n> is converted to B<\n>.  In the output
  2120. stream, each occurrence of B<\n> is converted to a sequence of
  2121. B<\r\n>.  See B<binmode()> to change the default.  TCP protocols
  2122. typically use the ASCII sequence I<carriage-return> I<newline> to
  2123. designate a newline.
  2124.  
  2125. You'll need to be running at least Perl version 5.002 to use this
  2126. module.  This module does not require any libraries that don't already
  2127. come with the standard Perl distribution.  If you have the IO::
  2128. libraries then methods are inherited from the class IO::Socket::INET,
  2129. otherwise FileHandle is used as a base class.
  2130.  
  2131. Special methods are provided to handle errors.  Normally when an error
  2132. or timeout is encountered using a telnet object, the program dies with
  2133. an error message printed to standard error.  You may arrange for the
  2134. methods to return with an undefined value instead by using
  2135. B<errmode()> or the B<errmode> option to B<new()>.  See B<errmode()>
  2136. for other sophisticated error mode settings.  The error message itself
  2137. may be obtained using the B<errmsg()>.
  2138.  
  2139. Note that I<eof> is not considered an error while I<timing-out> is.
  2140.  
  2141. While debugging your program use B<input_log()> or B<dump_log()> to
  2142. see what's actually being received and sent.
  2143.  
  2144. Two different styles of named arguments are supported.  This document
  2145. only shows the IO:: style:
  2146.  
  2147.     Net::Telnet->new(Timeout => 20);
  2148.  
  2149. however the dash-option style is also allowed:
  2150.  
  2151.     Net::Telnet->new(-timeout => 20);
  2152.  
  2153. For more help, see the B<EXAMPLES> section below.
  2154.  
  2155. This is an alpha version - meaning that the interface may change in
  2156. future versions.  Contact me, Jay Rogers <jay@rgrs.com>, if you find
  2157. any bugs or have suggestions for improvement.
  2158.  
  2159.  
  2160. =head1 METHODS
  2161.  
  2162.  
  2163. =head2 new - create a new Net::Telnet object
  2164.  
  2165.     $obj = Net::Telnet->new([Binmode    => $mode,]
  2166.                             [Dump_Log   => $filename,]
  2167.                             [Errmode    => $errmode,]
  2168.                             [Fhopen     => $filehandle,]
  2169.                             [Host       => $host,]
  2170.                             [Input_log  => $file,]
  2171.                             [Input_record_separator => $char,]
  2172.                             [Output_log => $file,]
  2173.                             [Output_record_separator => $char,]
  2174.                             [Port       => $port,]
  2175.                             [Prompt     => $matchop,]
  2176.                             [Telnetmode => $mode,]
  2177.                             [Timeout    => $secs,]);
  2178.  
  2179. This is the constructor for Net::Telnet objects.  A new object is
  2180. returned on success, the I<$errmode> action is performed on failure -
  2181. see B<errmode()>.  The arguments are short-cuts to methods of the same
  2182. name.
  2183.  
  2184. If the I<$host> argument is given then the object is opened by
  2185. connecting to TCP I<$port> on I<$host>.  Also see B<open()>.  The new
  2186. object returned is given the following defaults in the absence of
  2187. corresponding named arguments:
  2188.  
  2189. =over 2
  2190.  
  2191. =item *
  2192.  
  2193. The default B<host> is B<"localhost">
  2194.  
  2195. =item *
  2196.  
  2197. The default B<port> is B<23>
  2198.  
  2199. =item *
  2200.  
  2201. The default B<prompt> is B<'/[$%#>>B<] $/'>
  2202.  
  2203. =item *
  2204.  
  2205. The default B<timeout> is B<10>
  2206.  
  2207. =item *
  2208.  
  2209. The default B<errmode> is B<'die'>
  2210.  
  2211. =item *
  2212.  
  2213. The default B<output_record_separator> is B<"\n">
  2214.  
  2215. =item *
  2216.  
  2217. The default B<input_record_separator> is B<"\n">
  2218.  
  2219. =item *
  2220.  
  2221. The default B<binmode> is B<0>, which means do newline translations
  2222.  
  2223. =back
  2224.  
  2225. =head2 binmode - turn off/on newline translation
  2226.  
  2227.     $prev = $obj->binmode($mode);
  2228.  
  2229. This method controls whether or not sequences of B<\r\n> are
  2230. translated.  By default they are translated (i.e. binmode is I<off>).
  2231.  
  2232. If I<$mode> is missing or B<1> then binmode is I<on> and newline
  2233. translation is not done.
  2234.  
  2235. If I<$mode> is B<0> then binmode is I<off> and newline translation is
  2236. done.  In the input stream, each sequence of B<\r\n> is converted to
  2237. B<\n> and in the output stream, each occurrence of B<\n> is converted
  2238. to a sequence of B<\r\n>.
  2239.  
  2240. Note that input is always buffered.  Changing binmode doesn't effect
  2241. what's already been read into the buffer.  Output is not buffered and
  2242. changing binmode will have an immediate effect.
  2243.  
  2244.  
  2245. =head2 break - send TELNET break character
  2246.  
  2247.     $ok = $obj->break;
  2248.  
  2249. This method sends the TELNET break character.  This character is
  2250. provided because it's a signal outside the USASCII set which is
  2251. currently given local meaning within many systems.  It's intended to
  2252. indicate that the Break Key or the Attention Key was hit.
  2253.  
  2254.  
  2255. =head2 close - close object
  2256.  
  2257.     $ok = $obj->close;
  2258.  
  2259. This method closes the socket, file, or pipe associated with the
  2260. object.
  2261.  
  2262.  
  2263. =head2 cmd - issue command and retrieve output
  2264.  
  2265.     $ok = $obj->cmd($string);
  2266.     $ok = $obj->cmd(String   => $string,
  2267.                     [Output  => $ref,]
  2268.                     [Prompt  => $match,]
  2269.                     [Timeout => $secs,]);
  2270.  
  2271.     @output = $obj->cmd($string);
  2272.     @output = $obj->cmd(String  => $string,
  2273.                         [Output  => $ref,]
  2274.                         [Prompt  => $match,]
  2275.                         [Timeout => $secs,]);
  2276.  
  2277. This method sends the command I<$string>, and reads the characters
  2278. sent back by the command up until and including the matching prompt.
  2279. It's assumed that the program to which you're sending is some kind of
  2280. command prompting interpreter such as a shell.
  2281.  
  2282. In a scalar context the characters read are discarded and a boolean is
  2283. returned indicating the success or failure of sending the command
  2284. string and reading the prompt.  Note that in order to return on error,
  2285. B<errmode()> must not be set to I<die>.
  2286.  
  2287. In an array context, just the output generated by the command is
  2288. returned, one line per element.  In other words, all the characters in
  2289. between the echoed back command string and the prompt are returned.
  2290. If the command happens to return no output, an array containing one
  2291. element, the null string is returned.  This is so the array will
  2292. indicate I<true> in a boolean context.
  2293.  
  2294. Optional named arguments are provided to override the current settings
  2295. of prompt and timeout.
  2296.  
  2297. The B<output> named argument provides an alternative method of
  2298. receiving command output.  If you pass a scalar reference, the output
  2299. is returned in the referenced scalar.  If you pass an array or hash
  2300. reference, the lines of output are returned in the referenced array or
  2301. hash.
  2302.  
  2303.  
  2304. =head2 dump_log - log all I/O in dump format
  2305.  
  2306.     $fh = $obj->dump_log;
  2307.  
  2308.     $fh = $obj->dump_log($fh);
  2309.  
  2310.     $fh = $obj->dump_log($filename);
  2311.  
  2312. This method starts or stops dump format logging of all the object's
  2313. input and output.  The dump format shows the blocks read and written
  2314. in a hexadecimal and printable character format.  This method is
  2315. useful when debugging, however you might want to first try
  2316. B<input_log()> as it's more readable.
  2317.  
  2318. If no argument is given, the current log filehandle is returned.  A
  2319. null string indicates logging is off.
  2320.  
  2321. To stop logging, use a null string as an argument.
  2322.  
  2323. If an open filehandle is given, it is used for logging and returned.
  2324. Otherwise, the argument is assumed to be the name of a file, the file
  2325. is opened and a filehandle to it is returned.
  2326.  
  2327.  
  2328. =head2 eof - end of file read indicator
  2329.  
  2330.     $eof = $obj->eof;
  2331.  
  2332. This method indicates if end of file has been read.  Because the input
  2333. is buffered this isn't the same thing as I<$obj> has closed.  In other
  2334. words I<$obj> can be closed but there still can be stuff in the buffer
  2335. to be read.  Under this condition you can still read but you won't be
  2336. able to write.
  2337.  
  2338.  
  2339. =head2 errmode - set action to perform on error
  2340.  
  2341.     $mode = $obj->errmode;
  2342.  
  2343.     $prev = $obj->errmode($mode);
  2344.  
  2345. This method gets or sets the action used when errors are encountered
  2346. using the object.  The first calling sequence returns the current
  2347. error mode.  The second calling sequence sets it to I<$mode> and
  2348. returns the previous mode.  Valid values for I<$mode> are B<die> (the
  2349. default), B<return>, a I<coderef>, or an I<arrayref>.
  2350.  
  2351. When mode is B<die> then when an error is encountered using the
  2352. object, the program dies and an error message is printed on standard
  2353. error.
  2354.  
  2355. When mode is B<return> then the method generating the error places an
  2356. error message in the object and returns the undefined value in a
  2357. scalar context and a null list in list context.  The error message may
  2358. be obtained using B<errmsg()>.
  2359.  
  2360. When mode is a I<coderef>, then when an error is encountered
  2361. I<coderef> is called with the error message as its first argument.
  2362. Using this mode you may have your own subroutine handle errors.  If
  2363. I<coderef> itself returns then the method generating the error returns
  2364. undefined or a null list depending on context.
  2365.  
  2366. When mode is an I<arrayref>, the first element of the array must be a
  2367. I<coderef>.  Any elements that follow are the arguments to I<coderef>.
  2368. When an error is encountered, the I<coderef> is called with its
  2369. arguments.  Using this mode you may have your own subroutine handle
  2370. errors.  If the I<coderef> itself returns then the method generating
  2371. the error returns undefined or a null list depending on context.
  2372.  
  2373.  
  2374. =head2 errmsg - most recent error message
  2375.  
  2376.     $msg = $obj->errmsg;
  2377.  
  2378.     $prev = $obj->errmsg(@msgs);
  2379.  
  2380. The first calling sequence returns the error message associated with
  2381. the object.  The null string is returned if no error has been
  2382. encountered yet.  The second calling sequence sets the error message
  2383. for the object to the concatenation of I<@msgs> and returns the
  2384. previous error message.  Normally, error messages are set internally
  2385. by a method when an error is encountered.
  2386.  
  2387.  
  2388. =head2 error - perform the error mode action
  2389.  
  2390.     $obj->error(@msgs);
  2391.  
  2392. This method concatenates I<@msgs> into a string and places it in the
  2393. object as the error message.  Also see B<errmsg()>.  It then performs
  2394. the error mode.  Also see B<errmode()>.
  2395.  
  2396. If the error mode doesn't cause the program to die then the undefined
  2397. value or a null list is returned depending on context.
  2398.  
  2399. This method is primarily used by this class or a sub-class to perform
  2400. the user requested action when an error is encountered.
  2401.  
  2402.  
  2403. =head2 fhopen - use an existing open filehandle
  2404.  
  2405.     $ok = $obj->fhopen($fh);
  2406.  
  2407. This method associates the open filehandle I<$fh> with the object for
  2408. further I/O.
  2409.  
  2410. This method provides a way to use this module with a filehandle that's
  2411. already opened.  Suppose you want to use the features of this module
  2412. to do I/O to something other than a TCP port.  Instead of opening the
  2413. object for I/O to a TCP port by passing a B<host> arg to B<new()> or
  2414. invoking B<open()>, call this method instead.
  2415.  
  2416.  
  2417. =head2 get - read block of data
  2418.  
  2419.     $data = $obj->get([Timeout => $secs,]);
  2420.  
  2421. This method reads a block of data from the object and returns it along
  2422. with any buffered data.  If no buffered data is available to return,
  2423. it will wait for data to read using the timeout specified in the
  2424. object.  You can override that timeout using I<$secs>.  Also see
  2425. B<timeout()>.  If buffered data is available to return, it also checks
  2426. for a block of data that can be immediately read.
  2427.  
  2428. On eof an undefined value is returned.  On timeout or other errors the
  2429. error mode action is performed.
  2430.  
  2431.  
  2432. =head2 getline - read next line
  2433.  
  2434.     $line = $obj->getline([Timeout => $secs,]);
  2435.  
  2436. This method reads and returns the next line of data from the object.
  2437. You can use B<input_record_separator()> to change the notion of what
  2438. separates a line.  The default is B<\n>.
  2439.  
  2440. If a line isn't immediately available, this method blocks waiting for
  2441. a line or the timeout.  You can override the object's timeout for this
  2442. method using I<$secs>.  Also see B<timeout()>.
  2443.  
  2444. On eof an undefined value is returned.  On timeout or other errors the
  2445. error mode action is performed.
  2446.  
  2447.  
  2448. =head2 getlines - read next lines
  2449.  
  2450.     @lines = $obj->getlines([Timeout => $secs,]);
  2451.  
  2452. This method reads and returns the next available lines of data from
  2453. the object.  You can use B<input_record_separator()> to change the
  2454. notion of what separates a line.  The default is B<\n>.
  2455.  
  2456. If a line isn't immediately available, this method blocks waiting for
  2457. one or more lines, or the timeout.  You can override the object's
  2458. timeout for this method using I<$secs>.  Also see B<timeout()>.
  2459.  
  2460. On eof a null array is returned.  On timeout or other errors the error
  2461. mode action is performed.
  2462.  
  2463.  
  2464. =head2 host - name of remote host
  2465.  
  2466.     $host = $obj->host;
  2467.  
  2468.     $prev = $obj->host($host);
  2469.  
  2470. This method designates the remote host.  With no argument this method
  2471. returns the current host name set in the object.  With an argument it
  2472. sets the current host name to I<$host> and returns the previous host
  2473. name.  You may indicate the remote host using either a hostname or an
  2474. IP address.
  2475.  
  2476.  
  2477. =head2 input_log - log all input
  2478.  
  2479.     $fh = $obj->input_log;
  2480.  
  2481.     $fh = $obj->input_log($fh);
  2482.  
  2483.     $fh = $obj->input_log($filename);
  2484.  
  2485. This method starts or stops logging of input.  This is useful when
  2486. debugging.  Also see B<dump_log()>.  Because most command interpreters
  2487. echo back commands received, its likely all your output will also be
  2488. in this log.  Note that input logging occurs after newline
  2489. translation.  See B<binmode()> for details on newline translation.
  2490.  
  2491. If no argument is given, the log filehandle is returned.  A null
  2492. string indicates logging is off.
  2493.  
  2494. To stop logging, use a null string as an argument.
  2495.  
  2496. If an open filehandle is given, it is used for logging and returned.
  2497. Otherwise, the argument is assumed to be the name of a file, the file
  2498. is opened for logging and a filehandle to it is returned.
  2499.  
  2500.  
  2501. =head2 input_record_separator - input line delimiter
  2502.  
  2503.     $rs = $obj->input_record_separator;
  2504.  
  2505.     $prev = $obj->input_record_separator($rs);
  2506.  
  2507. This method designates the line delimiter for input.  It's used with
  2508. B<getline()>, B<getlines()>, and B<cmd()> to determine lines in the
  2509. input.
  2510.  
  2511. With no argument this method returns the current input record
  2512. separator set in the object.  With an argument it sets the input
  2513. record separator to I<$rs> and returns the previous value.
  2514.  
  2515.  
  2516. =head2 lastline - the lastline read
  2517.  
  2518.     $line = $obj->lastline;
  2519.  
  2520.     $prev = $obj->lastline($line);
  2521.  
  2522. This method saves the last line read from the object.  This may be a
  2523. useful error message when the remote side abnormally closes the
  2524. connection.  Typically the remote side will print an error message
  2525. before closing.
  2526.  
  2527. With no argument this method returns the last line read from the
  2528. object.  With an argument it sets the last line read to I<$line> and
  2529. returns the previous value.  Normally, only internal methods set the
  2530. last line.
  2531.  
  2532.  
  2533. =head2 login - perform standard login
  2534.  
  2535.     $ok = $obj->login($username, $password);
  2536.  
  2537.     $ok = $obj->login(Name     => $username,
  2538.                       Password => $password,
  2539.                       [Prompt  => $match,]
  2540.                       [Timeout => $secs,]);
  2541.  
  2542. This method performs a standard login by waiting for a login prompt and
  2543. responding with I<$username>, then waiting for the password prompt and
  2544. responding with I<$password>, and then waiting for the command
  2545. interpreter prompt.  If any of the prompts sent don't match what's
  2546. expected, the method will timeout - unless timeout is turned off.
  2547.  
  2548. Login prompts must match either of the patterns:
  2549.  
  2550.     /login[: ]*$/i
  2551.     /username[: ]*$/i
  2552.  
  2553. Password prompts must match the pattern:
  2554.  
  2555.     /password[: ]*$/i
  2556.  
  2557. The command interpreter prompt must match the current value of
  2558. B<prompt()>.
  2559.  
  2560. Optional named arguments are provided to override the current settings
  2561. of prompt and timeout.
  2562.  
  2563.  
  2564. =head2 max_buffer_length - maximum size of input buffer
  2565.  
  2566.     $len = $obj->max_buffer_length;
  2567.  
  2568.     $prev = $obj->max_buffer_length($len);
  2569.  
  2570. This method designates the maximum size of the input buffer.  An error
  2571. is generated when a read causes the buffer to exceed this limit.  The
  2572. default value is 1,048,576 bytes (1MB).  The input buffer can grow
  2573. much larger than the block size when you read using B<getline()> or
  2574. B<waitfor()> and the data stream contains no newlines or matching
  2575. waitfor patterns.
  2576.  
  2577. With no argument this method returns the current maximum buffer length
  2578. set in the object.  With an argument it sets the maximum buffer length
  2579. to I<$len> and returns the previous value.
  2580.  
  2581.  
  2582. =head2 open - connect to host and port
  2583.  
  2584.     $ok = $obj->open($host);
  2585.  
  2586.     $ok = $obj->open([Host    => $host,]
  2587.                      [Port    => $port,]
  2588.                      [Timeout => $secs,]);
  2589.  
  2590. This method opens a TCP connection to I<$port> on I<$host>.  If either
  2591. argument is missing then the current value of B<host()> or B<port()>
  2592. is used.
  2593.  
  2594. An optional named argument is provided to override the current setting
  2595. of timeout.
  2596.  
  2597. Timeouts don't work for this method on machines that don't implement
  2598. SIGALRM.  For those machines, an error is returned when the system
  2599. reaches its own time-out while trying to connect.
  2600.  
  2601. A side effect of this method is to reset the alarm interval associated
  2602. with SIGALRM.
  2603.  
  2604.  
  2605. =head2 output_field_separator - field separator for print
  2606.  
  2607.     $ofs = $obj->output_field_separator;
  2608.  
  2609.     $prev = $obj->output_field_separator($ofs);
  2610.  
  2611. This method designates the output field separator for B<print()>.
  2612. Ordinarily the print method simply prints out the comma separated
  2613. fields you specify.  Set this to specify what's printed between
  2614. fields.
  2615.  
  2616. With no argument this method returns the current output field
  2617. separator set in the object.  With an argument it sets the output
  2618. field separator to I<$ofs> and returns the previous value.
  2619.  
  2620.  
  2621. =head2 output_log - log all output
  2622.  
  2623.     $fh = $obj->output_log;
  2624.  
  2625.     $fh = $obj->output_log($fh);
  2626.  
  2627.     $fh = $obj->output_log($filename);
  2628.  
  2629. This method starts or stops logging of output.  This is useful when
  2630. debugging.  Also see B<dump_log()>.  Because most command interpreters
  2631. echo back commands received, its likely all your output would also be
  2632. in an input log.  See B<input_log()>.  Note that output logging occurs
  2633. before newline translation.  See B<binmode()> for details on newline
  2634. translation.
  2635.  
  2636. If no argument is given, the log filehandle is returned.  A null
  2637. string indicates logging is off.
  2638.  
  2639. To stop logging, use a null string as an argument.
  2640.  
  2641. If an open filehandle is given, it is used for logging and returned.
  2642. Otherwise, the argument is assumed to be the name of a file, the file
  2643. is opened for logging and a filehandle to it is returned.
  2644.  
  2645.  
  2646. =head2 output_record_separator - output line delimiter
  2647.  
  2648.     $ors = $obj->output_record_separator;
  2649.  
  2650.     $prev = $obj->output_record_separator($ors);
  2651.  
  2652. This method designates the output record separator for B<print()>.
  2653. Ordinarily the print operator simply prints out the comma separated
  2654. fields you specify, with no trailing newline or record separator
  2655. assumed.  Set this variable to specify what's printed at the end of
  2656. the print.
  2657.  
  2658. Note: the output record separator is set to B<\n> by default, so
  2659. there's no need to append all your commands with a newline.
  2660.  
  2661. With no argument this method returns the current output record
  2662. separator set in the object.  With an argument it sets the output
  2663. record separator to I<$ors> and returns the previous value.
  2664.  
  2665.  
  2666. =head2 port - remote port
  2667.  
  2668.     $port = $obj->port;
  2669.  
  2670.     $prev = $obj->port($port);
  2671.  
  2672. This method designates the remote TCP port.  With no argument this
  2673. method returns the current port number.  With an argument it sets the
  2674. current port number to I<$port> and returns the previous port.  If
  2675. I<$port> is a service name, then first it's converted to a port number
  2676. using the perl function B<getservbyname()>.
  2677.  
  2678.  
  2679. =head2 print - write to object
  2680.  
  2681.     $ok = $obj->print(@list);
  2682.  
  2683. This method prints a string or a comma-separated list of strings to
  2684. the opened object and returns non-zero if all data was successfully
  2685. written.
  2686.  
  2687. By default, the B<output_record_separator()> is set to B<\n> in order
  2688. to have your commands automatically end with a newline.  In most cases
  2689. your output is being read by a command interpreter which won't accept
  2690. a command until newline is read.  This is similar to someone typing a
  2691. command and hitting the return key.
  2692.  
  2693. On failure, it's possible that some data was written.  If you choose
  2694. to try and recover from a print timing-out, use B<print_length()> to
  2695. determine how much was written before timeout occurred.
  2696.  
  2697.  
  2698. =head2 print_length - number of bytes written by print
  2699.  
  2700.     $num = $obj->print_length;
  2701.  
  2702. This returns the number of bytes successfully written by the most
  2703. recent B<print()>.
  2704.  
  2705.  
  2706. =head2 prompt - pattern to match a prompt
  2707.  
  2708.     $matchop = $obj->prompt;
  2709.  
  2710.     $prev = $obj->prompt($matchop);
  2711.  
  2712. This method sets the pattern used to find a prompt in the input
  2713. stream.  It must be a string representing a valid perl pattern match
  2714. operator.  The methods B<login()> and B<cmd()> try to read until
  2715. matching the prompt.  If the pattern chosen doesn't match what's
  2716. sent, then it's likely those commands will timeout.
  2717.  
  2718. With no argument this method returns the prompt set in the object.
  2719. With an argument it sets the prompt to I<$matchop> and returns the
  2720. previous value.
  2721.  
  2722. The default prompt is '/[$%#>] $/'
  2723.  
  2724. Always use single quotes to construct I<$matchop> to avoid unintended
  2725. backslash interpretation.  Using single quotes, you only need add
  2726. extra backslashes to quote patterns containing B<\'> or B<\\>.
  2727.  
  2728.  
  2729. =head2 telnetmode - turn off/on telnet command interpretation
  2730.  
  2731.     $prev = $obj->telnet($mode);
  2732.  
  2733. This method controls whether or not telnet commands in the data stream
  2734. are recognized and handled.  The telnet protocol uses certain
  2735. character sequences sent in the data stream to control the session.
  2736. If the port you're connecting to isn't using the telnet protocol, then
  2737. you should turn this mode off.  The default is I<on>.
  2738.  
  2739. If I<$mode> is B<0> then telnet mode is off.  If I<$mode> is missing
  2740. or B<1> then telnet mode is on.
  2741.  
  2742.  
  2743. =head2 timed_out - timeout indicator
  2744.  
  2745.     $boolean = $obj->timed_out;
  2746.  
  2747.     $prev = $obj->timed_out($boolean);
  2748.  
  2749. This method indicates if a previous read or write method timed-out.
  2750.  
  2751. With no argument this method returns true if a previous method
  2752. timed-out.  With an argument it sets the indicator.  Generally this is
  2753. used by internal methods to clear it.
  2754.  
  2755.  
  2756. =head2 timeout - I/O timeout interval
  2757.  
  2758.     $secs = $obj->timeout;
  2759.  
  2760.     $prev = $obj->timeout($secs);
  2761.  
  2762. This method sets the timeout interval that's used when performing I/O
  2763. or connecting to a port.  When a method doesn't complete within the
  2764. timeout interval then it's an error and the error mode action is
  2765. performed.
  2766.  
  2767. The timeout may be expressed as a relative or absolute value.  If
  2768. I<$secs> is greater than or equal to the time the program was started,
  2769. as determined by $^T, then it's the absolute time when timeout occurs.
  2770. Also see the perl function B<time()>.  A relative timeout happens
  2771. I<$secs> from when the I/O method begins.
  2772.  
  2773. If I<$secs> is B<0> then timeout occurs if the data cannot be
  2774. immediately read or written.  Use the undefined value to turn off
  2775. timing-out.
  2776.  
  2777. With no argument this method returns the timeout set in the object.
  2778. With an argument it sets the timeout to I<$secs> and returns the
  2779. previous value.
  2780.  
  2781.  
  2782. =head2 watchfor - wait for pattern in the input
  2783.  
  2784.     $ok = $obj->waitfor($matchop);
  2785.     $ok = $obj->waitfor([Match   => $matchop,]
  2786.                         [String  => $string,]
  2787.                         [Timeout => $secs,]);
  2788.  
  2789.     ($prematch, $match) = $obj->waitfor($matchop);
  2790.     ($prematch, $match) = $obj->waitfor([Match   => $matchop,]
  2791.                                         [String  => $string,]
  2792.                                         [Timeout => $secs,]);
  2793.  
  2794. This method reads until a pattern match or string is found in the
  2795. input stream.  All the characters before and including the match are
  2796. removed from the input stream.  On eof an undefined value is returned.
  2797. On timeout or other errors the error mode action is performed.
  2798.  
  2799. In an array context the characters before the match and the matched
  2800. characters are returned in I<$prematch> and I<$match>.
  2801.  
  2802. You can specify more than one pattern or string by simply providing
  2803. multiple B<Match> and/or B<String> named arguments.  A I<$matchop>
  2804. must be a string representing a valid perl pattern match operator.
  2805. The I<$string> is just a substring to find in the input stream.
  2806.  
  2807. An optional named argument is provided to override the current setting
  2808. of timeout.
  2809.  
  2810. Always use single quotes to construct I<$matchop> to avoid unintended
  2811. backslash interpretation.  Using single quotes, you only need add
  2812. extra backslashes to quote patterns containing B<\'> or B<\\>.
  2813.  
  2814.  
  2815. =head1 SEE ALSO
  2816.  
  2817. =over 2
  2818.  
  2819. =item *
  2820.  
  2821. RFC 854 - TELNET Protocol Specification
  2822.  
  2823. =item *
  2824.  
  2825. RFC 1143 - The Q Method of Implementing TELNET Option Negotiation
  2826.  
  2827. =item *
  2828.  
  2829. TELNET Options
  2830.  
  2831. =back
  2832.  
  2833.  
  2834. =head1 EXAMPLES
  2835.  
  2836. This example gets the current weather forecast for Brainerd, Minnesota.
  2837.  
  2838.     use Net::Telnet ();
  2839.     my($forecast, $t);
  2840.  
  2841.     $t = new Net::Telnet (-host => "rainmaker.wunderground.com");
  2842.  
  2843.     ## Wait for first prompt and "hit return".
  2844.     $t->waitfor('/continue:.*$/');
  2845.     $t->print("");
  2846.  
  2847.     ## Wait for second prompt and respond with city code.
  2848.     $t->waitfor('/city code:.*$/');
  2849.     $t->print("BRD");
  2850.  
  2851.     ## Read and print the first page of forecast.
  2852.     ($forecast) = $t->waitfor('/[ \t]+press return to continue/i');
  2853.     print $forecast;
  2854.  
  2855.     exit;
  2856.  
  2857.  
  2858. This example checks a POP server to see if you have mail.
  2859.  
  2860.     use Net::Telnet ();
  2861.     my($hostname, $line, $passwd, $pop, $username);
  2862.  
  2863.     $hostname = "your_destination_host_here";
  2864.     $username = "your_username_here";
  2865.     $passwd = "your_password_here";
  2866.  
  2867.     $pop = new Net::Telnet (-host => $hostname,
  2868.                 -port => 110,
  2869.                 -telnetmode => '');
  2870.  
  2871.     ## Read connection message.
  2872.     $line = $pop->getline;
  2873.     die $line unless $line =~ /^\+OK/;
  2874.  
  2875.     ## Send user name.
  2876.     $pop->print("user $username");
  2877.     $line = $pop->getline;
  2878.     die $line unless $line =~ /^\+OK/;
  2879.  
  2880.     ## Send password.
  2881.     $pop->print("pass $passwd");
  2882.     $line = $pop->getline;
  2883.     die $line unless $line =~ /^\+OK/;
  2884.  
  2885.     ## Request status of messages.
  2886.     $pop->print("list");
  2887.     $line = $pop->getline;
  2888.     print $line;
  2889.  
  2890.     exit;
  2891.  
  2892.  
  2893. Here's an example you can use to down load a file of any type.  The
  2894. file is read from the remote host's standard output using cat.  To
  2895. prevent any output processing, the remote host's standard output is
  2896. put in raw mode using the Bourne shell.  The Bourne shell is used
  2897. because some shells, notably tcsh, prevent changing tty modes.  Upon
  2898. completion, FTP style statistics are printed to stderr.
  2899.  
  2900.     use Net::Telnet;
  2901.     my($block, $filename, $host, $hostname, $k_per_sec, $line,
  2902.        $num_read, $passwd, $prevblock, $prompt, $size, $size_bsd,
  2903.        $size_sysv, $start_time, $total_time, $username);
  2904.  
  2905.     $hostname = "your_destination_host_here";
  2906.     $username = "your_username_here";
  2907.     $passwd = "your_password_here";
  2908.     $filename = "your_download_file_here";
  2909.  
  2910.     ## Connect and login.
  2911.     $host = new Net::Telnet (Host => $hostname,
  2912.                              Timeout => 30,
  2913.                              Prompt => '/[%#>] $/');
  2914.     $host->login($username, $passwd);
  2915.  
  2916.     ## Make sure prompt won't match anything in send data.
  2917.     $prompt = '_funkyPrompt_';
  2918.     $host->prompt("/$prompt\$/");
  2919.     $host->cmd("set prompt = '$prompt'");
  2920.  
  2921.     ## Get size of file.
  2922.     ($line) = $host->cmd("/usr/bin/ls -l $filename");
  2923.     ($size_bsd, $size_sysv) = (split ' ', $line)[3,4];
  2924.     if ($size_sysv =~ /^\d+$/) {
  2925.         $size = $size_sysv;
  2926.     }
  2927.     elsif ($size_bsd =~ /^\d+$/) {
  2928.         $size = $size_bsd;
  2929.     }
  2930.     else {
  2931.         die "$filename: no such file on $hostname";
  2932.     }
  2933.  
  2934.     ## Start sending the file.
  2935.     binmode STDOUT;
  2936.     $host->binmode;
  2937.     $host->print("/usr/bin/sh -c 'stty raw; cat $filename'");
  2938.     $host->getline;    # discard echoed back line
  2939.  
  2940.     ## Read file a block at a time.
  2941.     $num_read = 0;
  2942.     $prevblock = '';
  2943.     $start_time = time;
  2944.     while (($block = $host->get) and ($block !~ /$prompt$/o)) {
  2945.         if (length $block >= length $prompt) {
  2946.             print $prevblock;
  2947.             $num_read += length $prevblock;
  2948.             $prevblock = $block;
  2949.         }
  2950.         else {
  2951.             $prevblock .= $block;
  2952.         }
  2953.  
  2954.     }
  2955.     $host->close;
  2956.  
  2957.     ## Print last block without trailing prompt.
  2958.     $prevblock .= $block;
  2959.     $prevblock =~ s/$prompt$//;
  2960.     print $prevblock;
  2961.     $num_read += length $prevblock;
  2962.     die "error: expected size $size, received size $num_read\n"
  2963.         unless $num_read == $size;
  2964.  
  2965.     ## Print totals.
  2966.     $total_time = (time - $start_time) || 1;
  2967.     $k_per_sec = ($size / 1024) / $total_time;
  2968.     $k_per_sec = sprintf "%3.1f", $k_per_sec;
  2969.     warn("$num_read bytes received in $total_time seconds ",
  2970.          "($k_per_sec Kbytes/s)\n");
  2971.  
  2972.     exit;
  2973.  
  2974.  
  2975. Here's an example that shows how to talk to a program that
  2976. must communicate via a terminal.  In this case we're talking
  2977. to the telnet program via a pseudo-terminal.  We use the
  2978. Comm package to start the telnet program and return a
  2979. filehandle to the pseudo-terminal.  This example sends some
  2980. initial commands and then allows the user to type commands
  2981. to the telnet session.
  2982.  
  2983.     use Net::Telnet;
  2984.     my($comm_pty, $host, $hostname, $passwd, $pty,
  2985.        $username, @lines);
  2986.  
  2987.     $hostname = "your_host_here";
  2988.     $username = "your_name_here";
  2989.     $passwd = "your_passwd_here";
  2990.  
  2991.     ## Start the telnet program so we can talk to it via a
  2992.     ## pseudo-terminal.
  2993.     {
  2994.         local $^W = 0;  # Comm.pl isn't warning clean
  2995.  
  2996.         require "Comm.pl";
  2997.         &Comm::init("close_it", "interact",
  2998.                     "open_proc", "stty_raw", "stty_sane");
  2999.         $comm_pty = &open_proc("telnet $hostname")
  3000.             or die "open_proc failed";
  3001.  
  3002.         ## Unfortunately the Comm package doesn't
  3003.         ## return us a fully qualified filehandle.  We
  3004.         ## must keep the filehandle Comm returned for
  3005.         ## its use and we must build another filehandle
  3006.         ## qualified with the current package for our
  3007.         ## use.
  3008.         $pty = "main::" . $comm_pty;
  3009.     }
  3010.  
  3011.     ## Obtain a new Net::Telnet object that does I/O to the
  3012.     ## pseudo-terminal attached to the running telnet
  3013.     ## program.  The "Telnetmode" is "off" because we're
  3014.     ## not talking directly to a telnet port as we normally
  3015.     ## do, we're talking to a pseudo-terminal.  The
  3016.     ## "Output_record_separator" is now a carriage-return
  3017.     ## because that's what you'd normally hit when you get
  3018.     ## done typing a line at a terminal.
  3019.     $host = new Net::Telnet (Fhopen => $pty,
  3020.                              Timeout => 10,
  3021.                              Prompt => '/[%#>] $/',
  3022.                              Telnetmode => 0,
  3023.                              Output_record_separator => "\r");
  3024.  
  3025.     ## Issue some commands.
  3026.     $host->login($username, $passwd);
  3027.     $host->cmd("setenv DISPLAY $ENV{DISPLAY}");
  3028.     print $host->cmd("who");
  3029.  
  3030.     ## Allow the user to interact with telnet program until
  3031.     ## they exit.
  3032.     {
  3033.         no strict 'subs';  # so we can refer to STDIN
  3034.         local $^W = 0;     # Comm.pl isn't warning clean
  3035.  
  3036.         &stty_raw(STDIN);
  3037.         &interact($comm_pty);
  3038.         &stty_sane(STDIN);
  3039.         &close_it($comm_pty);
  3040.     }
  3041.  
  3042.     print "Exited telnet\n";
  3043.     exit;
  3044.  
  3045.  
  3046. =head1 AUTHOR
  3047.  
  3048. Jay Rogers <jay@rgrs.com>
  3049.  
  3050.  
  3051. =head1 COPYRIGHT
  3052.  
  3053. Copyright (c) 1997 Jay Rogers. All rights reserved.  This program is
  3054. free software; you can redistribute it and/or modify it under the same
  3055. terms as Perl itself.
  3056.