/* 
 * 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 <sys/types.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#define NAMELEN 28
#define NETPATHLEN 40
static int isdigit(int c) {return ((c >= '0' && c <= '9'));}

static int call(char *clone, char *dest, int *cfdp, char *dir, char *local,
                int flags)
{
	int fd, cfd;
	int n;
	char name[3*NAMELEN+5];
	char data[3*NAMELEN+10];
	char *p;

	cfd = open(clone, O_RDWR);
	if(cfd < 0)
		return -1;

	/* get directory name */
	n = read(cfd, name, sizeof(name)-1);
	if(n < 0){
		close(cfd);
		return -1;
	}
	name[n] = 0;
	p = strrchr(clone, '/');
	*p = 0;
	if(dir)
		sprintf(dir, "%.*s/%.*s", 2*NAMELEN+1, clone, NAMELEN, name);
	sprintf(data, "%.*s/%.*s/data", 2*NAMELEN+1, clone, NAMELEN, name);

	/* set local side (port number, for example) if we need to */
	if(local)
		sprintf(name, "connect %.*s %.*s", 2*NAMELEN, dest, NAMELEN, local);
	else
		sprintf(name, "connect %.*s", 2*NAMELEN, dest);
	/* connect */
	if(write(cfd, name, strlen(name)) < 0){
		close(cfd);
		return -1;
	}

	/* open data connection */
	fd = open(data, O_RDWR | (flags & O_NONBLOCK));
	if(fd < 0){
		close(cfd);
		return -1;
	}
	if(cfdp)
		*cfdp = cfd;
	else
		close(cfd);
	return fd;
}

int dial9(char *dest, char *local, char *dir, int *cfdp, int flags)
{
	char net[128];
	char netdir[128], csname[NETPATHLEN], *slp;
	char clone[NAMELEN+12];
	char *p;
	int n;
	int fd;
	int rv;

	/* go for a standard form net!... */
	p = strchr(dest, '!');
	if(p == 0){
		sprintf(net, "net!%.*s", sizeof(net)-5, dest);
	} else {
		strncpy(net, dest, sizeof(net)-1);
		net[sizeof(net)-1] = 0;
	}

	slp = strrchr(net, '/');
	if (slp != 0) {
		*slp++ = '\0';
		strcpy(netdir, net);
		memmove(net, slp, strlen(slp)+1);
	} else
		strcpy(netdir, "/net");
 

	// special case because we are so special.
	// if the first char of the address is a digit,
	// and the first char of the port is a digit,
	// skip all this cs stuff.
	p = strchr(net, '!');
	if (p && isdigit(p[1])) {
		char *q = strchr(&p[1], '!');
		if (q && isdigit(q[1])) {
			*p++ = 0;
			sprintf(clone, "%s/%s/clone", netdir, net);
			return call(clone, p, cfdp, dir, local, flags);
		}
	}
	/* call the connection server */
	sprintf(csname, "%s/cs", netdir);
	fd = open(csname, O_RDWR);
	if(fd < 0){
		/* no connection server, don't translate */
		p = strchr(net, '!');
		*p++ = 0;
		sprintf(clone, "%s/%s/clone", netdir, net);
		return call(clone, p, cfdp, dir, local, flags);
	}

	/*
	 *  send dest to connection to translate
	 */
	if(write(fd, net, strlen(net)) < 0){
		close(fd);
		return -1;
	}

	/*
	 *  loop through each address from the connection server till
	 *  we get one that works.
	 */
	rv = -1;
	lseek(fd, 0, 0);
	while((n = read(fd, net, sizeof(net) - 1)) > 0){
		net[n] = 0;
		p = strchr(net, ' ');
		if(p == 0)
			continue;
		*p++ = 0;
		rv = call(net, p, cfdp, dir, local, flags);
		if(rv >= 0)
			break;
	}
	close(fd);
	return rv;
}
