/* 
 * 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.
 */
#include <stdlib.h>

#include <stdio.h>
#include <fcntl.h>
#include <parlib/parlib.h>
#include <unistd.h>
#include <signal.h>
#include <iplib/iplib.h>

static int	nettrans(char*, char*, int na, char*, int);

enum
{
	Maxpath=	256,
};

/*
 *  announce a network service.
 */
int announce9(char *addr, char *dir, int flags)
{
	int ctl, n, m;
	char buf[Maxpath];
	char buf2[Maxpath];
	char netdir[Maxpath];
	char naddr[Maxpath];
	char *cp;

	/*
	 *  translate the address
	 */
	if(nettrans(addr, naddr, sizeof(naddr), netdir, sizeof(netdir)) < 0)
		return -1;

	/*
	 * get a control channel
	 */
	ctl = open(netdir, O_RDWR);
	if(ctl<0){
		fprintf(stderr,"announce opening %s: %r\n", netdir);
		return -1;
	}
	cp = strrchr(netdir, '/');
	if(cp == NULL){
		fprintf(stderr,"announce arg format %s\n", netdir);
		close(ctl);
		return -1;
	}
	*cp = 0;

	/*
	 *  find out which line we have
	 */
	n = snprintf(buf, sizeof(buf), "%s/", netdir);
	m = read(ctl, &buf[n], sizeof(buf)-n-1);
	if(m <= 0){
		fprintf(stderr,"announce reading %s: %r\n", netdir);
		close(ctl);
		return -1;
	}
	buf[n+m] = 0;

	/*
	 *  make the call
	 */
	n = snprintf(buf2, sizeof(buf2), "announce %s", naddr);
	if(write(ctl, buf2, n)!=n){
		fprintf(stderr,"announce writing %s: %r\n", netdir);
		close(ctl);
		return -1;
	}

	/*
	 *  return directory etc.
	 */
	if(dir){
		strncpy(dir, buf, NETPATHLEN);
		dir[NETPATHLEN-1] = 0;
	}
	return ctl;
}

/*
 *  listen for an incoming call
 */
int listen9(char *dir, char *newdir, int flags)
{
	int ctl, n, m;
	char buf[Maxpath];
	char *cp;

	/*
	 *  open listen, wait for a call
	 */
	snprintf(buf, sizeof(buf), "%s/listen", dir);
	ctl = open(buf, O_RDWR | (flags & O_NONBLOCK));
	if(ctl < 0){
		if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
			fprintf(stderr,"listen opening %s: %r\n", buf);
		return -1;
	}

	/*
	 *  find out which line we have
	 */
	strncpy(buf, dir, sizeof(buf) - 1);
	buf[sizeof(buf) - 1] = 0;
	cp = strrchr(buf, '/');
	if(cp == NULL){
		close(ctl);
		fprintf(stderr,"listen arg format %s\n", dir);
		return -1;
	}
	*++cp = 0;
	n = cp-buf;
	m = read(ctl, cp, sizeof(buf) - n - 1);
	if(m <= 0){
		close(ctl);
		fprintf(stderr,"listen reading %s/listen: %r\n", dir);
		return -1;
	}
	buf[n+m] = 0;

	/*
	 *  return directory etc.
	 */
	if(newdir){
		strncpy(newdir, buf, NETPATHLEN);
		newdir[NETPATHLEN-1] = 0;
	}
	return ctl;

}

/*
 *  accept a call, return an fd to the open data file
 */
int accept9(int ctl, char *dir)
{
	char buf[Maxpath];
	char *num;
	long n;

	num = strrchr(dir, '/');
	if(num == NULL)
		num = dir;
	else
		num++;

	n = snprintf(buf, sizeof(buf), "accept %s", num);
	write(ctl, buf, n); /* ignore return value, network might not need accepts */

	snprintf(buf, sizeof(buf), "%s/data", dir);
	return open(buf, O_RDWR);
}

/*
 *  reject a call, tell device the reason for the rejection
 */
int reject9(int ctl, char *dir, char *cause)
{
	char buf[Maxpath];
	char *num;
	long n;

	num = strrchr(dir, '/');
	if(num == 0)
		num = dir;
	else
		num++;
	snprintf(buf, sizeof(buf), "reject %s %s", num, cause);
	n = strlen(buf);
	if(write(ctl, buf, n) != n)
		return -1;
	return 0;
}

/*
 *  perform the identity translation (in case we can't reach cs)
 */
static int
identtrans(char *netdir, char *addr, char *naddr, int na, char *file, int nf)
{
	char proto[Maxpath];
	char *p;

	/* parse the protocol */
	strncpy(proto, addr, sizeof(proto));
	proto[sizeof(proto)-1] = 0;
	p = strchr(proto, '!');
	if(p)
		*p++ = 0;

	snprintf(file, nf, "%s/%s/clone", netdir, proto);
	strncpy(naddr, p, na);
	naddr[na-1] = 0;

	return 1;
}

/*
 *  call up the connection server and get a translation
 */
static int
nettrans(char *addr, char *naddr, int na, char *file, int nf)
{
	int i, fd;
	char buf[Maxpath];
	char netdir[Maxpath];
	char *p, *p2;
	long n;

	/*
	 *  parse, get network directory
	 */
	p = strchr(addr, '!');
	if(p == 0){
		fprintf(stderr,"bad dial string: %s\n", addr);
		return -1;
	}
	if(*addr != '/'){
		strncpy(netdir, "/net", sizeof(netdir));
		netdir[sizeof(netdir) - 1] = 0;
	} else {
		for(p2 = p; *p2 != '/'; p2--)
			;
		i = p2 - addr;
		if(i == 0 || i >= sizeof(netdir)){
			fprintf(stderr,"bad dial string: %s\n", addr);
			return -1;
		}
		strncpy(netdir, addr, i);
		netdir[i] = 0;
		addr = p2 + 1;
	}

	/*
	 *  ask the connection server
	 */
	snprintf(buf, sizeof(buf), "%s/cs", netdir);
	fd = open(buf, O_RDWR);
	if(fd < 0)
		return identtrans(netdir, addr, naddr, na, file, nf);
	if(write(fd, addr, strlen(addr)) < 0){
		close(fd);
		return -1;
	}
	lseek(fd, 0, 0);
	n = read(fd, buf, sizeof(buf)-1);
	close(fd);
	if(n <= 0)
		return -1;
	buf[n] = 0;

	/*
	 *  parse the reply
	 */
	p = strchr(buf, ' ');
	if(p == 0)
		return -1;
	*p++ = 0;
	strncpy(naddr, p, na);
	naddr[na-1] = 0;

	if(buf[0] == '/'){
		p = strchr(buf+1, '/');
		if(p == NULL)
			p = buf;
		else 
			p++;
	}
	snprintf(file, nf, "%s/%s", netdir, p);
	return 0;
}
