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