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