comparison libgaim/protocols/irc/cmds.c @ 14192:60b1bc8dbf37

[gaim-migrate @ 16863] Renamed 'core' to 'libgaim' committer: Tailor Script <tailor@pidgin.im>
author Evan Schoenberg <evan.s@dreskin.net>
date Sat, 19 Aug 2006 01:50:10 +0000
parents
children a5c7db7be826
comparison
equal deleted inserted replaced
14191:009db0b357b5 14192:60b1bc8dbf37
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 {
340 stamp = g_strdup_printf("%s %lu", target, time(NULL));
341 buf = irc_format(irc, "v:", "PING", stamp);
342 g_free(stamp);
343 }
344 irc_send(irc, buf);
345 g_free(buf);
346
347 return 0;
348 }
349
350 int irc_cmd_privmsg(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
351 {
352 const char *cur, *end;
353 char *msg, *buf;
354
355 if (!args || !args[0] || !args[1])
356 return 0;
357
358 cur = args[1];
359 end = args[1];
360 while (*end && *cur) {
361 end = strchr(cur, '\n');
362 if (!end)
363 end = cur + strlen(cur);
364 msg = g_strndup(cur, end - cur);
365 buf = irc_format(irc, "vt:", "PRIVMSG", args[0], msg);
366 irc_send(irc, buf);
367 g_free(msg);
368 g_free(buf);
369 cur = end + 1;
370 }
371
372 return 0;
373 }
374
375 int irc_cmd_quit(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
376 {
377 char *buf;
378
379 if (!irc->quitting) {
380 /*
381 * Use gaim_account_get_string(irc->account, "quitmsg", IRC_DEFAULT_QUIT)
382 * and uncomment the appropriate account preference in irc.c if we
383 * decide we want custom quit messages.
384 */
385 buf = irc_format(irc, "v:", "QUIT", (args && args[0]) ? args[0] : IRC_DEFAULT_QUIT);
386 irc_send(irc, buf);
387 g_free(buf);
388
389 irc->quitting = TRUE;
390
391 if (!irc->account->disconnecting)
392 gaim_account_set_status(irc->account, "offline", TRUE, NULL);
393 }
394
395 return 0;
396 }
397
398 int irc_cmd_quote(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
399 {
400 char *buf;
401
402 if (!args || !args[0])
403 return 0;
404
405 buf = irc_format(irc, "v", args[0]);
406 irc_send(irc, buf);
407 g_free(buf);
408
409 return 0;
410 }
411
412 int irc_cmd_query(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
413 {
414 GaimConversation *convo;
415 GaimConnection *gc;
416
417 if (!args || !args[0])
418 return 0;
419
420 convo = gaim_conversation_new(GAIM_CONV_TYPE_IM, irc->account, args[0]);
421 gaim_conversation_present(convo);
422
423 if (args[1]) {
424 gc = gaim_account_get_connection(irc->account);
425 irc_cmd_privmsg(irc, cmd, target, args);
426 gaim_conv_im_write(GAIM_CONV_IM(convo), gaim_connection_get_display_name(gc),
427 args[1], GAIM_MESSAGE_SEND, time(NULL));
428 }
429
430 return 0;
431 }
432
433 int irc_cmd_remove(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
434 {
435 char *buf;
436
437 if (!args || !args[0])
438 return 0;
439
440 if (!irc_ischannel(target)) /* not a channel, punt */
441 return 0;
442
443 if (args[1])
444 buf = irc_format(irc, "vcn:", "REMOVE", target, args[0], args[1]);
445 else
446 buf = irc_format(irc, "vcn", "REMOVE", target, args[0]);
447 irc_send(irc, buf);
448 g_free(buf);
449
450 return 0;
451 }
452
453 int irc_cmd_service(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
454 {
455 char *capital_cmd, *buf;
456
457 if (!args || !args[0])
458 return 0;
459
460 /* cmd will be one of nickserv, chanserv, memoserv or operserv */
461 capital_cmd = g_ascii_strup(cmd, -1);
462 buf = irc_format(irc, "v:", capital_cmd, args[0]);
463 irc_send(irc, buf);
464 g_free(capital_cmd);
465 g_free(buf);
466
467 return 0;
468 }
469
470 int irc_cmd_time(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
471 {
472 char *buf;
473
474 buf = irc_format(irc, "v", "TIME");
475 irc_send(irc, buf);
476 g_free(buf);
477
478 return 0;
479 }
480
481 int irc_cmd_topic(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
482 {
483 char *buf;
484 const char *topic;
485 GaimConversation *convo;
486
487 if (!args)
488 return 0;
489
490 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, target, irc->account);
491 if (!convo)
492 return 0;
493
494 if (!args[0]) {
495 topic = gaim_conv_chat_get_topic (GAIM_CONV_CHAT(convo));
496
497 if (topic) {
498 char *tmp, *tmp2;
499 tmp = g_markup_escape_text(topic, -1);
500 tmp2 = gaim_markup_linkify(tmp);
501 buf = g_strdup_printf(_("current topic is: %s"), tmp2);
502 g_free(tmp);
503 g_free(tmp2);
504 } else
505 buf = g_strdup(_("No topic is set"));
506 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), target, buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL));
507 g_free(buf);
508
509 return 0;
510 }
511
512 buf = irc_format(irc, "vt:", "TOPIC", target, args[0]);
513 irc_send(irc, buf);
514 g_free(buf);
515
516 return 0;
517 }
518
519 int irc_cmd_wallops(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
520 {
521 char *buf;
522
523 if (!args || !args[0])
524 return 0;
525
526 if (!strcmp(cmd, "wallops"))
527 buf = irc_format(irc, "v:", "WALLOPS", args[0]);
528 else if (!strcmp(cmd, "operwall"))
529 buf = irc_format(irc, "v:", "OPERWALL", args[0]);
530 else
531 return 0;
532
533 irc_send(irc, buf);
534 g_free(buf);
535
536 return 0;
537 }
538
539 int irc_cmd_whois(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
540 {
541 char *buf;
542
543 if (!args || !args[0])
544 return 0;
545
546 if (args[1]) {
547 buf = irc_format(irc, "vvn", "WHOIS", args[0], args[1]);
548 irc->whois.nick = g_strdup(args[1]);
549 } else {
550 buf = irc_format(irc, "vn", "WHOIS", args[0]);
551 irc->whois.nick = g_strdup(args[0]);
552 }
553
554 irc_send(irc, buf);
555 g_free(buf);
556
557 return 0;
558 }
559
560 static void irc_do_mode(struct irc_conn *irc, const char *target, const char *sign, char **ops)
561 {
562 char *buf, mode[5];
563 int i = 0;
564
565 if (!sign)
566 return;
567
568 while (ops[i]) {
569 if (ops[i + 2] && ops[i + 4]) {
570 g_snprintf(mode, sizeof(mode), "%s%s%s%s", sign,
571 ops[i], ops[i + 2], ops[i + 4]);
572 buf = irc_format(irc, "vcvnnn", "MODE", target, mode,
573 ops[i + 1], ops[i + 3], ops[i + 5]);
574 i += 6;
575 } else if (ops[i + 2]) {
576 g_snprintf(mode, sizeof(mode), "%s%s%s",
577 sign, ops[i], ops[i + 2]);
578 buf = irc_format(irc, "vcvnn", "MODE", target, mode,
579 ops[i + 1], ops[i + 3]);
580 i += 4;
581 } else {
582 g_snprintf(mode, sizeof(mode), "%s%s", sign, ops[i]);
583 buf = irc_format(irc, "vcvn", "MODE", target, mode, ops[i + 1]);
584 i += 2;
585 }
586 irc_send(irc, buf);
587 g_free(buf);
588 }
589
590 return;
591 }