ref: f96a13204b5f5910880b73bc1747b40d42d2755f
parent: f7c354bfa6b8cffe2ce4880712decd29a4f22106
author: Michael Misch <michaelmisch1985@gmail.com>
date: Sat Aug 10 00:03:27 EDT 2024
Updates found while integrating
--- a/alt.h
+++ b/alt.h
@@ -1,13 +1,34 @@
typedef struct Buffer Buffer;
typedef struct Notify Notify;
+typedef struct Cmd Cmd;
+enum
+{+ CloneCmd,
+ CreateCmd,
+ DeleteCmd,
+ RemoveCmd,
+ NotifyCmd,
+ ErrorCmd,
+ StatusCmd,
+ SideCmd,
+ NavCmd,
+ TitleCmd,
+ ImageCmd,
+ FeedCmd,
+ QuitCmd,
+ ServiceCmd,
+
+ MaxBuflen = 256,
+};
+
struct Buffer
{QLock l;
- char *name;
+ char name[MaxBuflen];
char title[1024];
char status[1024];
- char aside[1024];
+ char *aside;
int fd; // feed
int tag; // feed
int unread;
@@ -23,6 +44,15 @@
Notify *next;
};
+struct Cmd
+{+ // Potentially big
+ int type;
+ char buffer[MaxBuflen];
+ char data[2048];
+ char svccmd[256];
+};
+
Buffer *bufferCreate(Channel*);
Buffer *bufferSearch(Buffer*, char*);
Buffer *bufferSearchTag(Buffer*, ulong);
@@ -42,6 +72,7 @@
char *logdir;
int debug;
+Cmd* convS2C(char*);
void clattach(Req*);
void clstat(Req*);
char *clwalk1(Fid*, char*, Qid*);
--- a/buffer.c
+++ b/buffer.c
@@ -51,14 +51,11 @@
}
b = mallocz(sizeof(*b), 1);
- b->name = estrdup(name);
+ strcpy(b->name, name);
b->notify = nil;
b->unread = 0;
b->tag = -1;
b->rz.l = &b->l;
- memset(b->title, 0, sizeof(b->title));
- memset(b->status, 0, sizeof(b->status));
- memset(b->aside, 0, sizeof(b->aside));
snprint(p, sizeof(p), "%s/%s/%s", logdir, base->name, name);
if(access(p, 0) == 0)
b->fd = open(p, OWRITE);
@@ -104,10 +101,6 @@
Buffer *b;
b = mallocz(sizeof(*b), 1);
- 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->tag = -1;
b->unread = 0;
--- a/client.c
+++ b/client.c
@@ -343,7 +343,7 @@
f->cl->current = b;
b->tag = r->tag;
qunlock(&b->l);
- memset(path, sizeof(path), 0);
+ memset(path, 0, sizeof(path));
snprint(path, sizeof(path), "%s/%s/%s", logdir, root->name, s);
f->cl->fd = open(path, OREAD);
r->fid->aux = f;
@@ -361,9 +361,8 @@
respond(r, nil);
} else {snprint(path, sizeof(path), "%s %s", t, s);
- srvrelease(fs);
send(root->cmds, path);
- srvacquire(fs);
+ send(root->cmds, nil);
respond(r, nil);
}
return;
@@ -373,10 +372,13 @@
return;
}
n = r->ofcall.count = r->ifcall.count;
- n += strlen(f->cl->current->name) + 7;
- snprint(path, n, "input %s\n%s", f->cl->current->name, r->ifcall.data);
+ n += strlen(f->cl->current->name) + 8;
+ memset(path, 0, sizeof(path));
+ snprint(path, n, "input %s\n%s\n", f->cl->current->name, r->ifcall.data);
send(root->cmds, path);
+ send(root->cmds, nil);
respond(r, nil);
+
return;
}
respond(r, "not implemented");
--- /dev/null
+++ b/convS2C.c
@@ -1,0 +1,146 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+#include "alt.h"
+
+struct state
+{+ Cmd cmd;
+ char *base;
+ int size;
+ int (*fn)(struct state *s);
+};
+
+static int parse_cmd(struct state *s);
+static int parse_from(struct state *s);
+static int parse_data(struct state *s);
+
+Cmd*
+convS2C(char *c)
+{+ struct state s;
+ Cmd cmd;
+
+ s.fn = (*parse_cmd);
+ s.cmd.type = ErrorCmd;
+ strcpy(s.cmd.data, "An unknown error has occured");
+ s.base = c;
+ s.size = strlen(c);
+ while((s.fn(&s) > 0));
+
+ cmd.type = s.cmd.type;
+ strcpy(cmd.buffer, s.cmd.buffer);
+ strcpy(cmd.data, s.cmd.data);
+ strcpy(cmd.svccmd, s.cmd.svccmd);
+
+ return &cmd;
+}
+
+static int
+parse_cmd(struct state *s)
+{+ int n;
+
+ n = 0;
+ for(;;){+ if(n > s->size)
+ return -1;
+ switch(s->base[n]){+ case '\0':
+ case '\r':
+ case '\n':
+ // Check we aren't at "quit"
+ s->base[n] = '\0';
+ s->cmd.type = CloneCmd;
+ if(strncmp("quit", s->base, n) == 0)+ s->cmd.type = QuitCmd;
+ else
+ strcpy(s->cmd.data, s->base);
+ return 0;
+ case ' ':
+ case '\t':
+ // The overwhelming majority will be feed activity
+ if(strncmp(s->base, "feed", 4) == 0)
+ s->cmd.type = FeedCmd;
+ else if(strncmp(s->base, "aside", 5) == 0)
+ s->cmd.type = SideCmd;
+ else if(strncmp(s->base, "nav", 3) == 0)
+ s->cmd.type = NavCmd;
+ else if(strncmp(s->base, "title", 5) == 0)
+ s->cmd.type = TitleCmd;
+ else if(strncmp(s->base, "image", 5) == 0)
+ s->cmd.type = ImageCmd;
+ else if(strncmp(s->base, "delete", 6) == 0)
+ s->cmd.type = DeleteCmd;
+ else if(strncmp(s->base, "remove", 6) == 0)
+ s->cmd.type = RemoveCmd;
+ else if(strncmp(s->base, "notification", 12) == 0)
+ s->cmd.type = NotifyCmd;
+ else if(strncmp(s->base, "error", 5) == 0)
+ s->cmd.type = ErrorCmd;
+ else if(strncmp(s->base, "status", 6) == 0)
+ s->cmd.type = StatusCmd;
+ else if(strncmp(s->base, "create", 6) == 0)
+ s->cmd.type = CreateCmd;
+ else {+ s->cmd.type = ServiceCmd;
+ strncpy(s->cmd.svccmd, s->base, n);
+ }
+ s->size -= n;
+ n++;
+ s->base += n;
+ s->fn = (*parse_from);
+ return 1;
+ default:
+ n++;
+ }
+ }
+}
+
+static int
+parse_from(struct state *s)
+{+ int n;
+ n = 0;
+ for(;;){+ if(n > s->size || n > MaxBuflen)
+ return -1;
+ switch(s->base[n]){+ // leading spaces/tabs, ignore
+ case ' ':
+ case '\t':
+ // NOTE: This moves our pointer forward so n++ isn't necessary
+ s->size--;
+ s->base++;
+ break;
+ case '\0':
+ strncpy(s->cmd.buffer, s->base, n);
+ return 0;
+ case '\n':
+ case '\r':
+ s->base[n] = '\0';
+ strncpy(s->cmd.buffer, s->base, n+1);
+ // return if we have no data to parse
+ if (n >= s->size)
+ return 0;
+ s->size -=n;
+ n++;
+ s->base += n;
+ s->fn = (*parse_data);
+ return 1;
+ default:
+ n++;
+ }
+ }
+}
+
+static int
+parse_data(struct state *s)
+{+ // We may eventually do some processing here
+ strncpy(s->cmd.data, s->base, s->size);
+ s->cmd.data[s->size] ='\0';
+ return 0;
+}
--- a/mkfile
+++ b/mkfile
@@ -11,6 +11,7 @@
fs.$O\
buffer.$O\
client.$O\
+ convS2C.$O\
service.$O\
notification.$O\
tabs.$O\
--- a/service.c
+++ b/service.c
@@ -300,20 +300,18 @@
memset(buf, 0, sizeof(buf));
// NOTE: This stays here so we always get a good ID back on the client from the initial read
if(!f->svc->isInitialized) {- while(nbrecv(f->svc->cmds, nil) == 1)
- ;
snprint(buf, sizeof(buf), "%d\n", SERVICEID(f->svc));
readstr(r, buf);
respond(r, nil);
} else {+ // Wait for any data/command from the client
srvrelease(fs);
recv(f->svc->cmds, buf);
- if(strcmp(buf, "flush") == 0)
+ srvacquire(fs);
+ if(strcmp(buf, "flush") != 0)
readstr(r, buf);
respond(r, nil);
- srvacquire(fs);
}
-
return;
}
@@ -320,72 +318,16 @@
respond(r, "not implemented");
}
-static char*
-svcctl(Service *svc, char *s, char *data)
-{- // Probably notifications as well?
- Buffer *b;
- Dir *d;
- char *cmd, *targ;
- cmd = strtok(s, " ");
- targ = strtok(nil, "\n");
- if(strcmp(cmd, "feed")==0) { - if(b = bufferSearch(svc->base, targ)) {-print("%s %s %s\n", cmd, targ, data);- qlock(&b->l);
- d = dirfstat(b->fd);
- pwrite(b->fd, data, strlen(data), d->length);
- free(d);
- if(rwakeupall(&b->rz) == 0)
- b->unread++;
- qunlock(&b->l);
- return nil;
- }
- return "buffer not found";
- } else if(strcmp(cmd, "status")==0){- if(b = bufferSearch(svc->base, targ)) {- strcpy(b->status, data);
- return nil;
- }
- return "buffer not found";
- } else if(strcmp(cmd, "title")==0){- if(b = bufferSearch(svc->base, targ)) {- strcpy(b->title, data);
- return nil;
- }
- return "buffer not found";
- } else if(strcmp(cmd, "status")==0){- if(b = bufferSearch(svc->base, targ)) {- strcpy(b->status, data);
- return nil;
- }
- return "buffer not found";
- } else if(strcmp(cmd, "aside")==0){- if(b = bufferSearch(svc->base, targ)) {- 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 if(strcmp(cmd, "error")==0)
- return targ;
- else
- return "command not supported";
-}
-
void
svcwrite(Req *r)
{int n;
- char *s, *t;
Svcfid *f;
+ Cmd *c;
+ Buffer *b;
+ Dir *d;
+ char *p;
char path[1024];
f = r->fid->aux;
@@ -392,36 +334,71 @@
if(f->level == Qctl){n = r->ofcall.count = r->ifcall.count;
- s = mallocz(n+1, 1);
- memmove(s, r->ifcall.data, n);
- while(n > 0 && strchr("\r\n", s[n-1]))- n--;
- s[n] = 0;
- if(f->svc->isInitialized){- t = s;
-print("s in: %s\n", 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);
- f->svc->base->name = estrdup(s);
- memset(path, 0, sizeof(path));
- snprint(path, sizeof(path), "%s/%s", logdir, s);
- close(create(path, OREAD, DMDIR | 0755));
- clfs.aux = f->svc->base;
- f->svc->childpid = threadpostsrv(&clfs, s);
- if(f->svc->childpid >= 0){- f->svc->isInitialized++;
- r->fid->aux = f;
- respond(r, nil);
- } else
- respond(r, "Unable to post to srv");
+ p = mallocz(n+1, 1);
+ memmove(p, r->ifcall.data, n);
+ c = convS2C(p);
+ if(c == nil){+ respond(r, "unable to parse command");
+ return;
}
- free(s);
+ switch(c->type){+ case CloneCmd:
+ if(!f->svc->isInitialized){+ f->svc->name = estrdup(c->data);
+ strcpy(f->svc->base->name, c->data);
+ memset(path, 0, sizeof(path));
+ snprint(path, sizeof(path), "%s/%s", logdir, c->data);
+ close(create(path, OREAD, DMDIR | 0755));
+ clfs.aux = f->svc->base;
+ f->svc->childpid = threadpostsrv(&clfs, strdup(c->data));
+ if(f->svc->childpid >= 0){+ f->svc->isInitialized++;
+ r->fid->aux = f;
+ respond(r, nil);
+ } else
+ respond(r, "Unable to post to srv");
+ return;
+ }
+ // Ignore, something weird going on.
+ respond(r, nil);
+ return;
+ case CreateCmd:
+ respond(r, bufferPush(f->svc->base, c->buffer));
+ return;
+ case NotifyCmd:
+ respond(r, "not implemented yet");
+ return;
+ case DeleteCmd:
+ respond(r, bufferDrop(f->svc->base, c->buffer));
+ return;
+ case ErrorCmd:
+ respond(r, "not implemented yet");
+ return;
+ }
+ if(b = bufferSearch(f->svc->base, c->buffer)) {+ qlock(&b->l);
+ switch(c->type){+ case FeedCmd:
+ d = dirfstat(b->fd);
+ pwrite(b->fd, c->data, strlen(c->data), d->length);
+ free(d);
+ if(rwakeupall(&b->rz) == 0)
+ b->unread++;
+ break;
+ case StatusCmd:
+ strcpy(b->status, c->data);
+ break;
+ case TitleCmd:
+ strcpy(b->title, c->data);
+ break;
+ case SideCmd:
+ strcpy(b->aside, c->data);
+ break;
+ }
+ qunlock(&b->l);
+ respond(r, nil);
+ } else
+ respond(r, "buffer not found");
return;
}
respond(r, "not implemented");
@@ -430,12 +407,11 @@
void
svcflush(Req *r)
{- Buffer *b;
int i;
for(i = 0; i < nservice; i++)
if(service[i].ref > 0)
- if((b = bufferSearchTag(service[i].base, r->tag))){- send(service[i].cmds, "flush");
+ if((bufferSearchTag(service[i].base, r->tag))){+ nbsend(service[i].cmds, "flush");
break;
}
respond(r, nil);
--
⑨