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

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 '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)
		xauth();

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

	rfork(RFNOTEG);
	if(post9pservice(fd, service) < 0)
		sysfatal("post9pservice: %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
post9pservice(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)
			execlp("9pserve", "9pserve", "-u",
				"-M",
					smprint("%d", msize),
				"-A",
					aname,
					smprint("%d", afid),
				s, (char*)0);
		else		
			execlp("9pserve", "9pserve", "-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;
}

