Пример #1
0
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);
}
Пример #2
0
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;
}