shithub: neinchat

Download patch

ref: b8cc5e02b3662d1e98953e35034f33fff9715e7f
parent: 533faf7e48638405d9589c44df517c76cdfd74ef
author: Peter Mikkelsen <[email protected]>
date: Fri Feb 12 18:30:07 EST 2021

First steps towards something

--- a/main.c
+++ b/main.c
@@ -1,9 +1,232 @@
 #include <u.h>
 #include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
 
+enum {
+	Qroot,
+		Qnickname,
+		Qchannels,
+};
+
+typedef struct Neinfile Neinfile;
+typedef struct NeinAux NeinAux;
+
+struct Neinfile {
+	char	*name;
+	Qid	qid;
+	ulong	mode;
+};
+
+struct NeinAux {
+	char	*nickname;
+	int	currentChan;
+};
+
+void	fsattach(Req*);
+void	fsstat(Req*);
+void	fsread(Req*);
+void	fswrite(Req*);
+char	*fsclone(Fid*, Fid*);
+char	*fswalk1(Fid*, char*, Qid*);
+int	rootgen(int, Dir*, void*);
+int	channelsgen(int, Dir*, void*);
+Neinfile	*findfile(uvlong);
+void	fillstat(Dir*, Neinfile);
+
+Srv fs = {
+	.attach = fsattach,
+	.walk1 = fswalk1,
+	.clone = fsclone,
+	.stat = fsstat,
+	.read = fsread,
+	.write = fswrite,
+};
+
+char *username;
+
+Neinfile qroot[] = {
+	"nickname", {Qnickname, 0, QTFILE}, 0666,
+	"channels", {Qchannels, 0, QTDIR}, 0555 | DMDIR,
+};
+
+Neinfile root = {"/", {Qroot, 0, QTDIR}, 555 | DMDIR};
+
+int nicknamecount;
+
 void
 main()
 {
-	print("Eyo neinchat server\n");
+	chatty9p = 1;
+	char *mountpoint = "/mnt/neinchat";
+	username = getuser();
+	print("Starting neinchat server on %s\n", mountpoint);
+	postmountsrv(&fs, "neinchat", mountpoint, MREPL|MCREATE);
 	exits(nil);
+}
+
+void
+fsattach(Req *r)
+{
+	NeinAux *aux;
+
+	r->fid->qid = root.qid;
+	r->ofcall.qid = r->fid->qid;
+
+	aux = emalloc9p(sizeof(NeinAux));
+	aux->nickname = smprint("RandomUser%d", nicknamecount++);
+	aux->currentChan = -1;
+	r->fid->aux = aux;
+	respond(r, nil);
+}
+
+void
+fsstat(Req *r)
+{
+	Neinfile *f = findfile(r->fid->qid.path);
+	if(f == nil){
+		respond(r, "not found");
+		return;
+	}
+	fillstat(&r->d, *f);
+	respond(r, nil);
+}
+
+void
+fsread(Req *r)
+{
+	char *str;
+	NeinAux *aux;
+
+	switch(r->fid->qid.path){
+	case Qroot:
+		dirread9p(r, rootgen, nil);
+		respond(r, nil);
+		break;
+	case Qchannels:
+		dirread9p(r, channelsgen, nil);
+		respond(r, nil);
+		break;
+	case Qnickname:
+		aux = r->fid->aux;
+		str = smprint("%s\n", aux->nickname);
+		readstr(r, str);
+		free(str);
+		respond(r, nil);
+		break;
+	default:
+		respond(r, "wut no");
+	}
+}
+
+void
+fswrite(Req *r)
+{
+	NeinAux *aux = r->fid->aux;
+
+	if(r->fid->qid.path == Qnickname){
+		if(r->ifcall.count > 64){
+			respond(r, "nickname too long (max is 64 chars)");
+			return;
+		}
+		if(r->ifcall.offset != 0){
+			respond(r, "Can't write at offset");
+			return;
+		}
+
+		char *buf = emalloc9p(r->ifcall.count + 1);
+		memcpy(buf, r->ifcall.data, r->ifcall.count);
+		buf[r->ifcall.count] = 0;
+		free(aux->nickname);
+		aux->nickname = buf;
+		r->ofcall.count = r->ifcall.count;
+		respond(r, nil);
+		return;
+	}
+	
+	respond(r, "write prohibited");
+}
+
+char *
+fsclone(Fid *old, Fid *new)
+{
+	new->aux = old->aux;
+	return nil;
+}
+
+char *
+fswalk1(Fid *fid, char *name, Qid *qid)
+{
+	int i;
+
+	if(strcmp("..", name) == 0){
+		*qid = root.qid;
+		fid->qid = *qid;
+		return nil;
+	}
+
+	switch(fid->qid.path){
+	case Qroot:
+		for(i = 0; i < nelem(qroot); i++){
+			if(strcmp(qroot[i].name, name) == 0){
+				*qid = qroot[i].qid;
+				fid->qid = *qid;
+				return nil;
+			}
+		}
+		if(strcmp("..", name) == 0){
+			*qid = root.qid;
+			fid->qid = *qid;
+			return nil;
+		}
+		break;
+	}
+	return "not found";
+}
+
+int
+rootgen(int n, Dir *d, void *)
+{
+	if(n >= nelem(qroot))
+		return -1;
+	Neinfile f = qroot[n];
+	fillstat(d, f);
+	return 0;
+}
+
+int
+channelsgen(int n, Dir *d, void *)
+{
+	USED(n);
+	USED(d);
+	return -1;
+}
+
+Neinfile *
+findfile(uvlong path)
+{
+	int i;
+	if(path == Qroot)
+		return &root;
+	
+	for(i = 0; i < nelem(qroot); i++){
+		if(qroot[i].qid.path == path)
+			return &qroot[i];
+	}
+	return nil;
+}
+
+void
+fillstat(Dir *d, Neinfile f)
+{
+	d->qid = f.qid;
+	d->mode = f.mode;
+	d->length = 0;
+	d->name = estrdup9p(f.name);
+	d->uid = estrdup9p(username);
+	d->gid = estrdup9p(username);
+	d->muid = estrdup9p(username);
+	d->atime = time(0);
+	d->mtime = time(0);
 }
\ No newline at end of file