src/protocols/irc/cmds.c

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

mercurial