Mercurial > pidgin
diff libpurple/protocols/jabber/presence.c @ 25168:805aadbb1a85
propagate from branch 'im.pidgin.pidgin' (head 98fe04f817ef415faebd3f7a38b7f0588c0b0cba)
to branch 'org.darkrain42.pidgin.xmpp' (head ac187cbd274e328fdc1b2f362f58333a0467f54f)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sat, 22 Nov 2008 19:44:46 +0000 |
parents | 39841a84c944 7dcba13d0e28 |
children | b1b1b75a922e |
line wrap: on
line diff
--- a/libpurple/protocols/jabber/presence.c Fri Nov 21 19:49:47 2008 +0000 +++ b/libpurple/protocols/jabber/presence.c Sat Nov 22 19:44:46 2008 +0000 @@ -94,11 +94,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 = gc->proto_data; + jabber_presence_send(js, FALSE); +} + +void jabber_presence_send(JabberStream *js, gboolean force) +{ + PurpleAccount *account; xmlnode *presence, *x, *photo; char *stripped = NULL; JabberBuddyState state; @@ -107,28 +127,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) { @@ -142,16 +145,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); @@ -182,8 +187,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); @@ -261,11 +265,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]; @@ -277,7 +286,7 @@ JabberFeature *feat = (JabberFeature*)feature->data; unsigned featlen; - if(feat->is_enabled != NULL && feat->is_enabled(js, feat->shortname, feat->namespace) == FALSE) + if(feat->is_enabled != NULL && feat->is_enabled(js, feat->namespace) == FALSE) continue; /* skip this feature */ featlen = strlen(feat->shortname); @@ -297,7 +306,7 @@ if(remaining < 1023) xmlnode_set_attrib(c, "ext", extlist); } - +#endif return presence; } @@ -373,38 +382,31 @@ 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, 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); return; } - if(jbr->caps) - jabber_caps_free_clientinfo(jbr->caps); + /* old value in jbr->caps is owned by caps code */ jbr->caps = info; 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"); - - jabber_iq_set_callback(iq, jabber_adhoc_disco_result_cb, NULL); - jabber_iq_send(iq); - break; - } + GList *node = g_list_find_custom(info->features, "http://jabber.org/protocol/commands", (GCompareFunc)strcmp); + if (node) { + 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); } } @@ -748,16 +750,19 @@ 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 *ext = xmlnode_get_attrib(caps,"ext"); + const char *hash = xmlnode_get_attrib(caps,"hash"); - if(node && ver) { + if(node && ver && hash) { 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, + (jabber_caps_get_info_cb)jabber_presence_set_capabilities, + userdata); } } }