xref: /plan9/sys/src/ape/lib/net/dial.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1*3e12c5d1SDavid du Colombier #include <stdlib.h>
2*3e12c5d1SDavid du Colombier #include <sys/types.h>
3*3e12c5d1SDavid du Colombier #include <string.h>
4*3e12c5d1SDavid du Colombier #include <fcntl.h>
5*3e12c5d1SDavid du Colombier #include <stdio.h>
6*3e12c5d1SDavid du Colombier #include <unistd.h>
7*3e12c5d1SDavid du Colombier #include <libnet.h>
8*3e12c5d1SDavid du Colombier 
9*3e12c5d1SDavid du Colombier #define NAMELEN 28
10*3e12c5d1SDavid du Colombier 
11*3e12c5d1SDavid du Colombier static int
12*3e12c5d1SDavid du Colombier call(char *clone, char *dest, int *cfdp, char *dir, char *local)
13*3e12c5d1SDavid du Colombier {
14*3e12c5d1SDavid du Colombier 	int fd, cfd;
15*3e12c5d1SDavid du Colombier 	int n;
16*3e12c5d1SDavid du Colombier 	char name[3*NAMELEN+5];
17*3e12c5d1SDavid du Colombier 	char data[3*NAMELEN+10];
18*3e12c5d1SDavid du Colombier 	char *p;
19*3e12c5d1SDavid du Colombier 
20*3e12c5d1SDavid du Colombier 	cfd = open(clone, O_RDWR);
21*3e12c5d1SDavid du Colombier 	if(cfd < 0)
22*3e12c5d1SDavid du Colombier 		return -1;
23*3e12c5d1SDavid du Colombier 
24*3e12c5d1SDavid du Colombier 	/* get directory name */
25*3e12c5d1SDavid du Colombier 	n = read(cfd, name, sizeof(name)-1);
26*3e12c5d1SDavid du Colombier 	if(n < 0){
27*3e12c5d1SDavid du Colombier 		close(cfd);
28*3e12c5d1SDavid du Colombier 		return -1;
29*3e12c5d1SDavid du Colombier 	}
30*3e12c5d1SDavid du Colombier 	name[n] = 0;
31*3e12c5d1SDavid du Colombier 	p = strrchr(clone, '/');
32*3e12c5d1SDavid du Colombier 	*p = 0;
33*3e12c5d1SDavid du Colombier 	if(dir)
34*3e12c5d1SDavid du Colombier 		sprintf(dir, "%.*s/%.*s", 2*NAMELEN+1, clone, NAMELEN, name);
35*3e12c5d1SDavid du Colombier 	sprintf(data, "%.*s/%.*s/data", 2*NAMELEN+1, clone, NAMELEN, name);
36*3e12c5d1SDavid du Colombier 
37*3e12c5d1SDavid du Colombier 	/* set local side (port number, for example) if we need to */
38*3e12c5d1SDavid du Colombier 	if(local){
39*3e12c5d1SDavid du Colombier 		sprintf(name, "announce %s", 2*NAMELEN, local);
40*3e12c5d1SDavid du Colombier 		if(write(cfd, name, strlen(name)) < 0){
41*3e12c5d1SDavid du Colombier 			close(cfd);
42*3e12c5d1SDavid du Colombier 			return -1;
43*3e12c5d1SDavid du Colombier 		}
44*3e12c5d1SDavid du Colombier 	}
45*3e12c5d1SDavid du Colombier 
46*3e12c5d1SDavid du Colombier 	/* connect */
47*3e12c5d1SDavid du Colombier 	sprintf(name, "connect %.*s", 2*NAMELEN, dest);
48*3e12c5d1SDavid du Colombier 	if(write(cfd, name, strlen(name)) < 0){
49*3e12c5d1SDavid du Colombier 		close(cfd);
50*3e12c5d1SDavid du Colombier 		return -1;
51*3e12c5d1SDavid du Colombier 	}
52*3e12c5d1SDavid du Colombier 
53*3e12c5d1SDavid du Colombier 	/* open data connection */
54*3e12c5d1SDavid du Colombier 	fd = open(data, O_RDWR);
55*3e12c5d1SDavid du Colombier 	if(fd < 0){
56*3e12c5d1SDavid du Colombier 		close(cfd);
57*3e12c5d1SDavid du Colombier 		return -1;
58*3e12c5d1SDavid du Colombier 	}
59*3e12c5d1SDavid du Colombier 	if(cfdp)
60*3e12c5d1SDavid du Colombier 		*cfdp = cfd;
61*3e12c5d1SDavid du Colombier 	else
62*3e12c5d1SDavid du Colombier 		close(cfd);
63*3e12c5d1SDavid du Colombier 	return fd;
64*3e12c5d1SDavid du Colombier }
65*3e12c5d1SDavid du Colombier 
66*3e12c5d1SDavid du Colombier int
67*3e12c5d1SDavid du Colombier dial(char *dest, char *local, char *dir, int *cfdp)
68*3e12c5d1SDavid du Colombier {
69*3e12c5d1SDavid du Colombier 	char net[128];
70*3e12c5d1SDavid du Colombier 	char clone[NAMELEN+12];
71*3e12c5d1SDavid du Colombier 	char *p;
72*3e12c5d1SDavid du Colombier 	int n;
73*3e12c5d1SDavid du Colombier 	int fd;
74*3e12c5d1SDavid du Colombier 	int rv;
75*3e12c5d1SDavid du Colombier 
76*3e12c5d1SDavid du Colombier 	/* go for a standard form net!... */
77*3e12c5d1SDavid du Colombier 	p = strchr(dest, '!');
78*3e12c5d1SDavid du Colombier 	if(p == 0){
79*3e12c5d1SDavid du Colombier 		sprintf(net, "net!%.*s", sizeof(net)-5, dest);
80*3e12c5d1SDavid du Colombier 	} else {
81*3e12c5d1SDavid du Colombier 		strncpy(net, dest, sizeof(net)-1);
82*3e12c5d1SDavid du Colombier 		net[sizeof(net)-1] = 0;
83*3e12c5d1SDavid du Colombier 	}
84*3e12c5d1SDavid du Colombier 
85*3e12c5d1SDavid du Colombier 	/* call the connection server */
86*3e12c5d1SDavid du Colombier 	fd = open("/net/cs", O_RDWR);
87*3e12c5d1SDavid du Colombier 	if(fd < 0){
88*3e12c5d1SDavid du Colombier 		/* no connection server, don't translate */
89*3e12c5d1SDavid du Colombier 		p = strchr(net, '!');
90*3e12c5d1SDavid du Colombier 		*p++ = 0;
91*3e12c5d1SDavid du Colombier 		sprintf(clone, "/net/%s/clone", net);
92*3e12c5d1SDavid du Colombier 		return call(clone, p, cfdp, dir, local);
93*3e12c5d1SDavid du Colombier 	}
94*3e12c5d1SDavid du Colombier 
95*3e12c5d1SDavid du Colombier 	/*
96*3e12c5d1SDavid du Colombier 	 *  send dest to connection to translate
97*3e12c5d1SDavid du Colombier 	 */
98*3e12c5d1SDavid du Colombier 	if(write(fd, net, strlen(net)) < 0){
99*3e12c5d1SDavid du Colombier 		close(fd);
100*3e12c5d1SDavid du Colombier 		return -1;
101*3e12c5d1SDavid du Colombier 	}
102*3e12c5d1SDavid du Colombier 
103*3e12c5d1SDavid du Colombier 	/*
104*3e12c5d1SDavid du Colombier 	 *  loop through each address from the connection server till
105*3e12c5d1SDavid du Colombier 	 *  we get one that works.
106*3e12c5d1SDavid du Colombier 	 */
107*3e12c5d1SDavid du Colombier 	rv = -1;
108*3e12c5d1SDavid du Colombier 	lseek(fd, 0, 0);
109*3e12c5d1SDavid du Colombier 	while((n = read(fd, net, sizeof(net) - 1)) > 0){
110*3e12c5d1SDavid du Colombier 		net[n] = 0;
111*3e12c5d1SDavid du Colombier 		p = strchr(net, ' ');
112*3e12c5d1SDavid du Colombier 		if(p == 0)
113*3e12c5d1SDavid du Colombier 			continue;
114*3e12c5d1SDavid du Colombier 		*p++ = 0;
115*3e12c5d1SDavid du Colombier 		rv = call(net, p, cfdp, dir, local);
116*3e12c5d1SDavid du Colombier 		if(rv >= 0)
117*3e12c5d1SDavid du Colombier 			break;
118*3e12c5d1SDavid du Colombier 	}
119*3e12c5d1SDavid du Colombier 	close(fd);
120*3e12c5d1SDavid du Colombier 	return rv;
121*3e12c5d1SDavid du Colombier }
122