shithub: svcfs

Download patch

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);
--