[comp.unix.admin] telnet in a shell script

briantr@sunnet.EBay.Sun.COM (Brian Tran) (11/13/90)

I have a need to use the equivalence of the ".telnetrc" for use with
"telnet" in a C-shell program. How can I implement this so that
user doesn't not have to enter "username" and "password" when using
this little program?

Hints/suggestions/RTFM welcome

Many thanks,
brian

libes@cme.nist.gov (Don Libes) (11/14/90)

In article <3886@male.EBay.Sun.COM> briantr@sunnet.EBay.Sun.COM (Brian Tran) writes:
>I have a need to use the equivalence of the ".telnetrc" for use with
>"telnet" in a C-shell program. How can I implement this so that
>user doesn't not have to enter "username" and "password" when using
>this little program?

From your shell script, call an expect script like the following:

	spawn telnet male.ebay.sun.com
	expect "*login:*"
	send "brian\r"
	expect "*Password:"
	send "igiveup\r"
	interact


The "interact" will let you use the telnet as if you had logged in
yourself.  Or you can do more send/expect statements.

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/14/90)

In article <8026@muffin.cme.nist.gov> libes@cme.nist.gov (Don Libes) writes:
> In article <3886@male.EBay.Sun.COM> briantr@sunnet.EBay.Sun.COM (Brian Tran) writes:
    [ a telnet automation question ]
> From your shell script, call an expect script like the following:
> 	spawn telnet male.ebay.sun.com
> 	expect "*login:*"
> 	send "brian\r"
> 	expect "*Password:"
> 	send "igiveup\r"
> 	interact

A simple, exact translation of this into sh/pty code is shown below. It
works on any machine with named pipes---SunOS and Ultrix, for instance.
It's easy to modify for other machines.

One big advantage of the sh/pty version over Don's expect-based version
is that expect can't handle telnet job control. sh can't either, but at
least the user can type ``^]z'' to telnet followed by ``^Z'' to regain
his shell.

   #!/bin/sh
   /etc/mknod out.$$ p; exec 2>&1
   ( exec 4<out.$$; rm -f out.$$
   <&4 waitfor 'login: '
       echo 'brian'
   <&4 waitfor 'Password:'
       echo 'igiveup'
   <&4 cat -u >&2 &
       cat -u
   ) | pty telnet male.ebay.sun.com > out.$$

Here waitfor is a dumb program along the lines of

   extern char *malloc(); main(argc,argv) int argc; char *argv[]; {
    int len; char *s; int pos; char ch; int f; int p; if (!argv[1])
    exit(1); len = strlen(argv[1]); if (!(s = malloc(len))) exit(2);
    pos = 0; f = 0; while (read(0,&ch,1) == 1) { if (write(2,&ch,1) != 1)
    exit(3); if (ch) { s[pos] = ch; pos++; if (pos == len) { f = 1;
    pos = 0; } if (f && (ch == argv[1][len - 1])) { for (p = 1;
    s[(pos + p) % len] == argv[1][p];p++) ; if (!argv[1][p]) exit(0);
    } } } exit(4); }

Btw, Don, this is an example of what I meant by jury-rigging. Obviously
I only bothered to write waitfor once; it might be better to use a more
general tool (Perl, perhaps) to do the job, but waitfor isn't sluggish.

> The "interact" will let you use the telnet as if you had logged in
> yourself.  Or you can do more send/expect statements.

Similar comments apply to the script.

---Dan

libes@cme.nist.gov (Don Libes) (11/14/90)

In article <7006:Nov1408:13:3290@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>One big advantage of the sh/pty version over Don's expect-based version
>is that expect can't handle telnet job control. sh can't either, but at
>least the user can type ``^]z'' to telnet followed by ``^Z'' to regain
>his shell.

expect does understand job control.  (The man page explains all this.)
By default, "interact" passes characters like ^Z and ^] to the interactive
process (telnet, in this case) which is usually what is desired.  If you
want a csh you can suspend back to, just spawn a csh first.  Or, if you
want to suspend expect itself, just press the interact escape character
and you'll get back to the expect interpreter from which you can suspend
back to your shell by typing ^Z.  (This is how telnet itself works, too.)

Please, Dan, go ahead and talk about your own work, but stop trying to
explain mine.  You've done it an injustice every time.  Do me a favor
and don't even mention expect in your postings.

Don Libes          libes@cme.nist.gov      ...!uunet!cme-durer!libes

weimer@ssd.kodak.com (Gary Weimer) (11/15/90)

In article <7006:Nov1408:13:3290@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>Here waitfor is a dumb program along the lines of
>
>   extern char *malloc(); main(argc,argv) int argc; char *argv[]; {
>    int len; char *s; int pos; char ch; int f; int p; if (!argv[1])
>    exit(1); len = strlen(argv[1]); if (!(s = malloc(len))) exit(2);
>    pos = 0; f = 0; while (read(0,&ch,1) == 1) { if (write(2,&ch,1) != 1)
>    exit(3); if (ch) { s[pos] = ch; pos++; if (pos == len) { f = 1;
>    pos = 0; } if (f && (ch == argv[1][len - 1])) { for (p = 1;
>    s[(pos + p) % len] == argv[1][p];p++) ; if (!argv[1][p]) exit(0);
>    } } } exit(4); }

Niceformatingyougotthere :-)

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/15/90)

In article <8028@muffin.cme.nist.gov> libes@cme.nist.gov (Don Libes) writes:
> expect does understand job control.

No, it does not.

When I type ``z'' to telnet or ``suspend'' to csh, I expect it to stop.
The interaction should be transparent; the user shouldn't have to think
about expect being in the way. But expect doesn't monitor the status of
the spawned process and hence cannot handle job control transparently.
This is a limitation and you know it.

> (The man page explains all this.)

Yes, it does.

---Dan

craig@attcan.UUCP (Craig Campbell) (11/20/90)

In article <7006:Nov1408:13:3290@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>In article <8026@muffin.cme.nist.gov> libes@cme.nist.gov (Don Libes) writes:
 
>Here waitfor is a dumb program along the lines of
 
>   extern char *malloc(); main(argc,argv) int argc; char *argv[]; {
>    int len; char *s; int pos; char ch; int f; int p; if (!argv[1])
>    exit(1); len = strlen(argv[1]); if (!(s = malloc(len))) exit(2);
>    pos = 0; f = 0; while (read(0,&ch,1) == 1) { if (write(2,&ch,1) != 1)
>    exit(3); if (ch) { s[pos] = ch; pos++; if (pos == len) { f = 1;
>    pos = 0; } if (f && (ch == argv[1][len - 1])) { for (p = 1;
>    s[(pos + p) % len] == argv[1][p];p++) ; if (!argv[1][p]) exit(0);
>    } } } exit(4); }
 
>Btw, Don, this is an example of what I meant by jury-rigging. Obviously
>I only bothered to write waitfor once; it might be better to use a more
>general tool (Perl, perhaps) to do the job, but waitfor isn't sluggish.
 
>---Dan


Wow,
     I'm suprised that you would post code to the net looking like that!!
     (Actually, I'm suprised anyone would write code that looked like that.)
     Why did you do that?
     Is a <cr> keystroke really that much more expensive than a <sp> keystroke?
     
     Oh wait!!! I've got it!!  You crunched up some beautiful code just to 
     conserve net bandwidth and allow the display of the entire program on one
     screen!  Thanks for the thought, but I suspect resources aren't running 
     that short yet!!

     I'm glad I figured that one out....

craig

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/20/90)

In article <13064@vpk1.UUCP> craig@vpk1.ATT.COM (Craig Campbell) writes:
> In article <7006:Nov1408:13:3290@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> > Here waitfor is a dumb program along the lines of
    [ seven-plus packed lines of C code ]
> I'm suprised that you would post code to the net looking like that!!
> (Actually, I'm suprised anyone would write code that looked like that.)
> Why did you do that?

Why did I do that? Because I try to save the reader's time. Most readers
do not want to wade through fifty lines of beautifully formatted code
just to see the rest of the article; they'll accept that the blob of C
does the job I say it does, and inspect an indented version at their
leisure if they want to invest more time.

Putting a nicely formatted C program into the middle of a posting when
it is not directly relevant to the thread is not polite.

---Dan