Mercurial > pidgin.yaz
annotate src/protocols/irc/msgs.c @ 6621:42fdf16f1dad
[gaim-migrate @ 7145]
Individual accounts remember the "No Proxy" setting instead of reverting
back to "Use Global Proxy Settings"
Proxy settings for individual accounts do not revert to "No Proxy" if
you open an account, don't change the proxy drop down, then save the
account.
Those two sound like the same thing, but they're different. I think.
Added the "use environmental variables" setting in a way that isn't
horrible.
We're not using that thing that splits the proxy variable into
host:port yet. I'll do that later. I would have done that
earlier, but I had to go buy a bike.
Also, I'd like to show what the environmental variables are set to
somewhere. That'll come later.
Also a patch from Robot101:
(22:10:25) Bzubhipheron: I have a patch that replaces #define WFLAG_* with
GaimMessageFlags GAIM_MESSAGE_*
(22:10:30) Bzubhipheron: (an enum in disguise)
(22:14:18) Bzubhipheron: GaimMessageFlags protrays much better typing
information than "int". most of the other #defines are gone, and glib
standardises on enums for its flags too.
(22:14:27) Bzubhipheron: (gone or going)
(22:14:45) Bzubhipheron: and it makes the prototype of my message queueing stuff prettier.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 25 Aug 2003 02:49:42 +0000 |
parents | ba0b99a72be2 |
children | a4622f1fb5a1 |
rev | line source |
---|---|
6333 | 1 /** |
2 * @file msgs.c | |
3 * | |
4 * gaim | |
5 * | |
6 * Copyright (C) 2003, Ethan Blanton <eblanton@cs.purdue.edu> | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 */ | |
22 | |
23 #include "internal.h" | |
24 | |
25 /* XXX g_show_info_text */ | |
26 #include "gaim.h" | |
27 | |
28 #include "conversation.h" | |
29 #include "blist.h" | |
30 #include "notify.h" | |
31 #include "util.h" | |
32 #include "debug.h" | |
33 #include "irc.h" | |
34 | |
35 #include <stdio.h> | |
36 | |
37 static char *irc_mask_nick(const char *mask); | |
38 static char *irc_mask_userhost(const char *mask); | |
39 static void irc_chat_remove_buddy(GaimConversation *convo, char *data[2]); | |
40 static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc); | |
41 | |
42 static char *irc_mask_nick(const char *mask) | |
43 { | |
44 char *end, *buf; | |
45 | |
46 end = strchr(mask, '!'); | |
47 if (!end) | |
48 buf = g_strdup(mask); | |
49 else | |
50 buf = g_strndup(mask, end - mask); | |
51 | |
52 return buf; | |
53 } | |
54 | |
55 static char *irc_mask_userhost(const char *mask) | |
56 { | |
57 return g_strdup(strchr(mask, '!') + 1); | |
58 } | |
59 | |
60 static void irc_chat_remove_buddy(GaimConversation *convo, char *data[2]) | |
61 { | |
62 GList *users = gaim_chat_get_users(GAIM_CHAT(convo)); | |
63 char *message = g_strdup_printf("quit: %s", data[1]); | |
64 | |
65 if (g_list_find_custom(users, data[0], (GCompareFunc)(strcmp))) | |
66 gaim_chat_remove_user(GAIM_CHAT(convo), data[0], message); | |
67 | |
68 g_free(message); | |
69 } | |
70 | |
71 void irc_msg_default(struct irc_conn *irc, const char *name, const char *from, char **args) | |
72 { | |
73 gaim_debug(GAIM_DEBUG_INFO, "irc", "Unrecognized message: %s\n", args[0]); | |
74 } | |
75 | |
76 void irc_msg_away(struct irc_conn *irc, const char *name, const char *from, char **args) | |
77 { | |
78 GaimConnection *gc; | |
79 | |
80 if (!args || !args[1]) | |
81 return; | |
82 | |
83 if (irc->whois.nick && !gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
84 /* We're doing a whois, show this in the whois dialog */ | |
85 irc_msg_whois(irc, name, from, args); | |
86 return; | |
87 } | |
88 | |
89 gc = gaim_account_get_connection(irc->account); | |
90 if (gc) | |
91 serv_got_im(gc, args[1], args[2], IM_FLAG_AWAY, time(NULL), -1); | |
92 } | |
93 | |
94 void irc_msg_badmode(struct irc_conn *irc, const char *name, const char *from, char **args) | |
95 { | |
96 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
97 | |
98 if (!args || !args[1] || !gc) | |
99 return; | |
100 | |
101 gaim_notify_error(gc, NULL, _("Bad mode"), args[1]); | |
102 } | |
103 | |
104 void irc_msg_banned(struct irc_conn *irc, const char *name, const char *from, char **args) | |
105 { | |
106 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
107 char *buf; | |
108 | |
109 if (!args || !args[1] || !gc) | |
110 return; | |
111 | |
112 buf = g_strdup_printf(_("You are banned from %s."), args[1]); | |
113 gaim_notify_error(gc, _("Banned"), _("Banned"), buf); | |
114 g_free(buf); | |
115 } | |
116 | |
117 void irc_msg_chanmode(struct irc_conn *irc, const char *name, const char *from, char **args) | |
118 { | |
119 GaimConversation *convo; | |
120 char *buf; | |
121 | |
122 if (!args || !args[1] || !args[2]) | |
123 return; | |
124 | |
125 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
126 if (!convo) /* XXX punt on channels we are not in for now */ | |
127 return; | |
128 | |
129 buf = g_strdup_printf("mode for %s: %s %s", args[1], args[2], args[3] ? args[3] : ""); | |
6621 | 130 gaim_chat_write(GAIM_CHAT(convo), "", buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 131 g_free(buf); |
132 | |
133 return; | |
134 } | |
135 | |
136 void irc_msg_whois(struct irc_conn *irc, const char *name, const char *from, char **args) | |
137 { | |
138 if (!irc->whois.nick) { | |
139 gaim_debug(GAIM_DEBUG_WARNING, "irc", "Unexpected WHOIS reply for %s\n", args[1]); | |
140 return; | |
141 } | |
142 | |
143 if (gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
144 gaim_debug(GAIM_DEBUG_WARNING, "irc", "Got WHOIS reply for %s while waiting for %s\n", args[1], irc->whois.nick); | |
145 return; | |
146 } | |
147 | |
148 if (!strcmp(name, "301")) { | |
149 irc->whois.away = g_strdup(args[2]); | |
150 } else if (!strcmp(name, "311")) { | |
151 irc->whois.userhost = g_strdup_printf("%s@%s", args[2], args[3]); | |
152 irc->whois.name = g_strdup(args[5]); | |
153 } else if (!strcmp(name, "312")) { | |
154 irc->whois.server = g_strdup(args[2]); | |
155 irc->whois.serverinfo = g_strdup(args[3]); | |
156 } else if (!strcmp(name, "313")) { | |
157 irc->whois.ircop = 1; | |
158 } else if (!strcmp(name, "317")) { | |
159 irc->whois.idle = atoi(args[2]); | |
160 if (args[3]) | |
161 irc->whois.signon = (time_t)atoi(args[3]); | |
162 } else if (!strcmp(name, "319")) { | |
163 irc->whois.channels = g_strdup(args[2]); | |
164 } else if (!strcmp(name, "320")) { | |
165 irc->whois.identified = 1; | |
166 } | |
167 } | |
168 | |
169 void irc_msg_endwhois(struct irc_conn *irc, const char *name, const char *from, char **args) | |
170 { | |
171 GaimConnection *gc; | |
172 GString *info; | |
173 char *str; | |
174 | |
175 if (!irc->whois.nick) { | |
176 gaim_debug(GAIM_DEBUG_WARNING, "irc", "Unexpected End of WHOIS for %s\n", args[1]); | |
177 return; | |
178 } | |
179 if (gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
180 gaim_debug(GAIM_DEBUG_WARNING, "irc", "Received end of WHOIS for %s, expecting %s\n", args[1], irc->whois.nick); | |
181 return; | |
182 } | |
183 | |
184 info = g_string_new(""); | |
185 g_string_append_printf(info, "<b>%s:</b> %s%s%s<br>", _("Nick"), args[1], | |
186 irc->whois.ircop ? _(" <i>(ircop)</i>") : "", | |
187 irc->whois.identified ? _(" <i>(identified)</i>") : ""); | |
188 if (irc->whois.away) { | |
189 g_string_append_printf(info, "<b>%s:</b> %s<br>", _("Away"), irc->whois.away); | |
190 g_free(irc->whois.away); | |
191 } | |
192 if (irc->whois.userhost) { | |
193 g_string_append_printf(info, "<b>%s:</b> %s<br>", _("Username"), irc->whois.userhost); | |
194 g_string_append_printf(info, "<b>%s:</b> %s<br>", _("Realname"), irc->whois.name); | |
195 g_free(irc->whois.userhost); | |
196 g_free(irc->whois.name); | |
197 } | |
198 if (irc->whois.server) { | |
199 g_string_append_printf(info, "<b>%s:</b> %s (%s)<br>", _("Server"), irc->whois.server, irc->whois.serverinfo); | |
200 g_free(irc->whois.server); | |
201 g_free(irc->whois.serverinfo); | |
202 } | |
203 if (irc->whois.channels) { | |
204 g_string_append_printf(info, "<b>%s:</b> %s<br>", _("Currently on"), irc->whois.channels); | |
205 g_free(irc->whois.channels); | |
206 } | |
207 if (irc->whois.idle) { | |
6357 | 208 gchar *timex = sec_to_text(irc->whois.idle); |
209 g_string_append_printf(info, _("<b>Idle for:</b> %s<br>"), timex); | |
210 g_free(timex); | |
6333 | 211 g_string_append_printf(info, "<b>%s:</b> %s", _("Online since"), ctime(&irc->whois.signon)); |
212 } | |
213 if (!strcmp(irc->whois.nick, "Paco-Paco")) { | |
214 g_string_append_printf(info, _("<br><b>Defining adjective:</b> Glorious<br>")); | |
215 } | |
216 | |
217 gc = gaim_account_get_connection(irc->account); | |
218 str = g_string_free(info, FALSE); | |
219 g_show_info_text(gc, irc->whois.nick, 2, str, NULL); | |
220 g_free(str); | |
221 memset(&irc->whois, 0, sizeof(irc->whois)); | |
222 } | |
223 | |
224 void irc_msg_topic(struct irc_conn *irc, const char *name, const char *from, char **args) | |
225 { | |
226 char *chan, *topic, *msg, *nick; | |
227 GaimConversation *convo; | |
228 | |
229 if (!strcmp(name, "topic")) { | |
230 chan = args[0]; | |
231 topic = args[1]; | |
232 } else { | |
233 chan = args[1]; | |
234 topic = args[2]; | |
235 } | |
236 | |
237 convo = gaim_find_conversation_with_account(chan, irc->account); | |
238 if (!convo) { | |
239 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a topic for %s, which doesn't exist\n", chan); | |
240 } | |
241 gaim_chat_set_topic(GAIM_CHAT(convo), NULL, topic); | |
242 /* If this is an interactive update, print it out */ | |
243 if (!strcmp(name, "topic")) { | |
244 nick = irc_mask_nick(from); | |
245 msg = g_strdup_printf(_("%s has changed the topic to: %s"), nick, topic); | |
246 g_free(nick); | |
6621 | 247 gaim_chat_write(GAIM_CHAT(convo), from, msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 248 g_free(msg); |
249 } else { | |
250 msg = g_strdup_printf(_("The topic for %s is: %s"), chan, topic); | |
6621 | 251 gaim_chat_write(GAIM_CHAT(convo), "", msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 252 g_free(msg); |
253 } | |
254 } | |
255 | |
256 void irc_msg_unknown(struct irc_conn *irc, const char *name, const char *from, char **args) | |
257 { | |
258 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
259 char *buf; | |
260 | |
261 if (!args || !args[1] || !gc) | |
262 return; | |
263 | |
264 buf = g_strdup_printf(_("Unknown message '%s'"), args[1]); | |
265 gaim_notify_error(gc, _("Unknown message"), buf, _("Gaim has sent a message the IRC server did not understand.")); | |
266 g_free(buf); | |
267 } | |
268 | |
269 void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, char **args) | |
270 { | |
271 char *names, *cur, *end, *tmp, *msg; | |
272 GaimConversation *convo; | |
273 | |
274 if (!strcmp(name, "366")) { | |
275 convo = gaim_find_conversation_with_account(irc->nameconv ? irc->nameconv : args[1], irc->account); | |
276 if (!convo) { | |
277 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a NAMES list for %s, which doesn't exist\n", args[2]); | |
278 g_string_free(irc->names, TRUE); | |
279 irc->names = NULL; | |
280 g_free(irc->nameconv); | |
281 irc->nameconv = NULL; | |
282 return; | |
283 } | |
284 | |
285 names = cur = g_string_free(irc->names, FALSE); | |
286 irc->names = NULL; | |
287 if (irc->nameconv) { | |
288 msg = g_strdup_printf("Users on %s: %s", args[1], names); | |
289 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT) | |
6621 | 290 gaim_chat_write(GAIM_CHAT(convo), "", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 291 else |
6621 | 292 gaim_im_write(GAIM_IM(convo), "", msg, -1, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 293 g_free(msg); |
294 g_free(irc->nameconv); | |
295 irc->nameconv = NULL; | |
296 } else { | |
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
297 GList *users = NULL; |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
298 |
6333 | 299 while (*cur) { |
300 end = strchr(cur, ' '); | |
301 if (!end) | |
302 end = cur + strlen(cur); | |
303 if (*cur == '@' || *cur == '%' || *cur == '+') | |
304 cur++; | |
305 tmp = g_strndup(cur, end - cur); | |
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
306 users = g_list_append(users, tmp); |
6333 | 307 cur = end; |
308 if (*cur) | |
309 cur++; | |
310 } | |
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
311 |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
312 if (users != NULL) { |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
313 GList *l; |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
314 |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
315 gaim_chat_add_users(GAIM_CHAT(convo), users); |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
316 |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
317 for (l = users; l != NULL; l = l->next) |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
318 g_free(l->data); |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
319 |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
320 g_list_free(users); |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
321 } |
6333 | 322 } |
323 g_free(names); | |
324 } else { | |
325 if (!irc->names) | |
326 irc->names = g_string_new(""); | |
327 | |
328 irc->names = g_string_append(irc->names, args[3]); | |
329 } | |
330 } | |
331 | |
332 void irc_msg_motd(struct irc_conn *irc, const char *name, const char *from, char **args) | |
333 { | |
334 GaimConnection *gc; | |
335 if (!strcmp(name, "375")) { | |
336 gc = gaim_account_get_connection(irc->account); | |
337 if (gc) | |
338 gaim_connection_set_display_name(gc, args[0]); | |
339 } | |
340 | |
341 if (!irc->motd) | |
342 irc->motd = g_string_new(""); | |
343 | |
344 g_string_append_printf(irc->motd, "%s<br>", args[1]); | |
345 } | |
346 | |
347 void irc_msg_endmotd(struct irc_conn *irc, const char *name, const char *from, char **args) | |
348 { | |
349 GaimConnection *gc; | |
350 | |
351 gc = gaim_account_get_connection(irc->account); | |
352 if (!gc) | |
353 return; | |
354 | |
355 gaim_connection_set_state(gc, GAIM_CONNECTED); | |
356 | |
357 irc_blist_timeout(irc); | |
358 irc->timer = g_timeout_add(45000, (GSourceFunc)irc_blist_timeout, (gpointer)irc); | |
359 } | |
360 | |
361 void irc_msg_nonick(struct irc_conn *irc, const char *name, const char *from, char **args) | |
362 { | |
363 GaimConnection *gc; | |
364 GaimConversation *convo; | |
365 | |
366 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
367 if (convo) { | |
368 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT) /* does this happen? */ | |
369 gaim_chat_write(GAIM_CHAT(convo), args[1], _("no such channel"), | |
6621 | 370 GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 371 else |
372 gaim_im_write(GAIM_IM(convo), args[1], _("User is not logged in"), -1, | |
6621 | 373 GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 374 } else { |
375 if ((gc = gaim_account_get_connection(irc->account)) == NULL) | |
376 return; | |
377 gaim_notify_error(gc, NULL, _("No such nick or channel"), args[1]); | |
378 } | |
379 | |
380 if (irc->whois.nick && !gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
381 g_free(irc->whois.nick); | |
382 irc->whois.nick = NULL; | |
383 } | |
384 } | |
385 | |
386 void irc_msg_nosend(struct irc_conn *irc, const char *name, const char *from, char **args) | |
387 { | |
388 GaimConnection *gc; | |
389 GaimConversation *convo; | |
390 | |
391 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
392 if (convo) { | |
6621 | 393 gaim_chat_write(GAIM_CHAT(convo), args[1], args[2], GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 394 } else { |
395 if ((gc = gaim_account_get_connection(irc->account)) == NULL) | |
396 return; | |
397 gaim_notify_error(gc, NULL, _("Could not send"), args[2]); | |
398 } | |
399 } | |
400 | |
401 void irc_msg_notinchan(struct irc_conn *irc, const char *name, const char *from, char **args) | |
402 { | |
403 GaimConversation *convo = gaim_find_conversation_with_account(args[1], irc->account); | |
404 | |
405 gaim_debug(GAIM_DEBUG_INFO, "irc", "We're apparently not in %s, but tried to use it\n", args[1]); | |
406 if (convo) { | |
407 /*g_slist_remove(irc->gc->buddy_chats, convo); | |
408 gaim_conversation_set_account(convo, NULL);*/ | |
6621 | 409 gaim_chat_write(GAIM_CHAT(convo), args[1], args[2], GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 410 } |
411 } | |
412 | |
413 void irc_msg_notop(struct irc_conn *irc, const char *name, const char *from, char **args) | |
414 { | |
415 GaimConversation *convo; | |
416 | |
417 if (!args || !args[1] || !args[2]) | |
418 return; | |
419 | |
420 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
421 if (!convo) | |
422 return; | |
423 | |
6621 | 424 gaim_chat_write(GAIM_CHAT(convo), "", args[2], GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 425 } |
426 | |
427 void irc_msg_invite(struct irc_conn *irc, const char *name, const char *from, char **args) | |
428 { | |
429 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
430 GHashTable *components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
431 char *nick = irc_mask_nick(from); | |
432 | |
433 if (!args || !args[1] || !gc) { | |
434 g_free(nick); | |
435 g_hash_table_destroy(components); | |
436 return; | |
437 } | |
438 | |
439 g_hash_table_insert(components, strdup("channel"), strdup(args[1])); | |
440 | |
441 serv_got_chat_invite(gc, args[1], nick, NULL, components); | |
442 g_free(nick); | |
443 } | |
444 | |
445 void irc_msg_inviteonly(struct irc_conn *irc, const char *name, const char *from, char **args) | |
446 { | |
447 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
448 char *buf; | |
449 | |
450 if (!args || !args[1] || !gc) | |
451 return; | |
452 | |
453 buf = g_strdup_printf(_("Joining %s requires an invitation."), args[1]); | |
454 gaim_notify_error(gc, _("Invitation only"), _("Invitation only"), buf); | |
455 g_free(buf); | |
456 } | |
457 | |
458 void irc_msg_ison(struct irc_conn *irc, const char *name, const char *from, char **args) | |
459 { | |
460 char **nicks; | |
461 struct irc_buddy *ib; | |
462 int i; | |
463 | |
464 if (!args || !args[1]) | |
465 return; | |
466 | |
467 nicks = g_strsplit(args[1], " ", -1); | |
468 | |
469 for (i = 0; nicks[i]; i++) { | |
470 if ((ib = g_hash_table_lookup(irc->buddies, (gconstpointer)nicks[i])) == NULL) { | |
471 continue; | |
472 } | |
473 ib->flag = TRUE; | |
474 } | |
475 | |
6350 | 476 g_strfreev(nicks); |
477 | |
6333 | 478 g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_status, (gpointer)irc); |
479 } | |
480 | |
481 static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc) | |
482 { | |
483 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
484 struct buddy *buddy = gaim_find_buddy(irc->account, name); | |
485 | |
486 if (!gc || !buddy) | |
487 return; | |
488 | |
489 if (ib->online && !ib->flag) { | |
490 serv_got_update(gc, buddy->name, 0, 0, 0, 0, 0); | |
491 ib->online = FALSE; | |
492 } | |
493 | |
494 if (!ib->online && ib->flag) { | |
495 serv_got_update(gc, buddy->name, 1, 0, 0, 0, 0); | |
496 ib->online = TRUE; | |
497 } | |
498 } | |
499 | |
500 void irc_msg_join(struct irc_conn *irc, const char *name, const char *from, char **args) | |
501 { | |
502 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
503 GaimConversation *convo; | |
504 char *nick = irc_mask_nick(from), *userhost; | |
505 static int id = 1; | |
506 | |
507 if (!gc) { | |
508 g_free(nick); | |
509 return; | |
510 } | |
511 | |
512 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
513 /* We are joining a channel for the first time */ | |
514 serv_got_joined_chat(gc, id++, args[0]); | |
515 g_free(nick); | |
516 return; | |
517 } | |
518 | |
519 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
520 if (convo == NULL) { | |
521 gaim_debug(GAIM_DEBUG_ERROR, "irc", "JOIN for %s failed\n", args[0]); | |
522 g_free(nick); | |
523 return; | |
524 } | |
525 | |
526 userhost = irc_mask_userhost(from); | |
527 gaim_chat_add_user(GAIM_CHAT(convo), nick, userhost); | |
528 g_free(userhost); | |
529 g_free(nick); | |
530 } | |
531 | |
532 void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char **args) | |
533 { | |
534 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
535 GaimConversation *convo = gaim_find_conversation_with_account(args[0], irc->account); | |
536 char *nick = irc_mask_nick(from), *buf; | |
537 | |
538 if (!gc) { | |
539 g_free(nick); | |
540 return; | |
541 } | |
542 | |
543 if (!convo) { | |
544 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Recieved a KICK for unknown channel %s\n", args[0]); | |
545 g_free(nick); | |
546 return; | |
547 } | |
548 | |
549 if (!gaim_utf8_strcasecmp(gaim_connection_get_display_name(gc), args[1])) { | |
550 buf = g_strdup_printf(_("You have been kicked by %s: (%s)"), nick, args[2]); | |
6621 | 551 gaim_chat_write(GAIM_CHAT(convo), args[0], buf, GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 552 g_free(buf); |
553 /*g_slist_remove(irc->gc->buddy_chats, convo); | |
554 gaim_conversation_set_account(convo, NULL);*/ | |
555 /*g_list_free(gaim_chat_get_users(GAIM_CHAT(convo))); | |
556 gaim_chat_set_users(GAIM_CHAT(convo), NULL);*/ | |
557 } else { | |
558 buf = g_strdup_printf(_("Kicked by %s (%s)"), nick, args[2]); | |
559 gaim_chat_remove_user(GAIM_CHAT(convo), args[1], buf); | |
560 g_free(buf); | |
561 } | |
562 | |
563 g_free(nick); | |
564 return; | |
565 } | |
566 | |
567 void irc_msg_mode(struct irc_conn *irc, const char *name, const char *from, char **args) | |
568 { | |
569 GaimConversation *convo; | |
570 char *nick = irc_mask_nick(from), *buf; | |
571 | |
572 if (*args[0] == '#' || *args[0] == '&') { /* Channel */ | |
573 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
574 if (!convo) { | |
575 gaim_debug(GAIM_DEBUG_ERROR, "irc", "MODE received for %s, which we are not in\n", args[0]); | |
576 g_free(nick); | |
577 return; | |
578 } | |
579 buf = g_strdup_printf(_("mode (%s %s) by %s"), args[1], args[2] ? args[2] : "", nick); | |
6621 | 580 gaim_chat_write(GAIM_CHAT(convo), args[0], buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 581 g_free(buf); |
582 } else { /* User */ | |
583 } | |
584 g_free(nick); | |
585 } | |
586 | |
587 void irc_msg_nick(struct irc_conn *irc, const char *name, const char *from, char **args) | |
588 { | |
589 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
590 GSList *chats; | |
591 char *nick = irc_mask_nick(from); | |
592 | |
593 if (!gc) { | |
594 g_free(nick); | |
595 return; | |
596 } | |
597 chats = gc->buddy_chats; | |
598 | |
599 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
600 gaim_connection_set_display_name(gc, args[0]); | |
601 } | |
602 | |
603 while (chats) { | |
604 GaimChat *chat = GAIM_CHAT(chats->data); | |
605 GList *users = gaim_chat_get_users(chat); | |
606 | |
607 while (users) { | |
608 char *user = users->data; | |
609 | |
610 if (!strcmp(nick, user)) { | |
611 gaim_chat_rename_user(chat, user, args[0]); | |
612 users = gaim_chat_get_users(chat); | |
613 break; | |
614 } | |
615 users = users->next; | |
616 } | |
617 chats = chats->next; | |
618 } | |
619 g_free(nick); | |
620 } | |
621 | |
622 void irc_msg_nickused(struct irc_conn *irc, const char *name, const char *from, char **args) | |
623 { | |
624 char *newnick, *buf, *end; | |
625 | |
626 if (!args || !args[1]) | |
627 return; | |
628 | |
629 newnick = strdup(args[1]); | |
630 end = newnick + strlen(newnick) - 1; | |
631 /* try three fallbacks */ | |
632 if (*end == 2) *end = '3'; | |
633 else if (*end == 1) *end = '2'; | |
634 else *end = '1'; | |
635 | |
636 buf = irc_format(irc, "vn", "NICK", newnick); | |
637 irc_send(irc, buf); | |
638 g_free(buf); | |
639 } | |
640 | |
641 void irc_msg_notice(struct irc_conn *irc, const char *name, const char *from, char **args) | |
642 { | |
643 char *newargs[2]; | |
644 | |
645 newargs[0] = " notice "; /* The spaces are magic, leave 'em in! */ | |
646 newargs[1] = args[1]; | |
647 irc_msg_privmsg(irc, name, from, newargs); | |
648 } | |
649 | |
650 void irc_msg_part(struct irc_conn *irc, const char *name, const char *from, char **args) | |
651 { | |
652 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
653 GaimConversation *convo; | |
654 char *nick, *msg; | |
655 | |
656 if (!args || !args[0] || !args[1] || !gc) | |
657 return; | |
658 | |
659 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
660 if (!convo) { | |
661 gaim_debug(GAIM_DEBUG_INFO, "irc", "Got a PART on %s, which doesn't exist -- probably closed\n", args[0]); | |
662 return; | |
663 } | |
664 | |
665 nick = irc_mask_nick(from); | |
666 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
667 msg = g_strdup_printf(_("You have parted the channel%s%s"), *args[1] ? ": " : "", args[1]); | |
6621 | 668 gaim_chat_write(GAIM_CHAT(convo), args[0], msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 669 g_free(msg); |
670 } else { | |
671 gaim_chat_remove_user(GAIM_CHAT(convo), nick, args[1]); | |
672 } | |
673 g_free(nick); | |
674 } | |
675 | |
676 void irc_msg_ping(struct irc_conn *irc, const char *name, const char *from, char **args) | |
677 { | |
678 char *buf; | |
679 if (!args || !args[0]) | |
680 return; | |
681 | |
682 buf = irc_format(irc, "v:", "PONG", args[0]); | |
683 irc_send(irc, buf); | |
684 g_free(buf); | |
685 } | |
686 | |
687 void irc_msg_pong(struct irc_conn *irc, const char *name, const char *from, char **args) | |
688 { | |
689 GaimConversation *convo; | |
690 GaimConnection *gc; | |
691 char **parts, *msg; | |
692 time_t oldstamp; | |
693 | |
694 if (!args || !args[1]) | |
695 return; | |
696 | |
697 parts = g_strsplit(args[1], " ", 2); | |
698 | |
699 if (!parts[0] || !parts[1]) { | |
700 g_strfreev(parts); | |
701 return; | |
702 } | |
703 | |
704 if (sscanf(parts[1], "%lu", &oldstamp) != 1) { | |
705 msg = g_strdup(_("Error: invalid PONG from server")); | |
706 } else { | |
6350 | 707 msg = g_strdup_printf(_("PING reply -- Lag: %lu seconds"), time(NULL) - oldstamp); |
6333 | 708 } |
709 | |
710 convo = gaim_find_conversation_with_account(parts[0], irc->account); | |
711 g_strfreev(parts); | |
712 if (convo) { | |
713 if (gaim_conversation_get_type (convo) == GAIM_CONV_CHAT) | |
6621 | 714 gaim_chat_write(GAIM_CHAT(convo), "PONG", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 715 else |
6621 | 716 gaim_im_write(GAIM_IM(convo), "PONG", msg, -1, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 717 } else { |
718 gc = gaim_account_get_connection(irc->account); | |
719 if (!gc) { | |
720 g_free(msg); | |
721 return; | |
722 } | |
723 gaim_notify_info(gc, NULL, "PONG", msg); | |
724 } | |
725 g_free(msg); | |
726 } | |
727 | |
728 void irc_msg_privmsg(struct irc_conn *irc, const char *name, const char *from, char **args) | |
729 { | |
730 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
731 GaimConversation *convo; | |
732 char *nick = irc_mask_nick(from), *tmp, *msg; | |
733 int notice = 0; | |
734 | |
735 if (!args || !args[0] || !args[1] || !gc) { | |
736 g_free(nick); | |
737 return; | |
738 } | |
739 | |
740 notice = !strcmp(args[0], " notice "); | |
741 tmp = irc_parse_ctcp(irc, nick, args[0], args[1], notice); | |
742 if (!tmp) { | |
743 g_free(nick); | |
744 return; | |
745 } | |
746 msg = irc_mirc2html(tmp); | |
747 g_free(tmp); | |
748 if (notice) { | |
749 tmp = g_strdup_printf("(notice) %s", msg); | |
750 g_free(msg); | |
751 msg = tmp; | |
752 } | |
753 | |
754 if (!gaim_utf8_strcasecmp(args[0], gaim_connection_get_display_name(gc))) { | |
755 serv_got_im(gc, nick, msg, 0, time(NULL), -1); | |
756 } else if (notice) { | |
757 serv_got_im(gc, nick, msg, 0, time(NULL), -1); | |
758 } else { | |
759 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
760 if (convo) | |
761 serv_got_chat_in(gc, gaim_chat_get_id(GAIM_CHAT(convo)), nick, 0, msg, time(NULL)); | |
762 else | |
763 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a PRIVMSG on %s, which does not exist\n", args[0]); | |
764 } | |
765 g_free(msg); | |
766 g_free(nick); | |
767 } | |
768 | |
769 void irc_msg_quit(struct irc_conn *irc, const char *name, const char *from, char **args) | |
770 { | |
771 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
772 char *data[2]; | |
773 | |
774 if (!args || !args[0] || !gc) | |
775 return; | |
776 | |
777 data[0] = irc_mask_nick(from); | |
778 data[1] = args[0]; | |
779 /* XXX this should have an API, I shouldn't grab this directly */ | |
780 g_slist_foreach(gc->buddy_chats, (GFunc)irc_chat_remove_buddy, data); | |
781 g_free(data[0]); | |
782 | |
783 return; | |
784 } | |
785 | |
786 void irc_msg_wallops(struct irc_conn *irc, const char *name, const char *from, char **args) | |
787 { | |
788 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
789 char *nick, *msg; | |
790 | |
791 if (!args || !args[0] || !gc) | |
792 return; | |
793 | |
794 nick = irc_mask_nick(from); | |
795 msg = g_strdup_printf (_("Wallops from %s"), nick); | |
796 g_free(nick); | |
797 gaim_notify_info(gc, NULL, msg, args[0]); | |
798 g_free(msg); | |
799 } | |
800 | |
801 void irc_msg_ignore(struct irc_conn *irc, const char *name, const char *from, char **args) | |
802 { | |
803 return; | |
804 } |