Mercurial > pidgin
annotate src/protocols/irc/cmds.c @ 9772:5f7c81eeebd2
[gaim-migrate @ 10640]
Another ft patch from Dave West. This one makes transfers appear in the
ft dialog earlier. I'm a bit concerned that transfers might not be
removed correctly when canceled early on. Or that they won't show up
with the right status between the time they're initiated and the time
the file actually begins being transferred.
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Wed, 18 Aug 2004 04:22:31 +0000 |
| parents | 3f97624e7753 |
| children | cbdce0acbbe6 |
| 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) { |
| 9762 | 447 char *tmp, *tmp2; |
| 448 tmp = gaim_escape_html(topic); | |
| 449 tmp2 = gaim_markup_linkify(tmp); | |
| 450 buf = g_strdup_printf(_("current topic is: %s"), tmp2); | |
| 8504 | 451 g_free(tmp); |
| 9762 | 452 g_free(tmp2); |
| 8504 | 453 } else |
| 6333 | 454 buf = g_strdup(_("No topic is set")); |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
455 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), target, buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); |
| 6333 | 456 g_free(buf); |
| 457 | |
| 458 return 0; | |
| 459 } | |
| 460 | |
| 461 buf = irc_format(irc, "vt:", "TOPIC", target, args[0]); | |
| 462 irc_send(irc, buf); | |
| 463 g_free(buf); | |
| 464 | |
| 465 return 0; | |
| 466 } | |
| 467 | |
| 468 int irc_cmd_wallops(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 469 { | |
| 470 char *buf; | |
| 471 | |
| 472 if (!args || !args[0]) | |
| 6350 | 473 return 0; |
| 6333 | 474 |
| 475 if (!strcmp(cmd, "wallops")) | |
| 476 buf = irc_format(irc, "v:", "WALLOPS", args[0]); | |
| 477 else if (!strcmp(cmd, "operwall")) | |
| 478 buf = irc_format(irc, "v:", "OPERWALL", args[0]); | |
| 6365 | 479 else |
| 480 return 0; | |
| 6333 | 481 |
| 482 irc_send(irc, buf); | |
| 483 g_free(buf); | |
| 484 | |
| 485 return 0; | |
| 486 } | |
| 487 | |
| 488 int irc_cmd_whois(struct irc_conn *irc, const char *cmd, const char *target, const char **args) | |
| 489 { | |
| 490 char *buf; | |
| 491 | |
| 492 if (!args || !args[0]) | |
| 493 return 0; | |
| 494 | |
| 495 buf = irc_format(irc, "vn", "WHOIS", args[0]); | |
| 496 irc_send(irc, buf); | |
| 497 g_free(buf); | |
| 498 irc->whois.nick = g_strdup(args[0]); | |
| 499 | |
| 500 return 0; | |
| 501 } | |
| 502 | |
| 503 static void irc_do_mode(struct irc_conn *irc, const char *target, const char *sign, char **ops) | |
| 504 { | |
| 505 char *buf, mode[5]; | |
| 506 int i = 0; | |
| 507 | |
| 508 if (!sign) | |
| 509 return; | |
| 510 | |
| 511 while (ops[i]) { | |
| 512 if (ops[i + 2] && ops[i + 4]) { | |
| 513 g_snprintf(mode, sizeof(mode), "%s%s%s%s", sign, | |
| 514 ops[i], ops[i + 2], ops[i + 4]); | |
| 515 buf = irc_format(irc, "vcvnnn", "MODE", target, mode, | |
| 516 ops[i + 1], ops[i + 3], ops[i + 5]); | |
| 517 i += 6; | |
| 518 } else if (ops[i + 2]) { | |
| 519 g_snprintf(mode, sizeof(mode), "%s%s%s", | |
| 520 sign, ops[i], ops[i + 2]); | |
| 521 buf = irc_format(irc, "vcvnn", "MODE", target, mode, | |
| 522 ops[i + 1], ops[i + 3]); | |
| 523 i += 4; | |
| 524 } else { | |
| 525 g_snprintf(mode, sizeof(mode), "%s%s", sign, ops[i]); | |
| 526 buf = irc_format(irc, "vcvn", "MODE", target, mode, ops[i + 1]); | |
| 527 i += 2; | |
| 528 } | |
| 529 irc_send(irc, buf); | |
| 530 g_free(buf); | |
| 531 } | |
| 6350 | 532 |
| 533 return; | |
| 6333 | 534 } |
