shithub: ircd

Download patch

ref: 4161df5fd7487feaf4758b93a8d8371bec433471
parent: b402639434e9360c99fc8b9cb12d51614abfbeea
author: sirjofri <sirjofri@sirjofri.de>
date: Sat Jul 19 17:14:03 EDT 2025

working filesystem with async reads (works with con -C)

--- a/cmd.c
+++ b/cmd.c
@@ -6,18 +6,38 @@
 #include "version.h"
 
 static void
-cversion(Request *r)
+cversion(User *u, Request *r)
 {
 	if (r->args[0]) {
 		fprint(2, "get version of '%s' (not implemented yet!)\n", r->args[0]);
-		reply(Enosuchserver, r->args[0]);
+		reply(u, Enosuchserver, r->args[0]);
 		return;
 	}
-	reply(Rversion, getversion());
+	reply(u, Rversion, getversion());
 }
 
+static void
+cuser(User *u, Request *r)
+{
+	// TODO: how to respond without knowing the user?
+	if (!r->args[3]) {
+		fprint(2, "user without enough args%R\n", *r);
+		// reply(u, Eneedmoreparams, r->cmd.name);
+		return;
+	}
+	u = finduser(r->args[0]);
+	if (u) {
+		fprint(2, "user already registered%R\n", *r);
+		// reply(u, Ealreadyregistered);
+		return;
+	}
+	u = adduser(r->args[0]);
+	setuser(u);
+}
+
 static Command commands[] = {
 	{ "version", cversion },
+	{ "user", cuser },
 };
 int ncommands = sizeof(commands) / sizeof(Command);
 
@@ -38,7 +58,7 @@
 }
 
 void
-execrequest(Request r)
+execrequest(User *u, Request r)
 {
 	if (!(r.cmd && r.cmd->func)) {
 		fprint(2, "cannot execute request: no command\n");
@@ -46,5 +66,5 @@
 	}
 	if (debug)
 		fprint(2, "run command '%s'\n", r.cmd->name);
-	r.cmd->func(&r);
+	r.cmd->func(u, &r);
 }
--- a/cmd.h
+++ b/cmd.h
@@ -7,3 +7,13 @@
 	.nr = 402,
 	.msg = "%s :No such server",
 };
+
+Reply Eneedmoreparams = {
+	.nr = 461,
+	.msg = "%s :Not enough parameters",
+};
+
+Reply Ealreadyregistered = {
+	.nr = 462,
+	.msg = ":Unauthorized command (already registered)",
+};
--- a/dat.h
+++ b/dat.h
@@ -2,6 +2,9 @@
 typedef struct Request Request;
 typedef struct Command Command;
 typedef struct Reply Reply;
+typedef struct User User;
+typedef struct Replybuffer Replybuffer;
+typedef struct Userlist Userlist;
 
 #pragma varargck type "R" Request
 
@@ -22,7 +25,7 @@
 struct Command
 {
 	char *name;
-	void (*func)(Request*);
+	void (*func)(User*,Request*);
 };
 
 struct Reply
@@ -31,4 +34,25 @@
 	char *msg;
 };
 
+struct Replybuffer
+{
+	QLock;
+	void *reply;
+};
+
+struct User
+{
+	char *name;
+	Replybuffer replies;
+	
+	User *prev;
+	User *next;
+};
+
+struct Userlist
+{
+	User *first;
+};
+
 extern int debug;
+extern char* sysnameb;
--- a/fns.h
+++ b/fns.h
@@ -2,11 +2,17 @@
 
 Command* findcommand(char*);
 Command* findcommandn(int);
-void execrequest(Request);
+void execrequest(User*, Request);
 void clearrequest(Request);
 
-void reply(Reply, ...);
-int hasreplies(char*);
+void setuser(User*);
+void reply(User*, Reply, ...);
+char *getreplies(User*);
+void flushreplies(User*);
 
 int Rfmt(Fmt *f);
 char *getversion(void);
+
+User* adduser(char*);
+void deluser(User*);
+User* finduser(char*);
--- a/ircd.c
+++ b/ircd.c
@@ -13,11 +13,11 @@
 usage(void)
 {
 	fprint(2, "usage: %s\n", argv0);
-	exits("usage");
+	threadexitsall("usage");
 }
 
 static Biobuf *bio;
-static char *sysnameb = "nil";
+char *sysnameb = "nil";
 static char *versionstring = nil;
 int debug = 0;
 
@@ -31,43 +31,39 @@
 	return versionstring;
 }
 
-static void
-parselines(void)
-{
-	char *line;
-	Request parsedrequest;
-	
-	while (line = Brdstr(bio, '\n', 1)) {
-		parsedrequest = parseline(line);
-		if (debug > 1)
-			fprint(2, "request: %R\n", parsedrequest);
-		execrequest(parsedrequest);
-		free(line);
-	}
-}
-
 char *mtpt = "/mnt/ircd";
 char *srvname = "ircd";
 Reqqueue *reqqueue = nil;
+User *ircuser = nil;
 
-// TODO: implement hasdata for client. put all replies in a bulk buffer.
-int hasdata = 0;
-QLock datalock;
+void
+setuser(User *u)
+{
+	ircuser = u;
+}
 
 static void
 readproc(Req *r)
 {
+	char *repl;
+	
+	threadsetname("readproc");
+	
+	if (!ircuser) {
+		respond(r, nil);
+		return;
+	}
+	
 	while (1) {
-		qlock(&datalock);
-		if (hasdata) {
-			readstr(r, "hasdata\n");
-			fprint(2, "responded with hasdata\n");
-			hasdata = 0;
-			qunlock(&datalock);
+		qlock(&ircuser->replies);
+		repl = getreplies(ircuser);
+		if (repl) {
+			readstr(r, repl);
+			qunlock(&ircuser->replies);
 			respond(r, nil);
 			return;
 		}
-		qunlock(&datalock);
+		qunlock(&ircuser->replies);
 	}
 }
 
@@ -99,12 +95,8 @@
 	parsed = parseline(line);
 	if (debug > 1)
 		fprint(2, "request:%R", parsed);
-	execrequest(parsed);
+	execrequest(ircuser, parsed);
 	
-	qlock(&datalock);
-	hasdata = 1;
-	qunlock(&datalock);
-	
 	respond(r, nil);
 }
 
@@ -140,7 +132,7 @@
 		break;
 	case 'v':
 		fprint(2, "version: %s\n", getversion());
-		exits(nil);
+		threadexitsall(nil);
 	case 's':
 		srvname = EARGF(usage());
 		break;
@@ -163,17 +155,5 @@
 	fs.tree = alloctree(nil, nil, DMDIR|0777, nil);
 	populatetree(fs.tree->root);
 	threadpostmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
-	exits(nil);
-}
-
-void
-reply(Reply repl, ...)
-{
-	char buf[511];
-	va_list arg;
-	
-	va_start(arg, repl);
-	vsnprint(buf, sizeof buf, repl.msg, arg);
-	va_end(arg);
-	print(":%s %03d %s\r\n", sysnameb, repl.nr, buf);
+	//exits(nil);
 }
--- a/mkfile
+++ b/mkfile
@@ -6,6 +6,8 @@
 	cmd.$O\
 	parse.$O\
 	fmt.$O\
+	reply.$O\
+	users.$O\
 
 HFILES=fns.h dat.h cmd.h
 
--- /dev/null
+++ b/reply.c
@@ -1,0 +1,40 @@
+#include <u.h>
+#include <libc.h>
+#include <String.h>
+#include "dat.h"
+#include "fns.h"
+
+char*
+getreplies(User *u)
+{
+	return u->replies.reply;
+}
+
+void
+flushreplies(User *u)
+{
+	if (!u->replies.reply)
+		return;
+	free(u->replies.reply);
+	u->replies.reply = nil;
+}
+
+void
+reply(User *u, Reply repl, ...)
+{
+	char buf[511];
+	va_list arg;
+	String *s = u->replies.reply;
+	
+	snprint(buf, sizeof buf, "%s %03d ", sysnameb, repl.nr);
+	s_append(s, buf);
+	
+	va_start(arg, repl);
+	vsnprint(buf, sizeof buf, repl.msg, arg);
+	va_end(arg);
+	
+	s_append(s, buf);
+	s_append(s, "\r\n");
+	
+	fprint(2, ":%s %03d %s\r\n", sysnameb, repl.nr, buf);
+}
--- /dev/null
+++ b/users.c
@@ -1,0 +1,54 @@
+#include <u.h>
+#include <libc.h>
+#include <String.h>
+#include "dat.h"
+#include "fns.h"
+
+static Userlist users;
+
+User*
+adduser(char *name)
+{
+	User *n;
+	n = mallocz(sizeof(User), 1);
+	n->name = strdup(name);
+	n->replies.reply = s_new();
+	
+	if (!users.first) {
+		users.first = n;
+		return n;
+	}
+	n->next = users.first;
+	users.first->prev = n;
+	users.first = n;
+	return n;
+}
+
+void
+deluser(User *user)
+{
+	String *s;
+	if (!user->prev) {
+		users.first = user->next;
+		if (user->next)
+			user->next->prev = nil;
+	} else {
+		user->prev->next = user->next;
+		if (user->next)
+			user->next->prev = user->prev;
+	}
+	s = user->replies.reply;
+	s_free(s);
+	free(user->name);
+	free(user);
+}
+
+User*
+finduser(char *name)
+{
+	for (User *u = users.first; u; u = u->next) {
+		if (strcmp(name, u->name) == 0)
+			return u;
+	}
+	return nil;
+}
--