ref: 29bcaa927a15091164661069e56da7c2431f7a33
parent: e6b34aae9701ee0f54ea60d974eeb87058e464db
author: Peter Mikkelsen <petermikkelsen10@gmail.com>
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