hlfw.ca

registry

Download patch

ref: 894718e16f690d6ae1d1f1061a8ad703947ea5d9
parent: 5ddcb59618def30c1e17a651b29c9722dca82df2
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Oct 19 18:35:27 PDT 2023

monitor also can be a simple binary, make a lib function to free a svc

--- a/libservice/mkfile
+++ b/libservice/mkfile
@@ -6,6 +6,7 @@
 	svcdial.$O\
 	svcquery.$O\
 	svctimefmt.$O\
+	svcfree.$O\
 
 HFILES=\
 	service.h
--- a/libservice/service.h
+++ b/libservice/service.h
@@ -30,3 +30,4 @@
 int svctimefmt(Fmt *f);
 int svcdial(char *netroot, char *authdom);
 Service* svcquery(int fd, char *query, char **argv, int argc);
+void svcfree(Service *);
--- /dev/null
+++ b/libservice/svcfree.c
@@ -1,0 +1,14 @@
+#include <u.h>
+#include <libc.h>
+#include "service.h"
+
+void
+svcfree(Service *s)
+{
+	Service *sn;
+	
+	for(; s; s = sn){
+		sn = s->next;
+		free(s);
+	}
+}
--- a/mkfile
+++ b/mkfile
@@ -5,7 +5,8 @@
 	drop\
 	publish\
 	query\
-	svcfs
+	svcfs\
+	monitor
 
 LIB=libservice/libservice.a$O
 
--- a/monitor
+++ /dev/null
@@ -1,51 +1,0 @@
-#!/bin/rc
-
-$argv0 = $0
-
-fn usage {
-    echo 'Usage: '$argv0' [-o] [-s svcfs]' >[1=2]
-    exits 'usage'
-}
-
-svcfs=()
-order=1
-while(~ $1 -*){
-	switch($1){
-	case -o; order=2
-	case *
-		~ $#* 1 && usage
-		switch($1){
-		case -s; svcfs=(-s $2)
-		case *; usage
-		}
-		shift
-	}
-	shift
-}
-
-! ~ $#* 0 && usage
-
-# TODO: Authdom goes in first line of tuple, consider that as well
-fn update {
-	for(f in `{svc/query $svcfs . status ok grep service}){
-		name=`{echo f | sed 's/.*service=//;s/ address=.*//'}
-		address=`{echo f | sed 's/.*address=tcp!//;s/ .*//'}
-		entry=$name^'/'^$address
-		~ $order 2 && entry=$address^'.'^$name
-		test -f '/srv/'^$entry || srv $address $entry
-	}
-	for(f in `{svc/query $svcfs . status down | grep services}){
-		name=`{echo f | sed 's/.*service=//;s/ address=.*//'}
-		address=`{echo f | sed 's/.*address=tcp!//;s/ .*//'}
-		entry='/srv/'^$name^'.'^$address
-		~ $order 2 && entry='/srv/'^$address^'.'^$name
-		test -f $entry && rm $entry
-	}
-}
-
-fn watch {
-	while(1){
-		update
-		sleep 30 # Not the best way to watch for a service coming up. At worst it can take a full minute
-	}
-}
--- /dev/null
+++ b/monitor.c
@@ -1,0 +1,130 @@
+#include <u.h>
+#include <libc.h>
+#include "libservice/service.h"
+
+void monitor(char *,int, int, int);
+void publish(Service *, char *);
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-o] [-r timeout] [-a authdom] [-s svcfs]\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	char *svcfs;
+	char *authdom;
+	int style, fd, pollrate;
+
+	svcfs = nil;
+	authdom = nil;
+	style = 1;
+	pollrate = 30;
+
+	ARGBEGIN{
+	case 's':
+		svcfs = EARGF(usage());
+		break;
+	case 'a':
+		authdom = EARGF(usage());
+		break;
+	case 'o':
+		style++;
+		break;
+	case 'r':
+		pollrate = atoi(EARGF(usage()));
+		break;
+	default:
+		usage();
+	}ARGEND
+	argv0 = "monitor";
+
+	if(argc > 0)
+		usage();
+	if((fd = svcdial(svcfs, authdom)) < 0){
+		fprint(2, "Unable to dial svcfs: %r\n");
+		exits("error");
+	}
+
+	if(authdom != nil){
+		monitor(authdom, fd, style, pollrate);
+		exits(0);
+	}
+	monitor("9front", fd, style, pollrate);
+	exits(0);
+
+}
+
+char *
+clean(char *addr)
+{
+	char *c;
+	if(strncmp(addr, "tcp!", 4) == 0)
+		addr += 4;
+	c = strchr(addr, '!');
+	if(c != nil)
+		*c='\0';
+	return addr ;
+}
+
+void
+monitor(char *authdom, int fd, int style, int rate)
+{
+	Service *svc, *s;
+	char srv[MAXADDR];
+	int i;
+
+	for(;;){
+		for(i=0; i < rate; i++)
+			sleep(1000);
+		svc = svcquery(fd, ".", nil, 0);
+		for(s = svc; s; s = s->next){
+			switch(style){
+			case 1:
+				sprint(srv, "/srv/%s.%s.%s", s->name, clean(s->address), authdom);
+				break;
+			case 2:
+				sprint(srv, "/srv/%s.%s.%s", authdom, clean(s->address), s->name);
+				break;
+			}
+			switch(s->status){
+			case Sok:
+				publish(s, srv);
+				break;
+			case Sdown:
+				remove(srv);
+				break;
+			case Sreg:
+				// No-op
+				break;
+			}
+		}
+		svcfree(svc);
+	}
+}
+
+void
+publish(Service *s, char *srv)
+{
+	char buf[128];
+	int f, fd;
+	char *dest;
+
+	/* TODO: stat first and bail before we double dial/create */
+
+	/* Dial */
+	dest = netmkaddr(s->address, 0, "9fs");
+	fd = dial(dest, 0, 0, 0);
+	if(fd < 0)
+		return;
+	f = create(srv, OWRITE, 0666);
+	if(f < 0)
+		return;
+	/* Publish fd from dial */
+	sprint(buf, "%d", fd);
+	write(f, buf, strlen(buf));
+	close(f);
+}
--- a/query.c
+++ b/query.c
@@ -33,11 +33,7 @@
 		if(s->next != nil)
 			print("\n");
 	}
-	for(s = svcs; s;){
-		svcs = s->next;
-		free(s);
-		s = svcs;
-	}
+	svcfree(svcs);
 }
 
 void