2 silc-channels.c : irssi
4 Copyright (C) 2000-2001 Timo Sirainen
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.
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.
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
26 #include "channels-setup.h"
29 #include "silc-channels.h"
30 #include "silc-nicklist.h"
32 #include "fe-common/core/printtext.h"
34 SILC_CHANNEL_REC *silc_channel_create(SILC_SERVER_REC *server,
35 const char *name, int automatic)
37 SILC_CHANNEL_REC *rec;
39 g_return_val_if_fail(server == NULL || IS_SILC_SERVER(server), NULL);
40 g_return_val_if_fail(name != NULL, NULL);
42 rec = g_new0(SILC_CHANNEL_REC, 1);
43 rec->chat_type = SILC_PROTOCOL;
44 rec->name = g_strdup(name);
47 channel_init((CHANNEL_REC *) rec, automatic);
51 static void sig_channel_destroyed(SILC_CHANNEL_REC *channel)
53 if (!IS_SILC_CHANNEL(channel))
56 if (channel->server != NULL && !channel->left && !channel->kicked) {
57 /* destroying channel record without actually
58 having left the channel yet */
59 silc_command_exec(channel->server, "PART", channel->name);
63 static void silc_channels_join(SILC_SERVER_REC *server,
64 const char *channels, int automatic)
66 char **list, **tmp, *channel;
68 list = g_strsplit(channels, ",", -1);
69 for (tmp = list; *tmp != NULL; tmp++) {
70 channel = **tmp == '#' ? g_strdup(*tmp) :
71 g_strconcat("#", *tmp, NULL);
72 silc_channel_create(server, channel, FALSE);
73 silc_command_exec(server, "JOIN", channel);
79 static void sig_connected(SILC_SERVER_REC *server)
81 if (IS_SILC_SERVER(server))
82 server->channels_join = (void *) silc_channels_join;
85 SILC_CHANNEL_REC *silc_channel_find_entry(SILC_SERVER_REC *server,
86 SilcChannelEntry entry)
90 g_return_val_if_fail(IS_SILC_SERVER(server), NULL);
92 for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
93 SILC_CHANNEL_REC *rec = tmp->data;
95 if (rec->entry == entry)
102 static void event_join(SILC_SERVER_REC *server, va_list va)
104 SILC_CHANNEL_REC *chanrec;
105 SILC_NICK_REC *nickrec;
106 SilcClientEntry client;
107 SilcChannelEntry channel;
109 client = va_arg(va, SilcClientEntry);
110 channel = va_arg(va, SilcChannelEntry);
112 if (client == server->conn->local_entry) {
113 /* you joined to channel */
114 chanrec = silc_channel_find(server, channel->channel_name);
115 if (chanrec != NULL && !chanrec->joined)
116 chanrec->entry = channel;
118 chanrec = silc_channel_find_entry(server, channel);
119 if (chanrec != NULL) {
120 SilcChannelUser user;
122 silc_list_start(chanrec->entry->clients);
123 while ((user = silc_list_get(chanrec->entry->clients)) != NULL)
124 if (user->client == client) {
125 nickrec = silc_nicklist_insert(chanrec, user, TRUE);
131 signal_emit("message join", 4, server, channel->channel_name,
133 client->username == NULL ? "" : client->username);
136 static void event_leave(SILC_SERVER_REC *server, va_list va)
138 SILC_CHANNEL_REC *chanrec;
139 SILC_NICK_REC *nickrec;
140 SilcClientEntry client;
141 SilcChannelEntry channel;
143 client = va_arg(va, SilcClientEntry);
144 channel = va_arg(va, SilcChannelEntry);
146 signal_emit("message part", 5, server, channel->channel_name,
148 client->username == NULL ? "" : client->username, "");
150 chanrec = silc_channel_find_entry(server, channel);
151 if (chanrec != NULL) {
152 nickrec = silc_nicklist_find(chanrec, client);
154 nicklist_remove(CHANNEL(chanrec), NICK(nickrec));
158 static void event_signoff(SILC_SERVER_REC *server, va_list va)
160 SilcClientEntry client;
163 client = va_arg(va, SilcClientEntry);
165 signal_emit("message quit", 4, server, client->nickname,
166 client->username == NULL ? "" : client->username, "");
168 nicks = nicklist_get_same_unique(SERVER(server), client);
169 for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
170 CHANNEL_REC *channel = tmp->data;
171 NICK_REC *nickrec = tmp->next->data;
173 nicklist_remove(channel, nickrec);
177 static void event_topic(SILC_SERVER_REC *server, va_list va)
179 SILC_CHANNEL_REC *chanrec;
180 SilcClientEntry client;
181 SilcChannelEntry channel;
184 client = va_arg(va, SilcClientEntry);
185 topic = va_arg(va, char *);
186 channel = va_arg(va, SilcChannelEntry);
188 chanrec = silc_channel_find_entry(server, channel);
189 if (chanrec != NULL) {
190 g_free_not_null(chanrec->topic);
191 chanrec->topic = *topic == '\0' ? NULL : g_strdup(topic);
192 signal_emit("channel topic changed", 1, chanrec);
195 signal_emit("message topic", 5, server, channel->channel_name,
196 topic, client->nickname, client->username);
199 static void event_invite(SILC_SERVER_REC *server, va_list va)
201 SilcClientEntry client;
202 SilcChannelEntry channel;
204 client = va_arg(va, SilcClientEntry);
205 channel = va_arg(va, SilcChannelEntry);
207 signal_emit("message invite", 4, server, channel->channel_name,
208 client->nickname, client->username);
211 static void event_nick(SILC_SERVER_REC *server, va_list va)
213 SilcClientEntry oldclient, newclient;
215 oldclient = va_arg(va, SilcClientEntry);
216 newclient = va_arg(va, SilcClientEntry);
218 nicklist_rename_unique(SERVER(server),
219 oldclient, oldclient->nickname,
220 newclient, newclient->nickname);
222 signal_emit("message nick", 4, server, newclient->nickname,
223 oldclient->nickname, newclient->username);
226 static void event_cmode(SILC_SERVER_REC *server, va_list va)
228 SILC_CHANNEL_REC *chanrec;
229 SilcClientEntry client;
230 SilcChannelEntry channel;
233 client = va_arg(va, SilcClientEntry);
234 mode = silc_client_chmode(va_arg(va, unsigned int));
235 channel = va_arg(va, SilcChannelEntry);
237 chanrec = silc_channel_find_entry(server, channel);
238 if (chanrec != NULL) {
239 g_free_not_null(chanrec->mode);
240 chanrec->mode = g_strdup(mode == NULL ? "" : mode);
241 signal_emit("channel mode changed", 1, chanrec);
244 /*signal_emit("message mode", 5, server, chanrec->name,
245 client->nickname, client->username, mode);*/
246 printtext(server, channel->channel_name, MSGLEVEL_MODES,
247 "mode/%s [%s] by %s", channel->channel_name, mode,
253 static void event_cumode(SILC_SERVER_REC *server, va_list va)
255 SILC_CHANNEL_REC *chanrec;
256 SilcClientEntry client, destclient;
257 SilcChannelEntry channel;
261 client = va_arg(va, SilcClientEntry);
262 mode = va_arg(va, unsigned int);
263 destclient = va_arg(va, SilcClientEntry);
264 channel = va_arg(va, SilcChannelEntry);
266 modestr = silc_client_chumode(mode);
267 chanrec = silc_channel_find_entry(server, channel);
268 if (chanrec != NULL) {
271 if (destclient == server->conn->local_entry) {
273 (mode & SILC_CHANNEL_UMODE_CHANOP) != 0;
276 nick = silc_nicklist_find(chanrec, client);
278 nick->op = (mode & SILC_CHANNEL_UMODE_CHANOP) != 0;
279 signal_emit("nick mode changed", 2, chanrec, nick);
283 /*signal_emit("message mode", 5, server, chanrec->name,
284 client->nickname, client->username, modestr);*/
285 printtext(server, channel->channel_name, MSGLEVEL_MODES,
286 "mode/%s [%s] by %s", channel->channel_name, modestr,
292 static void command_part(const char *data, SILC_SERVER_REC *server,
295 SILC_CHANNEL_REC *chanrec;
297 if (!IS_SILC_SERVER(server) || !server->connected)
301 if (!IS_SILC_CHANNEL(item))
302 cmd_return_error(CMDERR_NOT_JOINED);
306 chanrec = silc_channel_find(server, data);
307 if (chanrec == NULL) cmd_return_error(CMDERR_CHAN_NOT_FOUND);
309 signal_emit("message part", 5, server, chanrec->name,
310 server->nick, "", "");
312 silc_command_exec(server, "LEAVE", chanrec->name);
315 channel_destroy(CHANNEL(chanrec));
318 void silc_channels_init(void)
320 signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
321 signal_add("server connected", (SIGNAL_FUNC) sig_connected);
323 signal_add("silc event join", (SIGNAL_FUNC) event_join);
324 signal_add("silc event leave", (SIGNAL_FUNC) event_leave);
325 signal_add("silc event signoff", (SIGNAL_FUNC) event_signoff);
326 signal_add("silc event topic", (SIGNAL_FUNC) event_topic);
327 signal_add("silc event invite", (SIGNAL_FUNC) event_invite);
328 signal_add("silc event nick", (SIGNAL_FUNC) event_nick);
329 signal_add("silc event cmode", (SIGNAL_FUNC) event_cmode);
330 signal_add("silc event cumode", (SIGNAL_FUNC) event_cumode);
332 command_bind("part", MODULE_NAME, (SIGNAL_FUNC) command_part);
334 silc_nicklist_init();
337 void silc_channels_deinit(void)
339 signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
340 signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
342 signal_remove("silc event join", (SIGNAL_FUNC) event_join);
343 signal_remove("silc event leave", (SIGNAL_FUNC) event_leave);
344 signal_remove("silc event signoff", (SIGNAL_FUNC) event_signoff);
345 signal_remove("silc event topic", (SIGNAL_FUNC) event_topic);
346 signal_remove("silc event invite", (SIGNAL_FUNC) event_invite);
347 signal_remove("silc event nick", (SIGNAL_FUNC) event_nick);
348 signal_remove("silc event cmode", (SIGNAL_FUNC) event_cmode);
349 signal_remove("silc event cumode", (SIGNAL_FUNC) event_cumode);
351 command_unbind("part", (SIGNAL_FUNC) command_part);
353 silc_nicklist_deinit();