void jabber_roster_parse(JabberStream *js, const char *from, JabberIqType type, const char *id, xmlnode *query) { xmlnode *item, *group; if (!jabber_is_own_account(js, from)) { purple_debug_warning("jabber", "Received bogon roster push from %s\n", from); return; } js->currently_parsing_roster_push = TRUE; for(item = xmlnode_get_child(query, "item"); item; item = xmlnode_get_next_twin(item)) { const char *jid, *name, *subscription, *ask; JabberBuddy *jb; subscription = xmlnode_get_attrib(item, "subscription"); jid = xmlnode_get_attrib(item, "jid"); name = xmlnode_get_attrib(item, "name"); ask = xmlnode_get_attrib(item, "ask"); if(!jid) continue; if(!(jb = jabber_buddy_find(js, jid, TRUE))) continue; if(subscription) { if (jb == js->user_jb) jb->subscription = JABBER_SUB_BOTH; else if(!strcmp(subscription, "none")) jb->subscription = JABBER_SUB_NONE; else if(!strcmp(subscription, "to")) jb->subscription = JABBER_SUB_TO; else if(!strcmp(subscription, "from")) jb->subscription = JABBER_SUB_FROM; else if(!strcmp(subscription, "both")) jb->subscription = JABBER_SUB_BOTH; else if(!strcmp(subscription, "remove")) jb->subscription = JABBER_SUB_REMOVE; } if(purple_strequal(ask, "subscribe")) jb->subscription |= JABBER_SUB_PENDING; else jb->subscription &= ~JABBER_SUB_PENDING; if(jb->subscription & JABBER_SUB_REMOVE) { remove_purple_buddies(js, jid); } else { GSList *groups = NULL; gboolean seen_empty = FALSE; if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) if (!jabber_google_roster_incoming(js, item)) continue; for(group = xmlnode_get_child(item, "group"); group; group = xmlnode_get_next_twin(group)) { char *group_name = xmlnode_get_data(group); if (!group_name && !seen_empty) { group_name = g_strdup(""); seen_empty = TRUE; } groups = g_slist_prepend(groups, group_name); } add_purple_buddy_to_groups(js, jid, name, groups); if (jb == js->user_jb) jabber_presence_fake_to_self(js, NULL); } } js->currently_parsing_roster_push = FALSE; /* if we're just now parsing the roster for the first time, * then now would be the time to declare ourselves connected. */ if (js->state != JABBER_STREAM_CONNECTED) jabber_stream_set_state(js, JABBER_STREAM_CONNECTED); }
void jabber_roster_parse(JabberStream *js, const char *from, JabberIqType type, const char *id, xmlnode *query) { xmlnode *item, *group; #if 0 const char *ver; #endif if (!jabber_is_own_account(js, from)) { purple_debug_warning("jabber", "Received bogon roster push from %s\n", from); return; } js->currently_parsing_roster_push = TRUE; for(item = xmlnode_get_child(query, "item"); item; item = xmlnode_get_next_twin(item)) { const char *jid, *name, *subscription, *ask; JabberBuddy *jb; subscription = xmlnode_get_attrib(item, "subscription"); jid = xmlnode_get_attrib(item, "jid"); name = xmlnode_get_attrib(item, "name"); ask = xmlnode_get_attrib(item, "ask"); if(!jid) continue; if(!(jb = jabber_buddy_find(js, jid, TRUE))) continue; if(subscription) { if (g_str_equal(subscription, "remove")) jb->subscription = JABBER_SUB_REMOVE; else if (jb == js->user_jb) jb->subscription = JABBER_SUB_BOTH; else if (g_str_equal(subscription, "none")) jb->subscription = JABBER_SUB_NONE; else if (g_str_equal(subscription, "to")) jb->subscription = JABBER_SUB_TO; else if (g_str_equal(subscription, "from")) jb->subscription = JABBER_SUB_FROM; else if (g_str_equal(subscription, "both")) jb->subscription = JABBER_SUB_BOTH; } if(purple_strequal(ask, "subscribe")) jb->subscription |= JABBER_SUB_PENDING; else jb->subscription &= ~JABBER_SUB_PENDING; if(jb->subscription & JABBER_SUB_REMOVE) { remove_purple_buddies(js, jid); } else { GSList *groups = NULL; gboolean seen_empty = FALSE; if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) if (!jabber_google_roster_incoming(js, item)) continue; for(group = xmlnode_get_child(item, "group"); group; group = xmlnode_get_next_twin(group)) { char *group_name = xmlnode_get_data(group); if (!group_name && !seen_empty) { group_name = g_strdup(""); seen_empty = TRUE; } /* * See the note in add_purple_buddy_to_groups; the core handles * names case-insensitively and this is required to not * end up with duplicates if a buddy is in, e.g., * 'XMPP' and 'xmpp' */ if (g_slist_find_custom(groups, group_name, (GCompareFunc)purple_utf8_strcasecmp)) g_free(group_name); else groups = g_slist_prepend(groups, group_name); } add_purple_buddy_to_groups(js, jid, name, groups); if (jb == js->user_jb) jabber_presence_fake_to_self(js, NULL); } } #if 0 ver = xmlnode_get_attrib(query, "ver"); if (ver) { PurpleAccount *account = purple_connection_get_account(js->gc); purple_account_set_string(account, "roster_ver", ver); } #endif if (type == JABBER_IQ_SET) { JabberIq *ack = jabber_iq_new(js, JABBER_IQ_RESULT); jabber_iq_set_id(ack, id); jabber_iq_send(ack); } js->currently_parsing_roster_push = FALSE; }