Mercurial > pidgin
annotate src/protocols/irc/msgs.c @ 7104:7700a28929bd
[gaim-migrate @ 7669]
When retrieving user info for an MSN user, the prpl checks if the info is
empty. If so, it displays an error dialog indicating so. Otherwise, it
displays the info.
committer: Tailor Script <tailor@pidgin.im>
| author | Christian Hammond <chipx86@chipx86.com> |
|---|---|
| date | Wed, 01 Oct 2003 05:42:40 +0000 |
| parents | 86ed8b2aa665 |
| children | 6faeeecab0dc |
| 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 { | |
| 59 GList *users = gaim_chat_get_users(GAIM_CHAT(convo)); | |
| 60 char *message = g_strdup_printf("quit: %s", data[1]); | |
| 61 | |
| 62 if (g_list_find_custom(users, data[0], (GCompareFunc)(strcmp))) | |
| 63 gaim_chat_remove_user(GAIM_CHAT(convo), data[0], message); | |
| 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) | |
| 6982 | 88 serv_got_im(gc, args[1], args[2], GAIM_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] : ""); | |
| 6621 | 127 gaim_chat_write(GAIM_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) { | |
| 6357 | 206 gchar *timex = sec_to_text(irc->whois.idle); |
| 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 | |
| 226 void irc_msg_topic(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 227 { | |
| 228 char *chan, *topic, *msg, *nick; | |
| 229 GaimConversation *convo; | |
| 230 | |
| 231 if (!strcmp(name, "topic")) { | |
| 232 chan = args[0]; | |
| 233 topic = args[1]; | |
| 234 } else { | |
| 235 chan = args[1]; | |
| 236 topic = args[2]; | |
| 237 } | |
| 238 | |
| 239 convo = gaim_find_conversation_with_account(chan, irc->account); | |
| 240 if (!convo) { | |
| 241 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a topic for %s, which doesn't exist\n", chan); | |
| 242 } | |
| 243 gaim_chat_set_topic(GAIM_CHAT(convo), NULL, topic); | |
| 244 /* If this is an interactive update, print it out */ | |
| 245 if (!strcmp(name, "topic")) { | |
| 246 nick = irc_mask_nick(from); | |
| 247 msg = g_strdup_printf(_("%s has changed the topic to: %s"), nick, topic); | |
| 248 g_free(nick); | |
| 6621 | 249 gaim_chat_write(GAIM_CHAT(convo), from, msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
| 6333 | 250 g_free(msg); |
| 251 } else { | |
| 252 msg = g_strdup_printf(_("The topic for %s is: %s"), chan, topic); | |
| 6621 | 253 gaim_chat_write(GAIM_CHAT(convo), "", msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
| 6333 | 254 g_free(msg); |
| 255 } | |
| 256 } | |
| 257 | |
| 258 void irc_msg_unknown(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 259 { | |
| 260 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 261 char *buf; | |
| 262 | |
| 263 if (!args || !args[1] || !gc) | |
| 264 return; | |
| 265 | |
| 266 buf = g_strdup_printf(_("Unknown message '%s'"), args[1]); | |
| 267 gaim_notify_error(gc, _("Unknown message"), buf, _("Gaim has sent a message the IRC server did not understand.")); | |
| 268 g_free(buf); | |
| 269 } | |
| 270 | |
| 271 void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 272 { | |
| 273 char *names, *cur, *end, *tmp, *msg; | |
| 274 GaimConversation *convo; | |
| 275 | |
| 276 if (!strcmp(name, "366")) { | |
| 277 convo = gaim_find_conversation_with_account(irc->nameconv ? irc->nameconv : args[1], irc->account); | |
| 278 if (!convo) { | |
| 279 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a NAMES list for %s, which doesn't exist\n", args[2]); | |
| 280 g_string_free(irc->names, TRUE); | |
| 281 irc->names = NULL; | |
| 282 g_free(irc->nameconv); | |
| 283 irc->nameconv = NULL; | |
| 284 return; | |
| 285 } | |
| 286 | |
| 287 names = cur = g_string_free(irc->names, FALSE); | |
| 288 irc->names = NULL; | |
| 289 if (irc->nameconv) { | |
| 290 msg = g_strdup_printf("Users on %s: %s", args[1], names); | |
| 291 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT) | |
| 6621 | 292 gaim_chat_write(GAIM_CHAT(convo), "", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 293 else |
| 6982 | 294 gaim_im_write(GAIM_IM(convo), "", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 295 g_free(msg); |
| 296 g_free(irc->nameconv); | |
| 297 irc->nameconv = NULL; | |
| 298 } else { | |
|
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
299 GList *users = NULL; |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
300 |
| 6333 | 301 while (*cur) { |
| 302 end = strchr(cur, ' '); | |
| 303 if (!end) | |
| 304 end = cur + strlen(cur); | |
| 305 if (*cur == '@' || *cur == '%' || *cur == '+') | |
| 306 cur++; | |
| 307 tmp = g_strndup(cur, end - cur); | |
|
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
308 users = g_list_append(users, tmp); |
| 6333 | 309 cur = end; |
| 310 if (*cur) | |
| 311 cur++; | |
| 312 } | |
|
6407
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
313 |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
314 if (users != NULL) { |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
315 GList *l; |
|
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 gaim_chat_add_users(GAIM_CHAT(convo), users); |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
318 |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
319 for (l = users; l != NULL; l = l->next) |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
320 g_free(l->data); |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
321 |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
322 g_list_free(users); |
|
ba0b99a72be2
[gaim-migrate @ 6913]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
323 } |
| 6333 | 324 } |
| 325 g_free(names); | |
| 326 } else { | |
| 327 if (!irc->names) | |
| 328 irc->names = g_string_new(""); | |
| 329 | |
| 330 irc->names = g_string_append(irc->names, args[3]); | |
| 331 } | |
| 332 } | |
| 333 | |
| 334 void irc_msg_motd(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 335 { | |
| 336 GaimConnection *gc; | |
| 337 if (!strcmp(name, "375")) { | |
| 338 gc = gaim_account_get_connection(irc->account); | |
| 339 if (gc) | |
| 340 gaim_connection_set_display_name(gc, args[0]); | |
| 341 } | |
| 342 | |
| 343 if (!irc->motd) | |
| 344 irc->motd = g_string_new(""); | |
| 345 | |
| 346 g_string_append_printf(irc->motd, "%s<br>", args[1]); | |
| 347 } | |
| 348 | |
| 349 void irc_msg_endmotd(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 350 { | |
| 351 GaimConnection *gc; | |
| 352 | |
| 353 gc = gaim_account_get_connection(irc->account); | |
| 354 if (!gc) | |
| 355 return; | |
| 356 | |
| 357 gaim_connection_set_state(gc, GAIM_CONNECTED); | |
| 358 | |
| 359 irc_blist_timeout(irc); | |
| 360 irc->timer = g_timeout_add(45000, (GSourceFunc)irc_blist_timeout, (gpointer)irc); | |
| 361 } | |
| 362 | |
| 363 void irc_msg_nonick(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 364 { | |
| 365 GaimConnection *gc; | |
| 366 GaimConversation *convo; | |
| 367 | |
| 368 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
| 369 if (convo) { | |
| 370 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT) /* does this happen? */ | |
| 371 gaim_chat_write(GAIM_CHAT(convo), args[1], _("no such channel"), | |
| 6621 | 372 GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 373 else |
| 6982 | 374 gaim_im_write(GAIM_IM(convo), args[1], _("User is not logged in"), |
| 6621 | 375 GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 376 } else { |
| 377 if ((gc = gaim_account_get_connection(irc->account)) == NULL) | |
| 378 return; | |
| 379 gaim_notify_error(gc, NULL, _("No such nick or channel"), args[1]); | |
| 380 } | |
| 381 | |
| 382 if (irc->whois.nick && !gaim_utf8_strcasecmp(irc->whois.nick, args[1])) { | |
| 383 g_free(irc->whois.nick); | |
| 384 irc->whois.nick = NULL; | |
| 385 } | |
| 386 } | |
| 387 | |
| 388 void irc_msg_nosend(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 389 { | |
| 390 GaimConnection *gc; | |
| 391 GaimConversation *convo; | |
| 392 | |
| 393 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
| 394 if (convo) { | |
| 6621 | 395 gaim_chat_write(GAIM_CHAT(convo), args[1], args[2], GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 396 } else { |
| 397 if ((gc = gaim_account_get_connection(irc->account)) == NULL) | |
| 398 return; | |
| 399 gaim_notify_error(gc, NULL, _("Could not send"), args[2]); | |
| 400 } | |
| 401 } | |
| 402 | |
| 403 void irc_msg_notinchan(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 404 { | |
| 405 GaimConversation *convo = gaim_find_conversation_with_account(args[1], irc->account); | |
| 406 | |
| 407 gaim_debug(GAIM_DEBUG_INFO, "irc", "We're apparently not in %s, but tried to use it\n", args[1]); | |
| 408 if (convo) { | |
| 409 /*g_slist_remove(irc->gc->buddy_chats, convo); | |
| 410 gaim_conversation_set_account(convo, NULL);*/ | |
| 6621 | 411 gaim_chat_write(GAIM_CHAT(convo), args[1], args[2], GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 412 } |
| 413 } | |
| 414 | |
| 415 void irc_msg_notop(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 416 { | |
| 417 GaimConversation *convo; | |
| 418 | |
| 419 if (!args || !args[1] || !args[2]) | |
| 420 return; | |
| 421 | |
| 422 convo = gaim_find_conversation_with_account(args[1], irc->account); | |
| 423 if (!convo) | |
| 424 return; | |
| 425 | |
| 6621 | 426 gaim_chat_write(GAIM_CHAT(convo), "", args[2], GAIM_MESSAGE_SYSTEM, time(NULL)); |
| 6333 | 427 } |
| 428 | |
| 429 void irc_msg_invite(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 430 { | |
| 431 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 432 GHashTable *components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
| 433 char *nick = irc_mask_nick(from); | |
| 434 | |
| 435 if (!args || !args[1] || !gc) { | |
| 436 g_free(nick); | |
| 437 g_hash_table_destroy(components); | |
| 438 return; | |
| 439 } | |
| 440 | |
| 441 g_hash_table_insert(components, strdup("channel"), strdup(args[1])); | |
| 442 | |
| 443 serv_got_chat_invite(gc, args[1], nick, NULL, components); | |
| 444 g_free(nick); | |
| 445 } | |
| 446 | |
| 447 void irc_msg_inviteonly(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 448 { | |
| 449 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 450 char *buf; | |
| 451 | |
| 452 if (!args || !args[1] || !gc) | |
| 453 return; | |
| 454 | |
| 455 buf = g_strdup_printf(_("Joining %s requires an invitation."), args[1]); | |
| 456 gaim_notify_error(gc, _("Invitation only"), _("Invitation only"), buf); | |
| 457 g_free(buf); | |
| 458 } | |
| 459 | |
| 460 void irc_msg_ison(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 461 { | |
| 462 char **nicks; | |
| 463 struct irc_buddy *ib; | |
| 464 int i; | |
| 465 | |
| 466 if (!args || !args[1]) | |
| 467 return; | |
| 468 | |
| 469 nicks = g_strsplit(args[1], " ", -1); | |
| 470 | |
| 471 for (i = 0; nicks[i]; i++) { | |
| 472 if ((ib = g_hash_table_lookup(irc->buddies, (gconstpointer)nicks[i])) == NULL) { | |
| 473 continue; | |
| 474 } | |
| 475 ib->flag = TRUE; | |
| 476 } | |
| 477 | |
| 6350 | 478 g_strfreev(nicks); |
| 479 | |
| 6333 | 480 g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_status, (gpointer)irc); |
| 481 } | |
| 482 | |
| 483 static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc) | |
| 484 { | |
| 485 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 6695 | 486 GaimBuddy *buddy = gaim_find_buddy(irc->account, name); |
| 6333 | 487 |
| 488 if (!gc || !buddy) | |
| 489 return; | |
| 490 | |
| 491 if (ib->online && !ib->flag) { | |
| 492 serv_got_update(gc, buddy->name, 0, 0, 0, 0, 0); | |
| 493 ib->online = FALSE; | |
| 494 } | |
| 495 | |
| 496 if (!ib->online && ib->flag) { | |
| 497 serv_got_update(gc, buddy->name, 1, 0, 0, 0, 0); | |
| 498 ib->online = TRUE; | |
| 499 } | |
| 500 } | |
| 501 | |
| 502 void irc_msg_join(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 503 { | |
| 504 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 505 GaimConversation *convo; | |
| 506 char *nick = irc_mask_nick(from), *userhost; | |
| 507 static int id = 1; | |
| 508 | |
| 509 if (!gc) { | |
| 510 g_free(nick); | |
| 511 return; | |
| 512 } | |
| 513 | |
| 514 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
| 515 /* We are joining a channel for the first time */ | |
| 516 serv_got_joined_chat(gc, id++, args[0]); | |
| 517 g_free(nick); | |
| 518 return; | |
| 519 } | |
| 520 | |
| 521 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
| 522 if (convo == NULL) { | |
| 523 gaim_debug(GAIM_DEBUG_ERROR, "irc", "JOIN for %s failed\n", args[0]); | |
| 524 g_free(nick); | |
| 525 return; | |
| 526 } | |
| 527 | |
| 528 userhost = irc_mask_userhost(from); | |
| 529 gaim_chat_add_user(GAIM_CHAT(convo), nick, userhost); | |
| 530 g_free(userhost); | |
| 531 g_free(nick); | |
| 532 } | |
| 533 | |
| 534 void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 535 { | |
| 536 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 537 GaimConversation *convo = gaim_find_conversation_with_account(args[0], irc->account); | |
| 538 char *nick = irc_mask_nick(from), *buf; | |
| 539 | |
| 540 if (!gc) { | |
| 541 g_free(nick); | |
| 542 return; | |
| 543 } | |
| 544 | |
| 545 if (!convo) { | |
| 546 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Recieved a KICK for unknown channel %s\n", args[0]); | |
| 547 g_free(nick); | |
| 548 return; | |
| 549 } | |
| 550 | |
| 551 if (!gaim_utf8_strcasecmp(gaim_connection_get_display_name(gc), args[1])) { | |
| 552 buf = g_strdup_printf(_("You have been kicked by %s: (%s)"), nick, args[2]); | |
| 6621 | 553 gaim_chat_write(GAIM_CHAT(convo), args[0], buf, GAIM_MESSAGE_SYSTEM, time(NULL)); |
| 6333 | 554 g_free(buf); |
| 555 /*g_slist_remove(irc->gc->buddy_chats, convo); | |
| 556 gaim_conversation_set_account(convo, NULL);*/ | |
| 557 /*g_list_free(gaim_chat_get_users(GAIM_CHAT(convo))); | |
| 558 gaim_chat_set_users(GAIM_CHAT(convo), NULL);*/ | |
| 559 } else { | |
| 560 buf = g_strdup_printf(_("Kicked by %s (%s)"), nick, args[2]); | |
| 561 gaim_chat_remove_user(GAIM_CHAT(convo), args[1], buf); | |
| 562 g_free(buf); | |
| 563 } | |
| 564 | |
| 565 g_free(nick); | |
| 566 return; | |
| 567 } | |
| 568 | |
| 569 void irc_msg_mode(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 570 { | |
| 571 GaimConversation *convo; | |
| 572 char *nick = irc_mask_nick(from), *buf; | |
| 573 | |
| 574 if (*args[0] == '#' || *args[0] == '&') { /* Channel */ | |
| 575 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
| 576 if (!convo) { | |
| 577 gaim_debug(GAIM_DEBUG_ERROR, "irc", "MODE received for %s, which we are not in\n", args[0]); | |
| 578 g_free(nick); | |
| 579 return; | |
| 580 } | |
| 581 buf = g_strdup_printf(_("mode (%s %s) by %s"), args[1], args[2] ? args[2] : "", nick); | |
| 6621 | 582 gaim_chat_write(GAIM_CHAT(convo), args[0], buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 583 g_free(buf); |
| 584 } else { /* User */ | |
| 585 } | |
| 586 g_free(nick); | |
| 587 } | |
| 588 | |
| 589 void irc_msg_nick(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 590 { | |
| 591 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 592 GSList *chats; | |
| 593 char *nick = irc_mask_nick(from); | |
| 594 | |
| 595 if (!gc) { | |
| 596 g_free(nick); | |
| 597 return; | |
| 598 } | |
| 599 chats = gc->buddy_chats; | |
| 600 | |
| 601 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
| 602 gaim_connection_set_display_name(gc, args[0]); | |
| 603 } | |
| 604 | |
| 605 while (chats) { | |
| 606 GaimChat *chat = GAIM_CHAT(chats->data); | |
| 607 GList *users = gaim_chat_get_users(chat); | |
| 608 | |
| 609 while (users) { | |
| 610 char *user = users->data; | |
| 611 | |
| 612 if (!strcmp(nick, user)) { | |
| 613 gaim_chat_rename_user(chat, user, args[0]); | |
| 614 users = gaim_chat_get_users(chat); | |
| 615 break; | |
| 616 } | |
| 617 users = users->next; | |
| 618 } | |
| 619 chats = chats->next; | |
| 620 } | |
| 621 g_free(nick); | |
| 622 } | |
| 623 | |
| 624 void irc_msg_nickused(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 625 { | |
| 626 char *newnick, *buf, *end; | |
| 627 | |
| 628 if (!args || !args[1]) | |
| 629 return; | |
| 630 | |
| 631 newnick = strdup(args[1]); | |
| 632 end = newnick + strlen(newnick) - 1; | |
| 633 /* try three fallbacks */ | |
| 634 if (*end == 2) *end = '3'; | |
| 635 else if (*end == 1) *end = '2'; | |
| 636 else *end = '1'; | |
| 637 | |
| 638 buf = irc_format(irc, "vn", "NICK", newnick); | |
| 639 irc_send(irc, buf); | |
| 640 g_free(buf); | |
| 641 } | |
| 642 | |
| 643 void irc_msg_notice(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 644 { | |
| 645 char *newargs[2]; | |
| 646 | |
| 647 newargs[0] = " notice "; /* The spaces are magic, leave 'em in! */ | |
| 648 newargs[1] = args[1]; | |
| 649 irc_msg_privmsg(irc, name, from, newargs); | |
| 650 } | |
| 651 | |
| 6718 | 652 void irc_msg_nochangenick(struct irc_conn *irc, const char *name, const char *from, char **args) |
| 653 { | |
| 654 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 655 char *msg; | |
| 656 | |
| 6753 | 657 if (!args || !args[2] || !gc) |
| 6718 | 658 return; |
| 659 | |
| 6753 | 660 msg = g_strdup_printf(_("Could not change nick")); |
| 6718 | 661 gaim_notify_error(gc, _("Cannot change nick"), msg, args[2]); |
| 662 g_free(msg); | |
| 663 } | |
| 664 | |
| 6333 | 665 void irc_msg_part(struct irc_conn *irc, const char *name, const char *from, char **args) |
| 666 { | |
| 667 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 668 GaimConversation *convo; | |
| 669 char *nick, *msg; | |
| 670 | |
| 671 if (!args || !args[0] || !args[1] || !gc) | |
| 672 return; | |
| 673 | |
| 674 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
| 675 if (!convo) { | |
| 676 gaim_debug(GAIM_DEBUG_INFO, "irc", "Got a PART on %s, which doesn't exist -- probably closed\n", args[0]); | |
| 677 return; | |
| 678 } | |
| 679 | |
| 680 nick = irc_mask_nick(from); | |
| 681 if (!gaim_utf8_strcasecmp(nick, gaim_connection_get_display_name(gc))) { | |
| 682 msg = g_strdup_printf(_("You have parted the channel%s%s"), *args[1] ? ": " : "", args[1]); | |
| 6621 | 683 gaim_chat_write(GAIM_CHAT(convo), args[0], msg, GAIM_MESSAGE_SYSTEM, time(NULL)); |
| 6333 | 684 g_free(msg); |
| 685 } else { | |
| 686 gaim_chat_remove_user(GAIM_CHAT(convo), nick, args[1]); | |
| 687 } | |
| 688 g_free(nick); | |
| 689 } | |
| 690 | |
| 691 void irc_msg_ping(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 692 { | |
| 693 char *buf; | |
| 694 if (!args || !args[0]) | |
| 695 return; | |
| 696 | |
| 697 buf = irc_format(irc, "v:", "PONG", args[0]); | |
| 698 irc_send(irc, buf); | |
| 699 g_free(buf); | |
| 700 } | |
| 701 | |
| 702 void irc_msg_pong(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 703 { | |
| 704 GaimConversation *convo; | |
| 705 GaimConnection *gc; | |
| 706 char **parts, *msg; | |
| 707 time_t oldstamp; | |
| 708 | |
| 709 if (!args || !args[1]) | |
| 710 return; | |
| 711 | |
| 712 parts = g_strsplit(args[1], " ", 2); | |
| 713 | |
| 714 if (!parts[0] || !parts[1]) { | |
| 715 g_strfreev(parts); | |
| 716 return; | |
| 717 } | |
| 718 | |
| 719 if (sscanf(parts[1], "%lu", &oldstamp) != 1) { | |
| 720 msg = g_strdup(_("Error: invalid PONG from server")); | |
| 721 } else { | |
| 6350 | 722 msg = g_strdup_printf(_("PING reply -- Lag: %lu seconds"), time(NULL) - oldstamp); |
| 6333 | 723 } |
| 724 | |
| 725 convo = gaim_find_conversation_with_account(parts[0], irc->account); | |
| 726 g_strfreev(parts); | |
| 727 if (convo) { | |
| 728 if (gaim_conversation_get_type (convo) == GAIM_CONV_CHAT) | |
| 6621 | 729 gaim_chat_write(GAIM_CHAT(convo), "PONG", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 730 else |
| 6982 | 731 gaim_im_write(GAIM_IM(convo), "PONG", msg, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 732 } else { |
| 733 gc = gaim_account_get_connection(irc->account); | |
| 734 if (!gc) { | |
| 735 g_free(msg); | |
| 736 return; | |
| 737 } | |
| 738 gaim_notify_info(gc, NULL, "PONG", msg); | |
| 739 } | |
| 740 g_free(msg); | |
| 741 } | |
| 742 | |
| 743 void irc_msg_privmsg(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 744 { | |
| 745 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 746 GaimConversation *convo; | |
| 747 char *nick = irc_mask_nick(from), *tmp, *msg; | |
| 748 int notice = 0; | |
| 749 | |
| 750 if (!args || !args[0] || !args[1] || !gc) { | |
| 751 g_free(nick); | |
| 752 return; | |
| 753 } | |
| 754 | |
| 755 notice = !strcmp(args[0], " notice "); | |
| 756 tmp = irc_parse_ctcp(irc, nick, args[0], args[1], notice); | |
| 757 if (!tmp) { | |
| 758 g_free(nick); | |
| 759 return; | |
| 760 } | |
| 761 msg = irc_mirc2html(tmp); | |
| 762 g_free(tmp); | |
| 763 if (notice) { | |
| 764 tmp = g_strdup_printf("(notice) %s", msg); | |
| 765 g_free(msg); | |
| 766 msg = tmp; | |
| 767 } | |
| 768 | |
| 769 if (!gaim_utf8_strcasecmp(args[0], gaim_connection_get_display_name(gc))) { | |
| 6982 | 770 serv_got_im(gc, nick, msg, 0, time(NULL)); |
| 6333 | 771 } else if (notice) { |
| 6982 | 772 serv_got_im(gc, nick, msg, 0, time(NULL)); |
| 6333 | 773 } else { |
| 774 convo = gaim_find_conversation_with_account(args[0], irc->account); | |
| 775 if (convo) | |
| 776 serv_got_chat_in(gc, gaim_chat_get_id(GAIM_CHAT(convo)), nick, 0, msg, time(NULL)); | |
| 777 else | |
| 778 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got a PRIVMSG on %s, which does not exist\n", args[0]); | |
| 779 } | |
| 780 g_free(msg); | |
| 781 g_free(nick); | |
| 782 } | |
| 783 | |
| 6714 | 784 void irc_msg_regonly(struct irc_conn *irc, const char *name, const char *from, char **args) |
| 785 { | |
| 786 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 787 char *msg; | |
| 788 | |
| 789 if (!args || !args[1] || !args[2] || !gc) | |
| 790 return; | |
| 791 | |
| 792 msg = g_strdup_printf(_("Cannot join %s:"), args[1]); | |
| 793 gaim_notify_error(gc, _("Cannot join channel"), msg, args[2]); | |
| 794 g_free(msg); | |
| 795 } | |
| 796 | |
| 6333 | 797 void irc_msg_quit(struct irc_conn *irc, const char *name, const char *from, char **args) |
| 798 { | |
| 799 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 800 char *data[2]; | |
| 801 | |
| 802 if (!args || !args[0] || !gc) | |
| 803 return; | |
| 804 | |
| 805 data[0] = irc_mask_nick(from); | |
| 806 data[1] = args[0]; | |
| 807 /* XXX this should have an API, I shouldn't grab this directly */ | |
| 808 g_slist_foreach(gc->buddy_chats, (GFunc)irc_chat_remove_buddy, data); | |
| 809 g_free(data[0]); | |
| 810 | |
| 811 return; | |
| 812 } | |
| 813 | |
| 814 void irc_msg_wallops(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 815 { | |
| 816 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 817 char *nick, *msg; | |
| 818 | |
| 819 if (!args || !args[0] || !gc) | |
| 820 return; | |
| 821 | |
| 822 nick = irc_mask_nick(from); | |
| 823 msg = g_strdup_printf (_("Wallops from %s"), nick); | |
| 824 g_free(nick); | |
| 825 gaim_notify_info(gc, NULL, msg, args[0]); | |
| 826 g_free(msg); | |
| 827 } | |
| 828 | |
| 829 void irc_msg_ignore(struct irc_conn *irc, const char *name, const char *from, char **args) | |
| 830 { | |
| 831 return; | |
| 832 } |
