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){--
⑨