xref: /plan9/sys/src/ape/lib/net/announce.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
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