shithub: svcfs

Download patch

ref: f7ca9ea5d0072096857c116b42c77036344677a4
parent: d41d7a57904b372d1be5521f07be41aacb200817
author: Michael Misch <michaelmisch1985@gmail.com>
date: Sat Jun 15 18:58:10 EDT 2024

Start wiring together the client and server in with the buffers

--- a/alt.h
+++ b/alt.h
@@ -3,13 +3,19 @@
 
 struct Buffer
 {
-	char	title[256];
-	char	status[256];
+	char	*name;
+	char	*title;
+	char	*status;
 	char	*aside;
 	int	fd;
+	long	offset;
 	Notify	*notify;
-	// callback function from server for processing input
+
 	Buffer	*next;
+
+	// Passed by the service
+	void	(*input)(char*);
+	char	*(*ctl)(char*, char*);
 };
 
 struct Notify
@@ -17,6 +23,12 @@
 	char	*data;
 	Notify	*next;
 };
+
+Buffer *bufferCreate(void(*fn)(char*), char*(*fn)(char*, char*));
+Buffer *bufferSearch(Buffer*, char*);
+char *bufferDrop(Buffer*, char*);
+char *bufferPush(Buffer*, char*);
+void bufferDestroy(Buffer*);
 
 void* emalloc(int);
 char* estrdup(char*);
--- a/buffer.c
+++ b/buffer.c
@@ -1,0 +1,82 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+#include "alt.h"
+
+static void
+bufferFree(Buffer *match)
+{
+	if(match->name)
+		free(match->name);
+	free(match);
+}
+
+char *
+bufferDrop(Buffer *base, char *name)
+{
+	Buffer *mp, *bp;
+	for(bp = base; bp->next; bp = bp->next){
+		mp = bp->next;
+		if(strcmp(bp->next->name, name) == 0){
+			if(mp && mp->next)
+				bp->next = mp->next;
+			else
+				bp->next = nil;
+			if(mp)
+				bufferFree(mp);
+		}
+	}
+				
+	return nil;
+}
+
+char *
+bufferPush(Buffer *base, char *name)
+{
+	Buffer *b, *ep;
+
+	for(ep = base; ep->next; ep = ep->next){
+		if(ep && strcmp(ep->name, name) == 0)
+			return "buffer exists";
+		if(ep->next == nil)
+			break;
+	}
+	
+	b = emalloc(sizeof(*b));
+	b->name = estrdup(name);
+	b->notify = nil;
+	b->input = base->input;
+	ep->next = b;
+
+	return nil;
+}
+
+Buffer *
+bufferSearch(Buffer *base, char *name)
+{
+	Buffer *sp;
+
+	for(sp = base; sp; sp = sp->next)
+		if(strcmp(sp->name, name) == 0)
+			return sp;
+	return nil;
+}
+
+Buffer*
+bufferCreate(void (*input)(char*), char *(*ctl)(char*, char*))
+{
+	Buffer *b;
+
+	b = emalloc(sizeof(*b));
+	b->name = "root";
+	b->input = input;
+	b->ctl = ctl;
+	b->notify = nil;
+	b->next = nil;
+
+	return b;
+}
+
--- a/client.c
+++ b/client.c
@@ -53,7 +53,7 @@
 static int time0;
 
 static Client*
-newclient(void)
+newclient(char *aname)
 {
 	Client *cl;
 	int i;
@@ -68,7 +68,7 @@
 	cl = &client[i];
 	cl->ref++;
 
-	cl->current = nil;
+	cl->current = bufferSearch(root, aname);;
 	cl->showmarkdown = 0;
 
 	return cl;
@@ -122,14 +122,8 @@
 {
 	Clfid *f;
 
-	// TODO: We want to actually use the aname here
-	if(r->ifcall.aname && r->ifcall.aname[0]){
-		print(r->ifcall.aname);
-		// TODO: Check and establish buffer, abort if it's not available
-	} else {
-		// TODO: If we have any valid buffers, we take the top of the list here
-	}
 	f = emalloc(sizeof(*f));
+	f->cl = newclient(r->ifcall.aname);
 	f->level = Qcroot;
 	clmkqid(&r->fid->qid, f->level, nil);
 	r->ofcall.qid = r->fid->qid;
@@ -193,8 +187,14 @@
 void
 clopen(Req *r)
 {
+	Clfid *f;
+
+	f = r->fid->aux;
+	if(f->level == Qfeed){
+		// open the actual backing file
+		// don't double open if already open though.
+	}
 	respond(r, nil);
-	// Use feed for fid, with offset as well.
 }
 
 static int
@@ -212,6 +212,7 @@
 clread(Req *r)
 {
 	Clfid *f;
+	char buf[1024];
 
 	f = r->fid->aux;
 	switch(f->level){
@@ -219,7 +220,19 @@
 		dirread9p(r, rootgen, f->cl);
 		respond(r, nil);
 		return;
+	case Qtitle:
+		if(f->cl->current){
+			snprint(buf, sizeof(buf), "%s", f->cl->current->title);
+			readstr(r, buf);
+			respond(r, nil);
+		} else
+			respond(r, "no buffer selected");
+		return;
+	//case Qstatus:
+	//case Qaside:
+	//case Qnotify:
 	//case Qfeed:
+		// return a pread with our offset on our open fid
 	}
 	respond(r, "not implemented");
 }
@@ -227,8 +240,38 @@
 void
 clwrite(Req *r)
 {
-	// TODO: Input, ctl
-	respond(r, nil);
+	Clfid *f;
+	char *s, *t;
+	int n;
+
+	f = r->fid->aux;
+	switch(f->level){
+	case Qctl:
+		n = r->ofcall.count = r->ifcall.count;
+		s = emalloc(n+1);
+		memmove(s, r->ifcall.data, n);
+		t = strtok(s, " ");
+		s = strtok(nil, "\n");
+		if(strcmp(t, "buffer") == 0){
+			f->cl->current = bufferSearch(root, s);
+			r->fid->aux = f;
+			respond(r, nil);
+		} else
+			respond(r, root->ctl(t, s));
+		return;
+	case Qinput:
+		if(!f->cl || !f->cl->current){
+			respond(r, "No buffer selected");
+			return;
+		}
+		n = r->ofcall.count = r->ifcall.count;
+		s = emalloc(n+1);
+		memmove(s, r->ifcall.data, n);
+		f->cl->current->input(s);
+		respond(r, nil);
+		return;
+	}
+	respond(r, "not implemented");
 }
 
 void
@@ -253,6 +296,8 @@
 void
 clstart(Srv *s)
 {
+	root = emalloc(sizeof(*root));
+	USED(root);
 	root = (Buffer*)s->aux;
 	time0 = time(0);
 }
--- a/service.c
+++ b/service.c
@@ -75,10 +75,9 @@
 	if(i == nservice)
 		nservice++;
 	svc = &service[i];
-	svc->ref++;
 
-	// TODO: Instantiate a proper base
-	svc->base = nil;
+	svc->ref++;
+	svc->base = bufferCreate(nil, nil);
 	svc->isInitialized = 0;
 	
 	return svc;
@@ -300,11 +299,44 @@
 	respond(r, "not implemented");
 }
 
+static char*
+svcctl(Service *svc, char *s, char *data)
+{
+	// Hashing the buffername would be nice
+	Buffer *b;
+	char *cmd, *targ;
+
+	cmd = strtok(s, " ");
+	targ = strtok(nil, "\n");
+	if(strcmp(cmd, "feed")==0) {
+		// Updoot teh feedfile
+	} else if(strcmp(cmd, "status")==0){
+		if(b = bufferSearch(svc->base, targ)) {
+			b->status = data;
+			return nil;
+		}
+		return "buffer not found";
+	} else if(strcmp(cmd, "title")==0){
+		if(b = bufferSearch(svc->base, targ)) {
+			b->title = data;
+			return nil;
+		}
+		return "buffer not found";
+	} 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";
+	return nil;
+}
+
 void
 svcwrite(Req *r)
 {
 	int n;
-	char *s;
+	char *s, *t;
 	Svcfid *f;
 
 	f = r->fid->aux;
@@ -313,16 +345,19 @@
 		n = r->ofcall.count = r->ifcall.count;
 		s = emalloc(n+1);
 		memmove(s, r->ifcall.data, n);
+		while(n > 0 && strchr("\r\n", s[n-1]))
+			n--;
 		s[n] = 0;
-		if(n > 0 && s[n-1] == '\n')
-			s[n-1] = 0;
 		if(f->svc->isInitialized){
-			print("Command: %s\n", s);
-			
-			respond(r, nil);
+			t = s;
+			while(*t && strchr("\t\r\n", *t)==0)
+				t++;
+			while(*t && strchr("\t\r\n", *t))
+				*t++ = 0;
+			t = svcctl(f->svc, s, t);
+			respond(r, t);
 		} else {
 			f->svc->name = estrdup(s);
-			// TODO: Buffers will have an input cb from the server
 			clfs.aux = f->svc->base;
 			f->svc->childpid = threadpostsrv(&clfs, s);
 			if(f->svc->childpid >= 0){
--