summary refs log tree commit diff
path: root/handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'handle.c')
-rw-r--r--handle.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/handle.c b/handle.c
index 377a95e..a8b1e5f 100644
--- a/handle.c
+++ b/handle.c
@@ -74,6 +74,51 @@ join(struct Message *msg, struct Peer *peer)
 }
 
 static int
+kick(struct Message *msg, struct Peer *peer)
+{
+	struct Channel *ch;
+	size_t i;
+
+	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, 431), 0);
+
+	for (i = 0; i < channels_c; ++channels_c)
+		if (!strcmp(channels[i].name, msg->params[0]))
+			break;
+	ensure(i != channels_c, reply(peer, 403, msg->params[0]), 0);
+	ch = &channels[i];
+
+	for (i = 0; i < ch->peers_c; ++i)
+		if (ch->peers[i].p->fd == peer->fd)
+			break;
+	ensure(i != ch->peers_c, reply(peer, 442, ch->name), 0);
+	ensure(ch->peers[i].modes & CHANNEL_OPER, reply(peer, 482, ch->name), 0);
+
+	for (i = 0; i < ch->peers_c; ++i)
+		if (!strcmp(ch->peers[i].p->nick, msg->params[1]))
+			break;
+	ensure(i != ch->peers_c, reply(peer, 441, msg->params[1], ch->name), 0);
+
+	writechanf(
+		0,
+		ch,
+		":%s!%s@%s KICK %s %s%s%s",
+		getnick(peer),
+		peer->user,
+		peer->host,
+		ch->name,
+		ch->peers[i].p->nick,
+		msg->params[2] ? " :" : "",
+		msg->params[2] ? msg->params[2] : ""
+	);
+
+	channel_exit(ch, ch->peers[i].p);
+
+	return 0;
+}
+
+static int
 mode_channel(struct Message *msg, struct Peer *peer)
 {
 	const struct ChannelModeParam *parsed;
@@ -558,6 +603,7 @@ static struct Handler {
 } handlers[] =
 {
 	{ "join", join },
+	{ "kick", kick },
 	{ "mode", mode },
 	{ "names", names },
 	{ "nick", nick },