summary refs log tree commit diff
path: root/handle.c
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-02-05 14:11:41 +0300
committerNakidai <nakidai@disroot.org>2026-02-05 14:11:41 +0300
commit68a91231a9480d591b43b359ad9a02af1faef07b (patch)
treed09fe703286c6450a266e83580b7e6eddec87961 /handle.c
parent5c240d0121aa82ad4ced73b70d3a1674ae81c764 (diff)
downloadlibreircd-68a91231a9480d591b43b359ad9a02af1faef07b.tar.gz
libreircd-68a91231a9480d591b43b359ad9a02af1faef07b.zip
Add OPER/SETOPER
SETOPER is a command for config, OPER is the one to authorize a user
Diffstat (limited to 'handle.c')
-rw-r--r--handle.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/handle.c b/handle.c
index b99e82d..fb08f73 100644
--- a/handle.c
+++ b/handle.c
@@ -24,6 +24,9 @@
 #include <err.h>
 
 
+static struct Oper opers[OPERS_MAX];
+size_t opers_c;
+
 static int names(struct Message *msg, struct Peer *peer);
 
 static int
@@ -192,6 +195,26 @@ nick(struct Message *msg, struct Peer *peer)
 }
 
 static int
+oper(struct Message *msg, struct Peer *peer)
+{
+	size_t i;
+
+	ensure(peer->type, reply(peer, 451), 0);
+	ensure(msg->params[0] && *msg->params[0], reply(peer, 461), 0);
+	ensure(msg->params[1] && *msg->params[1], reply(peer, 464), 0);
+
+	for (i = 0; i < opers_c; ++i)
+		if (!strcmp(opers[i].nick, msg->params[0]))
+			break;
+	ensure(i != opers_c && !strcmp(opers[i].pass, msg->params[1]), reply(peer, 464), 0);
+
+	peer->modes |= OPER;
+	reply(peer, 381);
+
+	return 0;
+}
+
+static int
 part(struct Message *msg, struct Peer *peer)
 {
 	size_t i;
@@ -343,6 +366,38 @@ setinfo(struct Message *msg, struct Peer *peer)
 }
 
 static int
+setoper(struct Message *msg, struct Peer *peer)
+{
+	size_t i;
+
+	ensure(peer->type == CONFIG, reply(peer, 481, "You're not a config file"), 0);
+	ensure(msg->params[0] && *msg->params[0], reply(peer, 461), 0);
+	ensure(msg->params[1], reply(peer, 461), 0);
+	ensure(
+		!*msg->params[1] || *msg->params[1] && opers_c < OPERS_MAX,
+		reply(peer, 420, msg->params[0]),
+		0
+	);
+
+	for (i = 0; i < opers_c; ++i)
+		if (!strcmp(opers[i].nick, msg->params[0]))
+			break;
+
+	if (*msg->params[1])
+	{
+		++opers_c;
+		strlcpy(opers[i].nick, msg->params[0], sizeof(opers->pass));
+		strlcpy(opers[i].pass, msg->params[1], sizeof(opers->pass));
+	}
+	else if (i < PEERS_MAX)
+	{
+		opers[i] = opers[--opers_c];
+	}
+
+	return 0;
+}
+
+static int
 user(struct Message *msg, struct Peer *peer)
 {
 	size_t i;
@@ -422,6 +477,7 @@ static struct Handler {
 	{ "names", names },
 	{ "nick", nick },
 	{ "notice", privmsg },
+	{ "oper", oper },
 	{ "part", part },
 	{ "ping", ping },
 	{ "pong", pong },
@@ -429,6 +485,7 @@ static struct Handler {
 	{ "quit", quit },
 	{ "setcreation", setcreation },
 	{ "setinfo", setinfo },
+	{ "setoper", setoper },
 	{ "user", user },
 	{ "whois", whois },
 };