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 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 63 dial(char *dest, char *local, char *dir, int *cfdp) 64 { 65 char net[128]; 66 char clone[NAMELEN+12]; 67 char *p; 68 int n; 69 int fd; 70 int rv; 71 72 /* go for a standard form net!... */ 73 p = strchr(dest, '!'); 74 if(p == 0){ 75 sprintf(net, "net!%.*s", sizeof(net)-5, dest); 76 } else { 77 strncpy(net, dest, sizeof(net)-1); 78 net[sizeof(net)-1] = 0; 79 } 80 81 /* call the connection server */ 82 fd = open("/net/cs", O_RDWR); 83 if(fd < 0){ 84 /* no connection server, don't translate */ 85 p = strchr(net, '!'); 86 *p++ = 0; 87 sprintf(clone, "/net/%s/clone", net); 88 return call(clone, p, cfdp, dir, local); 89 } 90 91 /* 92 * send dest to connection to translate 93 */ 94 if(write(fd, net, strlen(net)) < 0){ 95 close(fd); 96 return -1; 97 } 98 99 /* 100 * loop through each address from the connection server till 101 * we get one that works. 102 */ 103 rv = -1; 104 lseek(fd, 0, 0); 105 while((n = read(fd, net, sizeof(net) - 1)) > 0){ 106 net[n] = 0; 107 p = strchr(net, ' '); 108 if(p == 0) 109 continue; 110 *p++ = 0; 111 rv = call(net, p, cfdp, dir, local); 112 if(rv >= 0) 113 break; 114 } 115 close(fd); 116 return rv; 117 } 118