[comp.lang.perl] Telnet from within Perl?

anders@dit.lth.se (Anders Ardo) (02/15/91)

I need to trap part of the output from a telnet session into a file and do
some processing to it. I would like to do the processing with Perl.
Is it possible to run telnet interactively from within a Perl-script?
How do I do it?

Actually the telnet need not be interactive, I would settle for a way
to run a fixed script as input to telnet (with usernames and passwords
etc.) if that is possible.

  Any hints or suggestions are welcome.       Thanks for your help.
           Anders
-- 
 Anders Ardo                       Tel: int+46 46 107522
 Dept. of Computer Engineering     fax: int+46 46 104714
 University of Lund, P.O. Box 118  Internet: anders@dit.lth.se
 S-221 00  Lund, Sweden               or     anders%dit.lth.se@uunet.uu.net
                

rrr@u02.svl.cdc.com (Rich Ragan) (02/16/91)

In <1991Feb15.141235.9157@lth.se> anders@dit.lth.se (Anders Ardo) writes:

>I need to trap part of the output from a telnet session into a file and do
>some processing to it. I would like to do the processing with Perl.
>Is it possible to run telnet interactively from within a Perl-script?
>How do I do it?

I recently built a mail gateway using Perl. It uses telnet to get
to the external system. The following code excerpts should show
you how I did it. Basically, I open an input pipe to Telnet to
use for driving the connection and use a pseudo-terminal to
pick up the outputs from the Telnet connection. I left in a little
logic showing prompt matching (sub end_write) to give you a feel
of the general logic. Hope this helps.

#! /usr/local/bin/perl

#	Get pseudo tty's and open a pipe to telnet.

local($pty,$tty) = &getpty($PTY,$TTY);
open(IN,"+>$pty") || die "Can't get pty";
open(F,"|/usr/ucb/telnet external_sys  >$tty;exit;");
select(F);$|=1;select(STDOUT);$|=1;

 [STUFF DELETED]

#	Get next character from telnet and build string
#	received so far.

sub get_char {
        $c = getc(IN);
	$str .= $c;
[stuff deleted]
}

#	Master loop for WRITE processing prompts.

sub end_write {
%WRITES = ("//",1,"WRITE SUBCOMMAND:",2, 
"CHOOSE ONE NUMBER (C.R. FOR MORE, \"N\" TO BYPASS):",3,
"CHOOSE ONE NUMBER (TYPE \"N\" TO BYPASS):",3,
"LETTER NOT SENT",4, "FOUND UNIQUE ADDRESSEE:", 5, 
"(FOR ASSISTANCE, TYPE \"HELP ADDRESSEE\")",6, 
"LETTER SENT TO",7,
"NO ADDRESSEES",8);

        print F "SEND\r";
        while (1) {
                &get_char;
                $kind = $WRITES{$str} || next;
                $str = "";
                if ($kind == 1) {&quit_from_mail;}
                if ($kind == 2) {print F "SEND\r";}
                if ($kind == 3) {print F "N\r";$err=67;}
                if ($kind == 4) {$err=67;}
		if ($kind == 5) {&wait_for("SELECT (Y/N)?");print F "Y\r";}
		if ($kind == 6) {$err=67;}
		if ($kind == 7) {&wait_for("WRITE SUBCOMMAND:");
					print F "QUIT\r";}
		if ($kind == 8) {$err=67;&wait_for("WRITE SUBCOMMAND:");
					print F "QUIT\r";}
        }
}
#	wait_for(string) - Eat chars until string is matched.

sub wait_for {
    local($match) = @_;
        while ($str ne $match) {&get_char;}
        $str = "";
}

#	Disconnect the Telnet connection.

sub quit_from_mail {
        print F "\035\r";print F "quit\r";
	close(IN);;close(F);
}


#      Get a pseudo terminal connection.. (Borrowed code from expect.pl)

sub getpty {
        local($PTY,$TTY) = @_;
        # don't adjust $PTY,$TTY with main', but use caller when available
        local($pty,$tty);
        for $bank (112..127) {
                next unless -e sprintf("/dev/pty%c0", $bank);
                for $unit (48..57) {
                        $pty = sprintf("/dev/pty%c%c", $bank, $unit);
			open(PTY,"+>$pty") || next;
                        close(PTY); 
                        ($tty = $pty) =~ s/pty/tty/;
                        return ($pty,$tty);
                }
        }
	$err = 75; &quit_from_mail;
}

--
Richard R. Ragan   rrr@svl.cdc.com    (408) 496-4340 
Control Data Corporation - Silicon Valley Operations
5101 Patrick Henry Drive, Santa Clara, CA 95054-1111