summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPatrick Griffis <tingping@tingping.se>2016-01-28 16:02:04 -0500
committerPatrick Griffis <tingping@tingping.se>2016-01-28 16:02:04 -0500
commit7a85c9160dbff92502f60c2651e572039de3e8ba (patch)
tree2ffcf0c68f96fbd5a2d4f85b2e72e9a1a968a9c8
parent4e061a43b3453a9856d34250c3913175c45afe9d (diff)
Add support for cap-notify
-rw-r--r--src/common/inbound.c119
-rw-r--r--src/common/inbound.h2
-rw-r--r--src/common/proto-irc.c8
-rw-r--r--src/common/text.c5
-rw-r--r--src/common/textevents.in6
5 files changed, 86 insertions, 54 deletions
diff --git a/src/common/inbound.c b/src/common/inbound.c
index 645cc824..70aa5b2e 100644
--- a/src/common/inbound.c
+++ b/src/common/inbound.c
@@ -1633,70 +1633,82 @@ inbound_identified (server *serv)	/* 'MODE +e MYSELF' on freenode */
 	}
 }
 
-void
-inbound_cap_ack (server *serv, char *nick, char *extensions,
-					  const message_tags_data *tags_data)
+static void
+inbound_toggle_caps (server *serv, const char *extensions_str, gboolean enable)
 {
-	EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPACK, serv->server_session, nick, extensions,
-								  NULL, NULL, 0, tags_data->timestamp);
+	char **extensions;
+	gsize i;
 
-	if (strstr (extensions, "identify-msg") != NULL)
-	{
-		serv->have_idmsg = TRUE;
-	}
+	extensions = g_strsplit (extensions_str, " ", 0);
 
-	if (strstr (extensions, "multi-prefix") != NULL)
+	for (i = 0; extensions[i]; i++)
 	{
-		serv->have_namesx = TRUE;
-	}
+		const char *extension = extensions[i];
 
-	if (strstr (extensions, "away-notify") != NULL)
-	{
-		serv->have_awaynotify = TRUE;
-	}
+		if (!strcmp (extension, "identify-msg"))
+			serv->have_idmsg = enable;
+		else if (!strcmp (extension, "multi-prefix"))
+			serv->have_namesx = enable;
+		else if (!strcmp (extension, "account-notify"))
+			serv->have_accnotify = enable;
+		else if (!strcmp (extension, "extended-join"))
+			serv->have_extjoin = enable;
+		else if (!strcmp (extension, "userhost-in-names"))
+			serv->have_uhnames = enable;
+		else if (!strcmp (extension, "server-time")
+				|| !strcmp (extension, "znc.in/server-time")
+				|| !strcmp (extension, "znc.in/server-time-iso"))
+			serv->have_server_time = enable;
+		else if (!strcmp (extension, "away-notify"))
+			serv->have_awaynotify = enable;
+		else if (!strcmp (extension, "sasl"))
+		{
+			serv->have_sasl = enable;
+			if (enable)
+			{
+				serv->sent_saslauth = FALSE;
 
-	if (strstr (extensions, "account-notify") != NULL)
-	{
-		serv->have_accnotify = TRUE;
-	}
-					
-	if (strstr (extensions, "extended-join") != NULL)
-	{
-		serv->have_extjoin = TRUE;
+#ifdef USE_OPENSSL
+				if (serv->loginmethod == LOGIN_SASLEXTERNAL)
+				{
+					serv->sasl_mech = MECH_EXTERNAL;
+					tcp_send_len (serv, "AUTHENTICATE EXTERNAL\r\n", 23);
+				}
+				else
+				{
+					/* default to most secure, it will fallback if not supported */
+					serv->sasl_mech = MECH_AES;
+					tcp_send_len (serv, "AUTHENTICATE DH-AES\r\n", 21);
+				}
+#else
+				serv->sasl_mech = MECH_PLAIN;
+				tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20);
+#endif
+			}
+		}
 	}
 
-	if (strstr (extensions, "userhost-in-names") != NULL)
-	{
-		serv->have_uhnames = TRUE;
-	}
+	g_strfreev (extensions);
+}
 
-	if (strstr (extensions, "server-time") != NULL)
-	{
-		serv->have_server_time = TRUE;
-	}
+void
+inbound_cap_ack (server *serv, char *nick, char *extensions,
+					  const message_tags_data *tags_data)
+{
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPACK, serv->server_session, nick, extensions,
+								  NULL, NULL, 0, tags_data->timestamp);
 
-	if (strstr (extensions, "sasl") != NULL)
-	{
-		serv->have_sasl = TRUE;
-		serv->sent_saslauth = FALSE;
+	inbound_toggle_caps (serv, extensions, TRUE);
+}
 
-#ifdef USE_OPENSSL
-		if (serv->loginmethod == LOGIN_SASLEXTERNAL)
-		{
-			serv->sasl_mech = MECH_EXTERNAL;
-			tcp_send_len (serv, "AUTHENTICATE EXTERNAL\r\n", 23);
-		}
-		else
-		{
-			/* default to most secure, it will fallback if not supported */
-			serv->sasl_mech = MECH_AES;
-			tcp_send_len (serv, "AUTHENTICATE DH-AES\r\n", 21);
-		}
-#else
-		serv->sasl_mech = MECH_PLAIN;
-		tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20);
-#endif
-	}
+void
+inbound_cap_del (server *serv, char *nick, char *extensions,
+					 const message_tags_data *tags_data)
+{
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPDEL, serv->server_session, nick, extensions,
+								  NULL, NULL, 0, tags_data->timestamp);
+
+	inbound_toggle_caps (serv, extensions, FALSE);
 }
 
 static const char * const supported_caps[] = {
@@ -1712,6 +1724,7 @@ static const char * const supported_caps[] = {
 	/* IRCv3.2 */
 	"server-time"
 	"userhost-in-names",
+	"cap-notify",
 
 	/* ZNC */
 	"znc.in/server-time-iso",
diff --git a/src/common/inbound.h b/src/common/inbound.h
index bbba2e22..c5d10445 100644
--- a/src/common/inbound.h
+++ b/src/common/inbound.h
@@ -95,6 +95,8 @@ void inbound_cap_ls (server *serv, char *nick, char *extensions,
 void inbound_cap_nak (server *serv, const message_tags_data *tags_data);
 void inbound_cap_list (server *serv, char *nick, char *extensions,
 							  const message_tags_data *tags_data);
+void inbound_cap_del (server *serv, char *nick, char *extensions,
+							  const message_tags_data *tags_data);
 void inbound_sasl_authenticate (server *serv, char *data);
 int inbound_sasl_error (server *serv);
 void inbound_sasl_supportedmechs (server *serv, char *list);
diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c
index d8f15cb5..b737d23b 100644
--- a/src/common/proto-irc.c
+++ b/src/common/proto-irc.c
@@ -1280,7 +1280,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
 										  word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5],
 										  tags_data);
 				}
-				else if (strncasecmp (word[4], "LS", 2) == 0)
+				else if (strncasecmp (word[4], "LS", 2) == 0 || strncasecmp (word[4], "NEW", 3) == 0)
 				{
 					inbound_cap_ls (serv, word[1], 
 										 word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5],
@@ -1296,6 +1296,12 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
 											word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5],
 											tags_data);
 				}
+				else if (strncasecmp (word[4], "DEL", 3) == 0)
+				{
+					inbound_cap_del (serv, word[1],
+											word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5],
+											tags_data);
+				}
 
 				return;
 		}
diff --git a/src/common/text.c b/src/common/text.c
index cd9ea26e..8cf850ba 100644
--- a/src/common/text.c
+++ b/src/common/text.c
@@ -976,6 +976,11 @@ static char * const pevt_capack_help[] = {
 	N_("Acknowledged Capabilities")
 };
 
+static char * const pevt_capdel_help[] = {
+	N_("Server Name"),
+	N_("Removed Capabilities")
+};
+
 static char * const pevt_caplist_help[] = {
 	N_("Server Name"),
 	N_("Server Capabilities")
diff --git a/src/common/textevents.in b/src/common/textevents.in
index 26e2b3e3..e4405ca3 100644
--- a/src/common/textevents.in
+++ b/src/common/textevents.in
@@ -28,6 +28,12 @@ pevt_capack_help
 %C29*%O$tCapabilities acknowledged: %C29$2%O
 2
 
+Capability Deleted
+XP_TE_CAPDEL
+pevt_capdel_help
+%C29*%O$tCapabilities removed: %C29$2%O
+2
+
 Capability List
 XP_TE_CAPLIST
 pevt_caplist_help