2000-04-26 04:03:38 -04:00
|
|
|
/*
|
|
|
|
notifylist.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 "modules.h"
|
|
|
|
#include "signals.h"
|
|
|
|
|
|
|
|
#include "irc.h"
|
|
|
|
#include "irc-server.h"
|
|
|
|
#include "server-redirect.h"
|
|
|
|
#include "masks.h"
|
|
|
|
#include "nicklist.h"
|
|
|
|
|
|
|
|
#include "notifylist.h"
|
|
|
|
#include "notify-setup.h"
|
|
|
|
|
|
|
|
GSList *notifies;
|
|
|
|
|
|
|
|
NOTIFYLIST_REC *notifylist_add(const char *mask, const char *ircnets,
|
|
|
|
int away_check, int idle_check_time)
|
|
|
|
{
|
|
|
|
NOTIFYLIST_REC *rec;
|
|
|
|
|
|
|
|
g_return_val_if_fail(mask != NULL, NULL);
|
|
|
|
|
|
|
|
rec = g_new0(NOTIFYLIST_REC, 1);
|
|
|
|
rec->mask = g_strdup(mask);
|
|
|
|
rec->ircnets = ircnets == NULL || *ircnets == '\0' ? NULL :
|
|
|
|
g_strsplit(ircnets, " ", -1);
|
|
|
|
rec->away_check = away_check;
|
|
|
|
rec->idle_check_time = idle_check_time;
|
|
|
|
|
|
|
|
notifylist_add_config(rec);
|
|
|
|
|
|
|
|
notifies = g_slist_append(notifies, rec);
|
|
|
|
signal_emit("notifylist new", 1, rec);
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void notify_destroy(NOTIFYLIST_REC *rec)
|
|
|
|
{
|
|
|
|
if (rec->ircnets != NULL) g_strfreev(rec->ircnets);
|
|
|
|
g_free(rec->mask);
|
|
|
|
g_free(rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
void notifylist_destroy_all(void)
|
|
|
|
{
|
|
|
|
g_slist_foreach(notifies, (GFunc) notify_destroy, NULL);
|
|
|
|
g_slist_free(notifies);
|
|
|
|
|
|
|
|
notifies = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void notifylist_remove(const char *mask)
|
|
|
|
{
|
|
|
|
NOTIFYLIST_REC *rec;
|
|
|
|
|
|
|
|
g_return_if_fail(mask != NULL);
|
|
|
|
|
|
|
|
rec = notifylist_find(mask, "*");
|
|
|
|
if (rec == NULL) return;
|
|
|
|
|
|
|
|
notifylist_remove_config(rec);
|
|
|
|
notifies = g_slist_remove(notifies, rec);
|
|
|
|
signal_emit("notifylist remove", 1, rec);
|
|
|
|
|
|
|
|
notify_destroy(rec);
|
|
|
|
}
|
|
|
|
|
2000-04-28 04:07:42 -04:00
|
|
|
int notifylist_ircnets_match(NOTIFYLIST_REC *rec, const char *ircnet)
|
2000-04-26 04:03:38 -04:00
|
|
|
{
|
|
|
|
char **tmp;
|
|
|
|
|
|
|
|
if (rec->ircnets == NULL) return TRUE;
|
|
|
|
if (ircnet == NULL) return FALSE;
|
|
|
|
if (strcmp(ircnet, "*") == 0) return TRUE;
|
|
|
|
|
|
|
|
for (tmp = rec->ircnets; *tmp != NULL; tmp++) {
|
|
|
|
if (g_strcasecmp(*tmp, ircnet) == 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NOTIFYLIST_REC *notifylist_find(const char *mask, const char *ircnet)
|
|
|
|
{
|
|
|
|
NOTIFYLIST_REC *best;
|
|
|
|
GSList *tmp;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
best = NULL;
|
|
|
|
len = strlen(mask);
|
|
|
|
for (tmp = notifies; tmp != NULL; tmp = tmp->next) {
|
|
|
|
NOTIFYLIST_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
/* check mask */
|
|
|
|
if (g_strncasecmp(rec->mask, mask, len) != 0 ||
|
|
|
|
(rec->mask[len] != '\0' && rec->mask[len] != '!')) continue;
|
|
|
|
|
|
|
|
/* check ircnet */
|
|
|
|
if (rec->ircnets == NULL) {
|
|
|
|
best = rec;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2000-04-28 04:07:42 -04:00
|
|
|
if (notifylist_ircnets_match(rec, ircnet))
|
2000-04-26 04:03:38 -04:00
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
return best;
|
|
|
|
}
|
|
|
|
|
|
|
|
int notifylist_ison_server(IRC_SERVER_REC *server, const char *nick)
|
|
|
|
{
|
|
|
|
NOTIFY_NICK_REC *rec;
|
|
|
|
|
|
|
|
g_return_val_if_fail(nick != NULL, FALSE);
|
|
|
|
g_return_val_if_fail(server != NULL, FALSE);
|
|
|
|
|
|
|
|
rec = notify_nick_find(server, nick);
|
|
|
|
return rec != NULL && rec->host_ok && rec->away_ok && rec->idle_ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
static IRC_SERVER_REC *notifylist_ison_serverlist(const char *nick, const char *taglist)
|
|
|
|
{
|
|
|
|
IRC_SERVER_REC *server;
|
|
|
|
char **list, **tmp;
|
|
|
|
|
|
|
|
list = g_strsplit(taglist, " ", -1);
|
|
|
|
|
|
|
|
server = NULL;
|
|
|
|
for (tmp = list; *tmp != NULL; tmp++) {
|
|
|
|
server = (IRC_SERVER_REC *) server_find_ircnet(*tmp);
|
|
|
|
|
|
|
|
if (server != NULL && notifylist_ison_server(server, nick))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
g_strfreev(list);
|
|
|
|
|
|
|
|
return tmp == NULL ? NULL : server;
|
|
|
|
}
|
|
|
|
|
|
|
|
IRC_SERVER_REC *notifylist_ison(const char *nick, const char *serverlist)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
g_return_val_if_fail(nick != NULL, FALSE);
|
|
|
|
g_return_val_if_fail(serverlist != NULL, FALSE);
|
|
|
|
|
|
|
|
if (*serverlist != '\0')
|
|
|
|
return notifylist_ison_serverlist(nick, serverlist);
|
|
|
|
|
|
|
|
/* any server.. */
|
|
|
|
for (tmp = servers; tmp != NULL; tmp = tmp->next) {
|
|
|
|
if (notifylist_ison_server(tmp->data, nick))
|
|
|
|
return tmp->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void notifylist_init_server(IRC_SERVER_REC *server)
|
|
|
|
{
|
|
|
|
MODULE_SERVER_REC *rec;
|
|
|
|
|
|
|
|
g_return_if_fail(server != NULL);
|
|
|
|
|
|
|
|
rec = g_new0(MODULE_SERVER_REC,1 );
|
|
|
|
MODULE_DATA_SET(server, rec);
|
|
|
|
|
|
|
|
server_redirect_init((SERVER_REC *) server, "command ison", 1, ISON_EVENT, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void notifylist_deinit_server(IRC_SERVER_REC *server)
|
|
|
|
{
|
|
|
|
MODULE_SERVER_REC *mserver;
|
|
|
|
NOTIFY_NICK_REC *rec;
|
|
|
|
|
|
|
|
g_return_if_fail(server != NULL);
|
|
|
|
|
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
while (mserver->notify_users != NULL) {
|
|
|
|
rec = mserver->notify_users->data;
|
|
|
|
|
|
|
|
mserver->notify_users = g_slist_remove(mserver->notify_users, rec);
|
|
|
|
notify_nick_destroy(rec);
|
|
|
|
}
|
|
|
|
g_free(mserver);
|
|
|
|
}
|
|
|
|
|
|
|
|
void notifylist_left(IRC_SERVER_REC *server, NOTIFY_NICK_REC *rec)
|
|
|
|
{
|
|
|
|
MODULE_SERVER_REC *mserver;
|
|
|
|
|
|
|
|
mserver = MODULE_DATA(server);
|
|
|
|
mserver->notify_users = g_slist_remove(mserver->notify_users, rec);
|
|
|
|
|
|
|
|
if (rec->host_ok && rec->away_ok) {
|
|
|
|
signal_emit("notifylist left", 6,
|
|
|
|
server, rec->nick,
|
|
|
|
rec->user, rec->host,
|
|
|
|
rec->realname, rec->awaymsg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void notifylist_idle_reset(IRC_SERVER_REC *server, const char *nick)
|
|
|
|
{
|
|
|
|
NOTIFY_NICK_REC *rec;
|
|
|
|
NOTIFYLIST_REC *notify;
|
|
|
|
|
|
|
|
notify = notifylist_find(nick, server->connrec->ircnet);
|
|
|
|
rec = notify_nick_find(server, nick);
|
|
|
|
|
|
|
|
if (notify != NULL && rec != NULL && notify->idle_check_time > 0 &&
|
|
|
|
time(NULL)-rec->idle_time > notify->idle_check_time) {
|
|
|
|
rec->idle_time = time(NULL);
|
|
|
|
signal_emit("notifylist unidle", 6,
|
|
|
|
server, rec->nick,
|
|
|
|
rec->user, rec->host,
|
|
|
|
rec->realname, rec->awaymsg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void event_quit(const char *data, IRC_SERVER_REC *server, const char *nick)
|
|
|
|
{
|
|
|
|
NOTIFY_NICK_REC *rec;
|
|
|
|
|
|
|
|
if (*data == ':') data++; /* quit message */
|
|
|
|
|
|
|
|
rec = notify_nick_find(server, nick);
|
|
|
|
if (rec != NULL) notifylist_left(server, rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void notifylist_check_join(IRC_SERVER_REC *server, const char *nick,
|
|
|
|
const char *userhost, const char *realname, int away)
|
|
|
|
{
|
|
|
|
NOTIFYLIST_REC *notify;
|
|
|
|
NOTIFY_NICK_REC *rec;
|
|
|
|
char *user, *host;
|
|
|
|
|
|
|
|
notify = notifylist_find(nick, server->connrec->ircnet);
|
|
|
|
if (notify == NULL) return;
|
|
|
|
|
|
|
|
rec = notify_nick_find(server, nick);
|
|
|
|
if (rec != NULL && rec->join_announced) return;
|
|
|
|
if (rec == NULL) rec = notify_nick_create(server, nick);
|
|
|
|
|
|
|
|
user = g_strdup(userhost);
|
|
|
|
host = strchr(user, '@');
|
|
|
|
if (host != NULL) *host++ = '\0'; else host = "";
|
|
|
|
|
|
|
|
if (!irc_mask_match(notify->mask, nick, user, host)) {
|
|
|
|
g_free(user);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (notify->away_check && away == -1) {
|
|
|
|
/* we need to know if the nick is away */
|
|
|
|
g_free(user);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free_not_null(rec->user);
|
|
|
|
g_free_not_null(rec->host);
|
|
|
|
g_free_not_null(rec->realname);
|
|
|
|
rec->user = g_strdup(user);
|
|
|
|
rec->host = g_strdup(host);
|
|
|
|
rec->realname = *realname == '\0' ? NULL : g_strdup(realname);
|
|
|
|
|
|
|
|
if (away != -1) rec->away = away;
|
|
|
|
rec->host_ok = TRUE;
|
|
|
|
rec->join_announced = TRUE;
|
|
|
|
rec->idle_time = time(NULL);
|
|
|
|
|
|
|
|
signal_emit("notifylist joined", 6,
|
|
|
|
server, rec->nick, rec->user, rec->host, realname, NULL);
|
|
|
|
g_free(user);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address)
|
|
|
|
{
|
|
|
|
if (nick != NULL) {
|
|
|
|
notifylist_check_join(server, nick, address, "", -1);
|
|
|
|
notifylist_idle_reset(server, nick);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void event_join(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address)
|
|
|
|
{
|
|
|
|
notifylist_check_join(server, nick, address, "", -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sig_channel_wholist(CHANNEL_REC *channel)
|
|
|
|
{
|
|
|
|
GSList *nicks, *tmp;
|
|
|
|
|
|
|
|
nicks = nicklist_getnicks(channel);
|
|
|
|
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
|
|
|
|
NICK_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
notifylist_check_join(channel->server, rec->nick, rec->host, rec->realname, rec->gone);
|
|
|
|
}
|
|
|
|
g_slist_free(nicks);
|
|
|
|
}
|
|
|
|
|
2000-05-25 07:30:47 -04:00
|
|
|
void irc_notifylist_init(void)
|
2000-04-26 04:03:38 -04:00
|
|
|
{
|
|
|
|
notifylist_read_config();
|
|
|
|
|
|
|
|
notifylist_commands_init();
|
|
|
|
notifylist_ison_init();
|
|
|
|
notifylist_whois_init();
|
|
|
|
signal_add("server connected", (SIGNAL_FUNC) notifylist_init_server);
|
|
|
|
signal_add("server disconnected", (SIGNAL_FUNC) notifylist_deinit_server);
|
|
|
|
signal_add("event quit", (SIGNAL_FUNC) event_quit);
|
|
|
|
signal_add("event privmsg", (SIGNAL_FUNC) event_privmsg);
|
|
|
|
signal_add("event join", (SIGNAL_FUNC) event_join);
|
|
|
|
signal_add("channel wholist", (SIGNAL_FUNC) sig_channel_wholist);
|
|
|
|
signal_add("setup reread", (SIGNAL_FUNC) notifylist_read_config);
|
|
|
|
}
|
|
|
|
|
2000-05-25 07:30:47 -04:00
|
|
|
void irc_notifylist_deinit(void)
|
2000-04-26 04:03:38 -04:00
|
|
|
{
|
|
|
|
notifylist_commands_deinit();
|
|
|
|
notifylist_ison_deinit();
|
|
|
|
notifylist_whois_deinit();
|
|
|
|
|
|
|
|
signal_remove("server connected", (SIGNAL_FUNC) notifylist_init_server);
|
|
|
|
signal_remove("server disconnected", (SIGNAL_FUNC) notifylist_deinit_server);
|
|
|
|
signal_remove("event quit", (SIGNAL_FUNC) event_quit);
|
|
|
|
signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg);
|
|
|
|
signal_remove("event join", (SIGNAL_FUNC) event_join);
|
|
|
|
signal_remove("channel wholist", (SIGNAL_FUNC) sig_channel_wholist);
|
|
|
|
signal_remove("setup reread", (SIGNAL_FUNC) notifylist_read_config);
|
|
|
|
|
|
|
|
notifylist_destroy_all();
|
|
|
|
}
|