| 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) |