xref: /plan9-contrib/sys/src/9k/ip/chandial.c (revision a3323688dee1e9a0fcc1d7d933e3ce101170952d)
19ef1f84bSDavid du Colombier #include	"u.h"
29ef1f84bSDavid du Colombier #include	"../port/lib.h"
39ef1f84bSDavid du Colombier #include	"mem.h"
49ef1f84bSDavid du Colombier #include	"dat.h"
59ef1f84bSDavid du Colombier #include	"fns.h"
69ef1f84bSDavid du Colombier #include	"../port/error.h"
79ef1f84bSDavid du Colombier #include	"../ip/ip.h"
89ef1f84bSDavid du Colombier 
99ef1f84bSDavid du Colombier typedef struct DS DS;
109ef1f84bSDavid du Colombier static Chan*	call(char*, char*, DS*);
119ef1f84bSDavid du Colombier static void	_dial_string_parse(char*, DS*);
129ef1f84bSDavid du Colombier 
139ef1f84bSDavid du Colombier enum
149ef1f84bSDavid du Colombier {
159ef1f84bSDavid du Colombier 	Maxstring=	128,
169ef1f84bSDavid du Colombier };
179ef1f84bSDavid du Colombier 
189ef1f84bSDavid du Colombier struct DS
199ef1f84bSDavid du Colombier {
209ef1f84bSDavid du Colombier 	char	buf[Maxstring];			/* dist string */
219ef1f84bSDavid du Colombier 	char	*netdir;
229ef1f84bSDavid du Colombier 	char	*proto;
239ef1f84bSDavid du Colombier 	char	*rem;
249ef1f84bSDavid du Colombier 	char	*local;				/* other args */
259ef1f84bSDavid du Colombier 	char	*dir;
269ef1f84bSDavid du Colombier 	Chan	**ctlp;
279ef1f84bSDavid du Colombier };
289ef1f84bSDavid du Colombier 
299ef1f84bSDavid du Colombier /*
309ef1f84bSDavid du Colombier  *  the dialstring is of the form '[/net/]proto!dest'
319ef1f84bSDavid du Colombier  */
329ef1f84bSDavid du Colombier Chan*
chandial(char * dest,char * local,char * dir,Chan ** ctlp)339ef1f84bSDavid du Colombier chandial(char *dest, char *local, char *dir, Chan **ctlp)
349ef1f84bSDavid du Colombier {
359ef1f84bSDavid du Colombier 	DS ds;
369ef1f84bSDavid du Colombier 	char clone[Maxpath];
379ef1f84bSDavid du Colombier 
389ef1f84bSDavid du Colombier 	ds.local = local;
399ef1f84bSDavid du Colombier 	ds.dir = dir;
409ef1f84bSDavid du Colombier 	ds.ctlp = ctlp;
419ef1f84bSDavid du Colombier 
429ef1f84bSDavid du Colombier 	_dial_string_parse(dest, &ds);
439ef1f84bSDavid du Colombier 	if(ds.netdir == 0)
449ef1f84bSDavid du Colombier 		ds.netdir = "/net";
459ef1f84bSDavid du Colombier 
469ef1f84bSDavid du Colombier 	/* no connection server, don't translate */
479ef1f84bSDavid du Colombier 	snprint(clone, sizeof(clone), "%s/%s/clone", ds.netdir, ds.proto);
489ef1f84bSDavid du Colombier 	return call(clone, ds.rem, &ds);
499ef1f84bSDavid du Colombier }
509ef1f84bSDavid du Colombier 
519ef1f84bSDavid du Colombier static Chan*
call(char * clone,char * dest,DS * ds)529ef1f84bSDavid du Colombier call(char *clone, char *dest, DS *ds)
539ef1f84bSDavid du Colombier {
549ef1f84bSDavid du Colombier 	int n;
559ef1f84bSDavid du Colombier 	Chan *dchan, *cchan;
569ef1f84bSDavid du Colombier 	char name[Maxpath], data[Maxpath], *p;
579ef1f84bSDavid du Colombier 
589ef1f84bSDavid du Colombier 	cchan = namec(clone, Aopen, ORDWR, 0);
599ef1f84bSDavid du Colombier 
609ef1f84bSDavid du Colombier 	/* get directory name */
619ef1f84bSDavid du Colombier 	if(waserror()){
629ef1f84bSDavid du Colombier 		cclose(cchan);
639ef1f84bSDavid du Colombier 		nexterror();
649ef1f84bSDavid du Colombier 	}
659ef1f84bSDavid du Colombier 	n = cchan->dev->read(cchan, name, sizeof(name)-1, 0);
669ef1f84bSDavid du Colombier 	name[n] = 0;
679ef1f84bSDavid du Colombier 	for(p = name; *p == ' '; p++)
689ef1f84bSDavid du Colombier 		;
69*a3323688SDavid du Colombier 	snprint(name, sizeof name, "%lud", strtoul(p, 0, 0));
709ef1f84bSDavid du Colombier 	p = strrchr(clone, '/');
719ef1f84bSDavid du Colombier 	*p = 0;
729ef1f84bSDavid du Colombier 	if(ds->dir)
739ef1f84bSDavid du Colombier 		snprint(ds->dir, Maxpath, "%s/%s", clone, name);
749ef1f84bSDavid du Colombier 	snprint(data, sizeof(data), "%s/%s/data", clone, name);
759ef1f84bSDavid du Colombier 
769ef1f84bSDavid du Colombier 	/* connect */
779ef1f84bSDavid du Colombier 	if(ds->local)
789ef1f84bSDavid du Colombier 		snprint(name, sizeof(name), "connect %s %s", dest, ds->local);
799ef1f84bSDavid du Colombier 	else
809ef1f84bSDavid du Colombier 		snprint(name, sizeof(name), "connect %s", dest);
819ef1f84bSDavid du Colombier 	cchan->dev->write(cchan, name, strlen(name), 0);
829ef1f84bSDavid du Colombier 
839ef1f84bSDavid du Colombier 	/* open data connection */
849ef1f84bSDavid du Colombier 	dchan = namec(data, Aopen, ORDWR, 0);
859ef1f84bSDavid du Colombier 	if(ds->ctlp)
869ef1f84bSDavid du Colombier 		*ds->ctlp = cchan;
879ef1f84bSDavid du Colombier 	else
889ef1f84bSDavid du Colombier 		cclose(cchan);
899ef1f84bSDavid du Colombier 	poperror();
909ef1f84bSDavid du Colombier 	return dchan;
919ef1f84bSDavid du Colombier 
929ef1f84bSDavid du Colombier }
939ef1f84bSDavid du Colombier 
949ef1f84bSDavid du Colombier /*
959ef1f84bSDavid du Colombier  *  parse a dial string
969ef1f84bSDavid du Colombier  */
979ef1f84bSDavid du Colombier static void
_dial_string_parse(char * str,DS * ds)989ef1f84bSDavid du Colombier _dial_string_parse(char *str, DS *ds)
999ef1f84bSDavid du Colombier {
1009ef1f84bSDavid du Colombier 	char *p, *p2;
1019ef1f84bSDavid du Colombier 
1029ef1f84bSDavid du Colombier 	strncpy(ds->buf, str, Maxstring);
1039ef1f84bSDavid du Colombier 	ds->buf[Maxstring-1] = 0;
1049ef1f84bSDavid du Colombier 
1059ef1f84bSDavid du Colombier 	p = strchr(ds->buf, '!');
1069ef1f84bSDavid du Colombier 	if(p == 0) {
1079ef1f84bSDavid du Colombier 		ds->netdir = 0;
1089ef1f84bSDavid du Colombier 		ds->proto = "net";
1099ef1f84bSDavid du Colombier 		ds->rem = ds->buf;
1109ef1f84bSDavid du Colombier 	} else {
1119ef1f84bSDavid du Colombier 		if(*ds->buf != '/' && *ds->buf != '#'){
1129ef1f84bSDavid du Colombier 			ds->netdir = 0;
1139ef1f84bSDavid du Colombier 			ds->proto = ds->buf;
1149ef1f84bSDavid du Colombier 		} else {
1159ef1f84bSDavid du Colombier 			for(p2 = p; *p2 != '/'; p2--)
1169ef1f84bSDavid du Colombier 				;
1179ef1f84bSDavid du Colombier 			*p2++ = 0;
1189ef1f84bSDavid du Colombier 			ds->netdir = ds->buf;
1199ef1f84bSDavid du Colombier 			ds->proto = p2;
1209ef1f84bSDavid du Colombier 		}
1219ef1f84bSDavid du Colombier 		*p = 0;
1229ef1f84bSDavid du Colombier 		ds->rem = p + 1;
1239ef1f84bSDavid du Colombier 	}
1249ef1f84bSDavid du Colombier }
125