summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/common/hexchat.h1
-rw-r--r--src/common/inbound.c115
-rw-r--r--src/common/proto-irc.c10
-rw-r--r--src/common/server.c1
4 files changed, 82 insertions, 45 deletions
diff --git a/src/common/hexchat.h b/src/common/hexchat.h
index 1a759f14..ca9f9c44 100644
--- a/src/common/hexchat.h
+++ b/src/common/hexchat.h
@@ -593,6 +593,7 @@ typedef struct server
 	unsigned int have_idmsg:1;		/* freenode's IDENTIFY-MSG */
 	unsigned int have_accnotify:1; /* cap account-notify */
 	unsigned int have_extjoin:1;	/* cap extended-join */
+	unsigned int have_server_time:1;	/* cap server-time */
 	unsigned int have_sasl:1;		/* SASL capability */
 	unsigned int have_except:1;	/* ban exemptions +e */
 	unsigned int have_invite:1;	/* invite exemptions +I */
diff --git a/src/common/inbound.c b/src/common/inbound.c
index a37ca31b..82f5826a 100644
--- a/src/common/inbound.c
+++ b/src/common/inbound.c
@@ -1239,7 +1239,8 @@ inbound_next_nick (session *sess, char *nick, int error,
 		break;
 
 	default:
-		EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKFAIL, sess, NULL, NULL, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKFAIL, sess, NULL, NULL, NULL, NULL, 0,
+									  tags_data->timestamp);
 	}
 }
 
@@ -1549,32 +1550,37 @@ inbound_cap_ack (server *serv, char *nick, char *extensions,
 	EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPACK, serv->server_session, nick, extensions,
 								  NULL, NULL, 0, tags_data->timestamp);
 
-	if (strstr (extensions, "identify-msg") != 0)
+	if (strstr (extensions, "identify-msg") != NULL)
 	{
 		serv->have_idmsg = TRUE;
 	}
 
-	if (strstr (extensions, "multi-prefix") != 0)
+	if (strstr (extensions, "multi-prefix") != NULL)
 	{
 		serv->have_namesx = TRUE;
 	}
 
-	if (strstr (extensions, "away-notify") != 0)
+	if (strstr (extensions, "away-notify") != NULL)
 	{
 		serv->have_awaynotify = TRUE;
 	}
 
-	if (strstr (extensions, "account-notify") != 0)
+	if (strstr (extensions, "account-notify") != NULL)
 	{
 		serv->have_accnotify = TRUE;
 	}
 					
-	if (strstr (extensions, "extended-join") != 0)
+	if (strstr (extensions, "extended-join") != NULL)
 	{
 		serv->have_extjoin = TRUE;
 	}
 
-	if (strstr (extensions, "sasl") != 0)
+	if (strstr (extensions, "server-time") != NULL)
+	{
+		serv->have_server_time = TRUE;
+	}
+
+	if (strstr (extensions, "sasl") != NULL)
 	{
 		char *user;
 
@@ -1594,53 +1600,82 @@ inbound_cap_ack (server *serv, char *nick, char *extensions,
 }
 
 void
-inbound_cap_ls (server *serv, char *nick, char *extensions,
+inbound_cap_ls (server *serv, char *nick, char *extensions_str,
 					 const message_tags_data *tags_data)
 {
 	char buffer[256];	/* buffer for requesting capabilities and emitting the signal */
 	guint32 want_cap; /* format the CAP REQ string based on previous capabilities being requested or not */
 	guint32 want_sasl; /* CAP END shouldn't be sent when SASL is requested, it needs further responses */
+	char **extensions;
+	int i;
 
-	EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPLIST, serv->server_session, nick, extensions,
-								  NULL, NULL, 0, tags_data->timestamp);
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPLIST, serv->server_session, nick,
+								  extensions_str, NULL, NULL, 0, tags_data->timestamp);
 	want_cap = 0;
 	want_sasl = 0;
 
+	extensions = g_strsplit (extensions_str, " ", 0);
+
 	strcpy (buffer, "CAP REQ :");
 
-	if (strstr (extensions, "identify-msg") != 0)
-	{
-		strcat (buffer, "identify-msg ");
-		want_cap = 1;
-	}
-	if (strstr (extensions, "multi-prefix") != 0)
-	{
-		strcat (buffer, "multi-prefix ");
-		want_cap = 1;
-	}
-	if (strstr (extensions, "away-notify") != 0)
-	{
-		strcat (buffer, "away-notify ");
-		want_cap = 1;
-	}
-	if (strstr (extensions, "account-notify") != 0)
-	{
-		strcat (buffer, "account-notify ");
-		want_cap = 1;
-	}
-	if (strstr (extensions, "extended-join") != 0)
+	for (i=0; extensions[i]; i++)
 	{
-		strcat (buffer, "extended-join ");
-		want_cap = 1;
-	}
-	/* if the SASL password is set AND auth mode is set to SASL, request SASL auth */
-	if (strstr (extensions, "sasl") != 0 && strlen (serv->password) != 0 && serv->loginmethod == LOGIN_SASL)
-	{
-		strcat (buffer, "sasl ");
-		want_cap = 1;
-		want_sasl = 1;
+		const char *extension = extensions[i];
+
+		if (!strcmp (extension, "identify-msg"))
+		{
+			strcat (buffer, "identify-msg ");
+			want_cap = 1;
+		}
+		if (!strcmp (extension, "multi-prefix"))
+		{
+			strcat (buffer, "multi-prefix ");
+			want_cap = 1;
+		}
+		if (!strcmp (extension, "away-notify"))
+		{
+			strcat (buffer, "away-notify ");
+			want_cap = 1;
+		}
+		if (!strcmp (extension, "account-notify"))
+		{
+			strcat (buffer, "account-notify ");
+			want_cap = 1;
+		}
+		if (!strcmp (extension, "extended-join"))
+		{
+			strcat (buffer, "extended-join ");
+			want_cap = 1;
+		}
+
+		/* bouncers can prefix a name space to the extension so we should use.
+		 * znc uses "znc.in/server-time".
+		 */
+		if (!strcmp (extension, "znc.in/server-time"))
+		{
+			strcat (buffer, "znc.in/server-time");
+			strcat (buffer, " ");
+		}
+		else if (!strcmp (extension, "server-time"))
+		{
+			/* ignore. it is best to have server-time explicitly enabled or have
+			 * a option in the preferences (or per server).
+			 */
+		}
+		
+		/* if the SASL password is set AND auth mode is set to SASL, request SASL auth */
+		if (serv->loginmethod == LOGIN_SASL
+			 && strcmp (extension, "sasl") != 0
+			 && strlen (serv->password) != 0)
+		{
+			strcat (buffer, "sasl ");
+			want_cap = 1;
+			want_sasl = 1;
+		}
 	}
 
+	g_strfreev (extensions);
+
 	if (want_cap)
 	{
 		/* buffer + 9 = emit buffer without "CAP REQ :" */
diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c
index 3c9a63e5..875247e7 100644
--- a/src/common/proto-irc.c
+++ b/src/common/proto-irc.c
@@ -1384,9 +1384,9 @@ handle_message_tag_time (const char *time, message_tags_data *tags_data)
  *
  * See http://ircv3.atheme.org/specification/message-tags-3.2 
  */
-/* TODO:orium: we should ignore capabilities not enabled! */
 static void
-handle_message_tags (const char *tags_str, message_tags_data *tags_data)
+handle_message_tags (server *serv, const char *tags_str,
+							message_tags_data *tags_data)
 {
 	char **tags;
 	int i;
@@ -1407,7 +1407,7 @@ handle_message_tags (const char *tags_str, message_tags_data *tags_data)
 		*value = '\0';
 		value++;
 
-		if (!strcmp (key, "time"))
+		if (serv->have_server_time && !strcmp (key, "time"))
 			handle_message_tag_time (value, tags_data);
 	}
 	
@@ -1447,7 +1447,7 @@ irc_inline (server *serv, char *buf, int len)
 		*sep = '\0';
 		buf = sep + 1;
 
-		handle_message_tags(tags, &tags_data);
+		handle_message_tags(serv, tags, &tags_data);
 	}
 
 	url_check_line (buf, len);
@@ -1495,7 +1495,7 @@ irc_inline (server *serv, char *buf, int len)
 		if (*text == ':')
 			text++;
 
-		process_numeric (sess, atoi (word[2]), word, word_eol, text, &tags_data); // TODO:orium (data tags)
+		process_numeric (sess, atoi (word[2]), word, word_eol, text, &tags_data);
 	} else
 	{
 		process_named_msg (sess, type, word, word_eol, &tags_data);
diff --git a/src/common/server.c b/src/common/server.c
index 99e7563e..e59a7ee3 100644
--- a/src/common/server.c
+++ b/src/common/server.c
@@ -1895,6 +1895,7 @@ server_set_defaults (server *serv)
 	serv->have_idmsg = FALSE;
 	serv->have_accnotify = FALSE;
 	serv->have_extjoin = FALSE;
+	serv->have_server_time = FALSE;
 	serv->have_sasl = FALSE;
 	serv->have_except = FALSE;
 	serv->have_invite = FALSE;