commit a70c58bebb03f441e1f4c2c2bdd4ac7a139797db
parent df30786a6cc4c3dc986fac071cebc27ddd89ebd4
Author: rpa <rpa@laika>
Date: Sun, 19 Feb 2023 13:51:48 +0000
wdb/srv: move to keyval directory
Diffstat:
4 files changed, 271 insertions(+), 178 deletions(-)
diff --git a/src/keyval/mkfile b/src/keyval/mkfile
@@ -0,0 +1,5 @@
+</$objtype/mkfile
+BIN=
+TARG=srv
+OFILES=srv.$O
+</sys/src/cmd/mkone
diff --git a/src/keyval/srv.c b/src/keyval/srv.c
@@ -0,0 +1,265 @@
+#include <u.h>
+#include <libc.h>
+#include <regexp.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+enum {
+ BufSize = 8192,
+ FauxSize = BufSize,
+ MetaSize = 256,
+ KeySize = MetaSize - 6,
+};
+
+typedef struct Key Key;
+typedef struct Val Val;
+typedef struct Keyval Faux;
+typedef struct Keyval Keyval;
+
+struct Val {
+ long n;
+ char *p;
+};
+
+struct Key {
+ char key[KeySize];
+ Val val;
+ Key *next;
+};
+
+struct Keyval {
+ u16int count, op, reserved;
+ char key[KeySize];
+ char data[BufSize - MetaSize];
+};
+
+void usage(void);
+void keyval(void);
+int eval(char *buf, int n);
+
+void ctl_open(Req *r);
+void ctl_read(Req *r);
+void ctl_write(Req *r);
+void ctl_destroyfid(Fid *fid);
+
+void * allocfaux(void);
+void freefaux(void *v);
+
+int fd, pd[2];
+Key *keyp;
+char *serv = "wdb";
+char *mnt = "/mnt/wdb";
+
+Reprog *reg;
+Srv fs = {
+ .open = ctl_open,
+ .read = ctl_read,
+ .write = ctl_write,
+ .destroyfid = ctl_destroyfid,
+};
+
+void
+main(int argc, char **argv)
+{
+ ARGBEGIN{
+ case 'D':
+ chatty9p++;
+ break;
+ case 's':
+ serv = EARGF(usage());
+ break;
+ case 'm':
+ mnt = EARGF(usage());
+ break;
+ default:
+ usage();
+ }ARGEND
+
+ if (argc != 0) usage();
+
+ fs.tree = alloctree("keyval", "keyval", 0555, nil);
+ createfile(fs.tree->root, "ctl", "keyval", DMAPPEND|0666, nil);
+
+ postmountsrv(&fs, serv, mnt, MREPL);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [-s name] [-m path]\n", argv0);
+ exits("usage");
+}
+
+void
+keyval(void)
+{
+ int n;
+ char buf[BufSize];
+ for (;;) {
+ memset(buf, 0, BufSize);
+ n = read(pd[1], buf, BufSize);
+ n = eval(buf, n);
+ if (write(pd[1], buf, n) < n) break;
+ }
+ fprint(2, "%r\n");
+}
+
+Key *
+findkey(Key *root, char *key)
+{
+ Key *kp;
+ for (kp = root; kp != nil; kp = kp->next) {
+ if (strncmp(key, kp->key, KeySize) == 0) return kp;
+ }
+ return nil;
+}
+
+int
+setkey(Key **root, char *key, char *p, int n)
+{
+ Key *k = findkey(*root, key);
+ if (k == nil) {
+ k = mallocz(sizeof(Key), 1);
+ strncpy(k->key, key, KeySize);
+ k->next = *root;
+ *root = k;
+ } else if (k->val.p != nil) {
+ free(k->val.p);
+ }
+ if (k == nil) return -1;
+ k->val.n = n;
+ k->val.p = mallocz(n, 1);
+ if (k->val.p == nil) return -1;
+ memcpy(k->val.p, p, n);
+ return 0;
+}
+
+Val *
+getkey(Key *root, char *key)
+{
+ Key *k = findkey(root, key);
+ if (k == nil) return nil;
+ return &(k->val);
+}
+
+int
+keyreg(char *buf, Key *kp, Reprog *reg)
+{
+ int n;
+ char *bp = buf;
+ bp += sprint(bp, "ok ");
+ for(n = 0; kp != nil; kp = kp->next) {
+ if (regexec(reg, kp->key, nil, 0) == 1) {
+ n++;
+ bp += snprint(bp, BufSize - (bp - buf), "%s ", kp->key);
+ }
+ }
+ bp[-1] = '\0';
+ return n;
+}
+
+int
+valreg(char *buf, Key *kp, Reprog *reg)
+{
+ int n;
+ char *bp = buf;
+ bp += sprint(bp, "ok ");
+ for(n = 0; kp != nil; kp = kp->next) {
+ if (regexec(reg, kp->val.p, nil, 0) == 1) {
+ n++;
+ bp += snprint(bp, BufSize - (bp - buf), "%s ", kp->key);
+ }
+ }
+ bp[-1] = '\0';
+ return n;
+}
+
+int
+eval(char *buf, int n)
+{
+ char *args[3], *act, *key, *data;
+ for (; n > 0; buf++, n--) if (strchr(" \t\n", buf[0]) == nil) break;
+ if (n <= 0) return 0;
+ if (buf[0] == '\n') return 0;
+ if (getfields(buf, args, 3, 1, " \t\n") < 2) return sprint(buf, "error malformed message");
+ act = args[0], key = args[1], data = args[2];
+ if (strlen(act) >= 8) return sprint(buf, "error bad command");
+ if (strlen(key) >= KeySize) return sprint(buf, "error bad key");
+ if (strncmp(act, "store", 8) == 0) {
+ if (setkey(&keyp, key, data, data - buf + n) != 0) {
+ return sprint(buf, "error store failed");
+ } else {
+ return sprint(buf, "ok %s", key);
+ }
+ }
+ if (strncmp(act, "fetch", 8) == 0) {
+ Val *v = getkey(keyp, key);
+ if (v == nil) {
+ return sprint(buf, "nil %s", key);
+ } else {
+ return sprint(buf, "ok %s %s", key, v->p);
+ }
+ }
+ if (strncmp(act, "valreg", 8) == 0) {
+ reg = regcompnl(args[1]);
+ if (reg == nil) return sprint(buf, "error bad regex");
+ if (valreg(buf, keyp, reg) == 0) return sprint(buf, "nil");
+ return strlen(buf);
+ }
+ if (strncmp(act, "keyreg", 8) == 0) {
+ reg = regcompnl(args[1]);
+ if (reg == nil) return sprint(buf, "error bad regex");
+ if (keyreg(buf, keyp, reg) == 0) return sprint(buf, "nil");
+ return strlen(buf);
+ }
+ return sprint(buf, "error unknown command");
+}
+
+void ctl_read(Req *r)
+{
+ if (r->fid->aux == nil) {
+ sysfatal("aux is nil");
+ }
+ int count;
+ Faux *faux = r->fid->aux;
+ count = (r->ifcall.count > faux->count) ? faux->count : r->ifcall.count;
+ memcpy(r->ofcall.data, faux, count);
+ r->ofcall.count = count;
+ respond(r, nil);
+}
+
+void ctl_write(Req *r)
+{
+ if (r->fid->aux == nil) {
+ sysfatal("aux is nil");
+ }
+ respond(r, nil);
+}
+
+void ctl_open(Req *r)
+{
+ r->fid->aux = allocfaux();
+ respond(r, nil);
+}
+
+void ctl_destroyfid(Fid *fid)
+{
+ if (fid->aux == nil) {
+ sysfatal("aux is nil");
+ }
+ freefaux(fid->aux);
+}
+
+void *
+allocfaux(void)
+{
+ void *v = mallocz(FauxSize, 1);
+ return v;
+}
+
+void
+freefaux(void *v)
+{
+ free(v);
+}
diff --git a/src/wdb/mkfile b/src/wdb/mkfile
@@ -1,5 +1,5 @@
</$objtype/mkfile
-TARG=search srv
+TARG=search
HFILES=wdb.h util.h
OFILES=util.$O
</sys/src/cmd/mkmany
diff --git a/src/wdb/srv.c b/src/wdb/srv.c
@@ -1,177 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <regexp.h>
-// #include <fcall.h>
-// #include <9p.h>
-
-enum {
- BufSize = 8192,
- KeySize = 256,
-};
-
-typedef struct Key Key;
-typedef struct Val Val;
-
-struct Val {
- long n;
- char *p;
-};
-
-struct Key {
- char key[KeySize];
- Val val;
- Key *next;
-};
-
-int fd, pd[2];
-Key *keyp;
-
-void keyval(void);
-int eval(char *buf, int n);
-Reprog *reg;
-
-void
-main(int, char **)
-{
- pipe(pd);
- fd = create("/srv/wdb", OWRITE, 0666);
- fprint(fd, "%d", pd[0]);
- close(fd);
- close(pd[0]);
- close(0);
- close(1);
- switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG|RFREND)) { // TODO: double check flags
- case -1:
- fprint(2, "%r\n");
- exits("fork");
- break;
- case 0:
- keyval();
- break;
- }
-}
-
-void
-keyval(void)
-{
- int n;
- char buf[BufSize];
- for (;;) {
- memset(buf, 0, BufSize);
- n = read(pd[1], buf, BufSize);
- n = eval(buf, n);
- if (write(pd[1], buf, n) < n) break;
- }
- fprint(2, "%r\n");
-}
-
-Key *
-findkey(Key *root, char *key)
-{
- Key *kp;
- for (kp = root; kp != nil; kp = kp->next) {
- if (strncmp(key, kp->key, KeySize) == 0) return kp;
- }
- return nil;
-}
-
-int
-setkey(Key **root, char *key, char *p, int n)
-{
- Key *k = findkey(*root, key);
- if (k == nil) {
- k = mallocz(sizeof(Key), 1);
- strncpy(k->key, key, KeySize);
- k->next = *root;
- *root = k;
- } else if (k->val.p != nil) {
- free(k->val.p);
- }
- if (k == nil) return -1;
- k->val.n = n;
- k->val.p = mallocz(n, 1);
- if (k->val.p == nil) return -1;
- memcpy(k->val.p, p, n);
- return 0;
-}
-
-Val *
-getkey(Key *root, char *key)
-{
- Key *k = findkey(root, key);
- if (k == nil) return nil;
- return &(k->val);
-}
-
-int
-keyreg(char *buf, Key *kp, Reprog *reg)
-{
- int n;
- char *bp = buf;
- bp += sprint(bp, "ok ");
- for(n = 0; kp != nil; kp = kp->next) {
- if (regexec(reg, kp->key, nil, 0) == 1) {
- n++;
- bp += snprint(bp, BufSize - (bp - buf), "%s ", kp->key);
- }
- }
- bp[-1] = '\0';
- return n;
-}
-
-int
-valreg(char *buf, Key *kp, Reprog *reg)
-{
- int n;
- char *bp = buf;
- bp += sprint(bp, "ok ");
- for(n = 0; kp != nil; kp = kp->next) {
- if (regexec(reg, kp->val.p, nil, 0) == 1) {
- n++;
- bp += snprint(bp, BufSize - (bp - buf), "%s ", kp->key);
- }
- }
- bp[-1] = '\0';
- return n;
-}
-
-int
-eval(char *buf, int n)
-{
- char *args[3], *act, *key, *data;
- for (; n > 0; buf++, n--) if (strchr(" \t\n", buf[0]) == nil) break;
- if (n <= 0) return 0;
- if (buf[0] == '\n') return 0;
- if (getfields(buf, args, 3, 1, " \t\n") < 2) return sprint(buf, "error malformed message");
- act = args[0], key = args[1], data = args[2];
- if (strlen(act) >= 8) return sprint(buf, "error bad command");
- if (strlen(key) >= KeySize) return sprint(buf, "error bad key");
- if (strncmp(act, "store", 8) == 0) {
- if (setkey(&keyp, key, data, data - buf + n) != 0) {
- return sprint(buf, "error store failed");
- } else {
- return sprint(buf, "ok %s", key);
- }
- }
- if (strncmp(act, "fetch", 8) == 0) {
- Val *v = getkey(keyp, key);
- if (v == nil) {
- return sprint(buf, "nil %s", key);
- } else {
- return sprint(buf, "ok %s %s", key, v->p);
- }
- }
- if (strncmp(act, "valreg", 8) == 0) {
- reg = regcompnl(args[1]);
- if (reg == nil) return sprint(buf, "error bad regex");
- if (valreg(buf, keyp, reg) == 0) return sprint(buf, "nil");
- return strlen(buf);
- }
- if (strncmp(act, "keyreg", 8) == 0) {
- reg = regcompnl(args[1]);
- if (reg == nil) return sprint(buf, "error bad regex");
- if (keyreg(buf, keyp, reg) == 0) return sprint(buf, "nil");
- return strlen(buf);
- }
- return sprint(buf, "error unknown command");
-}