1 /*
2 * Copyright (C) 2007 Colin DIDIER
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18 #include <stdlib.h>
19
20 #include "module.h"
21 #include "channels.h"
22 #include "nicklist.h"
23 #include "recode.h"
24 #include "settings.h"
25 #include "signals.h"
26 #include "window-item-def.h"
27
28 #include "xmpp-commands.h"
29 #include "xmpp-queries.h"
30 #include "xmpp-servers.h"
31 #include "rosters-tools.h"
32 #include "tools.h"
33
34 const char *xmpp_commands[] = {
35 "away",
36 "quote",
37 "roster",
38 "whois",
39 "presence",
40 NULL
41 };
42
43 const char *xmpp_command_roster[] = {
44 "full",
45 "add",
46 "remove",
47 "name",
48 "group",
49 NULL
50 };
51
52 const char *xmpp_command_presene[] = {
53 "accept",
54 "deny",
55 "subscribe",
56 "unsubscribe",
57 NULL
58 };
59
60 static char *
cmd_connect_get_line(const char * data)61 cmd_connect_get_line(const char *data)
62 {
63 GHashTable *optlist;
64 const char *port;
65 char *line, *jid, *password, *network, *network_free, *host, *host_free;
66 void *free_arg;
67
68 line = host_free = network_free = NULL;
69 if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS,
70 "xmppconnect", &optlist, &jid, &password))
71 return NULL;
72 if (*password == '\0')
73 password = g_strdup("\r"); /* we will prompt for password later */
74 if (*jid == '\0' || password == NULL || *password == '\0'
75 || !xmpp_have_domain(jid)) {
76 cmd_params_free(free_arg);
77 signal_emit("error command", 1,
78 GINT_TO_POINTER(CMDERR_NOT_ENOUGH_PARAMS));
79 signal_stop();
80 return NULL;
81 }
82 network = g_hash_table_lookup(optlist, "network");
83 if (network == NULL || *network == '\0') {
84 char *stripped = xmpp_strip_resource(jid);
85 network = network_free = g_strconcat("xmpp:", stripped, (void *)NULL);
86 g_free(stripped);
87 }
88 host = g_hash_table_lookup(optlist, "host");
89 if (host == NULL || *host == '\0')
90 host = host_free = xmpp_extract_domain(jid);
91 port = g_hash_table_lookup(optlist, "port");
92 if (port == NULL)
93 port = "0";
94 line = g_strdup_printf("%s-xmppnet \"%s\" %s %d \"%s\" \"%s\"",
95 (g_hash_table_lookup(optlist, "ssl") != NULL) ? "-ssl " : "",
96 network, host, atoi(port), password, jid);
97 g_free(network_free);
98 g_free(host_free);
99 cmd_params_free(free_arg);
100 return line;
101 }
102
103 /* SYNTAX: XMPPCONNECT [-ssl] [-host <server>] [-port <port>]
104 * <jid>[/<resource>] <password> */
105 static void
cmd_xmppconnect(const char * data,SERVER_REC * server,WI_ITEM_REC * item)106 cmd_xmppconnect(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
107 {
108 char *line, *cmd_line;
109
110 if ((line = cmd_connect_get_line(data)) == NULL)
111 return;
112 cmd_line = g_strconcat(settings_get_str("cmdchars"), "CONNECT ",
113 line, (void *)NULL);
114 g_free(line);
115 signal_emit("send command", 3, cmd_line, server, item);
116 g_free(cmd_line);
117 }
118
119 /* SYNTAX: XMPPSERVER [-ssl] [-host <server>] [-port <port>]
120 * <jid>[/<resource>] <password> */
121 static void
cmd_xmppserver(const char * data,SERVER_REC * server,WI_ITEM_REC * item)122 cmd_xmppserver(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
123 {
124 char *line, *cmd_line;
125
126 if ((line = cmd_connect_get_line(data)) == NULL)
127 return;
128 cmd_line = g_strconcat(settings_get_str("cmdchars"), "SERVER ",
129 line, (void *)NULL);
130 g_free(line);
131 signal_emit("send command", 3, cmd_line, server, item);
132 g_free(cmd_line);
133 }
134
135 static void
set_away(XMPP_SERVER_REC * server,const char * data)136 set_away(XMPP_SERVER_REC *server, const char *data)
137 {
138 char **tmp;
139 const char *reason;
140 int show, priority;
141
142 if (!IS_XMPP_SERVER(server))
143 return;
144 priority = settings_get_int("xmpp_priority");
145 tmp = g_strsplit(data, " ", 2);
146 if (*data == '\0') {
147 show = XMPP_PRESENCE_AVAILABLE;
148 reason = NULL;
149 } else {
150 show = xmpp_get_show(tmp[0]);
151 if (show == XMPP_PRESENCE_AVAILABLE && g_ascii_strcasecmp(
152 xmpp_presence_show[XMPP_PRESENCE_ONLINE], tmp[0]) != 0) {
153 show = xmpp_get_show(
154 settings_get_str("xmpp_default_away_mode"));
155 reason = data;
156 } else
157 reason = tmp[1];
158 if (show == XMPP_PRESENCE_AWAY)
159 priority = settings_get_int("xmpp_priority_away");
160 }
161 signal_emit("xmpp set presence", 4, server, show, reason,
162 priority);
163 g_strfreev(tmp);
164 }
165
166 /* SYNTAX: AWAY [-one | -all] [away|dnd|xa|chat] [<reason>] */
167 static void
cmd_away(const char * data,XMPP_SERVER_REC * server)168 cmd_away(const char *data, XMPP_SERVER_REC *server)
169 {
170 GHashTable *optlist;
171 char *reason;
172 void *free_arg;
173
174 CMD_XMPP_SERVER(server);
175 if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
176 PARAM_FLAG_GETREST, "away", &optlist, &reason))
177 return;
178 if (g_hash_table_lookup(optlist, "one") != NULL)
179 set_away(server, reason);
180 else
181 g_slist_foreach(servers, (GFunc)set_away, reason);
182 cmd_params_free(free_arg);
183 }
184
185 /* SYNTAX: QUOTE <raw_command> */
186 static void
cmd_quote(const char * data,XMPP_SERVER_REC * server)187 cmd_quote(const char *data, XMPP_SERVER_REC *server)
188 {
189 char *recoded;
190
191 CMD_XMPP_SERVER(server);
192 if (*data == '\0')
193 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
194 g_strstrip((char *)data);
195 if (*data == '\0')
196 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
197 signal_emit("xmpp xml out", 2, server, data);
198 recoded = xmpp_recode_out(data);
199 lm_connection_send_raw(server->lmconn, recoded, NULL);
200 g_free(recoded);
201 }
202
203 /* SYNTAX: ROSTER */
204 static void
cmd_roster(const char * data,XMPP_SERVER_REC * server,WI_ITEM_REC * item)205 cmd_roster(const char *data, XMPP_SERVER_REC *server, WI_ITEM_REC *item)
206 {
207 CMD_XMPP_SERVER(server);
208 if (*data == '\0')
209 signal_emit("xmpp roster show", 1, server);
210 else
211 command_runsub(xmpp_commands[XMPP_COMMAND_ROSTER], data,
212 server, item);
213 }
214
215 /* SYNTAX: ROSTER FULL */
216 static void
cmd_roster_full(const char * data,XMPP_SERVER_REC * server,WI_ITEM_REC * item)217 cmd_roster_full(const char *data, XMPP_SERVER_REC *server, WI_ITEM_REC *item)
218 {
219 gboolean oldvalue;
220
221 CMD_XMPP_SERVER(server);
222 oldvalue = settings_get_bool("xmpp_roster_show_offline");
223 if (!oldvalue)
224 settings_set_bool("xmpp_roster_show_offline", TRUE);
225 signal_emit("xmpp roster show", 1, server);
226 if (!oldvalue)
227 settings_set_bool("xmpp_roster_show_offline", oldvalue);
228 }
229
230 /* SYNTAX: ROSTER ADD <jid> */
231 static void
cmd_roster_add(const char * data,XMPP_SERVER_REC * server)232 cmd_roster_add(const char *data, XMPP_SERVER_REC *server)
233 {
234 LmMessage *lmsg;
235 LmMessageNode *query_node, *item_node;
236 GHashTable *optlist;
237 const char *jid;
238 char *jid_recoded;
239 void *free_arg;
240
241 CMD_XMPP_SERVER(server);
242 if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
243 "roster add", &optlist, &jid))
244 return;
245 if (*jid == '\0')
246 cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
247 lmsg = lm_message_new_with_sub_type(NULL,
248 LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET);
249 query_node = lm_message_node_add_child(lmsg->node, "query", NULL);
250 lm_message_node_set_attribute(query_node, "xmlns", "jabber:iq:roster");
251 jid_recoded = xmpp_recode_out(jid);
252 item_node = lm_message_node_add_child(query_node, "item", NULL);
253 lm_message_node_set_attribute(item_node, "jid", jid_recoded);
254 signal_emit("xmpp send iq", 2, server, lmsg);
255 lm_message_unref(lmsg);
256 if (g_hash_table_lookup(optlist, "nosub") == NULL) {
257 lmsg = lm_message_new_with_sub_type(jid_recoded,
258 LM_MESSAGE_TYPE_PRESENCE, LM_MESSAGE_SUB_TYPE_SUBSCRIBE);
259 signal_emit("xmpp send presence", 2, server, lmsg);
260 lm_message_unref(lmsg);
261 }
262 g_free(jid_recoded);
263 cmd_params_free(free_arg);
264 }
265
266
267 /* SYNTAX: ROSTER REMOVE <jid> */
268 static void
cmd_roster_remove(const char * data,XMPP_SERVER_REC * server)269 cmd_roster_remove(const char *data, XMPP_SERVER_REC *server)
270 {
271 LmMessage *lmsg;
272 LmMessageNode *query_node, *item_node;
273 XMPP_ROSTER_USER_REC *user;
274 const char *jid;
275 char *recoded;
276 void *free_arg;
277
278 CMD_XMPP_SERVER(server);
279 if (!cmd_get_params(data, &free_arg, 1, &jid))
280 return;
281 if (*jid == '\0')
282 cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
283 user = rosters_find_user(server->roster, jid, NULL, NULL);
284 if (user == NULL) {
285 signal_emit("xmpp not in roster", 2, server, jid);
286 goto out;
287 }
288 lmsg = lm_message_new_with_sub_type(NULL,
289 LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET);
290 query_node = lm_message_node_add_child(lmsg->node, "query", NULL);
291 lm_message_node_set_attribute(query_node, "xmlns", "jabber:iq:roster");
292 item_node = lm_message_node_add_child(query_node, "item", NULL);
293 recoded = xmpp_recode_out(jid);
294 lm_message_node_set_attribute(item_node, "jid", recoded);
295 g_free(recoded);
296 lm_message_node_set_attribute(item_node, "subscription", "remove");
297 signal_emit("xmpp send iq", 2, server, lmsg);
298 lm_message_unref(lmsg);
299
300 out:
301 cmd_params_free(free_arg);
302 }
303
304 /* SYNTAX: ROSTER NAME <jid> [<name>] */
305 static void
cmd_roster_name(const char * data,XMPP_SERVER_REC * server)306 cmd_roster_name(const char *data, XMPP_SERVER_REC *server)
307 {
308 LmMessage *lmsg;
309 LmMessageNode *query_node, *item_node;
310 XMPP_ROSTER_USER_REC *user;
311 XMPP_ROSTER_GROUP_REC *group;
312 const char *jid, *name;
313 char *recoded;
314 void *free_arg;
315
316 CMD_XMPP_SERVER(server);
317 if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &jid,
318 &name))
319 return;
320 if (*jid == '\0')
321 cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
322 user = rosters_find_user(server->roster, jid, &group, NULL);
323 if (user == NULL) {
324 signal_emit("xmpp not in roster", 2, server, jid);
325 goto out;
326 }
327 lmsg = lm_message_new_with_sub_type(NULL,
328 LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET);
329 query_node = lm_message_node_add_child(lmsg->node, "query", NULL);
330 lm_message_node_set_attribute(query_node, "xmlns", "jabber:iq:roster");
331 item_node = lm_message_node_add_child(query_node, "item", NULL);
332 recoded = xmpp_recode_out(jid);
333 lm_message_node_set_attribute(item_node, "jid", recoded);
334 g_free(recoded);
335 if (group->name != NULL) {
336 recoded = xmpp_recode_out(group->name);
337 lm_message_node_add_child(item_node, "group", recoded);
338 g_free(recoded);
339 }
340 if (*name != '\0') {
341 recoded = xmpp_recode_out(name);
342 lm_message_node_set_attribute(item_node, "name", recoded);
343 g_free(recoded);
344 }
345 signal_emit("xmpp send iq", 2, server, lmsg);
346 lm_message_unref(lmsg);
347
348 out:
349 cmd_params_free(free_arg);
350 }
351
352 /* SYNTAX: ROSTER GROUP <jid> [<group>] */
353 static void
cmd_roster_group(const char * data,XMPP_SERVER_REC * server)354 cmd_roster_group(const char *data, XMPP_SERVER_REC *server)
355 {
356 LmMessage *lmsg;
357 LmMessageNode *query_node, *item_node;
358 XMPP_ROSTER_USER_REC *user;
359 XMPP_ROSTER_GROUP_REC *group;
360 const char *jid, *group_name;
361 char *recoded;
362 void *free_arg;
363
364 CMD_XMPP_SERVER(server);
365 if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &jid,
366 &group_name))
367 return;
368 if (*jid == '\0')
369 cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
370 user = rosters_find_user(server->roster, jid, &group, NULL);
371 if (user == NULL) {
372 signal_emit("xmpp not in roster", 2, server, jid);
373 goto out;
374 }
375 lmsg = lm_message_new_with_sub_type(NULL,
376 LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET);
377 query_node = lm_message_node_add_child(lmsg->node, "query", NULL);
378 lm_message_node_set_attribute(query_node, "xmlns", "jabber:iq:roster");
379 item_node = lm_message_node_add_child(query_node, "item", NULL);
380 recoded = xmpp_recode_out(jid);
381 lm_message_node_set_attribute(item_node, "jid", recoded);
382 g_free(recoded);
383 if (*group_name != '\0') {
384 recoded = xmpp_recode_out(group_name);
385 lm_message_node_add_child(item_node, "group", recoded);
386 g_free(recoded);
387 }
388 if (user->name != NULL) {
389 recoded = xmpp_recode_out(user->name);
390 lm_message_node_set_attribute(item_node, "name", recoded);
391 g_free(recoded);
392 }
393 signal_emit("xmpp send iq", 2, server, lmsg);
394 lm_message_unref(lmsg);
395
396 out:
397 cmd_params_free(free_arg);
398 }
399
400 /* SYNTAX: PRESENCE */
401 static void
cmd_presence(const char * data,XMPP_SERVER_REC * server,WI_ITEM_REC * item)402 cmd_presence(const char *data, XMPP_SERVER_REC *server, WI_ITEM_REC *item)
403 {
404 CMD_XMPP_SERVER(server);
405 if (*data == '\0')
406 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
407 else
408 command_runsub(xmpp_commands[XMPP_COMMAND_PRESENCE], data,
409 server, item);
410 }
411
412
413 /* SYNTAX: PRESENCE ACCEPT <jid> */
414 static void
cmd_presence_accept(const char * data,XMPP_SERVER_REC * server)415 cmd_presence_accept(const char *data, XMPP_SERVER_REC *server)
416 {
417 LmMessage *lmsg;
418 const char *jid;
419 char *recoded;
420 void *free_arg;
421
422 CMD_XMPP_SERVER(server);
423 if (!cmd_get_params(data, &free_arg, 1, &jid))
424 return;
425 if (*jid == '\0')
426 cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
427 recoded = xmpp_recode_out(jid);
428 lmsg = lm_message_new_with_sub_type(recoded,
429 LM_MESSAGE_TYPE_PRESENCE, LM_MESSAGE_SUB_TYPE_SUBSCRIBED);
430 g_free(recoded);
431 signal_emit("xmpp send presence", 2, server, lmsg);
432 lm_message_unref(lmsg);
433 cmd_params_free(free_arg);
434 }
435
436 /* SYNTAX: PRESENCE DENY <jid> */
437 static void
cmd_presence_deny(const char * data,XMPP_SERVER_REC * server)438 cmd_presence_deny(const char *data, XMPP_SERVER_REC *server)
439 {
440 LmMessage *lmsg;
441 const char *jid;
442 char *recoded;
443 void *free_arg;
444
445 CMD_XMPP_SERVER(server);
446 if (!cmd_get_params(data, &free_arg, 1, &jid))
447 return;
448 if (*jid == '\0')
449 cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
450 recoded = xmpp_recode_out(jid);
451 lmsg = lm_message_new_with_sub_type(recoded,
452 LM_MESSAGE_TYPE_PRESENCE,LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED);
453 g_free(recoded);
454 signal_emit("xmpp send presence", 2, server, lmsg);
455 lm_message_unref(lmsg);
456 cmd_params_free(free_arg);
457 }
458
459 /* SYNTAX: PRESENCE SUBSCRIBE <jid> [<reason>] */
460 static void
cmd_presence_subscribe(const char * data,XMPP_SERVER_REC * server)461 cmd_presence_subscribe(const char *data, XMPP_SERVER_REC *server)
462 {
463 LmMessage *lmsg;
464 const char *jid, *reason;
465 char *recoded;
466 void *free_arg;
467
468 CMD_XMPP_SERVER(server);
469 if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &jid,
470 &reason))
471 return;
472 if (*jid == '\0')
473 cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
474 recoded = xmpp_recode_out(jid);
475 lmsg = lm_message_new_with_sub_type(recoded,
476 LM_MESSAGE_TYPE_PRESENCE, LM_MESSAGE_SUB_TYPE_SUBSCRIBE);
477 g_free(recoded);
478 if (*reason != '\0') {
479 recoded = xmpp_recode_out(reason);
480 lm_message_node_add_child(lmsg->node, "status", recoded);
481 g_free(recoded);
482 }
483 signal_emit("xmpp send presence", 2, server, lmsg);
484 lm_message_unref(lmsg);
485 cmd_params_free(free_arg);
486 }
487
488 /* SYNTAX: PRESENCE UNSUBSCRIBE <jid> */
489 static void
cmd_presence_unsubscribe(const char * data,XMPP_SERVER_REC * server)490 cmd_presence_unsubscribe(const char *data, XMPP_SERVER_REC *server)
491 {
492 LmMessage *lmsg;
493 const char *jid;
494 char *recoded;
495 void *free_arg;
496
497 CMD_XMPP_SERVER(server);
498 if (!cmd_get_params(data, &free_arg, 1, &jid))
499 return;
500 if (*jid == '\0')
501 cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
502 recoded = xmpp_recode_out(jid);
503 lmsg = lm_message_new_with_sub_type(recoded,
504 LM_MESSAGE_TYPE_PRESENCE, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE);
505 g_free(recoded);
506 signal_emit("xmpp send presence", 2, server, lmsg);
507 lm_message_unref(lmsg);
508 cmd_params_free(free_arg);
509 }
510
511 /* SYNTAX: ME <message> */
512 static void
cmd_me(const char * data,XMPP_SERVER_REC * server,WI_ITEM_REC * item)513 cmd_me(const char *data, XMPP_SERVER_REC *server, WI_ITEM_REC *item)
514 {
515 const char *target;
516 char *str, *recoded;
517 int type;
518
519 CMD_XMPP_SERVER(server);
520 if (item == NULL || *data == '\0')
521 return;
522 g_strstrip((char *)data);
523 if (*data == '\0')
524 return;
525 target = window_item_get_target(item);
526 type = IS_CHANNEL(item) ? SEND_TARGET_CHANNEL : SEND_TARGET_NICK;
527 if (type == SEND_TARGET_NICK)
528 signal_emit("message xmpp own_action", 4, server, data, target,
529 SEND_TARGET_NICK);
530 str = g_strconcat("/me ", data, (void *)NULL);
531 recoded = recode_out(SERVER(server), str, target);
532 g_free(str);
533 server->send_message(SERVER(server), target, recoded, type);
534 g_free(recoded);
535 }
536
537 char *
xmpp_get_dest(const char * cmd_dest,XMPP_SERVER_REC * server,WI_ITEM_REC * item)538 xmpp_get_dest(const char *cmd_dest, XMPP_SERVER_REC *server, WI_ITEM_REC *item)
539 {
540 NICK_REC *nick;
541 char *dest;
542
543 if (cmd_dest == NULL || *cmd_dest == '\0')
544 return IS_QUERY(item) ? g_strdup(QUERY(item)->name)
545 : g_strconcat(server->jid, "/", server->resource, (void *)NULL);
546 if (IS_CHANNEL(item)
547 && (nick = nicklist_find(CHANNEL(item), cmd_dest)) != NULL)
548 return g_strdup(nick->host);
549 if ((dest = rosters_resolve_name(server, cmd_dest)) != NULL)
550 return dest;
551 return g_strdup(cmd_dest);
552 }
553
554 void
xmpp_commands_init(void)555 xmpp_commands_init(void)
556 {
557 command_set_options("connect", "+xmppnet");
558 command_set_options("server add", "-xmppnet");
559 command_bind("xmppconnect", NULL, (SIGNAL_FUNC)cmd_xmppconnect);
560 command_set_options("xmppconnect", "ssl -network -host @port");
561 command_bind("xmppserver", NULL, (SIGNAL_FUNC)cmd_xmppserver);
562 command_bind_xmpp("away", NULL, (SIGNAL_FUNC)cmd_away);
563 command_bind_xmpp("quote", NULL, (SIGNAL_FUNC)cmd_quote);
564 command_bind_xmpp("roster", NULL, (SIGNAL_FUNC)cmd_roster);
565 command_bind_xmpp("roster full", NULL, (SIGNAL_FUNC)cmd_roster_full);
566 command_bind_xmpp("roster add", NULL, (SIGNAL_FUNC)cmd_roster_add);
567 command_set_options("roster add", "nosub");
568 command_bind_xmpp("roster remove", NULL,
569 (SIGNAL_FUNC)cmd_roster_remove);
570 command_bind_xmpp("roster name", NULL, (SIGNAL_FUNC)cmd_roster_name);
571 command_bind_xmpp("roster group", NULL, (SIGNAL_FUNC)cmd_roster_group);
572 command_bind_xmpp("presence", NULL, (SIGNAL_FUNC)cmd_presence);
573 command_bind_xmpp("presence accept", NULL,
574 (SIGNAL_FUNC)cmd_presence_accept);
575 command_bind_xmpp("presence deny", NULL,
576 (SIGNAL_FUNC)cmd_presence_deny);
577 command_bind_xmpp("presence subscribe", NULL,
578 (SIGNAL_FUNC)cmd_presence_subscribe);
579 command_bind_xmpp("presence unsubscribe", NULL,
580 (SIGNAL_FUNC)cmd_presence_unsubscribe);
581 command_bind_xmpp("me", NULL, (SIGNAL_FUNC)cmd_me);
582 settings_add_str("xmpp", "xmpp_default_away_mode", "away");
583 }
584
585 void
xmpp_commands_deinit(void)586 xmpp_commands_deinit(void)
587 {
588 command_unbind("xmppconnect", (SIGNAL_FUNC)cmd_xmppconnect);
589 command_unbind("xmppserver", (SIGNAL_FUNC)cmd_xmppserver);
590 command_unbind("away", (SIGNAL_FUNC)cmd_away);
591 command_unbind("quote", (SIGNAL_FUNC)cmd_quote);
592 command_unbind("roster", (SIGNAL_FUNC)cmd_roster);
593 command_unbind("roster full", (SIGNAL_FUNC)cmd_roster_full);
594 command_unbind("roster add", (SIGNAL_FUNC)cmd_roster_add);
595 command_unbind("roster remove", (SIGNAL_FUNC)cmd_roster_remove);
596 command_unbind("roster name", (SIGNAL_FUNC)cmd_roster_name);
597 command_unbind("roster group", (SIGNAL_FUNC)cmd_roster_group);
598 command_unbind("presence", (SIGNAL_FUNC)cmd_presence);
599 command_unbind("presence accept", (SIGNAL_FUNC)cmd_presence_accept);
600 command_unbind("presence deny", (SIGNAL_FUNC)cmd_presence_deny);
601 command_unbind("presence subscribe",
602 (SIGNAL_FUNC)cmd_presence_subscribe);
603 command_unbind("presence unsubscribe",
604 (SIGNAL_FUNC)cmd_presence_unsubscribe);
605 command_unbind("me", (SIGNAL_FUNC)cmd_me);
606 }
607