diff options
author | TingPing <tingping@tingping.se> | 2013-06-28 11:59:33 -0400 |
---|---|---|
committer | TingPing <tingping@tingping.se> | 2013-06-28 11:59:33 -0400 |
commit | ad926e9b07f499bfb70b57890475c73f9d64812a (patch) | |
tree | e7274fe1de9f1caf264701be28b6785841f960ed | |
parent | ac5771377ea95287a99bfd5c8c99ec65e9bb069d (diff) | |
parent | 059cbcd406a3defbe43859c3d8df7afe5a89e362 (diff) |
Merge pull request #656 from orium/server-time
Closes #499
-rw-r--r-- | src/common/cfgfiles.c | 2 | ||||
-rw-r--r-- | src/common/ctcp.c | 23 | ||||
-rw-r--r-- | src/common/ctcp.h | 4 | ||||
-rw-r--r-- | src/common/dcc.c | 20 | ||||
-rw-r--r-- | src/common/dcc.h | 4 | ||||
-rw-r--r-- | src/common/hexchat.h | 2 | ||||
-rw-r--r-- | src/common/inbound.c | 424 | ||||
-rw-r--r-- | src/common/inbound.h | 105 | ||||
-rw-r--r-- | src/common/modes.c | 86 | ||||
-rw-r--r-- | src/common/modes.h | 7 | ||||
-rw-r--r-- | src/common/notify.c | 44 | ||||
-rw-r--r-- | src/common/notify.h | 13 | ||||
-rw-r--r-- | src/common/outbound.c | 46 | ||||
-rw-r--r-- | src/common/proto-irc.c | 521 | ||||
-rw-r--r-- | src/common/proto-irc.h | 17 | ||||
-rw-r--r-- | src/common/server.c | 1 | ||||
-rw-r--r-- | src/common/text.c | 36 | ||||
-rw-r--r-- | src/common/text.h | 12 | ||||
-rw-r--r-- | src/common/userlist.c | 5 | ||||
-rw-r--r-- | src/common/userlist.h | 4 | ||||
-rw-r--r-- | src/fe-gtk/setup.c | 5 |
21 files changed, 923 insertions, 458 deletions
diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c index 20f1e848..008a0787 100644 --- a/src/common/cfgfiles.c +++ b/src/common/cfgfiles.c @@ -507,6 +507,7 @@ const struct prefs vars[] = {"irc_auto_rejoin", P_OFFINT (hex_irc_auto_rejoin), TYPE_BOOL}, {"irc_ban_type", P_OFFINT (hex_irc_ban_type), TYPE_INT}, + {"irc_cap_server_time", P_OFFINT (hex_irc_cap_server_time), TYPE_BOOL}, {"irc_conf_mode", P_OFFINT (hex_irc_conf_mode), TYPE_BOOL}, {"irc_extra_hilight", P_OFFSET (hex_irc_extra_hilight), TYPE_STR}, {"irc_hide_version", P_OFFINT (hex_irc_hide_version), TYPE_BOOL}, @@ -748,6 +749,7 @@ load_default_config(void) prefs.hex_text_thin_sep = 1; prefs.hex_text_wordwrap = 1; prefs.hex_url_grabber = 1; + prefs.hex_irc_cap_server_time = 0; /* NUMBERS */ prefs.hex_away_size_max = 300; diff --git a/src/common/ctcp.c b/src/common/ctcp.c index ebfb604d..b4fb55b7 100644 --- a/src/common/ctcp.c +++ b/src/common/ctcp.c @@ -85,7 +85,8 @@ ctcp_check (session *sess, char *nick, char *word[], char *word_eol[], void ctcp_handle (session *sess, char *to, char *nick, char *ip, - char *msg, char *word[], char *word_eol[], int id) + char *msg, char *word[], char *word_eol[], int id, + const message_tags_data *tags_data) { char *po; session *chansess; @@ -103,7 +104,7 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip, if (!ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset)) { if (!ignore_check (word[1], IG_DCC)) - handle_dcc (sess, nick, word, word_eol); + handle_dcc (sess, nick, word, word_eol, tags_data); } return; } @@ -128,7 +129,7 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip, if (ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset)) goto generic; - inbound_action (sess, to, nick, ip, msg + 7, FALSE, id); + inbound_action (sess, to, nick, ip, msg + 7, FALSE, id, tags_data); return; } @@ -161,12 +162,13 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip, if (!chansess) chansess = sess; - EMIT_SIGNAL (XP_TE_CTCPSNDC, chansess, word[5], - nick, to, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CTCPSNDC, chansess, word[5], + nick, to, NULL, 0, tags_data->timestamp); } else { - EMIT_SIGNAL (XP_TE_CTCPSND, sess->server->front_session, word[5], - nick, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CTCPSND, sess->server->front_session, + word[5], nick, NULL, NULL, 0, + tags_data->timestamp); } /* don't let IRCers specify path */ @@ -187,13 +189,14 @@ generic: if (!is_channel (sess->server, to)) { - EMIT_SIGNAL (XP_TE_CTCPGEN, sess->server->front_session, msg, nick, - NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CTCPGEN, sess->server->front_session, msg, + nick, NULL, NULL, 0, tags_data->timestamp); } else { chansess = find_channel (sess->server, to); if (!chansess) chansess = sess; - EMIT_SIGNAL (XP_TE_CTCPGENC, chansess, msg, nick, to, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CTCPGENC, chansess, msg, nick, to, NULL, 0, + tags_data->timestamp); } } diff --git a/src/common/ctcp.h b/src/common/ctcp.h index 54e33f4c..9d811e57 100644 --- a/src/common/ctcp.h +++ b/src/common/ctcp.h @@ -20,6 +20,8 @@ #ifndef HEXCHAT_CTCP_H #define HEXCHAT_CTCP_H -void ctcp_handle (session *sess, char *to, char *nick, char *ip, char *msg, char *word[], char *word_eol[], int id); +void ctcp_handle (session *sess, char *to, char *nick, char *ip, char *msg, + char *word[], char *word_eol[], int id, + const message_tags_data *tags_data); #endif diff --git a/src/common/dcc.c b/src/common/dcc.c index 4980cabc..c0527510 100644 --- a/src/common/dcc.c +++ b/src/common/dcc.c @@ -509,6 +509,7 @@ dcc_chat_line (struct DCC *dcc, char *line) int len; gsize utf_len; char portbuf[32]; + message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; len = strlen (line); if (dcc->serv->using_cp1255) @@ -576,10 +577,11 @@ dcc_chat_line (struct DCC *dcc, char *line) po = strchr (line + 8, '\001'); if (po) po[0] = 0; - inbound_action (sess, dcc->serv->nick, dcc->nick, "", line + 8, FALSE, FALSE); + inbound_action (sess, dcc->serv->nick, dcc->nick, "", line + 8, FALSE, + FALSE, &no_tags); } else { - inbound_privmsg (dcc->serv, dcc->nick, "", line, FALSE); + inbound_privmsg (dcc->serv, dcc->nick, "", line, FALSE, &no_tags); } if (utf) g_free (utf); @@ -2375,8 +2377,8 @@ dcc_add_file (session *sess, char *file, DCC_SIZE size, int port, char *nick, gu } void -handle_dcc (struct session *sess, char *nick, char *word[], - char *word_eol[]) +handle_dcc (struct session *sess, char *nick, char *word[], char *word_eol[], + const message_tags_data *tags_data) { char tbuf[512]; struct DCC *dcc; @@ -2472,8 +2474,9 @@ handle_dcc (struct session *sess, char *nick, char *word[], dcc->serv->p_ctcp (dcc->serv, dcc->nick, tbuf); } sprintf (tbuf, "%"DCC_SFMT, dcc->pos); - EMIT_SIGNAL (XP_TE_DCCRESUMEREQUEST, sess, nick, - file_part (dcc->file), tbuf, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_DCCRESUMEREQUEST, sess, nick, + file_part (dcc->file), tbuf, NULL, 0, + tags_data->timestamp); } return; } @@ -2543,8 +2546,9 @@ handle_dcc (struct session *sess, char *nick, char *word[], } else { - EMIT_SIGNAL (XP_TE_DCCGENERICOFFER, sess->server->front_session, - word_eol[4] + 2, nick, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_DCCGENERICOFFER, sess->server->front_session, + word_eol[4] + 2, nick, NULL, NULL, 0, + tags_data->timestamp); } } diff --git a/src/common/dcc.h b/src/common/dcc.h index 32d0ed5f..e3163c8a 100644 --- a/src/common/dcc.h +++ b/src/common/dcc.h @@ -20,6 +20,7 @@ /* dcc.h */ #include <time.h> /* for time_t */ +#include "proto-irc.h" #ifndef HEXCHAT_DCC_H #define HEXCHAT_DCC_H @@ -127,7 +128,8 @@ void dcc_send (struct session *sess, char *to, char *file, int maxcps, int passi struct DCC *find_dcc (char *nick, char *file, int type); void dcc_get_nick (struct session *sess, char *nick); void dcc_chat (session *sess, char *nick, int passive); -void handle_dcc (session *sess, char *nick, char *word[], char *word_eol[]); +void handle_dcc (session *sess, char *nick, char *word[], char *word_eol[], + const message_tags_data *tags_data); void dcc_show_list (session *sess); guint32 dcc_get_my_address (void); void dcc_get_with_destfile (struct DCC *dcc, char *utf8file); diff --git a/src/common/hexchat.h b/src/common/hexchat.h index 1a759f14..074d5a22 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -215,6 +215,7 @@ struct hexchatprefs unsigned int hex_irc_wallops; unsigned int hex_irc_who_join; unsigned int hex_irc_whois_front; + unsigned int hex_irc_cap_server_time; unsigned int hex_net_auto_reconnect; unsigned int hex_net_auto_reconnectonfail; unsigned int hex_net_proxy_auth; @@ -593,6 +594,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 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); +} diff --git a/src/common/inbound.h b/src/common/inbound.h index 32368cc1..cbb04890 100644 --- a/src/common/inbound.h +++ b/src/common/inbound.h @@ -17,43 +17,86 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "proto-irc.h" + #ifndef HEXCHAT_INBOUND_H #define HEXCHAT_INBOUND_H -void inbound_next_nick (session *sess, char *nick, int error); -void inbound_uback (server *serv); -void inbound_uaway (server *serv); -void inbound_account (server *serv, char *nick, char *account); -void inbound_part (server *serv, char *chan, char *user, char *ip, char *reason); -void inbound_upart (server *serv, char *chan, char *ip, char *reason); -void inbound_ukick (server *serv, char *chan, char *kicker, char *reason); -void inbound_kick (server *serv, char *chan, char *user, char *kicker, char *reason); -void inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id); -void inbound_quit (server *serv, char *nick, char *ip, char *reason); -void 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); -void inbound_ujoin (server *serv, char *chan, char *nick, char *ip); -void inbound_topictime (server *serv, char *chan, char *nick, time_t stamp); -void inbound_topic (server *serv, char *chan, char *topic_text); -void 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); -void inbound_foundip (session *sess, char *ip); -int inbound_banlist (session *sess, time_t stamp, char *chan, char *mask, char *banner, int is_exemption); -void inbound_ping_reply (session *sess, char *timestring, char *from); -void inbound_nameslist (server *serv, char *chan, char *names); -int inbound_nameslist_end (server *serv, char *chan); -void inbound_away (server *serv, char *nick, char *msg); -void inbound_away_notify (server *serv, char *nick, char *reason); -void inbound_login_start (session *sess, char *nick, char *servname); -void inbound_login_end (session *sess, char *text); -void inbound_chanmsg (server *serv, session *sess, char *chan, char *from, char *text, char fromme, int id); +void inbound_next_nick (session *sess, char *nick, int error, + const message_tags_data *tags_data); +void inbound_uback (server *serv, const message_tags_data *tags_data); +void inbound_uaway (server *serv, const message_tags_data *tags_data); +void inbound_account (server *serv, char *nick, char *account, + const message_tags_data *tags_data); +void inbound_part (server *serv, char *chan, char *user, char *ip, char *reason, + const message_tags_data *tags_data); +void inbound_upart (server *serv, char *chan, char *ip, char *reason, + const message_tags_data *tags_data); +void inbound_ukick (server *serv, char *chan, char *kicker, char *reason, + const message_tags_data *tags_data); +void inbound_kick (server *serv, char *chan, char *user, char *kicker, + char *reason, const message_tags_data *tags_data); +void inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, + int id, const message_tags_data *tags_data); +void inbound_quit (server *serv, char *nick, char *ip, char *reason, + const message_tags_data *tags_data); +void inbound_topicnew (server *serv, char *nick, char *chan, char *topic, + const message_tags_data *tags_data); +void inbound_join (server *serv, char *chan, char *user, char *ip, + char *account, char *realname, + const message_tags_data *tags_data); +void inbound_ujoin (server *serv, char *chan, char *nick, char *ip, + const message_tags_data *tags_data); +void inbound_topictime (server *serv, char *chan, char *nick, time_t stamp, + const message_tags_data *tags_data); +void inbound_topic (server *serv, char *chan, char *topic_text, + const message_tags_data *tags_data); +void inbound_user_info_start (session *sess, char *nick, + const message_tags_data *tags_data); +void inbound_user_info (session *sess, char *chan, char *user, char *host, + char *servname, char *nick, char *realname, char *account, + unsigned int away, const message_tags_data *tags_data); +void inbound_foundip (session *sess, char *ip, + const message_tags_data *tags_data); +int inbound_banlist (session *sess, time_t stamp, char *chan, char *mask, + char *banner, int is_exemption, + const message_tags_data *tags_data); +void inbound_ping_reply (session *sess, char *timestring, char *from, + const message_tags_data *tags_data); +void inbound_nameslist (server *serv, char *chan, char *names, + const message_tags_data *tags_data); +int inbound_nameslist_end (server *serv, char *chan, + const message_tags_data *tags_data); +void inbound_away (server *serv, char *nick, char *msg, + const message_tags_data *tags_data); +void inbound_away_notify (server *serv, char *nick, char *reason, + const message_tags_data *tags_data); +void inbound_login_start (session *sess, char *nick, char *servname, + const message_tags_data *tags_data); +void inbound_login_end (session *sess, char *text, + const message_tags_data *tags_data); +void inbound_chanmsg (server *serv, session *sess, char *chan, char *from, + char *text, char fromme, int id, + const message_tags_data *tags_data); void clear_channel (session *sess); void set_topic (session *sess, char *topic, char *stripped_topic); -void inbound_privmsg (server *serv, char *from, char *ip, char *text, int id); -void inbound_action (session *sess, char *chan, char *from, char *ip, char *text, int fromme, int id); -void inbound_newnick (server *serv, char *nick, char *newnick, int quiet); -void do_dns (session *sess, char *nick, char *host); +void inbound_privmsg (server *serv, char *from, char *ip, char *text, int id, + const message_tags_data *tags_data); +void inbound_action (session *sess, char *chan, char *from, char *ip, + char *text, int fromme, int id, + const message_tags_data *tags_data); +void inbound_newnick (server *serv, char *nick, char *newnick, int quiet, + const message_tags_data *tags_data); void inbound_identified (server *serv); +void inbound_cap_ack (server *serv, char *nick, char *extensions, + const message_tags_data *tags_data); +void inbound_cap_ls (server *serv, char *nick, char *extensions, + const message_tags_data *tags_data); +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 do_dns (session *sess, char *nick, char *host, + const message_tags_data *tags_data); gboolean alert_match_word (char *word, char *masks); gboolean alert_match_text (char *text, char *masks); diff --git a/src/common/modes.c b/src/common/modes.c index f8b25fcd..420f3e8c 100644 --- a/src/common/modes.c +++ b/src/common/modes.c @@ -46,9 +46,12 @@ typedef struct static int is_prefix_char (server * serv, char c); static void record_chan_mode (session *sess, char sign, char mode, char *arg); static char *mode_cat (char *str, char *addition); -static void handle_single_mode (mode_run *mr, char sign, char mode, char *nick, char *chan, char *arg, int quiet, int is_324); +static void handle_single_mode (mode_run *mr, char sign, char mode, char *nick, + char *chan, char *arg, int quiet, int is_324, + const message_tags_data *tags_data); static int mode_has_arg (server *serv, char sign, char mode); -static void mode_print_grouped (session *sess, char *nick, mode_run *mr); +static void mode_print_grouped (session *sess, char *nick, mode_run *mr, + const message_tags_data *tags_data); static int mode_chanmode_type (server * serv, char mode); @@ -387,7 +390,8 @@ mode_cat (char *str, char *addition) static void handle_single_mode (mode_run *mr, char sign, char mode, char *nick, - char *chan, char *arg, int quiet, int is_324) + char *chan, char *arg, int quiet, int is_324, + const message_tags_data *tags_data) { session *sess; server *serv = mr->serv; @@ -440,14 +444,16 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick, fe_update_channel_key (sess); fe_update_mode_buttons (sess, mode, sign); if (!quiet) - EMIT_SIGNAL (XP_TE_CHANSETKEY, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANSETKEY, sess, nick, arg, NULL, + NULL, 0, tags_data->timestamp); return; case 'l': sess->limit = atoi (arg); fe_update_channel_limit (sess); fe_update_mode_buttons (sess, mode, sign); if (!quiet) - EMIT_SIGNAL (XP_TE_CHANSETLIMIT, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANSETLIMIT, sess, nick, arg, NULL, + NULL, 0, tags_data->timestamp); return; case 'o': if (!quiet) @@ -455,7 +461,8 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick, return; case 'h': if (!quiet) - EMIT_SIGNAL (XP_TE_CHANHOP, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANHOP, sess, nick, arg, NULL, NULL, + 0, tags_data->timestamp); return; case 'v': if (!quiet) @@ -463,21 +470,25 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick, return; case 'b': if (!quiet) - EMIT_SIGNAL (XP_TE_CHANBAN, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANBAN, sess, nick, arg, NULL, NULL, + 0, tags_data->timestamp); return; case 'e': if (!quiet) - EMIT_SIGNAL (XP_TE_CHANEXEMPT, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANEXEMPT, sess, nick, arg, NULL, + NULL, 0, tags_data->timestamp); return; case 'I': if (!quiet) - EMIT_SIGNAL (XP_TE_CHANINVITE, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANINVITE, sess, nick, arg, NULL, NULL, + 0, tags_data->timestamp); return; case 'q': if (!supportsq) break; /* +q is owner on this server */ if (!quiet) - EMIT_SIGNAL (XP_TE_CHANQUIET, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANQUIET, sess, nick, arg, NULL, NULL, 0, + tags_data->timestamp); return; } break; @@ -489,14 +500,16 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick, fe_update_channel_key (sess); fe_update_mode_buttons (sess, mode, sign); if (!quiet) - EMIT_SIGNAL (XP_TE_CHANRMKEY, sess, nick, NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANRMKEY, sess, nick, NULL, NULL, + NULL, 0, tags_data->timestamp); return; case 'l': sess->limit = 0; fe_update_channel_limit (sess); fe_update_mode_buttons (sess, mode, sign); if (!quiet) - EMIT_SIGNAL (XP_TE_CHANRMLIMIT, sess, nick, NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANRMLIMIT, sess, nick, NULL, NULL, + NULL, 0, tags_data->timestamp); return; case 'o': if (!quiet) @@ -504,7 +517,8 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick, return; case 'h': if (!quiet) - EMIT_SIGNAL (XP_TE_CHANDEHOP, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDEHOP, sess, nick, arg, NULL, + NULL, 0, tags_data->timestamp); return; case 'v': if (!quiet) @@ -512,21 +526,25 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick, return; case 'b': if (!quiet) - EMIT_SIGNAL (XP_TE_CHANUNBAN, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANUNBAN, sess, nick, arg, NULL, NULL, + 0, tags_data->timestamp); return; case 'e': if (!quiet) - EMIT_SIGNAL (XP_TE_CHANRMEXEMPT, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANRMEXEMPT, sess, nick, arg, NULL, + NULL, 0, tags_data->timestamp); return; case 'I': if (!quiet) - EMIT_SIGNAL (XP_TE_CHANRMINVITE, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANRMINVITE, sess, nick, arg, NULL, + NULL, 0, tags_data->timestamp); return; case 'q': if (!supportsq) break; /* -q is owner on this server */ if (!quiet) - EMIT_SIGNAL (XP_TE_CHANUNQUIET, sess, nick, arg, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANUNQUIET, sess, nick, arg, NULL, + NULL, 0, tags_data->timestamp); return; } } @@ -544,10 +562,12 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick, { char *buf = malloc (strlen (chan) + strlen (arg) + 2); sprintf (buf, "%s %s", chan, arg); - EMIT_SIGNAL (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, buf, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODEGEN, sess, nick, outbuf, + outbuf + 2, buf, 0, tags_data->timestamp); free (buf); } else - EMIT_SIGNAL (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, chan, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODEGEN, sess, nick, outbuf, + outbuf + 2, chan, 0, tags_data->timestamp); } } @@ -607,33 +627,38 @@ mode_chanmode_type (server * serv, char mode) } static void -mode_print_grouped (session *sess, char *nick, mode_run *mr) +mode_print_grouped (session *sess, char *nick, mode_run *mr, + const message_tags_data *tags_data) { /* print all the grouped Op/Deops */ if (mr->op) { - EMIT_SIGNAL (XP_TE_CHANOP, sess, nick, mr->op, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANOP, sess, nick, mr->op, NULL, NULL, 0, + tags_data->timestamp); free (mr->op); mr->op = NULL; } if (mr->deop) { - EMIT_SIGNAL (XP_TE_CHANDEOP, sess, nick, mr->deop, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDEOP, sess, nick, mr->deop, NULL, NULL, + 0, tags_data->timestamp); free (mr->deop); mr->deop = NULL; } if (mr->voice) { - EMIT_SIGNAL (XP_TE_CHANVOICE, sess, nick, mr->voice, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANVOICE, sess, nick, mr->voice, NULL, NULL, + 0, tags_data->timestamp); free (mr->voice); mr->voice = NULL; } if (mr->devoice) { - EMIT_SIGNAL (XP_TE_CHANDEVOICE, sess, nick, mr->devoice, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDEVOICE, sess, nick, mr->devoice, NULL, + NULL, 0, tags_data->timestamp); free (mr->devoice); mr->devoice = NULL; } @@ -644,7 +669,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr) void handle_mode (server * serv, char *word[], char *word_eol[], - char *nick, int numeric_324) + char *nick, int numeric_324, const message_tags_data *tags_data) { session *sess; char *chan; @@ -687,7 +712,8 @@ handle_mode (server * serv, char *word[], char *word_eol[], word_eol[offset][len] = 0; if (prefs.hex_irc_raw_modes && !numeric_324) - EMIT_SIGNAL (XP_TE_RAWMODES, sess, nick, word_eol[offset], 0, 0, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_RAWMODES, sess, nick, word_eol[offset], 0, 0, 0, + tags_data->timestamp); if (numeric_324 && !using_front_tab) { @@ -731,7 +757,7 @@ handle_mode (server * serv, char *word[], char *word_eol[], case '-': case '+': /* print all the grouped Op/Deops */ - mode_print_grouped (sess, nick, &mr); + mode_print_grouped (sess, nick, &mr, tags_data); sign = *modes; break; default: @@ -743,7 +769,7 @@ handle_mode (server * serv, char *word[], char *word_eol[], } handle_single_mode (&mr, sign, *modes, nick, chan, argstr, numeric_324 || prefs.hex_irc_raw_modes, - numeric_324); + numeric_324, tags_data); } modes++; @@ -754,13 +780,13 @@ handle_mode (server * serv, char *word[], char *word_eol[], fe_set_title (sess); /* print all the grouped Op/Deops */ - mode_print_grouped (sess, nick, &mr); + mode_print_grouped (sess, nick, &mr, tags_data); } /* handle the 005 numeric */ void -inbound_005 (server * serv, char *word[]) +inbound_005 (server * serv, char *word[], const message_tags_data *tags_data) { int w; char *pre; diff --git a/src/common/modes.h b/src/common/modes.h index e55ec911..7e13c7df 100644 --- a/src/common/modes.h +++ b/src/common/modes.h @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "proto-irc.h" + #ifndef HEXCHAT_MODES_H #define HEXCHAT_MODES_H @@ -24,8 +26,9 @@ int is_channel (server *serv, char *chan); char get_nick_prefix (server *serv, unsigned int access); unsigned int nick_access (server *serv, char *nick, int *modechars); int mode_access (server *serv, char mode, char *prefix); -void inbound_005 (server *serv, char *word[]); -void handle_mode (server *serv, char *word[], char *word_eol[], char *nick, int numeric_324); +void inbound_005 (server *serv, char *word[], const message_tags_data *tags_data); +void handle_mode (server *serv, char *word[], char *word_eol[], char *nick, + int numeric_324, const message_tags_data *tags_data); void send_channel_modes (session *sess, char *tbuf, char *word[], int start, int end, char sign, char mode, int modes_per_line); #endif diff --git a/src/common/notify.c b/src/common/notify.c index 301bb393..944d826c 100644 --- a/src/common/notify.c +++ b/src/common/notify.c @@ -205,7 +205,8 @@ notify_find (server *serv, char *nick) static void notify_announce_offline (server * serv, struct notify_per_server *servnot, - char *nick, int quiet) + char *nick, int quiet, + const message_tags_data *tags_data) { session *sess; @@ -214,15 +215,16 @@ notify_announce_offline (server * serv, struct notify_per_server *servnot, servnot->ison = FALSE; servnot->lastoff = time (0); if (!quiet) - EMIT_SIGNAL (XP_TE_NOTIFYOFFLINE, sess, nick, serv->servername, - server_get_network (serv, TRUE), NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTIFYOFFLINE, sess, nick, serv->servername, + server_get_network (serv, TRUE), NULL, 0, + tags_data->timestamp); fe_notify_update (nick); fe_notify_update (0); } static void notify_announce_online (server * serv, struct notify_per_server *servnot, - char *nick) + char *nick, const message_tags_data *tags_data) { session *sess; @@ -234,8 +236,9 @@ notify_announce_online (server * serv, struct notify_per_server *servnot, servnot->ison = TRUE; servnot->laston = time (0); - EMIT_SIGNAL (XP_TE_NOTIFYONLINE, sess, nick, serv->servername, - server_get_network (serv, TRUE), NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTIFYONLINE, sess, nick, serv->servername, + server_get_network (serv, TRUE), NULL, 0, + tags_data->timestamp); fe_notify_update (nick); fe_notify_update (0); @@ -254,7 +257,8 @@ notify_announce_online (server * serv, struct notify_per_server *servnot, /* handles numeric 601 */ void -notify_set_offline (server * serv, char *nick, int quiet) +notify_set_offline (server * serv, char *nick, int quiet, + const message_tags_data *tags_data) { struct notify_per_server *servnot; @@ -262,13 +266,14 @@ notify_set_offline (server * serv, char *nick, int quiet) if (!servnot) return; - notify_announce_offline (serv, servnot, nick, quiet); + notify_announce_offline (serv, servnot, nick, quiet, tags_data); } /* handles numeric 604 and 600 */ void -notify_set_online (server * serv, char *nick) +notify_set_online (server * serv, char *nick, + const message_tags_data *tags_data) { struct notify_per_server *servnot; @@ -276,7 +281,7 @@ notify_set_online (server * serv, char *nick) if (!servnot) return; - notify_announce_online (serv, servnot, nick); + notify_announce_online (serv, servnot, nick, tags_data); } static void @@ -369,7 +374,7 @@ notify_send_watches (server * serv) /* called when receiving a ISON 303 - should this func go? */ void -notify_markonline (server *serv, char *word[]) +notify_markonline (server *serv, char *word[], const message_tags_data *tags_data) { struct notify *notify; struct notify_per_server *servnot; @@ -392,7 +397,7 @@ notify_markonline (server *serv, char *word[]) if (!serv->p_cmp (notify->name, word[i])) { seen = TRUE; - notify_announce_online (serv, servnot, notify->name); + notify_announce_online (serv, servnot, notify->name, tags_data); break; } i++; @@ -406,7 +411,7 @@ notify_markonline (server *serv, char *word[]) } if (!seen && servnot->ison) { - notify_announce_offline (serv, servnot, notify->name, FALSE); + notify_announce_offline (serv, servnot, notify->name, FALSE, tags_data); } list = list->next; } @@ -467,7 +472,7 @@ notify_checklist (void) /* check ISON list */ } void -notify_showlist (struct session *sess) +notify_showlist (struct session *sess, const message_tags_data *tags_data) { char outbuf[256]; struct notify *notify; @@ -475,7 +480,8 @@ notify_showlist (struct session *sess) struct notify_per_server *servnot; int i = 0; - EMIT_SIGNAL (XP_TE_NOTIFYHEAD, sess, NULL, NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTIFYHEAD, sess, NULL, NULL, NULL, NULL, 0, + tags_data->timestamp); while (list) { i++; @@ -485,15 +491,17 @@ notify_showlist (struct session *sess) snprintf (outbuf, sizeof (outbuf), _(" %-20s online\n"), notify->name); else snprintf (outbuf, sizeof (outbuf), _(" %-20s offline\n"), notify->name); - PrintText (sess, outbuf); + PrintTextTimeStamp (sess, outbuf, tags_data->timestamp); list = list->next; } if (i) { sprintf (outbuf, "%d", i); - EMIT_SIGNAL (XP_TE_NOTIFYNUMBER, sess, outbuf, NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTIFYNUMBER, sess, outbuf, NULL, NULL, NULL, + 0, tags_data->timestamp); } else - EMIT_SIGNAL (XP_TE_NOTIFYEMPTY, sess, NULL, NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_NOTIFYEMPTY, sess, NULL, NULL, NULL, NULL, 0, + tags_data->timestamp); } int diff --git a/src/common/notify.h b/src/common/notify.h index 8e513d5f..4a6ffb35 100644 --- a/src/common/notify.h +++ b/src/common/notify.h @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "proto-irc.h" + #ifndef HEXCHAT_NOTIFY_H #define HEXCHAT_NOTIFY_H @@ -41,8 +43,10 @@ extern GSList *notify_list; extern int notify_tag; /* the WATCH stuff */ -void notify_set_online (server * serv, char *nick); -void notify_set_offline (server * serv, char *nick, int quiet); +void notify_set_online (server * serv, char *nick, + const message_tags_data *tags_data); +void notify_set_offline (server * serv, char *nick, int quiet, + const message_tags_data *tags_data); void notify_send_watches (server * serv); /* the general stuff */ @@ -51,13 +55,14 @@ int notify_deluser (char *name); void notify_cleanup (void); void notify_load (void); void notify_save (void); -void notify_showlist (session *sess); +void notify_showlist (session *sess, const message_tags_data *tags_data); gboolean notify_is_in_list (server *serv, char *name); int notify_isnotify (session *sess, char *name); struct notify_per_server *notify_find_server_entry (struct notify *notify, struct server *serv); /* the old ISON stuff - remove me? */ -void notify_markonline (server *serv, char *word[]); +void notify_markonline (server *serv, char *word[], + const message_tags_data *tags_data); int notify_checklist (void); #endif diff --git a/src/common/outbound.c b/src/common/outbound.c index 120bb241..3709ce96 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -1419,7 +1419,8 @@ cmd_dns (struct session *sess, char *tbuf, char *word[], char *word_eol[]) user = userlist_find (sess, nick); if (user && user->hostname) { - do_dns (sess, user->nick, user->hostname); + message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; + do_dns (sess, user->nick, user->hostname, &no_tags); } else { sess->server->p_get_ip (sess->server, nick); @@ -2606,6 +2607,7 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) char *split_text = NULL; int cmd_length = 22; /* " PRIVMSG ", " ", :, \001ACTION, " ", \001, \r, \n */ int offset = 0; + message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; if (!(*act)) return FALSE; @@ -2621,7 +2623,8 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (dcc_write_chat (sess->channel, tbuf)) { /* print it to screen */ - inbound_action (sess, sess->channel, sess->server->nick, "", act, TRUE, FALSE); + inbound_action (sess, sess->channel, sess->server->nick, "", act, TRUE, FALSE, + &no_tags); } else { /* DCC CHAT failed, try through server */ @@ -2631,7 +2634,9 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { sess->server->p_action (sess->server, sess->channel, split_text); /* print it to screen */ - inbound_action (sess, sess->channel, sess->server->nick, "", split_text, TRUE, FALSE); + inbound_action (sess, sess->channel, sess->server->nick, "", + split_text, TRUE, FALSE, + &no_tags); if (*split_text) offset += strlen(split_text); @@ -2641,7 +2646,8 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) sess->server->p_action (sess->server, sess->channel, act + offset); /* print it to screen */ - inbound_action (sess, sess->channel, sess->server->nick, "", act + offset, TRUE, FALSE); + inbound_action (sess, sess->channel, sess->server->nick, "", + act + offset, TRUE, FALSE, &no_tags); } else { notc_msg (sess); @@ -2701,7 +2707,6 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]) char *nick = word[2]; char *msg = word_eol[3]; struct session *newsess; - char *split_text = NULL; int cmd_length = 13; /* " PRIVMSG ", " ", :, \r, \n */ int offset = 0; @@ -2752,10 +2757,13 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]) newsess = find_channel (sess->server, nick); if (newsess) { + message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; + while ((split_text = split_up_text (sess, msg + offset, cmd_length, split_text))) { inbound_chanmsg (newsess->server, NULL, newsess->channel, - newsess->server->nick, split_text, TRUE, FALSE); + newsess->server->nick, split_text, TRUE, FALSE, + &no_tags); if (*split_text) offset += strlen(split_text); @@ -2763,7 +2771,8 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]) g_free(split_text); } inbound_chanmsg (newsess->server, NULL, newsess->channel, - newsess->server->nick, msg + offset, TRUE, FALSE); + newsess->server->nick, msg + offset, TRUE, FALSE, + &no_tags); } else { @@ -2825,7 +2834,11 @@ cmd_nick (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (sess->server->connected) sess->server->p_change_nick (sess->server, nick); else - inbound_newnick (sess->server, sess->server->nick, nick, TRUE); + { + message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; + inbound_newnick (sess->server, sess->server->nick, nick, TRUE, + &no_tags); + } return TRUE; } return FALSE; @@ -2894,7 +2907,10 @@ cmd_notify (struct session *sess, char *tbuf, char *word[], char *word_eol[]) } } } else - notify_showlist (sess); + { + message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; + notify_showlist (sess, &no_tags); + } return TRUE; } @@ -3699,8 +3715,11 @@ cmd_wallchan (struct session *sess, char *tbuf, char *word[], sess = list->data; if (sess->type == SESS_CHANNEL) { + message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; + inbound_chanmsg (sess->server, NULL, sess->channel, - sess->server->nick, word_eol[2], TRUE, FALSE); + sess->server->nick, word_eol[2], TRUE, FALSE, + &no_tags); sess->server->p_message (sess->server, sess->channel, word_eol[2]); } list = list->next; @@ -4344,6 +4363,7 @@ handle_say (session *sess, char *text, int check_spch) char *newcmd = newcmd_static; int len; int newcmdlen = sizeof newcmd_static; + message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; if (strcmp (sess->channel, "(lastlog)") == 0) { @@ -4396,7 +4416,7 @@ handle_say (session *sess, char *text, int check_spch) if (dcc) { inbound_chanmsg (sess->server, NULL, sess->channel, - sess->server->nick, text, TRUE, FALSE); + sess->server->nick, text, TRUE, FALSE, &no_tags); set_topic (sess, net_ip (dcc->addr), net_ip (dcc->addr)); goto xit; } @@ -4411,7 +4431,7 @@ handle_say (session *sess, char *text, int check_spch) while ((split_text = split_up_text (sess, text + offset, cmd_length, split_text))) { inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick, - split_text, TRUE, FALSE); + split_text, TRUE, FALSE, &no_tags); sess->server->p_message (sess->server, sess->channel, split_text); if (*split_text) @@ -4421,7 +4441,7 @@ handle_say (session *sess, char *text, int check_spch) } inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick, - text + offset, TRUE, FALSE); + text + offset, TRUE, FALSE, &no_tags); sess->server->p_message (sess->server, sess->channel, text + offset); } else { diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index ec4a36a3..204fccda 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" @@ -443,17 +444,20 @@ irc_raw (server *serv, char *raw) static void -channel_date (session *sess, char *chan, char *timestr) +channel_date (session *sess, char *chan, char *timestr, + const message_tags_data *tags_data) { time_t timestamp = (time_t) atol (timestr); char *tim = ctime (×tamp); tim[24] = 0; /* get rid of the \n */ - EMIT_SIGNAL (XP_TE_CHANDATE, sess, chan, tim, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDATE, sess, chan, tim, NULL, NULL, 0, + tags_data->timestamp); } static void process_numeric (session * sess, int n, - char *word[], char *word_eol[], char *text) + char *word[], char *word_eol[], char *text, + const message_tags_data *tags_data) { server *serv = sess->server; /* show whois is the server tab */ @@ -468,7 +472,7 @@ process_numeric (session * sess, int n, switch (n) { case 1: - inbound_login_start (sess, word[3], word[1]); + inbound_login_start (sess, word[3], word[1], tags_data); /* if network is PTnet then you must get your IP address from "001" server message */ if ((strncmp(word[7], "PTnet", 5) == 0) && @@ -478,7 +482,7 @@ process_numeric (session * sess, int n, { serv->use_who = FALSE; if (prefs.hex_dcc_ip_from_server) - inbound_foundip (sess, strrchr(word[10], '@')+1); + inbound_foundip (sess, strrchr(word[10], '@')+1, tags_data); } goto def; @@ -500,7 +504,7 @@ process_numeric (session * sess, int n, goto def; case 5: - inbound_005 (serv, word); + inbound_005 (serv, word, tags_data); goto def; case 263: /*Server load is temporarily too heavy */ @@ -513,7 +517,8 @@ process_numeric (session * sess, int n, case 301: inbound_away (serv, word[4], - (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5]); + (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5], + tags_data); break; case 302: @@ -527,7 +532,7 @@ process_numeric (session * sess, int n, { char *at = strrchr (eq + 1, '@'); if (at) - inbound_foundip (sess, at + 1); + inbound_foundip (sess, at + 1, tags_data); } } @@ -538,39 +543,42 @@ process_numeric (session * sess, int n, case 303: word[4]++; - notify_markonline (serv, word); + notify_markonline (serv, word, tags_data); break; case 305: - inbound_uback (serv); + inbound_uback (serv, tags_data); goto def; case 306: - inbound_uaway (serv); + inbound_uaway (serv, tags_data); goto def; case 312: if (!serv->skip_next_whois) - EMIT_SIGNAL (XP_TE_WHOIS3, whois_sess, word[4], word_eol[5], NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS3, whois_sess, word[4], word_eol[5], + NULL, NULL, 0, tags_data->timestamp); else - inbound_user_info (sess, NULL, NULL, NULL, word[5], word[4], NULL, NULL, 0xff); + inbound_user_info (sess, NULL, NULL, NULL, word[5], word[4], NULL, NULL, + 0xff, tags_data); break; case 311: /* WHOIS 1st line */ serv->inside_whois = 1; - inbound_user_info_start (sess, word[4]); + inbound_user_info_start (sess, word[4], tags_data); if (!serv->skip_next_whois) - EMIT_SIGNAL (XP_TE_WHOIS1, whois_sess, word[4], word[5], - word[6], word_eol[8] + 1, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS1, whois_sess, word[4], word[5], + word[6], word_eol[8] + 1, 0, tags_data->timestamp); else inbound_user_info (sess, NULL, word[5], word[6], NULL, word[4], - word_eol[8][0] == ':' ? word_eol[8] + 1 : word_eol[8], NULL, 0xff); + word_eol[8][0] == ':' ? word_eol[8] + 1 : word_eol[8], + NULL, 0xff, tags_data); break; case 314: /* WHOWAS */ - inbound_user_info_start (sess, word[4]); - EMIT_SIGNAL (XP_TE_WHOIS1, whois_sess, word[4], word[5], - word[6], word_eol[8] + 1, 0); + inbound_user_info_start (sess, word[4], tags_data); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS1, whois_sess, word[4], word[5], + word[6], word_eol[8] + 1, 0, tags_data->timestamp); break; case 317: @@ -585,22 +593,22 @@ process_numeric (session * sess, int n, "%02ld:%02ld:%02ld", idle / 3600, (idle / 60) % 60, idle % 60); if (timestamp == 0) - EMIT_SIGNAL (XP_TE_WHOIS4, whois_sess, word[4], - outbuf, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS4, whois_sess, word[4], + outbuf, NULL, NULL, 0, tags_data->timestamp); else { tim = ctime (×tamp); tim[19] = 0; /* get rid of the \n */ - EMIT_SIGNAL (XP_TE_WHOIS4T, whois_sess, word[4], - outbuf, tim, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS4T, whois_sess, word[4], + outbuf, tim, NULL, 0, tags_data->timestamp); } } break; case 318: /* END OF WHOIS */ if (!serv->skip_next_whois) - EMIT_SIGNAL (XP_TE_WHOIS6, whois_sess, word[4], NULL, - NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS6, whois_sess, word[4], NULL, + NULL, NULL, 0, tags_data->timestamp); serv->skip_next_whois = 0; serv->inside_whois = 0; break; @@ -608,20 +616,23 @@ process_numeric (session * sess, int n, case 313: case 319: if (!serv->skip_next_whois) - EMIT_SIGNAL (XP_TE_WHOIS2, whois_sess, word[4], - word_eol[5] + 1, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS2, whois_sess, word[4], + word_eol[5] + 1, NULL, NULL, 0, + tags_data->timestamp); break; case 307: /* dalnet version */ case 320: /* :is an identified user */ if (!serv->skip_next_whois) - EMIT_SIGNAL (XP_TE_WHOIS_ID, whois_sess, word[4], - word_eol[5] + 1, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS_ID, whois_sess, word[4], + word_eol[5] + 1, NULL, NULL, 0, + tags_data->timestamp); break; case 321: if (!fe_is_chanwindow (sess->server)) - EMIT_SIGNAL (XP_TE_CHANLISTHEAD, serv->server_session, NULL, NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANLISTHEAD, serv->server_session, NULL, + NULL, NULL, NULL, 0, tags_data->timestamp); break; case 322: @@ -630,14 +641,16 @@ process_numeric (session * sess, int n, fe_add_chan_list (sess->server, word[4], word[5], word_eol[6] + 1); } else { - PrintTextf (serv->server_session, "%-16s %-7d %s\017\n", - word[4], atoi (word[5]), word_eol[6] + 1); + PrintTextTimeStampf (serv->server_session, tags_data->timestamp, + "%-16s %-7d %s\017\n", word[4], atoi (word[5]), + word_eol[6] + 1); } break; case 323: if (!fe_is_chanwindow (sess->server)) - EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, serv->server_session, text, + word[1], word[2], NULL, 0, tags_data->timestamp); else fe_chan_list_end (sess->server); break; @@ -649,8 +662,8 @@ process_numeric (session * sess, int n, if (sess->ignore_mode) sess->ignore_mode = FALSE; else - EMIT_SIGNAL (XP_TE_CHANMODES, sess, word[4], word_eol[5], - NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODES, sess, word[4], word_eol[5], + NULL, NULL, 0, tags_data->timestamp); fe_update_mode_buttons (sess, 't', '-'); fe_update_mode_buttons (sess, 'n', '-'); fe_update_mode_buttons (sess, 's', '-'); @@ -659,7 +672,7 @@ process_numeric (session * sess, int n, fe_update_mode_buttons (sess, 'm', '-'); fe_update_mode_buttons (sess, 'l', '-'); fe_update_mode_buttons (sess, 'k', '-'); - handle_mode (serv, word, word_eol, "", TRUE); + handle_mode (serv, word, word_eol, "", TRUE, tags_data); break; case 329: @@ -669,36 +682,40 @@ process_numeric (session * sess, int n, if (sess->ignore_date) sess->ignore_date = FALSE; else - channel_date (sess, word[4], word[5]); + channel_date (sess, word[4], word[5], tags_data); } break; case 330: if (!serv->skip_next_whois) - EMIT_SIGNAL (XP_TE_WHOIS_AUTH, whois_sess, word[4], - word_eol[6] + 1, word[5], NULL, 0); - inbound_user_info (sess, NULL, NULL, NULL, NULL, word[4], NULL, word[5], 0xff); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS_AUTH, whois_sess, word[4], + word_eol[6] + 1, word[5], NULL, 0, + tags_data->timestamp); + inbound_user_info (sess, NULL, NULL, NULL, NULL, word[4], NULL, word[5], + 0xff, tags_data); break; case 332: inbound_topic (serv, word[4], - (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5]); + (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5], + tags_data); break; case 333: - inbound_topictime (serv, word[4], word[5], atol (word[6])); + inbound_topictime (serv, word[4], word[5], atol (word[6]), tags_data); break; #if 0 case 338: /* Undernet Real user@host, Real IP */ - EMIT_SIGNAL (XP_TE_WHOIS_REALHOST, sess, word[4], word[5], word[6], - (word_eol[7][0]==':') ? word_eol[7]+1 : word_eol[7], 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS_REALHOST, sess, word[4], word[5], word[6], + (word_eol[7][0]==':') ? word_eol[7]+1 : word_eol[7], + 0, tags_data->timestamp); break; #endif case 341: /* INVITE ACK */ - EMIT_SIGNAL (XP_TE_UINVITE, sess, word[4], word[5], serv->servername, - NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_UINVITE, sess, word[4], word[5], + serv->servername, NULL, 0, tags_data->timestamp); break; case 352: /* WHO */ @@ -710,12 +727,13 @@ process_numeric (session * sess, int n, away = 1; inbound_user_info (sess, word[4], word[5], word[6], word[7], - word[8], word_eol[11], NULL, away); + word[8], word_eol[11], NULL, away, + tags_data); /* try to show only user initiated whos */ if (!who_sess || !who_sess->doing_who) - EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], - word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, serv->server_session, text, word[1], + word[2], NULL, 0, tags_data->timestamp); } break; @@ -734,12 +752,14 @@ process_numeric (session * sess, int n, /* :server 354 yournick 152 #channel ~ident host servname nick H account :realname */ inbound_user_info (sess, word[5], word[6], word[7], word[8], - word[9], word_eol[12]+1, word[11], away); + word[9], word_eol[12]+1, word[11], away, + tags_data); /* try to show only user initiated whos */ if (!who_sess || !who_sess->doing_who) - EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, - word[1], word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, serv->server_session, text, + word[1], word[2], NULL, 0, + tags_data->timestamp); } else goto def; } @@ -752,21 +772,23 @@ process_numeric (session * sess, int n, if (who_sess) { if (!who_sess->doing_who) - EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, - word[1], word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, serv->server_session, text, + word[1], word[2], NULL, 0, + tags_data->timestamp); who_sess->doing_who = FALSE; } else { if (!serv->doing_dns) - EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, - word[1], word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, serv->server_session, text, + word[1], word[2], NULL, 0, tags_data->timestamp); serv->doing_dns = FALSE; } } break; case 346: /* +I-list entry */ - if (!inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], 346)) + if (!inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], 346, + tags_data)) goto def; break; @@ -776,7 +798,8 @@ process_numeric (session * sess, int n, break; case 348: /* +e-list entry */ - if (!inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], 348)) + if (!inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], 348, + tags_data)) goto def; break; @@ -793,16 +816,18 @@ process_numeric (session * sess, int n, case 353: /* NAMES */ inbound_nameslist (serv, word[5], - (word_eol[6][0] == ':') ? word_eol[6] + 1 : word_eol[6]); + (word_eol[6][0] == ':') ? word_eol[6] + 1 : word_eol[6], + tags_data); break; case 366: - if (!inbound_nameslist_end (serv, word[4])) + if (!inbound_nameslist_end (serv, word[4], tags_data)) goto def; break; case 367: /* banlist entry */ - if (!inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], 367)) + if (!inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], 367, + tags_data)) goto def; break; @@ -819,20 +844,21 @@ process_numeric (session * sess, int n, case 369: /* WHOWAS end */ case 406: /* WHOWAS error */ - EMIT_SIGNAL (XP_TE_SERVTEXT, whois_sess, text, word[1], word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, whois_sess, text, word[1], word[2], + NULL, 0, tags_data->timestamp); serv->inside_whois = 0; break; case 372: /* motd text */ case 375: /* motd start */ if (!prefs.hex_irc_skip_motd || serv->motd_skipped) - 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); break; case 376: /* end of motd */ case 422: /* motd file is missing */ - inbound_login_end (sess, text); + inbound_login_end (sess, text, tags_data); break; case 432: /* erroneous nickname */ @@ -840,7 +866,7 @@ process_numeric (session * sess, int n, { goto def; } - inbound_next_nick (sess, word[4], 1); + inbound_next_nick (sess, word[4], 1, tags_data); break; case 433: /* nickname in use */ @@ -848,48 +874,53 @@ process_numeric (session * sess, int n, { goto def; } - inbound_next_nick (sess, word[4], 0); + inbound_next_nick (sess, word[4], 0, tags_data); break; case 437: if (serv->end_of_motd || is_channel (serv, word[4])) goto def; - inbound_next_nick (sess, word[4], 0); + inbound_next_nick (sess, word[4], 0, tags_data); break; case 471: - EMIT_SIGNAL (XP_TE_USERLIMIT, sess, word[4], NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_USERLIMIT, sess, word[4], NULL, NULL, NULL, 0, + tags_data->timestamp); break; case 473: - EMIT_SIGNAL (XP_TE_INVITE, sess, word[4], NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITE, sess, word[4], NULL, NULL, NULL, 0, + tags_data->timestamp); break; case 474: - EMIT_SIGNAL (XP_TE_BANNED, sess, word[4], NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_BANNED, sess, word[4], NULL, NULL, NULL, 0, + tags_data->timestamp); break; case 475: - EMIT_SIGNAL (XP_TE_KEYWORD, sess, word[4], NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_KEYWORD, sess, word[4], NULL, NULL, NULL, 0, + tags_data->timestamp); break; case 601: - notify_set_offline (serv, word[4], FALSE); + notify_set_offline (serv, word[4], FALSE, tags_data); break; case 605: - notify_set_offline (serv, word[4], TRUE); + notify_set_offline (serv, word[4], TRUE, tags_data); break; case 600: case 604: - notify_set_online (serv, word[4]); + notify_set_online (serv, word[4], tags_data); break; case 728: /* +q-list entry */ /* NOTE: FREENODE returns these results inconsistent with e.g. +b */ /* Who else has imlemented MODE_QUIET, I wonder? */ - if (!inbound_banlist (sess, atol (word[8]), word[4], word[6], word[7], 728)) + if (!inbound_banlist (sess, atol (word[8]), word[4], word[6], word[7], 728, + tags_data)) goto def; break; @@ -902,25 +933,29 @@ process_numeric (session * sess, int n, ex = strchr (word[4], '!'); /* only send the nick */ if (ex) ex[0] = 0; - notify_set_online (serv, word[4] + 1); + notify_set_online (serv, word[4] + 1, tags_data); break; case 731: /* RPL_MONOFFLINE */ ex = strchr (word[4], '!'); /* only send the nick */ if (ex) ex[0] = 0; - notify_set_offline (serv, word[4] + 1, FALSE); + notify_set_offline (serv, word[4] + 1, FALSE, tags_data); break; case 900: /* successful SASL 'logged in as ' */ - EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, word_eol[6]+1, word[1], word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, serv->server_session, + word_eol[6]+1, word[1], word[2], NULL, 0, + tags_data->timestamp); break; case 903: /* successful SASL auth */ case 904: /* aborted SASL auth */ case 905: /* failed SASL auth */ case 906: /* registration completes before SASL auth */ case 907: /* attempting to re-auth after a successful auth */ - EMIT_SIGNAL (XP_TE_SASLRESPONSE, serv->server_session, word[1], word[2], word[3], ++word_eol[4], 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SASLRESPONSE, serv->server_session, word[1], + word[2], word[3], ++word_eol[4], 0, + tags_data->timestamp); tcp_send_len (serv, "CAP END\r\n", 9); break; @@ -930,9 +965,9 @@ process_numeric (session * sess, int n, { /* some unknown WHOIS reply, ircd coders make them up weekly */ if (!serv->skip_next_whois) - EMIT_SIGNAL (XP_TE_WHOIS_SPECIAL, whois_sess, word[4], - (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5], - word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS_SPECIAL, whois_sess, word[4], + (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5], + word[2], NULL, 0, tags_data->timestamp); return; } @@ -951,7 +986,8 @@ process_numeric (session * sess, int n, else sess=serv->server_session; - EMIT_SIGNAL (XP_TE_SERVTEXT, sess, text, word[1], word[2], NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, sess, text, word[1], word[2], + NULL, 0, tags_data->timestamp); } } } @@ -959,7 +995,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 *tags_data) { server *serv = sess->server; char ip[128], nick[NICKLEN]; @@ -997,9 +1034,10 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) if (*chan == ':') chan++; if (!serv->p_cmp (nick, serv->nick)) - inbound_ujoin (serv, chan, nick, ip); + inbound_ujoin (serv, chan, nick, ip, tags_data); else - inbound_join (serv, chan, nick, ip, account, realname); + inbound_join (serv, chan, nick, ip, account, realname, + tags_data); } return; @@ -1012,24 +1050,26 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) if (*reason == ':') reason++; if (!strcmp (kicked, serv->nick)) - inbound_ukick (serv, word[3], nick, reason); + inbound_ukick (serv, word[3], nick, reason, tags_data); else - inbound_kick (serv, word[3], kicked, nick, reason); + inbound_kick (serv, word[3], kicked, nick, reason, tags_data); } } return; case WORDL('K','I','L','L'): - EMIT_SIGNAL (XP_TE_KILL, sess, nick, word_eol[5], NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_KILL, sess, nick, word_eol[5], NULL, NULL, + 0, tags_data->timestamp); return; case WORDL('M','O','D','E'): - handle_mode (serv, word, word_eol, nick, FALSE); /* modes.c */ + handle_mode (serv, word, word_eol, nick, FALSE, tags_data); /* modes.c */ return; case WORDL('N','I','C','K'): - inbound_newnick (serv, nick, (word_eol[3][0] == ':') - ? word_eol[3] + 1 : word_eol[3], FALSE); + inbound_newnick (serv, nick, + (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3], + FALSE, tags_data); return; case WORDL('P','A','R','T'): @@ -1042,25 +1082,28 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) if (*reason == ':') reason++; if (!strcmp (nick, serv->nick)) - inbound_upart (serv, chan, ip, reason); + inbound_upart (serv, chan, ip, reason, tags_data); else - inbound_part (serv, chan, nick, ip, reason); + inbound_part (serv, chan, nick, ip, reason, tags_data); } return; case WORDL('P','O','N','G'): inbound_ping_reply (serv->server_session, - (word[4][0] == ':') ? word[4] + 1 : word[4], word[3]); + (word[4][0] == ':') ? word[4] + 1 : word[4], + word[3], tags_data); return; case WORDL('Q','U','I','T'): inbound_quit (serv, nick, ip, - (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3]); + (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3], + tags_data); return; case WORDL('A','W','A','Y'): inbound_away_notify (serv, nick, - (word_eol[3][0] == ':') ? word_eol[3] + 1 : NULL); + (word_eol[3][0] == ':') ? word_eol[3] + 1 : NULL, + tags_data); return; } @@ -1077,7 +1120,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) { case WORDL('A','C','C','O'): - inbound_account (serv, nick, word[3]); + inbound_account (serv, nick, word[3], tags_data); return; case WORDL('I','N','V','I'): @@ -1085,11 +1128,13 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) return; if (word[4][0] == ':') - EMIT_SIGNAL (XP_TE_INVITED, sess, word[4] + 1, nick, - serv->servername, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, word[4] + 1, nick, + serv->servername, NULL, 0, + tags_data->timestamp); else - EMIT_SIGNAL (XP_TE_INVITED, sess, word[4], nick, - serv->servername, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, word[4], nick, + serv->servername, NULL, 0, + tags_data->timestamp); return; @@ -1129,7 +1174,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) } if (!ignore_check (word[1], IG_NOTI)) - inbound_notice (serv, word[3], nick, text, ip, id); + inbound_notice (serv, word[3], nick, text, ip, id, tags_data); } return; @@ -1166,19 +1211,21 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) if (g_ascii_strncasecmp (text, "DCC ", 4) == 0) /* redo this with handle_quotes TRUE */ process_data_init (word[1], word_eol[1], word, word_eol, TRUE, FALSE); - ctcp_handle (sess, to, nick, ip, text, word, word_eol, id); + ctcp_handle (sess, to, nick, ip, text, word, word_eol, id, + tags_data); } else { if (is_channel (serv, to)) { 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)) return; - inbound_privmsg (serv, nick, ip, text, id); + inbound_privmsg (serv, nick, ip, text, id, tags_data); } } } @@ -1187,14 +1234,16 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) case WORDL('T','O','P','I'): inbound_topicnew (serv, nick, word[3], - (word_eol[4][0] == ':') ? word_eol[4] + 1 : word_eol[4]); + (word_eol[4][0] == ':') ? word_eol[4] + 1 : word_eol[4], + tags_data); return; case WORDL('W','A','L','L'): text = word_eol[3]; if (*text == ':') text++; - EMIT_SIGNAL (XP_TE_WALLOPS, sess, nick, text, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_WALLOPS, sess, nick, text, NULL, NULL, 0, + tags_data->timestamp); return; } } @@ -1202,10 +1251,6 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) else if (len == 3) { guint32 t; - 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 *pass; /* buffer for SASL password */ - char buffer[256]; /* buffer for requesting capabilities and emitting the signal */ t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); switch (t) @@ -1213,117 +1258,25 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) case WORDL('C','A','P','\0'): if (strncasecmp (word[4], "ACK", 3) == 0) { - EMIT_SIGNAL (XP_TE_CAPACK, sess->server->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0); - - if (strstr (word_eol[5], "identify-msg") != 0) - { - serv->have_idmsg = TRUE; - } - - if (strstr (word_eol[5], "multi-prefix") != 0) - { - serv->have_namesx = TRUE; - } - - if (strstr (word_eol[5], "away-notify") != 0) - { - serv->have_awaynotify = TRUE; - } - - if (strstr (word_eol[5], "account-notify") != 0) - { - serv->have_accnotify = TRUE; - } - - if (strstr (word_eol[5], "extended-join") != 0) - { - serv->have_extjoin = TRUE; - } - - if (strstr (word_eol[5], "sasl") != 0) - { - serv->have_sasl = TRUE; - EMIT_SIGNAL - ( - XP_TE_SASLAUTH, - serv->server_session, - (((ircnet *)sess->server->network)->user) ? (((ircnet *)sess->server->network)->user) : prefs.hex_irc_user_name, - NULL, - NULL, - NULL, - 0 - ); - tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20); - - pass = encode_sasl_pass - ( - (((ircnet *)sess->server->network)->user) ? (((ircnet *)sess->server->network)->user) : prefs.hex_irc_user_name, - sess->server->password - ); - tcp_sendf (sess->server, "AUTHENTICATE %s\r\n", pass); - free (pass); - } + inbound_cap_ack (serv, word[1], + word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5], + tags_data); } else if (strncasecmp (word[4], "LS", 2) == 0) { - EMIT_SIGNAL (XP_TE_CAPLIST, serv->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0); - want_cap = 0; - want_sasl = 0; - - strcpy (buffer, "CAP REQ :"); - - if (strstr (word_eol[5], "identify-msg") != 0) - { - strcat (buffer, "identify-msg "); - want_cap = 1; - } - if (strstr (word_eol[5], "multi-prefix") != 0) - { - strcat (buffer, "multi-prefix "); - want_cap = 1; - } - if (strstr (word_eol[5], "away-notify") != 0) - { - strcat (buffer, "away-notify "); - want_cap = 1; - } - if (strstr (word_eol[5], "account-notify") != 0) - { - strcat (buffer, "account-notify "); - want_cap = 1; - } - if (strstr (word_eol[5], "extended-join") != 0) - { - 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 (word_eol[5], "sasl") != 0 && strlen (sess->server->password) != 0 && serv->loginmethod == LOGIN_SASL) - { - strcat (buffer, "sasl "); - want_cap = 1; - want_sasl = 1; - } - - if (want_cap) - { - /* buffer + 9 = emit buffer without "CAP REQ :" */ - EMIT_SIGNAL (XP_TE_CAPREQ, sess->server->server_session, buffer + 9, NULL, NULL, NULL, 0); - 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); - } + inbound_cap_ls (serv, word[1], + word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5], + tags_data); } else if (strncasecmp (word[4], "NAK", 3) == 0) { - tcp_send_len (serv, "CAP END\r\n", 9); + inbound_cap_nak (serv, tags_data); } else if (strncasecmp (word[4], "LIST", 4) == 0) { - EMIT_SIGNAL (XP_TE_CAPACK, sess->server->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0); + inbound_cap_list (serv, word[1], + word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5], + tags_data); } return; @@ -1332,13 +1285,14 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) garbage: /* unknown message */ - PrintTextf (sess, "GARBAGE: %s\n", word_eol[1]); + PrintTextTimeStampf (sess, tags_data->timestamp, "GARBAGE: %s\n", word_eol[1]); } /* handle named messages that DON'T start with a ':' */ static void -process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol[]) +process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol[], + const message_tags_data *tags_data) { sess = sess->server->server_session; @@ -1349,7 +1303,8 @@ process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol } if (!strncmp (buf, "ERROR", 5)) { - EMIT_SIGNAL (XP_TE_SERVERERROR, sess, buf + 7, NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVERERROR, sess, buf + 7, NULL, NULL, NULL, + 0, tags_data->timestamp); return; } if (!strncmp (buf, "NOTICE ", 7)) @@ -1357,7 +1312,9 @@ process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol buf = word_eol[3]; if (*buf == ':') buf++; - EMIT_SIGNAL (XP_TE_SERVNOTICE, sess, buf, sess->server->servername, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVNOTICE, sess, buf, + sess->server->servername, NULL, NULL, 0, + tags_data->timestamp); return; } if (!strncmp (buf, "AUTHENTICATE +", 14)) /* omit SASL "empty" responses */ @@ -1365,11 +1322,99 @@ process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol return; } - EMIT_SIGNAL (XP_TE_SERVTEXT, sess, buf, sess->server->servername, rawname, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, sess, buf, sess->server->servername, + rawname, NULL, 0, tags_data->timestamp); } -/* irc_inline() - 1 single line received from serv */ +/* Handle time-server tags. + * + * Sets tags_data->timestamp to the correct time (in unix time). + * This received time is always in UTC. + * + * See http://ircv3.atheme.org/extensions/server-time-3.2 + */ +static void +handle_message_tag_time (const char *time, message_tags_data *tags_data) +{ + /* The time format defined in the ircv3.2 specification is + * YYYY-MM-DDThh:mm:ss.sssZ + * but znc simply sends a unix time (with 3 decimal places for miliseconds) + * so we might as well support both. + */ + if (!*time) + return; + + if (time[strlen (time) - 1] == 'Z') + { + /* as defined in the specification */ + struct tm t; + int z; + + /* we ignore the milisecond part */ + z = sscanf (time, "%d-%d-%dT%d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday, + &t.tm_hour, &t.tm_min, &t.tm_sec); + if (z != 6) + return; + + t.tm_isdst = 0; /* day light saving time */ + + tags_data->timestamp = mktime (&t); + + if (tags_data->timestamp < 0) + { + tags_data->timestamp = 0; + return; + } + } + else + { + /* znc */ + long long int t; + + /* we ignore the milisecond part */ + if (sscanf (time, "%lld", &t) != 1) + return; + + tags_data->timestamp = (time_t) t; + } +} + +/* Handle message tags. + * + * See http://ircv3.atheme.org/specification/message-tags-3.2 + */ +static void +handle_message_tags (server *serv, const char *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 (serv->have_server_time && !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 +1424,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 +1436,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(serv, 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 +1477,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; @@ -1425,7 +1484,7 @@ irc_inline (server *serv, char *buf, int len) if (buf[0] != ':') { - process_named_servermsg (sess, buf, word[0], word_eol); + process_named_servermsg (sess, buf, word[0], word_eol, &tags_data); goto xit; } @@ -1436,10 +1495,10 @@ irc_inline (server *serv, char *buf, int len) if (*text == ':') text++; - process_numeric (sess, atoi (word[2]), word, word_eol, text); + process_numeric (sess, atoi (word[2]), word, word_eol, text, &tags_data); } else { - process_named_msg (sess, type, word, word_eol); + process_named_msg (sess, type, word, word_eol, &tags_data); } xit: diff --git a/src/common/proto-irc.h b/src/common/proto-irc.h index 2de9815c..a7b4029c 100644 --- a/src/common/proto-irc.h +++ b/src/common/proto-irc.h @@ -17,9 +17,26 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <time.h> +#include "hexchat.h" + #ifndef HEXCHAT_PROTO_H #define HEXCHAT_PROTO_H +#define MESSAGE_TAGS_DATA_INIT \ + { \ + (time_t)0, /* timestamp */ \ + } + +/* Message tag information that might be passed along with a server message + * + * See http://ircv3.atheme.org/specification/capability-negotiation-3.1 + */ +typedef struct +{ + time_t timestamp; +} message_tags_data; + void proto_fill_her_up (server *serv); #endif 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; diff --git a/src/common/text.c b/src/common/text.c index f0a1dfb1..a0e860ce 100644 --- a/src/common/text.c +++ b/src/common/text.c @@ -866,7 +866,7 @@ text_validate (char **text, int *len) } void -PrintText (session *sess, char *text) +PrintTextTimeStamp (session *sess, char *text, time_t timestamp) { char *conv; @@ -890,13 +890,19 @@ PrintText (session *sess, char *text) log_write (sess, text); scrollback_save (sess, text); - fe_print_text (sess, text, 0); + fe_print_text (sess, text, timestamp); if (conv) g_free (conv); } void +PrintText (session *sess, char *text) +{ + PrintTextTimeStamp (sess, text, 0); +} + +void PrintTextf (session *sess, char *format, ...) { va_list args; @@ -910,6 +916,20 @@ PrintTextf (session *sess, char *format, ...) g_free (buf); } +void +PrintTextTimeStampf (session *sess, time_t timestamp, char *format, ...) +{ + va_list args; + char *buf; + + va_start (args, format); + buf = g_strdup_vprintf (format, args); + va_end (args); + + PrintTextTimeStamp (sess, buf, timestamp); + g_free (buf); +} + /* Print Events stuff here --AGL */ /* Consider the following a NOTES file: @@ -1836,12 +1856,13 @@ format_event (session *sess, int index, char **args, char *o, int sizeofo, unsig } static void -display_event (session *sess, int event, char **args, unsigned int stripcolor_args) +display_event (session *sess, int event, char **args, + unsigned int stripcolor_args, time_t timestamp) { char o[4096]; format_event (sess, event, args, o, sizeof (o), stripcolor_args); if (o[0]) - PrintText (sess, o); + PrintTextTimeStamp (sess, o, timestamp); } int @@ -2042,7 +2063,8 @@ text_color_of (char *name) /* called by EMIT_SIGNAL macro */ void -text_emit (int index, session *sess, char *a, char *b, char *c, char *d) +text_emit (int index, session *sess, char *a, char *b, char *c, char *d, + time_t timestamp) { char *word[PDIWORDS]; int i; @@ -2120,7 +2142,7 @@ text_emit (int index, session *sess, char *a, char *b, char *c, char *d) } sound_play_event (index); - display_event (sess, index, word, stripcolor_args); + display_event (sess, index, word, stripcolor_args, timestamp); } char * @@ -2143,7 +2165,7 @@ text_emit_by_name (char *name, session *sess, char *a, char *b, char *c, char *d i = pevent_find (name, &i); if (i >= 0) { - text_emit (i, sess, a, b, c, d); + text_emit (i, sess, a, b, c, d, 0); return 1; } diff --git a/src/common/text.h b/src/common/text.h index 52cc8ea9..5a51c894 100644 --- a/src/common/text.h +++ b/src/common/text.h @@ -17,12 +17,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <time.h> #include "textenums.h" #ifndef HEXCHAT_TEXT_H #define HEXCHAT_TEXT_H -#define EMIT_SIGNAL(i, sess, a, b, c, d, e) text_emit(i, sess, a, b, c, d) +/* timestamp is non-zero if we are using server-time */ +#define EMIT_SIGNAL_TIMESTAMP(i, sess, a, b, c, d, e, timestamp) \ + text_emit(i, sess, a, b, c, d, timestamp) +#define EMIT_SIGNAL(i, sess, a, b, c, d, e) \ + text_emit(i, sess, a, b, c, d, 0) struct text_event { @@ -37,7 +42,9 @@ void scrollback_load (session *sess); int text_word_check (char *word, int len); void PrintText (session *sess, char *text); +void PrintTextTimeStamp (session *sess, char *text, time_t timestamp); void PrintTextf (session *sess, char *format, ...); +void PrintTextTimeStampf (session *sess, time_t timestamp, char *format, ...); void log_close (session *sess); void log_open_or_close (session *sess); void load_text_events (void); @@ -46,7 +53,8 @@ int pevt_build_string (const char *input, char **output, int *max_arg); int pevent_load (char *filename); void pevent_make_pntevts (void); int text_color_of (char *name); -void text_emit (int index, session *sess, char *a, char *b, char *c, char *d); +void text_emit (int index, session *sess, char *a, char *b, char *c, char *d, + time_t timestamp); int text_emit_by_name (char *name, session *sess, char *a, char *b, char *c, char *d); char *text_validate (char **text, int *len); int get_stamp_str (char *fmt, time_t tim, char **ret); diff --git a/src/common/userlist.c b/src/common/userlist.c index 5e53be2a..c6c806bd 100644 --- a/src/common/userlist.c +++ b/src/common/userlist.c @@ -383,7 +383,8 @@ userlist_remove_user (struct session *sess, struct User *user) } void -userlist_add (struct session *sess, char *name, char *hostname, char *account, char *realname) +userlist_add (struct session *sess, char *name, char *hostname, + char *account, char *realname, const message_tags_data *tags_data) { struct User *user; int row, prefix_chars; @@ -391,7 +392,7 @@ userlist_add (struct session *sess, char *name, char *hostname, char *account, c acc = nick_access (sess->server, name, &prefix_chars); - notify_set_online (sess->server, name + prefix_chars); + notify_set_online (sess->server, name + prefix_chars, tags_data); user = malloc (sizeof (struct User)); memset (user, 0, sizeof (struct User)); diff --git a/src/common/userlist.h b/src/common/userlist.h index 777d61ea..ebf95606 100644 --- a/src/common/userlist.h +++ b/src/common/userlist.h @@ -18,6 +18,7 @@ */ #include <time.h> +#include "proto-irc.h" #ifndef HEXCHAT_USERLIST_H #define HEXCHAT_USERLIST_H @@ -51,7 +52,8 @@ struct User *userlist_find (session *sess, const char *name); struct User *userlist_find_global (server *serv, char *name); void userlist_clear (session *sess); void userlist_free (session *sess); -void userlist_add (session *sess, char *name, char *hostname, char *account, char *realname); +void userlist_add (session *sess, char *name, char *hostname, char *account, + char *realname, const message_tags_data *tags_data); int userlist_remove (session *sess, char *name); void userlist_remove_user (session *sess, struct User *user); int userlist_change (session *sess, char *oldname, char *newname); diff --git a/src/fe-gtk/setup.c b/src/fe-gtk/setup.c index 391004ee..2c5b982f 100644 --- a/src/fe-gtk/setup.c +++ b/src/fe-gtk/setup.c @@ -522,12 +522,13 @@ static const setting advanced_settings[] = "Otherwise, include color information if the CONTROL key is held down " "while selecting."), 0, 0}, - {ST_HEADER, N_("Miscellaneous"),0,0,0}, + {ST_HEADER, N_("Miscellaneous"), 0, 0, 0}, {ST_ENTRY, N_("Real name:"), P_OFFSETNL(hex_irc_real_name), 0, 0, sizeof prefs.hex_irc_real_name}, #ifdef WIN32 - {ST_ENTRY, N_("Alternative fonts:"), P_OFFSETNL(hex_text_font_alternative), "Separate multiple entries with commas without spaces before or after.", 0, sizeof prefs.hex_text_font_alternative}, + {ST_ENTRY, N_("Alternative fonts:"), P_OFFSETNL(hex_text_font_alternative), N_("Separate multiple entries with commas without spaces before or after."), 0, sizeof prefs.hex_text_font_alternative}, #endif {ST_TOGGLE, N_("Display lists in compact mode"), P_OFFINTNL(hex_gui_compact), N_("Use less spacing between user list/channel tree rows."), 0, 0}, + {ST_TOGGLE, N_("Use server time if supported"), P_OFFINTNL(hex_irc_cap_server_time), N_("Display timestamps obtained from server if it supports the time-server extension."), 0, 0}, {ST_TOGGLE, N_("Automatically reconnect to servers on disconnect"), P_OFFINTNL(hex_net_auto_reconnect), 0, 0, 1}, {ST_NUMBER, N_("Auto reconnect delay:"), P_OFFINTNL(hex_net_reconnect_delay), 0, 0, 9999}, {ST_NUMBER, N_("Auto join delay:"), P_OFFINTNL(hex_irc_join_delay), 0, 0, 9999}, |