about summary refs log tree commit diff
path: root/reply.c
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-01-06 04:01:24 +0300
committerNakidai <nakidai@disroot.org>2026-01-06 04:01:24 +0300
commit833c53b1ad3338677056445c32c490cac0a08875 (patch)
tree24e60715c46ff89c26c5efc254e036b84aebcb13 /reply.c
parent78426afe18d9ce730a4d92033ca261f9b2f173a0 (diff)
downloadlibreircd-833c53b1ad3338677056445c32c490cac0a08875.tar.gz
libreircd-833c53b1ad3338677056445c32c490cac0a08875.zip
Add basic channels
Though they don't have modes, and JOIN/PART must be able to parse
comma separated list of channels
Diffstat (limited to 'reply.c')
-rw-r--r--reply.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/reply.c b/reply.c
new file mode 100644
index 0000000..b73fbea
--- /dev/null
+++ b/reply.c
@@ -0,0 +1,209 @@
+/*
+ * 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 <stdarg.h>
+
+#include <err.h>
+
+
+typedef int Reply(const struct Peer *peer, va_list ap);
+
+#define REPLY(n) static int r##n (const struct Peer *peer, va_list ap)
+#define ARG(n) const char *n = va_arg(ap, const char *)
+
+REPLY(1)
+{
+	return writef(
+		peer->fd,
+		":%s 001 %s Welcome to the Internet Relay Network %s!%s@%s",
+		hostname,
+		getnick(peer),
+		getnick(peer),
+		peer->user,
+		peer->host
+	);
+}
+
+REPLY(401)
+{
+	ARG(name);
+	return writef(
+		peer->fd,
+		":%s 401 %s %s :No such nick/channel",
+		hostname,
+		getnick(peer),
+		name
+	);
+}
+
+REPLY(403)
+{
+	ARG(channel);
+	return writef(
+		peer->fd,
+		":%s 403 %s %s :No such channel",
+		hostname,
+		getnick(peer),
+		channel
+	);
+}
+
+REPLY(405)
+{
+	ARG(channel);
+	return writef(
+		peer->fd,
+		":%s 405 %s %s :You have joined too many channels",
+		hostname,
+		getnick(peer),
+		channel
+	);
+}
+
+REPLY(411)
+{
+	return writef(
+		peer->fd,
+		":%s 411 %s :No recipient given (PRIVMSG)",
+		hostname,
+		getnick(peer)
+	);
+}
+
+REPLY(412)
+{
+	return writef(
+		peer->fd,
+		":%s 412 %s :No text to send",
+		hostname,
+		getnick(peer)
+	);
+}
+
+REPLY(421)
+{
+	ARG(command);
+	return writef(
+		peer->fd,
+		":%s 421 %s %s :Unknown command",
+		hostname,
+		getnick(peer),
+		command
+	);
+}
+
+REPLY(431)
+{
+	return writef(
+		peer->fd,
+		":%s 431 %s :No nickname given",
+		hostname,
+		getnick(peer)
+	);
+}
+
+REPLY(442)
+{
+	ARG(channel);
+	return writef(
+		peer->fd,
+		":%s 442 %s %s :You're not on that channel",
+		hostname,
+		getnick(peer),
+		channel
+	);
+}
+
+REPLY(451)
+{
+	return writef(
+		peer->fd,
+		":%s 451 %s :You have not registered",
+		hostname,
+		getnick(peer)
+	);
+}
+
+REPLY(461)
+{
+	ARG(command);
+	return writef(
+		peer->fd,
+		":%s 461 %s %s :Not enough parameters",
+		hostname,
+		getnick(peer),
+		command
+	);
+}
+
+REPLY(462)
+{
+	return writef(
+		peer->fd,
+		":%s 462 %s :Unauthorized command (already registered)",
+		hostname,
+		getnick(peer)
+	);
+}
+
+REPLY(471)
+{
+	ARG(channel);
+	return writef(
+		peer->fd,
+		":%s 471 %s %s :Cannot join channel (+l)",
+		hostname,
+		getnick(peer),
+		channel
+	);
+}
+
+#undef REPLY
+#define REPLY(n) [n] = r##n
+static Reply *replies[] = {
+	REPLY(  1),
+	REPLY(401),
+	REPLY(403),
+	REPLY(405),
+	REPLY(411),
+	REPLY(412),
+	REPLY(421),
+	REPLY(431),
+	REPLY(442),
+	REPLY(451),
+	REPLY(461),
+	REPLY(462),
+	REPLY(471),
+};
+
+int
+reply(const struct Peer *peer, int number, ...)
+{
+	Reply *choice;
+	va_list args;
+	int ret;
+
+	choice = replies[number];
+	if (!choice)
+		warnx("YOU FUCKING STUPID SHIT IMPLEMENT REPLY #%d NOW!!!", number);
+	va_start(args, number);
+	ret = choice(peer, args);
+	va_end(args);
+
+	return ret;
+}