comparison libpurple/protocols/jabber/disco.c @ 26487:bc7fac8e2f79

propagate from branch 'im.pidgin.pidgin' (head f144c6bda9daf701aa891c875fce7a4dedd611ae) to branch 'im.pidgin.cpw.darkrain42.xmpp.bosh' (head 8b60514f2b44295e87ee3587669aec5059556149)
author Paul Aurich <paul@darkrain42.org>
date Sun, 05 Apr 2009 21:13:10 +0000
parents 20743d9bd62d 4f14455a86d2
children 3912f55a1633
comparison
equal deleted inserted replaced
26463:b01e8e76c59d 26487:bc7fac8e2f79
44 feature = xmlnode_new_child(query, "feature"); \ 44 feature = xmlnode_new_child(query, "feature"); \
45 xmlnode_set_attrib(feature, "var", x); \ 45 xmlnode_set_attrib(feature, "var", x); \
46 } 46 }
47 47
48 static void 48 static void
49 jabber_disco_bytestream_server_cb(JabberStream *js, xmlnode *packet, gpointer data) { 49 jabber_disco_bytestream_server_cb(JabberStream *js, const char *from,
50 JabberIqType type, const char *id,
51 xmlnode *packet, gpointer data)
52 {
50 JabberBytestreamsStreamhost *sh = data; 53 JabberBytestreamsStreamhost *sh = data;
51 const char *from = xmlnode_get_attrib(packet, "from");
52 xmlnode *query = xmlnode_get_child_with_namespace(packet, "query", 54 xmlnode *query = xmlnode_get_child_with_namespace(packet, "query",
53 "http://jabber.org/protocol/bytestreams"); 55 "http://jabber.org/protocol/bytestreams");
54 56
55 if (from && !strcmp(from, sh->jid) && query != NULL) { 57 if (from && !strcmp(from, sh->jid) && query != NULL) {
56 xmlnode *sh_node = xmlnode_get_child(query, "streamhost"); 58 xmlnode *sh_node = xmlnode_get_child(query, "streamhost");
84 js->bs_proxies = g_list_remove(js->bs_proxies, sh); 86 js->bs_proxies = g_list_remove(js->bs_proxies, sh);
85 } 87 }
86 } 88 }
87 89
88 90
89 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) { 91 void jabber_disco_info_parse(JabberStream *js, const char *from,
90 const char *from = xmlnode_get_attrib(packet, "from"); 92 JabberIqType type, const char *id,
91 const char *type = xmlnode_get_attrib(packet, "type"); 93 xmlnode *in_query)
92 94 {
93 if(!from || !type) 95
94 return; 96 if(!from)
95 97 return;
96 if(!strcmp(type, "get")) { 98
99 if(type == JABBER_IQ_GET) {
97 xmlnode *query, *identity, *feature; 100 xmlnode *query, *identity, *feature;
98 JabberIq *iq; 101 JabberIq *iq;
99 102 const char *node = xmlnode_get_attrib(in_query, "node");
100 xmlnode *in_query;
101 const char *node = NULL;
102 char *node_uri = NULL; 103 char *node_uri = NULL;
103 104
104 /* create custom caps node URI */ 105 /* create custom caps node URI */
105 node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_own_hash(js), NULL); 106 node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_own_hash(js), NULL);
106 107
107 if((in_query = xmlnode_get_child(packet, "query"))) {
108 node = xmlnode_get_attrib(in_query, "node");
109 }
110
111
112 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, 108 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT,
113 "http://jabber.org/protocol/disco#info"); 109 "http://jabber.org/protocol/disco#info");
114 110
115 jabber_iq_set_id(iq, xmlnode_get_attrib(packet, "id")); 111 jabber_iq_set_id(iq, id);
116 112
117 xmlnode_set_attrib(iq->node, "to", from); 113 xmlnode_set_attrib(iq->node, "to", from);
118 query = xmlnode_get_child(iq->node, "query"); 114 query = xmlnode_get_child(iq->node, "query");
119 115
120 if(node) 116 if(node)
144 for(features = jabber_features; features; features = features->next) { 140 for(features = jabber_features; features; features = features->next) {
145 JabberFeature *feat = (JabberFeature*)features->data; 141 JabberFeature *feat = (JabberFeature*)features->data;
146 if (!feat->is_enabled || feat->is_enabled(js, feat->namespace)) { 142 if (!feat->is_enabled || feat->is_enabled(js, feat->namespace)) {
147 feature = xmlnode_new_child(query, "feature"); 143 feature = xmlnode_new_child(query, "feature");
148 xmlnode_set_attrib(feature, "var", feat->namespace); 144 xmlnode_set_attrib(feature, "var", feat->namespace);
149 } 145 }
150 } 146 }
151 #ifdef USE_VV 147 #ifdef USE_VV
152 } else if (g_str_equal(node, CAPS0115_NODE "#" "voice-v1")) { 148 } else if (g_str_equal(node, CAPS0115_NODE "#" "voice-v1")) {
153 /* 149 /*
154 * HUGE HACK! We advertise this ext (see jabber_presence_create_js 150 * HUGE HACK! We advertise this ext (see jabber_presence_create_js
175 inf = xmlnode_new_child(error, "item-not-found"); 171 inf = xmlnode_new_child(error, "item-not-found");
176 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); 172 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas");
177 } 173 }
178 g_free(node_uri); 174 g_free(node_uri);
179 jabber_iq_send(iq); 175 jabber_iq_send(iq);
180 } else if(!strcmp(type, "result")) { 176 } else if(type == JABBER_IQ_RESULT) {
181 xmlnode *query = xmlnode_get_child(packet, "query");
182 xmlnode *child; 177 xmlnode *child;
183 JabberID *jid; 178 JabberID *jid;
184 JabberBuddy *jb; 179 JabberBuddy *jb;
185 JabberBuddyResource *jbr = NULL; 180 JabberBuddyResource *jbr = NULL;
186 JabberCapabilities capabilities = JABBER_CAP_NONE; 181 JabberCapabilities capabilities = JABBER_CAP_NONE;
193 } 188 }
194 189
195 if(jbr) 190 if(jbr)
196 capabilities = jbr->capabilities; 191 capabilities = jbr->capabilities;
197 192
198 for(child = query->child; child; child = child->next) { 193 for(child = in_query->child; child; child = child->next) {
199 if(child->type != XMLNODE_TYPE_TAG) 194 if(child->type != XMLNODE_TYPE_TAG)
200 continue; 195 continue;
201 196
202 if(!strcmp(child->name, "identity")) { 197 if(!strcmp(child->name, "identity")) {
203 const char *category = xmlnode_get_attrib(child, "category"); 198 const char *category = xmlnode_get_attrib(child, "category");
243 capabilities |= JABBER_CAP_BYTESTREAMS; 238 capabilities |= JABBER_CAP_BYTESTREAMS;
244 else if(!strcmp(var, "jabber:iq:search")) 239 else if(!strcmp(var, "jabber:iq:search"))
245 capabilities |= JABBER_CAP_IQ_SEARCH; 240 capabilities |= JABBER_CAP_IQ_SEARCH;
246 else if(!strcmp(var, "jabber:iq:register")) 241 else if(!strcmp(var, "jabber:iq:register"))
247 capabilities |= JABBER_CAP_IQ_REGISTER; 242 capabilities |= JABBER_CAP_IQ_REGISTER;
248 else if(!strcmp(var, "http://www.xmpp.org/extensions/xep-0199.html#ns")) 243 else if(!strcmp(var, "urn:xmpp:ping"))
249 capabilities |= JABBER_CAP_PING; 244 capabilities |= JABBER_CAP_PING;
250 else if(!strcmp(var, "http://jabber.org/protocol/commands")) { 245 else if(!strcmp(var, "http://jabber.org/protocol/commands")) {
251 capabilities |= JABBER_CAP_ADHOC; 246 capabilities |= JABBER_CAP_ADHOC;
252 } 247 }
253 else if(!strcmp(var, "http://jabber.org/protocol/ibb")) { 248 else if(!strcmp(var, "http://jabber.org/protocol/ibb")) {
264 259
265 if((jdicd = g_hash_table_lookup(js->disco_callbacks, from))) { 260 if((jdicd = g_hash_table_lookup(js->disco_callbacks, from))) {
266 jdicd->callback(js, from, capabilities, jdicd->data); 261 jdicd->callback(js, from, capabilities, jdicd->data);
267 g_hash_table_remove(js->disco_callbacks, from); 262 g_hash_table_remove(js->disco_callbacks, from);
268 } 263 }
269 } else if(!strcmp(type, "error")) { 264 } else if(type == JABBER_IQ_ERROR) {
270 JabberID *jid; 265 JabberID *jid;
271 JabberBuddy *jb; 266 JabberBuddy *jb;
272 JabberBuddyResource *jbr = NULL; 267 JabberBuddyResource *jbr = NULL;
273 JabberCapabilities capabilities = JABBER_CAP_NONE; 268 JabberCapabilities capabilities = JABBER_CAP_NONE;
274 struct _jabber_disco_info_cb_data *jdicd; 269 struct _jabber_disco_info_cb_data *jdicd;
288 jdicd->callback(js, from, capabilities, jdicd->data); 283 jdicd->callback(js, from, capabilities, jdicd->data);
289 g_hash_table_remove(js->disco_callbacks, from); 284 g_hash_table_remove(js->disco_callbacks, from);
290 } 285 }
291 } 286 }
292 287
293 void jabber_disco_items_parse(JabberStream *js, xmlnode *packet) { 288 void jabber_disco_items_parse(JabberStream *js, const char *from,
294 const char *from = xmlnode_get_attrib(packet, "from"); 289 JabberIqType type, const char *id,
295 const char *type = xmlnode_get_attrib(packet, "type"); 290 xmlnode *query)
296 291 {
297 if(type && !strcmp(type, "get")) { 292 if(type == JABBER_IQ_GET) {
298 JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, 293 JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_RESULT,
299 "http://jabber.org/protocol/disco#items"); 294 "http://jabber.org/protocol/disco#items");
300 295
301 /* preserve node */ 296 /* preserve node */
302 xmlnode *iq_query = xmlnode_get_child_with_namespace(iq->node,"query","http://jabber.org/protocol/disco#items"); 297 xmlnode *iq_query = xmlnode_get_child(iq->node, "query");
303 if(iq_query) { 298 const char *node = xmlnode_get_attrib(query, "node");
304 xmlnode *query = xmlnode_get_child_with_namespace(packet,"query","http://jabber.org/protocol/disco#items"); 299 if(node)
305 if(query) { 300 xmlnode_set_attrib(iq_query,"node",node);
306 const char *node = xmlnode_get_attrib(query,"node"); 301
307 if(node) 302 jabber_iq_set_id(iq, id);
308 xmlnode_set_attrib(iq_query,"node",node); 303
309 } 304 if (from)
310 } 305 xmlnode_set_attrib(iq->node, "to", from);
311
312 jabber_iq_set_id(iq, xmlnode_get_attrib(packet, "id"));
313
314 xmlnode_set_attrib(iq->node, "to", from);
315 jabber_iq_send(iq); 306 jabber_iq_send(iq);
316 } 307 }
317 } 308 }
318 309
319 static void 310 static void
371 } 362 }
372 363
373 } 364 }
374 365
375 static void 366 static void
376 jabber_disco_server_info_result_cb(JabberStream *js, xmlnode *packet, gpointer data) 367 jabber_disco_server_info_result_cb(JabberStream *js, const char *from,
368 JabberIqType type, const char *id,
369 xmlnode *packet, gpointer data)
377 { 370 {
378 xmlnode *query, *child; 371 xmlnode *query, *child;
379 const char *from = xmlnode_get_attrib(packet, "from"); 372
380 const char *type = xmlnode_get_attrib(packet, "type"); 373 if (!from || strcmp(from, js->user->domain)) {
381
382 if((!from || !type) ||
383 (strcmp(from, js->user->domain))) {
384 jabber_disco_finish_server_info_result_cb(js); 374 jabber_disco_finish_server_info_result_cb(js);
385 return; 375 return;
386 } 376 }
387 377
388 if(strcmp(type, "result")) { 378 if (type == JABBER_IQ_ERROR) {
389 /* A common way to get here is for the server not to support xmlns http://jabber.org/protocol/disco#info */ 379 /* A common way to get here is for the server not to support xmlns http://jabber.org/protocol/disco#info */
390 jabber_disco_finish_server_info_result_cb(js); 380 jabber_disco_finish_server_info_result_cb(js);
391 return; 381 return;
392 } 382 }
393 383
449 439
450 jabber_disco_finish_server_info_result_cb(js); 440 jabber_disco_finish_server_info_result_cb(js);
451 } 441 }
452 442
453 static void 443 static void
454 jabber_disco_server_items_result_cb(JabberStream *js, xmlnode *packet, gpointer data) 444 jabber_disco_server_items_result_cb(JabberStream *js, const char *from,
445 JabberIqType type, const char *id,
446 xmlnode *packet, gpointer data)
455 { 447 {
456 xmlnode *query, *child; 448 xmlnode *query, *child;
457 const char *from = xmlnode_get_attrib(packet, "from"); 449
458 const char *type = xmlnode_get_attrib(packet, "type"); 450 if (!from || strcmp(from, js->user->domain) != 0)
459 451 return;
460 if(!from || !type) 452
461 return; 453 if (type == JABBER_IQ_ERROR)
462
463 if(strcmp(from, js->user->domain))
464 return;
465
466 if(strcmp(type, "result"))
467 return; 454 return;
468 455
469 while(js->chat_servers) { 456 while(js->chat_servers) {
470 g_free(js->chat_servers->data); 457 g_free(js->chat_servers->data);
471 js->chat_servers = g_list_delete_link(js->chat_servers, js->chat_servers); 458 js->chat_servers = g_list_delete_link(js->chat_servers, js->chat_servers);
536 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info"); 523 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info");
537 xmlnode_set_attrib(iq->node, "to", who); 524 xmlnode_set_attrib(iq->node, "to", who);
538 525
539 jabber_iq_send(iq); 526 jabber_iq_send(iq);
540 } 527 }
541
542