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