#include <u.h>
#include <libc.h>

#undef	accept
#undef	announce
#undef	dial
#undef	setnetmtpt
#undef	hangup
#undef	listen
#undef	netmkaddr
#undef	reject

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/un.h>
#include <netdb.h>

#undef unix
#define unix xunix

static int
isany(struct sockaddr_storage *ss)
{
	switch(ss->ss_family){
	case AF_INET:
		return (((struct sockaddr_in*)ss)->sin_addr.s_addr == INADDR_ANY);
	case AF_INET6:
		return (memcmp(((struct sockaddr_in6*)ss)->sin6_addr.s6_addr,
			in6addr_any.s6_addr, sizeof (struct in6_addr)) == 0);
	}
	return 0;
}

static int
addrlen(struct sockaddr_storage *ss)
{
	switch(ss->ss_family){
	case AF_INET:
		return sizeof(struct sockaddr_in);
	case AF_INET6:
		return sizeof(struct sockaddr_in6);
	case AF_UNIX:
		return sizeof(struct sockaddr_un);
	}
	return 0;
}

int
p9dial(char *addr, char *local, char *dummy2, int *dummy3)
{
	char *buf;
	char *net, *unix;
	int port;
	int proto;
	socklen_t sn;
	int n;
	struct sockaddr_storage ss, ssl;
	int s;

	if(dummy2 || dummy3){
		werrstr("cannot handle extra arguments in dial");
		return -1;
	}

	buf = strdup(addr);
	if(buf == nil)
		return -1;

	if(p9dialparse(buf, &net, &unix, &ss, &port) < 0){
		free(buf);
		return -1;
	}
	if(strcmp(net, "unix") != 0 && isany(&ss)){
		werrstr("invalid dial address 0.0.0.0 (aka *)");
		free(buf);
		return -1;
	}

	if(strcmp(net, "tcp") == 0)
		proto = SOCK_STREAM;
	else if(strcmp(net, "udp") == 0)
		proto = SOCK_DGRAM;
	else if(strcmp(net, "unix") == 0)
		goto Unix;
	else{
		werrstr("can only handle tcp, udp, and unix: not %s", net);
		free(buf);
		return -1;
	}
	free(buf);

	if((s = socket(ss.ss_family, proto, 0)) < 0)
		return -1;
		
	if(local){
		buf = strdup(local);
		if(buf == nil){
			close(s);
			return -1;
		}
		if(p9dialparse(buf, &net, &unix, &ss, &port) < 0){
		badlocal:
			free(buf);
			close(s);
			return -1;
		}
		if(unix){
			werrstr("bad local address %s for dial %s", local, addr);
			goto badlocal;
		}
		sn = sizeof n;
		if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) >= 0
		&& n == SOCK_STREAM){
			n = 1;
			setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
		}
		if(bind(s, (struct sockaddr*)&ssl, addrlen(&ssl)) < 0)
			goto badlocal;
		free(buf);
	}

	n = 1;
	setsockopt(s, SOL_SOCKET, SO_BROADCAST, &n, sizeof n);
	if(!isany(&ss)){
		if(connect(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0){
			close(s);
			return -1;
		}
	}
	if(proto == SOCK_STREAM){
		int one = 1;
		setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
	}
	return s;

Unix:
	if(local){
		werrstr("local address not supported on unix network");
		free(buf);
		return -1;
	}
	/* Allow regular files in addition to Unix sockets. */
	if((s = open(unix, ORDWR)) >= 0)
		return s;
	free(buf);
	if((s = socket(ss.ss_family, SOCK_STREAM, 0)) < 0){
		werrstr("socket: %r");
		return -1;
	}
	if(connect(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0){
		werrstr("connect %s: %r", ((struct sockaddr_un*)&ss)->sun_path);
		close(s);
		return -1;
	}
	return s;
}

