/* 
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */
/* posix */
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

/* bsd extensions */
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>

#include "priv.h"

int connect (int fd, __CONST_SOCKADDR_ARG a, socklen_t alen)
{
	Rock *r;
	int n, cfd, nfd;
	char msg[8+256+1], file[8+256+1];
	struct sockaddr_in *lip, *rip;
	struct sockaddr_un *runix;
	static int vers;

	r = _sock_findrock(fd, 0);
	if(r == 0){
		errno = ENOTSOCK;
		return -1;
	}
	if(alen > sizeof(r->raddr)){
		errno = ENAMETOOLONG;
		return -1;
	}
	memmove(&r->raddr, a, alen);

	switch(r->domain){
	case PF_INET:
		/* UDP sockets are already announced (during bind), so we can't issue
		 * a connect message.  Either connect or announce, not both.  All sends
		 * will later do a sendto, based off the contents of r->raddr, so we're
		 * already done here */
		if (r->stype == SOCK_DGRAM)
			return 0;
		/* set up a tcp or udp connection */
		cfd = open(r->ctl, O_RDWR);
		if(cfd < 0){
			return -1;
		}
		/* whatever .. */
		rip = (void *)a;
		lip = (struct sockaddr_in*)&r->addr;
		if(lip->sin_port)
			snprintf(msg, sizeof msg, "connect %s!%d%s %d",
				inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
				r->reserved ? "!r" : "",
				ntohs(lip->sin_port));
		else
			snprintf(msg, sizeof msg, "connect %s!%d%s",
				inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
				r->reserved ? "!r" : "");
		n = write(cfd, msg, strlen(msg));
		if(n < 0){
			close(cfd);
			return -1;
		}
		close(cfd);
		return 0;
	case PF_UNIX:
		/* null terminate the address */
		if(alen == sizeof(r->raddr))
			alen--;
		*(((char*)&r->raddr)+alen) = 0;

		if(r->other < 0){
			errno = EINVAL; //EGREG;
			return -1;
		}

		/* put far end of our pipe in /srv */
		snprintf(msg, sizeof msg, "UD.%d.%d", getpid(), vers++);
		if(_sock_srv(msg, r->other) < 0){
			r->other = -1;
			return -1;
		}
		r->other = -1;

		/* tell server the /srv file to open */
		runix = (struct sockaddr_un*)&r->raddr;
		_sock_srvname(file, runix->sun_path);
		nfd = open(file, O_RDWR);
		if(nfd < 0){
			unlink(msg);
			return -1;
		}
		if(write(nfd, msg, strlen(msg)) < 0){
			close(nfd);
			unlink(msg);
			return -1;
		}
		close(nfd);

		/* wait for server to open it and then remove it */
		read(fd, file, sizeof(file));
		_sock_srvname(file, msg);
		unlink(file);
		return 0;
	default:
		errno = EAFNOSUPPORT;
		return -1;
	}
}
