summaryrefslogtreecommitdiff
path: root/src/irc/notifylist/notifylist.c
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2000-04-26 08:03:38 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2000-04-26 08:03:38 +0000
commitc95034c6de1bf72536595e1e3431d8ec64b9880e (patch)
treee51aa4528257ed8aa9d53640649519f299aaf0c7 /src/irc/notifylist/notifylist.c
parentd01b094151705d433bc43cae9eeb304e6f110a17 (diff)
downloadirssi-c95034c6de1bf72536595e1e3431d8ec64b9880e.zip
..adding new files..
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@171 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/irc/notifylist/notifylist.c')
-rw-r--r--src/irc/notifylist/notifylist.c356
1 files changed, 356 insertions, 0 deletions
diff --git a/src/irc/notifylist/notifylist.c b/src/irc/notifylist/notifylist.c
new file mode 100644
index 00000000..00561dc9
--- /dev/null
+++ b/src/irc/notifylist/notifylist.c
@@ -0,0 +1,356 @@
+/*
+ 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);
+}
+
+int notify_ircnets_match(NOTIFYLIST_REC *rec, const char *ircnet)
+{
+ 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;
+ }
+
+ if (notify_ircnets_match(rec, ircnet))
+ 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);
+}
+
+void notifylist_init(void)
+{
+ 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);
+}
+
+void notifylist_deinit(void)
+{
+ 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();
+}