2000-04-26 08:03:38 +00:00
|
|
|
/*
|
|
|
|
notify-ison.c : irssi
|
|
|
|
|
|
|
|
Copyright (C) 1999-2000 Timo Sirainen
|
|
|
|
|
|
|
|
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
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "module.h"
|
|
|
|
#include "signals.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "settings.h"
|
|
|
|
|
|
|
|
#include "irc.h"
|
2000-08-26 15:39:44 +00:00
|
|
|
#include "irc-servers.h"
|
|
|
|
#include "servers-redirect.h"
|
2000-04-26 08:03:38 +00:00
|
|
|
|
|
|
|
#include "notifylist.h"
|
|
|
|
|
|
|
|
#define DEFAULT_NOTIFY_CHECK_TIME 60
|
|
|
|
#define DEFAULT_NOTIFY_WHOIS_TIME (60*5)
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char *nick;
|
|
|
|
int hostok;
|
|
|
|
} ISON_REC;
|
|
|
|
|
|
|
|
static int notify_tag;
|
|
|
|
static int notify_whois_time;
|
|
|
|
|
|
|
|
NOTIFY_NICK_REC *notify_nick_create(IRC_SERVER_REC *server, const char *nick)
|
|
|
|
{
|
|
|
|
MODULE_SERVER_REC *mserver;
|
|
|
|
NOTIFY_NICK_REC *rec;
|
|
|
|
|
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
|
|
|
|
rec = g_new0(NOTIFY_NICK_REC, 1);
|
|
|
|
rec->nick = g_strdup(nick);
|
|
|
|
|
|
|
|
mserver->notify_users = g_slist_append(mserver->notify_users, rec);
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
void notify_nick_destroy(NOTIFY_NICK_REC *rec)
|
|
|
|
{
|
|
|
|
g_free(rec->nick);
|
|
|
|
g_free_not_null(rec->user);
|
|
|
|
g_free_not_null(rec->host);
|
|
|
|
g_free_not_null(rec->realname);
|
|
|
|
g_free_not_null(rec->awaymsg);
|
|
|
|
g_free(rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
NOTIFY_NICK_REC *notify_nick_find(IRC_SERVER_REC *server, const char *nick)
|
|
|
|
{
|
|
|
|
MODULE_SERVER_REC *mserver;
|
|
|
|
NOTIFY_NICK_REC *rec;
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
for (tmp = mserver->notify_users; tmp != NULL; tmp = tmp->next) {
|
|
|
|
rec = tmp->data;
|
|
|
|
|
|
|
|
if (g_strcasecmp(rec->nick, nick) == 0)
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-11-11 18:59:19 +00:00
|
|
|
static void ison_send(IRC_SERVER_REC *server, GString *cmd)
|
2000-04-26 08:03:38 +00:00
|
|
|
{
|
2001-11-11 18:59:19 +00:00
|
|
|
MODULE_SERVER_REC *mserver;
|
2000-04-26 08:03:38 +00:00
|
|
|
|
2001-11-11 18:59:19 +00:00
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
mserver->ison_count++;
|
2000-04-26 08:03:38 +00:00
|
|
|
|
|
|
|
g_string_truncate(cmd, cmd->len-1);
|
|
|
|
g_string_prepend(cmd, "ISON :");
|
|
|
|
|
2001-11-12 22:15:04 +00:00
|
|
|
server_redirect_event(server, "ison", 1, NULL, -1, NULL,
|
2001-11-11 18:59:19 +00:00
|
|
|
"event 303", "notifylist event", NULL);
|
2000-04-26 08:03:38 +00:00
|
|
|
irc_send_cmd(server, cmd->str);
|
|
|
|
|
|
|
|
g_string_truncate(cmd, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* timeout function: send /ISON commands to server to check if someone in
|
|
|
|
notify list is in IRC */
|
|
|
|
static void notifylist_timeout_server(IRC_SERVER_REC *server)
|
|
|
|
{
|
2001-11-11 18:59:19 +00:00
|
|
|
MODULE_SERVER_REC *mserver;
|
2000-04-26 08:03:38 +00:00
|
|
|
GSList *tmp;
|
|
|
|
GString *cmd;
|
|
|
|
char *nick, *ptr;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
g_return_if_fail(server != NULL);
|
|
|
|
|
2000-09-28 00:32:56 +00:00
|
|
|
if (!IS_IRC_SERVER(server))
|
|
|
|
return;
|
|
|
|
|
2001-11-11 18:59:19 +00:00
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
if (mserver->ison_count > 0) {
|
2000-04-26 08:03:38 +00:00
|
|
|
/* still not received all replies to previous /ISON commands.. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd = g_string_new(NULL);
|
|
|
|
for (tmp = notifies; tmp != NULL; tmp = tmp->next) {
|
|
|
|
NOTIFYLIST_REC *rec = tmp->data;
|
|
|
|
|
2000-08-26 15:39:44 +00:00
|
|
|
if (!notifylist_ircnets_match(rec, server->connrec->chatnet))
|
2000-04-26 08:03:38 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
nick = g_strdup(rec->mask);
|
|
|
|
ptr = strchr(nick, '!');
|
|
|
|
if (ptr != NULL) *ptr = '\0';
|
|
|
|
|
|
|
|
len = strlen(nick);
|
|
|
|
|
|
|
|
if (cmd->len+len+1 > 510)
|
|
|
|
ison_send(server, cmd);
|
|
|
|
|
|
|
|
g_string_sprintfa(cmd, "%s ", nick);
|
|
|
|
g_free(nick);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cmd->len > 0)
|
|
|
|
ison_send(server, cmd);
|
|
|
|
g_string_free(cmd, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int notifylist_timeout_func(void)
|
|
|
|
{
|
|
|
|
g_slist_foreach(servers, (GFunc) notifylist_timeout_server, NULL);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ison_save_users(MODULE_SERVER_REC *mserver, char *online)
|
|
|
|
{
|
|
|
|
char *ptr;
|
|
|
|
|
|
|
|
while (online != NULL && *online != '\0') {
|
|
|
|
ptr = strchr(online, ' ');
|
|
|
|
if (ptr != NULL) *ptr++ = '\0';
|
|
|
|
|
|
|
|
mserver->ison_tempusers =
|
|
|
|
g_slist_append(mserver->ison_tempusers, g_strdup(online));
|
|
|
|
online = ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void whois_send(IRC_SERVER_REC *server, char *nicks)
|
|
|
|
{
|
|
|
|
char *p, *str;
|
|
|
|
|
|
|
|
/* "nick1,nick2" -> "nick1,nick2 nick1 nick2" because
|
|
|
|
End of WHOIS give nick1,nick2 while other whois events give
|
|
|
|
nick1 or nick2 */
|
|
|
|
str = g_strconcat(nicks, " ", nicks, NULL);
|
|
|
|
for (p = str+strlen(nicks)+1; *p != '\0'; p++)
|
|
|
|
if (*p == ',') *p = ' ';
|
|
|
|
|
2001-11-12 22:15:04 +00:00
|
|
|
server_redirect_event(server, "whois", 1, str, FALSE,
|
2001-11-11 18:59:19 +00:00
|
|
|
"notifylist event whois end",
|
|
|
|
"event 318", "notifylist event whois end",
|
|
|
|
"event 311", "notifylist event whois",
|
|
|
|
"event 301", "notifylist event whois away",
|
|
|
|
"event 317", "notifylist event whois idle",
|
|
|
|
"", "event empty", NULL);
|
2001-11-14 23:37:39 +00:00
|
|
|
g_free(str);
|
|
|
|
|
|
|
|
irc_send_cmdv(server, "WHOIS %s", nicks);
|
2000-04-26 08:03:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void whois_send_server(IRC_SERVER_REC *server, char *nick)
|
|
|
|
{
|
|
|
|
char *str;
|
|
|
|
|
|
|
|
str = g_strdup_printf("%s %s", nick, nick);
|
|
|
|
whois_send(server, str);
|
|
|
|
g_free(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to send as many nicks in one WHOIS as possible */
|
|
|
|
static void whois_list_send(IRC_SERVER_REC *server, GSList *nicks)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
GString *str;
|
|
|
|
char *nick;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
str = g_string_new(NULL);
|
|
|
|
count = 0;
|
|
|
|
|
|
|
|
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
|
|
|
|
nick = tmp->data;
|
|
|
|
|
|
|
|
count++;
|
|
|
|
g_string_sprintfa(str, "%s,", nick);
|
|
|
|
|
|
|
|
if (count >= server->max_whois_in_cmd) {
|
|
|
|
g_string_truncate(str, str->len-1);
|
|
|
|
whois_send(server, str->str);
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (str->len > 0) {
|
|
|
|
g_string_truncate(str, str->len-1);
|
|
|
|
whois_send(server, str->str);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_string_free(str, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ison_check_joins(IRC_SERVER_REC *server)
|
|
|
|
{
|
|
|
|
MODULE_SERVER_REC *mserver;
|
|
|
|
NOTIFYLIST_REC *notify;
|
|
|
|
NOTIFY_NICK_REC *rec;
|
|
|
|
GSList *tmp, *newnicks;
|
|
|
|
int send_whois;
|
|
|
|
time_t now;
|
|
|
|
|
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
|
|
|
|
now = time(NULL);
|
|
|
|
newnicks = NULL;
|
|
|
|
for (tmp = mserver->ison_tempusers; tmp != NULL; tmp = tmp->next) {
|
|
|
|
char *nick = tmp->data;
|
|
|
|
|
2000-08-26 15:39:44 +00:00
|
|
|
notify = notifylist_find(nick, server->connrec->chatnet);
|
2000-04-26 08:03:38 +00:00
|
|
|
send_whois = notify != NULL &&
|
|
|
|
(notify->away_check || notify->idle_check_time > 0);
|
|
|
|
|
|
|
|
rec = notify_nick_find(server, nick);
|
|
|
|
if (rec != NULL) {
|
|
|
|
/* check if we want to send WHOIS yet.. */
|
|
|
|
if (now-rec->last_whois < notify_whois_time)
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
rec = notify_nick_create(server, nick);
|
|
|
|
if (!send_whois) newnicks = g_slist_append(newnicks, nick);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (send_whois) {
|
|
|
|
/* we need away message or idle time -
|
|
|
|
send the WHOIS reply to the nick's server */
|
|
|
|
rec->last_whois = now;
|
|
|
|
whois_send_server(server, nick);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
whois_list_send(server, newnicks);
|
|
|
|
g_slist_free(newnicks);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ison_check_parts(IRC_SERVER_REC *server)
|
|
|
|
{
|
|
|
|
MODULE_SERVER_REC *mserver;
|
|
|
|
GSList *tmp, *next;
|
|
|
|
|
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
for (tmp = mserver->notify_users; tmp != NULL; tmp = next) {
|
|
|
|
NOTIFY_NICK_REC *rec = tmp->data;
|
|
|
|
next = tmp->next;
|
|
|
|
|
|
|
|
if (gslist_find_icase_string(mserver->ison_tempusers, rec->nick) != NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
notifylist_left(server, rec);
|
|
|
|
notify_nick_destroy(rec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-12-05 21:12:52 +00:00
|
|
|
static void event_ison(IRC_SERVER_REC *server, const char *data)
|
2000-04-26 08:03:38 +00:00
|
|
|
{
|
|
|
|
MODULE_SERVER_REC *mserver;
|
|
|
|
char *params, *online;
|
|
|
|
|
|
|
|
g_return_if_fail(data != NULL);
|
|
|
|
g_return_if_fail(server != NULL);
|
|
|
|
|
|
|
|
params = event_get_params(data, 2, NULL, &online);
|
|
|
|
|
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
ison_save_users(mserver, online);
|
|
|
|
|
2001-11-11 18:59:19 +00:00
|
|
|
if (--mserver->ison_count > 0) {
|
2000-04-26 08:03:38 +00:00
|
|
|
/* wait for the rest of the /ISON replies */
|
|
|
|
g_free(params);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ison_check_joins(server);
|
|
|
|
ison_check_parts(server);
|
|
|
|
|
|
|
|
/* free memory used by temp list */
|
|
|
|
g_slist_foreach(mserver->ison_tempusers, (GFunc) g_free, NULL);
|
|
|
|
g_slist_free(mserver->ison_tempusers);
|
|
|
|
mserver->ison_tempusers = NULL;
|
|
|
|
|
|
|
|
g_free(params);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void read_settings(void)
|
|
|
|
{
|
|
|
|
if (notify_tag != -1) g_source_remove(notify_tag);
|
|
|
|
notify_tag = g_timeout_add(1000*settings_get_int("notify_check_time"), (GSourceFunc) notifylist_timeout_func, NULL);
|
|
|
|
|
|
|
|
notify_whois_time = settings_get_int("notify_whois_time");
|
|
|
|
}
|
|
|
|
|
|
|
|
void notifylist_ison_init(void)
|
|
|
|
{
|
|
|
|
settings_add_int("misc", "notify_check_time", DEFAULT_NOTIFY_CHECK_TIME);
|
|
|
|
settings_add_int("misc", "notify_whois_time", DEFAULT_NOTIFY_WHOIS_TIME);
|
|
|
|
|
|
|
|
notify_tag = -1;
|
|
|
|
read_settings();
|
|
|
|
|
|
|
|
signal_add("notifylist event", (SIGNAL_FUNC) event_ison);
|
|
|
|
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
|
|
|
}
|
|
|
|
|
|
|
|
void notifylist_ison_deinit(void)
|
|
|
|
{
|
|
|
|
g_source_remove(notify_tag);
|
|
|
|
|
|
|
|
signal_remove("notifylist event", (SIGNAL_FUNC) event_ison);
|
|
|
|
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
|
|
|
}
|