Mercurial > pidgin
annotate src/protocols/irc/cmds.c @ 9593:a64febebdd1e
[gaim-migrate @ 10436]
Prevent nick changes from showing up in channels where the user is not
present. I think this showed up because the new chatlist stuff
doesn't check to see if a user is present before mucking with it ...
and this solution is slower than solving it there, but arguably we
shouldn't be trying to rename users that don't exist. So now we don't.
committer: Tailor Script <tailor@pidgin.im>
| author | Ethan Blanton <elb@pidgin.im> |
|---|---|
| date | Sun, 25 Jul 2004 17:52:22 +0000 |
| parents | 00242c2419c3 |
| children | 3f97624e7753 |
| rev | line source |
|---|---|
| 6333 | 1 /** |
| 2 * @file cmds.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" | |
| 8504 | 26 #include "debug.h" |
| 6333 | 27 #include "notify.h" |
| 8624 | 28 #include "util.h" |
| 8504 | 29 |
| 6333 | 30 #include "irc.h" |
| 31 | |
| 32 | |
| 33 static void irc_do_mode(struct irc_conn *irc, const char *target, const char *sign, char **ops); | |
| 34 | |
| 35 int irc_cmd_default(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 36 { | |
| 37 GaimConversation *convo = gaim_find_conversation_with_account(target, irc->account); | |
| 38 char *buf; | |
| 39 | |
| 40 if (!convo) | |
| 6350 | 41 return 1; |
| 6333 | 42 |
| 43 buf = g_strdup_printf(_("Unknown command: %s"), cmd); | |
| 44 if (gaim_conversation_get_type(convo) == GAIM_CONV_IM) | |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
45 gaim_conv_im_write(GAIM_CONV_IM(convo), "", buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 46 else |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
47 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), "", buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 48 g_free(buf); |
| 49 | |
| 50 return 1; | |
| 51 } | |
| 52 | |
| 53 int irc_cmd_away(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 54 { | |
| 55 char *buf, *message, *cur; | |
| 56 | |
| 57 if (args[0] && strcmp(cmd, "back")) { | |
| 58 message = strdup(args[0]); | |
| 59 for (cur = message; *cur; cur++) { | |
| 60 if (*cur == '\n') | |
| 61 *cur = ' '; | |
| 62 } | |
| 63 buf = irc_format(irc, "v:", "AWAY", message); | |
| 64 g_free(message); | |
| 65 } else { | |
| 66 buf = irc_format(irc, "v", "AWAY"); | |
| 67 } | |
| 68 irc_send(irc, buf); | |
| 69 g_free(buf); | |
| 70 | |
| 71 return 0; | |
| 72 } | |
| 73 | |
| 74 int irc_cmd_ctcp_action(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 75 { | |
| 76 GaimConnection *gc = gaim_account_get_connection(irc->account); | |
| 77 char *action, *dst, **newargs; | |
| 78 const char *src; | |
| 79 GaimConversation *convo; | |
| 80 | |
| 81 if (!args || !args[0] || !gc) | |
| 82 return 0; | |
| 83 | |
| 6376 | 84 action = g_malloc(strlen(args[0]) + 10); |
| 6333 | 85 |
| 86 sprintf(action, "\001ACTION "); | |
| 87 | |
| 88 src = args[0]; | |
| 89 dst = action + 8; | |
| 90 while (*src) { | |
| 91 if (*src == '\n') { | |
| 92 if (*(src + 1) == '\0') { | |
| 93 break; | |
| 94 } else { | |
| 95 *dst++ = ' '; | |
| 96 src++; | |
| 97 continue; | |
| 98 } | |
| 99 } | |
| 100 *dst++ = *src++; | |
| 101 } | |
| 102 *dst++ = '\001'; | |
| 103 *dst = '\0'; | |
| 104 | |
| 105 newargs = g_new0(char *, 2); | |
| 106 newargs[0] = g_strdup(target); | |
| 107 newargs[1] = action; | |
| 108 irc_cmd_privmsg(irc, cmd, target, (const char **)newargs); | |
| 109 g_free(newargs[0]); | |
| 110 g_free(newargs[1]); | |
| 111 g_free(newargs); | |
| 112 | |
| 113 convo = gaim_find_conversation_with_account(target, irc->account); | |
| 9130 | 114 if (convo) { |
| 6333 | 115 action = g_strdup_printf("/me %s", args[0]); |
| 116 if (action[strlen(action) - 1] == '\n') | |
| 117 action[strlen(action) - 1] = '\0'; | |
| 9130 | 118 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT) |
| 119 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo)), | |
| 120 gaim_connection_get_display_name(gc), | |
| 121 0, action, time(NULL)); | |
| 122 else | |
| 123 gaim_conv_im_write(GAIM_CONV_IM(convo), gaim_connection_get_display_name(gc), | |
| 124 action, 0, time(NULL)); | |
| 6333 | 125 g_free(action); |
| 126 } | |
| 127 | |
| 128 return 1; | |
| 129 } | |
| 130 | |
| 131 int irc_cmd_invite(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 132 { | |
| 133 char *buf; | |
| 134 | |
| 135 if (!args || !args[0] || !(args[1] || target)) | |
| 136 return 0; | |
| 137 | |
| 138 buf = irc_format(irc, "vnc", "INVITE", args[0], args[1] ? args[1] : target); | |
| 139 irc_send(irc, buf); | |
| 140 g_free(buf); | |
| 141 | |
| 142 return 0; | |
| 143 } | |
| 144 | |
| 145 int irc_cmd_join(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 146 { | |
| 147 char *buf; | |
| 148 | |
| 149 if (!args || !args[0]) | |
| 150 return 0; | |
| 151 | |
| 152 if (args[1]) | |
| 153 buf = irc_format(irc, "vcv", "JOIN", args[0], args[1]); | |
| 154 else | |
| 155 buf = irc_format(irc, "vc", "JOIN", args[0]); | |
| 156 irc_send(irc, buf); | |
| 157 g_free(buf); | |
| 158 | |
| 159 return 0; | |
| 160 } | |
| 161 | |
| 162 int irc_cmd_kick(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 163 { | |
| 164 char *buf; | |
| 165 GaimConversation *convo; | |
| 166 | |
| 167 if (!args || !args[0]) | |
| 168 return 0; | |
| 169 | |
| 170 convo = gaim_find_conversation_with_account(target, irc->account); | |
| 171 if (!convo || gaim_conversation_get_type(convo) != GAIM_CONV_CHAT) | |
| 6350 | 172 return 0; |
| 6333 | 173 |
| 174 if (args[1]) | |
| 175 buf = irc_format(irc, "vcn:", "KICK", target, args[0], args[1]); | |
| 176 else | |
| 177 buf = irc_format(irc, "vcn", "KICK", target, args[0]); | |
| 178 irc_send(irc, buf); | |
| 179 g_free(buf); | |
| 180 | |
| 181 return 0; | |
| 182 } | |
| 183 | |
| 8114 | 184 int irc_cmd_list(struct irc_conn *irc, const char *cmd, const char *target, const char **args) |
| 185 { | |
| 8352 | 186 gaim_roomlist_show_with_account(irc->account); |
| 8114 | 187 |
| 188 return 0; | |
| 189 } | |
| 190 | |
| 6333 | 191 int irc_cmd_mode(struct irc_conn *irc, const char *cmd, const char *target, const char **args) |
| 192 { | |
| 193 GaimConnection *gc; | |
| 194 char *buf; | |
| 195 | |
| 196 if (!args) | |
| 197 return 0; | |
| 198 | |
| 199 if (!strcmp(cmd, "mode")) { | |
| 200 if (!args[0] && (*target == '#' || *target == '&')) | |
| 201 buf = irc_format(irc, "vc", "MODE", target); | |
| 202 else if (args[0] && (*args[0] == '+' || *args[0] == '-')) | |
| 203 buf = irc_format(irc, "vcv", "MODE", target, args[0]); | |
| 204 else if (args[0]) | |
| 205 buf = irc_format(irc, "vv", "MODE", args[0]); | |
| 206 else | |
| 6350 | 207 return 0; |
| 6333 | 208 } else if (!strcmp(cmd, "umode")) { |
| 209 if (!args[0]) | |
| 6350 | 210 return 0; |
| 6333 | 211 gc = gaim_account_get_connection(irc->account); |
| 212 buf = irc_format(irc, "vnv", "MODE", gaim_connection_get_display_name(gc), args[0]); | |
| 6365 | 213 } else { |
| 214 return 0; | |
| 6333 | 215 } |
| 6365 | 216 |
| 6333 | 217 irc_send(irc, buf); |
| 218 g_free(buf); | |
| 219 | |
| 220 return 0; | |
| 221 } | |
| 222 | |
| 223 int irc_cmd_names(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 224 { | |
| 225 char *buf; | |
| 226 | |
| 227 if (!args) | |
| 228 return 0; | |
| 229 | |
| 230 buf = irc_format(irc, "vc", "NAMES", args[0] ? args[0] : target); | |
| 231 irc_send(irc, buf); | |
| 232 g_free(buf); | |
| 233 | |
| 234 irc->nameconv = g_strdup(target); | |
| 235 | |
| 236 return 0; | |
| 237 } | |
| 238 | |
| 239 int irc_cmd_nick(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 240 { | |
| 241 char *buf; | |
| 242 | |
| 243 if (!args || !args[0]) | |
| 244 return 0; | |
| 245 | |
| 246 buf = irc_format(irc, "v:", "NICK", args[0]); | |
| 247 irc_send(irc, buf); | |
| 248 g_free(buf); | |
| 249 | |
| 250 return 0; | |
| 251 } | |
| 252 | |
| 253 int irc_cmd_op(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 254 { | |
| 255 char **nicks, **ops, *sign, *mode; | |
| 256 int i = 0, used = 0; | |
| 257 | |
| 258 if (!args || !args[0] || !*args[0]) | |
| 259 return 0; | |
| 260 | |
| 261 if (!strcmp(cmd, "op")) { | |
| 262 sign = "+"; | |
| 263 mode = "o"; | |
| 264 } else if (!strcmp(cmd, "deop")) { | |
| 265 sign = "-"; | |
| 266 mode = "o"; | |
| 267 } else if (!strcmp(cmd, "voice")) { | |
| 268 sign = "+"; | |
| 269 mode = "v"; | |
| 270 } else if (!strcmp(cmd, "devoice")) { | |
| 271 sign = "-"; | |
| 272 mode = "v"; | |
| 273 } else { | |
| 274 gaim_debug(GAIM_DEBUG_ERROR, "irc", "invalid 'op' command '%s'\n", cmd); | |
| 275 return 0; | |
| 276 } | |
| 277 | |
| 278 nicks = g_strsplit(args[0], " ", -1); | |
| 279 | |
| 280 for (i = 0; nicks[i]; i++) | |
| 281 /* nothing */; | |
| 282 ops = g_new0(char *, i * 2 + 1); | |
| 283 | |
| 284 for (i = 0; nicks[i]; i++) { | |
| 285 if (!*nicks[i]) | |
| 286 continue; | |
| 287 ops[used++] = mode; | |
| 288 ops[used++] = nicks[i]; | |
| 289 } | |
| 290 | |
| 291 irc_do_mode(irc, target, sign, ops); | |
| 292 g_free(ops); | |
| 293 | |
| 6350 | 294 return 0; |
| 6333 | 295 } |
| 296 | |
| 297 int irc_cmd_part(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 298 { | |
| 299 char *buf; | |
| 300 | |
| 301 if (!args) | |
| 302 return 0; | |
| 303 | |
| 304 if (args[1]) | |
| 305 buf = irc_format(irc, "vc:", "PART", args[0] ? args[0] : target, args[1]); | |
| 306 else | |
| 307 buf = irc_format(irc, "vc", "PART", args[0] ? args[0] : target); | |
| 308 irc_send(irc, buf); | |
| 309 g_free(buf); | |
| 310 | |
| 311 return 0; | |
| 312 } | |
| 313 | |
| 314 int irc_cmd_ping(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 315 { | |
| 316 char *stamp; | |
| 317 char *buf; | |
| 318 | |
| 319 if (args && args[0]) { | |
| 320 if (*args[0] == '#' || *args[0] == '&') | |
| 321 return 0; | |
| 322 stamp = g_strdup_printf("\001PING %lu\001", time(NULL)); | |
| 323 buf = irc_format(irc, "vn:", "PRIVMSG", args[0], stamp); | |
| 324 g_free(stamp); | |
| 325 } else { | |
| 6350 | 326 stamp = g_strdup_printf("%s %lu", target, time(NULL)); |
| 6333 | 327 buf = irc_format(irc, "v:", "PING", stamp); |
| 328 g_free(stamp); | |
| 329 } | |
| 330 irc_send(irc, buf); | |
| 331 g_free(buf); | |
| 332 | |
| 333 return 0; | |
| 334 } | |
| 335 | |
| 336 int irc_cmd_privmsg(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 337 { | |
| 338 const char *cur, *end; | |
| 339 char *msg, *buf; | |
| 340 | |
| 341 if (!args || !args[0] || !args[1]) | |
| 342 return 0; | |
| 343 | |
| 344 cur = args[1]; | |
| 345 end = args[1]; | |
| 346 while (*end && *cur) { | |
| 347 end = strchr(cur, '\n'); | |
| 348 if (!end) | |
| 349 end = cur + strlen(cur); | |
| 350 msg = g_strndup(cur, end - cur); | |
| 351 buf = irc_format(irc, "vt:", "PRIVMSG", args[0], msg); | |
| 352 irc_send(irc, buf); | |
| 353 g_free(msg); | |
| 354 g_free(buf); | |
| 355 cur = end + 1; | |
| 356 } | |
| 357 | |
| 358 return 0; | |
| 359 } | |
| 360 | |
| 361 int irc_cmd_quit(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 362 { | |
| 363 char *buf; | |
| 364 | |
| 9440 | 365 if (!irc->quitting) { |
| 366 buf = irc_format(irc, "v:", "QUIT", (args && args[0]) ? args[0] : "Download Gaim: " GAIM_WEBSITE); | |
| 367 irc_send(irc, buf); | |
| 368 g_free(buf); | |
| 369 | |
| 370 irc->quitting = TRUE; | |
| 371 } | |
| 6333 | 372 |
| 373 return 0; | |
| 374 } | |
| 375 | |
| 376 int irc_cmd_quote(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 377 { | |
| 378 char *buf; | |
| 379 | |
| 380 if (!args || !args[0]) | |
| 381 return 0; | |
| 382 | |
| 383 buf = irc_format(irc, "v", args[0]); | |
| 384 irc_send(irc, buf); | |
| 385 g_free(buf); | |
| 386 | |
| 387 return 0; | |
| 388 } | |
| 389 | |
| 390 int irc_cmd_query(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 391 { | |
| 392 GaimConversation *convo; | |
| 393 GaimConnection *gc; | |
| 394 | |
| 395 if (!args || !args[0]) | |
| 396 return 0; | |
| 397 | |
| 398 convo = gaim_conversation_new(GAIM_CONV_IM, irc->account, args[0]); | |
| 399 | |
| 400 if (args[1]) { | |
| 401 gc = gaim_account_get_connection(irc->account); | |
| 402 irc_cmd_privmsg(irc, cmd, target, args); | |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
403 gaim_conv_im_write(GAIM_CONV_IM(convo), gaim_connection_get_display_name(gc), |
| 6982 | 404 args[1], GAIM_MESSAGE_SEND, time(NULL)); |
| 6333 | 405 } |
| 406 | |
| 407 return 0; | |
| 408 } | |
| 409 | |
| 410 int irc_cmd_remove(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 411 { | |
| 412 char *buf; | |
| 413 | |
| 414 if (!args || !args[0]) | |
| 415 return 0; | |
| 416 | |
| 417 if (*target != '#' && *target != '&') /* not a channel, punt */ | |
| 418 return 0; | |
| 419 | |
| 420 if (args[1]) | |
| 421 buf = irc_format(irc, "vcn:", "REMOVE", target, args[0], args[1]); | |
| 422 else | |
| 423 buf = irc_format(irc, "vcn", "REMOVE", target, args[0]); | |
| 424 irc_send(irc, buf); | |
| 425 g_free(buf); | |
| 426 | |
| 427 return 0; | |
| 428 } | |
| 429 | |
| 430 int irc_cmd_topic(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 431 { | |
| 432 char *buf; | |
| 433 const char *topic; | |
| 434 GaimConversation *convo; | |
| 435 | |
| 436 if (!args) | |
| 437 return 0; | |
| 438 | |
| 439 convo = gaim_find_conversation_with_account(target, irc->account); | |
| 440 if (!convo || gaim_conversation_get_type(convo) != GAIM_CONV_CHAT) | |
| 6350 | 441 return 0; |
| 6333 | 442 |
| 443 if (!args[0]) { | |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
444 topic = gaim_conv_chat_get_topic (GAIM_CONV_CHAT(convo)); |
| 6333 | 445 |
| 8504 | 446 if (topic) { |
| 447 char *tmp = gaim_escape_html(topic); | |
| 448 buf = g_strdup_printf(_("current topic is: %s"), tmp); | |
| 449 g_free(tmp); | |
| 450 } else | |
| 6333 | 451 buf = g_strdup(_("No topic is set")); |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
452 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), target, buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 453 g_free(buf); |
| 454 | |
| 455 return 0; | |
| 456 } | |
| 457 | |
| 458 buf = irc_format(irc, "vt:", "TOPIC", target, args[0]); | |
| 459 irc_send(irc, buf); | |
| 460 g_free(buf); | |
| 461 | |
| 462 return 0; | |
| 463 } | |
| 464 | |
| 465 int irc_cmd_wallops(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 466 { | |
| 467 char *buf; | |
| 468 | |
| 469 if (!args || !args[0]) | |
| 6350 | 470 return 0; |
| 6333 | 471 |
| 472 if (!strcmp(cmd, "wallops")) | |
| 473 buf = irc_format(irc, "v:", "WALLOPS", args[0]); | |
| 474 else if (!strcmp(cmd, "operwall")) | |
| 475 buf = irc_format(irc, "v:", "OPERWALL", args[0]); | |
| 6365 | 476 else |
| 477 return 0; | |
| 6333 | 478 |
| 479 irc_send(irc, buf); | |
| 480 g_free(buf); | |
| 481 | |
| 482 return 0; | |
| 483 } | |
| 484 | |
| 485 int irc_cmd_whois(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 486 { | |
| 487 char *buf; | |
| 488 | |
| 489 if (!args || !args[0]) | |
| 490 return 0; | |
| 491 | |
| 492 buf = irc_format(irc, "vn", "WHOIS", args[0]); | |
| 493 irc_send(irc, buf); | |
| 494 g_free(buf); | |
| 495 irc->whois.nick = g_strdup(args[0]); | |
| 496 | |
| 497 return 0; | |
| 498 } | |
| 499 | |
| 500 static void irc_do_mode(struct irc_conn *irc, const char *target, const char *sign, char **ops) | |
| 501 { | |
| 502 char *buf, mode[5]; | |
| 503 int i = 0; | |
| 504 | |
| 505 if (!sign) | |
| 506 return; | |
| 507 | |
| 508 while (ops[i]) { | |
| 509 if (ops[i + 2] && ops[i + 4]) { | |
| 510 g_snprintf(mode, sizeof(mode), "%s%s%s%s", sign, | |
| 511 ops[i], ops[i + 2], ops[i + 4]); | |
| 512 buf = irc_format(irc, "vcvnnn", "MODE", target, mode, | |
| 513 ops[i + 1], ops[i + 3], ops[i + 5]); | |
| 514 i += 6; | |
| 515 } else if (ops[i + 2]) { | |
| 516 g_snprintf(mode, sizeof(mode), "%s%s%s", | |
| 517 sign, ops[i], ops[i + 2]); | |
| 518 buf = irc_format(irc, "vcvnn", "MODE", target, mode, | |
| 519 ops[i + 1], ops[i + 3]); | |
| 520 i += 4; | |
| 521 } else { | |
| 522 g_snprintf(mode, sizeof(mode), "%s%s", sign, ops[i]); | |
| 523 buf = irc_format(irc, "vcvn", "MODE", target, mode, ops[i + 1]); | |
| 524 i += 2; | |
| 525 } | |
| 526 irc_send(irc, buf); | |
| 527 g_free(buf); | |
| 528 } | |
| 6350 | 529 |
| 530 return; | |
| 6333 | 531 } |
