void jabber_si_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *who) { struct jabber_transfer *tf; struct jabber_data *jd = ic->proto_data; struct jabber_buddy *bud; char *server = jd->server, *s; if ((s = strchr(who, '=')) && jabber_chat_by_jid(ic, s + 1)) { bud = jabber_buddy_by_ext_jid(ic, who, 0); } else { bud = jabber_buddy_by_jid(ic, who, 0); } if (bud == NULL) { imcb_file_canceled(ic, ft, "Couldn't find buddy (BUG?)"); return; } imcb_log(ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who); tf = g_new0(struct jabber_transfer, 1); tf->ic = ic; tf->ft = ft; tf->fd = -1; tf->ft->data = tf; tf->ft->free = jabber_si_free_transfer; tf->bud = bud; ft->write = jabber_bs_send_write; jd->filetransfers = g_slist_prepend(jd->filetransfers, tf); /* query buddy's features and server's streaming proxies if necessary */ if (!tf->bud->features) { jabber_iq_query_features(ic, bud->full_jid); } /* If <auto> is not set don't check for proxies */ if ((jd->have_streamhosts != 1) && (jd->streamhosts == NULL) && (strstr(set_getstr(&ic->acc->set, "proxy"), "<auto>") != NULL)) { jd->have_streamhosts = 0; jabber_iq_query_server(ic, server, XMLNS_DISCO_ITEMS); } else if (jd->streamhosts != NULL) { jd->have_streamhosts = 1; } /* if we had to do a query, wait for the result. * Otherwise fire away. */ if (!tf->bud->features || jd->have_streamhosts != 1) { tf->disco_timeout = b_timeout_add(500, jabber_si_waitfor_disco, tf); } else { jabber_si_transfer_start(tf); } }
/* * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info */ xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) { struct xt_node *c; struct jabber_data *jd = ic->proto_data; char *xmlns, *from; if( !( c = xt_find_node( node->children, "query" ) ) || !( from = xt_find_attr( node, "from" ) ) || !( xmlns = xt_find_attr( c, "xmlns" ) ) ) { imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); return XT_HANDLED; } jd->have_streamhosts++; if( strcmp( xmlns, XMLNS_DISCO_ITEMS ) == 0 ) { char *itemjid; /* answer from server */ c = c->children; while( ( c = xt_find_node( c, "item" ) ) ) { itemjid = xt_find_attr( c, "jid" ); if( itemjid ) jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO ); c = c->next; } } else if( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 ) { char *category, *type; /* answer from potential proxy */ c = c->children; while( ( c = xt_find_node( c, "identity" ) ) ) { category = xt_find_attr( c, "category" ); type = xt_find_attr( c, "type" ); if( type && ( strcmp( type, "bytestreams" ) == 0 ) && category && ( strcmp( category, "proxy" ) == 0 ) ) jabber_iq_query_server( ic, from, XMLNS_BYTESTREAMS ); c = c->next; } } else if( strcmp( xmlns, XMLNS_BYTESTREAMS ) == 0 ) { char *host, *jid, *port_s; int port; /* answer from proxy */ if( ( c = xt_find_node( c->children, "streamhost" ) ) && ( host = xt_find_attr( c, "host" ) ) && ( port_s = xt_find_attr( c, "port" ) ) && ( sscanf( port_s, "%d", &port ) == 1 ) && ( jid = xt_find_attr( c, "jid" ) ) ) { jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 ); sh->jid = g_strdup( jid ); sh->host = g_strdup( host ); g_snprintf( sh->port, sizeof( sh->port ), "%u", port ); imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port ); jd->streamhosts = g_slist_append( jd->streamhosts, sh ); } } if( jd->have_streamhosts == 0 ) jd->have_streamhosts++; return XT_HANDLED; }