| 220 |
220 |
| 221 jabber_iq_send(iq); |
221 jabber_iq_send(iq); |
| 222 } |
222 } |
| 223 } |
223 } |
| 224 |
224 |
| 225 static void urn_xmpp_ping_parse(JabberStream *js, xmlnode *packet) |
|
| 226 { |
|
| 227 const char *type, *id, *from; |
|
| 228 JabberIq *iq; |
|
| 229 |
|
| 230 type = xmlnode_get_attrib(packet, "type"); |
|
| 231 from = xmlnode_get_attrib(packet, "from"); |
|
| 232 id = xmlnode_get_attrib(packet, "id"); |
|
| 233 |
|
| 234 if(type && !strcmp(type, "get")) { |
|
| 235 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "urn:xmpp:ping"); |
|
| 236 |
|
| 237 jabber_iq_set_id(iq, id); |
|
| 238 xmlnode_set_attrib(iq->node, "to", from); |
|
| 239 |
|
| 240 jabber_iq_send(iq); |
|
| 241 } else { |
|
| 242 /* XXX: error */ |
|
| 243 } |
|
| 244 } |
|
| 245 |
|
| 246 static void jabber_iq_version_parse(JabberStream *js, xmlnode *packet) |
225 static void jabber_iq_version_parse(JabberStream *js, xmlnode *packet) |
| 247 { |
226 { |
| 248 JabberIq *iq; |
227 JabberIq *iq; |
| 249 const char *type, *from, *id; |
228 const char *type, *from, *id; |
| 250 xmlnode *query; |
229 xmlnode *query; |
| 307 } |
286 } |
| 308 |
287 |
| 309 void jabber_iq_parse(JabberStream *js, xmlnode *packet) |
288 void jabber_iq_parse(JabberStream *js, xmlnode *packet) |
| 310 { |
289 { |
| 311 JabberCallbackData *jcd; |
290 JabberCallbackData *jcd; |
| 312 xmlnode *query, *error, *x; |
291 xmlnode *child, *error, *x; |
| 313 const char *xmlns; |
292 const char *xmlns; |
| 314 const char *type, *id, *from; |
293 const char *type, *id, *from; |
| 315 JabberIqHandler *jih; |
294 JabberIqHandler *jih; |
| 316 |
295 |
| 317 query = xmlnode_get_child(packet, "query"); |
296 /* |
| |
297 * child will be either the first tag child or NULL if there is no child. |
| |
298 * Historically, we used just the 'query' subchild, but newer XEPs use |
| |
299 * differently named children. Grabbing the first child is (for the time |
| |
300 * being) sufficient. |
| |
301 */ |
| |
302 for (child = packet->child; child; child = child->next) { |
| |
303 if (child->type != XMLNODE_TYPE_TAG) |
| |
304 continue; |
| |
305 break; |
| |
306 } |
| |
307 |
| 318 type = xmlnode_get_attrib(packet, "type"); |
308 type = xmlnode_get_attrib(packet, "type"); |
| 319 from = xmlnode_get_attrib(packet, "from"); |
309 from = xmlnode_get_attrib(packet, "from"); |
| 320 id = xmlnode_get_attrib(packet, "id"); |
310 id = xmlnode_get_attrib(packet, "id"); |
| 321 |
311 |
| 322 if(type == NULL || !(!strcmp(type, "get") || !strcmp(type, "set") |
312 if(type == NULL || !(!strcmp(type, "get") || !strcmp(type, "set") |
| 351 |
341 |
| 352 return; |
342 return; |
| 353 } |
343 } |
| 354 |
344 |
| 355 /* First, lets see if a special callback got registered */ |
345 /* First, lets see if a special callback got registered */ |
| 356 |
|
| 357 if(!strcmp(type, "result") || !strcmp(type, "error")) { |
346 if(!strcmp(type, "result") || !strcmp(type, "error")) { |
| 358 if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) { |
347 if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) { |
| 359 jcd->callback(js, packet, jcd->data); |
348 jcd->callback(js, packet, jcd->data); |
| 360 jabber_iq_remove_callback_by_id(js, id); |
349 jabber_iq_remove_callback_by_id(js, id); |
| 361 return; |
350 return; |
| 362 } |
351 } |
| 363 } |
352 } |
| 364 |
353 |
| 365 /* Apparently not, so lets see if we have a pre-defined handler */ |
354 /* Apparently not, so lets see if we have a pre-defined handler */ |
| 366 |
355 if(child && (xmlns = xmlnode_get_namespace(child))) { |
| 367 if(query && (xmlns = xmlnode_get_namespace(query))) { |
|
| 368 if((jih = g_hash_table_lookup(iq_handlers, xmlns))) { |
356 if((jih = g_hash_table_lookup(iq_handlers, xmlns))) { |
| 369 jih(js, packet); |
357 jih(js, packet); |
| 370 return; |
358 return; |
| 371 } |
359 } |
| 372 } |
360 } |
| 373 |
361 |
| 374 if(xmlnode_get_child_with_namespace(packet, "si", "http://jabber.org/protocol/si")) { |
|
| 375 jabber_si_parse(js, packet); |
|
| 376 return; |
|
| 377 } |
|
| 378 |
|
| 379 if(xmlnode_get_child_with_namespace(packet, "new-mail", "google:mail:notify")) { |
|
| 380 jabber_gmail_poke(js, packet); |
|
| 381 return; |
|
| 382 } |
|
| 383 |
|
| 384 purple_debug_info("jabber", "jabber_iq_parse\n"); |
362 purple_debug_info("jabber", "jabber_iq_parse\n"); |
| 385 |
|
| 386 if(xmlnode_get_child_with_namespace(packet, "ping", "urn:xmpp:ping")) { |
|
| 387 jabber_ping_parse(js, packet); |
|
| 388 return; |
|
| 389 } |
|
| 390 |
|
| 391 if (xmlnode_get_child_with_namespace(packet, "data", XEP_0231_NAMESPACE)) { |
|
| 392 jabber_data_parse(js, packet); |
|
| 393 return; |
|
| 394 } |
|
| 395 |
363 |
| 396 /* If we get here, send the default error reply mandated by XMPP-CORE */ |
364 /* If we get here, send the default error reply mandated by XMPP-CORE */ |
| 397 if(!strcmp(type, "set") || !strcmp(type, "get")) { |
365 if(!strcmp(type, "set") || !strcmp(type, "get")) { |
| 398 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR); |
366 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR); |
| 399 |
367 |
| 429 jabber_iq_register_handler("urn:xmpp:time", jabber_iq_time_parse); |
397 jabber_iq_register_handler("urn:xmpp:time", jabber_iq_time_parse); |
| 430 jabber_iq_register_handler("jabber:iq:version", jabber_iq_version_parse); |
398 jabber_iq_register_handler("jabber:iq:version", jabber_iq_version_parse); |
| 431 jabber_iq_register_handler("http://jabber.org/protocol/disco#info", jabber_disco_info_parse); |
399 jabber_iq_register_handler("http://jabber.org/protocol/disco#info", jabber_disco_info_parse); |
| 432 jabber_iq_register_handler("http://jabber.org/protocol/disco#items", jabber_disco_items_parse); |
400 jabber_iq_register_handler("http://jabber.org/protocol/disco#items", jabber_disco_items_parse); |
| 433 jabber_iq_register_handler("jabber:iq:register", jabber_register_parse); |
401 jabber_iq_register_handler("jabber:iq:register", jabber_register_parse); |
| 434 jabber_iq_register_handler("urn:xmpp:ping", urn_xmpp_ping_parse); |
402 jabber_iq_register_handler("urn:xmpp:ping", jabber_ping_parse); |
| |
403 jabber_iq_register_handler("http://jabber.org/protocol/si", jabber_si_parse); |
| |
404 jabber_iq_register_handler("google:mail:notify", jabber_gmail_poke); |
| |
405 jabber_iq_register_handler(XEP_0231_NAMESPACE, jabber_data_parse); |
| 435 } |
406 } |
| 436 |
407 |
| 437 void jabber_iq_uninit(void) |
408 void jabber_iq_uninit(void) |
| 438 { |
409 { |
| 439 g_hash_table_destroy(iq_handlers); |
410 g_hash_table_destroy(iq_handlers); |