basically none of these build
diff --git a/src/libauth/auth_respond.c b/src/libauth/auth_respond.c
new file mode 100644
index 0000000..910f06b
--- /dev/null
+++ b/src/libauth/auth_respond.c
@@ -0,0 +1,73 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+#include <authsrv.h>
+#include "authlocal.h"
+
+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 */
+	}
+}
+
+int
+auth_respond(void *chal, uint nchal, char *user, uint nuser, void *resp, uint nresp, AuthGetkey *getkey, char *fmt, ...)
+{
+	char *p, *s;
+	va_list arg;
+	int afd;
+	AuthRpc *rpc;
+	Attr *a;
+
+	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
+		return -1;
+	
+	if((rpc = auth_allocrpc(afd)) == nil){
+		close(afd);
+		return -1;
+	}
+
+	quotefmtinstall();	/* just in case */
+	va_start(arg, fmt);
+	p = vsmprint(fmt, arg);
+	va_end(arg);
+
+	if(p==nil
+	|| dorpc(rpc, "start", p, strlen(p), getkey) != ARok
+	|| dorpc(rpc, "write", chal, nchal, getkey) != ARok
+	|| dorpc(rpc, "read", nil, 0, getkey) != ARok){
+		free(p);
+		close(afd);
+		auth_freerpc(rpc);
+		return -1;
+	}
+	free(p);
+
+	if(rpc->narg < nresp)
+		nresp = rpc->narg;
+	memmove(resp, rpc->arg, nresp);
+
+	if((a = auth_attr(rpc)) != nil
+	&& (s = _strfindattr(a, "user")) != nil && strlen(s) < nuser)
+		strcpy(user, s);
+	else if(nuser > 0)
+		user[0] = '\0';
+
+	_freeattr(a);
+	close(afd);
+	auth_freerpc(rpc);
+	return nresp;	
+}