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