Mercurial > pidgin.yaz
annotate src/protocols/irc/msgs.c @ 8273:f24172f53650
[gaim-migrate @ 8997]
This is Scott Lamb's eventloop abstraction patch. If it breaks things,
Scott Lamb will be glad to take the punishment. If it doesn't, it should
make integration into other event loops easier. Well, no, not easier,
harder actually, but it'll be done more appropriately and less hackily..
er, hacky. Is hackily a word?
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Tue, 17 Feb 2004 02:17:48 +0000 |
parents | 1d86096ae0f4 |
children | 534b479692d0 |
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 #include "conversation.h" | |
26 #include "blist.h" | |
27 #include "notify.h" | |
28 #include "util.h" | |
29 #include "debug.h" | |
30 #include "irc.h" | |
31 | |
32 #include <stdio.h> | |
33 | |
34 static char *irc_mask_nick(const char *mask); | |
35 static char *irc_mask_userhost(const char *mask); | |
36 static void irc_chat_remove_buddy(GaimConversation *convo, char *data[2]); | |
37 static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc); | |
38 | |
39 static char *irc_mask_nick(const char *mask) | |
40 { | |
41 char *end, *buf; | |
42 | |
43 end = strchr(mask, '!'); | |
44 if (!end) | |
45 buf = g_strdup(mask); | |
46 else | |
47 buf = g_strndup(mask, end - mask); | |
48 | |
49 return buf; | |
50 } | |
51 | |
52 static char *irc_mask_userhost(const char *mask) | |
53 { | |
54 return g_strdup(strchr(mask, '!') + 1); | |
55 } | |
56 | |
57 static void irc_chat_remove_buddy(GaimConversation *convo, char *data[2]) | |
58 { | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
59 GList *users = gaim_conv_chat_get_users(GAIM_CONV_CHAT(convo)); |
6333 | 60 char *message = g_strdup_printf("quit: %s", data[1]); |
61 | |
62 if (g_list_find_custom(users, data[0], (GCompareFunc)(strcmp))) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
63 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), data[0], message); |
6333 | 64 |
65 g_free(message); | |
66 } | |
67 | |
68 void irc_msg_default(struct irc_conn *irc, const char *name, const char *from, char **args) | |
69 { | |
70 gaim_debug(GAIM_DEBUG_INFO, "irc", "Unrecognized message: %s\n", args[0]); | |
71 } | |
72 | |
73 void irc_msg_away(struct irc_conn *irc, const char *name, const char *from, char **args) | |
74 { | |
75 GaimConnection *gc; | |
76 | |
77 if (!args || !args[1]) | |
78 return; | |
79 | |
80 if (irc->whois.nick && !gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
81 /* We're doing a whois, show this in the whois dialog */ | |
82 irc_msg_whois(irc, name, from, args); | |
83 return; | |
84 } | |
85 | |
86 gc = gaim_account_get_connection(irc->account); | |
87 if (gc) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
88 serv_got_im(gc, args[1], args[2], GAIM_CONV_IM_AUTO_RESP, time(NULL)); |
6333 | 89 } |
90 | |
91 void irc_msg_badmode(struct irc_conn *irc, const char *name, const char *from, char **args) | |
92 { | |
93 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
94 | |
95 if (!args || !args[1] || !gc) | |
96 return; | |
97 | |
98 gaim_notify_error(gc, NULL, _("Bad mode"), args[1]); | |
99 } | |
100 | |
101 void irc_msg_banned(struct irc_conn *irc, const char *name, const char *from, char **args) | |
102 { | |
103 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
104 char *buf; | |
105 | |
106 if (!args || !args[1] || !gc) | |
107 return; | |
108 | |
109 buf = g_strdup_printf(_("You are banned from %s."), args[1]); | |
110 gaim_notify_error(gc, _("Banned"), _("Banned"), buf); | |
111 g_free(buf); | |
112 } | |
113 | |
114 void irc_msg_chanmode(struct irc_conn *irc, const char *name, const char *from, char **args) | |
115 { | |
116 GaimConversation *convo; | |
117 char *buf; | |
118 | |
119 if (!args || !args[1] || !args[2]) | |
120 return; | |
121 | |
122 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
123 if (!convo) /* XXX punt on channels we are not in for now */ | |
124 return; | |
125 | |
126 buf = g_strdup_printf("mode for %s: %s %s", args[1], args[2], args[3] ? args[3] : ""); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
127 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), "", buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 128 g_free(buf); |
129 | |
130 return; | |
131 } | |
132 | |
133 void irc_msg_whois(struct irc_conn *irc, const char *name, const char *from, char **args) | |
134 { | |
135 if (!irc->whois.nick) { | |
136 gaim_debug(GAIM_DEBUG_WARNING, "irc", "Unexpected WHOIS reply for %s\n", args[1]); | |
137 return; | |
138 } | |
139 | |
140 if (gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
141 gaim_debug(GAIM_DEBUG_WARNING, "irc", "Got WHOIS reply for %s while waiting for %s\n", args[1], irc->whois.nick); | |
142 return; | |
143 } | |
144 | |
145 if (!strcmp(name, "301")) { | |
146 irc->whois.away = g_strdup(args[2]); | |
147 } else if (!strcmp(name, "311")) { | |
148 irc->whois.userhost = g_strdup_printf("%s@%s", args[2], args[3]); | |
149 irc->whois.name = g_strdup(args[5]); | |
150 } else if (!strcmp(name, "312")) { | |
151 irc->whois.server = g_strdup(args[2]); | |
152 irc->whois.serverinfo = g_strdup(args[3]); | |
153 } else if (!strcmp(name, "313")) { | |
154 irc->whois.ircop = 1; | |
155 } else if (!strcmp(name, "317")) { | |
156 irc->whois.idle = atoi(args[2]); | |
157 if (args[3]) | |
158 irc->whois.signon = (time_t)atoi(args[3]); | |
159 } else if (!strcmp(name, "319")) { | |
160 irc->whois.channels = g_strdup(args[2]); | |
161 } else if (!strcmp(name, "320")) { | |
162 irc->whois.identified = 1; | |
163 } | |
164 } | |
165 | |
166 void irc_msg_endwhois(struct irc_conn *irc, const char *name, const char *from, char **args) | |
167 { | |
168 GaimConnection *gc; | |
169 GString *info; | |
7062
86ed8b2aa665
[gaim-migrate @ 7626]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
170 char buffer[256]; |
6333 | 171 char *str; |
172 | |
173 if (!irc->whois.nick) { | |
174 gaim_debug(GAIM_DEBUG_WARNING, "irc", "Unexpected End of WHOIS for %s\n", args[1]); | |
175 return; | |
176 } | |
177 if (gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
178 gaim_debug(GAIM_DEBUG_WARNING, "irc", "Received end of WHOIS for %s, expecting %s\n", args[1], irc->whois.nick); | |
179 return; | |
180 } | |
181 | |
182 info = g_string_new(""); | |
183 g_string_append_printf(info, "<b>%s:</b> %s%s%s<br>", _("Nick"), args[1], | |
184 irc->whois.ircop ? _(" <i>(ircop)</i>") : "", | |
185 irc->whois.identified ? _(" <i>(identified)</i>") : ""); | |
186 if (irc->whois.away) { | |
187 g_string_append_printf(info, "<b>%s:</b> %s<br>", _("Away"), irc->whois.away); | |
188 g_free(irc->whois.away); | |
189 } | |
190 if (irc->whois.userhost) { | |
191 g_string_append_printf(info, "<b>%s:</b> %s<br>", _("Username"), irc->whois.userhost); | |
192 g_string_append_printf(info, "<b>%s:</b> %s<br>", _("Realname"), irc->whois.name); | |
193 g_free(irc->whois.userhost); | |
194 g_free(irc->whois.name); | |
195 } | |
196 if (irc->whois.server) { | |
197 g_string_append_printf(info, "<b>%s:</b> %s (%s)<br>", _("Server"), irc->whois.server, irc->whois.serverinfo); | |
198 g_free(irc->whois.server); | |
199 g_free(irc->whois.serverinfo); | |
200 } | |
201 if (irc->whois.channels) { | |
202 g_string_append_printf(info, "<b>%s:</b> %s<br>", _("Currently on"), irc->whois.channels); | |
203 g_free(irc->whois.channels); | |
204 } | |
205 if (irc->whois.idle) { | |
7108
6faeeecab0dc
[gaim-migrate @ 7673]
Christian Hammond <chipx86@chipx86.com>
parents:
7062
diff
changeset
|
206 gchar *timex = gaim_str_seconds_to_string(irc->whois.idle); |
6357 | 207 g_string_append_printf(info, _("<b>Idle for:</b> %s<br>"), timex); |
208 g_free(timex); | |
6333 | 209 g_string_append_printf(info, "<b>%s:</b> %s", _("Online since"), ctime(&irc->whois.signon)); |
210 } | |
211 if (!strcmp(irc->whois.nick, "Paco-Paco")) { | |
212 g_string_append_printf(info, _("<br><b>Defining adjective:</b> Glorious<br>")); | |
213 } | |
214 | |
215 gc = gaim_account_get_connection(irc->account); | |
216 str = g_string_free(info, FALSE); | |
7062
86ed8b2aa665
[gaim-migrate @ 7626]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
217 |
86ed8b2aa665
[gaim-migrate @ 7626]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
218 g_snprintf(buffer, sizeof(buffer), |
86ed8b2aa665
[gaim-migrate @ 7626]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
219 _("Buddy Information for %s"), irc->whois.nick); |
86ed8b2aa665
[gaim-migrate @ 7626]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
220 gaim_notify_formatted(gc, NULL, buffer, NULL, str, NULL, NULL); |
86ed8b2aa665
[gaim-migrate @ 7626]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
221 |
6333 | 222 g_free(str); |
223 memset(&irc->whois, 0, sizeof(irc->whois)); | |
224 } | |
225 | |
8114 | 226 void irc_msg_list(struct irc_conn *irc, const char *name, const char *from, char **args) |
227 { | |
228 if (!irc->roomlist) | |
229 return; | |
230 | |
231 if (!strcmp(name, "321")) { | |
232 gaim_roomlist_set_in_progress(irc->roomlist, TRUE); | |
233 return; | |
234 } | |
235 | |
236 if (!strcmp(name, "323")) { | |
237 gaim_roomlist_set_in_progress(irc->roomlist, FALSE); | |
238 gaim_roomlist_unref(irc->roomlist); | |
239 irc->roomlist = NULL; | |
240 } | |
241 | |
242 if (!strcmp(name, "322")) { | |
243 GaimRoomlistRoom *room; | |
244 | |
245 if (!args[0] || !args[1] || !args[2] || !args[3]) | |
246 return; | |
247 | |
248 room = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_ROOM, args[1], NULL); | |
249 gaim_roomlist_room_add_field(irc->roomlist, room, args[1]); | |
250 gaim_roomlist_room_add_field(irc->roomlist, room, GINT_TO_POINTER(strtol(args[2], NULL, 10))); | |
251 gaim_roomlist_room_add_field(irc->roomlist, room, args[3]); | |
252 gaim_roomlist_room_add(irc->roomlist, room); | |
253 } | |
254 } | |
255 | |
6333 | 256 void irc_msg_topic(struct irc_conn *irc, const char *name, const char *from, char **args) |
257 { | |
258 char *chan, *topic, *msg, *nick; | |
259 GaimConversation *convo; | |
260 | |
261 if (!strcmp(name, "topic")) { | |
262 chan = args[0]; | |
263 topic = args[1]; | |
264 } else { | |
265 chan = args[1]; | |
266 topic = args[2]; | |
267 } | |
268 | |
269 convo = gaim_find_conversation_with_account(chan, irc->account); | |
270 if (!convo) { | |
271 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a topic for %s, which doesn't exist\n", chan); | |
272 } | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
273 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(convo), NULL, topic); |
6333 | 274 /* If this is an interactive update, print it out */ |
275 if (!strcmp(name, "topic")) { | |
276 nick = irc_mask_nick(from); | |
277 msg = g_strdup_printf(_("%s has changed the topic to: %s"), nick, topic); | |
278 g_free(nick); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
279 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), from, msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 280 g_free(msg); |
281 } else { | |
282 msg = g_strdup_printf(_("The topic for %s is: %s"), chan, topic); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
283 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), "", msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 284 g_free(msg); |
285 } | |
286 } | |
287 | |
288 void irc_msg_unknown(struct irc_conn *irc, const char *name, const char *from, char **args) | |
289 { | |
290 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
291 char *buf; | |
292 | |
293 if (!args || !args[1] || !gc) | |
294 return; | |
295 | |
296 buf = g_strdup_printf(_("Unknown message '%s'"), args[1]); | |
297 gaim_notify_error(gc, _("Unknown message"), buf, _("Gaim has sent a message the IRC server did not understand.")); | |
298 g_free(buf); | |
299 } | |
300 | |
301 void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, char **args) | |
302 { | |
303 char *names, *cur, *end, *tmp, *msg; | |
304 GaimConversation *convo; | |
305 | |
306 if (!strcmp(name, "366")) { | |
307 convo = gaim_find_conversation_with_account(irc->nameconv ? irc->nameconv : args[1], irc->account); | |
308 if (!convo) { | |
309 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a NAMES list for %s, which doesn't exist\n", args[2]); | |
310 g_string_free(irc->names, TRUE); | |
311 irc->names = NULL; | |
312 g_free(irc->nameconv); | |
313 irc->nameconv = NULL; | |
314 return; | |
315 } | |
316 | |
317 names = cur = g_string_free(irc->names, FALSE); | |
318 irc->names = NULL; | |
319 if (irc->nameconv) { | |
320 msg = g_strdup_printf("Users on %s: %s", args[1], names); | |
321 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
322 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), "", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 323 else |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
324 gaim_conv_im_write(GAIM_CONV_IM(convo), "", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 325 g_free(msg); |
326 g_free(irc->nameconv); | |
327 irc->nameconv = NULL; | |
328 } else { | |
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
329 GList *users = NULL; |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
330 |
6333 | 331 while (*cur) { |
332 end = strchr(cur, ' '); | |
333 if (!end) | |
334 end = cur + strlen(cur); | |
335 if (*cur == '@' || *cur == '%' || *cur == '+') | |
336 cur++; | |
337 tmp = g_strndup(cur, end - cur); | |
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
338 users = g_list_append(users, tmp); |
6333 | 339 cur = end; |
340 if (*cur) | |
341 cur++; | |
342 } | |
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
343 |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
344 if (users != NULL) { |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
345 GList *l; |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
346 |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
347 gaim_conv_chat_add_users(GAIM_CONV_CHAT(convo), users); |
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
348 |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
349 for (l = users; l != NULL; l = l->next) |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
350 g_free(l->data); |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
351 |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
352 g_list_free(users); |
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
353 } |
6333 | 354 } |
355 g_free(names); | |
356 } else { | |
357 if (!irc->names) | |
358 irc->names = g_string_new(""); | |
359 | |
360 irc->names = g_string_append(irc->names, args[3]); | |
361 } | |
362 } | |
363 | |
364 void irc_msg_motd(struct irc_conn *irc, const char *name, const char *from, char **args) | |
365 { | |
366 GaimConnection *gc; | |
367 if (!strcmp(name, "375")) { | |
368 gc = gaim_account_get_connection(irc->account); | |
369 if (gc) | |
370 gaim_connection_set_display_name(gc, args[0]); | |
371 } | |
372 | |
373 if (!irc->motd) | |
374 irc->motd = g_string_new(""); | |
375 | |
376 g_string_append_printf(irc->motd, "%s<br>", args[1]); | |
377 } | |
378 | |
379 void irc_msg_endmotd(struct irc_conn *irc, const char *name, const char *from, char **args) | |
380 { | |
381 GaimConnection *gc; | |
382 | |
383 gc = gaim_account_get_connection(irc->account); | |
384 if (!gc) | |
385 return; | |
386 | |
387 gaim_connection_set_state(gc, GAIM_CONNECTED); | |
388 | |
389 irc_blist_timeout(irc); | |
8273
f24172f53650
[gaim-migrate @ 8997]
Christian Hammond <chipx86@chipx86.com>
parents:
8256
diff
changeset
|
390 irc->timer = gaim_timeout_add(45000, (GSourceFunc)irc_blist_timeout, (gpointer)irc); |
6333 | 391 } |
392 | |
7877 | 393 void irc_msg_nochan(struct irc_conn *irc, const char *name, const char *from, char **args) |
394 { | |
395 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
396 | |
397 if (gc == NULL || args == NULL || args[1] == NULL) | |
398 return; | |
399 | |
400 gaim_notify_error(gc, NULL, _("No such channel"), args[1]); | |
401 } | |
402 | |
6333 | 403 void irc_msg_nonick(struct irc_conn *irc, const char *name, const char *from, char **args) |
404 { | |
405 GaimConnection *gc; | |
406 GaimConversation *convo; | |
407 | |
408 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
409 if (convo) { | |
410 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT) /* does this happen? */ | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
411 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[1], _("no such channel"), |
6621 | 412 GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 413 else |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
414 gaim_conv_im_write(GAIM_CONV_IM(convo), args[1], _("User is not logged in"), |
6621 | 415 GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 416 } else { |
417 if ((gc = gaim_account_get_connection(irc->account)) == NULL) | |
418 return; | |
419 gaim_notify_error(gc, NULL, _("No such nick or channel"), args[1]); | |
420 } | |
421 | |
422 if (irc->whois.nick && !gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
423 g_free(irc->whois.nick); | |
424 irc->whois.nick = NULL; | |
425 } | |
426 } | |
427 | |
428 void irc_msg_nosend(struct irc_conn *irc, const char *name, const char *from, char **args) | |
429 { | |
430 GaimConnection *gc; | |
431 GaimConversation *convo; | |
432 | |
433 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
434 if (convo) { | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
435 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[1], args[2], GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 436 } else { |
437 if ((gc = gaim_account_get_connection(irc->account)) == NULL) | |
438 return; | |
439 gaim_notify_error(gc, NULL, _("Could not send"), args[2]); | |
440 } | |
441 } | |
442 | |
443 void irc_msg_notinchan(struct irc_conn *irc, const char *name, const char *from, char **args) | |
444 { | |
445 GaimConversation *convo = gaim_find_conversation_with_account(args[1], irc->account); | |
446 | |
447 gaim_debug(GAIM_DEBUG_INFO, "irc", "We're apparently not in %s, but tried to use it\n", args[1]); | |
448 if (convo) { | |
449 /*g_slist_remove(irc->gc->buddy_chats, convo); | |
450 gaim_conversation_set_account(convo, NULL);*/ | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
451 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[1], args[2], GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 452 } |
453 } | |
454 | |
455 void irc_msg_notop(struct irc_conn *irc, const char *name, const char *from, char **args) | |
456 { | |
457 GaimConversation *convo; | |
458 | |
459 if (!args || !args[1] || !args[2]) | |
460 return; | |
461 | |
462 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
463 if (!convo) | |
464 return; | |
465 | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
466 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), "", args[2], GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 467 } |
468 | |
469 void irc_msg_invite(struct irc_conn *irc, const char *name, const char *from, char **args) | |
470 { | |
471 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
472 GHashTable *components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
473 char *nick = irc_mask_nick(from); | |
474 | |
475 if (!args || !args[1] || !gc) { | |
476 g_free(nick); | |
477 g_hash_table_destroy(components); | |
478 return; | |
479 } | |
480 | |
481 g_hash_table_insert(components, strdup("channel"), strdup(args[1])); | |
482 | |
483 serv_got_chat_invite(gc, args[1], nick, NULL, components); | |
484 g_free(nick); | |
485 } | |
486 | |
487 void irc_msg_inviteonly(struct irc_conn *irc, const char *name, const char *from, char **args) | |
488 { | |
489 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
490 char *buf; | |
491 | |
492 if (!args || !args[1] || !gc) | |
493 return; | |
494 | |
495 buf = g_strdup_printf(_("Joining %s requires an invitation."), args[1]); | |
496 gaim_notify_error(gc, _("Invitation only"), _("Invitation only"), buf); | |
497 g_free(buf); | |
498 } | |
499 | |
500 void irc_msg_ison(struct irc_conn *irc, const char *name, const char *from, char **args) | |
501 { | |
502 char **nicks; | |
503 struct irc_buddy *ib; | |
504 int i; | |
505 | |
506 if (!args || !args[1]) | |
507 return; | |
508 | |
509 nicks = g_strsplit(args[1], " ", -1); | |
510 | |
511 for (i = 0; nicks[i]; i++) { | |
512 if ((ib = g_hash_table_lookup(irc->buddies, (gconstpointer)nicks[i])) == NULL) { | |
513 continue; | |
514 } | |
515 ib->flag = TRUE; | |
516 } | |
517 | |
6350 | 518 g_strfreev(nicks); |
519 | |
6333 | 520 g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_status, (gpointer)irc); |
521 } | |
522 | |
523 static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc) | |
524 { | |
525 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
6695 | 526 GaimBuddy *buddy = gaim_find_buddy(irc->account, name); |
6333 | 527 |
528 if (!gc || !buddy) | |
529 return; | |
530 | |
531 if (ib->online && !ib->flag) { | |
532 serv_got_update(gc, buddy->name, 0, 0, 0, 0, 0); | |
533 ib->online = FALSE; | |
534 } | |
535 | |
536 if (!ib->online && ib->flag) { | |
537 serv_got_update(gc, buddy->name, 1, 0, 0, 0, 0); | |
538 ib->online = TRUE; | |
539 } | |
540 } | |
541 | |
542 void irc_msg_join(struct irc_conn *irc, const char *name, const char *from, char **args) | |
543 { | |
544 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
545 GaimConversation *convo; | |
546 char *nick = irc_mask_nick(from), *userhost; | |
547 static int id = 1; | |
548 | |
549 if (!gc) { | |
550 g_free(nick); | |
551 return; | |
552 } | |
553 | |
554 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
555 /* We are joining a channel for the first time */ | |
556 serv_got_joined_chat(gc, id++, args[0]); | |
557 g_free(nick); | |
558 return; | |
559 } | |
560 | |
561 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
562 if (convo == NULL) { | |
563 gaim_debug(GAIM_DEBUG_ERROR, "irc", "JOIN for %s failed\n", args[0]); | |
564 g_free(nick); | |
565 return; | |
566 } | |
567 | |
568 userhost = irc_mask_userhost(from); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
569 gaim_conv_chat_add_user(GAIM_CONV_CHAT(convo), nick, userhost); |
6333 | 570 g_free(userhost); |
571 g_free(nick); | |
572 } | |
573 | |
574 void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char **args) | |
575 { | |
576 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
577 GaimConversation *convo = gaim_find_conversation_with_account(args[0], irc->account); | |
578 char *nick = irc_mask_nick(from), *buf; | |
579 | |
580 if (!gc) { | |
581 g_free(nick); | |
582 return; | |
583 } | |
584 | |
585 if (!convo) { | |
586 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Recieved a KICK for unknown channel %s\n", args[0]); | |
587 g_free(nick); | |
588 return; | |
589 } | |
590 | |
591 if (!gaim_utf8_strcasecmp(gaim_connection_get_display_name(gc), args[1])) { | |
592 buf = g_strdup_printf(_("You have been kicked by %s: (%s)"), nick, args[2]); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
593 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[0], buf, GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 594 g_free(buf); |
8256
1d86096ae0f4
[gaim-migrate @ 8979]
Christian Hammond <chipx86@chipx86.com>
parents:
8186
diff
changeset
|
595 serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo))); |
6333 | 596 } else { |
597 buf = g_strdup_printf(_("Kicked by %s (%s)"), nick, args[2]); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
598 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), args[1], buf); |
6333 | 599 g_free(buf); |
600 } | |
601 | |
602 g_free(nick); | |
603 return; | |
604 } | |
605 | |
606 void irc_msg_mode(struct irc_conn *irc, const char *name, const char *from, char **args) | |
607 { | |
608 GaimConversation *convo; | |
609 char *nick = irc_mask_nick(from), *buf; | |
610 | |
611 if (*args[0] == '#' || *args[0] == '&') { /* Channel */ | |
612 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
613 if (!convo) { | |
614 gaim_debug(GAIM_DEBUG_ERROR, "irc", "MODE received for %s, which we are not in\n", args[0]); | |
615 g_free(nick); | |
616 return; | |
617 } | |
618 buf = g_strdup_printf(_("mode (%s %s) by %s"), args[1], args[2] ? args[2] : "", nick); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
619 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[0], buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 620 g_free(buf); |
621 } else { /* User */ | |
622 } | |
623 g_free(nick); | |
624 } | |
625 | |
626 void irc_msg_nick(struct irc_conn *irc, const char *name, const char *from, char **args) | |
627 { | |
628 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
629 GSList *chats; | |
630 char *nick = irc_mask_nick(from); | |
631 | |
632 if (!gc) { | |
633 g_free(nick); | |
634 return; | |
635 } | |
636 chats = gc->buddy_chats; | |
637 | |
638 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
639 gaim_connection_set_display_name(gc, args[0]); | |
640 } | |
641 | |
642 while (chats) { | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
643 GaimConvChat *chat = GAIM_CONV_CHAT(chats->data); |
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
644 GList *users = gaim_conv_chat_get_users(chat); |
6333 | 645 |
646 while (users) { | |
647 char *user = users->data; | |
648 | |
649 if (!strcmp(nick, user)) { | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
650 gaim_conv_chat_rename_user(chat, user, args[0]); |
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
651 users = gaim_conv_chat_get_users(chat); |
6333 | 652 break; |
653 } | |
654 users = users->next; | |
655 } | |
656 chats = chats->next; | |
657 } | |
658 g_free(nick); | |
659 } | |
660 | |
661 void irc_msg_nickused(struct irc_conn *irc, const char *name, const char *from, char **args) | |
662 { | |
663 char *newnick, *buf, *end; | |
664 | |
665 if (!args || !args[1]) | |
666 return; | |
667 | |
668 newnick = strdup(args[1]); | |
669 end = newnick + strlen(newnick) - 1; | |
670 /* try three fallbacks */ | |
671 if (*end == 2) *end = '3'; | |
672 else if (*end == 1) *end = '2'; | |
673 else *end = '1'; | |
674 | |
675 buf = irc_format(irc, "vn", "NICK", newnick); | |
676 irc_send(irc, buf); | |
677 g_free(buf); | |
678 } | |
679 | |
680 void irc_msg_notice(struct irc_conn *irc, const char *name, const char *from, char **args) | |
681 { | |
682 char *newargs[2]; | |
683 | |
684 newargs[0] = " notice "; /* The spaces are magic, leave 'em in! */ | |
685 newargs[1] = args[1]; | |
686 irc_msg_privmsg(irc, name, from, newargs); | |
687 } | |
688 | |
6718 | 689 void irc_msg_nochangenick(struct irc_conn *irc, const char *name, const char *from, char **args) |
690 { | |
691 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
692 char *msg; | |
693 | |
6753 | 694 if (!args || !args[2] || !gc) |
6718 | 695 return; |
696 | |
6753 | 697 msg = g_strdup_printf(_("Could not change nick")); |
6718 | 698 gaim_notify_error(gc, _("Cannot change nick"), msg, args[2]); |
699 g_free(msg); | |
700 } | |
701 | |
6333 | 702 void irc_msg_part(struct irc_conn *irc, const char *name, const char *from, char **args) |
703 { | |
704 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
705 GaimConversation *convo; | |
706 char *nick, *msg; | |
707 | |
8186 | 708 if (!args || !args[0] || !gc) |
6333 | 709 return; |
710 | |
711 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
712 if (!convo) { | |
713 gaim_debug(GAIM_DEBUG_INFO, "irc", "Got a PART on %s, which doesn't exist -- probably closed\n", args[0]); | |
714 return; | |
715 } | |
716 | |
717 nick = irc_mask_nick(from); | |
718 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
8186 | 719 msg = g_strdup_printf(_("You have parted the channel%s%s"), |
720 (args[1] && *args[1]) ? ": " : "", args[1]); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
721 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[0], msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
6333 | 722 g_free(msg); |
8256
1d86096ae0f4
[gaim-migrate @ 8979]
Christian Hammond <chipx86@chipx86.com>
parents:
8186
diff
changeset
|
723 serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo))); |
6333 | 724 } else { |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
725 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), nick, args[1]); |
6333 | 726 } |
727 g_free(nick); | |
728 } | |
729 | |
730 void irc_msg_ping(struct irc_conn *irc, const char *name, const char *from, char **args) | |
731 { | |
732 char *buf; | |
733 if (!args || !args[0]) | |
734 return; | |
735 | |
736 buf = irc_format(irc, "v:", "PONG", args[0]); | |
737 irc_send(irc, buf); | |
738 g_free(buf); | |
739 } | |
740 | |
741 void irc_msg_pong(struct irc_conn *irc, const char *name, const char *from, char **args) | |
742 { | |
743 GaimConversation *convo; | |
744 GaimConnection *gc; | |
745 char **parts, *msg; | |
746 time_t oldstamp; | |
747 | |
748 if (!args || !args[1]) | |
749 return; | |
750 | |
751 parts = g_strsplit(args[1], " ", 2); | |
752 | |
753 if (!parts[0] || !parts[1]) { | |
754 g_strfreev(parts); | |
755 return; | |
756 } | |
757 | |
758 if (sscanf(parts[1], "%lu", &oldstamp) != 1) { | |
759 msg = g_strdup(_("Error: invalid PONG from server")); | |
760 } else { | |
6350 | 761 msg = g_strdup_printf(_("PING reply -- Lag: %lu seconds"), time(NULL) - oldstamp); |
6333 | 762 } |
763 | |
764 convo = gaim_find_conversation_with_account(parts[0], irc->account); | |
765 g_strfreev(parts); | |
766 if (convo) { | |
767 if (gaim_conversation_get_type (convo) == GAIM_CONV_CHAT) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
768 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), "PONG", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 769 else |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
770 gaim_conv_im_write(GAIM_CONV_IM(convo), "PONG", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
6333 | 771 } else { |
772 gc = gaim_account_get_connection(irc->account); | |
773 if (!gc) { | |
774 g_free(msg); | |
775 return; | |
776 } | |
777 gaim_notify_info(gc, NULL, "PONG", msg); | |
778 } | |
779 g_free(msg); | |
780 } | |
781 | |
782 void irc_msg_privmsg(struct irc_conn *irc, const char *name, const char *from, char **args) | |
783 { | |
784 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
785 GaimConversation *convo; | |
786 char *nick = irc_mask_nick(from), *tmp, *msg; | |
787 int notice = 0; | |
788 | |
789 if (!args || !args[0] || !args[1] || !gc) { | |
790 g_free(nick); | |
791 return; | |
792 } | |
793 | |
794 notice = !strcmp(args[0], " notice "); | |
795 tmp = irc_parse_ctcp(irc, nick, args[0], args[1], notice); | |
796 if (!tmp) { | |
797 g_free(nick); | |
798 return; | |
799 } | |
8163 | 800 |
801 msg = gaim_escape_html(tmp); | |
6333 | 802 g_free(tmp); |
8163 | 803 |
804 tmp = irc_mirc2html(msg); | |
805 g_free(msg); | |
806 msg = tmp; | |
6333 | 807 if (notice) { |
808 tmp = g_strdup_printf("(notice) %s", msg); | |
809 g_free(msg); | |
810 msg = tmp; | |
811 } | |
812 | |
813 if (!gaim_utf8_strcasecmp(args[0], gaim_connection_get_display_name(gc))) { | |
6982 | 814 serv_got_im(gc, nick, msg, 0, time(NULL)); |
6333 | 815 } else if (notice) { |
6982 | 816 serv_got_im(gc, nick, msg, 0, time(NULL)); |
6333 | 817 } else { |
818 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
819 if (convo) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7108
diff
changeset
|
820 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo)), nick, 0, msg, time(NULL)); |
6333 | 821 else |
822 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a PRIVMSG on %s, which does not exist\n", args[0]); | |
823 } | |
824 g_free(msg); | |
825 g_free(nick); | |
826 } | |
827 | |
6714 | 828 void irc_msg_regonly(struct irc_conn *irc, const char *name, const char *from, char **args) |
829 { | |
830 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
831 char *msg; | |
832 | |
833 if (!args || !args[1] || !args[2] || !gc) | |
834 return; | |
835 | |
836 msg = g_strdup_printf(_("Cannot join %s:"), args[1]); | |
837 gaim_notify_error(gc, _("Cannot join channel"), msg, args[2]); | |
838 g_free(msg); | |
839 } | |
840 | |
6333 | 841 void irc_msg_quit(struct irc_conn *irc, const char *name, const char *from, char **args) |
842 { | |
843 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
844 char *data[2]; | |
845 | |
846 if (!args || !args[0] || !gc) | |
847 return; | |
848 | |
849 data[0] = irc_mask_nick(from); | |
850 data[1] = args[0]; | |
851 /* XXX this should have an API, I shouldn't grab this directly */ | |
852 g_slist_foreach(gc->buddy_chats, (GFunc)irc_chat_remove_buddy, data); | |
853 g_free(data[0]); | |
854 | |
855 return; | |
856 } | |
857 | |
858 void irc_msg_wallops(struct irc_conn *irc, const char *name, const char *from, char **args) | |
859 { | |
860 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
861 char *nick, *msg; | |
862 | |
863 if (!args || !args[0] || !gc) | |
864 return; | |
865 | |
866 nick = irc_mask_nick(from); | |
867 msg = g_strdup_printf (_("Wallops from %s"), nick); | |
868 g_free(nick); | |
869 gaim_notify_info(gc, NULL, msg, args[0]); | |
870 g_free(msg); | |
871 } | |
872 | |
873 void irc_msg_ignore(struct irc_conn *irc, const char *name, const char *from, char **args) | |
874 { | |
875 return; | |
876 } |