Created SILC Runtime Toolkit git repository Part I.
[runtime.git] / apps / irssi / src / core / nicklist.c
diff --git a/apps/irssi/src/core/nicklist.c b/apps/irssi/src/core/nicklist.c
deleted file mode 100644 (file)
index 4f322bf..0000000
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- nicklist.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 "servers.h"
-#include "channels.h"
-#include "nicklist.h"
-#include "masks.h"
-
-#define isalnumhigh(a) \
-        (i_isalnum(a) || (unsigned char) (a) >= 128)
-
-static void nick_hash_add(CHANNEL_REC *channel, NICK_REC *nick)
-{
-       NICK_REC *list;
-
-       nick->next = NULL;
-
-       list = g_hash_table_lookup(channel->nicks, nick->nick);
-        if (list == NULL)
-               g_hash_table_insert(channel->nicks, nick->nick, nick);
-       else {
-                /* multiple nicks with same name */
-               while (list->next != NULL)
-                       list = list->next;
-               list->next = nick;
-       }
-
-       if (nick == channel->ownnick) {
-                /* move our own nick to beginning of the nick list.. */
-               nicklist_set_own(channel, nick);
-       }
-}
-
-static void nick_hash_remove(CHANNEL_REC *channel, NICK_REC *nick)
-{
-       NICK_REC *list;
-
-       list = g_hash_table_lookup(channel->nicks, nick->nick);
-       if (list == NULL)
-               return;
-
-       if (list == nick || list->next == NULL) {
-               g_hash_table_remove(channel->nicks, nick->nick);
-               if (list->next != NULL) {
-                       g_hash_table_insert(channel->nicks, nick->next->nick,
-                                           nick->next);
-               }
-       } else {
-               while (list->next != nick)
-                       list = list->next;
-               list->next = nick->next;
-       }
-}
-
-/* Add new nick to list */
-void nicklist_insert(CHANNEL_REC *channel, NICK_REC *nick)
-{
-       /*MODULE_DATA_INIT(nick);*/
-
-       nick->type = module_get_uniq_id("NICK", 0);
-        nick->chat_type = channel->chat_type;
-
-        nick_hash_add(channel, nick);
-       signal_emit("nicklist new", 2, channel, nick);
-}
-
-/* Set host address for nick */
-void nicklist_set_host(CHANNEL_REC *channel, NICK_REC *nick, const char *host)
-{
-        g_return_if_fail(channel != NULL);
-        g_return_if_fail(nick != NULL);
-       g_return_if_fail(host != NULL);
-
-        g_free_not_null(nick->host);
-       nick->host = g_strdup(host);
-
-        signal_emit("nicklist host changed", 2, channel, nick);
-}
-
-static void nicklist_destroy(CHANNEL_REC *channel, NICK_REC *nick)
-{
-       signal_emit("nicklist remove", 2, channel, nick);
-
-       if (channel->ownnick == nick)
-                channel->ownnick = NULL;
-
-        /*MODULE_DATA_DEINIT(nick);*/
-       g_free(nick->nick);
-       g_free_not_null(nick->realname);
-       g_free_not_null(nick->host);
-       g_free(nick);
-}
-
-/* Remove nick from list */
-void nicklist_remove(CHANNEL_REC *channel, NICK_REC *nick)
-{
-       g_return_if_fail(IS_CHANNEL(channel));
-       g_return_if_fail(nick != NULL);
-
-        nick_hash_remove(channel, nick);
-       nicklist_destroy(channel, nick);
-}
-
-static void nicklist_rename_list(SERVER_REC *server, void *new_nick_id,
-                                const char *old_nick, const char *new_nick,
-                                GSList *nicks)
-{
-       CHANNEL_REC *channel;
-       NICK_REC *nickrec;
-       GSList *tmp;
-
-       for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
-               channel = tmp->data;
-               nickrec = tmp->next->data;
-
-               /* remove old nick from hash table */
-                nick_hash_remove(channel, nickrec);
-
-               if (new_nick_id != NULL)
-                       nickrec->unique_id = new_nick_id;
-
-               g_free(nickrec->nick);
-               nickrec->nick = g_strdup(new_nick);
-
-               /* add new nick to hash table */
-                nick_hash_add(channel, nickrec);
-
-               signal_emit("nicklist changed", 3, channel, nickrec, old_nick);
-       }
-       g_slist_free(nicks);
-}
-
-void nicklist_rename(SERVER_REC *server, const char *old_nick,
-                    const char *new_nick)
-{
-       nicklist_rename_list(server, NULL, old_nick, new_nick,
-                            nicklist_get_same(server, old_nick));
-}
-
-void nicklist_rename_unique(SERVER_REC *server,
-                           void *old_nick_id, const char *old_nick,
-                           void *new_nick_id, const char *new_nick)
-{
-       nicklist_rename_list(server, new_nick_id, old_nick, new_nick,
-                            nicklist_get_same_unique(server, old_nick_id));
-}
-
-static NICK_REC *nicklist_find_wildcards(CHANNEL_REC *channel,
-                                        const char *mask)
-{
-       GSList *nicks, *tmp;
-       NICK_REC *nick;
-
-       nicks = nicklist_getnicks(channel);
-       nick = NULL;
-       for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
-               nick = tmp->data;
-
-               if (mask_match_address(channel->server, mask,
-                                      nick->nick, nick->host))
-                       break;
-       }
-       g_slist_free(nicks);
-       return tmp == NULL ? NULL : nick;
-}
-
-GSList *nicklist_find_multiple(CHANNEL_REC *channel, const char *mask)
-{
-       GSList *nicks, *tmp, *next;
-
-       g_return_val_if_fail(IS_CHANNEL(channel), NULL);
-       g_return_val_if_fail(mask != NULL, NULL);
-
-       nicks = nicklist_getnicks(channel);
-       for (tmp = nicks; tmp != NULL; tmp = next) {
-               NICK_REC *nick = tmp->data;
-
-               next = tmp->next;
-               if (!mask_match_address(channel->server, mask,
-                                       nick->nick, nick->host))
-                        nicks = g_slist_remove(nicks, tmp->data);
-       }
-
-       return nicks;
-}
-
-/* Find nick */
-NICK_REC *nicklist_find(CHANNEL_REC *channel, const char *nick)
-{
-       g_return_val_if_fail(IS_CHANNEL(channel), NULL);
-       g_return_val_if_fail(nick != NULL, NULL);
-
-       return g_hash_table_lookup(channel->nicks, nick);
-}
-
-NICK_REC *nicklist_find_unique(CHANNEL_REC *channel, const char *nick,
-                              void *id)
-{
-       NICK_REC *rec;
-
-       g_return_val_if_fail(IS_CHANNEL(channel), NULL);
-       g_return_val_if_fail(nick != NULL, NULL);
-
-       rec = g_hash_table_lookup(channel->nicks, nick);
-       while (rec != NULL && rec->unique_id != id)
-                rec = rec->next;
-
-        return rec;
-}
-
-/* Find nick mask, wildcards allowed */
-NICK_REC *nicklist_find_mask(CHANNEL_REC *channel, const char *mask)
-{
-       NICK_REC *nickrec;
-       char *nick, *host;
-
-       g_return_val_if_fail(IS_CHANNEL(channel), NULL);
-       g_return_val_if_fail(mask != NULL, NULL);
-
-       nick = g_strdup(mask);
-       host = strchr(nick, '!');
-       if (host != NULL) *host++ = '\0';
-
-       if (strchr(nick, '*') || strchr(nick, '?')) {
-               g_free(nick);
-               return nicklist_find_wildcards(channel, mask);
-       }
-
-       nickrec = g_hash_table_lookup(channel->nicks, nick);
-
-       if (host != NULL) {
-               while (nickrec != NULL) {
-                       if (nickrec->host != NULL &&
-                           match_wildcards(host, nickrec->host))
-                               break; /* match */
-                       nickrec = nickrec->next;
-               }
-       }
-       g_free(nick);
-       return nickrec;
-}
-
-static void get_nicks_hash(gpointer key, NICK_REC *rec, GSList **list)
-{
-       while (rec != NULL) {
-               *list = g_slist_append(*list, rec);
-                rec = rec->next;
-       }
-}
-
-/* Get list of nicks */
-GSList *nicklist_getnicks(CHANNEL_REC *channel)
-{
-       GSList *list;
-
-       g_return_val_if_fail(IS_CHANNEL(channel), NULL);
-
-       list = NULL;
-       g_hash_table_foreach(channel->nicks, (GHFunc) get_nicks_hash, &list);
-       return list;
-}
-
-typedef struct {
-        CHANNEL_REC *channel;
-       const char *nick;
-       GSList *list;
-} NICKLIST_GET_SAME_REC;
-
-static void get_nicks_same_hash(gpointer key, NICK_REC *nick,
-                               NICKLIST_GET_SAME_REC *rec)
-{
-       while (nick != NULL) {
-               if (g_strcasecmp(nick->nick, rec->nick) == 0) {
-                       rec->list = g_slist_append(rec->list, rec->channel);
-                       rec->list = g_slist_append(rec->list, nick);
-               }
-
-               nick = nick->next;
-       }
-}
-
-GSList *nicklist_get_same(SERVER_REC *server, const char *nick)
-{
-       NICKLIST_GET_SAME_REC rec;
-       GSList *tmp;
-
-       g_return_val_if_fail(IS_SERVER(server), NULL);
-
-       rec.nick = nick;
-       rec.list = NULL;
-       for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
-               rec.channel = tmp->data;
-               g_hash_table_foreach(rec.channel->nicks,
-                                    (GHFunc) get_nicks_same_hash, &rec);
-       }
-       return rec.list;
-}
-
-typedef struct {
-       CHANNEL_REC *channel;
-        void *id;
-       GSList *list;
-} NICKLIST_GET_SAME_UNIQUE_REC;
-
-static void get_nicks_same_hash_unique(gpointer key, NICK_REC *nick,
-                                      NICKLIST_GET_SAME_UNIQUE_REC *rec)
-{
-       while (nick != NULL) {
-               if (nick->unique_id == rec->id) {
-                       rec->list = g_slist_append(rec->list, rec->channel);
-                       rec->list = g_slist_append(rec->list, nick);
-                        break;
-               }
-
-                nick = nick->next;
-       }
-}
-
-GSList *nicklist_get_same_unique(SERVER_REC *server, void *id)
-{
-       NICKLIST_GET_SAME_UNIQUE_REC rec;
-       GSList *tmp;
-
-       g_return_val_if_fail(IS_SERVER(server), NULL);
-       g_return_val_if_fail(id != NULL, NULL);
-
-        rec.id = id;
-       rec.list = NULL;
-       for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
-               rec.channel = tmp->data;
-               g_hash_table_foreach(rec.channel->nicks,
-                                    (GHFunc) get_nicks_same_hash_unique,
-                                    &rec);
-       }
-       return rec.list;
-}
-
-#if GLIB_MAJOR_VERSION < 2
-/* glib1 doesn't have g_slist_sort_with_data, so non-standard prefixes won't be sorted correctly */
-int nicklist_compare_glib1(NICK_REC *p1, NICK_REC *p2)
-{
-       return nicklist_compare(p1, p2, NULL);
-}
-#endif
-
-/* nick record comparision for sort functions */
-int nicklist_compare(NICK_REC *p1, NICK_REC *p2, const char *nick_prefix)
-{
-       int status1, status2;
-       
-       if (p1 == NULL) return -1;
-       if (p2 == NULL) return 1;
-
-       /* we assign each status (op, halfop, voice, normal) a number
-        * and compare them. this is easier than 100,000 if's and
-        * returns :-)
-        * -- yath */
-
-       if (p1->other) {
-               const char *other = (nick_prefix == NULL) ? NULL : strchr(nick_prefix, p1->other);
-               status1 = (other == NULL) ? 5 : 1000 - (other - nick_prefix);
-       } else if (p1->op)
-               status1 = 4;
-       else if (p1->halfop)
-               status1 = 3;
-       else if (p1->voice)
-               status1 = 2;
-       else
-               status1 = 1;
-
-       if (p2->other) {
-               const char *other = (nick_prefix == NULL) ? NULL : strchr(nick_prefix, p2->other);
-               status2 = (other == NULL) ? 5 : 1000 - (other - nick_prefix);
-       } else if (p2->op)
-               status2 = 4;
-       else if (p2->halfop)
-               status2 = 3;
-       else if (p2->voice)
-               status2 = 2;
-       else
-               status2 = 1;
-       
-       if (status1 < status2)
-               return 1;
-       else if (status1 > status2)
-               return -1;
-       
-       return g_strcasecmp(p1->nick, p2->nick);
-}
-
-static void nicklist_update_flags_list(SERVER_REC *server, int gone,
-                                      int serverop, GSList *nicks)
-{
-       GSList *tmp;
-       CHANNEL_REC *channel;
-       NICK_REC *rec;
-
-       g_return_if_fail(IS_SERVER(server));
-
-       for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
-               channel = tmp->data;
-               rec = tmp->next->data;
-
-               rec->last_check = time(NULL);
-
-               if (gone != -1 && (int)rec->gone != gone) {
-                       rec->gone = gone;
-                       signal_emit("nicklist gone changed", 2, channel, rec);
-               }
-
-               if (serverop != -1 && (int)rec->serverop != serverop) {
-                       rec->serverop = serverop;
-                       signal_emit("nicklist serverop changed", 2, channel, rec);
-               }
-       }
-       g_slist_free(nicks);
-}
-
-void nicklist_update_flags(SERVER_REC *server, const char *nick,
-                          int gone, int serverop)
-{
-       nicklist_update_flags_list(server, gone, serverop,
-                                  nicklist_get_same(server, nick));
-}
-
-void nicklist_update_flags_unique(SERVER_REC *server, void *id,
-                                 int gone, int serverop)
-{
-       nicklist_update_flags_list(server, gone, serverop,
-                                  nicklist_get_same_unique(server, id));
-}
-
-/* Specify which nick in channel is ours */
-void nicklist_set_own(CHANNEL_REC *channel, NICK_REC *nick)
-{
-       NICK_REC *first, *next;
-
-        channel->ownnick = nick;
-
-       /* move our nick in the list to first, makes some things easier
-          (like handling multiple identical nicks in fe-messages.c) */
-       first = g_hash_table_lookup(channel->nicks, nick->nick);
-       if (first->next == NULL)
-               return;
-
-       next = nick->next;
-       nick->next = first;
-
-       while (first->next != nick)
-                first = first->next;
-       first->next = next;
-
-        g_hash_table_insert(channel->nicks, nick->nick, nick);
-}
-
-static void sig_channel_created(CHANNEL_REC *channel)
-{
-       g_return_if_fail(IS_CHANNEL(channel));
-
-       channel->nicks = g_hash_table_new((GHashFunc) g_istr_hash,
-                                         (GCompareFunc) g_istr_equal);
-}
-
-static void nicklist_remove_hash(gpointer key, NICK_REC *nick,
-                                CHANNEL_REC *channel)
-{
-       NICK_REC *next;
-
-       while (nick != NULL) {
-                next = nick->next;
-               nicklist_destroy(channel, nick);
-                nick = next;
-       }
-}
-
-static void sig_channel_destroyed(CHANNEL_REC *channel)
-{
-       g_return_if_fail(IS_CHANNEL(channel));
-
-       g_hash_table_foreach(channel->nicks,
-                            (GHFunc) nicklist_remove_hash, channel);
-       g_hash_table_destroy(channel->nicks);
-}
-
-static NICK_REC *nick_nfind(CHANNEL_REC *channel, const char *nick, int len)
-{
-        NICK_REC *rec;
-       char *tmpnick;
-
-       tmpnick = g_strndup(nick, len);
-       rec = g_hash_table_lookup(channel->nicks, tmpnick);
-
-       if (rec != NULL) {
-               /* if there's multiple, get the one with identical case */
-               while (rec->next != NULL) {
-                       if (strcmp(rec->nick, tmpnick) == 0)
-                               break;
-                        rec = rec->next;
-               }
-       }
-
-        g_free(tmpnick);
-       return rec;
-}
-
-/* Check is `msg' is meant for `nick'. */
-int nick_match_msg(CHANNEL_REC *channel, const char *msg, const char *nick)
-{
-       const char *msgstart, *orignick;
-       int len, fullmatch;
-
-       g_return_val_if_fail(nick != NULL, FALSE);
-       g_return_val_if_fail(msg != NULL, FALSE);
-
-       if (channel != NULL && channel->server->nick_match_msg != NULL)
-               return channel->server->nick_match_msg(msg, nick);
-
-       /* first check for identical match */
-       len = strlen(nick);
-       if (g_strncasecmp(msg, nick, len) == 0 && !isalnumhigh((int) msg[len]))
-               return TRUE;
-
-       orignick = nick;
-       for (;;) {
-               nick = orignick;
-               msgstart = msg;
-                fullmatch = TRUE;
-
-               /* check if it matches for alphanumeric parts of nick */
-               while (*nick != '\0' && *msg != '\0') {
-                       if (i_toupper(*nick) == i_toupper(*msg)) {
-                               /* total match */
-                               msg++;
-                       } else if (i_isalnum(*msg) && !i_isalnum(*nick)) {
-                               /* some strange char in your nick, pass it */
-                                fullmatch = FALSE;
-                       } else
-                               break;
-
-                       nick++;
-               }
-
-               if (msg != msgstart && !isalnumhigh(*msg)) {
-                       /* at least some of the chars in line matched the
-                          nick, and msg continue with non-alphanum character,
-                          this might be for us.. */
-                       if (*nick != '\0') {
-                               /* remove the rest of the non-alphanum chars
-                                  from nick and check if it then matches. */
-                                fullmatch = FALSE;
-                               while (*nick != '\0' && !i_isalnum(*nick))
-                                       nick++;
-                       }
-
-                       if (*nick == '\0') {
-                               /* yes, match! */
-                                break;
-                       }
-               }
-
-               /* no match. check if this is a message to multiple people
-                  (like nick1,nick2: text) */
-               while (*msg != '\0' && *msg != ' ' && *msg != ',') msg++;
-
-               if (*msg != ',') {
-                        nick = orignick;
-                       break;
-               }
-
-                msg++;
-       }
-
-       if (*nick != '\0')
-               return FALSE; /* didn't match */
-
-       if (fullmatch)
-               return TRUE; /* matched without fuzzyness */
-
-       /* matched with some fuzzyness .. check if there's an exact match
-          for some other nick in the same channel. */
-        return nick_nfind(channel, msgstart, (int) (msg-msgstart)) == NULL;
-}
-
-void nicklist_init(void)
-{
-       signal_add_first("channel created", (SIGNAL_FUNC) sig_channel_created);
-       signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
-}
-
-void nicklist_deinit(void)
-{
-       signal_remove("channel created", (SIGNAL_FUNC) sig_channel_created);
-       signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
-
-       module_uniq_destroy("NICK");
-}