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

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

#undef sun
#define sun sockun
extern int _p9dialparse(char*, char**, char**, u32int*, int*);

int
_p9netfd(char *dir)
{
	int fd;

	if(strncmp(dir, "/dev/fd/", 8) != 0)
		return -1;
	fd = strtol(dir+8, &dir, 0);
	if(*dir != 0)
		return -1;
	return fd;
}

static void
putfd(char *dir, int fd)
{
	snprint(dir, NETPATHLEN, "/dev/fd/%d", fd);
}

#undef unix

int
p9announce(char *addr, char *dir)
{
	int proto;
	char *buf, *unix;
	char *net;
	u32int host;
	int port, s;
	int n, sn;
	struct sockaddr_in sa;
	struct sockaddr_un sun;

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

	if(_p9dialparse(buf, &net, &unix, &host, &port) < 0){
		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);

	memset(&sa, 0, sizeof sa);
	memmove(&sa.sin_addr, &host, 4);
	sa.sin_family = AF_INET;
	sa.sin_port = htons(port);
	if((s = socket(AF_INET, proto, 0)) < 0)
		return -1;
	sn = sizeof n;
	if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&n, &sn) >= 0
	&& n == SOCK_STREAM){
		n = 1;
		setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
	}
	if(bind(s, (struct sockaddr*)&sa, sizeof sa) < 0){
		close(s);
		return -1;
	}
	if(proto == SOCK_STREAM){
		listen(s, 8);
		putfd(dir, s);
	}
	return s;

Unix:
	memset(&sun, 0, sizeof sun);
	sun.sun_family = AF_UNIX;
	strcpy(sun.sun_path, unix);
	if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
		return -1;
	sn = sizeof sun;
	if(bind(s, (struct sockaddr*)&sun, sizeof sun) < 0){
		if(errno == EADDRINUSE
		&& connect(s, (struct sockaddr*)&sun, sizeof sun) < 0
		&& errno == ECONNREFUSED){
			/* dead socket, so remove it */
			remove(unix);
			close(s);
			if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
				return -1;
			if(bind(s, (struct sockaddr*)&sun, sizeof sun) >= 0)
				goto Success;
		}
		close(s);
		return -1;
	}
Success:
	listen(s, 8);
	putfd(dir, s);
	return s;
}

int
p9listen(char *dir, char *newdir)
{
	int fd;

	if((fd = _p9netfd(dir)) < 0){
		werrstr("bad 'directory' in listen: %s", dir);
		return -1;
	}

	if((fd = accept(fd, nil, nil)) < 0)
		return -1;

	putfd(newdir, fd);
	return fd;
}

int
p9accept(int cfd, char *dir)
{
	int fd;

	if((fd = _p9netfd(dir)) < 0){
		werrstr("bad 'directory' in accept");
		return -1;
	}
	/* need to dup because the listen fd will be closed */
	return dup(fd);
}

