summary refs log tree commit diff stats
path: root/src/common/inbound.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/inbound.c')
-rw-r--r--src/common/inbound.c424
1 files changed, 329 insertions, 95 deletions
diff --git a/src/common/inbound.c b/src/common/inbound.c
index b1b739e5..2645c438 100644
--- a/src/common/inbound.c
+++ b/src/common/inbound.c
@@ -122,13 +122,15 @@ find_session_from_nick (char *nick, server *serv)
 }
 
 static session *
-inbound_open_dialog (server *serv, char *from)
+inbound_open_dialog (server *serv, char *from,
+							const message_tags_data *tags_data)
 {
 	session *sess;
 
 	sess = new_ircwindow (serv, from, SESS_DIALOG, 0);
 	/* for playing sounds */
-	EMIT_SIGNAL (XP_TE_OPENDIALOG, sess, NULL, NULL, NULL, NULL, 0);
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_OPENDIALOG, sess, NULL, NULL, NULL, NULL, 0,
+								  tags_data->timestamp);
 
 	return sess;
 }
@@ -152,7 +154,8 @@ inbound_make_idtext (server *serv, char *idtext, int max, int id)
 }
 
 void
-inbound_privmsg (server *serv, char *from, char *ip, char *text, int id)
+inbound_privmsg (server *serv, char *from, char *ip, char *text, int id,
+					  const message_tags_data *tags_data)
 {
 	session *sess;
 	struct User *user;
@@ -168,7 +171,7 @@ inbound_privmsg (server *serv, char *from, char *ip, char *text, int id)
 		{
 			if (flood_check (from, ip, serv, current_sess, 1))
 				/* Create a dialog session */
-				sess = inbound_open_dialog (serv, from);
+				sess = inbound_open_dialog (serv, from, tags_data);
 			else
 				sess = serv->server_session;
 			if (!sess)
@@ -186,7 +189,7 @@ inbound_privmsg (server *serv, char *from, char *ip, char *text, int id)
 			}
 			set_topic (sess, ip, ip);
 		}
-		inbound_chanmsg (serv, NULL, NULL, from, text, FALSE, id);
+		inbound_chanmsg (serv, NULL, NULL, from, text, FALSE, id, tags_data);
 		return;
 	}
 
@@ -208,9 +211,11 @@ inbound_privmsg (server *serv, char *from, char *ip, char *text, int id)
 	inbound_make_idtext (serv, idtext, sizeof (idtext), id);
 
 	if (sess->type == SESS_DIALOG && !nodiag)
-		EMIT_SIGNAL (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0,
+									  tags_data->timestamp);
 	else
-		EMIT_SIGNAL (XP_TE_PRIVMSG, sess, from, text, idtext, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_PRIVMSG, sess, from, text, idtext, NULL, 0, 
+									  tags_data->timestamp);
 }
 
 /* used for Alerts section. Masks can be separated by commas and spaces. */
@@ -323,7 +328,8 @@ is_hilight (char *from, char *text, session *sess, server *serv)
 }
 
 void
-inbound_action (session *sess, char *chan, char *from, char *ip, char *text, int fromme, int id)
+inbound_action (session *sess, char *chan, char *from, char *ip, char *text,
+					 int fromme, int id, const message_tags_data *tags_data)
 {
 	session *def = sess;
 	server *serv = sess->server;
@@ -348,7 +354,7 @@ inbound_action (session *sess, char *chan, char *from, char *ip, char *text, int
 			{
 				/* but only if it wouldn't flood */
 				if (flood_check (from, ip, serv, current_sess, 1))
-					sess = inbound_open_dialog (serv, from);
+					sess = inbound_open_dialog (serv, from, tags_data);
 				else
 					sess = serv->server_session;
 			}
@@ -394,23 +400,30 @@ inbound_action (session *sess, char *chan, char *from, char *ip, char *text, int
 	{
 		if (is_hilight (from, text, sess, serv))
 		{
-			EMIT_SIGNAL (XP_TE_HCHANACTION, sess, from, text, nickchar, idtext, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_HCHANACTION, sess, from, text, nickchar,
+										  idtext, 0, tags_data->timestamp);
 			return;
 		}
 	}
 
 	if (fromme)
-		EMIT_SIGNAL (XP_TE_UACTION, sess, from, text, nickchar, idtext, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_UACTION, sess, from, text, nickchar, idtext,
+									  0, tags_data->timestamp);
 	else if (!privaction)
-		EMIT_SIGNAL (XP_TE_CHANACTION, sess, from, text, nickchar, idtext, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANACTION, sess, from, text, nickchar,
+									  idtext, 0, tags_data->timestamp);
 	else if (sess->type == SESS_DIALOG)
-		EMIT_SIGNAL (XP_TE_DPRIVACTION, sess, from, text, idtext, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_DPRIVACTION, sess, from, text, idtext, NULL,
+									  0, tags_data->timestamp);
 	else
-		EMIT_SIGNAL (XP_TE_PRIVACTION, sess, from, text, idtext, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_PRIVACTION, sess, from, text, idtext, NULL, 0,
+									  tags_data->timestamp);
 }
 
 void
-inbound_chanmsg (server *serv, session *sess, char *chan, char *from, char *text, char fromme, int id)
+inbound_chanmsg (server *serv, session *sess, char *chan, char *from, 
+					  char *text, char fromme, int id, 
+					  const message_tags_data *tags_data)
 {
 	struct User *user;
 	int hilight = FALSE;
@@ -452,7 +465,8 @@ inbound_chanmsg (server *serv, session *sess, char *chan, char *from, char *text
 	{
   		if (prefs.hex_away_auto_unmark && serv->is_away)
 			sess->server->p_set_back (sess->server);
-		EMIT_SIGNAL (XP_TE_UCHANMSG, sess, from, text, nickchar, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_UCHANMSG, sess, from, text, nickchar, NULL,
+									  0, tags_data->timestamp);
 		return;
 	}
 
@@ -462,15 +476,19 @@ inbound_chanmsg (server *serv, session *sess, char *chan, char *from, char *text
 		hilight = TRUE;
 
 	if (sess->type == SESS_DIALOG)
-		EMIT_SIGNAL (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0,
+									  tags_data->timestamp);
 	else if (hilight)
-		EMIT_SIGNAL (XP_TE_HCHANMSG, sess, from, text, nickchar, idtext, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_HCHANMSG, sess, from, text, nickchar, idtext,
+									  0, tags_data->timestamp);
 	else
-		EMIT_SIGNAL (XP_TE_CHANMSG, sess, from, text, nickchar, idtext, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMSG, sess, from, text, nickchar, idtext,
+									  0, tags_data->timestamp);
 }
 
 void
-inbound_newnick (server *serv, char *nick, char *newnick, int quiet)
+inbound_newnick (server *serv, char *nick, char *newnick, int quiet,
+					  const message_tags_data *tags_data)
 {
 	int me = FALSE;
 	session *sess;
@@ -492,11 +510,12 @@ inbound_newnick (server *serv, char *nick, char *newnick, int quiet)
 				if (!quiet)
 				{
 					if (me)
-						EMIT_SIGNAL (XP_TE_UCHANGENICK, sess, nick, newnick, NULL,
-										 NULL, 0);
+						EMIT_SIGNAL_TIMESTAMP (XP_TE_UCHANGENICK, sess, nick, 
+													  newnick, NULL, NULL, 0,
+													  tags_data->timestamp);
 					else
-						EMIT_SIGNAL (XP_TE_CHANGENICK, sess, nick, newnick, NULL,
-										 NULL, 0);
+						EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANGENICK, sess, nick,
+													  newnick, NULL, NULL, 0, tags_data->timestamp);
 				}
 			}
 			if (sess->type == SESS_DIALOG && !serv->p_cmp (sess->channel, nick))
@@ -554,7 +573,8 @@ find_session_from_waitchannel (char *chan, struct server *serv)
 }
 
 void
-inbound_ujoin (server *serv, char *chan, char *nick, char *ip)
+inbound_ujoin (server *serv, char *chan, char *nick, char *ip,
+					const message_tags_data *tags_data)
 {
 	session *sess;
 
@@ -592,7 +612,8 @@ inbound_ujoin (server *serv, char *chan, char *nick, char *ip)
 	/* sends a MODE */
 	serv->p_join_info (sess->server, chan);
 
-	EMIT_SIGNAL (XP_TE_UJOIN, sess, nick, chan, ip, NULL, 0);
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_UJOIN, sess, nick, chan, ip, NULL, 0,
+								  tags_data->timestamp);
 
 	if (prefs.hex_irc_who_join)
 	{
@@ -603,12 +624,14 @@ inbound_ujoin (server *serv, char *chan, char *nick, char *ip)
 }
 
 void
-inbound_ukick (server *serv, char *chan, char *kicker, char *reason)
+inbound_ukick (server *serv, char *chan, char *kicker, char *reason,
+					const message_tags_data *tags_data)
 {
 	session *sess = find_channel (serv, chan);
 	if (sess)
 	{
-		EMIT_SIGNAL (XP_TE_UKICK, sess, serv->nick, chan, kicker, reason, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_UKICK, sess, serv->nick, chan, kicker, 
+									  reason, 0, tags_data->timestamp);
 		clear_channel (sess);
 		if (prefs.hex_irc_auto_rejoin)
 		{
@@ -619,22 +642,25 @@ inbound_ukick (server *serv, char *chan, char *kicker, char *reason)
 }
 
 void
-inbound_upart (server *serv, char *chan, char *ip, char *reason)
+inbound_upart (server *serv, char *chan, char *ip, char *reason,
+					const message_tags_data *tags_data)
 {
 	session *sess = find_channel (serv, chan);
 	if (sess)
 	{
 		if (*reason)
-			EMIT_SIGNAL (XP_TE_UPARTREASON, sess, serv->nick, ip, chan, reason,
-							 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_UPARTREASON, sess, serv->nick, ip, chan,
+										  reason, 0, tags_data->timestamp);
 		else
-			EMIT_SIGNAL (XP_TE_UPART, sess, serv->nick, ip, chan, NULL, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_UPART, sess, serv->nick, ip, chan, NULL,
+										  0, tags_data->timestamp);
 		clear_channel (sess);
 	}
 }
 
 void
-inbound_nameslist (server *serv, char *chan, char *names)
+inbound_nameslist (server *serv, char *chan, char *names,
+						 const message_tags_data *tags_data)
 {
 	session *sess;
 	char name[NICKLEN];
@@ -643,12 +669,13 @@ inbound_nameslist (server *serv, char *chan, char *names)
 	sess = find_channel (serv, chan);
 	if (!sess)
 	{
-		EMIT_SIGNAL (XP_TE_USERSONCHAN, serv->server_session, chan, names, NULL,
-						 NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_USERSONCHAN, serv->server_session, chan,
+									  names, NULL, NULL, 0, tags_data->timestamp);
 		return;
 	}
 	if (!sess->ignore_names)
-		EMIT_SIGNAL (XP_TE_USERSONCHAN, sess, chan, names, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_USERSONCHAN, sess, chan, names, NULL, NULL,
+									  0, tags_data->timestamp);
 
 	if (sess->end_of_names)
 	{
@@ -663,12 +690,12 @@ inbound_nameslist (server *serv, char *chan, char *names)
 		case 0:
 			name[pos] = 0;
 			if (pos != 0)
-				userlist_add (sess, name, 0, NULL, NULL);
+				userlist_add (sess, name, 0, NULL, NULL, tags_data);
 			return;
 		case ' ':
 			name[pos] = 0;
 			pos = 0;
-			userlist_add (sess, name, 0, NULL, NULL);
+			userlist_add (sess, name, 0, NULL, NULL, tags_data);
 			break;
 		default:
 			name[pos] = *names;
@@ -680,7 +707,8 @@ inbound_nameslist (server *serv, char *chan, char *names)
 }
 
 void
-inbound_topic (server *serv, char *chan, char *topic_text)
+inbound_topic (server *serv, char *chan, char *topic_text,
+					const message_tags_data *tags_data)
 {
 	session *sess = find_channel (serv, chan);
 	char *stripped_topic;
@@ -693,11 +721,13 @@ inbound_topic (server *serv, char *chan, char *topic_text)
 	} else
 		sess = serv->server_session;
 
-	EMIT_SIGNAL (XP_TE_TOPIC, sess, chan, topic_text, NULL, NULL, 0);
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_TOPIC, sess, chan, topic_text, NULL, NULL, 0,
+								  tags_data->timestamp);
 }
 
 void
-inbound_topicnew (server *serv, char *nick, char *chan, char *topic)
+inbound_topicnew (server *serv, char *nick, char *chan, char *topic,
+						const message_tags_data *tags_data)
 {
 	session *sess;
 	char *stripped_topic;
@@ -705,7 +735,8 @@ inbound_topicnew (server *serv, char *nick, char *chan, char *topic)
 	sess = find_channel (serv, chan);
 	if (sess)
 	{
-		EMIT_SIGNAL (XP_TE_NEWTOPIC, sess, nick, topic, chan, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_NEWTOPIC, sess, nick, topic, chan, NULL, 0,
+									  tags_data->timestamp);
 		stripped_topic = strip_color (topic, -1, STRIP_ALL);
 		set_topic (sess, topic, stripped_topic);
 		g_free (stripped_topic);
@@ -713,43 +744,51 @@ inbound_topicnew (server *serv, char *nick, char *chan, char *topic)
 }
 
 void
-inbound_join (server *serv, char *chan, char *user, char *ip, char *account, char *realname)
+inbound_join (server *serv, char *chan, char *user, char *ip, char *account,
+				  char *realname, const message_tags_data *tags_data)
 {
 	session *sess = find_channel (serv, chan);
 	if (sess)
 	{
-		EMIT_SIGNAL (XP_TE_JOIN, sess, user, chan, ip, NULL, 0);
-		userlist_add (sess, user, ip, account, realname);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_JOIN, sess, user, chan, ip, NULL, 0,
+									  tags_data->timestamp);
+		userlist_add (sess, user, ip, account, realname, tags_data);
 	}
 }
 
 void
-inbound_kick (server *serv, char *chan, char *user, char *kicker, char *reason)
+inbound_kick (server *serv, char *chan, char *user, char *kicker, char *reason,
+				  const message_tags_data *tags_data)
 {
 	session *sess = find_channel (serv, chan);
 	if (sess)
 	{
-		EMIT_SIGNAL (XP_TE_KICK, sess, kicker, user, chan, reason, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_KICK, sess, kicker, user, chan, reason, 0,
+									  tags_data->timestamp);
 		userlist_remove (sess, user);
 	}
 }
 
 void
-inbound_part (server *serv, char *chan, char *user, char *ip, char *reason)
+inbound_part (server *serv, char *chan, char *user, char *ip, char *reason,
+				  const message_tags_data *tags_data)
 {
 	session *sess = find_channel (serv, chan);
 	if (sess)
 	{
 		if (*reason)
-			EMIT_SIGNAL (XP_TE_PARTREASON, sess, user, ip, chan, reason, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_PARTREASON, sess, user, ip, chan, reason,
+										  0, tags_data->timestamp);
 		else
-			EMIT_SIGNAL (XP_TE_PART, sess, user, ip, chan, NULL, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_PART, sess, user, ip, chan, NULL, 0,
+										  tags_data->timestamp);
 		userlist_remove (sess, user);
 	}
 }
 
 void
-inbound_topictime (server *serv, char *chan, char *nick, time_t stamp)
+inbound_topictime (server *serv, char *chan, char *nick, time_t stamp,
+						 const message_tags_data *tags_data)
 {
 	char *tim = ctime (&stamp);
 	session *sess = find_channel (serv, chan);
@@ -758,11 +797,13 @@ inbound_topictime (server *serv, char *chan, char *nick, time_t stamp)
 		sess = serv->server_session;
 
 	tim[24] = 0;	/* get rid of the \n */
-	EMIT_SIGNAL (XP_TE_TOPICDATE, sess, chan, nick, tim, NULL, 0);
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_TOPICDATE, sess, chan, nick, tim, NULL, 0,
+								  tags_data->timestamp);
 }
 
 void
-inbound_quit (server *serv, char *nick, char *ip, char *reason)
+inbound_quit (server *serv, char *nick, char *ip, char *reason,
+				  const message_tags_data *tags_data)
 {
 	GSList *list = sess_list;
 	session *sess;
@@ -778,21 +819,24 @@ inbound_quit (server *serv, char *nick, char *ip, char *reason)
  				was_on_front_session = TRUE;
 			if ((user = userlist_find (sess, nick)))
 			{
-				EMIT_SIGNAL (XP_TE_QUIT, sess, nick, reason, ip, NULL, 0);
+				EMIT_SIGNAL_TIMESTAMP (XP_TE_QUIT, sess, nick, reason, ip, NULL, 0,
+											  tags_data->timestamp);
 				userlist_remove_user (sess, user);
 			} else if (sess->type == SESS_DIALOG && !serv->p_cmp (sess->channel, nick))
 			{
-				EMIT_SIGNAL (XP_TE_QUIT, sess, nick, reason, ip, NULL, 0);
+				EMIT_SIGNAL_TIMESTAMP (XP_TE_QUIT, sess, nick, reason, ip, NULL, 0,
+											  tags_data->timestamp);
 			}
 		}
 		list = list->next;
 	}
 
-	notify_set_offline (serv, nick, was_on_front_session);
+	notify_set_offline (serv, nick, was_on_front_session, tags_data);
 }
 
 void
-inbound_account (server *serv, char *nick, char *account)
+inbound_account (server *serv, char *nick, char *account,
+					  const message_tags_data *tags_data)
 {
 	session *sess = NULL;
 	GSList *list;
@@ -808,7 +852,8 @@ inbound_account (server *serv, char *nick, char *account)
 }
 
 void
-inbound_ping_reply (session *sess, char *timestring, char *from)
+inbound_ping_reply (session *sess, char *timestring, char *from,
+						  const message_tags_data *tags_data)
 {
 	unsigned long tim, nowtim, dif;
 	int lag = 0;
@@ -839,11 +884,13 @@ inbound_ping_reply (session *sess, char *timestring, char *from)
 		if (sess->server->lag_sent)
 			sess->server->lag_sent = 0;
 		else
-			EMIT_SIGNAL (XP_TE_PINGREP, sess, from, "?", NULL, NULL, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_PINGREP, sess, from, "?", NULL, NULL, 0,
+										  tags_data->timestamp);
 	} else
 	{
 		snprintf (outbuf, sizeof (outbuf), "%ld.%ld%ld", dif / 1000000, (dif / 100000) % 10, dif % 10);
-		EMIT_SIGNAL (XP_TE_PINGREP, sess, from, outbuf, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_PINGREP, sess, from, outbuf, NULL, NULL, 0,
+									  tags_data->timestamp);
 	}
 }
 
@@ -863,7 +910,8 @@ find_session_from_type (int type, server *serv)
 }
 
 void
-inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id)
+inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id,
+					 const message_tags_data *tags_data)
 {
 	char *po,*ptr=to;
 	session *sess = 0;
@@ -954,7 +1002,7 @@ inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id)
 		msg++;
 		if (!strncmp (msg, "PING", 4))
 		{
-			inbound_ping_reply (sess, msg + 5, nick);
+			inbound_ping_reply (sess, msg + 5, nick, tags_data);
 			return;
 		}
 	}
@@ -963,15 +1011,19 @@ inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id)
 		po[0] = 0;
 
 	if (server_notice)
-		EMIT_SIGNAL (XP_TE_SERVNOTICE, sess, msg, nick, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVNOTICE, sess, msg, nick, NULL, NULL, 0,
+									  tags_data->timestamp);
 	else if (ptr)
-		EMIT_SIGNAL (XP_TE_CHANNOTICE, sess, nick, to, msg, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANNOTICE, sess, nick, to, msg, NULL, 0,
+									  tags_data->timestamp);
 	else
-		EMIT_SIGNAL (XP_TE_NOTICE, sess, nick, msg, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTICE, sess, nick, msg, NULL, NULL, 0,
+									  tags_data->timestamp);
 }
 
 void
-inbound_away (server *serv, char *nick, char *msg)
+inbound_away (server *serv, char *nick, char *msg,
+				  const message_tags_data *tags_data)
 {
 	struct away_msg *away = server_away_find_message (serv, nick);
 	session *sess = NULL;
@@ -998,7 +1050,8 @@ inbound_away (server *serv, char *nick, char *msg)
 
 	/* possibly hide the output */
 	if (!serv->inside_whois || !serv->skip_next_whois)
-		EMIT_SIGNAL (XP_TE_WHOIS5, sess, nick, msg, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS5, sess, nick, msg, NULL, NULL, 0,
+									  tags_data->timestamp);
 
 	list = sess_list;
 	while (list)
@@ -1011,7 +1064,8 @@ inbound_away (server *serv, char *nick, char *msg)
 }
 
 void
-inbound_away_notify (server *serv, char *nick, char *reason)
+inbound_away_notify (server *serv, char *nick, char *reason,
+							const message_tags_data *tags_data)
 {
 	session *sess = NULL;
 	GSList *list;
@@ -1026,9 +1080,11 @@ inbound_away_notify (server *serv, char *nick, char *reason)
 			if (sess == serv->front_session && notify_is_in_list (serv, nick))
 			{
 				if (reason)
-					EMIT_SIGNAL (XP_TE_NOTIFYAWAY, sess, nick, reason, NULL, NULL, 0);
+					EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTIFYAWAY, sess, nick, reason, NULL,
+												  NULL, 0, tags_data->timestamp);
 				else
-					EMIT_SIGNAL (XP_TE_NOTIFYBACK, sess, nick, NULL, NULL, NULL, 0);
+					EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTIFYBACK, sess, nick, NULL, NULL, 
+												  NULL, 0, tags_data->timestamp);
 			}
 		}
 		list = list->next;
@@ -1036,7 +1092,8 @@ inbound_away_notify (server *serv, char *nick, char *reason)
 }
 
 int
-inbound_nameslist_end (server *serv, char *chan)
+inbound_nameslist_end (server *serv, char *chan,
+							  const message_tags_data *tags_data)
 {
 	session *sess;
 	GSList *list;
@@ -1145,7 +1202,8 @@ check_autojoin_channels (server *serv)
 }
 
 void
-inbound_next_nick (session *sess, char *nick, int error)
+inbound_next_nick (session *sess, char *nick, int error,
+						 const message_tags_data *tags_data)
 {
 	char *newnick;
 	server *serv = sess->server;
@@ -1166,11 +1224,13 @@ inbound_next_nick (session *sess, char *nick, int error)
 		serv->p_change_nick (serv, newnick);
 		if (error)
 		{
-			EMIT_SIGNAL (XP_TE_NICKERROR, sess, nick, newnick, NULL, NULL, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKERROR, sess, nick, newnick, NULL, NULL,
+										  0, tags_data->timestamp);
 		}
 		else
 		{
-			EMIT_SIGNAL (XP_TE_NICKCLASH, sess, nick, newnick, NULL, NULL, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKCLASH, sess, nick, newnick, NULL, NULL,
+										  0, tags_data->timestamp);
 		}
 		break;
 
@@ -1178,21 +1238,25 @@ inbound_next_nick (session *sess, char *nick, int error)
 		serv->p_change_nick (serv, prefs.hex_irc_nick3);
 		if (error)
 		{
-			EMIT_SIGNAL (XP_TE_NICKERROR, sess, nick, prefs.hex_irc_nick3, NULL, NULL, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKERROR, sess, nick, prefs.hex_irc_nick3,
+										  NULL, NULL, 0, tags_data->timestamp);
 		}
 		else
 		{
-			EMIT_SIGNAL (XP_TE_NICKCLASH, sess, nick, prefs.hex_irc_nick3, NULL, NULL, 0);
+			EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKCLASH, sess, nick, prefs.hex_irc_nick3,
+										  NULL, NULL, 0, tags_data->timestamp);
 		}
 		break;
 
 	default:
-		EMIT_SIGNAL (XP_TE_NICKFAIL, sess, NULL, NULL, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKFAIL, sess, NULL, NULL, NULL, NULL, 0,
+									  tags_data->timestamp);
 	}
 }
 
 void
-do_dns (session *sess, char *nick, char *host)
+do_dns (session *sess, char *nick, char *host,
+		  const message_tags_data *tags_data)
 {
 	char *po;
 	char tbuf[1024];
@@ -1200,7 +1264,8 @@ do_dns (session *sess, char *nick, char *host)
 	po = strrchr (host, '@');
 	if (po)
 		host = po + 1;
-	EMIT_SIGNAL (XP_TE_RESOLVINGUSER, sess, nick, host, NULL, NULL, 0);
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_RESOLVINGUSER, sess, nick, host, NULL, NULL, 0,
+								  tags_data->timestamp);
 	snprintf (tbuf, sizeof (tbuf), "exec -d %s %s", prefs.hex_dnsprogram, host);
 	handle_command (sess, tbuf, FALSE);
 }
@@ -1227,9 +1292,10 @@ set_default_modes (server *serv)
 }
 
 void
-inbound_login_start (session *sess, char *nick, char *servname)
+inbound_login_start (session *sess, char *nick, char *servname,
+							const message_tags_data *tags_data)
 {
-	inbound_newnick (sess->server, sess->server->nick, nick, TRUE);
+	inbound_newnick (sess->server, sess->server->nick, nick, TRUE, tags_data);
 	server_set_name (sess->server, servname);
 	if (sess->type == SESS_SERVER)
 		log_open_or_close (sess);
@@ -1258,7 +1324,7 @@ inbound_set_all_away_status (server *serv, char *nick, unsigned int status)
 }
 
 void
-inbound_uaway (server *serv)
+inbound_uaway (server *serv, const message_tags_data *tags_data)
 {
 	serv->is_away = TRUE;
 	serv->away_time = time (NULL);
@@ -1268,7 +1334,7 @@ inbound_uaway (server *serv)
 }
 
 void
-inbound_uback (server *serv)
+inbound_uback (server *serv, const message_tags_data *tags_data)
 {
 	serv->is_away = FALSE;
 	serv->reconnect_away = FALSE;
@@ -1278,7 +1344,7 @@ inbound_uback (server *serv)
 }
 
 void
-inbound_foundip (session *sess, char *ip)
+inbound_foundip (session *sess, char *ip, const message_tags_data *tags_data)
 {
 	struct hostent *HostAddr;
 
@@ -1286,14 +1352,15 @@ inbound_foundip (session *sess, char *ip)
 	if (HostAddr)
 	{
 		prefs.dcc_ip = ((struct in_addr *) HostAddr->h_addr)->s_addr;
-		EMIT_SIGNAL (XP_TE_FOUNDIP, sess->server->server_session,
-						 inet_ntoa (*((struct in_addr *) HostAddr->h_addr)),
-						 NULL, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_FOUNDIP, sess->server->server_session,
+									  inet_ntoa (*((struct in_addr *) HostAddr->h_addr)),
+									  NULL, NULL, NULL, 0, tags_data->timestamp);
 	}
 }
 
 void
-inbound_user_info_start (session *sess, char *nick)
+inbound_user_info_start (session *sess, char *nick,
+								 const message_tags_data *tags_data)
 {
 	/* set away to FALSE now, 301 may turn it back on */
 	inbound_set_all_away_status (sess->server, nick, 0);
@@ -1305,7 +1372,8 @@ inbound_user_info_start (session *sess, char *nick)
 void
 inbound_user_info (session *sess, char *chan, char *user, char *host,
 						 char *servname, char *nick, char *realname,
-						 char *account, unsigned int away)
+						 char *account, unsigned int away,
+						 const message_tags_data *tags_data)
 {
 	server *serv = sess->server;
 	session *who_sess;
@@ -1326,7 +1394,7 @@ inbound_user_info (session *sess, char *chan, char *user, char *host,
 		else
 		{
 			if (serv->doing_dns && nick && host)
-				do_dns (sess, nick, host);
+				do_dns (sess, nick, host, tags_data);
 		}
 	}
 	else
@@ -1346,7 +1414,8 @@ inbound_user_info (session *sess, char *chan, char *user, char *host,
 }
 
 int
-inbound_banlist (session *sess, time_t stamp, char *chan, char *mask, char *banner, int rplcode)
+inbound_banlist (session *sess, time_t stamp, char *chan, char *mask, 
+					  char *banner, int rplcode, const message_tags_data *tags_data)
 {
 	char *time_str = ctime (&stamp);
 	server *serv = sess->server;
@@ -1368,7 +1437,8 @@ inbound_banlist (session *sess, time_t stamp, char *chan, char *mask, char *bann
 	{
 nowindow:
 
-		EMIT_SIGNAL (XP_TE_BANLIST, sess, chan, mask, banner, time_str, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_BANLIST, sess, chan, mask, banner, time_str,
+									  0, tags_data->timestamp);
 		return TRUE;
 	}
 
@@ -1405,7 +1475,7 @@ inbound_nickserv_login (server *serv)
 }
 
 void
-inbound_login_end (session *sess, char *text)
+inbound_login_end (session *sess, char *text, const message_tags_data *tags_data)
 {
 	GSList *cmdlist;
 	commandentry *cmd;
@@ -1462,11 +1532,13 @@ inbound_login_end (session *sess, char *text)
 	if (prefs.hex_irc_skip_motd && !serv->motd_skipped)
 	{
 		serv->motd_skipped = TRUE;
-		EMIT_SIGNAL (XP_TE_MOTDSKIP, serv->server_session, NULL, NULL, NULL, NULL, 0);
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_MOTDSKIP, serv->server_session, NULL, NULL,
+									  NULL, NULL, 0, tags_data->timestamp);
 		return;
 	}
 
-	EMIT_SIGNAL (XP_TE_MOTD, serv->server_session, text, NULL, NULL, NULL, 0);
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_MOTD, serv->server_session, text, NULL, NULL,
+								  NULL, 0, tags_data->timestamp);
 }
 
 void
@@ -1480,3 +1552,165 @@ inbound_identified (server *serv)	/* 'MODE +e MYSELF' on freenode */
 		check_autojoin_channels (serv);
 	}
 }
+
+void
+inbound_cap_ack (server *serv, char *nick, char *extensions,
+					  const message_tags_data *tags_data)
+{
+	char *pass; /* buffer for SASL password */
+
+	EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPACK, serv->server_session, nick, extensions,
+								  NULL, NULL, 0, tags_data->timestamp);
+
+	if (strstr (extensions, "identify-msg") != NULL)
+	{
+		serv->have_idmsg = TRUE;
+	}
+
+	if (strstr (extensions, "multi-prefix") != NULL)
+	{
+		serv->have_namesx = TRUE;
+	}
+
+	if (strstr (extensions, "away-notify") != NULL)
+	{
+		serv->have_awaynotify = TRUE;
+	}
+
+	if (strstr (extensions, "account-notify") != NULL)
+	{
+		serv->have_accnotify = TRUE;
+	}
+					
+	if (strstr (extensions, "extended-join") != NULL)
+	{
+		serv->have_extjoin = TRUE;
+	}
+
+	if (strstr (extensions, "server-time") != NULL)
+	{
+		serv->have_server_time = TRUE;
+	}
+
+	if (strstr (extensions, "sasl") != NULL)
+	{
+		char *user;
+
+		serv->have_sasl = TRUE;
+
+		user = (((ircnet *)serv->network)->user) 
+			? (((ircnet *)serv->network)->user) : prefs.hex_irc_user_name;
+
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_SASLAUTH, serv->server_session, user, NULL,
+									  NULL,	NULL,	0,	tags_data->timestamp);
+		tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20);
+
+		pass = encode_sasl_pass (user, serv->password);
+		tcp_sendf (serv, "AUTHENTICATE %s\r\n", pass);
+		free (pass);
+	}
+}
+
+void
+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_str, NULL, NULL, 0, tags_data->timestamp);
+	want_cap = 0;
+	want_sasl = 0;
+
+	extensions = g_strsplit (extensions_str, " ", 0);
+
+	strcpy (buffer, "CAP REQ :");
+
+	for (i=0; extensions[i]; i++)
+	{
+		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 ");
+		}
+		if (prefs.hex_irc_cap_server_time
+			 && !strcmp (extension, "server-time"))
+		{
+			strcat (buffer, "server-time ");
+		}
+		
+		/* 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 :" */
+		EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPREQ, serv->server_session,
+									  buffer + 9, NULL, NULL, NULL, 0,
+									  tags_data->timestamp);
+		tcp_sendf (serv, "%s\r\n", buffer);
+	}
+	if (!want_sasl)
+	{
+		/* if we use SASL, CAP END is dealt via raw numerics */
+		tcp_send_len (serv, "CAP END\r\n", 9);
+	}
+}
+
+void
+inbound_cap_nak (server *serv, const message_tags_data *tags_data)
+{
+	tcp_send_len (serv, "CAP END\r\n", 9);
+}
+
+void
+inbound_cap_list (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);
+}