summary refs log tree commit diff
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-02-05 12:53:36 +0300
committerNakidai <nakidai@disroot.org>2026-02-05 12:53:36 +0300
commitc638c90e5545111fd1217c777724397759dc06d7 (patch)
tree9917543314f7f74ea1bca2004bc4f05711d4ea78
parenteba9ea345af1f259bf27936f3d0941ab2a2f5bfb (diff)
downloadlibreircd-c638c90e5545111fd1217c777724397759dc06d7.tar.gz
libreircd-c638c90e5545111fd1217c777724397759dc06d7.zip
Add NAMES
So not it can show who's on the channel, yay. Though, no showing ops
-rw-r--r--config.h2
-rw-r--r--handle.c40
-rw-r--r--ircd.h1
-rw-r--r--reply.c13
4 files changed, 55 insertions, 1 deletions
diff --git a/config.h b/config.h
index dce385b..1aefc9d 100644
--- a/config.h
+++ b/config.h
@@ -39,4 +39,4 @@
 #define PEER_PINGTIMEOUT 120
 #define PEER_PONGTIMEOUT 20
 
-#define POLL_TIMEOUT (PEER_PINGTIMEOUT < PEER_PONGTIMEOUT ? PEER_PINGTIMEOUT : PEER_PONGTIMEOUT)
+#define POLL_TIMEOUT min(PEER_PINGTIMEOUT, PEER_PONGTIMEOUT)
diff --git a/handle.c b/handle.c
index 9e8cb5f..76f0a32 100644
--- a/handle.c
+++ b/handle.c
@@ -24,9 +24,12 @@
 #include <err.h>
 
 
+static int names(struct Message *msg, struct Peer *peer);
+
 static int
 join(struct Message *msg, struct Peer *peer)
 {
+	struct Message namesmsg;
 	size_t i;
 	char *cp;
 
@@ -46,6 +49,7 @@ join(struct Message *msg, struct Peer *peer)
 	for (i = 0; i < peer->channels_c; ++i)
 		ensure(strcmp(channels[i].name, msg->params[0]), (void)0, 0);
 
+	namesmsg = (struct Message){ .params = { msg->params[0] } };
 	for (i = 0; i < channels_c; ++i)
 	{
 		if (strcmp(channels[i].name, msg->params[0]))
@@ -53,12 +57,15 @@ join(struct Message *msg, struct Peer *peer)
 
 		if (channel_join(&channels[i], peer))
 			reply(peer, 471);
+		else
+			names(&namesmsg, peer);
 		return 0;
 	}
 
 	channels[channels_c] = (struct Channel){0};
 	strlcpy(channels[channels_c].name, msg->params[0], sizeof(channels->name));
 	channel_join(&channels[channels_c++], peer);
+	names(&namesmsg, peer);
 	return 0;
 }
 
@@ -103,6 +110,38 @@ mode(struct Message *msg, struct Peer *peer)
 }
 
 static int
+names(struct Message *msg, struct Peer *peer)
+{
+	static char buf[MESSAGE_MAX];
+	size_t i, j;
+
+	for (i = 0; i < peer->channels_c; ++i)
+	{
+		if (msg->params[0] && strcmp(msg->params[0], peer->channels[i]->name))
+			continue;
+
+		memset(buf, 0, sizeof(buf));
+		for (j = 0; j < peer->channels[i]->users_c; ++j)
+		{
+			strlcat(buf, peer->channels[i]->users[j]->nick, sizeof(buf));
+			if (strlen(buf) >= MESSAGE_MAX - 4*PEER_NICK_MAX)
+			{
+				reply(peer, 353, peer->channels[i]->name, buf);
+				memset(buf, 0, sizeof(buf));
+			} else
+			{
+				strlcat(buf, " ", sizeof(buf));
+			}
+		}
+		if (*buf)
+			reply(peer, 353, peer->channels[i]->name, buf);
+	}
+
+	reply(peer, 366, msg->params[0] ? msg->params[0] : "*");
+	return 0;
+}
+
+static int
 nick(struct Message *msg, struct Peer *peer)
 {
 	size_t i;
@@ -380,6 +419,7 @@ static struct Handler {
 {
 	{ "join", join },
 	{ "mode", mode },
+	{ "names", names },
 	{ "nick", nick },
 	{ "notice", privmsg },
 	{ "part", part },
diff --git a/ircd.h b/ircd.h
index 1f5bba8..f85d33f 100644
--- a/ircd.h
+++ b/ircd.h
@@ -20,6 +20,7 @@
 #include <stddef.h>
 #include <time.h>
 
+#define min(A, B) ((A) < (B) ? (A) : (B))
 #include "config.h"
 
 #define BIT(x) x##_BIT, x = 1 << x##_BIT, x##_BIT_ = x##_BIT
diff --git a/reply.c b/reply.c
index a295da8..6670ecf 100644
--- a/reply.c
+++ b/reply.c
@@ -133,6 +133,19 @@ vreply(const struct Peer *peer, int number, va_list ap)
 		getnick(peer),
 		nick
 	), nick, _);
+	REPLY(353, WRITE(
+		":%s 353 %s = %s :%s",
+		hostname,
+		getnick(peer),
+		channel,
+		nicklist
+	), channel, nicklist, _);
+	REPLY(366, WRITE(
+		":%s 366 %s %s :End of NAMES list",
+		hostname,
+		getnick(peer),
+		channel
+	), channel, _);
 	REPLY(401, WRITE(
 		":%s 401 %s %s :No such nick/channel",
 		hostname,