Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* posix */
2
#include <sys/types.h>
3
#include <unistd.h>
4
#include <stdlib.h>
5
#include <stdio.h>
6
#include <fcntl.h>
7
#include <string.h>
8
#include <errno.h>
9
 
10
/* bsd extensions */
11
#include <sys/uio.h>
12
#include <sys/socket.h>
13
#include <netinet/in.h>
14
#include <sys/un.h>
15
#include <sys/stat.h>
16
 
17
#include "priv.h"
18
 
19
int
20
connect(int fd, void *a, int alen)
21
{
22
	Rock *r;
23
	int n, cfd, nfd;
24
	char msg[8+256+1], file[8+256+1];
25
	struct sockaddr_in *lip, *rip;
26
	struct sockaddr_un *runix;
27
	static int vers;
28
 
29
	r = _sock_findrock(fd, 0);
30
	if(r == 0){
31
		errno = ENOTSOCK;
32
		return -1;
33
	}
34
	if(alen > sizeof(r->raddr)){
35
		errno = ENAMETOOLONG;
36
		return -1;
37
	}
38
	memmove(&r->raddr, a, alen);
39
 
40
	switch(r->domain){
41
	case PF_INET:
42
		/* set up a tcp or udp connection */
43
		cfd = open(r->ctl, O_RDWR);
44
		if(cfd < 0){
45
			_syserrno();
46
			return -1;
47
		}
48
		rip = a;
49
		lip = (struct sockaddr_in*)&r->addr;
50
		if(lip->sin_port)
51
			snprintf(msg, sizeof msg, "connect %s!%d%s %d",
52
				inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
53
				r->reserved ? "!r" : "",
54
				ntohs(lip->sin_port));
55
		else
56
			snprintf(msg, sizeof msg, "connect %s!%d%s",
57
				inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
58
				r->reserved ? "!r" : "");
59
		n = write(cfd, msg, strlen(msg));
60
		if(n < 0){
61
			_syserrno();
62
			close(cfd);
63
			return -1;
64
		}
65
		close(cfd);
66
		return 0;
67
	case PF_UNIX:
68
		/* null terminate the address */
69
		if(alen == sizeof(r->raddr))
70
			alen--;
71
		*(((char*)&r->raddr)+alen) = 0;
72
 
73
		if(r->other < 0){
74
			errno = EGREG;
75
			return -1;
76
		}
77
 
78
		/* put far end of our pipe in /srv */
79
		snprintf(msg, sizeof msg, "UD.%d.%d", getpid(), vers++);
80
		if(_sock_srv(msg, r->other) < 0){
81
			r->other = -1;
82
			return -1;
83
		}
84
		r->other = -1;
85
 
86
		/* tell server the /srv file to open */
87
		runix = (struct sockaddr_un*)&r->raddr;
88
		_sock_srvname(file, runix->sun_path);
89
		nfd = open(file, O_RDWR);
90
		if(nfd < 0){
91
			_syserrno();
92
			unlink(msg);
93
			return -1;
94
		}
95
		if(write(nfd, msg, strlen(msg)) < 0){
96
			_syserrno();
97
			close(nfd);
98
			unlink(msg);
99
			return -1;
100
		}
101
		close(nfd);
102
 
103
		/* wait for server to open it and then remove it */
104
		read(fd, file, sizeof(file));
105
		_sock_srvname(file, msg);
106
		unlink(file);
107
		return 0;
108
	default:
109
		errno = EAFNOSUPPORT;
110
		return -1;
111
	}
112
}