changeset 955:9b167c5c4b78

irccd: add rules filtering
author David Demelier <markand@malikania.fr>
date Wed, 20 Jan 2021 17:01:51 +0100
parents 30643d18a635
children 5e682f1cebcc
files irccd/main.c lib/irccd/irccd.c lib/irccd/rule.c
diffstat 3 files changed, 66 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/irccd/main.c	Wed Jan 20 14:08:14 2021 +0100
+++ b/irccd/main.c	Wed Jan 20 17:01:51 2021 +0100
@@ -26,6 +26,7 @@
 #include <irccd/util.h>
 #include <irccd/plugin.h>
 #include <irccd/js-plugin.h>
+#include <irccd/rule.h>
 
 int
 main(int argc, char **argv)
@@ -45,10 +46,15 @@
 	struct irc_plugin p = {
 		.name = "test"
 	};
+	struct irc_rule r = {
+		.action = IRC_RULE_DROP
+	};
+
+	irc_rule_add(r.events, "onMe");
 
 	irc_log_set_verbose(true);
 	irc_bot_init();
-
+	irc_bot_insert_rule(&r, 0);
 	irc_transport_bind("/tmp/irccd.sock");
 	irc_server_join(&s, "#test", NULL);
 	irc_bot_add_server(irc_util_memdup(&s, sizeof (s)));
--- a/lib/irccd/irccd.c	Wed Jan 20 14:08:14 2021 +0100
+++ b/lib/irccd/irccd.c	Wed Jan 20 17:01:51 2021 +0100
@@ -96,6 +96,60 @@
 	return ev;
 }
 
+static bool
+invokable(const struct irc_plugin *p, const struct irc_event *ev)
+{
+	switch (ev->type) {
+	case IRC_EVENT_COMMAND:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onCommand");
+	case IRC_EVENT_CONNECT:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    NULL, NULL, p->name, "onConnect");
+	case IRC_EVENT_DISCONNECT:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    NULL, NULL, p->name, "onDisconnect");
+	case IRC_EVENT_INVITE:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[1], ev->msg.prefix, p->name, "onInvite");
+	case IRC_EVENT_JOIN:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onJoin");
+	case IRC_EVENT_KICK:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onKick");
+		break;
+	case IRC_EVENT_ME:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onMe");
+	case IRC_EVENT_MESSAGE:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onMessage");
+	case IRC_EVENT_MODE:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onMode");
+	case IRC_EVENT_NAMES:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], NULL, p->name, "onNames");
+	case IRC_EVENT_NICK:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    NULL, ev->msg.prefix, p->name, "onNick");
+	case IRC_EVENT_NOTICE:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onNotice");
+	case IRC_EVENT_PART:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onPart");
+	case IRC_EVENT_TOPIC:
+		return irc_rule_matchlist(irc.rules, irc.rulesz, ev->server->name,
+		    ev->msg.args[0], ev->msg.prefix, p->name, "onTopic");
+	case IRC_EVENT_WHOIS:
+		return true;
+	default:
+		return true;
+	}
+}
+
 static struct pkg
 prepare(void)
 {
@@ -159,11 +213,11 @@
 	for (size_t i = 0; i < irc.pluginsz; ++i) {
 		if (is_command(&irc.plugins[i], ev))
 			plgcmd = &irc.plugins[i];
-		else
+		else if (invokable(&irc.plugins[i], ev))
 			irc_plugin_handle(&irc.plugins[i], ev);
 	}
 
-	if (plgcmd)
+	if (plgcmd && invokable(plgcmd, ev))
 		irc_plugin_handle(plgcmd, to_command(plgcmd, ev));
 }
 
@@ -228,7 +282,7 @@
 	}
 }
 
-static void
+static inline void
 clean(struct pkg *pkg)
 {
 	free(pkg->fds);
--- a/lib/irccd/rule.c	Wed Jan 20 14:08:14 2021 +0100
+++ b/lib/irccd/rule.c	Wed Jan 20 17:01:51 2021 +0100
@@ -52,12 +52,12 @@
 static inline bool
 match(const char *str, const char *value)
 {
-	size_t len = strlen(value);
+	size_t len;
 	const char *p;
 
 	if (!str[0])
 		return true;
-	if (len == 0 || !(p = find(str, value)))
+	if (!value || (len = strlen(value)) == 0 || !(p = find(str, value)))
 		return false;
 
 	/*