2 * This file is part of the UCB release of Plan 9. It is subject to the license
3 * terms in the LICENSE file found in the top-level directory of this
4 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5 * part of the UCB release of Plan 9, including this file, may be copied,
6 * modified, propagated, or distributed except according to the terms contained
13 #include <parlib/parlib.h>
16 #include <iplib/iplib.h>
18 static int nettrans(char*, char*, int na, char*, int);
26 * announce a network service.
28 int announce9(char *addr, char *dir, int flags)
38 * translate the address
40 if(nettrans(addr, naddr, sizeof(naddr), netdir, sizeof(netdir)) < 0)
44 * get a control channel
46 ctl = open(netdir, O_RDWR | (flags & O_NONBLOCK));
48 fprintf(stderr,"announce opening %s: %r\n", netdir);
51 cp = strrchr(netdir, '/');
53 fprintf(stderr,"announce arg format %s\n", netdir);
60 * find out which line we have
62 n = snprintf(buf, sizeof(buf), "%s/", netdir);
63 m = read(ctl, &buf[n], sizeof(buf)-n-1);
65 fprintf(stderr,"announce reading %s: %r\n", netdir);
74 n = snprintf(buf2, sizeof(buf2), "announce %s", naddr);
75 if(write(ctl, buf2, n)!=n){
76 fprintf(stderr,"announce writing %s: %r\n", netdir);
82 * return directory etc.
85 strncpy(dir, buf, NETPATHLEN);
86 dir[NETPATHLEN-1] = 0;
92 * listen for an incoming call
94 int listen9(char *dir, char *newdir, int flags)
101 * open listen, wait for a call
103 snprintf(buf, sizeof(buf), "%s/listen", dir);
104 ctl = open(buf, O_RDWR | (flags & O_NONBLOCK));
106 if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
107 fprintf(stderr,"listen opening %s: %r\n", buf);
112 * find out which line we have
114 strncpy(buf, dir, sizeof(buf) - 1);
115 buf[sizeof(buf) - 1] = 0;
116 cp = strrchr(buf, '/');
119 fprintf(stderr,"listen arg format %s\n", dir);
124 m = read(ctl, cp, sizeof(buf) - n - 1);
127 fprintf(stderr,"listen reading %s/listen: %r\n", dir);
133 * return directory etc.
136 strncpy(newdir, buf, NETPATHLEN);
137 newdir[NETPATHLEN-1] = 0;
144 * accept a call, return an fd to the open data file
146 int accept9(int ctl, char *dir)
152 num = strrchr(dir, '/');
158 n = snprintf(buf, sizeof(buf), "accept %s", num);
159 write(ctl, buf, n); /* ignore return value, network might not need accepts */
161 snprintf(buf, sizeof(buf), "%s/data", dir);
162 return open(buf, O_RDWR);
166 * reject a call, tell device the reason for the rejection
168 int reject9(int ctl, char *dir, char *cause)
174 num = strrchr(dir, '/');
179 snprintf(buf, sizeof(buf), "reject %s %s", num, cause);
181 if(write(ctl, buf, n) != n)
187 * perform the identity translation (in case we can't reach cs)
190 identtrans(char *netdir, char *addr, char *naddr, int na, char *file, int nf)
195 /* parse the protocol */
196 strncpy(proto, addr, sizeof(proto));
197 proto[sizeof(proto)-1] = 0;
198 p = strchr(proto, '!');
202 snprintf(file, nf, "%s/%s/clone", netdir, proto);
203 strncpy(naddr, p, na);
210 * call up the connection server and get a translation
213 nettrans(char *addr, char *naddr, int na, char *file, int nf)
217 char netdir[Maxpath];
222 * parse, get network directory
224 p = strchr(addr, '!');
226 fprintf(stderr,"bad dial string: %s\n", addr);
230 strncpy(netdir, "/net", sizeof(netdir));
231 netdir[sizeof(netdir) - 1] = 0;
233 for(p2 = p; *p2 != '/'; p2--)
236 if(i == 0 || i >= sizeof(netdir)){
237 fprintf(stderr,"bad dial string: %s\n", addr);
240 strncpy(netdir, addr, i);
246 * ask the connection server
248 snprintf(buf, sizeof(buf), "%s/cs", netdir);
249 fd = open(buf, O_RDWR);
251 return identtrans(netdir, addr, naddr, na, file, nf);
252 if(write(fd, addr, strlen(addr)) < 0){
257 n = read(fd, buf, sizeof(buf)-1);
266 p = strchr(buf, ' ');
270 strncpy(naddr, p, na);
274 p = strchr(buf+1, '/');
280 snprintf(file, nf, "%s/%s", netdir, p);