9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: David Presotto <presotto@closedmind.org>
To: 9fans@cse.psu.edu
Subject: Re: [9fans] ppp patches
Date: Sun, 20 Jul 2003 20:48:50 -0400	[thread overview]
Message-ID: <7ce34037c3cbd6915eeb039abcdbd617@plan9.bell-labs.com> (raw)
In-Reply-To: <20030720235129.11224.qmail@g.bio.cse.psu.edu>

[-- Attachment #1: Type: text/plain, Size: 311 bytes --]

Actually, I've been trying to get rid of the cat stuff in favor of the
dial/expect, dial/at stuff.  Since this can be embedded in a shell script
with a control structure, I find it a lot more powerful than our chat
scripts.  I'ld rather see the effort go there than turning the chat
scripts into another rc.

[-- Attachment #2: Type: message/rfc822, Size: 9821 bytes --]

[-- Attachment #2.1.1: Type: text/plain, Size: 748 bytes --]

Here's a suggested change to ppp, to provide better support for chat
scripts.  The main idea is to allow tokens like USER, PASSWD, SERVER and
to let factotum hand over the real values, so you can dial completely
non-interactively.

The server flag does double duty: it lets you store multiple ppp
credentials inside factotum and also uses the name of the server as the
phone number to dial.  Absent the -s flag, it tries to deduce from the
name of the chat file or from the telco string.

Examples,
ppp -b 115200 -f -P -u -M telco.chat -p telco!5552222
ppp -b 115200 -f -P -u -M modem.chat -p /dev/eia1 -s 5552222
ppp -b 115200 -f -P -u -M 5552222.chat -p /dev/eia1

This is lightly tested, so let me know if anything goes wrong.


[-- Attachment #2.1.2: Type: text/plain, Size: 2614 bytes --]

#include <u.h>
#include <libc.h>
#include <auth.h>
#include "chat.h"

// XXX - make these parameters?
extern int debug;
extern char servername[128];

#define RLEN 1024
#define TIMEOUT (60*1000)

int chat(int ifd, int ofd, char *chatfile)
{
	int chatfd, lineno, nb;
	char *script, *p, *s, response[RLEN];
	Dir *dir;
	UserPasswd *up;

	if ((chatfd = open(chatfile, OREAD)) < 0)
		sysfatal("cannot open %s: %r", chatfile);

	if ((dir = dirfstat(chatfd)) == nil)
		sysfatal("cannot fstat %s: %r",chatfile);

	script = (char *)malloc(dir->length + 1);
	assert(script);

	if ((nb = read(chatfd, script, dir->length)) < 0)
		sysfatal("cannot read chatfile %s: %r", chatfile);
	assert(nb == dir->length);
	script[dir->length] = '\0';
	free(dir);
	close(chatfd);

	p = script;
	lineno = 0;
	while (1) {
		char *_args[3];

		if ((s = strchr(p, '\n')) == nil)
			break;
		*s++ = '\0';
	
		lineno++;

		if (*p == '#') {
			p = s; 
			continue;
		}

		if (tokenize(p, _args, 3) != 2)
			sysfatal("invalid line %d (line expected: 'send' 'expect')", 
					lineno);

		if (strcmp(_args[0], "USER") == 0) {
			up = getuserpass();
			_args[0] = up->user;
		}
		else if (strcmp(_args[0], "PASSWD") == 0) {
			up = getuserpass();
			_args[0] = up->passwd;
		}
		else if (strcmp(_args[0], "SERVER") == 0) {
			_args[0] = servername;
		}
		else if (strcmp(_args[0], "CRNL") == 0) {
			_args[0] = "\r\n";
		}
		else if (strcmp(_args[0], "CR") == 0) {
			_args[0] = "\r";
		}
		else if (strcmp(_args[0], "NL") == 0) {
			_args[0] = "\n";
		}
		else if (strcmp(_args[0], "PAUSE") == 0) {
			sleep(5000);
			_args[0] = "";
		}

		if (debug)
			fprint(2, "sending “%s”, expecting “%s”\n", _args[0], _args[1]);

		if ((nb = write(ofd, _args[0], strlen(_args[0]))) < 0)
			sysfatal("cannot write %ss: %r", _args[0]);
		assert(nb == strlen(_args[0]));

		if (strlen(_args[1]) > 0) {
			char *rp = response;
			char *ep = response+sizeof(response)-1;
			int found = 0;

			alarm(TIMEOUT);
			while ((nb = read(ifd, rp, 1)) >= 0 && rp < ep) {
				if (debug)
					fprint(2, "response %02x %c\n", *rp, *rp);
				rp += nb;
				*rp = 0;
				found = cistrstr(response, _args[1]) != nil;
				if (found) {
					if (debug) fprint(2, "found “%s”\n", response);
					break;
				}
			}
			alarm(0);
			if (nb < 0)
				sysfatal("cannot read response from: %r");
			if (nb == 0)
				sysfatal("eof on input?\n");
			if (!found)
				sysfatal("expected %s, got %s\n", _args[1], response);
		}
		p = s;
	}
	free(script);
	return 1;
}

[-- Attachment #2.1.3: Type: text/plain, Size: 72 bytes --]

extern UserPasswd *getuserpass(void);
extern int chat(int,int,char*);

[-- Attachment #2.1.4: Type: text/plain, Size: 162 bytes --]

# send expect
ATQ0V1E0M1S0=0 ''
atdt   ''
SERVER ''
CR     'CONNECT'
#
PAUSE ''
CRNL  ':'
#
USER ''
CRNL :
#
PASSWD ''
CRNL   :
#
ppp  ''
CRNL ~

[-- Attachment #2.1.5: Type: text/plain, Size: 3411 bytes --]

term% diff /sys/src/cmd/ip/ppp .
Only in .: 8632222.chat
Only in .: chat.c
Only in .: chat.h
diff /sys/src/cmd/ip/ppp/mkfile ./mkfile
11a12
> 	chat.$O\
Only in .: modem.chat
diff /sys/src/cmd/ip/ppp/ppp.c ./ppp.c
8a9
> #include "chat.h"
24a26
> char	servername[PATH];
2512,2572c2514,2519
< 		int chatfd, lineno, nb;
< 		char *buf, *p, *s, response[128];
< 		Dir *dir;
<
< 		if ((chatfd = open(chatfile, OREAD)) < 0)
< 			sysfatal("cannot open %s: %r", chatfile);
<
< 		if ((dir = dirfstat(chatfd)) == nil)
< 			sysfatal("cannot fstat %s: %r",chatfile);
<
< 		buf = (char *)malloc(dir->length + 1);
< 		assert(buf);
<
< 		if ((nb = read(chatfd, buf, dir->length)) < 0)
< 			sysfatal("cannot read chatfile %s: %r", chatfile);
< 		assert(nb == dir->length);
< 		buf[dir->length] = '\0';
< 		free(dir);
< 		close(chatfd);
<
< 		p = buf;
< 		lineno = 0;
< 		while (1) {
< 			char *_args[3];
<
< 			if ((s = strchr(p, '\n')) == nil)
< 				break;
< 			*s++ = '\0';
<
< 			lineno++;
<
< 			if (*p == '#') {
< 				p = s;
< 				continue;
< 			}
<
< 			if (tokenize(p, _args, 3) != 2)
< 				sysfatal("invalid line %d (line expected: 'send' 'expect')",
< 						lineno);
<
< 			if (debug)
< 				print("sending %s, expecting %s\n", _args[0], _args[1]);
<
< 			if ((nb = write(fd, _args[0], strlen(_args[0]))) < 0)
< 				sysfatal("cannot write %ss: %r", _args[0]);
< 			assert(nb == strlen(_args[0]));
<
< 			if (strlen(_args[1]) > 0) {
< 				if ((nb = read(fd, response, sizeof response)) < 0)
< 					sysfatal("cannot read response from: %r");
<
< 				if (debug)
< 					print("response %s\n", response);
<
< 				if (nb == 0)
< 					sysfatal("eof on input?\n");
<
< 				if (cistrstr(response, _args[1]) == nil)
< 					sysfatal("expected %s, got %s\n", _args[1], response);
< 			}
< 			p = s;
---
> 		// Try to deduce the server name from the chatfile name.
> 		if (!*servername) {
> 			char *p;
> 			strecpy(servername, servername+PATH-1, chatfile);
> 			if ((p=strstr(servername, ".chat")))
> 				*p = 0;
2574c2521
< 		free(buf);
---
> 		chat(fd, fd, chatfile);
2576c2523
< 	}
---
> 	};
2632c2579
< 	fprint(2, "usage: ppp [-cCdfPSu] [-b baud] [-k keyspec] [-m mtu] [-p dev] [-s username] [-x netmntpt] [-t modemcmd] [local-addr [remote-addr]]\n");
---
> 	fprint(2, "usage: ppp [-cCdfPSu] [-b baud] [-k keyspec] [-m mtu] [-p dev] [-s servername] [-x netmntpt] [-t modemcmd] [local-addr [remote-addr]]\n");
2706a2654,2656
> 	case 's':
> 		snprint(servername, PATH, "%s", EARGF(usage()));
> 		break;
2743a2694,2701
> 				// If we don't have a user specified server name,
> 				// try to deduce one from the dial string.
> 				if(!*servername) {
> 					char *p = strchr(dev,'!');
> 					snprint(servername, PATH, "%s", p+1);
> 					p = strchr(servername, '!');
> 					if (p) *p = 0;
> 				}
2751a2710
>
2885a2845,2855
> UserPasswd *
> getuserpass()
> {
> 	if (servername[0]==0)
> 		return auth_getuserpasswd(auth_getkey,
> 			"proto=pass service=ppp %s", keyspec);
> 	else
> 		return auth_getuserpasswd(auth_getkey,
> 			"proto=pass service=ppp server=%s %s", servername, keyspec);
> }
>
2893,2895c2863,2864
<
< 	up = auth_getuserpasswd(auth_getkey,"proto=pass service=ppp %s", keyspec);
< 	if(up != nil){
---
>
> 	if((up = getuserpass()) != nil){
2899a2869
>
Only in .: telco.chat
Only in .: try

[-- Attachment #2.1.6: Type: text/plain, Size: 100 bytes --]

# send expect
PAUSE ''
CRNL  ':'
#
USER ''
CRNL :
#
PASSWD ''
CRNL   :
#
ppp  ''
CRNL ~

  reply	other threads:[~2003-07-21  0:48 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-20 23:51 Scott Schwartz
2003-07-21  0:48 ` David Presotto [this message]
2003-07-21  7:48   ` Richard Miller
2003-07-21 12:34   ` David Presotto
2003-07-21 14:51     ` Scott Schwartz
2003-07-21 15:08       ` David Presotto
2003-07-23  1:42         ` Scott Schwartz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7ce34037c3cbd6915eeb039abcdbd617@plan9.bell-labs.com \
    --to=presotto@closedmind.org \
    --cc=9fans@cse.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).