lucho changes
diff --git a/src/libauth/auth_attr.c b/src/libauth/auth_attr.c
index 8842590..2acc32f 100644
--- a/src/libauth/auth_attr.c
+++ b/src/libauth/auth_attr.c
@@ -1,7 +1,6 @@
 #include <u.h>
 #include <libc.h>
 #include <auth.h>
-#include <authsrv.h>
 #include "authlocal.h"
 
 Attr*
diff --git a/src/libauth/auth_challenge.c b/src/libauth/auth_challenge.c
index 298f5f1..b12d0fe 100644
--- a/src/libauth/auth_challenge.c
+++ b/src/libauth/auth_challenge.c
@@ -24,18 +24,15 @@
 		return nil;
 	}
 
-	if((c->afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
+	if((c->rpc=auth_allocrpc()) == nil
+	|| auth_rpc(c->rpc, "start", p, strlen(p)) != ARok
+	|| auth_rpc(c->rpc, "read", nil, 0) != ARok){
 	Error:
 		auth_freechal(c);
 		free(p);
 		return nil;
 	}
 
-	if((c->rpc=auth_allocrpc(c->afd)) == nil
-	|| auth_rpc(c->rpc, "start", p, strlen(p)) != ARok
-	|| auth_rpc(c->rpc, "read", nil, 0) != ARok)
-		goto Error;
-
 	if(c->rpc->narg > sizeof(c->chal)-1){
 		werrstr("buffer too small for challenge");
 		goto Error;
@@ -53,7 +50,7 @@
 	AuthInfo *ai;
 
 	ai = nil;
-	if(c->afd < 0){
+	if(c->rpc == nil){
 		werrstr("auth_response: connection not open");
 		return nil;
 	}
@@ -94,9 +91,7 @@
 	}
 
 Out:
-	close(c->afd);
 	auth_freerpc(c->rpc);
-	c->afd = -1;
 	c->rpc = nil;
 	return ai;
 }
@@ -106,12 +101,8 @@
 {
 	if(c == nil)
 		return;
-
-	if(c->afd >= 0)
-		close(c->afd);
 	if(c->rpc != nil)
 		auth_freerpc(c->rpc);
-
 	memset(c, 0xBB, sizeof(*c));
 	free(c);
 }
diff --git a/src/libauth/auth_getkey.c b/src/libauth/auth_getkey.c
index 0ae28b1..6c26d0a 100644
--- a/src/libauth/auth_getkey.c
+++ b/src/libauth/auth_getkey.c
@@ -6,23 +6,13 @@
 auth_getkey(char *params)
 {
 	char *name;
-	Dir *d;
 	int pid;
 	Waitmsg *w;
 
 	/* start /factotum to query for a key */
-	name = "/factotum";
-	d = dirstat(name);
-	if(d == nil){
-		name = "/boot/factotum";
-		d = dirstat(name);
-	}
-	if(d == nil){
-		werrstr("auth_getkey: no /factotum or /boot/factotum: didn't get key %s", params);
-		return -1;
-	}
-if(0)	if(d->type != '/'){
-		werrstr("auth_getkey: /factotum may be bad: didn't get key %s", params);
+	name = unsharp("#9/bin/factotum");
+	if(name == nil || access(name, AEXEC) < 0){
+		werrstr("auth_getkey: no $PLAN9/bin/factotum: didn't get key %s", params);
 		return -1;
 	}
 	switch(pid = fork()){
@@ -33,6 +23,7 @@
 		execl(name, "getkey", "-g", params, nil);
 		exits(0);
 	default:
+		free(name);
 		for(;;){
 			w = wait();
 			if(w == nil)
diff --git a/src/libauth/auth_getuserpasswd.c b/src/libauth/auth_getuserpasswd.c
index 4d66dce..4a40b26 100644
--- a/src/libauth/auth_getuserpasswd.c
+++ b/src/libauth/auth_getuserpasswd.c
@@ -27,7 +27,6 @@
 {
 	AuthRpc *rpc;
 	char *f[3], *p, *params;
-	int fd;
 	va_list arg;
 	UserPasswd *up;
 
@@ -35,10 +34,7 @@
 	rpc = nil;
 	params = nil;
 
-	fd = open("/mnt/factotum/rpc", ORDWR);
-	if(fd < 0)
-		goto out;
-	rpc = auth_allocrpc(fd);
+	rpc = auth_allocrpc();
 	if(rpc == nil)
 		goto out;
 	quotefmtinstall();	/* just in case */
@@ -70,6 +66,5 @@
 out:
 	free(params);
 	auth_freerpc(rpc);
-	close(fd);
 	return up;
 }
diff --git a/src/libauth/auth_proxy.c b/src/libauth/auth_proxy.c
index 186031e..436c1b7 100644
--- a/src/libauth/auth_proxy.c
+++ b/src/libauth/auth_proxy.c
@@ -2,6 +2,7 @@
 #include <libc.h>
 #include <fcall.h>
 #include <auth.h>
+#include <9pclient.h>
 #include "authlocal.h"
 
 enum { 
@@ -179,7 +180,6 @@
 AuthInfo*
 auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
 {
-	int afd;
 	char *p;
 	va_list arg;
 	AuthInfo *ai;
@@ -190,14 +190,7 @@
 	p = vsmprint(fmt, arg);
 	va_end(arg);
 
-	afd = open("/mnt/factotum/rpc", ORDWR);
-	if(afd < 0){
-		werrstr("opening /mnt/factotum/rpc: %r");
-		free(p);
-		return nil;
-	}
-
-	rpc = auth_allocrpc(afd);
+	rpc = auth_allocrpc();
 	if(rpc == nil){
 		free(p);
 		return nil;
@@ -206,7 +199,95 @@
 	ai = fauth_proxy(fd, rpc, getkey, p);
 	free(p);
 	auth_freerpc(rpc);
-	close(afd);
+	return ai;
+}
+
+/*
+ *  this just proxies what the factotum tells it to.
+ */
+AuthInfo*
+fsfauth_proxy(CFid *fid, 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(fswrite(fid, 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 = fsread(fid, 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*
+fsauth_proxy(CFid *fid, 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 = fsfauth_proxy(fid, rpc, getkey, p);
+	free(p);
+	auth_freerpc(rpc);
 	return ai;
 }
 
diff --git a/src/libauth/auth_respond.c b/src/libauth/auth_respond.c
index 910f06b..d39facf 100644
--- a/src/libauth/auth_respond.c
+++ b/src/libauth/auth_respond.c
@@ -28,17 +28,11 @@
 {
 	char *p, *s;
 	va_list arg;
-	int afd;
 	AuthRpc *rpc;
 	Attr *a;
 
-	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
+	if((rpc = auth_allocrpc()) == nil)
 		return -1;
-	
-	if((rpc = auth_allocrpc(afd)) == nil){
-		close(afd);
-		return -1;
-	}
 
 	quotefmtinstall();	/* just in case */
 	va_start(arg, fmt);
@@ -50,7 +44,6 @@
 	|| dorpc(rpc, "write", chal, nchal, getkey) != ARok
 	|| dorpc(rpc, "read", nil, 0, getkey) != ARok){
 		free(p);
-		close(afd);
 		auth_freerpc(rpc);
 		return -1;
 	}
@@ -67,7 +60,6 @@
 		user[0] = '\0';
 
 	_freeattr(a);
-	close(afd);
 	auth_freerpc(rpc);
 	return nresp;	
 }
diff --git a/src/libauth/auth_rpc.c b/src/libauth/auth_rpc.c
index 4333a73..ffe3b08 100644
--- a/src/libauth/auth_rpc.c
+++ b/src/libauth/auth_rpc.c
@@ -1,6 +1,7 @@
 #include <u.h>
 #include <libc.h>
 #include <auth.h>
+#include <9pclient.h>
 #include "authlocal.h"
 
 static struct {
@@ -17,6 +18,24 @@
 	"error",		ARerror,
 };
 
+static long
+rpcread(AuthRpc *rpc, void *buf, int buflen)
+{
+	if (rpc->afd >= 0)
+		return read(rpc->afd, buf, buflen);
+	else
+		return fsread(rpc->afid, buf, buflen);
+}
+
+static long
+rpcwrite(AuthRpc *rpc, void *buf, int buflen)
+{
+	if (rpc->afd >= 0)
+		return write(rpc->afd, buf, buflen);
+	else
+		return fswrite(rpc->afid, buf, buflen);
+}
+
 static int
 classify(char *buf, uint n, AuthRpc *rpc)
 {
@@ -40,20 +59,31 @@
 }
 
 AuthRpc*
-auth_allocrpc(int afd)
+auth_allocrpc(void)
 {
 	AuthRpc *rpc;
 
 	rpc = mallocz(sizeof(*rpc), 1);
 	if(rpc == nil)
 		return nil;
-	rpc->afd = afd;
+	rpc->afd = open("/mnt/factotum/rpc", ORDWR);
+	if(rpc->afd < 0){
+		rpc->afid = nsopen("factotum", nil, "factotum/rpc", ORDWR);
+		if(rpc->afid == nil){
+			free(rpc);
+			return nil;
+		}
+	}
 	return rpc;
 }
 
 void
 auth_freerpc(AuthRpc *rpc)
 {
+	if(rpc->afd >= 0)
+		close(rpc->afd);
+	if(rpc->afid == nil)
+		fsclose(rpc->afid);
 	free(rpc);
 }
 
@@ -72,13 +102,13 @@
 	memmove(rpc->obuf, verb, l);
 	rpc->obuf[l] = ' ';
 	memmove(rpc->obuf+l+1, a, na);
-	if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){
+	if((n=rpcwrite(rpc, rpc->obuf, l+1+na)) != l+1+na){
 		if(n >= 0)
 			werrstr("auth_rpc short write");
 		return ARrpcfailure;
 	}
 
-	if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)
+	if((n=rpcread(rpc, rpc->ibuf, AuthRpcMax)) < 0)
 		return ARrpcfailure;
 	rpc->ibuf[n] = '\0';
 
diff --git a/src/libauth/auth_wep.c b/src/libauth/auth_wep.c
index afde46b..75d820a 100644
--- a/src/libauth/auth_wep.c
+++ b/src/libauth/auth_wep.c
@@ -11,7 +11,6 @@
 {
 	AuthRpc *rpc;
 	char *params, *p;
-	int fd;
 	va_list arg;
 	int rv;
 
@@ -22,11 +21,7 @@
 		return rv;
 	}
 
-	fd = open("/mnt/factotum/rpc", ORDWR);
-	if(fd < 0)
-		return rv;
-
-	rpc = auth_allocrpc(fd);
+	rpc = auth_allocrpc();
 	if(rpc != nil){
 		quotefmtinstall();	/* just in case */
 		va_start(arg, fmt);
@@ -44,7 +39,5 @@
 		}
 		auth_freerpc(rpc);
 	}
-	close(fd);
-		
 	return rv;
 }
diff --git a/src/libauth/mkfile b/src/libauth/mkfile
index 647835b..2512e9c 100644
--- a/src/libauth/mkfile
+++ b/src/libauth/mkfile
@@ -4,19 +4,19 @@
 LIB=libauth.a
 OFILES=\
 #	amount.$O\
-#	amount_getkey.$O\
+	amount_getkey.$O\
 	attr.$O\
-#	auth_attr.$O\
-#	auth_challenge.$O\
+	auth_attr.$O\
+	auth_challenge.$O\
 #	auth_chuid.$O\
-#	auth_getkey.$O\
-#	auth_getuserpasswd.$O\
-#	auth_proxy.$O\
-#	auth_respond.$O\
-#	auth_rpc.$O\
-#	auth_userpasswd.$O\
-#	auth_wep.$O\
-#	login.$O\
+	auth_getkey.$O\
+	auth_getuserpasswd.$O\
+	auth_proxy.$O\
+	auth_respond.$O\
+	auth_rpc.$O\
+	auth_userpasswd.$O\
+	auth_wep.$O\
+	login.$O\
 #	newns.$O\
 #	noworld.$O\