hlfw.ca

registry

Download patch

ref: 2bcc704bc097aec422a49e92c4d88f4b90825b60
parent: 66203a502d9d10b9f83e5728be0d2ef97df027fb
author: halfwit <michaelmisch1985@gmail.com>
date: Tue Oct 17 08:51:19 PDT 2023

Updates to enable proper querying

--- a/drop.c
+++ b/drop.c
@@ -1,6 +1,6 @@
 #include <u.h>
 #include <libc.h>
-#include "include/service.h"
+#include "libservice/service.h"
 
 static void
 usage(void)
--- a/include/service.h
+++ /dev/null
@@ -1,29 +1,0 @@
-#include <bio.h>
-#include <ndb.h>
-
-typedef struct Service Service;
-
-enum {
-    NAMELEN = 28,
-    NSVCS = 256,
-    MAXDESC = 256,
-    MAXADDR = 128,
-};
-
-enum {
-	Sok,
-	Sdown,
-	Sreg,
-	Smax,
-};
-
-struct Service {
-    char name[NAMELEN];
-    char description[MAXDESC];
-    char address[MAXADDR];
-    uchar status;
-    vlong uptime;
-};
-
-int svcdial(char *netroot, char *authdom);
-Nbdtuple *svcquery(int fd, char *query, char **argv, int argc);
--- /dev/null
+++ b/libservice/mkfile
@@ -1,0 +1,17 @@
+</$objtype/mkfile
+
+LIB=libservice.a$O
+
+OFILES=\
+	svcdial.$O\
+	svcquery.$O\
+	svctimefmt.$O\
+
+HFILES=\
+	service.h
+
+</sys/src/cmd/mklib
+
+nuke:V:
+	mk clean
+	rm -f libservice.a$O
--- /dev/null
+++ b/libservice/service.h
@@ -1,0 +1,32 @@
+#include <bio.h>
+#include <ndb.h>
+
+typedef struct Service Service;
+
+enum {
+    NAMELEN = 28,
+    NSVCS = 256,
+    MAXDESC = 256,
+    MAXADDR = 128,
+	RS = 0x1e,
+};
+
+enum {
+	Sok = 1,
+	Sdown = 2,
+	Sreg =3 ,
+	Smax =4,
+};
+
+struct Service {
+	char name[NAMELEN];
+	char description[MAXDESC];
+	char address[MAXADDR];
+	uchar status;
+	vlong uptime;
+	Service *next; /* Used for queries */
+};
+
+int svctimefmt(Fmt *f);
+int svcdial(char *netroot, char *authdom);
+Service* svcquery(int fd, char *query, char **argv, int argc);
--- a/libservice/svcdial.c
+++ b/libservice/svcdial.c
@@ -1,8 +1,6 @@
 #include <u.h>
 #include <libc.h>
-#include <bio.h>
-#include <ndb.h>
-#include "../include/service.h"
+#include "service.h"
 
 /* Connect to svcfs */
 int
--- a/libservice/svcquery.c
+++ b/libservice/svcquery.c
@@ -1,11 +1,97 @@
 #include <u.h>
 #include <libc.h>
-#include "../include/service.h"
+#include "service.h"
 
-Ndbtuple *
+char *
+readFile(char *dir, char *name, int len)
+{
+	int fd, n;
+	char buf[MAXDESC+1], path[NAMELEN+25];
+
+	sprint(path, "/mnt/services/%s/%s", dir, name);
+	if((fd = open(path, OREAD)) < 0)
+		return nil;
+	n = readn(fd, buf, len);
+	if(buf[n-1] == '\n' || buf[n-1] == RS)
+		buf[n-1] = '\0';
+	buf[n] = '\0';
+	close(fd);
+	return buf;
+}
+
+Service *
+addService(Dir d)
+{
+	Service *svc;
+	char *desc, *addr, *stat, *up;
+
+	svc = malloc(sizeof *svc);
+	memmove(svc->name, d.name, NAMELEN);
+	svc->name[strlen(d.name)] = '\0';
+	desc = readFile(d.name, "description", MAXDESC);
+	memmove(svc->description, desc, strlen(desc));
+	addr = readFile(d.name, "address", MAXADDR);
+	memmove(svc->address, addr, strlen(addr));
+	svc->status = Sreg;
+	stat = readFile(d.name, "status", 12);
+	if(strncmp(stat, "ok", 2) == 0)
+		svc->status = Sok;
+	if(strncmp(stat, "down", 4) == 0)
+		svc->status = Sdown;
+	up = readFile(d.name, "uptime", 64); /* Way huge */
+	svc->uptime = strtoll(up, nil, 10);
+
+	return svc;
+}
+
+int
+filter(Dir d, char *attr, char *value)
+{
+	char path[NAMELEN+25], buf[MAXDESC];
+	int fd, length;
+
+	length = strlen(value);
+	sprint(path, "/mnt/services/%s/%s", d.name, attr);
+	if((fd = open(path, OREAD)) < 0)
+		return -1;
+	if(readn(fd, buf, length) != length){
+		close(fd);
+		return -1;
+	}
+	if(strncmp(value, buf, length) != 0){
+		close(fd);
+		return -1;
+	}
+	return 0;
+}
+
+Service *
 svcquery(int fd, char *query, char **argv, int argc)
 {
+	Service *svc, *bsvc;
+	Dir *d;
+	int dfd, i, n;
+
+	bsvc = nil;
+
 	/* Build out a tuple based on our search values */
-	USED(fd); USED(query); USED(argv); USED(argc);	
-	return nil;
+	if(strlen(query) == 0)
+		return nil;
+	if(mount(fd, -1, "/mnt/services", MREPL, "") < 0)
+		return nil;
+	dfd = open("/mnt/services", OREAD);
+	while((n = dirread(dfd, &d)) > 0){
+		for(i=0; i < n; i++){
+			if(argc == 2 && filter(d[i], argv[0], argv[1]) < 0)
+				continue;
+			if(strncmp(query, d[i].name, strlen(query)) == 0 || strcmp(query, ".") == 0){
+				svc = addService(d[i]);
+				svc->next = bsvc;
+				bsvc = svc;
+			}
+		}
+		free(d);	
+	}
+	unmount(0, "/mnt/services");
+	return bsvc;
 }
--- /dev/null
+++ b/libservice/svctimefmt.c
@@ -1,0 +1,18 @@
+#include <u.h>
+#include <libc.h>
+#include "service.h"
+
+int
+svctimefmt(Fmt *f)
+{
+	vlong u, d, h, m, s;
+
+	/* Untested at the moment */
+	u = va_arg(f->args, vlong);
+	d = u / 86400;
+	h = u % 3600; // Give remaining hours
+	m = h % 60;
+	s = m % 60;
+	/* Print whole integer values for each */
+	return fmtprint(f, "\'%d days, %d hours, %d minutes, %d seconds\'", (int)d, (int)h, (int)m, (int)s);
+}
--- a/mkfile
+++ b/mkfile
@@ -7,9 +7,9 @@
 	query\
 	svcfs
 
-LIB=libservice.a
+LIB=libservice/libservice.a$O
 
-HFILES=include/service.h
+HFILES=libservice/service.h
 
 BIN=/$objtype/bin/svc
 
--- a/publish.c
+++ b/publish.c
@@ -1,6 +1,6 @@
 #include <u.h>
 #include <libc.h>
-#include "include/service.h"
+#include "libservice/service.h"
 
 static void
 usage(void)
@@ -51,7 +51,8 @@
 	}
 	/* If create fails, try to continue to update values */
 	sprint(ap, "/mnt/services/%s", argv[0]);
-	if((fd = create(ap, OWRITE, DMDIR|0777)) < 0)
+	fd = create(ap, OWRITE, DMDIR|0777);
+	if(fd < 0)
 		goto Error;
 	sprint(ap, "/mnt/services/%s/address", argv[0]);
 	if((fd = open(ap, OWRITE)) < 0)
--- a/query.c
+++ b/query.c
@@ -1,11 +1,11 @@
 #include <u.h>
 #include <libc.h>
-#include "include/service.h"
+#include "libservice/service.h"
 
 static void
 usage(void)
 {
-	fprint(2, "usage: %s [-s svcfs] [-d authdom] query [attr value]\n", argv0);
+	fprint(2, "usage: %s [-s svcfs] [-d authdom] query [attr value...]\n", argv0);
 	exits("usage");
 }
 
@@ -12,26 +12,43 @@
 void
 search(int fd, char *query, char **argv, int argc)
 {
-	Ndbtuple *t, *tt;
+	Service *s, *svcs;
 
-	tt = svcquery(fd, query, argv, argc);
-	for(t = tt; t; t = t->entry)
-		print("%s=%s ", t->attr, t->val);
-	print("\n");
-	ndbfree(tt);
+	svcs = svcquery(fd, query, argv, argc);
+	for(s = svcs; s; s = s->next){
+		print("service=%s address=%s\n", s->name, s->address);
+		switch(s->status){
+		case Sok:
+			print("\tstatus=ok\n");
+			break;
+		case Sdown:
+			print("\tstatus=down\n");
+			break;
+		case Sreg:
+			print("\tstatus=registered\n");
+			break;
+		}
+		print("\tdescription=\'%s\'\n", s->description);
+		print("\tuptime=%T\n", s->uptime);
+		if(s->next != nil)
+			print("\n");
+	}
+	for(s = svcs; s;){
+		svcs = s->next;
+		free(s);
+		s = svcs;
+	}
 }
 
 void
 main(int argc, char *argv[])
 {
-	char *svcfs, *attr, *value;
+	char *svcfs;
 	char *authdom;
 	int fd;
 
 	svcfs = nil;
 	authdom = nil;
-	attr = nil;
-	value = nil;
 	ARGBEGIN{
 	case 's':
 		svcfs = EARGF(usage());
@@ -45,14 +62,12 @@
 	}ARGEND
 	argv0 = "svcfs";
 
+	if(argc == 0)
+		usage();
+	fmtinstall('T', svctimefmt);
 	if((fd = svcdial(svcfs, authdom)) < 0)
 		exits("error");
 	search(fd, argv[0], argv+1, argc-1);
 	close(fd);
-	// Print out our query
 	exits(0);
-Error:
-	fprint(2, "Error with query: %r\n");
-	close(fd);
-	exits("error");
 }
--- a/svcfs.c
+++ b/svcfs.c
@@ -2,7 +2,7 @@
 #include <libc.h>
 #include <ctype.h>
 #include <fcall.h>
-#include "../include/service.h"
+#include "libservice/service.h"
 
 typedef struct Fid Fid;
 typedef struct Entry Entry;
@@ -15,17 +15,8 @@
 	Quptime,
 	Qdesc,
 	Qmax,
-	
-	RS = 0x1e,
 };
 
-enum {
-	Sok,
-	Sdown,
-	Sreg,
-	Smax,
-};
-
 struct Fid {
 	int	fid;
 	ulong	qtype;
@@ -143,7 +134,7 @@
 		error("Can't make pipe: %r");
 
 	readservices();
-	if((pid = rfork(RFPROC|RFMEM)) == 0) {
+	if((pid = rfork(RFPROC|RFNOTEG|RFMEM)) == 0) {
 		watch();
 		exits(0);
 	}