comparison libpurple/protocols/jabber/adhoccommands.c @ 17598:43df07968000

Implemented XEP-0050: Ad-Hoc Commands. Note that this XEP requires sending an initial command to the peer, which is not implemented in libpurple itself (since this requires a discovery browser or equivalent).
author Andreas Monitzer <pidgin@monitzer.com>
date Tue, 19 Jun 2007 02:53:24 +0000
parents
children 8c3fbc353a9c
comparison
equal deleted inserted replaced
17597:5f4dcaf1f886 17598:43df07968000
1 /*
2 * purple - Jabber Protocol Plugin
3 *
4 * Copyright (C) 2007, Andreas Monitzer <andy@monitzer.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22 #include "adhoccommands.h"
23 #include <assert.h>
24 #include <string.h>
25 #include "internal.h"
26 #include "xdata.h"
27 #include "iq.h"
28 #include "request.h"
29
30 static void do_adhoc_ignoreme(JabberStream *js, ...) {
31 /* we don't have to do anything */
32 }
33
34 typedef struct _JabberAdHocActionInfo {
35 char *sessionid;
36 char *who;
37 char *node;
38 GList *actionslist;
39 } JabberAdHocActionInfo;
40
41 /*static void do_adhoc_parse_iq(JabberStream *js, xmlnode *packet, gpointer data) {
42 jabber_adhoc_parse(js, packet);
43 }*/
44
45 static void do_adhoc_action_cb(JabberStream *js, xmlnode *result, const char *actionhandle, gpointer user_data) {
46 xmlnode *command;
47 GList *action;
48 JabberAdHocActionInfo *actionInfo = user_data;
49 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET);
50 /* jabber_iq_set_callback(iq, do_adhoc_parse_iq, NULL);*/
51
52 xmlnode_set_attrib(iq->node, "to", actionInfo->who);
53 command = xmlnode_new_child(iq->node,"command");
54 xmlnode_set_namespace(command,"http://jabber.org/protocol/commands");
55 xmlnode_set_attrib(command,"sessionid",actionInfo->sessionid);
56 xmlnode_set_attrib(command,"node",actionInfo->node);
57 if(actionhandle)
58 xmlnode_set_attrib(command,"action",actionhandle);
59 xmlnode_insert_child(command,result);
60
61 for(action = actionInfo->actionslist; action; action = g_list_next(action)) {
62 char *handle = action->data;
63 g_free(handle);
64 }
65 g_list_free(actionInfo->actionslist);
66 g_free(actionInfo->sessionid);
67 g_free(actionInfo->who);
68 g_free(actionInfo->node);
69
70 jabber_iq_send(iq);
71 }
72
73 void jabber_adhoc_parse(JabberStream *js, xmlnode *packet) {
74 xmlnode *command = xmlnode_get_child_with_namespace(packet, "command", "http://jabber.org/protocol/commands");
75 const char *status = xmlnode_get_attrib(command,"status");
76 xmlnode *xdata = xmlnode_get_child_with_namespace(command,"x","jabber:x:data");
77
78 if(!status)
79 return;
80
81 if(!strcmp(status,"completed")) {
82 /* display result */
83 xmlnode *note = xmlnode_get_child(command,"note");
84
85 if(note)
86 purple_request_action(js, xmlnode_get_attrib(packet, "from"), xmlnode_get_data(note), NULL, 0, purple_connection_get_account(js->gc), xmlnode_get_attrib(packet, "from"), NULL, NULL, 1, _("OK"), do_adhoc_ignoreme);
87
88 if(xdata)
89 jabber_x_data_request(js, xdata, (jabber_x_data_cb)do_adhoc_ignoreme, NULL);
90 return;
91 }
92 if(!strcmp(status,"executing")) {
93 /* this command needs more steps */
94 xmlnode *actions, *action;
95 int actionindex = 0;
96 GList *actionslist = NULL;
97 JabberAdHocActionInfo *actionInfo;
98 if(!xdata)
99 return; /* shouldn't happen */
100
101 actions = xmlnode_get_child(command,"actions");
102 if(!actions) {
103 JabberXDataAction *defaultaction = g_new0(JabberXDataAction, 1);
104 defaultaction->name = g_strdup(_("execute"));
105 defaultaction->handle = g_strdup("execute");
106 actionslist = g_list_append(actionslist, defaultaction);
107 } else {
108 const char *defaultactionhandle = xmlnode_get_attrib(actions, "execute");
109 int index = 0;
110 for(action = actions->child; action; action = action->next, ++index) {
111 if(action->type == XMLNODE_TYPE_TAG) {
112 JabberXDataAction *newaction = g_new0(JabberXDataAction, 1);
113 newaction->name = g_strdup(_(action->name));
114 newaction->handle = g_strdup(action->name);
115 actionslist = g_list_append(actionslist, newaction);
116 if(defaultactionhandle && !strcmp(defaultactionhandle, action->name))
117 actionindex = index;
118 }
119 }
120 }
121
122 actionInfo = g_new0(JabberAdHocActionInfo, 1);
123 actionInfo->sessionid = g_strdup(xmlnode_get_attrib(command,"sessionid"));
124 actionInfo->who = g_strdup(xmlnode_get_attrib(packet,"from"));
125 actionInfo->node = g_strdup(xmlnode_get_attrib(command,"node"));
126 actionInfo->actionslist = actionslist;
127
128 jabber_x_data_request_with_actions(js,xdata,actionslist,actionindex,do_adhoc_action_cb,actionInfo);
129 }
130 }