6 static int call(char*, char*, char*, DS*);
7 static int csdial(DS*);
8 static void _dial_string_parse(char*, DS*);
31 * the dialstring is of the form '[/net/]proto!dest'
34 dial(char *dest, char *local, char *dir, int *cfdp)
44 _dial_string_parse(dest, &ds);
53 errstr(err, sizeof err);
54 if(strcmp(err, "interrupted") == 0 || strstr(err, "refused") != nil){
55 errstr(err, sizeof err);
59 ds.netdir = "/net.alt";
63 errstr(err, sizeof err);
64 if(strstr(err, "translate") == nil && strstr(err, "does not exist") == nil)
65 errstr(err, sizeof err);
73 char *rem, *loc, buf[Maxstring], clone[Maxpath], err[ERRMAX];
76 * open connection server
78 snprint(buf, sizeof(buf), "%s/cs", ds->netdir);
79 fd = open(buf, ORDWR);
81 /* no connection server, don't translate */
82 snprint(clone, sizeof(clone), "%s/%s/clone", ds->netdir, ds->proto);
83 return call(clone, ds->rem, ds->local, ds);
87 * ask connection server to translate
89 snprint(buf, sizeof(buf), "%s!%s", ds->proto, ds->rem);
90 if(write(fd, buf, strlen(buf)) < 0){
96 * loop through each address from the connection server till
97 * we get one that works.
102 while((n = read(fd, buf, sizeof(buf) - 1)) > 0){
104 rem = strchr(buf, ' ');
108 loc = strchr(rem, ' ');
111 rv = call(buf, rem, ds->local!=nil? ds->local: loc, ds);
114 errstr(err, sizeof err);
115 if(strcmp(err, "interrupted") == 0)
117 if(strstr(err, "does not exist") != nil)
118 errstr(err, sizeof err); /* get previous error back */
122 /* restore errstr if any */
124 errstr(err, sizeof err);
130 call(char *clone, char *remote, char *local, DS *ds)
133 char cname[Maxpath], name[Maxpath], data[Maxpath], *p;
135 /* because cs is in a different name space, replace the mount point */
136 if(*clone == '/' || *clone == '#'){
137 p = strchr(clone+1, '/');
144 snprint(cname, sizeof cname, "%s/%s", ds->netdir, p);
146 cfd = open(cname, ORDWR);
150 /* get directory name */
151 n = read(cfd, name, sizeof(name)-1);
157 for(p = name; *p == ' '; p++)
159 snprint(name, sizeof(name), "%ld", strtoul(p, 0, 0));
160 p = strrchr(cname, '/');
163 snprint(ds->dir, NETPATHLEN, "%s/%s", cname, name);
164 snprint(data, sizeof(data), "%s/%s/data", cname, name);
168 snprint(name, sizeof(name), "connect %s %s", remote, local);
170 snprint(name, sizeof(name), "connect %s", remote);
171 if(write(cfd, name, strlen(name)) < 0){
176 /* open data connection */
177 fd = open(data, ORDWR);
190 * parse a dial string
193 _dial_string_parse(char *str, DS *ds)
197 strncpy(ds->buf, str, Maxstring);
198 ds->buf[Maxstring-1] = 0;
200 p = strchr(ds->buf, '!');
208 p2 = strchr(p2, '/');
209 if(p2 == nil || p2 > p)
216 for(p2 = p; *p2 != '/'; p2--)
219 ds->netdir = ds->buf;