2011-02-23 22:14:30 -05:00
|
|
|
/* X-Chat
|
|
|
|
* Copyright (C) 1998 Peter Zelezny.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-12-23 14:36:54 -05:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2011-02-23 22:14:30 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
2012-07-21 08:26:19 -04:00
|
|
|
#ifdef WIN32
|
|
|
|
#include <io.h>
|
|
|
|
#else
|
2011-12-11 11:34:02 -05:00
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2011-02-23 22:14:30 -05:00
|
|
|
#define WANTARPA
|
|
|
|
#define WANTDNS
|
|
|
|
#include "inet.h"
|
|
|
|
|
2012-10-24 15:33:02 -04:00
|
|
|
#include "hexchat.h"
|
2011-02-23 22:14:30 -05:00
|
|
|
#include "util.h"
|
|
|
|
#include "ignore.h"
|
|
|
|
#include "fe.h"
|
|
|
|
#include "modes.h"
|
|
|
|
#include "notify.h"
|
|
|
|
#include "outbound.h"
|
|
|
|
#include "inbound.h"
|
|
|
|
#include "server.h"
|
|
|
|
#include "servlist.h"
|
|
|
|
#include "text.h"
|
|
|
|
#include "ctcp.h"
|
2012-10-24 15:33:02 -04:00
|
|
|
#include "hexchatc.h"
|
2014-03-24 15:46:02 -04:00
|
|
|
#include "chanopt.h"
|
2011-02-23 22:14:30 -05:00
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
clear_channel (session *sess)
|
|
|
|
{
|
|
|
|
if (sess->channel[0])
|
|
|
|
strcpy (sess->waitchannel, sess->channel);
|
|
|
|
sess->channel[0] = 0;
|
|
|
|
sess->doing_who = FALSE;
|
|
|
|
sess->done_away_check = FALSE;
|
|
|
|
|
|
|
|
log_close (sess);
|
|
|
|
|
|
|
|
if (sess->current_modes)
|
|
|
|
{
|
2014-12-28 06:37:25 -05:00
|
|
|
g_free (sess->current_modes);
|
2011-02-23 22:14:30 -05:00
|
|
|
sess->current_modes = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sess->mode_timeout_tag)
|
|
|
|
{
|
|
|
|
fe_timeout_remove (sess->mode_timeout_tag);
|
|
|
|
sess->mode_timeout_tag = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
fe_clear_channel (sess);
|
|
|
|
userlist_clear (sess);
|
|
|
|
fe_set_nonchannel (sess, FALSE);
|
|
|
|
fe_set_title (sess);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
set_topic (session *sess, char *topic, char *stripped_topic)
|
|
|
|
{
|
2015-02-01 01:45:34 -05:00
|
|
|
/* The topic of dialogs are the users hostname which is logged is new */
|
|
|
|
if (sess->type == SESS_DIALOG && (!sess->topic || strcmp(sess->topic, stripped_topic))
|
|
|
|
&& sess->logfd != -1)
|
|
|
|
{
|
|
|
|
char tbuf[1024];
|
|
|
|
g_snprintf (tbuf, sizeof (tbuf), "[%s has address %s]\n", sess->channel, stripped_topic);
|
|
|
|
write (sess->logfd, tbuf, strlen (tbuf));
|
|
|
|
}
|
|
|
|
|
2014-12-28 06:37:25 -05:00
|
|
|
g_free (sess->topic);
|
|
|
|
sess->topic = g_strdup (stripped_topic);
|
2011-02-23 22:14:30 -05:00
|
|
|
fe_set_topic (sess, topic, stripped_topic);
|
|
|
|
}
|
|
|
|
|
|
|
|
static session *
|
|
|
|
find_session_from_nick (char *nick, server *serv)
|
|
|
|
{
|
|
|
|
session *sess;
|
|
|
|
GSList *list = sess_list;
|
|
|
|
|
|
|
|
sess = find_dialog (serv, nick);
|
|
|
|
if (sess)
|
|
|
|
return sess;
|
|
|
|
|
|
|
|
if (serv->front_session)
|
|
|
|
{
|
|
|
|
if (userlist_find (serv->front_session, nick))
|
|
|
|
return serv->front_session;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (current_sess && current_sess->server == serv)
|
|
|
|
{
|
|
|
|
if (userlist_find (current_sess, nick))
|
|
|
|
return current_sess;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
sess = list->data;
|
|
|
|
if (sess->server == serv)
|
|
|
|
{
|
|
|
|
if (userlist_find (sess, nick))
|
|
|
|
return sess;
|
|
|
|
}
|
|
|
|
list = list->next;
|
|
|
|
}
|
2014-12-31 11:31:17 -05:00
|
|
|
return NULL;
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static session *
|
2013-06-23 14:53:41 -04:00
|
|
|
inbound_open_dialog (server *serv, char *from,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess;
|
|
|
|
|
|
|
|
sess = new_ircwindow (serv, from, SESS_DIALOG, 0);
|
|
|
|
/* for playing sounds */
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_OPENDIALOG, sess, NULL, NULL, NULL, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
|
|
|
|
return sess;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
inbound_make_idtext (server *serv, char *idtext, int max, int id)
|
|
|
|
{
|
|
|
|
idtext[0] = 0;
|
2013-04-03 17:10:09 -04:00
|
|
|
if (serv->have_idmsg || serv->have_accnotify)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
if (id)
|
|
|
|
{
|
2012-10-22 08:50:36 -04:00
|
|
|
safe_strcpy (idtext, prefs.hex_irc_id_ytext, max);
|
2011-02-23 22:14:30 -05:00
|
|
|
} else
|
|
|
|
{
|
2012-10-22 08:50:36 -04:00
|
|
|
safe_strcpy (idtext, prefs.hex_irc_id_ntext, max);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
/* convert codes like %C,%U to the proper ones */
|
|
|
|
check_special_chars (idtext, TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_privmsg (server *serv, char *from, char *ip, char *text, int id,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess;
|
2013-03-22 22:41:56 -04:00
|
|
|
struct User *user;
|
2011-02-23 22:14:30 -05:00
|
|
|
char idtext[64];
|
2013-04-03 17:10:09 -04:00
|
|
|
gboolean nodiag = FALSE;
|
2011-02-23 22:14:30 -05:00
|
|
|
|
|
|
|
sess = find_dialog (serv, from);
|
|
|
|
|
2012-10-22 07:49:28 -04:00
|
|
|
if (sess || prefs.hex_gui_autoopen_dialog)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
2012-10-22 07:49:28 -04:00
|
|
|
/*0=ctcp 1=priv will set hex_gui_autoopen_dialog=0 here is flud detected */
|
2011-02-23 22:14:30 -05:00
|
|
|
if (!sess)
|
|
|
|
{
|
|
|
|
if (flood_check (from, ip, serv, current_sess, 1))
|
|
|
|
/* Create a dialog session */
|
2013-06-23 14:53:41 -04:00
|
|
|
sess = inbound_open_dialog (serv, from, tags_data);
|
2011-02-23 22:14:30 -05:00
|
|
|
else
|
|
|
|
sess = serv->server_session;
|
|
|
|
if (!sess)
|
|
|
|
return; /* ?? */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ip && ip[0])
|
|
|
|
set_topic (sess, ip, ip);
|
2013-06-21 19:13:36 -04:00
|
|
|
inbound_chanmsg (serv, NULL, NULL, from, text, FALSE, id, tags_data);
|
2011-02-23 22:14:30 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sess = find_session_from_nick (from, serv);
|
|
|
|
if (!sess)
|
|
|
|
{
|
|
|
|
sess = serv->front_session;
|
2013-04-03 17:10:09 -04:00
|
|
|
nodiag = TRUE; /* We don't want it to look like a normal message in front sess */
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
2013-04-03 17:10:09 -04:00
|
|
|
|
2013-03-22 22:41:56 -04:00
|
|
|
user = userlist_find (sess, from);
|
|
|
|
if (user)
|
2013-04-03 17:10:09 -04:00
|
|
|
{
|
2013-03-22 22:41:56 -04:00
|
|
|
user->lasttalk = time (0);
|
2013-04-03 17:10:09 -04:00
|
|
|
if (user->account)
|
|
|
|
id = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
inbound_make_idtext (serv, idtext, sizeof (idtext), id);
|
2011-02-23 22:14:30 -05:00
|
|
|
|
2013-04-03 17:10:09 -04:00
|
|
|
if (sess->type == SESS_DIALOG && !nodiag)
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_PRIVMSG, sess, from, text, idtext, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* used for Alerts section. Masks can be separated by commas and spaces. */
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
alert_match_word (char *word, char *masks)
|
|
|
|
{
|
|
|
|
char *p = masks;
|
|
|
|
char endchar;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
if (masks[0] == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
/* if it's a 0, space or comma, the word has ended. */
|
|
|
|
if (*p == 0 || *p == ' ' || *p == ',')
|
|
|
|
{
|
|
|
|
endchar = *p;
|
|
|
|
*p = 0;
|
|
|
|
res = match (masks, word);
|
|
|
|
*p = endchar;
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
return TRUE; /* yes, matched! */
|
|
|
|
|
|
|
|
masks = p + 1;
|
|
|
|
if (*p == 0)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
alert_match_text (char *text, char *masks)
|
|
|
|
{
|
|
|
|
unsigned char *p = text;
|
|
|
|
unsigned char endchar;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
if (masks[0] == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (*p >= '0' && *p <= '9')
|
|
|
|
{
|
|
|
|
p++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if it's RFC1459 <special>, it can be inside a word */
|
|
|
|
switch (*p)
|
|
|
|
{
|
|
|
|
case '-': case '[': case ']': case '\\':
|
|
|
|
case '`': case '^': case '{': case '}':
|
|
|
|
case '_': case '|':
|
|
|
|
p++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if it's a 0, space or comma, the word has ended. */
|
|
|
|
if (*p == 0 || *p == ' ' || *p == ',' ||
|
|
|
|
/* if it's anything BUT a letter, the word has ended. */
|
|
|
|
(!g_unichar_isalpha (g_utf8_get_char (p))))
|
|
|
|
{
|
|
|
|
endchar = *p;
|
|
|
|
*p = 0;
|
|
|
|
res = alert_match_word (text, masks);
|
|
|
|
*p = endchar;
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
return TRUE; /* yes, matched! */
|
|
|
|
|
|
|
|
text = p + g_utf8_skip [p[0]];
|
|
|
|
if (*p == 0)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
p += g_utf8_skip [p[0]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
is_hilight (char *from, char *text, session *sess, server *serv)
|
|
|
|
{
|
2012-10-22 08:50:36 -04:00
|
|
|
if (alert_match_word (from, prefs.hex_irc_no_hilight))
|
2011-02-23 22:14:30 -05:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
text = strip_color (text, -1, STRIP_ALL);
|
|
|
|
|
|
|
|
if (alert_match_text (text, serv->nick) ||
|
2012-10-22 08:50:36 -04:00
|
|
|
alert_match_text (text, prefs.hex_irc_extra_hilight) ||
|
|
|
|
alert_match_word (from, prefs.hex_irc_nick_hilight))
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
g_free (text);
|
|
|
|
if (sess != current_tab)
|
2013-01-05 16:23:34 -05:00
|
|
|
{
|
2011-02-23 22:14:30 -05:00
|
|
|
sess->nick_said = TRUE;
|
2012-12-25 00:33:57 -05:00
|
|
|
lastact_update (sess);
|
2013-01-05 16:23:34 -05:00
|
|
|
}
|
2011-02-23 22:14:30 -05:00
|
|
|
fe_set_hilight (sess);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (text);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-23 14:53:41 -04:00
|
|
|
inbound_action (session *sess, char *chan, char *from, char *ip, char *text,
|
|
|
|
int fromme, int id, const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *def = sess;
|
|
|
|
server *serv = sess->server;
|
|
|
|
struct User *user;
|
|
|
|
char nickchar[2] = "\000";
|
|
|
|
char idtext[64];
|
|
|
|
int privaction = FALSE;
|
|
|
|
|
|
|
|
if (!fromme)
|
|
|
|
{
|
|
|
|
if (is_channel (serv, chan))
|
|
|
|
{
|
|
|
|
sess = find_channel (serv, chan);
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
/* it's a private action! */
|
|
|
|
privaction = TRUE;
|
|
|
|
/* find a dialog tab for it */
|
|
|
|
sess = find_dialog (serv, from);
|
|
|
|
/* if non found, open a new one */
|
2012-10-22 07:49:28 -04:00
|
|
|
if (!sess && prefs.hex_gui_autoopen_dialog)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
/* but only if it wouldn't flood */
|
|
|
|
if (flood_check (from, ip, serv, current_sess, 1))
|
2013-06-23 14:53:41 -04:00
|
|
|
sess = inbound_open_dialog (serv, from, tags_data);
|
2011-02-23 22:14:30 -05:00
|
|
|
else
|
|
|
|
sess = serv->server_session;
|
|
|
|
}
|
|
|
|
if (!sess)
|
|
|
|
{
|
|
|
|
sess = find_session_from_nick (from, serv);
|
|
|
|
/* still not good? */
|
|
|
|
if (!sess)
|
|
|
|
sess = serv->front_session;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sess)
|
|
|
|
sess = def;
|
|
|
|
|
|
|
|
if (sess != current_tab)
|
|
|
|
{
|
|
|
|
if (fromme)
|
|
|
|
{
|
|
|
|
sess->msg_said = FALSE;
|
|
|
|
sess->new_data = TRUE;
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
sess->msg_said = TRUE;
|
|
|
|
sess->new_data = FALSE;
|
|
|
|
}
|
2012-12-25 00:33:57 -05:00
|
|
|
lastact_update (sess);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
user = userlist_find (sess, from);
|
|
|
|
if (user)
|
|
|
|
{
|
|
|
|
nickchar[0] = user->prefix[0];
|
|
|
|
user->lasttalk = time (0);
|
2013-04-03 17:10:09 -04:00
|
|
|
if (user->account)
|
|
|
|
id = TRUE;
|
2013-08-26 09:44:18 -04:00
|
|
|
if (user->me)
|
|
|
|
fromme = TRUE;
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
inbound_make_idtext (serv, idtext, sizeof (idtext), id);
|
|
|
|
|
|
|
|
if (!fromme && !privaction)
|
|
|
|
{
|
|
|
|
if (is_hilight (from, text, sess, serv))
|
|
|
|
{
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_HCHANACTION, sess, from, text, nickchar,
|
|
|
|
idtext, 0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fromme)
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_UACTION, sess, from, text, nickchar, idtext,
|
|
|
|
0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else if (!privaction)
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANACTION, sess, from, text, nickchar,
|
|
|
|
idtext, 0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else if (sess->type == SESS_DIALOG)
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_DPRIVACTION, sess, from, text, idtext, NULL,
|
|
|
|
0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_PRIVACTION, sess, from, text, idtext, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-21 19:13:36 -04:00
|
|
|
inbound_chanmsg (server *serv, session *sess, char *chan, char *from,
|
2013-06-22 11:55:41 -04:00
|
|
|
char *text, char fromme, int id,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
struct User *user;
|
|
|
|
int hilight = FALSE;
|
|
|
|
char nickchar[2] = "\000";
|
|
|
|
char idtext[64];
|
|
|
|
|
|
|
|
if (!sess)
|
|
|
|
{
|
|
|
|
if (chan)
|
|
|
|
{
|
|
|
|
sess = find_channel (serv, chan);
|
|
|
|
if (!sess && !is_channel (serv, chan))
|
|
|
|
sess = find_dialog (serv, chan);
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
sess = find_dialog (serv, from);
|
|
|
|
}
|
|
|
|
if (!sess)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sess != current_tab)
|
|
|
|
{
|
|
|
|
sess->msg_said = TRUE;
|
|
|
|
sess->new_data = FALSE;
|
2012-12-25 00:33:57 -05:00
|
|
|
lastact_update (sess);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
user = userlist_find (sess, from);
|
|
|
|
if (user)
|
|
|
|
{
|
2013-04-03 17:10:09 -04:00
|
|
|
if (user->account)
|
|
|
|
id = TRUE;
|
2011-02-23 22:14:30 -05:00
|
|
|
nickchar[0] = user->prefix[0];
|
|
|
|
user->lasttalk = time (0);
|
2013-08-26 09:44:18 -04:00
|
|
|
if (user->me)
|
|
|
|
fromme = TRUE;
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fromme)
|
|
|
|
{
|
2013-11-01 00:58:27 -04:00
|
|
|
if (prefs.hex_away_auto_unmark && serv->is_away && !tags_data->timestamp)
|
2011-02-23 22:14:30 -05:00
|
|
|
sess->server->p_set_back (sess->server);
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_UCHANMSG, sess, from, text, nickchar, NULL,
|
|
|
|
0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
inbound_make_idtext (serv, idtext, sizeof (idtext), id);
|
|
|
|
|
|
|
|
if (is_hilight (from, text, sess, serv))
|
|
|
|
hilight = TRUE;
|
|
|
|
|
|
|
|
if (sess->type == SESS_DIALOG)
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else if (hilight)
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_HCHANMSG, sess, from, text, nickchar, idtext,
|
|
|
|
0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMSG, sess, from, text, nickchar, idtext,
|
|
|
|
0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_newnick (server *serv, char *nick, char *newnick, int quiet,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
int me = FALSE;
|
|
|
|
session *sess;
|
|
|
|
GSList *list = sess_list;
|
|
|
|
|
|
|
|
if (!serv->p_cmp (nick, serv->nick))
|
|
|
|
{
|
|
|
|
me = TRUE;
|
|
|
|
safe_strcpy (serv->nick, newnick, NICKLEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
sess = list->data;
|
|
|
|
if (sess->server == serv)
|
|
|
|
{
|
|
|
|
if (userlist_change (sess, nick, newnick) || (me && sess->type == SESS_SERVER))
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
{
|
|
|
|
if (me)
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_UCHANGENICK, sess, nick,
|
|
|
|
newnick, NULL, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANGENICK, sess, nick,
|
|
|
|
newnick, NULL, NULL, 0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sess->type == SESS_DIALOG && !serv->p_cmp (sess->channel, nick))
|
|
|
|
{
|
|
|
|
safe_strcpy (sess->channel, newnick, CHANLEN);
|
|
|
|
fe_set_channel (sess);
|
|
|
|
}
|
|
|
|
fe_set_title (sess);
|
|
|
|
}
|
|
|
|
list = list->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
dcc_change_nick (serv, nick, newnick);
|
|
|
|
|
|
|
|
if (me)
|
|
|
|
fe_set_nick (serv, newnick);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find a "<none>" tab */
|
|
|
|
static session *
|
|
|
|
find_unused_session (server *serv)
|
|
|
|
{
|
|
|
|
session *sess;
|
|
|
|
GSList *list = sess_list;
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
sess = (session *) list->data;
|
|
|
|
if (sess->type == SESS_CHANNEL && sess->channel[0] == 0 &&
|
|
|
|
sess->server == serv)
|
|
|
|
{
|
|
|
|
if (sess->waitchannel[0] == 0)
|
|
|
|
return sess;
|
|
|
|
}
|
|
|
|
list = list->next;
|
|
|
|
}
|
2014-12-31 11:31:17 -05:00
|
|
|
return NULL;
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static session *
|
|
|
|
find_session_from_waitchannel (char *chan, struct server *serv)
|
|
|
|
{
|
|
|
|
session *sess;
|
|
|
|
GSList *list = sess_list;
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
sess = (session *) list->data;
|
|
|
|
if (sess->server == serv && sess->channel[0] == 0 && sess->type == SESS_CHANNEL)
|
|
|
|
{
|
|
|
|
if (!serv->p_cmp (chan, sess->waitchannel))
|
|
|
|
return sess;
|
|
|
|
}
|
|
|
|
list = list->next;
|
|
|
|
}
|
2014-12-31 11:31:17 -05:00
|
|
|
return NULL;
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_ujoin (server *serv, char *chan, char *nick, char *ip,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess;
|
2014-03-24 15:46:02 -04:00
|
|
|
int found_unused = FALSE;
|
2011-02-23 22:14:30 -05:00
|
|
|
|
|
|
|
/* already joined? probably a bnc */
|
|
|
|
sess = find_channel (serv, chan);
|
|
|
|
if (!sess)
|
|
|
|
{
|
|
|
|
/* see if a window is waiting to join this channel */
|
|
|
|
sess = find_session_from_waitchannel (chan, serv);
|
|
|
|
if (!sess)
|
|
|
|
{
|
|
|
|
/* find a "<none>" tab and use that */
|
|
|
|
sess = find_unused_session (serv);
|
2014-03-24 15:46:02 -04:00
|
|
|
found_unused = sess != NULL;
|
2011-02-23 22:14:30 -05:00
|
|
|
if (!sess)
|
|
|
|
/* last resort, open a new tab/window */
|
|
|
|
sess = new_ircwindow (serv, chan, SESS_CHANNEL, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
safe_strcpy (sess->channel, chan, CHANLEN);
|
2014-03-24 15:46:02 -04:00
|
|
|
if (found_unused)
|
|
|
|
{
|
|
|
|
chanopt_load (sess);
|
|
|
|
scrollback_load (sess);
|
2014-04-02 19:09:13 -04:00
|
|
|
if (sess->scrollwritten && sess->scrollback_replay_marklast)
|
|
|
|
sess->scrollback_replay_marklast (sess);
|
2014-03-24 15:46:02 -04:00
|
|
|
}
|
2011-02-23 22:14:30 -05:00
|
|
|
|
|
|
|
fe_set_channel (sess);
|
|
|
|
fe_set_title (sess);
|
|
|
|
fe_set_nonchannel (sess, TRUE);
|
|
|
|
userlist_clear (sess);
|
|
|
|
|
|
|
|
log_open_or_close (sess);
|
|
|
|
|
|
|
|
sess->waitchannel[0] = 0;
|
|
|
|
sess->ignore_date = TRUE;
|
|
|
|
sess->ignore_mode = TRUE;
|
|
|
|
sess->ignore_names = TRUE;
|
|
|
|
sess->end_of_names = FALSE;
|
|
|
|
|
|
|
|
/* sends a MODE */
|
|
|
|
serv->p_join_info (sess->server, chan);
|
|
|
|
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_UJOIN, sess, nick, chan, ip, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
|
2012-10-22 08:50:36 -04:00
|
|
|
if (prefs.hex_irc_who_join)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
/* sends WHO #channel */
|
|
|
|
serv->p_user_list (sess->server, chan);
|
|
|
|
sess->doing_who = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_ukick (server *serv, char *chan, char *kicker, char *reason,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess = find_channel (serv, chan);
|
|
|
|
if (sess)
|
|
|
|
{
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_UKICK, sess, serv->nick, chan, kicker,
|
|
|
|
reason, 0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
clear_channel (sess);
|
2012-10-22 08:50:36 -04:00
|
|
|
if (prefs.hex_irc_auto_rejoin)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
serv->p_join (serv, chan, sess->channelkey);
|
|
|
|
safe_strcpy (sess->waitchannel, chan, CHANLEN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_upart (server *serv, char *chan, char *ip, char *reason,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess = find_channel (serv, chan);
|
|
|
|
if (sess)
|
|
|
|
{
|
|
|
|
if (*reason)
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_UPARTREASON, sess, serv->nick, ip, chan,
|
|
|
|
reason, 0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_UPART, sess, serv->nick, ip, chan, NULL,
|
|
|
|
0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
clear_channel (sess);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 18:48:17 -04:00
|
|
|
inbound_nameslist (server *serv, char *chan, char *names,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess;
|
2013-10-18 04:40:39 -04:00
|
|
|
char **name_list;
|
2013-10-20 01:33:57 -04:00
|
|
|
char *host, *nopre_name;
|
2011-02-23 22:14:30 -05:00
|
|
|
char name[NICKLEN];
|
2014-12-04 07:06:38 -05:00
|
|
|
int i;
|
|
|
|
size_t offset;
|
2011-02-23 22:14:30 -05:00
|
|
|
|
|
|
|
sess = find_channel (serv, chan);
|
|
|
|
if (!sess)
|
|
|
|
{
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_USERSONCHAN, serv->server_session, chan,
|
|
|
|
names, NULL, NULL, 0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!sess->ignore_names)
|
2013-06-23 14:53:41 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_USERSONCHAN, sess, chan, names, NULL, NULL,
|
|
|
|
0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
|
|
|
|
if (sess->end_of_names)
|
|
|
|
{
|
|
|
|
sess->end_of_names = FALSE;
|
|
|
|
userlist_clear (sess);
|
|
|
|
}
|
|
|
|
|
2013-10-18 04:40:39 -04:00
|
|
|
name_list = g_strsplit (names, " ", -1);
|
|
|
|
for (i = 0; name_list[i]; i++)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
2013-10-18 04:40:39 -04:00
|
|
|
host = NULL;
|
2013-10-20 00:29:28 -04:00
|
|
|
offset = sizeof(name);
|
2013-10-18 04:40:39 -04:00
|
|
|
|
|
|
|
if (name_list[i][0] == 0)
|
|
|
|
continue;
|
|
|
|
|
2013-10-20 00:29:28 -04:00
|
|
|
if (serv->have_uhnames)
|
|
|
|
{
|
2013-10-20 01:33:57 -04:00
|
|
|
offset = 0;
|
|
|
|
nopre_name = name_list[i];
|
|
|
|
|
|
|
|
/* Ignore prefixes so '!' won't cause issues */
|
|
|
|
while (strchr (serv->nick_prefixes, *nopre_name) != NULL)
|
|
|
|
{
|
2013-10-22 14:53:33 -04:00
|
|
|
nopre_name++;
|
2013-10-20 01:33:57 -04:00
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
|
|
|
|
offset += strcspn (nopre_name, "!");
|
2013-10-20 00:29:28 -04:00
|
|
|
if (offset++ < strlen (name_list[i]))
|
|
|
|
host = name_list[i] + offset;
|
|
|
|
}
|
2013-10-18 04:40:39 -04:00
|
|
|
|
|
|
|
g_strlcpy (name, name_list[i], MIN(offset, sizeof(name)));
|
|
|
|
|
|
|
|
userlist_add (sess, name, host, NULL, NULL, tags_data);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
2013-10-18 04:40:39 -04:00
|
|
|
g_strfreev (name_list);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 18:48:17 -04:00
|
|
|
inbound_topic (server *serv, char *chan, char *topic_text,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess = find_channel (serv, chan);
|
|
|
|
char *stripped_topic;
|
|
|
|
|
|
|
|
if (sess)
|
|
|
|
{
|
|
|
|
stripped_topic = strip_color (topic_text, -1, STRIP_ALL);
|
|
|
|
set_topic (sess, topic_text, stripped_topic);
|
|
|
|
g_free (stripped_topic);
|
|
|
|
} else
|
|
|
|
sess = serv->server_session;
|
|
|
|
|
2013-06-22 18:48:17 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_TOPIC, sess, chan, topic_text, NULL, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_topicnew (server *serv, char *nick, char *chan, char *topic,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess;
|
|
|
|
char *stripped_topic;
|
|
|
|
|
|
|
|
sess = find_channel (serv, chan);
|
|
|
|
if (sess)
|
|
|
|
{
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_NEWTOPIC, sess, nick, topic, chan, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
stripped_topic = strip_color (topic, -1, STRIP_ALL);
|
|
|
|
set_topic (sess, topic, stripped_topic);
|
|
|
|
g_free (stripped_topic);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_join (server *serv, char *chan, char *user, char *ip, char *account,
|
|
|
|
char *realname, const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess = find_channel (serv, chan);
|
|
|
|
if (sess)
|
|
|
|
{
|
2014-04-06 15:22:51 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_JOIN, sess, user, chan, ip, account, 0,
|
2013-06-22 10:32:50 -04:00
|
|
|
tags_data->timestamp);
|
2013-06-22 18:48:17 -04:00
|
|
|
userlist_add (sess, user, ip, account, realname, tags_data);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_kick (server *serv, char *chan, char *user, char *kicker, char *reason,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess = find_channel (serv, chan);
|
|
|
|
if (sess)
|
|
|
|
{
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_KICK, sess, kicker, user, chan, reason, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
userlist_remove (sess, user);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_part (server *serv, char *chan, char *user, char *ip, char *reason,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
session *sess = find_channel (serv, chan);
|
|
|
|
if (sess)
|
|
|
|
{
|
|
|
|
if (*reason)
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_PARTREASON, sess, user, ip, chan, reason,
|
|
|
|
0, tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
else
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_PART, sess, user, ip, chan, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
userlist_remove (sess, user);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 18:48:17 -04:00
|
|
|
inbound_topictime (server *serv, char *chan, char *nick, time_t stamp,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
char *tim = ctime (&stamp);
|
|
|
|
session *sess = find_channel (serv, chan);
|
|
|
|
|
|
|
|
if (!sess)
|
|
|
|
sess = serv->server_session;
|
|
|
|
|
|
|
|
tim[24] = 0; /* get rid of the \n */
|
2013-06-22 18:48:17 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_TOPICDATE, sess, chan, nick, tim, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_quit (server *serv, char *nick, char *ip, char *reason,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
GSList *list = sess_list;
|
|
|
|
session *sess;
|
2011-05-30 14:27:08 -04:00
|
|
|
struct User *user;
|
2011-02-23 22:14:30 -05:00
|
|
|
int was_on_front_session = FALSE;
|
|
|
|
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
sess = (session *) list->data;
|
|
|
|
if (sess->server == serv)
|
|
|
|
{
|
|
|
|
if (sess == current_sess)
|
|
|
|
was_on_front_session = TRUE;
|
2012-12-03 16:00:11 -05:00
|
|
|
if ((user = userlist_find (sess, nick)))
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_QUIT, sess, nick, reason, ip, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-05-30 14:27:08 -04:00
|
|
|
userlist_remove_user (sess, user);
|
2011-02-23 22:14:30 -05:00
|
|
|
} else if (sess->type == SESS_DIALOG && !serv->p_cmp (sess->channel, nick))
|
|
|
|
{
|
2013-06-22 10:32:50 -04:00
|
|
|
EMIT_SIGNAL_TIMESTAMP (XP_TE_QUIT, sess, nick, reason, ip, NULL, 0,
|
|
|
|
tags_data->timestamp);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
list = list->next;
|
|
|
|
}
|
|
|
|
|
2013-06-22 18:48:17 -04:00
|
|
|
notify_set_offline (serv, nick, was_on_front_session, tags_data);
|
2011-02-23 22:14:30 -05:00
|
|
|
}
|
|
|
|
|
2013-04-03 17:10:09 -04:00
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_account (server *serv, char *nick, char *account,
|
|
|
|
const message_tags_data *tags_data)
|
2013-04-03 17:10:09 -04:00
|
|
|
{
|
|
|
|
session *sess = NULL;
|
|
|
|
GSList *list;
|
|
|
|
|
|
|
|
list = sess_list;
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
sess = list->data;
|
|
|
|
if (sess->server == serv)
|
|
|
|
userlist_set_account (sess, nick, account);
|
|
|
|
list = list->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-23 22:14:30 -05:00
|
|
|
void
|
2013-06-22 10:32:50 -04:00
|
|
|
inbound_ping_reply (session *sess, char *timestring, char *from,
|
|
|
|
const message_tags_data *tags_data)
|
2011-02-23 22:14:30 -05:00
|
|
|
{
|
|
|
|
unsigned long tim, nowtim, dif;
|
|
|
|
int lag = 0;
|
|
|
|
char outbuf[64];
|
|
|
|
|
|
|
|
if (strncmp (timestring, "LAG", 3) == 0)
|
|
|
|
{
|
|
|
|
timestring += 3;
|
|
|
|
lag = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
tim = strtoul (timestring, NULL, 10);
|
|
|
|
nowtim = make_ping_time ();
|
|
|
|
dif = nowtim - tim;
|
|
|
|
|
|
|
|
sess->server->ping_recv = time (0);
|
|
|
|
|
|
|
|
if (lag)
|
|
|
|
{
|
|
|
|
sess->server->lag_sent = 0;
|
2014-01-27 15:24:56 -05:00
|
|
|
sess->server->lag = dif;
|
|
|
|
fe_set_lag (sess->server, dif);
|
2011-02-23 22:14:30 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (atol (timestring) == 0)
|
|
|
|
{
|
|
|
|
if (sess->server->lag_sent)
|
|