about summary refs log tree commit diff
path: root/handle.c
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-01-10 16:32:54 +0300
committerNakidai <nakidai@disroot.org>2026-01-10 16:32:54 +0300
commit76e2c978829bc6ff7bfe6c49bfa3739e19370990 (patch)
tree07851d4ee5ca107ce4ec18889b20c006f56f53d3 /handle.c
parent346abf24c900a19a77a8ce66566a7ffd86a819bb (diff)
downloadlibreircd-76e2c978829bc6ff7bfe6c49bfa3739e19370990.tar.gz
libreircd-76e2c978829bc6ff7bfe6c49bfa3739e19370990.zip
Add basic user mode handling
So, now there're all modes listed in RFC 2812. The only what they
do now, though, is a +r restricting user from changing their nick
Diffstat (limited to 'handle.c')
-rw-r--r--handle.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/handle.c b/handle.c
index 87dfa77..9d705e0 100644
--- a/handle.c
+++ b/handle.c
@@ -57,11 +57,52 @@ join(struct Message *msg, struct Peer *peer)
 }
 
 static int
+mode(struct Message *msg, struct Peer *peer)
+{
+	int set = 1, m;
+
+	ensure(peer->type, reply(peer, 451), 0);
+	ensure(msg->params[0] && msg->params[0], reply(peer, 431), 0);
+	ensure(msg->params[1] && msg->params[1], reply(peer, 221), 0);
+
+	switch (*msg->params[1])
+	{
+	case '-':
+		set = !set;
+	case '+':
+		++msg->params[1];
+	default:
+	{
+		for (; *msg->params[1]; ++msg->params[1])
+		{
+			m = user_mode(*msg->params[1]);
+			if (!m)
+			{
+				reply(peer, 501, msg->params[1]);
+				continue;
+			}
+
+			if (m & AWAY)
+				continue;
+
+			if (set && !(m & (OPER | LOCALOPER)))
+				peer->modes |= m;
+			else if (!(m & RESTRICTED))
+				peer->modes &= ~m;
+		}
+	}
+	}
+
+	return 0;
+}
+
+static int
 nick(struct Message *msg, struct Peer *peer)
 {
 	ensure(msg->params[0] && msg->params[0], reply(peer, 431), 0);
+	ensure(!(peer->modes & RESTRICTED), reply(peer, 484), 0);
 
-	user_reg(peer, msg->params[0], NULL, NULL);
+	user_reg(peer, msg->params[0], NULL, NULL, NULL);
 
 	return 0;
 }
@@ -205,7 +246,7 @@ user(struct Message *msg, struct Peer *peer)
 	for (i = 0; i < 4; ++i)
 		ensure(msg->params[i] && *msg->params[i], reply(peer, 461), 0);
 
-	user_reg(peer, NULL, msg->params[0], msg->params[3]);
+	user_reg(peer, NULL, msg->params[0], msg->params[3], msg->params[1]);
 
 	return 0;
 }
@@ -225,6 +266,7 @@ static struct Handler {
 } handlers[] =
 {
 	{ "join", join },
+	{ "mode", mode },
 	{ "nick", nick },
 	{ "part", part },
 	{ "privmsg", privmsg },