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