comparison libpurple/protocols/irc/cmds.c @ 15373:5fe8042783c1

Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author Sean Egan <seanegan@gmail.com>
date Sat, 20 Jan 2007 02:32:10 +0000
parents
children 79f25bbe69bf
comparison
equal deleted inserted replaced
15372:f79e0f4df793 15373:5fe8042783c1
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"
26 #include "debug.h"
27 #include "notify.h"
28 #include "util.h"
29
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(GAIM_CONV_TYPE_ANY, target, irc->account);
38 char *buf;
39
40 if (!convo)
41 return 1;
42
43 buf = g_strdup_printf(_("Unknown command: %s"), cmd);
44 if (gaim_conversation_get_type(convo) == GAIM_CONV_TYPE_IM)
45 gaim_conv_im_write(GAIM_CONV_IM(convo), "", buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL));
46 else
47 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), "", buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL));
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;
56
57 if (args[0] && strcmp(cmd, "back")) {
58 message = gaim_markup_strip_html(args[0]);
59 gaim_util_chrreplace(message, '\n', ' ');
60 buf = irc_format(irc, "v:", "AWAY", message);
61 g_free(message);
62 } else {
63 buf = irc_format(irc, "v", "AWAY");
64 }
65 irc_send(irc, buf);
66 g_free(buf);
67
68 return 0;
69 }
70
71 int irc_cmd_ctcp_action(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
72 {
73 GaimConnection *gc = gaim_account_get_connection(irc->account);
74 char *action, *escaped, *dst, **newargs;
75 const char *src;
76 GaimConversation *convo;
77
78 if (!args || !args[0] || !gc)
79 return 0;
80
81 action = g_malloc(strlen(args[0]) + 10);
82
83 sprintf(action, "\001ACTION ");
84
85 src = args[0];
86 dst = action + 8;
87 while (*src) {
88 if (*src == '\n') {
89 if (*(src + 1) == '\0') {
90 break;
91 } else {
92 *dst++ = ' ';
93 src++;
94 continue;
95 }
96 }
97 *dst++ = *src++;
98 }
99 *dst++ = '\001';
100 *dst = '\0';
101
102 newargs = g_new0(char *, 2);
103 newargs[0] = g_strdup(target);
104 newargs[1] = action;
105 irc_cmd_privmsg(irc, cmd, target, (const char **)newargs);
106 g_free(newargs[0]);
107 g_free(newargs[1]);
108 g_free(newargs);
109
110 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, target, irc->account);
111 if (convo) {
112 escaped = g_markup_escape_text(args[0], -1);
113 action = g_strdup_printf("/me %s", escaped);
114 g_free(escaped);
115 if (action[strlen(action) - 1] == '\n')
116 action[strlen(action) - 1] = '\0';
117 if (gaim_conversation_get_type(convo) == GAIM_CONV_TYPE_CHAT)
118 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo)),
119 gaim_connection_get_display_name(gc),
120 0, action, time(NULL));
121 else
122 gaim_conv_im_write(GAIM_CONV_IM(convo), gaim_connection_get_display_name(gc),
123 action, 0, time(NULL));
124 g_free(action);
125 }
126
127 return 1;
128 }
129
130 int irc_cmd_ctcp_version(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
131 {
132 char *buf;
133
134
135 if (!args || !args[0])
136 return 0;
137
138 buf = irc_format(irc, "vn:", "PRIVMSG", args[0], "\001VERSION\001");
139 irc_send(irc, buf);
140 g_free(buf);
141
142 return 0;
143 }
144
145 int irc_cmd_invite(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
146 {
147 char *buf;
148
149 if (!args || !args[0] || !(args[1] || target))
150 return 0;
151
152 buf = irc_format(irc, "vnc", "INVITE", args[0], args[1] ? args[1] : target);
153 irc_send(irc, buf);
154 g_free(buf);
155
156 return 0;
157 }
158
159 int irc_cmd_join(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
160 {
161 char *buf;
162
163 if (!args || !args[0])
164 return 0;
165
166 if (args[1])
167 buf = irc_format(irc, "vcv", "JOIN", args[0], args[1]);
168 else
169 buf = irc_format(irc, "vc", "JOIN", args[0]);
170 irc_send(irc, buf);
171 g_free(buf);
172
173 return 0;
174 }
175
176 int irc_cmd_kick(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
177 {
178 char *buf;
179 GaimConversation *convo;
180
181 if (!args || !args[0])
182 return 0;
183
184 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, target, irc->account);
185 if (!convo)
186 return 0;
187
188 if (args[1])
189 buf = irc_format(irc, "vcn:", "KICK", target, args[0], args[1]);
190 else
191 buf = irc_format(irc, "vcn", "KICK", target, args[0]);
192 irc_send(irc, buf);
193 g_free(buf);
194
195 return 0;
196 }
197
198 int irc_cmd_list(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
199 {
200 gaim_roomlist_show_with_account(irc->account);
201
202 return 0;
203 }
204
205 int irc_cmd_mode(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
206 {
207 GaimConnection *gc;
208 char *buf;
209
210 if (!args)
211 return 0;
212
213 if (!strcmp(cmd, "mode")) {
214 if (!args[0] && irc_ischannel(target))
215 buf = irc_format(irc, "vc", "MODE", target);
216 else if (args[0] && (*args[0] == '+' || *args[0] == '-'))
217 buf = irc_format(irc, "vcv", "MODE", target, args[0]);
218 else if (args[0])
219 buf = irc_format(irc, "vv", "MODE", args[0]);
220 else
221 return 0;
222 } else if (!strcmp(cmd, "umode")) {
223 if (!args[0])
224 return 0;
225 gc = gaim_account_get_connection(irc->account);
226 buf = irc_format(irc, "vnv", "MODE", gaim_connection_get_display_name(gc), args[0]);
227 } else {
228 return 0;
229 }
230
231 irc_send(irc, buf);
232 g_free(buf);
233
234 return 0;
235 }
236
237 int irc_cmd_names(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
238 {
239 char *buf;
240
241 if (!args || (!args[0] && !irc_ischannel(target)))
242 return 0;
243
244 buf = irc_format(irc, "vc", "NAMES", args[0] ? args[0] : target);
245 irc_send(irc, buf);
246 g_free(buf);
247
248 irc->nameconv = g_strdup(target);
249
250 return 0;
251 }
252
253 int irc_cmd_nick(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
254 {
255 char *buf;
256
257 if (!args || !args[0])
258 return 0;
259
260 buf = irc_format(irc, "v:", "NICK", args[0]);
261 irc_send(irc, buf);
262 g_free(buf);
263
264 return 0;
265 }
266
267 int irc_cmd_op(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
268 {
269 char **nicks, **ops, *sign, *mode;
270 int i = 0, used = 0;
271
272 if (!args || !args[0] || !*args[0])
273 return 0;
274
275 if (!strcmp(cmd, "op")) {
276 sign = "+";
277 mode = "o";
278 } else if (!strcmp(cmd, "deop")) {
279 sign = "-";
280 mode = "o";
281 } else if (!strcmp(cmd, "voice")) {
282 sign = "+";
283 mode = "v";
284 } else if (!strcmp(cmd, "devoice")) {
285 sign = "-";
286 mode = "v";
287 } else {
288 gaim_debug(GAIM_DEBUG_ERROR, "irc", "invalid 'op' command '%s'\n", cmd);
289 return 0;
290 }
291
292 nicks = g_strsplit(args[0], " ", -1);
293
294 for (i = 0; nicks[i]; i++)
295 /* nothing */;
296 ops = g_new0(char *, i * 2 + 1);
297
298 for (i = 0; nicks[i]; i++) {
299 if (!*nicks[i])
300 continue;
301 ops[used++] = mode;
302 ops[used++] = nicks[i];
303 }
304
305 irc_do_mode(irc, target, sign, ops);
306 g_free(ops);
307
308 return 0;
309 }
310
311 int irc_cmd_part(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
312 {
313 char *buf;
314
315 if (!args)
316 return 0;
317
318 if (args[1])
319 buf = irc_format(irc, "vc:", "PART", args[0] ? args[0] : target, args[1]);
320 else
321 buf = irc_format(irc, "vc", "PART", args[0] ? args[0] : target);
322 irc_send(irc, buf);
323 g_free(buf);
324
325 return 0;
326 }
327
328 int irc_cmd_ping(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
329 {
330 char *stamp;
331 char *buf;
332
333 if (args && args[0]) {
334 if (irc_ischannel(args[0]))
335 return 0;
336 stamp = g_strdup_printf("\001PING %lu\001", time(NULL));
337 buf = irc_format(irc, "vn:", "PRIVMSG", args[0], stamp);
338 g_free(stamp);
339 } else if (target) {
340 stamp = g_strdup_printf("%s %lu", target, time(NULL));
341 buf = irc_format(irc, "v:", "PING", stamp);
342 g_free(stamp);
343 } else {
344 stamp = g_strdup_printf("%lu", time(NULL));
345 buf = irc_format(irc, "vv", "PING", stamp);
346 g_free(stamp);
347 }
348 irc_send(irc, buf);
349 g_free(buf);
350
351 return 0;
352 }
353
354 int irc_cmd_privmsg(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
355 {
356 const char *cur, *end;
357 char *msg, *buf;
358
359 if (!args || !args[0] || !args[1])
360 return 0;
361
362 cur = args[1];
363 end = args[1];
364 while (*end && *cur) {
365 end = strchr(cur, '\n');
366 if (!end)
367 end = cur + strlen(cur);
368 msg = g_strndup(cur, end - cur);
369 buf = irc_format(irc, "vt:", "PRIVMSG", args[0], msg);
370 irc_send(irc, buf);
371 g_free(msg);
372 g_free(buf);
373 cur = end + 1;
374 }
375
376 return 0;
377 }
378
379 int irc_cmd_quit(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
380 {
381 char *buf;
382
383 if (!irc->quitting) {
384 /*
385 * Use gaim_account_get_string(irc->account, "quitmsg", IRC_DEFAULT_QUIT)
386 * and uncomment the appropriate account preference in irc.c if we
387 * decide we want custom quit messages.
388 */
389 buf = irc_format(irc, "v:", "QUIT", (args && args[0]) ? args[0] : IRC_DEFAULT_QUIT);
390 irc_send(irc, buf);
391 g_free(buf);
392
393 irc->quitting = TRUE;
394
395 if (!irc->account->disconnecting)
396 gaim_account_set_status(irc->account, "offline", TRUE, NULL);
397 }
398
399 return 0;
400 }
401
402 int irc_cmd_quote(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
403 {
404 char *buf;
405
406 if (!args || !args[0])
407 return 0;
408
409 buf = irc_format(irc, "v", args[0]);
410 irc_send(irc, buf);
411 g_free(buf);
412
413 return 0;
414 }
415
416 int irc_cmd_query(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
417 {
418 GaimConversation *convo;
419 GaimConnection *gc;
420
421 if (!args || !args[0])
422 return 0;
423
424 convo = gaim_conversation_new(GAIM_CONV_TYPE_IM, irc->account, args[0]);
425 gaim_conversation_present(convo);
426
427 if (args[1]) {
428 gc = gaim_account_get_connection(irc->account);
429 irc_cmd_privmsg(irc, cmd, target, args);
430 gaim_conv_im_write(GAIM_CONV_IM(convo), gaim_connection_get_display_name(gc),
431 args[1], GAIM_MESSAGE_SEND, time(NULL));
432 }
433
434 return 0;
435 }
436
437 int irc_cmd_remove(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
438 {
439 char *buf;
440
441 if (!args || !args[0])
442 return 0;
443
444 if (!irc_ischannel(target)) /* not a channel, punt */
445 return 0;
446
447 if (args[1])
448 buf = irc_format(irc, "vcn:", "REMOVE", target, args[0], args[1]);
449 else
450 buf = irc_format(irc, "vcn", "REMOVE", target, args[0]);
451 irc_send(irc, buf);
452 g_free(buf);
453
454 return 0;
455 }
456
457 int irc_cmd_service(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
458 {
459 char *capital_cmd, *buf;
460
461 if (!args || !args[0])
462 return 0;
463
464 /* cmd will be one of nickserv, chanserv, memoserv or operserv */
465 capital_cmd = g_ascii_strup(cmd, -1);
466 buf = irc_format(irc, "v:", capital_cmd, args[0]);
467 irc_send(irc, buf);
468 g_free(capital_cmd);
469 g_free(buf);
470
471 return 0;
472 }
473
474 int irc_cmd_time(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
475 {
476 char *buf;
477
478 buf = irc_format(irc, "v", "TIME");
479 irc_send(irc, buf);
480 g_free(buf);
481
482 return 0;
483 }
484
485 int irc_cmd_topic(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
486 {
487 char *buf;
488 const char *topic;
489 GaimConversation *convo;
490
491 if (!args)
492 return 0;
493
494 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, target, irc->account);
495 if (!convo)
496 return 0;
497
498 if (!args[0]) {
499 topic = gaim_conv_chat_get_topic (GAIM_CONV_CHAT(convo));
500
501 if (topic) {
502 char *tmp, *tmp2;
503 tmp = g_markup_escape_text(topic, -1);
504 tmp2 = gaim_markup_linkify(tmp);
505 buf = g_strdup_printf(_("current topic is: %s"), tmp2);
506 g_free(tmp);
507 g_free(tmp2);
508 } else
509 buf = g_strdup(_("No topic is set"));
510 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), target, buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL));
511 g_free(buf);
512
513 return 0;
514 }
515
516 buf = irc_format(irc, "vt:", "TOPIC", target, args[0]);
517 irc_send(irc, buf);
518 g_free(buf);
519
520 return 0;
521 }
522
523 int irc_cmd_wallops(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
524 {
525 char *buf;
526
527 if (!args || !args[0])
528 return 0;
529
530 if (!strcmp(cmd, "wallops"))
531 buf = irc_format(irc, "v:", "WALLOPS", args[0]);
532 else if (!strcmp(cmd, "operwall"))
533 buf = irc_format(irc, "v:", "OPERWALL", args[0]);
534 else
535 return 0;
536
537 irc_send(irc, buf);
538 g_free(buf);
539
540 return 0;
541 }
542
543 int irc_cmd_whois(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
544 {
545 char *buf;
546
547 if (!args || !args[0])
548 return 0;
549
550 if (args[1]) {
551 buf = irc_format(irc, "vvn", "WHOIS", args[0], args[1]);
552 irc->whois.nick = g_strdup(args[1]);
553 } else {
554 buf = irc_format(irc, "vn", "WHOIS", args[0]);
555 irc->whois.nick = g_strdup(args[0]);
556 }
557
558 irc_send(irc, buf);
559 g_free(buf);
560
561 return 0;
562 }
563
564 static void irc_do_mode(struct irc_conn *irc, const char *target, const char *sign, char **ops)
565 {
566 char *buf, mode[5];
567 int i = 0;
568
569 if (!sign)
570 return;
571
572 while (ops[i]) {
573 if (ops[i + 2] && ops[i + 4]) {
574 g_snprintf(mode, sizeof(mode), "%s%s%s%s", sign,
575 ops[i], ops[i + 2], ops[i + 4]);
576 buf = irc_format(irc, "vcvnnn", "MODE", target, mode,
577 ops[i + 1], ops[i + 3], ops[i + 5]);
578 i += 6;
579 } else if (ops[i + 2]) {
580 g_snprintf(mode, sizeof(mode), "%s%s%s",
581 sign, ops[i], ops[i + 2]);
582 buf = irc_format(irc, "vcvnn", "MODE", target, mode,
583 ops[i + 1], ops[i + 3]);
584 i += 4;
585 } else {
586 g_snprintf(mode, sizeof(mode), "%s%s", sign, ops[i]);
587 buf = irc_format(irc, "vcvn", "MODE", target, mode, ops[i + 1]);
588 i += 2;
589 }
590 irc_send(irc, buf);
591 g_free(buf);
592 }
593
594 return;
595 }