xref: /plan9/sys/src/9/ip/chandial.c (revision 4e3613ab15c331a9ada113286cc0f2a35bc0373d)
180ee5cbfSDavid du Colombier #include	"u.h"
280ee5cbfSDavid du Colombier #include	"../port/lib.h"
380ee5cbfSDavid du Colombier #include	"mem.h"
480ee5cbfSDavid du Colombier #include	"dat.h"
580ee5cbfSDavid du Colombier #include	"fns.h"
680ee5cbfSDavid du Colombier #include	"../port/error.h"
79a747e4fSDavid du Colombier #include	"../ip/ip.h"
880ee5cbfSDavid du Colombier 
980ee5cbfSDavid du Colombier typedef struct DS DS;
1080ee5cbfSDavid du Colombier static Chan*	call(char*, char*, DS*);
1180ee5cbfSDavid du Colombier static void	_dial_string_parse(char*, DS*);
1280ee5cbfSDavid du Colombier 
1380ee5cbfSDavid du Colombier enum
1480ee5cbfSDavid du Colombier {
1580ee5cbfSDavid du Colombier 	Maxstring=	128,
1680ee5cbfSDavid du Colombier };
1780ee5cbfSDavid du Colombier 
1880ee5cbfSDavid du Colombier struct DS
1980ee5cbfSDavid du Colombier {
2080ee5cbfSDavid du Colombier 	char	buf[Maxstring];			/* dist string */
2180ee5cbfSDavid du Colombier 	char	*netdir;
2280ee5cbfSDavid du Colombier 	char	*proto;
2380ee5cbfSDavid du Colombier 	char	*rem;
2480ee5cbfSDavid du Colombier 	char	*local;				/* other args */
2580ee5cbfSDavid du Colombier 	char	*dir;
2680ee5cbfSDavid du Colombier 	Chan	**ctlp;
2780ee5cbfSDavid du Colombier };
2880ee5cbfSDavid du Colombier 
2980ee5cbfSDavid du Colombier /*
3080ee5cbfSDavid du Colombier  *  the dialstring is of the form '[/net/]proto!dest'
3180ee5cbfSDavid du Colombier  */
3280ee5cbfSDavid du Colombier Chan*
chandial(char * dest,char * local,char * dir,Chan ** ctlp)3380ee5cbfSDavid du Colombier chandial(char *dest, char *local, char *dir, Chan **ctlp)
3480ee5cbfSDavid du Colombier {
3580ee5cbfSDavid du Colombier 	DS ds;
3680ee5cbfSDavid du Colombier 	char clone[Maxpath];
3780ee5cbfSDavid du Colombier 
3880ee5cbfSDavid du Colombier 	ds.local = local;
3980ee5cbfSDavid du Colombier 	ds.dir = dir;
4080ee5cbfSDavid du Colombier 	ds.ctlp = ctlp;
4180ee5cbfSDavid du Colombier 
4280ee5cbfSDavid du Colombier 	_dial_string_parse(dest, &ds);
4380ee5cbfSDavid du Colombier 	if(ds.netdir == 0)
4480ee5cbfSDavid du Colombier 		ds.netdir = "/net";
4580ee5cbfSDavid du Colombier 
4680ee5cbfSDavid du Colombier 	/* no connection server, don't translate */
4780ee5cbfSDavid du Colombier 	snprint(clone, sizeof(clone), "%s/%s/clone", ds.netdir, ds.proto);
4880ee5cbfSDavid du Colombier 	return call(clone, ds.rem, &ds);
4980ee5cbfSDavid du Colombier }
5080ee5cbfSDavid du Colombier 
5180ee5cbfSDavid du Colombier static Chan*
call(char * clone,char * dest,DS * ds)5280ee5cbfSDavid du Colombier call(char *clone, char *dest, DS *ds)
5380ee5cbfSDavid du Colombier {
5480ee5cbfSDavid du Colombier 	int n;
5580ee5cbfSDavid du Colombier 	Chan *dchan, *cchan;
569a747e4fSDavid du Colombier 	char name[Maxpath], data[Maxpath], *p;
5780ee5cbfSDavid du Colombier 
5880ee5cbfSDavid du Colombier 	cchan = namec(clone, Aopen, ORDWR, 0);
5980ee5cbfSDavid du Colombier 
6080ee5cbfSDavid du Colombier 	/* get directory name */
6180ee5cbfSDavid du Colombier 	if(waserror()){
6280ee5cbfSDavid du Colombier 		cclose(cchan);
6380ee5cbfSDavid du Colombier 		nexterror();
6480ee5cbfSDavid du Colombier 	}
6580ee5cbfSDavid du Colombier 	n = devtab[cchan->type]->read(cchan, name, sizeof(name)-1, 0);
6680ee5cbfSDavid du Colombier 	name[n] = 0;
6780ee5cbfSDavid du Colombier 	for(p = name; *p == ' '; p++)
6880ee5cbfSDavid du Colombier 		;
69*4e3613abSDavid du Colombier 	snprint(name, sizeof name, "%lud", strtoul(p, 0, 0));
7080ee5cbfSDavid du Colombier 	p = strrchr(clone, '/');
7180ee5cbfSDavid du Colombier 	*p = 0;
7280ee5cbfSDavid du Colombier 	if(ds->dir)
739a747e4fSDavid du Colombier 		snprint(ds->dir, Maxpath, "%s/%s", clone, name);
7480ee5cbfSDavid du Colombier 	snprint(data, sizeof(data), "%s/%s/data", clone, name);
7580ee5cbfSDavid du Colombier 
7680ee5cbfSDavid du Colombier 	/* connect */
7780ee5cbfSDavid du Colombier 	if(ds->local)
7880ee5cbfSDavid du Colombier 		snprint(name, sizeof(name), "connect %s %s", dest, ds->local);
7980ee5cbfSDavid du Colombier 	else
8080ee5cbfSDavid du Colombier 		snprint(name, sizeof(name), "connect %s", dest);
8180ee5cbfSDavid du Colombier 	devtab[cchan->type]->write(cchan, name, strlen(name), 0);
8280ee5cbfSDavid du Colombier 
8380ee5cbfSDavid du Colombier 	/* open data connection */
8480ee5cbfSDavid du Colombier 	dchan = namec(data, Aopen, ORDWR, 0);
8580ee5cbfSDavid du Colombier 	if(ds->ctlp)
8680ee5cbfSDavid du Colombier 		*ds->ctlp = cchan;
8780ee5cbfSDavid du Colombier 	else
8880ee5cbfSDavid du Colombier 		cclose(cchan);
8980ee5cbfSDavid du Colombier 	poperror();
9080ee5cbfSDavid du Colombier 	return dchan;
9180ee5cbfSDavid du Colombier 
9280ee5cbfSDavid du Colombier }
9380ee5cbfSDavid du Colombier 
9480ee5cbfSDavid du Colombier /*
9580ee5cbfSDavid du Colombier  *  parse a dial string
9680ee5cbfSDavid du Colombier  */
9780ee5cbfSDavid du Colombier static void
_dial_string_parse(char * str,DS * ds)9880ee5cbfSDavid du Colombier _dial_string_parse(char *str, DS *ds)
9980ee5cbfSDavid du Colombier {
10080ee5cbfSDavid du Colombier 	char *p, *p2;
10180ee5cbfSDavid du Colombier 
10280ee5cbfSDavid du Colombier 	strncpy(ds->buf, str, Maxstring);
10380ee5cbfSDavid du Colombier 	ds->buf[Maxstring-1] = 0;
10480ee5cbfSDavid du Colombier 
10580ee5cbfSDavid du Colombier 	p = strchr(ds->buf, '!');
10680ee5cbfSDavid du Colombier 	if(p == 0) {
10780ee5cbfSDavid du Colombier 		ds->netdir = 0;
10880ee5cbfSDavid du Colombier 		ds->proto = "net";
10980ee5cbfSDavid du Colombier 		ds->rem = ds->buf;
11080ee5cbfSDavid du Colombier 	} else {
111b5a4c01bSDavid du Colombier 		if(*ds->buf != '/' && *ds->buf != '#'){
11280ee5cbfSDavid du Colombier 			ds->netdir = 0;
11380ee5cbfSDavid du Colombier 			ds->proto = ds->buf;
11480ee5cbfSDavid du Colombier 		} else {
11580ee5cbfSDavid du Colombier 			for(p2 = p; *p2 != '/'; p2--)
11680ee5cbfSDavid du Colombier 				;
11780ee5cbfSDavid du Colombier 			*p2++ = 0;
11880ee5cbfSDavid du Colombier 			ds->netdir = ds->buf;
11980ee5cbfSDavid du Colombier 			ds->proto = p2;
12080ee5cbfSDavid du Colombier 		}
12180ee5cbfSDavid du Colombier 		*p = 0;
12280ee5cbfSDavid du Colombier 		ds->rem = p + 1;
12380ee5cbfSDavid du Colombier 	}
12480ee5cbfSDavid du Colombier }
125