chandial.c (2276B)
1 #include "u.h" 2 #include "lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "error.h" 7 #include "ip/ip.h" 8 9 typedef struct DS DS; 10 static Chan* call(char*, char*, DS*); 11 static void _dial_string_parse(char*, DS*); 12 13 enum 14 { 15 Maxstring= 128, 16 }; 17 18 struct DS 19 { 20 char buf[Maxstring]; /* dist string */ 21 char *netdir; 22 char *proto; 23 char *rem; 24 char *local; /* other args */ 25 char *dir; 26 Chan **ctlp; 27 }; 28 29 /* 30 * the dialstring is of the form '[/net/]proto!dest' 31 */ 32 Chan* 33 chandial(char *dest, char *local, char *dir, Chan **ctlp) 34 { 35 DS ds; 36 char clone[Maxpath]; 37 38 ds.local = local; 39 ds.dir = dir; 40 ds.ctlp = ctlp; 41 42 _dial_string_parse(dest, &ds); 43 if(ds.netdir == 0) 44 ds.netdir = "/net"; 45 46 /* no connection server, don't translate */ 47 snprint(clone, sizeof(clone), "%s/%s/clone", ds.netdir, ds.proto); 48 return call(clone, ds.rem, &ds); 49 } 50 51 static Chan* 52 call(char *clone, char *dest, DS *ds) 53 { 54 int n; 55 Chan *dchan, *cchan; 56 char name[Maxpath], data[Maxpath], *p; 57 58 cchan = namec(clone, Aopen, ORDWR, 0); 59 60 /* get directory name */ 61 if(waserror()){ 62 cclose(cchan); 63 nexterror(); 64 } 65 n = devtab[cchan->type]->read(cchan, name, sizeof(name)-1, 0); 66 name[n] = 0; 67 for(p = name; *p == ' '; p++) 68 ; 69 sprint(name, "%lud", strtoul(p, 0, 0)); 70 p = strrchr(clone, '/'); 71 *p = 0; 72 if(ds->dir) 73 snprint(ds->dir, Maxpath, "%s/%s", clone, name); 74 snprint(data, sizeof(data), "%s/%s/data", clone, name); 75 76 /* connect */ 77 if(ds->local) 78 snprint(name, sizeof(name), "connect %s %s", dest, ds->local); 79 else 80 snprint(name, sizeof(name), "connect %s", dest); 81 devtab[cchan->type]->write(cchan, name, strlen(name), 0); 82 83 /* open data connection */ 84 dchan = namec(data, Aopen, ORDWR, 0); 85 if(ds->ctlp) 86 *ds->ctlp = cchan; 87 else 88 cclose(cchan); 89 poperror(); 90 return dchan; 91 92 } 93 94 /* 95 * parse a dial string 96 */ 97 static void 98 _dial_string_parse(char *str, DS *ds) 99 { 100 char *p, *p2; 101 102 strncpy(ds->buf, str, Maxstring); 103 ds->buf[Maxstring-1] = 0; 104 105 p = strchr(ds->buf, '!'); 106 if(p == 0) { 107 ds->netdir = 0; 108 ds->proto = "net"; 109 ds->rem = ds->buf; 110 } else { 111 if(*ds->buf != '/' && *ds->buf != '#'){ 112 ds->netdir = 0; 113 ds->proto = ds->buf; 114 } else { 115 for(p2 = p; *p2 != '/'; p2--) 116 ; 117 *p2++ = 0; 118 ds->netdir = ds->buf; 119 ds->proto = p2; 120 } 121 *p = 0; 122 ds->rem = p + 1; 123 } 124 }