comparison libpurple/protocols/jabber/disco.c @ 21603:a4b6854737d5

Implement more of XEP-0065 to support sending files through a proxy. To avoid adding strings this close to a release, it only supports using a proxy that is discovered from the server, but we'll include an account option to manually specify a ft proxy in the next release. Lots of this is based on a patch from galt - Fixes #3730, #116, #1768
author Daniel Atallah <daniel.atallah@gmail.com>
date Wed, 21 Nov 2007 05:22:39 +0000
parents 481749fc0b6b
children 10382f1e1353 60f5abc6cf0c 26eabe8e739b
comparison
equal deleted inserted replaced
21602:53fee49ce1c5 21603:a4b6854737d5
40 }; 40 };
41 41
42 #define SUPPORT_FEATURE(x) { \ 42 #define SUPPORT_FEATURE(x) { \
43 feature = xmlnode_new_child(query, "feature"); \ 43 feature = xmlnode_new_child(query, "feature"); \
44 xmlnode_set_attrib(feature, "var", x); \ 44 xmlnode_set_attrib(feature, "var", x); \
45 }
46
47 static void
48 jabber_disco_bytestream_server_cb(JabberStream *js, xmlnode *packet, gpointer data) {
49 JabberBytestreamsStreamhost *sh = data;
50 const char *from = xmlnode_get_attrib(packet, "from");
51 xmlnode *query = xmlnode_get_child_with_namespace(packet, "query",
52 "http://jabber.org/protocol/bytestreams");
53
54 if (from && !strcmp(from, sh->jid) && query != NULL) {
55 xmlnode *sh_node = xmlnode_get_child(query, "streamhost");
56 if (sh_node) {
57 const char *jid = xmlnode_get_attrib(sh_node, "jid");
58 const char *port = xmlnode_get_attrib(sh_node, "port");
59
60
61 if (jid == NULL || strcmp(jid, from) != 0)
62 purple_debug_error("jabber", "Invalid jid(%s) for bytestream.\n",
63 jid ? jid : "(null)");
64
65 sh->host = g_strdup(xmlnode_get_attrib(sh_node, "host"));
66 sh->zeroconf = g_strdup(xmlnode_get_attrib(sh_node, "zeroconf"));
67 if (port != NULL)
68 sh->port = atoi(port);
69 }
70 }
71
72 purple_debug_info("jabber", "Discovered bytestream proxy server: "
73 "jid='%s' host='%s' port='%d' zeroconf='%s'\n",
74 from ? from : "", sh->host ? sh->host : "",
75 sh->port, sh->zeroconf ? sh->zeroconf : "");
45 } 76 }
46 77
47 78
48 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) { 79 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) {
49 const char *from = xmlnode_get_attrib(packet, "from"); 80 const char *from = xmlnode_get_attrib(packet, "from");
189 continue; 220 continue;
190 221
191 if(!strcmp(category, "conference") && !strcmp(type, "text")) { 222 if(!strcmp(category, "conference") && !strcmp(type, "text")) {
192 /* we found a groupchat or MUC server, add it to the list */ 223 /* we found a groupchat or MUC server, add it to the list */
193 /* XXX: actually check for protocol/muc or gc-1.0 support */ 224 /* XXX: actually check for protocol/muc or gc-1.0 support */
194 js->chat_servers = g_list_append(js->chat_servers, g_strdup(from)); 225 js->chat_servers = g_list_prepend(js->chat_servers, g_strdup(from));
195 } else if(!strcmp(category, "directory") && !strcmp(type, "user")) { 226 } else if(!strcmp(category, "directory") && !strcmp(type, "user")) {
196 /* we found a JUD */ 227 /* we found a JUD */
197 js->user_directories = g_list_append(js->user_directories, g_strdup(from)); 228 js->user_directories = g_list_prepend(js->user_directories, g_strdup(from));
229 } else if(!strcmp(category, "proxy") && !strcmp(type, "bytestreams")) {
230 /* This is a bytestream proxy */
231 JabberIq *iq;
232 JabberBytestreamsStreamhost *sh;
233
234 purple_debug_info("jabber", "Found bytestream proxy server: %s\n", from);
235
236 sh = g_new0(JabberBytestreamsStreamhost, 1);
237 sh->jid = g_strdup(from);
238 js->bs_proxies = g_list_prepend(js->bs_proxies, sh);
239
240 iq = jabber_iq_new_query(js, JABBER_IQ_GET,
241 "http://jabber.org/protocol/bytestreams");
242 xmlnode_set_attrib(iq->node, "to", sh->jid);
243 jabber_iq_set_callback(iq, jabber_disco_bytestream_server_cb, sh);
244 jabber_iq_send(iq);
198 } 245 }
199 246
200 } else if(!strcmp(child->name, "feature")) { 247 } else if(!strcmp(child->name, "feature")) {
201 const char *var = xmlnode_get_attrib(child, "var"); 248 const char *var = xmlnode_get_attrib(child, "var");
202 if(!var) 249 if(!var)
342 continue; 389 continue;
343 390
344 g_free(js->server_name); 391 g_free(js->server_name);
345 js->server_name = g_strdup(name); 392 js->server_name = g_strdup(name);
346 if (!strcmp(name, "Google Talk")) { 393 if (!strcmp(name, "Google Talk")) {
347 purple_debug_info("jabber", "Google Talk!\n"); 394 purple_debug_info("jabber", "Google Talk!\n");
348 js->googletalk = TRUE; 395 js->googletalk = TRUE;
349 } 396 }
350 } 397 }
351 398
352 for (child = xmlnode_get_child(query, "feature"); child; 399 for (child = xmlnode_get_child(query, "feature"); child;
353 child = xmlnode_get_next_twin(child)) { 400 child = xmlnode_get_next_twin(child)) {
420 xmlnode_set_attrib(iq->node, "to", js->user->domain); 467 xmlnode_set_attrib(iq->node, "to", js->user->domain);
421 468
422 jabber_iq_set_callback(iq, jabber_disco_server_items_result_cb, NULL); 469 jabber_iq_set_callback(iq, jabber_disco_server_items_result_cb, NULL);
423 jabber_iq_send(iq); 470 jabber_iq_send(iq);
424 471
425 iq = jabber_iq_new_query(js, JABBER_IQ_GET, 472 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info");
426 "http://jabber.org/protocol/disco#info");
427 xmlnode_set_attrib(iq->node, "to", js->user->domain); 473 xmlnode_set_attrib(iq->node, "to", js->user->domain);
428 jabber_iq_set_callback(iq, jabber_disco_server_info_result_cb, NULL); 474 jabber_iq_set_callback(iq, jabber_disco_server_info_result_cb, NULL);
429 jabber_iq_send(iq); 475 jabber_iq_send(iq);
430 } 476 }
431 477