Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}