diff options
author | Timo Sirainen <cras@irssi.org> | 2000-04-26 08:03:38 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2000-04-26 08:03:38 +0000 |
commit | c95034c6de1bf72536595e1e3431d8ec64b9880e (patch) | |
tree | e51aa4528257ed8aa9d53640649519f299aaf0c7 /src/irc/notifylist/notifylist.c | |
parent | d01b094151705d433bc43cae9eeb304e6f110a17 (diff) | |
download | irssi-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.c | 356 |
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(); +} |