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);
}