1 #include <stdlib.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <ctype.h>
8 #include <libnet.h>
9
10 #define NAMELEN 28
11
12 static int nettrans(char*, char*, int na, char*, int);
13
14 /*
15 * announce a network service.
16 */
17 int
announce(char * addr,char * dir)18 announce(char *addr, char *dir)
19 {
20 int ctl, n, m;
21 char buf[3*NAMELEN];
22 char buf2[3*NAMELEN];
23 char netdir[2*NAMELEN];
24 char naddr[3*NAMELEN];
25 char *cp;
26
27 /*
28 * translate the address
29 */
30 if(nettrans(addr, naddr, sizeof(naddr), netdir, sizeof(netdir)) < 0)
31 return -1;
32
33 /*
34 * get a control channel
35 */
36 ctl = open(netdir, O_RDWR);
37 if(ctl<0)
38 return -1;
39 cp = strrchr(netdir, '/');
40 *cp = 0;
41
42 /*
43 * find out which line we have
44 */
45 n = sprintf(buf, "%.*s/", 2*NAMELEN+1, netdir);
46 m = read(ctl, &buf[n], sizeof(buf)-n-1);
47 if(n<=0){
48 close(ctl);
49 return -1;
50 }
51 buf[n+m] = 0;
52
53 /*
54 * make the call
55 */
56 n = sprintf(buf2, "announce %.*s", 2*NAMELEN, naddr);
57 if(write(ctl, buf2, n)!=n){
58 close(ctl);
59 return -1;
60 }
61
62 /*
63 * return directory etc.
64 */
65 if(dir)
66 strcpy(dir, buf);
67 return ctl;
68 }
69
70 /*
71 * listen for an incoming call
72 */
73 int
listen(char * dir,char * newdir)74 listen(char *dir, char *newdir)
75 {
76 int ctl, n, m;
77 char buf[3*NAMELEN];
78 char *cp;
79
80 /*
81 * open listen, wait for a call
82 */
83 sprintf(buf, "%.*s/listen", 2*NAMELEN+1, dir);
84 ctl = open(buf, O_RDWR);
85 if(ctl < 0)
86 return -1;
87
88 /*
89 * find out which line we have
90 */
91 strcpy(buf, dir);
92 cp = strrchr(buf, '/');
93 *++cp = 0;
94 n = cp-buf;
95 m = read(ctl, cp, sizeof(buf) - n - 1);
96 if(n<=0){
97 close(ctl);
98 return -1;
99 }
100 buf[n+m] = 0;
101
102 /*
103 * return directory etc.
104 */
105 if(newdir)
106 strcpy(newdir, buf);
107 return ctl;
108
109 }
110
111 /*
112 * accept a call, return an fd to the open data file
113 */
114 int
accept(int ctl,char * dir)115 accept(int ctl, char *dir)
116 {
117 char buf[128];
118 char *num;
119 long n;
120
121 num = strrchr(dir, '/');
122 if(num == 0)
123 num = dir;
124 else
125 num++;
126
127 sprintf(buf, "accept %s", num);
128 n = strlen(buf);
129 write(ctl, buf, n); /* ignore return value, netowrk might not need accepts */
130
131 sprintf(buf, "%s/data", dir);
132 return open(buf, O_RDWR);
133 }
134
135 /*
136 * reject a call, tell device the reason for the rejection
137 */
138 int
reject(int ctl,char * dir,char * cause)139 reject(int ctl, char *dir, char *cause)
140 {
141 char buf[128];
142 char *num;
143 long n;
144
145 num = strrchr(dir, '/');
146 if(num == 0)
147 num = dir;
148 else
149 num++;
150 sprintf(buf, "reject %s %s", num, cause);
151 n = strlen(buf);
152 if(write(ctl, buf, n) != n)
153 return -1;
154 return 0;
155 }
156
157 /*
158 * perform the identity translation (in case we can't reach cs)
159 */
160 static int
identtrans(char * addr,char * naddr,int na,char * file,int nf)161 identtrans(char *addr, char *naddr, int na, char *file, int nf)
162 {
163 char reply[4*NAMELEN];
164 char *p;
165
166 USED(nf);
167
168 /* parse the network */
169 strncpy(reply, addr, sizeof(reply));
170 reply[sizeof(reply)-1] = 0;
171 p = strchr(addr, '!');
172 if(p)
173 *p++ = 0;
174
175 sprintf(file, "/net/%.*s/clone", na - sizeof("/net//clone"), reply);
176 strncpy(naddr, p, na);
177 naddr[na-1] = 0;
178
179 return 1;
180 }
181
182 /*
183 * call up the connection server and get a translation
184 */
185 static int
nettrans(char * addr,char * naddr,int na,char * file,int nf)186 nettrans(char *addr, char *naddr, int na, char *file, int nf)
187 {
188 int fd;
189 char reply[4*NAMELEN];
190 char *cp;
191 long n;
192
193 /*
194 * ask the connection server
195 */
196 fd = open("/net/cs", O_RDWR);
197 if(fd < 0)
198 return identtrans(addr, naddr, na, file, nf);
199 if(write(fd, addr, strlen(addr)) < 0){
200 close(fd);
201 return -1;
202 }
203 lseek(fd, 0, 0);
204 n = read(fd, reply, sizeof(reply)-1);
205 close(fd);
206 if(n <= 0)
207 return -1;
208 reply[n] = 0;
209
210 /*
211 * parse the reply
212 */
213 cp = strchr(reply, ' ');
214 if(cp == 0)
215 return -1;
216 *cp++ = 0;
217 strncpy(naddr, cp, na);
218 naddr[na-1] = 0;
219 strncpy(file, reply, nf);
220 file[nf-1] = 0;
221 return 0;
222 }
223