changeset 1095:c46217eaac45

irccd: fix CTCP replies While here, add support for VERSION/SOURCE override.
author David Demelier <markand@malikania.fr>
date Fri, 13 Aug 2021 10:20:25 +0200
parents 6b4de5bff34e
children c3191ab50cee
files irccd/conf.y irccd/irccd.conf irccd/lex.l lib/irccd/limits.h lib/irccd/server.c lib/irccd/server.h man/irccd.conf.5
diffstat 7 files changed, 71 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/irccd/conf.y	Wed Aug 04 10:27:04 2021 +0200
+++ b/irccd/conf.y	Fri Aug 13 10:20:25 2021 +0200
@@ -72,6 +72,8 @@
 	char *username;
 	char *realname;
 	char *prefix;
+	char *ctcpversion;
+	char *ctcpsource;
 	struct string *channels;
 };
 
@@ -147,6 +149,7 @@
 %token T_CHANNELS
 %token T_COMMA
 %token T_CONFIG
+%token T_CTCP
 %token T_EVENTS
 %token T_GID
 %token T_HOOK
@@ -161,8 +164,8 @@
 %token T_PATHS
 %token T_PLUGIN
 %token T_PLUGINS
+%token T_PORT
 %token T_PREFIX
-%token T_PORT
 %token T_RULE
 %token T_SEMICOLON
 %token T_SERVER
@@ -491,6 +494,21 @@
 
 		string_list_finish($2);
 	}
+	| T_CTCP T_BRACE_OPEN pair_list T_BRACE_CLOSE server_params
+	{
+		$$ = $5;
+
+		for (struct pair *p = $3; p; p = p->next) {
+			if (strcmp(p->key, "version") == 0)
+				$$->ctcpversion = irc_util_strdup(p->value);
+			else if (strcmp(p->key, "source") == 0)
+				$$->ctcpsource = irc_util_strdup(p->value);
+			else
+				irc_util_die("invalid ctcp key: %s\n", p->key);
+		}
+
+		pair_list_finish($3);
+	}
 	|
 	{
 		$$ = irc_util_calloc(1, sizeof (*$$));
@@ -534,6 +552,10 @@
 			irc_util_strlcpy(s->prefix, $4->prefix, sizeof (s->prefix));
 		if ($4->password)
 			irc_util_strlcpy(s->ident.password, $4->password, sizeof (s->ident.password));
+		if ($4->ctcpversion)
+			irc_util_strlcpy(s->ident.ctcpversion, $4->ctcpversion, sizeof (s->ident.ctcpversion));
+		if ($4->ctcpsource)
+			irc_util_strlcpy(s->ident.ctcpsource, $4->ctcpsource, sizeof (s->ident.ctcpsource));
 
 		s->flags = $4->flags;
 		irc_bot_server_add(s);
@@ -545,6 +567,8 @@
 		free($4->realname);
 		free($4->prefix);
 		free($4->password);
+		free($4->ctcpversion);
+		free($4->ctcpsource);
 		free($4);
 	}
 	;
--- a/irccd/irccd.conf	Wed Aug 04 10:27:04 2021 +0200
+++ b/irccd/irccd.conf	Fri Aug 13 10:20:25 2021 +0200
@@ -66,6 +66,10 @@
 #   channels "#test", "#staff"; # List of channels to join.
 #   options AUTO-REJOIN;        # Enable auto-rejoin after a kick.
 #   prefix "!";                 # Prefix for invoking plugins.
+#   ctcp {
+#     version "my version";     # Custom CTCP VERSION reply.
+#     source "my SCM location"; # Custom CTCP SOURCE reply.
+#   }
 # }
 #
 
--- a/irccd/lex.l	Wed Aug 04 10:27:04 2021 +0200
+++ b/irccd/lex.l	Fri Aug 13 10:20:25 2021 +0200
@@ -37,6 +37,7 @@
 
 channels        channels
 config          config
+ctcp            ctcp
 events          events
 gid             gid
 hook            hook
@@ -53,8 +54,8 @@
 paths           paths
 plugin          plugin
 plugins         plugins
+port            port
 prefix          prefix
-port            port
 rule            rule
 rule_action     accept|drop
 server          server
@@ -88,6 +89,7 @@
 {channels}              return T_CHANNELS;
 {comma}                 return T_COMMA;
 {config}                return T_CONFIG;
+{ctcp}                  return T_CTCP;
 {events}                return T_EVENTS;
 {gid}                   return T_GID;
 {hook}                  return T_HOOK;
@@ -102,8 +104,8 @@
 {paths}                 return T_PATHS;
 {plugins}               return T_PLUGINS;
 {plugin}                return T_PLUGIN;
+{port}                  return T_PORT;
 {prefix}                return T_PREFIX;
-{port}                  return T_PORT;
 {semicolon}             return T_SEMICOLON;
 {servers}               return T_SERVERS;
 {server}                return T_SERVER;
--- a/lib/irccd/limits.h	Wed Aug 04 10:27:04 2021 +0200
+++ b/lib/irccd/limits.h	Fri Aug 13 10:20:25 2021 +0200
@@ -27,7 +27,7 @@
 #define IRC_REALNAME_LEN        64              /* Real name. */
 #define IRC_CHANNEL_LEN         64              /* Channel name. */
 #define IRC_PASSWORD_LEN        64              /* Password length. */
-#define IRC_CTCPVERSION_LEN     64              /* Custom CTCP version answer. */
+#define IRC_CTCP_LEN            64              /* Custom CTCP version answer. */
 #define IRC_USERMODES_LEN       8               /* Number of modes (e.g. ohv). */
 #define IRC_CHANTYPES_LEN       8               /* Channel types. */
 #define IRC_PREFIX_LEN          4               /* Prefix for plugin commands (e.g. !). */
--- a/lib/irccd/server.c	Wed Aug 04 10:27:04 2021 +0200
+++ b/lib/irccd/server.c	Fri Aug 13 10:20:25 2021 +0200
@@ -422,21 +422,28 @@
 	 * PRIVMSG jean :\001VERSION\001
 	 */
 	if (is_ctcp(msg->args[1])) {
+		struct irc_server_user user;
+
+		irc_server_split(msg->prefix, &user);
+
 		if (strcmp(msg->args[1], "\x01""CLIENTINFO\x01") == 0)
-			irc_server_notice(s, msg->prefix, "\x01""CLIENTINFO ACTION CLIENTINFO SOURCE TIME VERSION\x01");
+			irc_server_notice(s, user.nickname,
+			    "\x01""CLIENTINFO ACTION CLIENTINFO SOURCE TIME VERSION\x01");
 		else if (strcmp(msg->args[1], "\x01""SOURCE\x01") == 0)
-			irc_server_notice(s, msg->prefix, "\x01""http://hg.malikania.fr/irccd\x01");
+			irc_server_send(s, "NOTICE %s :\x01SOURCE %s\x01",
+			    user.nickname, s->ident.ctcpsource[0]
+			    ? s->ident.ctcpsource
+			    : "http://hg.malikania.fr/irccd");
 		else if (strcmp(msg->args[1], "\x01""TIME\x01") == 0) {
 			time_t now = time(NULL);
 
-			irc_server_send(s, "NOTICE %s :\x01""TIME %s\x01",
-			    msg->prefix, ctime(&now));
-		} else if (strcmp(msg->args[1], "\x01""VERSION\x01") == 0) {
-			/* Send a CTCP VERSION answer. */
+			irc_server_send(s, "NOTICE %s :\x01TIME %s\x01",
+			    user.nickname, ctime(&now));
+		} else if (strcmp(msg->args[1], "\x01VERSION\x01") == 0) {
 			if (strlen(s->ident.ctcpversion) != 0)
-				irc_server_send(s, "NOTICE %s :\x01""VERSION %s\x01",
-				    msg->prefix, s->ident.ctcpversion);
-		} else if (strncmp(msg->args[1], "\x01""ACTION\x01", 8) == 0) {
+				irc_server_send(s, "NOTICE %s :\x01VERSION %s\x01",
+				    user.nickname, s->ident.ctcpversion);
+		} else if (strncmp(msg->args[1], "\x01""ACTION", 7) == 0) {
 			ev->type = IRC_EVENT_ME;
 			ev->message.origin = irc_util_strdup(msg->prefix);
 			ev->message.channel = irc_util_strdup(msg->args[0]);
--- a/lib/irccd/server.h	Wed Aug 04 10:27:04 2021 +0200
+++ b/lib/irccd/server.h	Fri Aug 13 10:20:25 2021 +0200
@@ -64,7 +64,8 @@
 	char username[IRC_USERNAME_LEN];
 	char realname[IRC_REALNAME_LEN];
 	char password[IRC_PASSWORD_LEN];
-	char ctcpversion[IRC_CTCPVERSION_LEN];
+	char ctcpversion[IRC_CTCP_LEN];
+	char ctcpsource[IRC_CTCP_LEN];
 };
 
 struct irc_server_params {
--- a/man/irccd.conf.5	Wed Aug 04 10:27:04 2021 +0200
+++ b/man/irccd.conf.5	Fri Aug 13 10:20:25 2021 +0200
@@ -183,6 +183,19 @@
 .Ar password@
 if required. You must use double quotes if the channel starts with a hash (#)
 otherwise it would be detected as a comment.
+.It Ar ctcp { key value }
+Specify a CTCP version reply to
+.Ar value
+for the given
+.Ar key
+which may be one of
+.Dq version
+or
+.Dq source .
+The possible
+.Ar key
+are overriding their uppercase CTCP queries. Each entry in this block
+should be terminated by a semicolon.
 .It Ar options list
 Use specific server features. This is a list of string which can be one of
 following:
@@ -315,11 +328,17 @@
 # This channel will automatically join "#test" on connection and the password
 # protected "#nightclub" channel with password "secret"
 #
+# We also override the CTCP VERSION and SOURCE reply.
+#
 server example {
 	hostname example.org;
 	port 6667;
 	ident fr francis "Francis Meyer";
 	channels "#test", "secret@#nightclub";
+	ctcp {
+		version "custom CTCP VERSION reply";
+		source "custom SCM repository";
+	}
 }
 
 # Load several plugins with their default values and locations.