hlfw.ca

registry

Download patch

ref: 89a2012ebedcbf9c32160ec1501e6327e1dd9b46
parent: 4d109988ae6b45a44d7f4f774dc1f5b22132dfdb
author: halfwit <michaelmisch1985@gmail.com>
date: Sat Oct 14 08:31:16 PDT 2023

Update some to have binaries that use some of the libs

--- a/README.md
+++ b/README.md
@@ -85,25 +85,17 @@
 service=speakers addr=bedroom!1234 description='Bedroom speakers' uptime=123811 status=ok
 ```
 
-## svc/add 
-Usage: `svc/add [-s svcfs] svcname addr [attr value]`
+## svc/publish 
+Usage: `svc/publsh [-s svcfs] [-a authdom] svcname addr [attr value]`
 
-Create a service entry on the given `svcfs`, by default using the `registry=` value in `/lib/ndb/local`.
+Create a service entry on the given `svcfs`, by default using the `registry=` value in `/lib/ndb/local`. If a service already exists, it will attempt to update the svcfs with the attr/values given.
 
 - `attr` can be one of `description` or `auth`
 
-## svc/rm
-Usage: `svc/rm [-s svcfs] svcname`
+## svc/drop
+Usage: `svc/drop [-s svcfs] [-a authdom] svcname`
 
 This will remove the service entry from the `svcfs`. This must be ran as the user who created the service entry, or the hostowner of `svcfs`.
 
-## svc/update
-
-Usage: `svc/update [-s svcfs] svcname [attr value]`
-
-This replaces the given attr/value pairs with the ones provided. This must be ran as the user who created the service entry, or the hostowner of `svcfs`.
-- `attr` can be one of `description` or `auth`
-
 ## Future
-- Libraries for services to publish services
 - Integration into `cpurc`
--- a/aux/mkfile
+++ b/aux/mkfile
@@ -1,10 +1,13 @@
 # svcfs
 </$objtype/mkfile
 
+HFILES ../include/service.h
+
 TARG = svcfs
+
 OFILES =\
 	svcfs.$O
 
 BIN=/$objtype/bin/aux
 
-<//sys/src/cmd/mkone
+</sys/src/cmd/mkone
--- a/aux/svcfs.c
+++ b/aux/svcfs.c
@@ -2,14 +2,10 @@
 #include <libc.h>
 #include <ctype.h>
 #include <fcall.h>
+#include <service.h>
 
-// fs
-//  - addr, description, status, etc in dir from backing. 
-//  - uptime from keepalive thread
-// Every run, we check and set status + uptime
-
 typedef struct Fid Fid;
-typedef struct Service Service;
+typedef struct Entry Entry;
 
 enum {
 	Qroot,
@@ -20,10 +16,6 @@
 	Qdesc,
 	Qmax,
 
-	Namelen = 28,
-	Nsvcs = 512,
-	MAXDESC = 256,
-	MAXADDR = 128,
 	RS = 0x1e,
 };
 
@@ -37,22 +29,18 @@
 struct Fid {
 	int	fid;
 	ulong	qtype;
-	Service *svc;
+	Entry *svc;
 	int	busy;
 	Fid	*next;
 };
 
-struct Service {
-	char	*name;
-	char	*description;
-	char	*addr;
+struct Entry {
+	Service *svc;
 	char	removed;
-	int	ref;
-	vlong	uptime;
+	int		ref;
 	ulong	uniq;
 	uchar	persist;
-	uchar	status;
-	Service *link;
+	Entry *link;
 };
 
 char *qinfo[Qmax] = {
@@ -71,7 +59,7 @@
 };
 
 Fid *fids;
-Service *services[Nsvcs];
+Entry *services[Nsvcs];
 char	*svcfile;
 int		readonly;
 ulong	uniq;
@@ -79,17 +67,17 @@
 uchar	mdata[8192 + IOHDRSZ];
 int		messagesize = sizeof mdata;
 
-Service *findsvc(char*);
-Service *installsvc(char*);
-void	insertsvc(Service*);
-int		removesvc(Service*);
+Entry *findsvc(char*);
+Entry *installsvc(char*);
+void	insertsvc(Entry*);
+int		removesvc(Entry*);
 int		readservices(void);
-void		writeservices(void);
+void	writeservices(void);
 void	error(char*);
-int		dostat(Service*, ulong, void*, int);
+int		dostat(Entry*, ulong, void*, int);
 void	watch(void);
 void	io(int, int);
-Qid		mkqid(Service*, ulong);
+Qid		mkqid(Entry*, ulong);
 ulong	hash(char*);
 Fid		*findfid(int);
 void	*emalloc(ulong);
@@ -230,13 +218,13 @@
 	int i, j, max;
 	Fid *nf;
 	ulong qtype;
-	Service *svc;
+	Entry *e;
 
 	if(!f->busy)
 		return "walk of unused fid";
 	nf = nil;
 	qtype = f->qtype;
-	svc = f->svc;
+	e = f->svc;
 	if(rhdr.fid != rhdr.newfid){
 		nf = findfid(rhdr.newfid);
 		if(nf->busy)
@@ -256,17 +244,17 @@
 			case Qroot:
 				if(strcmp(name, "..") == 0)
 					goto Accept;
-				svc = findsvc(name);
-				if(svc == nil)
+				e = findsvc(name);
+				if(e == nil)
 					goto Out;
 				qtype = Qsvc;
 			Accept:
-				thdr.wqid[i] = mkqid(svc, qtype);
+				thdr.wqid[i] = mkqid(e, qtype);
 				break;
 			case Qsvc:
 				if(strcmp(name, "..") == 0) {
 					qtype = Qroot;
-					svc = nil;
+					e = nil;
 					goto Accept;
 				}
 				max = Qmax;
@@ -293,16 +281,16 @@
 	if(rhdr.fid != rhdr.newfid && i == rhdr.nwname){
 		nf->busy = 1;
 		nf->qtype = qtype;
-		nf->svc = svc;
-		if(svc != nil)
-			svc->ref++;
+		nf->svc = e;
+		if(e != nil)
+			e->ref++;
 	} else if(nf == nil && rhdr.nwname > 0){
 		Clunk(f);
 		f->busy = 1;
 		f->qtype = qtype;
-		f->svc = svc;
-		if(svc != nil)
-			svc->ref++;
+		f->svc = e;
+		if(e != nil)
+			e->ref++;
 	}
 	thdr.nwqid = i;
 	return 0;		
@@ -313,9 +301,10 @@
 {
 	f->busy = 0;
 	if(f->svc != nil && --f->svc->ref == 0 && f->svc->removed) {
-		free(f->svc->name);
-		free(f->svc->description);
-		free(f->svc->addr);
+		free(f->svc->svc->name);
+		free(f->svc->svc->description);
+		free(f->svc->svc->addr);
+		free(f->svc->svc);
 		free(f->svc);
 	}
 	f->svc = nil;
@@ -355,7 +344,7 @@
 		return "permission denied";
 	if(strcmp(name, "") == 0)
 		return "empty file name";
-	if(strlen(name) >= Namelen)
+	if(strlen(name) >= NAMELEN)
 		return "file name too long";
 	if(findsvc(name) != nil)
 		return "svc already exists";
@@ -372,7 +361,7 @@
 char *
 Read(Fid *f)
 {
-	Service *svc;
+	Entry *e;
 	char *data;
 	ulong off, n, m;
 	int i, j, max;
@@ -387,8 +376,8 @@
 	case Qroot:
 		j = 0;
 		for(i = 0; i < Nsvcs; i++)
-			for(svc = services[i]; svc != nil; j += m, svc = svc->link){
-				m = dostat(svc, Qsvc, data, n);
+			for(e = services[i]; e != nil; j += m, e = e->link){
+				m = dostat(e, Qsvc, data, n);
 				if(m <= BIT16SZ)
 					break;
 				if(j < off)
@@ -415,7 +404,7 @@
 		return 0;
 
 	case Qstatus:
-		sprint(data, "%s\n", status[f->svc->status]);
+		sprint(data, "%s\n", status[f->svc->svc->status]);
 	Readstr:
 		m = strlen(data);
 		if(off >= m)
@@ -431,13 +420,13 @@
 		thdr.count = n;
 		return 0;
 	case Qaddr:
-		sprint(data, "%s\n", f->svc->addr);
+		sprint(data, "%s\n", f->svc->svc->addr);
 		goto Readstr;
 	case Quptime:
-		sprint(data, "%lld\n", f->svc->uptime);
+		sprint(data, "%lld\n", f->svc->svc->uptime);
 		goto Readstr;
 	case Qdesc:
-		sprint(data, "%s\n", f->svc->description);
+		sprint(data, "%s\n", f->svc->svc->description);
 		goto Readstr;
 	default:
 		return "permission denied";
@@ -458,21 +447,21 @@
 	data = rhdr.data;
 	switch(f->qtype) {
 	case Qaddr:
-		if(n > Namelen)
+		if(n > NAMELEN)
 			return "address too big!";
 		if(data[n-1] = '\n')
 			n--;
-		memmove(f->svc->addr, data, n);
-		f->svc->addr[n] = '\0';
+		memmove(f->svc->svc->addr, data, n);
+		f->svc->svc->addr[n] = '\0';
 		thdr.count = n;
 		break;
 	case Qdesc:
-		if(n > Namelen)
+		if(n > NAMELEN)
 			return "description too long";
 		if(data[n-1] = '\n')
 			n--;
-		memmove(f->svc->description, data, n);
-		f->svc->description[n] = '\0';
+		memmove(f->svc->svc->description, data, n);
+		f->svc->svc->description[n] = '\0';
 		thdr.count = n;
 		break;
 	case Qroot:
@@ -536,14 +525,14 @@
 	if(convM2D(rhdr.stat, rhdr.nstat, &d, buf) == 0)
 		return "bad stat buffer";
 	n = strlen(d.name);
-	if(n == 0 || n > Namelen)
+	if(n == 0 || n > NAMELEN)
 		return "bad service name";
 	if(findsvc(d.name))
 		return "service already exists";
 	if(!removesvc(f->svc))
 		return "service already removed";
-	free(f->svc->name);
-	f->svc->name = estrdup(d.name);
+	free(f->svc->svc->name);
+	f->svc->svc->name = estrdup(d.name);
 	insertsvc(f->svc);
 	writeservices();
 	return 0;
@@ -550,14 +539,14 @@
 }
 
 Qid
-mkqid(Service *svc, ulong qtype)
+mkqid(Entry *e, ulong qtype)
 {
 	Qid q;
 
 	q.vers = 0;
 	q.path = qtype;
-	if(svc)
-		q.path |= svc->uniq * 0x100;
+	if(e)
+		q.path |= e->uniq * 0x100;
 	if(qtype == Qsvc || qtype == Qroot)
 		q.type = QTDIR;
 	else
@@ -566,16 +555,16 @@
 }
 
 int
-dostat(Service *svc, ulong qtype, void *p, int n)
+dostat(Entry *e, ulong qtype, void *p, int n)
 {
 	Dir d;
 
 	if(qtype == Qsvc)
-		d.name = svc->name;
+		d.name = e->name;
 	else
 		d.name = qinfo[qtype];
 	d.uid = d.gid = d.muid = "none"; // Maybe reggie or so
-	d.qid = mkqid(svc, qtype);
+	d.qid = mkqid(e, qtype);
 	if(d.qid.type & QTDIR)
 		d.mode = 0777|DMDIR;
 	else
@@ -590,7 +579,7 @@
 {
 	int entrylen;
 	int fd, ns, i;
-	Service *svc;
+	Entry *e;
 	uchar *p, *buf;
 	ns = 0;
 
@@ -599,10 +588,10 @@
 		return;
 	}
 	
-	entrylen = Namelen + MAXADDR + MAXDESC;
+	entrylen = NAMELEN + MAXADDR + MAXDESC;
 	/* Count our services */
 	for(i = 0; i < Nsvcs; i++)
-		for(svc = services[i]; svc != nil; svc = svc->link)
+		for(e = services[i]; e != nil; e = e->link)
 			ns++;
 
 	/* Make a buffer large enough to hold each line */
@@ -610,12 +599,12 @@
 	memset(buf, RS, entrylen);
 	p = buf;
 	for(i = 0; i < Nsvcs; i++)
-		for(svc = services[i]; svc !=nil; svc = svc->link){
-			strncpy((char *)p, svc->name, Namelen);
-			p += Namelen;
-			strncpy((char *)p, svc->addr, MAXADDR);
+		for(e = services[i]; e !=nil; e = e->link){
+			strncpy((char *)p, e->svc->name, NAMELEN);
+			p += NAMELEN;
+			strncpy((char *)p, e->svc->addr, MAXADDR);
 			p += MAXADDR;
-			strncpy((char *)p, svc->description, MAXDESC);
+			strncpy((char *)p, e->svc->description, MAXDESC);
 			p += MAXDESC;
 		}
 	fd = create(svcfile, OWRITE, 0660);
@@ -635,12 +624,12 @@
 {
 	int i, n, rv;
 	Rune r;
-	char buf[Namelen+1];
+	char buf[NAMELEN+1];
 
 	memset(buf, 0, sizeof buf);
-	memmove(buf, svc, Namelen);
+	memmove(buf, svc, NAMELEN);
 
-	if(buf[Namelen-1] != 0){
+	if(buf[NAMELEN-1] != 0){
 		fprint(2, "svcfs: %d: no termination\n", nu);
 		return -1;
 	}
@@ -694,7 +683,7 @@
 {
 	int fd, i, n, ns, entrylen;
 	uchar *buf, *ep;
-	Service *svc;
+	Entry *e;
 	Dir *d;
 
 	/* Read our file into buf */
@@ -717,15 +706,15 @@
 		return 0;
 	}
 	ep = buf;
-	entrylen = Namelen + MAXDESC + MAXADDR;
+	entrylen = NAMELEN + MAXDESC + MAXADDR;
 	n = n / entrylen;
 	ns = 0;
 	for(i = 0; i < n; ep += entrylen, i++){
-		svc = findsvc((char *)ep);
-		if(svc == nil)
-			svc = installsvc((char *)ep);
-		svc->addr = scrub(ep + Namelen, MAXADDR);
-		svc->description = scrub(ep + Namelen + MAXADDR, MAXDESC);
+		e = findsvc((char *)ep);
+		if(e == nil)
+			e = installsvc((char *)ep);
+		e->svc->addr = scrub(ep + NAMELEN, MAXADDR);
+		e->svc->description = scrub(ep + NAMELEN + MAXADDR, MAXDESC);
 		ns++;
 	}
 	free(buf);
@@ -734,48 +723,49 @@
 	return 1;
 }
 
-Service *
+Entry *
 installsvc(char *name)
 {
-	Service *svc;
+	Entry *e;
 	int h;
 
 	h = hash(name);
-	svc = emalloc(sizeof *svc);
-	svc->name = estrdup(name);
-	svc->description = estrdup("No description provided");
-	svc->addr = estrdup("none");
-	svc->removed = 0;
-	svc->ref = 0;
-	svc->status = Sreg;
-	svc->uniq = uniq++;
-	svc->link = services[h];
-	services[h] = svc;
-	return svc;
+	e = emalloc(sizeof *e);
+	e->svc = emalloc(sizeof Service);
+	e->svc->name = estrdup(name);
+	e->svc->description = estrdup("No description provided");
+	e->svc->addr = estrdup("none");
+	e->removed = 0;
+	e->ref = 0;
+	e->svc->status = Sreg;
+	e->uniq = uniq++;
+	e->link = services[h];
+	services[h] = e;
+	return e;
 }
 
-Service *
+Entry *
 findsvc(char *name)
 {
-	Service *svc;
+	Entry *e;
 
-	for(svc = services[hash(name)]; svc != nil; svc = svc->link)
-		if(strcmp(name, svc->name) == 0)
-			return svc;
+	for(e = services[hash(name)]; e != nil; e = e->link)
+		if(strcmp(name, e->svc->name) == 0)
+			return e;
 	return nil;
 }
 
 int
-removesvc(Service *svc)
+removesvc(Entry *e)
 {
-	Service *s, **last;
+	Entry *s, **last;
 	char *name;
 
-	svc->removed = 1;
-	name = svc->name;
+	e->removed = 1;
+	name = e->svc->name;
 	last = &services[hash(name)];
 	for(s = *last; s != nil; s = *last){
-		if(strcmp(name, s->name) == 0) {
+		if(strcmp(name, s->svc->name) == 0) {
 			*last = s->link;
 			return 1;
 		}
@@ -786,14 +776,14 @@
 }
 
 void
-insertsvc(Service *svc)
+insertsvc(Entry *e)
 {
 	int h;
 
-	svc->removed = 0;
-	h = hash(svc->name);
-	svc->link = services[h];
-	services[h] = svc;
+	e->removed = 0;
+	h = hash(e->svc->name);
+	e->link = services[h];
+	services[h] = e;
 }
 
 ulong
@@ -863,20 +853,20 @@
 }
 
 int
-alive(Service *svc)
+alive(Entry *e)
 {
 	int fd;
 
-	if(strncmp(svc->addr, "none", 4) == 0)
+	if(strncmp(e->svc->addr, "none", 4) == 0)
 		return 2;
-	fd = dial(svc->addr, nil, nil, nil);
+	fd = dial(e->svc->addr, nil, nil, nil);
 	if(fd < 0){
-		if(svc->status == Sreg)
+		if(e->svc->status == Sreg)
 			return 2;
 		return -1;
 	}
 	close(fd);
-	if(svc->status == Sok)
+	if(e->svc->status == Sok)
 		return 1;
 	return 0;
 }
@@ -885,7 +875,7 @@
 watch(void)
 {
 	/* Status, uptime */
-	Service *svc;
+	Entry *e;
 	int i;
 	int seconds;
 	vlong start;
@@ -896,20 +886,20 @@
 		for(i = 0; i < seconds; i++)
 			sleep(1000);
 		for(i = 0; i < Nsvcs; i++)
-			for(svc = services[i]; svc !=nil; svc = svc->link)
-				switch(alive(svc)){
+			for(e = services[i]; e !=nil; e = e->link)
+				switch(alive(e)){
 				case -1: 
 					/* Offline */
-					svc->status = Sdown;
+					e->svc->status = Sdown;
 					break;
 				case 0:
 					/* Coming online */
-					svc->status = Sok;
-					svc->uptime = 0;
+					e->svc->status = Sok;
+					e->svc->uptime = 0;
 					break;
 				case 1:
-					svc->status = Sok;
-					svc->uptime += ((nsec() - start) / 1000000000LL);
+					e->svc->status = Sok;
+					e->svc->uptime += ((nsec() - start) / 1000000000LL);
 					break;
 				default:
 					/* Still in setup */
--- /dev/null
+++ b/drop.c
@@ -1,0 +1,50 @@
+#include <u.h>
+#include <libc.h>
+#include <service.h>
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-s svcfs] [-d authdom] svcname\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	char *svcfs, *authdom;
+    int fd;
+
+	ARGBEGIN{
+	case 's':
+		svcfs = EARGF(usage());
+		break;
+    case 'a':
+        authdom = EARGF(usage());
+	default:
+		usage();
+		break;
+	}ARGEND
+	argv0 = "svcfs";
+
+	if(argc != 1)
+		usage();
+
+    if(strlen(argv[0]) > NAMELEN){
+        fprint(2, "Service name too large: %r\n");
+        exits("namelen");
+    }
+
+    fd = svcdial(svcfs, authdom);
+    if(mount(fd, -1, "/mnt/services", MAFTER, "") < 0)
+        goto Error;
+    if(remove(sprintf("/mnt/services/%s", argv[1])) < 0)
+        goto Error;
+    close(fd);
+    unmount("", "/mnt/services");
+    exits(0);
+Error:
+    fprint(2, "Error removing service: %r\n");
+    close(fd);
+    exits("error");
+}
--- /dev/null
+++ b/include/service.h
@@ -1,0 +1,21 @@
+#include <ndb.h>
+typedef struct Service Service;
+
+enum {
+    NAMELEN = 28,
+    NSVCS = 256,
+    MAXDESC = 256,
+    MAXADDR = 128,
+};
+
+
+struct Service {
+    char name[NAMELEN];
+    char description[MAXDESC];
+    char address[MAXADDR];
+    uchar status;
+    vlong uptime;
+};
+
+int svcdial(char *netroot, char *authdom);
+int svcquery(int fd, char *query, Ndbtuple *t);
--- /dev/null
+++ b/libservice/svcdial.c
@@ -1,0 +1,52 @@
+#include <u.h>
+#include <libc.h>
+#include <service.h>
+#include <ndb.h>
+
+/* Connect to svcfs */
+int
+svcdial(char *netroot, char *dom)
+{
+    Ndbtuple *t, *nt;
+	char *p;
+	int rv;
+
+	if(dom == nil)
+		/* look for one relative to my machine */
+		return dial(netmkaddr("$registry", nil, "16675"), nil, nil, nil);
+
+	/* look up an auth server in an authentication domain */
+	p = csgetvalue(netroot, "authdom", dom, "registry", &t);
+
+	/* if that didn't work, just try the IP domain */
+	if(p == nil)
+		p = csgetvalue(netroot, "dom", dom, "registry", &t);
+
+	/*
+	 * if that didn't work, try p9registry.$dom.  this is very helpful if
+	 * you can't edit /lib/ndb.
+	 */
+	if(p == nil) {
+		p = smprint("p9registry.%s", dom);
+		if(p == nil)
+			return -1;
+		t = ndbnew("registry", p);
+	}
+	free(p);
+
+	/*
+	 * allow multiple registry= attributes for backup auth servers,
+	 * try each one in order.
+	 */
+	rv = -1;
+	for(nt = t; nt != nil; nt = nt->entry) {
+		if(strcmp(nt->attr, "registry") == 0) {
+			rv = dial(netmkaddr(nt->val, nil, "16675"), nil, nil, nil);
+			if(rv >= 0)
+				break;
+		}
+	}
+	ndbfree(t);
+
+	return rv;
+}
--- a/mkfile
+++ b/mkfile
@@ -1,16 +1,13 @@
 # registry mkfile
 </$objtype/mkfile
 
-TARG =	\
-	registry\
-	regquery\
+TARG =\
+	drop\
+	publish\
+	query\
 
-HFILES = dns.h /$objtype/lib/libndb.a
+HFILES = include/service.h
 
-BIN=/$objtype/bin/ndb
+BIN=/$objtype/bin/svc
 
 </sys/src/cmd/mkmany
-
-$O.registry: registry.$O reglookup.$O
-	$LD -o $target $prereq
-
--- /dev/null
+++ b/publish.c
@@ -1,0 +1,80 @@
+#include <u.h>
+#include <libc.h>
+#include <service.h>
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-s svcfs] [-d authdom] svcname addr [attr value]\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	char *svcfs, *authdom, *ap;
+    int i, fd, sfd;
+
+	ARGBEGIN{
+	case 's':
+		svcfs = EARGF(usage());
+		break;
+    case 'a':
+        authdom = EARGF(usage());
+	default:
+		usage();
+		break;
+	}ARGEND
+	argv0 = "svcfs";
+
+	if(argc < 2)
+		usage();
+
+    if(strlen(argv[0]) > NAMELEN){
+        fprint(2, "Service name too large\n");
+        exits("namelen");
+    }
+    if(strlen(argv[0]) > MAXADDR){
+        fprint(2, "Address too long\n");
+        exits("address");
+    }
+    sfd = svcdial(svcfs, authdom);
+    if(mount(sfd, -1, "/mnt/services", MREPL, "/") == -1){
+        fprint(2, "Error mounting svcfs\n");
+        exits("error");
+    }
+
+    /* If create fails, try to continue to update values */
+    snprint(ap, sizeof ap, "/mnt/services/%s", argv[0]);
+    if((fd = create(ap, OREAD, DMDIR|0700)) >= 0)
+		close(fd);
+    snprint(ap, sizeof ap, "/mnt/services/%s/address", argv[0]);
+    if((fd = open(ap, OWRITE)) < 0)
+        goto Error;
+	if(write(fd, argv[1], MAXADDR) <= 0)
+        goto Error;
+
+    /* Description, authdom */
+    for(i = 2; i < argc + 1; i++){
+        if(strcmp(argv[i], "description") == 0){
+            snprint(ap, sizeof ap, "/mnt/services/%s/description", argv[0]);
+            if((fd = open(ap, OWRITE|OTRUNC)) < 0)
+                goto Error;
+            if(write(fd, argv[i+1], MAXDESC) <= 0)
+                goto Error;
+        } /*else if(strcmp(argv[i], "authdom") == 0){
+            snprint(ap, sizeof ap, "/mnt/services/%s/authdom", argv[0]);
+            if((fd = open(ap, OWRITE|OTRUNC)) < 0)
+                goto Error;
+            if(write(fd, argv[i+1], MAXADDR) <= 0)
+                goto Error;
+        }*/
+        i++;
+    }
+    unmount("", "/mnt/services");
+    exits(0);
+Error:
+    fprint(2, "Error publishing service: %r\n");
+    close(sfd);
+    exits("error");
+}
--- /dev/null
+++ b/query.c
@@ -1,0 +1,43 @@
+#include <u.h>
+#include <libc.h>
+#include <service.h>
+#include <ndb.h>
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-s svcfs] [-d authdom] query\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	char *svcfs;
+    char *authdom;
+    Ndbtuple *t;
+    int fd;
+
+	ARGBEGIN{
+	case 's':
+		svcfs = EARGF(usage());
+		break;
+    case 'a':
+        authdom = EARGF(usage());
+	default:
+		usage();
+		break;
+	}ARGEND
+	argv0 = "svcfs";
+
+	if(argc != 1)
+		usage();
+
+    fd = svcdial(svcfs, authdom);
+    if(svcquery(fd, argv[1], &t) < 0){
+        fprint(2, "error in querying registry\n");
+        exits("error");
+    }
+	// Print out our query
+    exits(0);
+}
--- /dev/null
+++ b/services
@@ -1,0 +1,57 @@
+#!/bin/rc
+
+$argv0 = $0
+
+fn usage {
+    echo 'Usage:' $argv0 '[-o] [-f servicesdb] [-s svcfs]' >[1=2]
+    exits 'usage'
+}
+
+dbfile=()
+svcfs=()
+order=1
+while(~ $1 -*){
+	switch($1){
+	case -o; order=2
+	case *
+		~ $#* 1 && usage
+		switch($1){
+		case -f; dbfile=$2
+		case -s; svcfs=$2
+		case *; usage
+		}
+		shift
+	}
+	shift
+}
+
+! ~ $#* 0 && usage
+
+if(~ $svcfs "")
+	svcfs=`{ndb/ipquery sys $sysname registry | sed 's/registry=//'}
+if(~ $svcfs ""){
+	echo 'Unable to find Registry'
+	exits 'registry'
+}
+# Ours, we check later for the one associated with svcfs
+# With -s, parse the addr ipnet if exists and use that instead
+ipnet=`{ndb/ipquery sys $sysname ipnet | sed 's/ipnet=//'}
+
+fn mount {
+	# Mount up svcfs in our namespace
+	srv -c -m $svcfs^'!16675' services /mnt/services
+
+}
+
+fn publish {
+	# Try /cfg/sysname/services if not set
+	# Initial read + post everything
+	#  - if we posted the service, service.local
+}
+
+fn serve {
+
+}
+
+# Walk the dir, parse addr file + build /srv/service.sysname.ipnet
+# With -o, /srv/ipnet.sysname.service
--- a/svc/add
+++ /dev/null
@@ -1,41 +1,0 @@
-#!/bin/rc
-
-argv0=$0
-
-fn usage {
-	echo 'Usage:' $argv0 ' [-s svcfs] svcname addr [attr value]'
-	exits 'usage';
-}
-
-svcfs=()
-desc=()
-auth=()
-
-if(~ $1 "-s"){
-	shift
-	svcfs=$1
-	shift
-}
-
-svcname=$1; shift
-addr=$1; shift
-
-~ $svcname "" && usage
-~ $addr "" && usage
-
-while(! ~ $#* 0){
-	switch($1){
-	case "description":
-		$desc=$2
-		shift
-	case "auth":
-		$auth=$2
-		shift
-	}
-	shift
-}
-
-if(! ~ $#* 0)
-	usage
-
-# Now connect to the svcfs. Create out file, then set the address, description, and apparently the auth server
--- a/svc/query
+++ /dev/null
@@ -1,2 +1,0 @@
-#!/bin/rc
-
--- a/svc/rm
+++ /dev/null
@@ -1,2 +1,0 @@
-#!/bin/rc
-
--- a/svc/services
+++ /dev/null
@@ -1,47 +1,0 @@
-#!/bin/rc
-
-$argv0 = $0
-
-fn usage {
-    echo 'Usage:' $argv0 '[-o] [-f servicesdb] [-s svcfs]' >[1=2]
-    exits 'usage'
-}
-
-dbfile=()
-svcfs=()
-order=1
-while(~ $1 -*){
-	switch($1){
-	case -o; order=2
-	case *
-		~ $#* 1 && usage
-		switch($1){
-		case -f; dbfile=$2
-		case -s; svcfs=$2
-		case *; usage
-		}
-		shift
-	}
-	shift
-}
-
-! ~ $#* 0 && usage
-
-if(~ $svcfs "")
-	svcfs=`{ndb/ipquery sys $sysname registry | sed 's/registry=//'}
-if(~ $svcfs ""){
-	echo 'Unable to find Registry'
-	exits 'registry'
-}
-# Ours, we check later for the one associated with svcfs
-ipnet=`{ndb/ipquery sys $sysname ipnet | sed 's/ipnet=//'}
-
-# Connect to svcfs
-# Initial writes
-# Initial read + post everything
-#  - if we posted the service, service.local
-# Try /cfg/sysname/services if not set
-# Walk the dir, parse addr file + build /srv/service.sysname.ipnet
-# With -o, /srv/ipnet.sysname.service
-# Lookup our own ipnet
-# With -s, parse the addr ipnet if exists and use that instead
\ No newline at end of file