libpurple/protocols/jabber/disco.c

changeset 26910
7813befc9bf9
parent 26908
e292ff5a9311
child 26911
579d7182a2fc
equal deleted inserted replaced
26909:c9ba288f897f 26910:7813befc9bf9
216 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); 216 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas");
217 } 217 }
218 } 218 }
219 219
220 jabber_iq_send(iq); 220 jabber_iq_send(iq);
221 } else if(type == JABBER_IQ_RESULT) { 221 } else if (type == JABBER_IQ_SET) {
222 /* wtf? seriously. wtf‽ */
223 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR);
224 xmlnode *error, *bad_request;
225
226 /* Free the <query/> */
227 xmlnode_free(xmlnode_get_child(iq->node, "query"));
228 /* Add an error */
229 error = xmlnode_new_child(iq->node, "error");
230 xmlnode_set_attrib(error, "type", "modify");
231 bad_request = xmlnode_new_child(error, "bad-request");
232 xmlnode_set_namespace(bad_request, "urn:ietf:params:xml:ns:xmpp-stanzas");
233
234 jabber_iq_set_id(iq, id);
235 xmlnode_set_attrib(iq->node, "to", from);
236
237 jabber_iq_send(iq);
238 }
239 }
240
241 static void jabber_disco_info_cb(JabberStream *js, const char *from,
242 JabberIqType type, const char *id,
243 xmlnode *packet, gpointer data)
244 {
245 struct _jabber_disco_info_cb_data *jdicd = data;
246 xmlnode *query;
247
248 query = xmlnode_get_child_with_namespace(packet, "query",
249 "http://jabber.org/protocol/disco#info");
250
251 if (type == JABBER_IQ_RESULT && query) {
222 xmlnode *child; 252 xmlnode *child;
223 JabberID *jid; 253 JabberID *jid;
224 JabberBuddy *jb; 254 JabberBuddy *jb;
225 JabberBuddyResource *jbr = NULL; 255 JabberBuddyResource *jbr = NULL;
226 JabberCapabilities capabilities = JABBER_CAP_NONE; 256 JabberCapabilities capabilities = JABBER_CAP_NONE;
227 struct _jabber_disco_info_cb_data *jdicd;
228 257
229 if((jid = jabber_id_new(from))) { 258 if((jid = jabber_id_new(from))) {
230 if(jid->resource && (jb = jabber_buddy_find(js, from, TRUE))) 259 if(jid->resource && (jb = jabber_buddy_find(js, from, TRUE)))
231 jbr = jabber_buddy_find_resource(jb, jid->resource); 260 jbr = jabber_buddy_find_resource(jb, jid->resource);
232 jabber_id_free(jid); 261 jabber_id_free(jid);
233 } 262 }
234 263
235 if(jbr) 264 if(jbr)
236 capabilities = jbr->capabilities; 265 capabilities = jbr->capabilities;
237 266
238 for(child = in_query->child; child; child = child->next) { 267 for(child = query->child; child; child = child->next) {
239 if(child->type != XMLNODE_TYPE_TAG) 268 if(child->type != XMLNODE_TYPE_TAG)
240 continue; 269 continue;
241 270
242 if(!strcmp(child->name, "identity")) { 271 if(!strcmp(child->name, "identity")) {
243 const char *category = xmlnode_get_attrib(child, "category"); 272 const char *category = xmlnode_get_attrib(child, "category");
302 capabilities |= JABBER_CAP_RETRIEVED; 331 capabilities |= JABBER_CAP_RETRIEVED;
303 332
304 if(jbr) 333 if(jbr)
305 jbr->capabilities = capabilities; 334 jbr->capabilities = capabilities;
306 335
307 if((jdicd = g_hash_table_lookup(js->disco_callbacks, id))) { 336 jdicd->callback(js, from, capabilities, jdicd->data);
308 jdicd->callback(js, from, capabilities, jdicd->data); 337 } else { /* type == JABBER_IQ_ERROR or query == NULL */
309 g_hash_table_remove(js->disco_callbacks, id);
310 }
311 } else if(type == JABBER_IQ_ERROR) {
312 JabberID *jid; 338 JabberID *jid;
313 JabberBuddy *jb; 339 JabberBuddy *jb;
314 JabberBuddyResource *jbr = NULL; 340 JabberBuddyResource *jbr = NULL;
315 JabberCapabilities capabilities = JABBER_CAP_NONE; 341 JabberCapabilities capabilities = JABBER_CAP_NONE;
316 struct _jabber_disco_info_cb_data *jdicd;
317
318 if(!(jdicd = g_hash_table_lookup(js->disco_callbacks, id)))
319 return;
320 342
321 if((jid = jabber_id_new(from))) { 343 if((jid = jabber_id_new(from))) {
322 if(jid->resource && (jb = jabber_buddy_find(js, from, TRUE))) 344 if(jid->resource && (jb = jabber_buddy_find(js, from, TRUE)))
323 jbr = jabber_buddy_find_resource(jb, jid->resource); 345 jbr = jabber_buddy_find_resource(jb, jid->resource);
324 jabber_id_free(jid); 346 jabber_id_free(jid);
326 348
327 if(jbr) 349 if(jbr)
328 capabilities = jbr->capabilities; 350 capabilities = jbr->capabilities;
329 351
330 jdicd->callback(js, from, capabilities, jdicd->data); 352 jdicd->callback(js, from, capabilities, jdicd->data);
331 g_hash_table_remove(js->disco_callbacks, id);
332 } 353 }
333 } 354 }
334 355
335 void jabber_disco_items_parse(JabberStream *js, const char *from, 356 void jabber_disco_items_parse(JabberStream *js, const char *from,
336 JabberIqType type, const char *id, 357 JabberIqType type, const char *id,
554 { 575 {
555 JabberID *jid; 576 JabberID *jid;
556 JabberBuddy *jb; 577 JabberBuddy *jb;
557 JabberBuddyResource *jbr = NULL; 578 JabberBuddyResource *jbr = NULL;
558 struct _jabber_disco_info_cb_data *jdicd; 579 struct _jabber_disco_info_cb_data *jdicd;
559 char *id;
560 JabberIq *iq; 580 JabberIq *iq;
561 581
562 if((jid = jabber_id_new(who))) { 582 if((jid = jabber_id_new(who))) {
563 if(jid->resource && (jb = jabber_buddy_find(js, who, TRUE))) 583 if(jid->resource && (jb = jabber_buddy_find(js, who, TRUE)))
564 jbr = jabber_buddy_find_resource(jb, jid->resource); 584 jbr = jabber_buddy_find_resource(jb, jid->resource);
575 jdicd->callback = callback; 595 jdicd->callback = callback;
576 596
577 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info"); 597 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info");
578 xmlnode_set_attrib(iq->node, "to", who); 598 xmlnode_set_attrib(iq->node, "to", who);
579 599
580 id = jabber_get_next_id(js); 600 jabber_iq_set_callback(iq, jabber_disco_info_cb, jdicd);
581 jabber_iq_set_id(iq, id);
582 g_hash_table_insert(js->disco_callbacks, id, jdicd);
583
584 jabber_iq_send(iq); 601 jabber_iq_send(iq);
585 } 602 }
586 603
587 static void 604 static void
588 jabber_disco_list_data_destroy(struct jabber_disco_list_data *data) 605 jabber_disco_list_data_destroy(struct jabber_disco_list_data *data)

mercurial