summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2021-06-21 00:29:36 +0100
committerGitHub <noreply@github.com>2021-06-20 23:29:36 +0000
commitd5b45773157f40e1f078a5b02695d3fa2bb41b2d (patch)
treeb5a19a48747fce0d9bdfaafd4a819094e618878c
parent55e4f1c42e8d1131b01659fad67db5d084780227 (diff)
Implement generic support for IRCv3 standard replies. (#2589)
https://ircv3.net/specs/extensions/standard-replies

Co-authored-by: Patrick <tingping@tingping.se>
-rw-r--r--src/common/proto-irc.c45
-rw-r--r--src/common/text.c11
-rw-r--r--src/common/textevents.in36
3 files changed, 92 insertions, 0 deletions
diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c
index 54a73e97..e0aa888e 100644
--- a/src/common/proto-irc.c
+++ b/src/common/proto-irc.c
@@ -460,6 +460,18 @@ channel_date (session *sess, char *chan, char *timestr,
 								  tags_data->timestamp);
 }
 
+static int
+trailing_index(const char *word_eol[])
+{
+	int param_index;
+	for (param_index = 3; param_index < PDIWORDS; ++param_index)
+	{
+		if (word_eol[param_index][0] == ':')
+			break;
+	}
+	return param_index;
+}
+
 static void
 process_numeric (session * sess, int n,
 					  char *word[], char *word_eol[], char *text,
@@ -1139,6 +1151,39 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
 										(word_eol[3][0] == ':') ? word_eol[3] + 1 : NULL,
 										tags_data);
 			return;
+
+		case WORDL('F','A','I','L'):
+			text = STRIP_COLON(word, word_eol, trailing_index(word_eol));
+			if (g_strcmp0(word[3], "*") == 0)
+			{
+				EMIT_SIGNAL_TIMESTAMP (XP_TE_FAIL, sess, word[4], text, NULL, NULL, NULL, tags_data->timestamp);
+			} else
+			{
+				EMIT_SIGNAL_TIMESTAMP (XP_TE_FAILCMD, sess, word[3], word[4], text, NULL, NULL, tags_data->timestamp);
+			}
+			return;
+
+		case WORDL('W','A','R','N'):
+			text = STRIP_COLON(word, word_eol, trailing_index(word_eol));
+			if (g_strcmp0(word[3], "*") == 0)
+			{
+				EMIT_SIGNAL_TIMESTAMP (XP_TE_WARN, sess, word[4], text, NULL, NULL, NULL, tags_data->timestamp);
+			} else
+			{
+				EMIT_SIGNAL_TIMESTAMP (XP_TE_WARNCMD, sess, word[3], word[4], text, NULL, NULL, tags_data->timestamp);
+			}
+			return;
+
+		case WORDL('N','O','T','E'):
+			text = STRIP_COLON(word, word_eol, trailing_index(word_eol));
+			if (g_strcmp0(word[3], "*") == 0)
+			{
+				EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTE, sess, word[4], text, NULL, NULL, NULL, tags_data->timestamp);
+			} else
+			{
+				EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTECMD, sess, word[3], word[4], text, NULL, NULL, tags_data->timestamp);
+			}
+			return;
 		}
 
 		goto garbage;
diff --git a/src/common/text.c b/src/common/text.c
index b0a90e03..a77700fa 100644
--- a/src/common/text.c
+++ b/src/common/text.c
@@ -1512,6 +1512,17 @@ static char * const pevt_discon_help[] = {
 	N_("Error"),
 };
 
+static char * const pevt_stdrpl_help[] = {
+	N_("Error Code"),
+	N_("Error Message"),
+};
+
+static char * const pevt_stdrplcmd_help[] = {
+	N_("Command"),
+	N_("Error Code"),
+	N_("Error Message"),
+};
+
 #include "textevents.h"
 
 static void
diff --git a/src/common/textevents.in b/src/common/textevents.in
index 14bd4b06..19b0d497 100644
--- a/src/common/textevents.in
+++ b/src/common/textevents.in
@@ -436,6 +436,18 @@ pevt_discon_help
 %C20*%O$tDisconnected (%C20$1%O)
 1
 
+Fail
+XP_TE_FAIL
+pevt_stdrpl_help
+%C20*%O$t$2%O
+2
+
+Fail Command
+XP_TE_FAILCMD
+pevt_stdrplcmd_help
+%C20*%O$t$1: $3%O
+3
+
 Found IP
 XP_TE_FOUNDIP
 pevt_foundip_help
@@ -574,6 +586,18 @@ pevt_generic_none_help
 %C23*%O$tNo process is currently running
 0
 
+Note
+XP_TE_NOTE
+pevt_stdrpl_help
+%C22*%O$t$2%O
+2
+
+Note Command
+XP_TE_NOTECMD
+pevt_stdrplcmd_help
+%C22*%O$t$1: $3%O
+3
+
 Notice
 XP_TE_NOTICE
 pevt_notice_help
@@ -802,6 +826,18 @@ pevt_usersonchan_help
 %C22*%O$tUsers on %C22$1%C: %C24$2%O
 2
 
+Warn
+XP_TE_WARN
+pevt_stdrpl_help
+%C23*%O$t$2%O
+2
+
+Warn Command
+XP_TE_WARNCMD
+pevt_stdrplcmd_help
+%C23*%O$t$1: $3%O
+3
+
 WhoIs Authenticated
 XP_TE_WHOIS_AUTH
 pevt_whoisauth_help