13e12c5d1SDavid du Colombier #include <stdlib.h>
23e12c5d1SDavid du Colombier #include <sys/types.h>
33e12c5d1SDavid du Colombier #include <string.h>
43e12c5d1SDavid du Colombier #include <fcntl.h>
53e12c5d1SDavid du Colombier #include <stdio.h>
63e12c5d1SDavid du Colombier #include <unistd.h>
73e12c5d1SDavid du Colombier #include <libnet.h>
83e12c5d1SDavid du Colombier
93e12c5d1SDavid du Colombier #define NAMELEN 28
103e12c5d1SDavid du Colombier
113e12c5d1SDavid du Colombier static int
call(char * clone,char * dest,int * cfdp,char * dir,char * local)123e12c5d1SDavid du Colombier call(char *clone, char *dest, int *cfdp, char *dir, char *local)
133e12c5d1SDavid du Colombier {
143e12c5d1SDavid du Colombier int fd, cfd;
153e12c5d1SDavid du Colombier int n;
163e12c5d1SDavid du Colombier char name[3*NAMELEN+5];
173e12c5d1SDavid du Colombier char data[3*NAMELEN+10];
183e12c5d1SDavid du Colombier char *p;
193e12c5d1SDavid du Colombier
203e12c5d1SDavid du Colombier cfd = open(clone, O_RDWR);
213e12c5d1SDavid du Colombier if(cfd < 0)
223e12c5d1SDavid du Colombier return -1;
233e12c5d1SDavid du Colombier
243e12c5d1SDavid du Colombier /* get directory name */
253e12c5d1SDavid du Colombier n = read(cfd, name, sizeof(name)-1);
263e12c5d1SDavid du Colombier if(n < 0){
273e12c5d1SDavid du Colombier close(cfd);
283e12c5d1SDavid du Colombier return -1;
293e12c5d1SDavid du Colombier }
303e12c5d1SDavid du Colombier name[n] = 0;
313e12c5d1SDavid du Colombier p = strrchr(clone, '/');
323e12c5d1SDavid du Colombier *p = 0;
333e12c5d1SDavid du Colombier if(dir)
343e12c5d1SDavid du Colombier sprintf(dir, "%.*s/%.*s", 2*NAMELEN+1, clone, NAMELEN, name);
353e12c5d1SDavid du Colombier sprintf(data, "%.*s/%.*s/data", 2*NAMELEN+1, clone, NAMELEN, name);
363e12c5d1SDavid du Colombier
373e12c5d1SDavid du Colombier /* set local side (port number, for example) if we need to */
387dd7cddfSDavid du Colombier if(local)
397dd7cddfSDavid du Colombier sprintf(name, "connect %.*s %.*s", 2*NAMELEN, dest, NAMELEN, local);
407dd7cddfSDavid du Colombier else
417dd7cddfSDavid du Colombier sprintf(name, "connect %.*s", 2*NAMELEN, dest);
423e12c5d1SDavid du Colombier
433e12c5d1SDavid du Colombier /* connect */
443e12c5d1SDavid du Colombier if(write(cfd, name, strlen(name)) < 0){
453e12c5d1SDavid du Colombier close(cfd);
463e12c5d1SDavid du Colombier return -1;
473e12c5d1SDavid du Colombier }
483e12c5d1SDavid du Colombier
493e12c5d1SDavid du Colombier /* open data connection */
503e12c5d1SDavid du Colombier fd = open(data, O_RDWR);
513e12c5d1SDavid du Colombier if(fd < 0){
523e12c5d1SDavid du Colombier close(cfd);
533e12c5d1SDavid du Colombier return -1;
543e12c5d1SDavid du Colombier }
553e12c5d1SDavid du Colombier if(cfdp)
563e12c5d1SDavid du Colombier *cfdp = cfd;
573e12c5d1SDavid du Colombier else
583e12c5d1SDavid du Colombier close(cfd);
593e12c5d1SDavid du Colombier return fd;
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier
623e12c5d1SDavid du Colombier int
dial(char * dest,char * local,char * dir,int * cfdp)633e12c5d1SDavid du Colombier dial(char *dest, char *local, char *dir, int *cfdp)
643e12c5d1SDavid du Colombier {
653e12c5d1SDavid du Colombier char net[128];
66*9a747e4fSDavid du Colombier char netdir[128], csname[NETPATHLEN], *slp;
673e12c5d1SDavid du Colombier char clone[NAMELEN+12];
683e12c5d1SDavid du Colombier char *p;
693e12c5d1SDavid du Colombier int n;
703e12c5d1SDavid du Colombier int fd;
713e12c5d1SDavid du Colombier int rv;
723e12c5d1SDavid du Colombier
733e12c5d1SDavid du Colombier /* go for a standard form net!... */
743e12c5d1SDavid du Colombier p = strchr(dest, '!');
753e12c5d1SDavid du Colombier if(p == 0){
763e12c5d1SDavid du Colombier sprintf(net, "net!%.*s", sizeof(net)-5, dest);
773e12c5d1SDavid du Colombier } else {
783e12c5d1SDavid du Colombier strncpy(net, dest, sizeof(net)-1);
793e12c5d1SDavid du Colombier net[sizeof(net)-1] = 0;
803e12c5d1SDavid du Colombier }
813e12c5d1SDavid du Colombier
82*9a747e4fSDavid du Colombier slp = strrchr(net, '/');
83*9a747e4fSDavid du Colombier if (slp != 0) {
84*9a747e4fSDavid du Colombier *slp++ = '\0';
85*9a747e4fSDavid du Colombier strcpy(netdir, net);
86*9a747e4fSDavid du Colombier memmove(net, slp, strlen(slp)+1);
87*9a747e4fSDavid du Colombier } else
88*9a747e4fSDavid du Colombier strcpy(netdir, "/net");
89*9a747e4fSDavid du Colombier
90*9a747e4fSDavid du Colombier
913e12c5d1SDavid du Colombier /* call the connection server */
92*9a747e4fSDavid du Colombier sprintf(csname, "%s/cs", netdir);
93*9a747e4fSDavid du Colombier fd = open(csname, O_RDWR);
943e12c5d1SDavid du Colombier if(fd < 0){
953e12c5d1SDavid du Colombier /* no connection server, don't translate */
963e12c5d1SDavid du Colombier p = strchr(net, '!');
973e12c5d1SDavid du Colombier *p++ = 0;
98*9a747e4fSDavid du Colombier sprintf(clone, "%s/%s/clone", netdir, net);
993e12c5d1SDavid du Colombier return call(clone, p, cfdp, dir, local);
1003e12c5d1SDavid du Colombier }
1013e12c5d1SDavid du Colombier
1023e12c5d1SDavid du Colombier /*
1033e12c5d1SDavid du Colombier * send dest to connection to translate
1043e12c5d1SDavid du Colombier */
1053e12c5d1SDavid du Colombier if(write(fd, net, strlen(net)) < 0){
1063e12c5d1SDavid du Colombier close(fd);
1073e12c5d1SDavid du Colombier return -1;
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier
1103e12c5d1SDavid du Colombier /*
1113e12c5d1SDavid du Colombier * loop through each address from the connection server till
1123e12c5d1SDavid du Colombier * we get one that works.
1133e12c5d1SDavid du Colombier */
1143e12c5d1SDavid du Colombier rv = -1;
1153e12c5d1SDavid du Colombier lseek(fd, 0, 0);
1163e12c5d1SDavid du Colombier while((n = read(fd, net, sizeof(net) - 1)) > 0){
1173e12c5d1SDavid du Colombier net[n] = 0;
1183e12c5d1SDavid du Colombier p = strchr(net, ' ');
1193e12c5d1SDavid du Colombier if(p == 0)
1203e12c5d1SDavid du Colombier continue;
1213e12c5d1SDavid du Colombier *p++ = 0;
1223e12c5d1SDavid du Colombier rv = call(net, p, cfdp, dir, local);
1233e12c5d1SDavid du Colombier if(rv >= 0)
1243e12c5d1SDavid du Colombier break;
1253e12c5d1SDavid du Colombier }
1263e12c5d1SDavid du Colombier close(fd);
1273e12c5d1SDavid du Colombier return rv;
1283e12c5d1SDavid du Colombier }
129