#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include <thread.h>

int post9p(int, char*);
int debug;
char *aname = "";
char *keypattern = "";
int fd;
int msize;
int doauth;
u32int afid = NOFID;
extern char *post9parg;	/* clumsy hack */
void xauth(void);
AuthInfo* xauth_proxy(AuthGetkey *getkey, char *fmt, ...);

void
usage(void)
{
	fprint(2, "usage: srv [-a] [-A aname] [-k keypattern] addr [srvname]\n");
	threadexitsall("usage");
}

void
threadmain(int argc, char **argv)
{
	char *addr, *service;

	fmtinstall('F', fcallfmt);
	fmtinstall('M', dirmodefmt);
	
	ARGBEGIN{
	case 'D':
		debug = 1;
		break;
	case 'A':
		/* BUG: should be able to repeat this and establish multiple afids */
		aname = EARGF(usage());
		break;
	case 'a':
		doauth = 1;
		break;
	case 'n':
		doauth = -1;
		break;
	case 'k':
		keypattern = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND
	
	if(argc != 1 && argc != 2)
		usage();

	addr = netmkaddr(argv[0], "tcp", "9fs");
	if((fd = dial(addr, nil, nil, nil)) < 0)
		sysfatal("dial %s: %r", addr);

	if(doauth > 0)
		xauth();

	if(argc == 2)
		service = argv[1];
	else
		service = argv[0];

	rfork(RFNOTEG);
	if(post9p(fd, service) < 0)
		sysfatal("post9p: %r");

	threadexitsall(0);
}

void
do9p(Fcall *tx, Fcall *rx)
{
	static uchar buf[9000];
	static char ebuf[200];
	int n;
	
	n = convS2M(tx, buf, sizeof buf);
	if(n == BIT16SZ){
		werrstr("convS2M failed");
		goto err;
	}
	if(debug)
		fprint(2, "<- %F\n", tx);
	if(write(fd, buf, n) != n)
		goto err;
	if((n = read9pmsg(fd, buf, sizeof buf)) < 0)
		goto err;
	if(n == 0){
		werrstr("unexpected eof");
		goto err;
	}
	if(convM2S(buf, n, rx) != n){
		werrstr("convM2S failed");
		goto err;
	}
	if(debug)
		fprint(2, "-> %F\n", rx);
	if(rx->type != Rerror && rx->type != tx->type+1){
		werrstr("unexpected type");
		goto err;
	}
	if(rx->tag != tx->tag){
		werrstr("unexpected tag");
		goto err;
	}
	return;

err:
	rerrstr(ebuf, sizeof ebuf);
	rx->ename = ebuf;
	rx->type = Rerror;
	return;
}

void
xauth(void)
{
	Fcall tx, rx;

	afid = 0;
	tx.type = Tversion;
	tx.tag = NOTAG;
	tx.version = "9P2000";
	tx.msize = 8192;
	do9p(&tx, &rx);
	if(rx.type == Rerror)
		sysfatal("Tversion: %s", rx.ename);
	msize = rx.msize;
	
	tx.type = Tauth;
	tx.tag = 1;
	tx.afid = afid;
	tx.uname = getuser();
	tx.aname = aname;
	do9p(&tx, &rx);
	if(rx.type == Rerror){
		fprint(2, "rx: %s\n", rx.ename);
		afid = NOFID;
		return;
	}

	if(xauth_proxy(auth_getkey, "proto=p9any role=client %s", keypattern) == nil)
		sysfatal("authproxy: %r");
}

int
xread(void *buf, int n)
{
	Fcall tx, rx;
	
	tx.type = Tread;
	tx.tag = 1;
	tx.fid = 0;	/* afid above */
	tx.count = n;
	tx.offset = 0;
	do9p(&tx, &rx);
	if(rx.type == Rerror){
		werrstr("%s", rx.ename);
		return -1;
	}
	
	if(rx.count > n){
		werrstr("too much data returned");
		return -1;
	}
	memmove(buf, rx.data, rx.count);
	return rx.count;
}

int
xwrite(void *buf, int n)
{
	Fcall tx, rx;
	
	tx.type = Twrite;
	tx.tag = 1;
	tx.fid = 0;	/* afid above */
	tx.data = buf;
	tx.count = n;
	tx.offset = 0;
	do9p(&tx, &rx);
	if(rx.type == Rerror){
		werrstr("%s", rx.ename);
		return -1;
	}
	return n;
}


/*
 * changed to add -A below
 */
#undef _exits
int
post9p(int fd, char *name)
{
	int i;
	char *ns, *s;
	Waitmsg *w;

	if((ns = getns()) == nil)
		return -1;

	s = smprint("unix!%s/%s", ns, name);
	free(ns);
	if(s == nil)
		return -1;
	switch(fork()){
	case -1:
		return -1;
	case 0:
		dup(fd, 0);
		dup(fd, 1);
		for(i=3; i<20; i++)
			close(i);
		if(doauth > 0)
			execlp("9pserve", "9pserve", "-u",
				"-M",
					smprint("%d", msize),
				"-A",
					aname,
					smprint("%d", afid),
				s, (char*)0);
		else
			execlp("9pserve", "9pserve",
				doauth < 0 ? "-nu" : "-u", s, (char*)0);
		fprint(2, "exec 9pserve: %r\n");
		_exits("exec");
	default:
		w = wait();
		if(w == nil)
			return -1;
		close(fd);
		free(s);
		if(w->msg && w->msg[0]){
			free(w);
			werrstr("9pserve failed");
			return -1;
		}
		free(w);
		return 0;
	}
}

enum { ARgiveup = 100 };
static int
dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
{
	int ret;

	for(;;){
		if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
			return ret;
		if(getkey == nil)
			return ARgiveup;	/* don't know how */
		if((*getkey)(rpc->arg) < 0)
			return ARgiveup;	/* user punted */
	}
}


/*
 *  this just proxies what the factotum tells it to.
 */
AuthInfo*
xfauth_proxy(AuthRpc *rpc, AuthGetkey *getkey, char *params)
{
	char *buf;
	int m, n, ret;
	AuthInfo *a;
	char oerr[ERRMAX];

	rerrstr(oerr, sizeof oerr);
	werrstr("UNKNOWN AUTH ERROR");

	if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
		werrstr("fauth_proxy start: %r");
		return nil;
	}

	buf = malloc(AuthRpcMax);
	if(buf == nil)
		return nil;
	for(;;){
		switch(dorpc(rpc, "read", nil, 0, getkey)){
		case ARdone:
			free(buf);
			a = auth_getinfo(rpc);
			errstr(oerr, sizeof oerr);	/* no error, restore whatever was there */
			return a;
		case ARok:
			if(xwrite(rpc->arg, rpc->narg) != rpc->narg){
				werrstr("auth_proxy write fid: %r");
				goto Error;
			}
			break;
		case ARphase:
			n = 0;
			memset(buf, 0, AuthRpcMax);
			while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
				if(atoi(rpc->arg) > AuthRpcMax)
					break;
				m = xread(buf+n, atoi(rpc->arg)-n);
				if(m <= 0){
					if(m == 0)
						werrstr("auth_proxy short read: %s", buf);
					goto Error;
				}
				n += m;
			}
			if(ret != ARok){
				werrstr("auth_proxy rpc write: %s: %r", buf);
				goto Error;
			}
			break;
		default:
			werrstr("auth_proxy rpc: %r");
			goto Error;
		}
	}
Error:
	free(buf);
	return nil;
}

AuthInfo*
xauth_proxy(AuthGetkey *getkey, char *fmt, ...)
{
	char *p;
	va_list arg;
	AuthInfo *ai;
	AuthRpc *rpc;

	quotefmtinstall();	/* just in case */
	va_start(arg, fmt);
	p = vsmprint(fmt, arg);
	va_end(arg);

	rpc = auth_allocrpc();
	if(rpc == nil){
		free(p);
		return nil;
	}

	ai = xfauth_proxy(rpc, getkey, p);
	free(p);
	auth_freerpc(rpc);
	return ai;
}

