Wed, 21 Jan 2009 00:19:33 +0000
Don't track a cb-per-POST and remove the PurpleHTTPResponse structure.
The only callback ever used is http_received_cb and the ordering of
responses from the server is not guaranteed to match the order of our requests,
so the metaphor of matching them doesn't make sense. Instead of that, just
track the number of requests (to ensure there is always a request outstanding).
Additionally, pass the data const-ified instead of copying it. It's just
fed to an XML parser anyway.
UPDATE:
Tobias pointed out my explanation was flat-out wrong. The server's replies *do*
correspond to a specific request (HTTP pipelining). I believe what I meant to
say is that the XML in the replies isn't guaranteed to correspond to the
request's payload.
In any event, the critical point is that the callback is always the same, so
there's no need to store it per-request.
| 7923 | 1 | /* |
| 15884 | 2 | * purple - Jabber Protocol Plugin |
| 7923 | 3 | * |
| 4 | * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.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 | |
|
19859
71d37b57eff2
The FSF changed its address a while ago; our files were out of date.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
19051
diff
changeset
|
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| 7923 | 19 | * |
| 20 | */ | |
| 21 | #include "internal.h" | |
| 22 | #include "request.h" | |
| 23 | #include "server.h" | |
| 24 | ||
| 25 | #include "xdata.h" | |
| 26 | ||
| 27 | typedef enum { | |
| 28 | JABBER_X_DATA_IGNORE = 0, | |
| 29 | JABBER_X_DATA_TEXT_SINGLE, | |
| 30 | JABBER_X_DATA_TEXT_MULTI, | |
| 31 | JABBER_X_DATA_LIST_SINGLE, | |
| 32 | JABBER_X_DATA_LIST_MULTI, | |
| 8295 | 33 | JABBER_X_DATA_BOOLEAN, |
| 34 | JABBER_X_DATA_JID_SINGLE | |
| 7923 | 35 | } jabber_x_data_field_type; |
| 36 | ||
| 37 | struct jabber_x_data_data { | |
| 38 | GHashTable *fields; | |
| 39 | GSList *values; | |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
40 | jabber_x_data_action_cb cb; |
| 7923 | 41 | gpointer user_data; |
| 42 | JabberStream *js; | |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
43 | GList *actions; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
44 | PurpleRequestFieldGroup *actiongroup; |
| 7923 | 45 | }; |
| 46 | ||
| 15884 | 47 | static void jabber_x_data_ok_cb(struct jabber_x_data_data *data, PurpleRequestFields *fields) { |
| 7923 | 48 | xmlnode *result = xmlnode_new("x"); |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
49 | jabber_x_data_action_cb cb = data->cb; |
| 7923 | 50 | gpointer user_data = data->user_data; |
| 51 | JabberStream *js = data->js; | |
| 52 | GList *groups, *flds; | |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
53 | char *actionhandle = NULL; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
54 | gboolean hasActions = (data->actions != NULL); |
| 7923 | 55 | |
| 13808 | 56 | xmlnode_set_namespace(result, "jabber:x:data"); |
| 7923 | 57 | xmlnode_set_attrib(result, "type", "submit"); |
| 58 | ||
| 15884 | 59 | for(groups = purple_request_fields_get_groups(fields); groups; groups = groups->next) { |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
60 | if(groups->data == data->actiongroup) { |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
61 | for(flds = purple_request_field_group_get_fields(groups->data); flds; flds = flds->next) { |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
62 | PurpleRequestField *field = flds->data; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
63 | const char *id = purple_request_field_get_id(field); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
64 | int handleindex; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
65 | if(strcmp(id, "libpurple:jabber:xdata:actions")) |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
66 | continue; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
67 | handleindex = purple_request_field_choice_get_value(field); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
68 | actionhandle = g_strdup(g_list_nth_data(data->actions, handleindex)); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
69 | break; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
70 | } |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
71 | continue; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
72 | } |
| 15884 | 73 | for(flds = purple_request_field_group_get_fields(groups->data); flds; flds = flds->next) { |
| 7923 | 74 | xmlnode *fieldnode, *valuenode; |
| 15884 | 75 | PurpleRequestField *field = flds->data; |
| 76 | const char *id = purple_request_field_get_id(field); | |
| 7923 | 77 | jabber_x_data_field_type type = GPOINTER_TO_INT(g_hash_table_lookup(data->fields, id)); |
| 78 | ||
| 79 | switch(type) { | |
| 80 | case JABBER_X_DATA_TEXT_SINGLE: | |
| 8295 | 81 | case JABBER_X_DATA_JID_SINGLE: |
| 7923 | 82 | { |
| 15884 | 83 | const char *value = purple_request_field_string_get_value(field); |
|
16398
a895aca0a7ce
Ok I couldn't resist. For iChat and Adium buddies who are advertising
Mark Doliner <markdoliner@pidgin.im>
parents:
16136
diff
changeset
|
84 | if (value == NULL) |
|
a895aca0a7ce
Ok I couldn't resist. For iChat and Adium buddies who are advertising
Mark Doliner <markdoliner@pidgin.im>
parents:
16136
diff
changeset
|
85 | break; |
| 7923 | 86 | fieldnode = xmlnode_new_child(result, "field"); |
| 87 | xmlnode_set_attrib(fieldnode, "var", id); | |
| 88 | valuenode = xmlnode_new_child(fieldnode, "value"); | |
| 89 | if(value) | |
| 90 | xmlnode_insert_data(valuenode, value, -1); | |
| 91 | break; | |
| 92 | } | |
| 93 | case JABBER_X_DATA_TEXT_MULTI: | |
| 94 | { | |
| 95 | char **pieces, **p; | |
| 15884 | 96 | const char *value = purple_request_field_string_get_value(field); |
|
16398
a895aca0a7ce
Ok I couldn't resist. For iChat and Adium buddies who are advertising
Mark Doliner <markdoliner@pidgin.im>
parents:
16136
diff
changeset
|
97 | if (value == NULL) |
|
a895aca0a7ce
Ok I couldn't resist. For iChat and Adium buddies who are advertising
Mark Doliner <markdoliner@pidgin.im>
parents:
16136
diff
changeset
|
98 | break; |
| 7923 | 99 | fieldnode = xmlnode_new_child(result, "field"); |
| 100 | xmlnode_set_attrib(fieldnode, "var", id); | |
| 101 | ||
| 102 | pieces = g_strsplit(value, "\n", -1); | |
| 103 | for(p = pieces; *p != NULL; p++) { | |
| 104 | valuenode = xmlnode_new_child(fieldnode, "value"); | |
| 105 | xmlnode_insert_data(valuenode, *p, -1); | |
| 106 | } | |
| 107 | g_strfreev(pieces); | |
| 108 | } | |
| 109 | break; | |
| 110 | case JABBER_X_DATA_LIST_SINGLE: | |
| 111 | case JABBER_X_DATA_LIST_MULTI: | |
| 112 | { | |
|
18190
bcf28ef7e8ff
Re-fix the DBus list handling code by killing const GList* / const GSList*
Richard Laager <rlaager@pidgin.im>
parents:
16490
diff
changeset
|
113 | GList *selected = purple_request_field_list_get_selected(field); |
| 7923 | 114 | char *value; |
| 115 | fieldnode = xmlnode_new_child(result, "field"); | |
| 116 | xmlnode_set_attrib(fieldnode, "var", id); | |
| 117 | ||
| 118 | while(selected) { | |
| 15884 | 119 | value = purple_request_field_list_get_data(field, selected->data); |
| 7923 | 120 | valuenode = xmlnode_new_child(fieldnode, "value"); |
| 121 | if(value) | |
| 122 | xmlnode_insert_data(valuenode, value, -1); | |
| 123 | selected = selected->next; | |
| 124 | } | |
| 125 | } | |
| 126 | break; | |
| 127 | case JABBER_X_DATA_BOOLEAN: | |
| 128 | fieldnode = xmlnode_new_child(result, "field"); | |
| 129 | xmlnode_set_attrib(fieldnode, "var", id); | |
| 130 | valuenode = xmlnode_new_child(fieldnode, "value"); | |
| 15884 | 131 | if(purple_request_field_bool_get_value(field)) |
| 7923 | 132 | xmlnode_insert_data(valuenode, "1", -1); |
| 133 | else | |
| 134 | xmlnode_insert_data(valuenode, "0", -1); | |
| 135 | break; | |
| 136 | case JABBER_X_DATA_IGNORE: | |
| 137 | break; | |
| 138 | } | |
| 139 | } | |
| 140 | } | |
| 141 | ||
| 142 | g_hash_table_destroy(data->fields); | |
| 143 | while(data->values) { | |
| 144 | g_free(data->values->data); | |
| 145 | data->values = g_slist_delete_link(data->values, data->values); | |
| 146 | } | |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
147 | if (data->actions) { |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
148 | GList *action; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
149 | for(action = data->actions; action; action = g_list_next(action)) { |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
150 | g_free(action->data); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
151 | } |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
152 | g_list_free(data->actions); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
153 | } |
| 7923 | 154 | g_free(data); |
| 155 | ||
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
156 | if (hasActions) { |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
157 | cb(js, result, actionhandle, user_data); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
158 | g_free(actionhandle); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
159 | } else |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
160 | ((jabber_x_data_cb)cb)(js, result, user_data); |
| 7923 | 161 | } |
| 162 | ||
| 15884 | 163 | static void jabber_x_data_cancel_cb(struct jabber_x_data_data *data, PurpleRequestFields *fields) { |
| 7923 | 164 | xmlnode *result = xmlnode_new("x"); |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
165 | jabber_x_data_action_cb cb = data->cb; |
| 7923 | 166 | gpointer user_data = data->user_data; |
| 167 | JabberStream *js = data->js; | |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
168 | gboolean hasActions = FALSE; |
| 7923 | 169 | g_hash_table_destroy(data->fields); |
| 170 | while(data->values) { | |
| 171 | g_free(data->values->data); | |
| 172 | data->values = g_slist_delete_link(data->values, data->values); | |
| 173 | } | |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
174 | if (data->actions) { |
|
19899
483c4f495a6c
Various warning fixes for the xmpp prpl.
Daniel Atallah <datallah@pidgin.im>
parents:
19897
diff
changeset
|
175 | GList *action; |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
176 | hasActions = TRUE; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
177 | for(action = data->actions; action; action = g_list_next(action)) { |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
178 | g_free(action->data); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
179 | } |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
180 | g_list_free(data->actions); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
181 | } |
| 7923 | 182 | g_free(data); |
| 183 | ||
| 13808 | 184 | xmlnode_set_namespace(result, "jabber:x:data"); |
| 7923 | 185 | xmlnode_set_attrib(result, "type", "cancel"); |
| 186 | ||
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
187 | if (hasActions) |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
188 | cb(js, result, NULL, user_data); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
189 | else |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
190 | ((jabber_x_data_cb)cb)(js, result, user_data); |
| 7923 | 191 | } |
| 192 | ||
| 8396 | 193 | void *jabber_x_data_request(JabberStream *js, xmlnode *packet, jabber_x_data_cb cb, gpointer user_data) |
| 7923 | 194 | { |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
195 | return jabber_x_data_request_with_actions(js, packet, NULL, 0, (jabber_x_data_action_cb)cb, user_data); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
196 | } |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
197 | |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
198 | void *jabber_x_data_request_with_actions(JabberStream *js, xmlnode *packet, GList *actions, int defaultaction, jabber_x_data_action_cb cb, gpointer user_data) |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
199 | { |
| 8396 | 200 | void *handle; |
| 7923 | 201 | xmlnode *fn, *x; |
| 15884 | 202 | PurpleRequestFields *fields; |
| 203 | PurpleRequestFieldGroup *group; | |
|
23493
e04778a3d29a
Kill the warning 'field' may be used uninitialized in this function
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
23402
diff
changeset
|
204 | PurpleRequestField *field = NULL; |
| 7923 | 205 | |
| 206 | char *title = NULL; | |
| 207 | char *instructions = NULL; | |
| 208 | ||
| 209 | struct jabber_x_data_data *data = g_new0(struct jabber_x_data_data, 1); | |
| 210 | ||
| 211 | data->fields = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); | |
| 212 | data->user_data = user_data; | |
| 213 | data->cb = cb; | |
| 214 | data->js = js; | |
| 215 | ||
| 15884 | 216 | fields = purple_request_fields_new(); |
| 217 | group = purple_request_field_group_new(NULL); | |
| 218 | purple_request_fields_add_group(fields, group); | |
| 7923 | 219 | |
| 8135 | 220 | for(fn = xmlnode_get_child(packet, "field"); fn; fn = xmlnode_get_next_twin(fn)) { |
| 221 | xmlnode *valuenode; | |
| 222 | const char *type = xmlnode_get_attrib(fn, "type"); | |
| 223 | const char *label = xmlnode_get_attrib(fn, "label"); | |
| 224 | const char *var = xmlnode_get_attrib(fn, "var"); | |
| 225 | char *value = NULL; | |
| 226 | ||
| 227 | if(!type) | |
|
17837
a9c447447c06
XEP-0004 says that if no field type is specified, text-single should be assumed.
Andreas Monitzer <am@adiumx.com>
parents:
17805
diff
changeset
|
228 | type = "text-single"; |
| 8135 | 229 | |
| 230 | if(!var && strcmp(type, "fixed")) | |
| 231 | continue; | |
| 232 | if(!label) | |
| 233 | label = var; | |
| 234 | ||
| 235 | if(!strcmp(type, "text-private")) { | |
| 236 | if((valuenode = xmlnode_get_child(fn, "value"))) | |
| 237 | value = xmlnode_get_data(valuenode); | |
| 238 | ||
| 15884 | 239 | field = purple_request_field_string_new(var, label, |
| 8135 | 240 | value ? value : "", FALSE); |
| 15884 | 241 | purple_request_field_string_set_masked(field, TRUE); |
| 242 | purple_request_field_group_add_field(group, field); | |
| 8135 | 243 | |
| 244 | g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_SINGLE)); | |
| 245 | ||
|
16136
49ddb8f06d96
I noticed some places where we were doing the whole
Mark Doliner <markdoliner@pidgin.im>
parents:
15884
diff
changeset
|
246 | g_free(value); |
| 8135 | 247 | } else if(!strcmp(type, "text-multi") || !strcmp(type, "jid-multi")) { |
| 248 | GString *str = g_string_new(""); | |
| 249 | ||
| 250 | for(valuenode = xmlnode_get_child(fn, "value"); valuenode; | |
| 251 | valuenode = xmlnode_get_next_twin(valuenode)) { | |
| 252 | ||
| 253 | if(!(value = xmlnode_get_data(valuenode))) | |
| 254 | continue; | |
| 255 | ||
| 256 | g_string_append_printf(str, "%s\n", value); | |
| 257 | g_free(value); | |
| 258 | } | |
| 259 | ||
| 15884 | 260 | field = purple_request_field_string_new(var, label, |
| 8135 | 261 | str->str, TRUE); |
| 15884 | 262 | purple_request_field_group_add_field(group, field); |
| 7923 | 263 | |
| 8135 | 264 | g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_MULTI)); |
| 265 | ||
| 266 | g_string_free(str, TRUE); | |
| 267 | } else if(!strcmp(type, "list-single") || !strcmp(type, "list-multi")) { | |
| 268 | xmlnode *optnode; | |
| 269 | GList *selected = NULL; | |
| 270 | ||
| 15884 | 271 | field = purple_request_field_list_new(var, label); |
| 8135 | 272 | |
| 273 | if(!strcmp(type, "list-multi")) { | |
| 15884 | 274 | purple_request_field_list_set_multi_select(field, TRUE); |
| 8135 | 275 | g_hash_table_replace(data->fields, g_strdup(var), |
| 276 | GINT_TO_POINTER(JABBER_X_DATA_LIST_MULTI)); | |
| 277 | } else { | |
| 278 | g_hash_table_replace(data->fields, g_strdup(var), | |
| 279 | GINT_TO_POINTER(JABBER_X_DATA_LIST_SINGLE)); | |
| 280 | } | |
| 281 | ||
| 282 | for(valuenode = xmlnode_get_child(fn, "value"); valuenode; | |
| 283 | valuenode = xmlnode_get_next_twin(valuenode)) { | |
|
22664
d2e81c1408ae
If the default value of a list-single or list-multi data forms field is NULL
Etan Reisner <deryni@pidgin.im>
parents:
21653
diff
changeset
|
284 | char *data = xmlnode_get_data(valuenode); |
|
d2e81c1408ae
If the default value of a list-single or list-multi data forms field is NULL
Etan Reisner <deryni@pidgin.im>
parents:
21653
diff
changeset
|
285 | if (data != NULL) { |
|
d2e81c1408ae
If the default value of a list-single or list-multi data forms field is NULL
Etan Reisner <deryni@pidgin.im>
parents:
21653
diff
changeset
|
286 | selected = g_list_prepend(selected, data); |
|
d2e81c1408ae
If the default value of a list-single or list-multi data forms field is NULL
Etan Reisner <deryni@pidgin.im>
parents:
21653
diff
changeset
|
287 | } |
| 8135 | 288 | } |
| 7923 | 289 | |
| 8135 | 290 | for(optnode = xmlnode_get_child(fn, "option"); optnode; |
| 291 | optnode = xmlnode_get_next_twin(optnode)) { | |
| 292 | const char *lbl; | |
| 293 | ||
| 294 | if(!(valuenode = xmlnode_get_child(optnode, "value"))) | |
| 295 | continue; | |
| 296 | ||
| 297 | if(!(value = xmlnode_get_data(valuenode))) | |
| 298 | continue; | |
| 299 | ||
| 300 | if(!(lbl = xmlnode_get_attrib(optnode, "label"))) | |
|
19051
b932fc2e28cd
For XMPP multi-selection lists in generic data forms, the intent here
Mark Doliner <markdoliner@pidgin.im>
parents:
18190
diff
changeset
|
301 | lbl = value; |
| 8135 | 302 | |
| 303 | data->values = g_slist_prepend(data->values, value); | |
| 304 | ||
| 15884 | 305 | purple_request_field_list_add(field, lbl, value); |
| 8135 | 306 | if(g_list_find_custom(selected, value, (GCompareFunc)strcmp)) |
| 15884 | 307 | purple_request_field_list_add_selected(field, lbl); |
| 8135 | 308 | } |
| 15884 | 309 | purple_request_field_group_add_field(group, field); |
| 8135 | 310 | |
| 311 | while(selected) { | |
| 312 | g_free(selected->data); | |
| 313 | selected = g_list_delete_link(selected, selected); | |
| 314 | } | |
| 315 | ||
| 316 | } else if(!strcmp(type, "boolean")) { | |
| 317 | gboolean def = FALSE; | |
| 7923 | 318 | |
| 319 | if((valuenode = xmlnode_get_child(fn, "value"))) | |
| 320 | value = xmlnode_get_data(valuenode); | |
| 321 | ||
|
8390
13e1ff9b2850
[gaim-migrate @ 9119]
Mark Doliner <markdoliner@pidgin.im>
parents:
8385
diff
changeset
|
322 | if(value && (!g_ascii_strcasecmp(value, "yes") || |
|
13e1ff9b2850
[gaim-migrate @ 9119]
Mark Doliner <markdoliner@pidgin.im>
parents:
8385
diff
changeset
|
323 | !g_ascii_strcasecmp(value, "true") || !g_ascii_strcasecmp(value, "1"))) |
| 8135 | 324 | def = TRUE; |
| 7923 | 325 | |
| 15884 | 326 | field = purple_request_field_bool_new(var, label, def); |
| 327 | purple_request_field_group_add_field(group, field); | |
| 7923 | 328 | |
| 8135 | 329 | g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_BOOLEAN)); |
| 7923 | 330 | |
|
16136
49ddb8f06d96
I noticed some places where we were doing the whole
Mark Doliner <markdoliner@pidgin.im>
parents:
15884
diff
changeset
|
331 | g_free(value); |
|
23402
03ec394ccfd6
Fix a memleak when handling jabber xforms. xmlnode_get_data() returns
Mark Doliner <markdoliner@pidgin.im>
parents:
22664
diff
changeset
|
332 | } else if(!strcmp(type, "fixed")) { |
| 8135 | 333 | if((valuenode = xmlnode_get_child(fn, "value"))) |
| 334 | value = xmlnode_get_data(valuenode); | |
| 7923 | 335 | |
|
23402
03ec394ccfd6
Fix a memleak when handling jabber xforms. xmlnode_get_data() returns
Mark Doliner <markdoliner@pidgin.im>
parents:
22664
diff
changeset
|
336 | if(value != NULL) { |
|
03ec394ccfd6
Fix a memleak when handling jabber xforms. xmlnode_get_data() returns
Mark Doliner <markdoliner@pidgin.im>
parents:
22664
diff
changeset
|
337 | field = purple_request_field_label_new("", value); |
|
03ec394ccfd6
Fix a memleak when handling jabber xforms. xmlnode_get_data() returns
Mark Doliner <markdoliner@pidgin.im>
parents:
22664
diff
changeset
|
338 | purple_request_field_group_add_field(group, field); |
| 7923 | 339 | |
|
23402
03ec394ccfd6
Fix a memleak when handling jabber xforms. xmlnode_get_data() returns
Mark Doliner <markdoliner@pidgin.im>
parents:
22664
diff
changeset
|
340 | g_free(value); |
|
03ec394ccfd6
Fix a memleak when handling jabber xforms. xmlnode_get_data() returns
Mark Doliner <markdoliner@pidgin.im>
parents:
22664
diff
changeset
|
341 | } |
| 8135 | 342 | } else if(!strcmp(type, "hidden")) { |
| 343 | if((valuenode = xmlnode_get_child(fn, "value"))) | |
| 344 | value = xmlnode_get_data(valuenode); | |
| 7923 | 345 | |
| 15884 | 346 | field = purple_request_field_string_new(var, "", value ? value : "", |
| 8135 | 347 | FALSE); |
| 15884 | 348 | purple_request_field_set_visible(field, FALSE); |
| 349 | purple_request_field_group_add_field(group, field); | |
| 7923 | 350 | |
| 8135 | 351 | g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_SINGLE)); |
| 7923 | 352 | |
|
16136
49ddb8f06d96
I noticed some places where we were doing the whole
Mark Doliner <markdoliner@pidgin.im>
parents:
15884
diff
changeset
|
353 | g_free(value); |
| 8135 | 354 | } else { /* text-single, jid-single, and the default */ |
| 355 | if((valuenode = xmlnode_get_child(fn, "value"))) | |
| 356 | value = xmlnode_get_data(valuenode); | |
| 7923 | 357 | |
| 15884 | 358 | field = purple_request_field_string_new(var, label, |
| 8135 | 359 | value ? value : "", FALSE); |
| 15884 | 360 | purple_request_field_group_add_field(group, field); |
| 7923 | 361 | |
| 8295 | 362 | if(!strcmp(type, "jid-single")) { |
| 15884 | 363 | purple_request_field_set_type_hint(field, "screenname"); |
| 8295 | 364 | g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_JID_SINGLE)); |
| 365 | } else { | |
| 366 | g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_SINGLE)); | |
| 367 | } | |
| 7923 | 368 | |
|
16136
49ddb8f06d96
I noticed some places where we were doing the whole
Mark Doliner <markdoliner@pidgin.im>
parents:
15884
diff
changeset
|
369 | g_free(value); |
| 7923 | 370 | } |
|
19894
b273d0db2bdd
Fixed code indenting, some spaces were still left and now replaced by tabs.
Andreas Monitzer <am@adiumx.com>
parents:
19203
diff
changeset
|
371 | |
|
b273d0db2bdd
Fixed code indenting, some spaces were still left and now replaced by tabs.
Andreas Monitzer <am@adiumx.com>
parents:
19203
diff
changeset
|
372 | if(field && xmlnode_get_child(fn, "required")) |
|
b273d0db2bdd
Fixed code indenting, some spaces were still left and now replaced by tabs.
Andreas Monitzer <am@adiumx.com>
parents:
19203
diff
changeset
|
373 | purple_request_field_set_required(field,TRUE); |
| 7923 | 374 | } |
|
17805
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
375 | |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
376 | if(actions != NULL) { |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
377 | PurpleRequestField *actionfield; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
378 | GList *action; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
379 | data->actiongroup = group = purple_request_field_group_new(_("Actions")); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
380 | purple_request_fields_add_group(fields, group); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
381 | actionfield = purple_request_field_choice_new("libpurple:jabber:xdata:actions", _("Select an action"), defaultaction); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
382 | |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
383 | for(action = actions; action; action = g_list_next(action)) { |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
384 | JabberXDataAction *a = action->data; |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
385 | |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
386 | purple_request_field_choice_add(actionfield, a->name); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
387 | data->actions = g_list_append(data->actions, g_strdup(a->handle)); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
388 | } |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
389 | purple_request_field_set_required(actionfield,TRUE); |
|
5bd417a1c847
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).
Andreas Monitzer <am@adiumx.com>
parents:
17774
diff
changeset
|
390 | purple_request_field_group_add_field(group, actionfield); |
| 7923 | 391 | } |
| 392 | ||
| 393 | if((x = xmlnode_get_child(packet, "title"))) | |
| 394 | title = xmlnode_get_data(x); | |
| 395 | ||
| 396 | if((x = xmlnode_get_child(packet, "instructions"))) | |
| 397 | instructions = xmlnode_get_data(x); | |
| 398 | ||
|
21653
621c47778132
merge of '73ae9aeda3c58fbf8437421da68d19d06f93e686'
Evan Schoenberg <evands@pidgin.im>
parents:
21233
diff
changeset
|
399 | handle = purple_request_fields(js->gc, title, title, instructions, fields, |
| 8396 | 400 | _("OK"), G_CALLBACK(jabber_x_data_ok_cb), |
|
16490
68c22924d66b
Added account, who, and conversation parameters to the request API calls, and updated all code to match. I can't compile the Perl module, so I'd appreciate it if someone who knows it would verify that this doesn't break Perl.
Evan Schoenberg <evands@pidgin.im>
parents:
16398
diff
changeset
|
401 | _("Cancel"), G_CALLBACK(jabber_x_data_cancel_cb), |
|
68c22924d66b
Added account, who, and conversation parameters to the request API calls, and updated all code to match. I can't compile the Perl module, so I'd appreciate it if someone who knows it would verify that this doesn't break Perl.
Evan Schoenberg <evands@pidgin.im>
parents:
16398
diff
changeset
|
402 | purple_connection_get_account(js->gc), /* XXX Do we have a who here? */ NULL, NULL, |
|
21653
621c47778132
merge of '73ae9aeda3c58fbf8437421da68d19d06f93e686'
Evan Schoenberg <evands@pidgin.im>
parents:
21233
diff
changeset
|
403 | data); |
| 7923 | 404 | |
|
16136
49ddb8f06d96
I noticed some places where we were doing the whole
Mark Doliner <markdoliner@pidgin.im>
parents:
15884
diff
changeset
|
405 | g_free(title); |
|
49ddb8f06d96
I noticed some places where we were doing the whole
Mark Doliner <markdoliner@pidgin.im>
parents:
15884
diff
changeset
|
406 | g_free(instructions); |
| 7923 | 407 | |
| 8396 | 408 | return handle; |
| 7923 | 409 | } |
| 410 | ||
| 411 |