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