about summary refs log tree commit diff
path: root/handle.c
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-01-04 17:41:32 +0300
committerNakidai <nakidai@disroot.org>2026-01-04 17:44:09 +0300
commit78426afe18d9ce730a4d92033ca261f9b2f173a0 (patch)
tree0c511b571e9a37496f170fce08737a849a8ba5ef /handle.c
downloadlibreircd-78426afe18d9ce730a4d92033ca261f9b2f173a0.tar.gz
libreircd-78426afe18d9ce730a4d92033ca261f9b2f173a0.zip
Add code
Diffstat (limited to 'handle.c')
-rw-r--r--handle.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/handle.c b/handle.c
new file mode 100644
index 0000000..79a3b9a
--- /dev/null
+++ b/handle.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2026 Nakidai Perumenei <nakidai at disroot dot org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ircd.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+
+#define ensure(cond, iffalse, doexit) if (!(cond)) { iffalse; if (doexit >= 0) return doexit; }
+
+static int
+nick(struct Message *msg, struct Peer *peer)
+{
+	ensure(msg->params[0] && msg->params[0], writef(
+		peer->fd,
+		":%s 431 %s :No nickname given",
+		hostname,
+		getnick(peer)
+	), 0);
+
+	user_reg(peer, msg->params[0], NULL, NULL);
+
+	return 0;
+}
+
+static int
+privmsg(struct Message *msg, struct Peer *peer)
+{
+	size_t i;
+
+	ensure(peer->type, writef(
+		peer->fd,
+		":%s 451 %s :You have not registered",
+		hostname,
+		getnick(peer)
+	), 0);
+	ensure(msg->params[0] && *msg->params[0], writef(
+		peer->fd,
+		":%s 411 %s :No recipient given (PRIVMSG)",
+		hostname,
+		getnick(peer)
+	), 0);
+	ensure(msg->params[1] && *msg->params[1], writef(
+		peer->fd,
+		":%s 412 %s :No text to send",
+		hostname,
+		getnick(peer)
+	), 0);
+
+	/* TODO: implement channels */
+	ensure(!strchr("!+#&", *msg->params[0]), writef(
+		peer->fd,
+		":%s 421 %s :Channels are not supported yet",
+		hostname,
+		getnick(peer)
+	), 0);
+
+	/* TODO: implement server-to-server communication */
+	for (i = 0; i < PEERS_MAX; ++i)
+		if (peers[i].type == CLIENT && !strcmp(peers[i].nick, msg->params[0]))
+			writef(
+				peers[i].fd,
+				":%s!%s@%s PRIVMSG %s :%s",
+				peer->nick,
+				peer->user,
+				peer->host,
+				peer->nick,
+				msg->params[1]
+			);
+	return 0;
+}
+
+static int
+quit(struct Message *msg, struct Peer *peer)
+{
+	return 1;
+}
+
+static int
+user(struct Message *msg, struct Peer *peer)
+{
+	size_t i;
+
+	ensure(!peer->type, writef(
+		peer->fd,
+		":%s 462 %s :Unauthorized command (already registered)",
+		hostname,
+		getnick(peer)
+	), 0);
+	for (i = 0; i < 4; ++i)
+		ensure(msg->params[i] && *msg->params[i], writef(
+			peer->fd,
+			":%s 461 %s %s :Not enough parameters",
+			hostname,
+			getnick(peer),
+			msg->command
+		), 0);
+
+	user_reg(peer, NULL, msg->params[0], msg->params[3]);
+
+	return 0;
+}
+
+static int
+default_handler(struct Message *msg, struct Peer *peer)
+{
+	ensure(peer->type, 0, 0);
+
+	writef(peer->fd, ":%s 421 %s %s :Unknown command", hostname, getnick(peer), msg->command);
+	return 0;
+}
+
+static struct Handler {
+	const char *name;
+	Handler *handler;
+} handlers[] =
+{
+	{ "nick", nick },
+	{ "privmsg", privmsg },
+	{ "quit", quit },
+	{ "user", user },
+};
+
+Handler *
+find(const char *command)
+{
+	struct Handler *l, *m, *r;
+	int res;
+
+	l = handlers;
+	r = handlers + lengthof(handlers) - 1;
+	while (l <= r)
+	{
+		m = l + (r - l) / 2;
+		res = strcmp(command, m->name);
+		if (res > 0)
+			l = ++m;
+		else if (res < 0)
+			r = --m;
+		else
+			return m->handler;
+	}
+
+	return default_handler;
+}