ref: 01098d2f2f2ad421a77beba1793b3e71ed97d0a2
parent: f96a13204b5f5910880b73bc1747b40d42d2755f
author: Michael Misch <michaelmisch1985@gmail.com>
date: Wed Aug 14 22:12:38 EDT 2024
Add in temporary changes to try to load structs in the messages
--- a/alt.h
+++ b/alt.h
@@ -18,8 +18,15 @@
FeedCmd,
QuitCmd,
ServiceCmd,
+ InputCmd,
+ FlushCmd,
+ BufferCmd,
+ MarkdownCmd,
- MaxBuflen = 256,
+ // TODO: Move data to the stack
+ MaxBuflen = 128,
+ MaxDatalen = 1024,
+ CmdSize = MaxBuflen * 2 + 1,
};
struct Buffer
@@ -26,13 +33,14 @@
{QLock l;
char name[MaxBuflen];
- char title[1024];
- char status[1024];
+ char title[512];
+ char status[512];
char *aside;
int fd; // feed
int tag; // feed
int unread;
Channel *cmds;
+ Channel *input;
Notify *notify;
Buffer *next;
Rendez rz;
@@ -49,11 +57,11 @@
// Potentially big
int type;
char buffer[MaxBuflen];
- char data[2048];
- char svccmd[256];
+ char svccmd[MaxBuflen];
+ char *data;
};
-Buffer *bufferCreate(Channel*);
+Buffer *bufferCreate(Channel*, Channel*);
Buffer *bufferSearch(Buffer*, char*);
Buffer *bufferSearchTag(Buffer*, ulong);
char *bufferDrop(Buffer*, char*);
@@ -62,6 +70,7 @@
int Tconv(Fmt*);
int Nconv(Fmt*);
+int Cconv(Fmt*);
void* emalloc(int);
char* estrdup(char*);
@@ -72,7 +81,8 @@
char *logdir;
int debug;
-Cmd* convS2C(char*);
+uint convS2C(Cmd*, char*, uint);
+
void clattach(Req*);
void clstat(Req*);
char *clwalk1(Fid*, char*, Qid*);
--- a/buffer.c
+++ b/buffer.c
@@ -96,12 +96,13 @@
}
Buffer*
-bufferCreate(Channel *cmds)
+bufferCreate(Channel *cmds, Channel *input)
{Buffer *b;
b = mallocz(sizeof(*b), 1);
b->cmds = cmds;
+ b->input = input;
b->tag = -1;
b->unread = 0;
b->notify = nil;
--- a/client.c
+++ b/client.c
@@ -235,6 +235,7 @@
Again:
// Check if we have a tag here, abort early if so.
if(b->tag != flushtag){+ memset(buf, 0, sizeof(buf));
n = pread(f->cl->fd, buf, sizeof(buf), r->ifcall.offset);
if(n > 0){// cut off the EOF
@@ -249,7 +250,6 @@
}
} else
flushtag = -1;
- memset(buf, 0, sizeof(buf));
srvacquire(fs);
respond(r, nil);
return;
@@ -301,7 +301,7 @@
qlock(&root->l);
memset(buf, 0, sizeof(buf));
for(b = root->next; b; b = b->next){- n += snprint(buf + n, sizeof(buf) - n, "%t\n", b);
+ n += snprint(buf + n, sizeof(buf) - n, "%N\n", b);
}
qunlock(&root->l);
goto String;
@@ -317,19 +317,21 @@
{Buffer *b;
Clfid *f;
- char *s, *t, path[1024];
- int n;
+ Cmd cmd;
+ char *s, t[MaxDatalen], path[1024];
f = r->fid->aux;
+
+ s = mallocz(r->ifcall.count, 1);
+ memmove(s, r->ifcall.data, r->ifcall.count);
+
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){- b = bufferSearch(root, s);
+ memset(&cmd, 0, CmdSize);
+ convS2C(&cmd, s, r->ifcall.count);
+ switch(cmd.type){+ case BufferCmd:
+ b = bufferSearch(root, cmd.buffer);
if(!b){respond(r, "No buffers available");
return;
@@ -337,7 +339,7 @@
qlock(&b->l);
if(f->cl->fd){b->tag = flushtag = 1;
- rwakeupall(&b->rz);
+ rwakeup(&b->rz);
close(f->cl->fd);
}
f->cl->current = b;
@@ -344,44 +346,32 @@
b->tag = r->tag;
qunlock(&b->l);
memset(path, 0, sizeof(path));
- snprint(path, sizeof(path), "%s/%s/%s", logdir, root->name, s);
+ snprint(path, sizeof(path), "%s/%s/%s", logdir, root->name, cmd.buffer);
f->cl->fd = open(path, OREAD);
r->fid->aux = f;
- respond(r, nil);
- } else if(strcmp(t, "markdown")==0){- if(f->cl->showmarkdown)
- f->cl->showmarkdown = 0;
- else
- f->cl->showmarkdown = 1;
- r->fid->aux = f;
- respond(r, nil);
- } else if(strcmp(t, "hidemarkdown")==0){- f->cl->showmarkdown = 0;
- r->fid->aux = f;
- respond(r, nil);
- } else {- snprint(path, sizeof(path), "%s %s", t, s);
- send(root->cmds, path);
- send(root->cmds, nil);
- respond(r, nil);
+ goto Out;
+ case MarkdownCmd:
+ f->cl->showmarkdown = !f->cl->showmarkdown;
+ goto Out;
+ default:
+ send(root->cmds, &cmd);
+ goto Out;
}
- return;
case Qinput:
- if(!f->cl || !f->cl->current){+ r->ofcall.count = 0;
+ if(f->cl->current == nil){respond(r, "No buffer selected");
return;
}
- n = r->ofcall.count = r->ifcall.count;
- 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;
+ // Cut off the newline
+ memset(t, 0, MaxDatalen);
+ snprint(t, sizeof(t), "input %s\n%s", f->cl->current->name, r->ifcall.data);
+ send(root->input, t);
}
- respond(r, "not implemented");
+Out:
+ free(s);
+ respond(r, nil);
+ return;
}
void
--- /dev/null
+++ b/cmd.c
@@ -1,0 +1,31 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+#include "alt.h"
+
+int
+Cconv(Fmt *fp)
+{+ char s[CmdSize];
+ Cmd *c;
+
+ c = va_arg(fp->args, Cmd*);
+ switch(c->type){+ case ServiceCmd:
+ if(c->data != nil)
+ snprint(s, sizeof(s), "%s %s\n%s", c->svccmd, c->buffer, c->data);
+ else
+ snprint(s, sizeof(s), "%s %s", c->svccmd, c->buffer);
+ break;
+ case InputCmd:
+ snprint(s, sizeof(s), "input %s\n%s", c->buffer, c->data);
+ break;
+ case FlushCmd:
+ snprint(s, sizeof(s), "flush");
+ break;
+ }
+ return fmtstrcpy(fp, s);
+}
--- a/convS2C.c
+++ b/convS2C.c
@@ -17,25 +17,22 @@
static int parse_from(struct state *s);
static int parse_data(struct state *s);
-Cmd*
-convS2C(char *c)
+uint
+convS2C(Cmd *cmd, char *c, uint n)
{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);
+ s.size = n;
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;
+ cmd->type = s.cmd.type;
+ cmd->data = s.cmd.data;
+ strcpy(cmd->buffer, s.cmd.buffer);
+ strcpy(cmd->svccmd, s.cmd.svccmd);
+ return sizeof(cmd);
}
static int
@@ -57,7 +54,7 @@
if(strncmp("quit", s->base, n) == 0)s->cmd.type = QuitCmd;
else
- strcpy(s->cmd.data, s->base);
+ s->cmd.data = strdup(s->base);
return 0;
case ' ':
case '\t':
@@ -64,26 +61,30 @@
// 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)
+ else if(strncmp(s->base, "asi", 3) == 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)
+ else if(strncmp(s->base, "titl", 4) == 0)
s->cmd.type = TitleCmd;
- else if(strncmp(s->base, "image", 5) == 0)
+ else if(strncmp(s->base, "ima", 3) == 0)
s->cmd.type = ImageCmd;
- else if(strncmp(s->base, "delete", 6) == 0)
+ else if(strncmp(s->base, "del", 3) == 0)
s->cmd.type = DeleteCmd;
- else if(strncmp(s->base, "remove", 6) == 0)
+ else if(strncmp(s->base, "rem", 3) == 0)
s->cmd.type = RemoveCmd;
- else if(strncmp(s->base, "notification", 12) == 0)
+ else if(strncmp(s->base, "noti", 4) == 0)
s->cmd.type = NotifyCmd;
- else if(strncmp(s->base, "error", 5) == 0)
+ else if(strncmp(s->base, "err", 3) == 0)
s->cmd.type = ErrorCmd;
- else if(strncmp(s->base, "status", 6) == 0)
+ else if(strncmp(s->base, "stat", 4) == 0)
s->cmd.type = StatusCmd;
- else if(strncmp(s->base, "create", 6) == 0)
+ else if(strncmp(s->base, "crea", 4) == 0)
s->cmd.type = CreateCmd;
+ else if(strncmp(s->base, "buf", 3) == 0)
+ s->cmd.type = BufferCmd;
+ else if(strncmp(s->base, "mark", 4) == 0)
+ s->cmd.type = MarkdownCmd;
else {s->cmd.type = ServiceCmd;
strncpy(s->cmd.svccmd, s->base, n);
@@ -140,7 +141,6 @@
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;
+ s->cmd.data = strdup(s->base);
+ return 0;
}
--- a/fs.c
+++ b/fs.c
@@ -50,8 +50,9 @@
void
threadmain(int argc, char *argv[])
{- fmtinstall('t', Tconv);+ fmtinstall('N', Tconv); fmtinstall('!', Nconv);+ fmtinstall('C', Cconv);user = getuser();
mtpt = "/mnt/alt";
logdir = "/tmp/alt";
--- a/mkfile
+++ b/mkfile
@@ -2,8 +2,7 @@
BIN=/$objtype/bin/alt
-TARG=\
- fs\
+TARG=fs
HFILES=alt.h
@@ -11,13 +10,11 @@
fs.$O\
buffer.$O\
client.$O\
+ cmd.$O\
convS2C.$O\
service.$O\
notification.$O\
tabs.$O\
-</sys/src/cmd/mkmany
+</sys/src/cmd/mkone
-install:V:
- mkdir -p $BIN
- mk $MKFLAGS fs.install
--- a/service.c
+++ b/service.c
@@ -52,6 +52,7 @@
Ref;
Channel *cmds;
+ Channel *input;
Buffer *base;
char *name;
int isInitialized;
@@ -80,8 +81,9 @@
// 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, 32);
- svc->base = bufferCreate(svc->cmds);
+ svc->cmds = chancreate(sizeof(Cmd*), 8);
+ svc->input = chancreate(sizeof(char*), 8);
+ svc->base = bufferCreate(svc->cmds, svc->input);
svc->isInitialized = 0;
return svc;
@@ -279,14 +281,31 @@
return 0;
}
+enum {+ CmdRead,
+ InputRead,
+};
+
+
void
svcread(Req *r)
{- char buf[1024];
+
+ Cmd cmd;
+ char input[MaxDatalen];
+ char buf[CmdSize];
Svcfid *f;
f = r->fid->aux;
+ memset(buf, 0, CmdSize);
+ Alt a[] = {+ [CmdRead] = { nil, &cmd, CHANRCV },+ [InputRead] = { nil, input, CHANRCV },+ };
+ a[CmdRead].c = f->svc->cmds;
+ a[InputRead].c = f->svc->input;
+
switch(f->level){case Qsroot:
dirread9p(r, rootgen, nil);
@@ -297,7 +316,6 @@
respond(r, nil);
return;
case Qctl:
- 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) {snprint(buf, sizeof(buf), "%d\n", SERVICEID(f->svc));
@@ -306,10 +324,20 @@
} else {// Wait for any data/command from the client
srvrelease(fs);
- recv(f->svc->cmds, buf);
+ memset(&cmd, 0, CmdSize);
+ switch(alt(a)) {+ case CmdRead:
+ if(cmd.type != FlushCmd){+ snprint(buf, sizeof(buf), "%C\n data", &cmd);
+ readstr(r, buf);
+
+ }
+ break;
+ case InputRead:
+ readstr(r, input);
+ break;
+ }
srvacquire(fs);
- if(strcmp(buf, "flush") != 0)
- readstr(r, buf);
respond(r, nil);
}
return;
@@ -324,10 +352,10 @@
{int n;
Svcfid *f;
- Cmd *c;
+ Cmd cmd;
Buffer *b;
Dir *d;
- char *p;
+ char *p, *s;
char path[1024];
f = r->fid->aux;
@@ -334,24 +362,30 @@
if(f->level == Qctl){n = r->ofcall.count = r->ifcall.count;
- p = mallocz(n+1, 1);
+ p = mallocz(n, 1);
memmove(p, r->ifcall.data, n);
- c = convS2C(p);
- if(c == nil){- respond(r, "unable to parse command");
- return;
- }
- switch(c->type){+ convS2C(&cmd, p, n);
+ switch(cmd.type){case CloneCmd:
if(!f->svc->isInitialized){- f->svc->name = estrdup(c->data);
- strcpy(f->svc->base->name, c->data);
+ f->svc->name = estrdup(cmd.data);
+ strcpy(f->svc->base->name, cmd.data);
memset(path, 0, sizeof(path));
- snprint(path, sizeof(path), "%s/%s", logdir, c->data);
+ snprint(path, sizeof(path), "%s/%s", logdir, cmd.data);
close(create(path, OREAD, DMDIR | 0755));
clfs.aux = f->svc->base;
- f->svc->childpid = threadpostsrv(&clfs, strdup(c->data));
+ f->svc->childpid = threadpostsrv(&clfs, strdup(cmd.data));
if(f->svc->childpid >= 0){+ s = emalloc(10+strlen(cmd.data));
+ strcpy(s, "/srv/");
+ strcat(s, cmd.data);
+ d = dirstat(s);
+ d->mode = 0666;
+ if(dirwstat(s, d) < 0){+ respond(r, "unable to set mode");
+ return;
+ }
+ free(s);
f->svc->isInitialized++;
r->fid->aux = f;
respond(r, nil);
@@ -363,36 +397,36 @@
respond(r, nil);
return;
case CreateCmd:
- respond(r, bufferPush(f->svc->base, c->buffer));
+ respond(r, bufferPush(f->svc->base, cmd.buffer));
return;
case NotifyCmd:
respond(r, "not implemented yet");
return;
case DeleteCmd:
- respond(r, bufferDrop(f->svc->base, c->buffer));
+ respond(r, bufferDrop(f->svc->base, cmd.buffer));
return;
case ErrorCmd:
respond(r, "not implemented yet");
return;
}
- if(b = bufferSearch(f->svc->base, c->buffer)) {+ if(b = bufferSearch(f->svc->base, cmd.buffer)) {qlock(&b->l);
- switch(c->type){+ switch(cmd.type){case FeedCmd:
d = dirfstat(b->fd);
- pwrite(b->fd, c->data, strlen(c->data), d->length);
+ pwrite(b->fd, cmd.data, strlen(cmd.data), d->length);
free(d);
if(rwakeupall(&b->rz) == 0)
b->unread++;
break;
case StatusCmd:
- strcpy(b->status, c->data);
+ strcpy(b->status, cmd.data);
break;
case TitleCmd:
- strcpy(b->title, c->data);
+ strcpy(b->title, cmd.data);
break;
case SideCmd:
- strcpy(b->aside, c->data);
+ strcpy(b->aside, cmd.data);
break;
}
qunlock(&b->l);
@@ -407,11 +441,15 @@
void
svcflush(Req *r)
{+ Cmd cmd;
int i;
+
for(i = 0; i < nservice; i++)
if(service[i].ref > 0)
if((bufferSearchTag(service[i].base, r->tag))){- nbsend(service[i].cmds, "flush");
+ memset(&cmd, 0, CmdSize);
+ cmd.type = FlushCmd;
+ send(service[i].cmds, &cmd);
break;
}
respond(r, nil);
--
⑨