Mercurial > pidgin.yaz
diff libpurple/protocols/jabber/presence.c @ 25987:c4fd9222dda1
propagate from branch 'im.pidgin.pidgin' (head 303af74a38e7b313d4fb0be4d4054a16cb13d819)
to branch 'im.pidgin.cpw.darkrain42.xmpp.bosh' (head 650d82b8a5f0c8860804dd8004cd54badea48e1e)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sat, 07 Mar 2009 01:59:40 +0000 |
parents | 5f9a24d1c25e 1d1d1829de11 |
children | 592b88eae0d5 |
line wrap: on
line diff
--- a/libpurple/protocols/jabber/presence.c Thu Mar 05 23:54:50 2009 +0000 +++ b/libpurple/protocols/jabber/presence.c Sat Mar 07 01:59:40 2009 +0000 @@ -93,11 +93,31 @@ g_free(my_base_jid); } - -void jabber_presence_send(PurpleAccount *account, PurpleStatus *status) +void jabber_set_status(PurpleAccount *account, PurpleStatus *status) { - PurpleConnection *gc = NULL; - JabberStream *js = NULL; + PurpleConnection *gc; + JabberStream *js; + + if (!purple_account_is_connected(account)) + return; + + if (!purple_status_is_active(status)) + return; + + if (purple_status_is_exclusive(status) && !purple_status_is_active(status)) { + /* An exclusive status can't be deactivated. You should just + * activate some other exclusive status. */ + return; + } + + gc = purple_account_get_connection(account); + js = purple_connection_get_protocol_data(gc); + jabber_presence_send(js, FALSE); +} + +void jabber_presence_send(JabberStream *js, gboolean force) +{ + PurpleAccount *account; xmlnode *presence, *x, *photo; char *stripped = NULL; JabberBuddyState state; @@ -106,28 +126,11 @@ int length = -1; gboolean allowBuzz; PurplePresence *p; - PurpleStatus *tune; - - if (purple_account_is_disconnected(account)) - return; - - p = purple_account_get_presence(account); - if (NULL == status) { - status = purple_presence_get_active_status(p); - } + PurpleStatus *status, *tune; - if (purple_status_is_exclusive(status)) { - /* An exclusive status can't be deactivated. You should just - * activate some other exclusive status. */ - if (!purple_status_is_active(status)) - return; - } else { - /* Work with the exclusive status. */ - status = purple_presence_get_active_status(p); - } - - gc = purple_account_get_connection(account); - js = gc->proto_data; + account = purple_connection_get_account(js->gc); + p = purple_account_get_presence(account); + status = purple_presence_get_active_status(p); /* we don't want to send presence before we've gotten our roster */ if(!js->roster_parsed) { @@ -141,16 +144,18 @@ allowBuzz = purple_status_get_attr_boolean(status,"buzz"); /* changing the buzz state has to trigger a re-broadcasting of the presence for caps */ - if (js->googletalk && stripped == NULL && purple_presence_is_status_primitive_active(p, PURPLE_STATUS_TUNE)) { - tune = purple_presence_get_status(p, "tune"); + tune = purple_presence_get_status(p, "tune"); + if (js->googletalk && !stripped && purple_status_is_active(tune)) { stripped = jabber_google_presence_outgoing(tune); } #define CHANGED(a,b) ((!a && b) || (a && a[0] == '\0' && b && b[0] != '\0') || \ (a && !b) || (a && a[0] != '\0' && b && b[0] == '\0') || (a && b && strcmp(a,b))) /* check if there are any differences to the <presence> and send them in that case */ - if (allowBuzz != js->allowBuzz || js->old_state != state || CHANGED(js->old_msg, stripped) || - js->old_priority != priority || CHANGED(js->old_avatarhash, js->avatar_hash)) { + if (force || allowBuzz != js->allowBuzz || js->old_state != state || + CHANGED(js->old_msg, stripped) || js->old_priority != priority || + CHANGED(js->old_avatarhash, js->avatar_hash)) { + /* Need to update allowBuzz before creating the presence (with caps) */ js->allowBuzz = allowBuzz; presence = jabber_presence_create_js(js, state, stripped, priority); @@ -181,8 +186,7 @@ g_free(stripped); /* next, check if there are any changes to the tune values */ - tune = purple_presence_get_status(p, "tune"); - if (tune && purple_status_is_active(tune)) { + if (purple_status_is_active(tune)) { artist = purple_status_get_attr_string(tune, PURPLE_TUNE_ARTIST); title = purple_status_get_attr_string(tune, PURPLE_TUNE_TITLE); source = purple_status_get_attr_string(tune, PURPLE_TUNE_ALBUM); @@ -260,11 +264,16 @@ } /* JEP-0115 */ + /* calculate hash */ + jabber_caps_calculate_own_hash(js); + /* create xml */ c = xmlnode_new_child(presence, "c"); xmlnode_set_namespace(c, "http://jabber.org/protocol/caps"); xmlnode_set_attrib(c, "node", CAPS0115_NODE); - xmlnode_set_attrib(c, "ver", VERSION); + xmlnode_set_attrib(c, "hash", "sha-1"); + xmlnode_set_attrib(c, "ver", jabber_caps_get_own_hash(js)); +#if 0 if(js != NULL) { /* add the extensions */ char extlist[1024]; @@ -296,7 +305,7 @@ if(remaining < 1023) xmlnode_set_attrib(c, "ext", extlist); } - +#endif return presence; } @@ -365,39 +374,41 @@ char *from; } JabberPresenceCapabilities; -static void jabber_presence_set_capabilities(JabberCapsClientInfo *info, gpointer user_data) { - JabberPresenceCapabilities *userdata = user_data; - JabberID *jid; +static void +jabber_presence_set_capabilities(JabberCapsClientInfo *info, GList *exts, + JabberPresenceCapabilities *userdata) +{ JabberBuddyResource *jbr; - GList *iter; + char *resource = g_utf8_strrchr(userdata->from, -1, '/'); + resource += 1; - jid = jabber_id_new(userdata->from); - jbr = jabber_buddy_find_resource(userdata->jb, jid->resource); - jabber_id_free(jid); - - if(!jbr) { + jbr = jabber_buddy_find_resource(userdata->jb, resource); + if (!jbr) { g_free(userdata->from); g_free(userdata); + if (exts) { + g_list_foreach(exts, (GFunc)g_free, NULL); + g_list_free(exts); + } return; } - if(jbr->caps) - jabber_caps_free_clientinfo(jbr->caps); - jbr->caps = info; + /* Any old jbr->caps.info is owned by the caps code */ + if (jbr->caps.exts) { + g_list_foreach(jbr->caps.exts, (GFunc)g_free, NULL); + g_list_free(jbr->caps.exts); + } - if (info) { - for(iter = info->features; iter; iter = g_list_next(iter)) { - if(!strcmp((const char*)iter->data, "http://jabber.org/protocol/commands")) { - JabberIq *iq = jabber_iq_new_query(userdata->js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#items"); - xmlnode *query = xmlnode_get_child_with_namespace(iq->node,"query","http://jabber.org/protocol/disco#items"); - xmlnode_set_attrib(iq->node, "to", userdata->from); - xmlnode_set_attrib(query, "node", "http://jabber.org/protocol/commands"); + jbr->caps.info = info; + jbr->caps.exts = exts; - jabber_iq_set_callback(iq, jabber_adhoc_disco_result_cb, NULL); - jabber_iq_send(iq); - break; - } - } + if (jabber_resource_has_capability(jbr, "http://jabber.org/protocol/commands")) { + JabberIq *iq = jabber_iq_new_query(userdata->js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#items"); + xmlnode *query = xmlnode_get_child_with_namespace(iq->node, "query", "http://jabber.org/protocol/disco#items"); + xmlnode_set_attrib(iq->node, "to", userdata->from); + xmlnode_set_attrib(query, "node", "http://jabber.org/protocol/commands"); + jabber_iq_set_callback(iq, jabber_adhoc_disco_result_cb, NULL); + jabber_iq_send(iq); } g_free(userdata->from); @@ -742,16 +753,22 @@ jbr = jabber_buddy_track_resource(jb, jid->resource, priority, state, status); if(caps) { + /* handle XEP-0115 */ const char *node = xmlnode_get_attrib(caps,"node"); const char *ver = xmlnode_get_attrib(caps,"ver"); + const char *hash = xmlnode_get_attrib(caps,"hash"); const char *ext = xmlnode_get_attrib(caps,"ext"); - if(node && ver) { + /* v1.3 uses: node, ver, and optionally ext. + * v1.5 uses: node, ver, and hash. */ + if (node && ver) { JabberPresenceCapabilities *userdata = g_new0(JabberPresenceCapabilities, 1); userdata->js = js; userdata->jb = jb; userdata->from = g_strdup(from); - jabber_caps_get_info(js, from, node, ver, ext, jabber_presence_set_capabilities, userdata); + jabber_caps_get_info(js, from, node, ver, hash, ext, + (jabber_caps_get_info_cb)jabber_presence_set_capabilities, + userdata); } } }