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 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