shithub: neinchat

Download patch

ref: 29bcaa927a15091164661069e56da7c2431f7a33
parent: e6b34aae9701ee0f54ea60d974eeb87058e464db
author: Peter Mikkelsen <[email protected]>
date: Fri Feb 12 20:23:26 EST 2021

More work

--- a/main.c
+++ b/main.c
@@ -7,13 +7,16 @@
 enum {
 	Qroot,
 		Qnickname,
+		Qspeak,
+		Qcurrentchan,
 		Qchannels,
+	Qmax,
 };
 
-typedef struct Neinfile Neinfile;
+typedef struct NeinFile NeinFile;
 typedef struct NeinAux NeinAux;
 
-struct Neinfile {
+struct NeinFile {
 	char	*name;
 	Qid	qid;
 	ulong	mode;
@@ -32,18 +35,25 @@
 char	*fswalk1(Fid*, char*, Qid*);
 int	rootgen(int, Dir*, void*);
 int	channelsgen(int, Dir*, void*);
-Neinfile	*findfile(uvlong);
-void	fillstat(Dir*, Neinfile);
+NeinFile	*findfile(uvlong);
+int	findchannel(char*);
+void	fillstat(Dir*, NeinFile);
+void	readchanlog(Req*, uvlong);
 
 char *username;
 
-Neinfile qroot[] = {
+NeinFile qroot[] = {
 	"nickname", {Qnickname, 0, QTFILE}, 0666,
+	"speak", {Qspeak, 0, QTFILE}, 0222,
+	"currentchan", {Qcurrentchan, 0, QTFILE}, 0666,
 	"channels", {Qchannels, 0, QTDIR}, 0555 | DMDIR,
 };
 
-Neinfile root = {"/", {Qroot, 0, QTDIR}, 555 | DMDIR};
+int nchannels;
+NeinFile *channels;
 
+NeinFile root = {"/", {Qroot, 0, QTDIR}, 555 | DMDIR};
+
 void
 main(void)
 {
@@ -58,6 +68,8 @@
 	char *postname = "neinchat";
 	char *addr = "tcp!*!12345";
 	username = getuser();
+	nchannels = 0;
+	channels = nil;
 	print("Starting neinchat server on %s and posting to /srv/%s\n", addr, postname);
 	listensrv(&fs, addr);
 	postmountsrv(&fs, "neinchat", nil, MREPL|MCREATE);
@@ -83,7 +95,7 @@
 void
 fsstat(Req *r)
 {
-	Neinfile *f = findfile(r->fid->qid.path);
+	NeinFile *f = findfile(r->fid->qid.path);
 	if(f == nil){
 		respond(r, "not found");
 		return;
@@ -96,9 +108,15 @@
 fsread(Req *r)
 {
 	char *str;
-	NeinAux *aux;
+	NeinAux *aux = r->fid->aux;
+	uvlong path = r->fid->qid.path;
+	
+	if(path >= Qmax && path < (Qmax + nchannels)){
+		readchanlog(r, path);
+		return;
+	}
 
-	switch(r->fid->qid.path){
+	switch(path){
 	case Qroot:
 		dirread9p(r, rootgen, nil);
 		respond(r, nil);
@@ -108,12 +126,22 @@
 		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;
+	case Qcurrentchan:
+		if(aux->currentChan == -1){
+			respond(r, "no channel selected");
+			return;
+		}else{
+			str = smprint("%s\n", channels[aux->currentChan].name);
+			readstr(r, str);
+			free(str);
+			respond(r, nil);
+		}
+		break;
 	default:
 		respond(r, "wut no");
 	}
@@ -123,28 +151,45 @@
 fswrite(Req *r)
 {
 	NeinAux *aux = r->fid->aux;
+	char *buf;
 
-	if(r->fid->qid.path == Qnickname){
+	if(r->ifcall.offset != 0){
+		respond(r, "Can't write at offset");
+		return;
+	}
+
+	switch(r->fid->qid.path){
+	case Qnickname:
 		if(r->ifcall.count > 64){
-			respond(r, "nickname too long (max is 64 chars)");
+			respond(r, "nickname too long");
 			return;
 		}
-		if(r->ifcall.offset != 0){
-			respond(r, "Can't write at offset");
-			return;
-		}
-
-		char *buf = emalloc9p(r->ifcall.count + 1);
+		r->ofcall.count = r->ifcall.count;
+		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;
+		respond(r, nil);
+		break;
+	case Qcurrentchan:
+		if(r->ifcall.count > 64){
+			respond(r, "Channel name too long");
+			return;
+		}
 		r->ofcall.count = r->ifcall.count;
+		buf = emalloc9p(r->ifcall.count + 1);
+		memcpy(buf, r->ifcall.data, r->ifcall.count);
+		buf[r->ifcall.count] = 0;
+		aux->currentChan = findchannel(buf);
 		respond(r, nil);
-		return;
+		break;
+	case Qspeak:
+		respond(r, "Speaking not implemented yet ☺");
+		break;
+	default:
+		respond(r, "write prohibited");
 	}
-	
-	respond(r, "write prohibited");
 }
 
 char *
@@ -159,7 +204,7 @@
 {
 	int i;
 
-	if(strcmp("..", name) == 0){
+	if(strcmp(name, "..") == 0){
 		*qid = root.qid;
 		fid->qid = *qid;
 		return nil;
@@ -174,10 +219,14 @@
 				return nil;
 			}
 		}
-		if(strcmp("..", name) == 0){
-			*qid = root.qid;
-			fid->qid = *qid;
-			return nil;
+		break;
+	case Qchannels:
+		for(i = 0; i < nchannels; i++){
+			if(strcmp(channels[i].name, name) == 0){
+				*qid = channels[i].qid;
+				fid->qid = *qid;
+				return nil;
+			}
 		}
 		break;
 	}
@@ -189,7 +238,7 @@
 {
 	if(n >= nelem(qroot))
 		return -1;
-	Neinfile f = qroot[n];
+	NeinFile f = qroot[n];
 	fillstat(d, f);
 	return 0;
 }
@@ -197,12 +246,15 @@
 int
 channelsgen(int n, Dir *d, void *)
 {
-	USED(n);
-	USED(d);
-	return -1;
+	if(n >= nchannels)
+		return -1;
+
+	NeinFile f = channels[n];
+	fillstat(d, f);
+	return 0;
 }
 
-Neinfile *
+NeinFile *
 findfile(uvlong path)
 {
 	int i;
@@ -216,8 +268,25 @@
 	return nil;
 }
 
+int
+findchannel(char *name)
+{
+	int i;
+	int path;
+	for(i = 0; i < nchannels; i++){
+		if(strcmp(channels[i].name, name) == 0)
+			return i;
+	}
+
+	nchannels++;
+	path = Qmax + i;
+	channels = erealloc9p(channels, sizeof(NeinFile) * nchannels);
+	channels[i] = (NeinFile){name, (Qid){path, 0, QTFILE}, 0444};
+	return i;
+}
+
 void
-fillstat(Dir *d, Neinfile f)
+fillstat(Dir *d, NeinFile f)
 {
 	d->qid = f.qid;
 	d->mode = f.mode;
@@ -228,4 +297,12 @@
 	d->muid = estrdup9p(username);
 	d->atime = time(0);
 	d->mtime = time(0);
+}
+
+void
+readchanlog(Req *r, uvlong path)
+{
+	USED(path);
+	readstr(r, "Nothing to see here yet\n");
+	respond(r, nil);
 }
\ No newline at end of file