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