shithub: svcfs

Download patch

ref: ac8357cd7d1798635ba95091029d9d3188743db6
parent: 3d0b6a15a45a2ec0afca34ce8d9041735be42513
author: Michael Misch <michaelmisch1985@gmail.com>
date: Mon Jun 17 08:53:05 EDT 2024

Wire up everything except for tabs/notifications

--- a/TODO
+++ b/TODO
@@ -15,7 +15,8 @@
 
 ### TODO: 
 
-- Add in command to toggle markup 
+- Add in command to toggle markup
+- Blocking reads for feed, potentially a cb to clear out unread counts
 
 ## Service
 
@@ -29,7 +30,6 @@
 
 ### TODO
 
-- handle `input` and `ctl` callbacks!
 - Add a stats/info file to root of /mnt/alt
 
 ## Notifications:
@@ -39,5 +39,5 @@
 
 ## Tabs:
 
-- Track unread from clients
+- list available buffers with unread counts, add notify `!` when applicable
 - Install fmt for printing
--- a/alt.h
+++ b/alt.h
@@ -8,13 +8,10 @@
 	char	status[1024];
 	char	aside[1024];
 	int	fd;
+	Channel	*cmds;
 	Notify	*notify;
 
 	Buffer	*next;
-
-	// Passed by the service
-	void	(*input)(char*);
-	char	*(*ctl)(char*, char*);
 };
 
 struct Notify
@@ -23,7 +20,7 @@
 	Notify	*next;
 };
 
-Buffer *bufferCreate(void(*fn)(char*), char*(*fn)(char*, char*));
+Buffer *bufferCreate(Channel*);
 Buffer *bufferSearch(Buffer*, char*);
 char *bufferDrop(Buffer*, char*);
 char *bufferPush(Buffer*, char*);
--- a/buffer.c
+++ b/buffer.c
@@ -49,7 +49,6 @@
 	b = emalloc(sizeof(*b));
 	b->name = estrdup(name);
 	b->notify = nil;
-	b->input = base->input;
 	memset(b->title, 0, sizeof(b->title));
 	memset(b->status, 0, sizeof(b->status));
 	memset(b->aside, 0, sizeof(b->aside));
@@ -76,14 +75,16 @@
 }
 
 Buffer*
-bufferCreate(void (*input)(char*), char *(*ctl)(char*, char*))
+bufferCreate(Channel *cmds)
 {
 	Buffer *b;
 
 	b = emalloc(sizeof(*b));
-	b->name = nil;;
-	b->input = input;
-	b->ctl = ctl;
+	b->name = nil;
+	memset(b->title, 0, sizeof(b->title));
+	memset(b->status, 0, sizeof(b->status));
+	memset(b->aside, 0, sizeof(b->aside));
+	b->cmds = cmds;
 	b->notify = nil;
 	b->next = nil;
 
--- a/client.c
+++ b/client.c
@@ -47,7 +47,6 @@
 
 	Buffer	*current;
 	int	fd;
-	int	offset;
 	int	showmarkdown;
 };
 
@@ -72,7 +71,7 @@
 	cl = &client[i];
 	cl->ref++;
 
-	cl->current = bufferSearch(root, aname);;
+	cl->current = bufferSearch(root, aname);
 	cl->showmarkdown = 0;
 
 	return cl;
@@ -211,6 +210,7 @@
 	Clfid *f;
 	Notify *np;
 	char buf[1024];
+	int n;
 
 	f = r->fid->aux;
 	switch(f->level){
@@ -219,10 +219,13 @@
 		respond(r, nil);
 		return;
 	case Qfeed:
-		memset(buf, 0, sizeof(buf));
-		pread(f->cl->fd, buf, sizeof(buf), f->cl->offset);
-String:
-		readstr(r, buf);
+		// TODO: We could read a channel here and not respond until we have new data
+		// This currently does not block for input, but we want it to
+		n = pread(f->cl->fd, buf, sizeof(buf), r->ifcall.offset);
+		if(n){
+			r->ofcall.count = n - 1;
+			memmove(r->ofcall.data, buf, r->ofcall.count);
+		}
 		respond(r, nil);
 		return;
 	case Qtitle:
@@ -229,7 +232,10 @@
 		if(f->cl->current && f->cl->current->title){
 			memset(buf, 0, sizeof(buf));
 			snprint(buf, sizeof(buf), "%s", f->cl->current->title);
-			goto String;
+String:
+			readstr(r, buf);
+			respond(r, nil);
+			return;	
 		}
 	case Qstatus:
 		if(f->cl->current && f->cl->current->status){
@@ -247,7 +253,7 @@
 		if(f->cl->current && f->cl->current->notify){
 			memset(buf, 0, sizeof(buf));
 			for(np = f->cl->current->notify; np->next; np = np->next)
-				// TODO: Really test this out. this likely overwrites what we have
+				// TODO: Move to fmt specifier for these
 				snprint(buf, sizeof(buf), "%s\n", np->data);
 			goto String;
 		}
@@ -283,11 +289,14 @@
 			memset(path, sizeof(path), 0);
 			snprint(path, sizeof(path), "%s/%s/%s", logdir, root->name, s);
 			f->cl->fd = open(path, OREAD);
-			f->cl->offset = 0;
 			r->fid->aux = f;
 			respond(r, nil);
-		} else
-			respond(r, root->ctl(t, s));
+		} else {
+			snprint(path, sizeof(path), "%s %s", t, s);
+			send(root->cmds, path);
+			// TODO: We will rcv a response
+			respond(r, nil);
+		}
 		return;
 	case Qinput:
 		if(!f->cl || !f->cl->current){
@@ -295,9 +304,9 @@
 			return;
 		}
 		n = r->ofcall.count = r->ifcall.count;
-		s = emalloc(n+1);
-		memmove(s, r->ifcall.data, n);
-		f->cl->current->input(s);
+		n += strlen(f->cl->current->name) + 7;
+		snprint(path, n, "input %s\n%s", f->cl->current->name, r->ifcall.data);
+		send(root->cmds, path);
 		respond(r, nil);
 		return;
 	}
--- a/service.c
+++ b/service.c
@@ -52,6 +52,7 @@
 {
 	Ref;
 
+	Channel	*cmds;
 	Buffer	*base;
 	char	*name;
 	int	isInitialized;
@@ -77,7 +78,11 @@
 	svc = &service[i];
 
 	svc->ref++;
-	svc->base = bufferCreate(nil, nil);
+	// TODO: Eventually create send and receive for return a string from commands
+	// NOTE: If you're sending more commands than this before they are processed, up this number
+	// But also it might be time to question your design, because commands really should not be taking long
+	svc->cmds = chancreate(1024, 16);
+	svc->base = bufferCreate(svc->cmds);
 	svc->isInitialized = 0;
 	
 	return svc;
@@ -88,6 +93,7 @@
 {
 	if(s == nil)
 		return;
+	chanfree(s->cmds);
 	memset(s, 0, sizeof(*s));
 }
 
@@ -293,10 +299,17 @@
 		return;
 	case Qctl:
 		memset(buf, 0, sizeof(buf));
-		snprint(buf, sizeof(buf), "%d\n", SERVICEID(f->svc));
-		readstr(r, buf);
+		// NOTE: This stays here so we always get a good ID back on the client from the initial read
+		if(!f->svc->isInitialized) {
+			snprint(buf, sizeof(buf), "%d\n", SERVICEID(f->svc));
+			readstr(r, buf);
+		} else {
+			recv(f->svc->cmds, buf);
+			print("%s\n", buf);
+		}
 		respond(r, nil);
 		return;
+
 	}
 	respond(r, "not implemented");
 }
@@ -319,35 +332,37 @@
 		return "buffer not found";
 	} else if(strcmp(cmd, "status")==0){
 		if(b = bufferSearch(svc->base, targ)) {
-			b->status = data;
+			strcpy(b->status, data);
 			return nil;
 		}
 		return "buffer not found";
 	} else if(strcmp(cmd, "title")==0){
 		if(b = bufferSearch(svc->base, targ)) {
-			b->title = data;
+			strcpy(b->title, data);
 			return nil;
 		}
 		return "buffer not found";
 	} else if(strcmp(cmd, "status")==0){
 		if(b = bufferSearch(svc->base, targ)) {
-			b->status = data;
+			strcpy(b->status, data);
 			return nil;
 		}
 		return "buffer not found";
 	} else if(strcmp(cmd, "aside")==0){
 		if(b = bufferSearch(svc->base, targ)) {
-			b->aside = data;
+			strcpy(b->aside, data);
 			return nil;
 		}
 		return "buffer not found";
+	} else if(strcmp(cmd, "notify")==0){
+		// Create notification here
+		return "not yet implemented";
 	} else if(strcmp(cmd, "create")==0)
 		return bufferPush(svc->base, targ);
 	else if(strcmp(cmd, "close")==0)
 		return bufferDrop(svc->base, targ);
-	else
-		// snprintf not found: %s cmd
-		return "command not found";
+	else 
+		return "command not supported";
 }
 
 void
@@ -408,8 +423,8 @@
 	Svcfid *f;
 
 	if(f = fid->aux){
-		//if(f->svc && f->svc->childpid)
-		//	postnote(PNGROUP, f->svc->childpid, "shutdown");
+		if(f->svc && f->svc->childpid)
+			postnote(PNGROUP, f->svc->childpid, "shutdown");
 		// TODO: Uncomment this after we are good to go, this is our keepalive roughly
 		//fid->aux = nil;
 		//if(f->svc)
--