9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] ppp patches
@ 2003-07-20 23:51 Scott Schwartz
  2003-07-21  0:48 ` David Presotto
  0 siblings, 1 reply; 7+ messages in thread
From: Scott Schwartz @ 2003-07-20 23:51 UTC (permalink / raw)
  To: 9fans

[-- Attachment #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: 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 #3: Type: text/plain, Size: 72 bytes --]

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

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

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

[-- Attachment #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 #6: Type: text/plain, Size: 100 bytes --]

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-07-23  1:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-20 23:51 [9fans] ppp patches Scott Schwartz
2003-07-21  0:48 ` David Presotto
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

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).