Merged silc_1_0_branch to trunk.
[silc.git] / apps / irssi / src / silc / core / silc-nicklist.c
1 /*
2  silc-nicklist.c : irssi
3
4     Copyright (C) 2000, 2003 Timo Sirainen, Pekka Riikonen
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "module.h"
22 #include "signals.h"
23 #include "misc.h"
24 #include "servers.h"
25
26 #include "silc-channels.h"
27 #include "silc-nicklist.h"
28
29 SILC_NICK_REC *silc_nicklist_insert(SILC_CHANNEL_REC *channel,
30                                     SilcChannelUser user, int send_massjoin)
31 {
32   SILC_NICK_REC *rec;
33
34   g_return_val_if_fail(IS_SILC_CHANNEL(channel), NULL);
35   if (!user)
36     return NULL;
37   if (!user->client)
38     return NULL;
39   if (!user->client->nickname)
40     return NULL;
41
42   rec = g_new0(SILC_NICK_REC, 1);
43   rec->nick = g_strdup(user->client->nickname);
44   rec->host = g_strdup_printf("%s@%s", user->client->username,
45                               user->client->hostname);
46   rec->realname = g_strdup(user->client->realname);
47   rec->silc_user = user;
48   rec->unique_id = user->client;
49
50   if (user->mode & SILC_CHANNEL_UMODE_CHANOP)
51     rec->op = TRUE;
52   if (user->mode & SILC_CHANNEL_UMODE_CHANFO)
53     rec->founder = TRUE;
54   rec->send_massjoin = send_massjoin;
55
56   nicklist_insert(CHANNEL(channel), (NICK_REC *) rec);
57   return rec;
58 }
59
60 SILC_NICK_REC *silc_nicklist_find(SILC_CHANNEL_REC *channel,
61                                   SilcClientEntry client)
62 {
63   if (!client || !client->nickname)
64     return NULL;
65
66   return (SILC_NICK_REC *)nicklist_find_unique(CHANNEL(channel),
67                                                client->nickname, client);
68 }
69
70 #define isnickchar(a) \
71     (isalnum((int) (a)) || (a) == '`' || (a) == '-' || (a) == '_' || \
72     (a) == '[' || (a) == ']' || (a) == '{' || (a) == '}' || \
73     (a) == '|' || (a) == '\\' || (a) == '^')
74
75 /* Remove all "extra" characters from `nick'. Like _nick_ -> nick */
76 char *silc_nick_strip(const char *nick)
77 {
78   char *stripped, *spos;
79
80   g_return_val_if_fail(nick != NULL, NULL);
81
82   spos = stripped = g_strdup(nick);
83   while (isnickchar(*nick)) {
84     if (isalnum((int) *nick))
85       *spos++ = *nick;
86     nick++;
87   }
88   if ((unsigned char) *nick >= 128)
89     *spos++ = *nick; /* just add it so that nicks won't match.. */
90   *spos = '\0';
91
92   return stripped;
93 }
94
95 /* Check is `msg' is meant for `nick'. */
96 int silc_nick_match(const char *nick, const char *msg)
97 {
98   char *stripnick, *stripmsg;
99   int ret, len;
100
101   g_return_val_if_fail(nick != NULL, FALSE);
102   g_return_val_if_fail(msg != NULL, FALSE);
103
104   len = strlen(nick);
105   if (g_strncasecmp(msg, nick, len) == 0 && !isalnum((int) msg[len]))
106     return TRUE;
107
108   stripnick = silc_nick_strip(nick);
109   stripmsg = silc_nick_strip(msg);
110
111   len = strlen(stripnick);
112   ret = len > 0 && g_strncasecmp(stripmsg, stripnick, len) == 0 &&
113     !isalnum((int) stripmsg[len]) &&
114     (unsigned char) stripmsg[len] < 128;
115
116   g_free(stripnick);
117   g_free(stripmsg);
118
119   return ret;
120 }
121
122 static const char *get_nick_flags(void)
123 {
124   static char flags[3] = { '@', '+', '\0' };
125   return flags;
126 }
127
128 static void sig_connected(SILC_SERVER_REC *server)
129 {
130   if (IS_SILC_SERVER(server))
131     server->get_nick_flags = (void *) get_nick_flags;
132 }
133
134 void silc_change_nick(SILC_SERVER_REC *server, const char *newnick)
135 {
136   server_change_nick((SERVER_REC *)server, newnick);
137 }
138
139 void silc_nicklist_init(void)
140 {
141   signal_add("server connected", (SIGNAL_FUNC) sig_connected);
142 }
143
144 void silc_nicklist_deinit(void)
145 {
146   signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
147 }