From 94186f7888d5a730e52e433a21698154dfcc4e2e Mon Sep 17 00:00:00 2001 From: Diogo Sousa Date: Sat, 22 Jun 2013 00:13:36 +0100 Subject: First step towards message tags extension support (see http://ircv3.atheme.org/specification/message-tags-3.2). In particular this commit implements a (very) dummy implementation sketch of the server-time extension (see http://ircv3.atheme.org/specification/message-tags-3.2 and #499). --- src/common/proto-irc.c | 83 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 10 deletions(-) (limited to 'src/common/proto-irc.c') diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index ec4a36a3..1061b42c 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -29,6 +29,7 @@ #endif #include "hexchat.h" +#include "proto-irc.h" #include "ctcp.h" #include "fe.h" #include "ignore.h" @@ -959,7 +960,8 @@ process_numeric (session * sess, int n, /* handle named messages that starts with a ':' */ static void -process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) +process_named_msg (session *sess, char *type, char *word[], char *word_eol[], + const message_tags_data const *tags_data) { server *serv = sess->server; char ip[128], nick[NICKLEN]; @@ -1173,7 +1175,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) { if (ignore_check (word[1], IG_CHAN)) return; - inbound_chanmsg (serv, NULL, to, nick, text, FALSE, id); + inbound_chanmsg (serv, NULL, to, nick, text, FALSE, id, tags_data); } else { if (ignore_check (word[1], IG_PRIV)) @@ -1368,8 +1370,55 @@ process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol EMIT_SIGNAL (XP_TE_SERVTEXT, sess, buf, sess->server->servername, rawname, NULL, 0); } -/* irc_inline() - 1 single line received from serv */ +/* Handle time-server tags. + * + * Sets timestamp to the correct time. This needs to take into account that + * time is in UTC, so we should convert it to our local time. + * + * See http://ircv3.atheme.org/extensions/server-time-3.2 + */ +static void +handle_message_tag_time (const char const *time, message_tags_data *tags_data) +{ + /* TODO, obviously :P */ + tags_data->timestamp = 44332211; +} + +/* Handle message tags. + * + * See http://ircv3.atheme.org/specification/message-tags-3.2 + */ +/* FIXME: we should ignore capabilities not enabled! */ +static void +handle_message_tags (const char const *tags_str, message_tags_data *tags_data) +{ + char **tags; + int i; + + /* FIXME We might want to avoid the allocation overhead here since + * this might be called for every message from the server. + */ + tags = g_strsplit (tags_str, ";", 0); + + for (i=0; tags[i]; i++) + { + char *key = tags[i]; + char *value = strchr (tags[i], '='); + + if (!value) + continue; + + *value = '\0'; + value++; + + if (!strcmp (key, "time")) + handle_message_tag_time (value, tags_data); + } + + g_strfreev (tags); +} +/* irc_inline() - 1 single line received from serv */ static void irc_inline (server *serv, char *buf, int len) { @@ -1379,8 +1428,7 @@ irc_inline (server *serv, char *buf, int len) char *word_eol[PDIWORDS+1]; char pdibuf_static[522]; /* 1 line can potentially be 512*6 in utf8 */ char *pdibuf = pdibuf_static; - - url_check_line (buf, len); + message_tags_data tags_data = MESSAGE_TAGS_DATA_INIT; /* need more than 522? fall back to malloc */ if (len >= sizeof (pdibuf_static)) @@ -1392,11 +1440,27 @@ irc_inline (server *serv, char *buf, int len) word[PDIWORDS] = NULL; word_eol[PDIWORDS] = NULL; - if (buf[0] == ':') + if (*buf == '@') { - /* split line into words and words_to_end_of_line */ - process_data_init (pdibuf, buf, word, word_eol, FALSE, FALSE); + char *tags = buf + 1; /* skip the '@' */ + char *sep = strchr (buf, ' '); + if (!sep) + goto xit; + + *sep = '\0'; + buf = sep + 1; + + handle_message_tags(tags, &tags_data); + } + + url_check_line (buf, len); + + /* split line into words and words_to_end_of_line */ + process_data_init (pdibuf, buf, word, word_eol, FALSE, FALSE); + + if (buf[0] == ':') + { /* find a context for this message */ if (is_channel (serv, word[3])) { @@ -1417,7 +1481,6 @@ irc_inline (server *serv, char *buf, int len) } else { - process_data_init (pdibuf, buf, word, word_eol, FALSE, FALSE); word[0] = type = word[1]; if (plugin_emit_server (sess, type, word, word_eol)) goto xit; @@ -1439,7 +1502,7 @@ irc_inline (server *serv, char *buf, int len) process_numeric (sess, atoi (word[2]), word, word_eol, text); } else { - process_named_msg (sess, type, word, word_eol); + process_named_msg (sess, type, word, word_eol, &tags_data); } xit: -- cgit 1.4.1