Esempio n. 1
0
void jabber_roster_parse(JabberStream *js, xmlnode *packet)
{
	int nCount    = 0;	/*VOXOX - JRT - 2009.04.08 */
	int nGroupCnt = 0;	//VOXOX - JRT - 2009.05.07 
	xmlnode *query, *item, *group;
	const char *from = xmlnode_get_attrib(packet, "from");

	if(from) {
		char *from_norm;
		gboolean invalid;

		from_norm = g_strdup(jabber_normalize(js->gc->account, from));

		if(!from_norm)
			return;

		invalid = g_utf8_collate(from_norm,
				jabber_normalize(js->gc->account,
					purple_account_get_username(js->gc->account)));

		g_free(from_norm);

		if(invalid)
			return;
	}

	query = xmlnode_get_child(packet, "query");
	if(!query)
		return;

	//VOXOX - JRT - 2009.04.11 - So we can notify UI of initial contact list loading is starting.
	if(!js->roster_parsed) 
	{
		set_purple_initial_load( 1 );
	}
	//End VoxOx
	js->currently_parsing_roster_push = TRUE;

	//VOXOX - JRT - 2009.04.08 - We parsed about 1200 in less than 1 second with add_purple_buddies_to_groups() commented.
	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) {
			gint me = -1;
			char *jid_norm;
			const char *username;

			jid_norm = g_strdup(jabber_normalize(js->gc->account, jid));
			username = purple_account_get_username(js->gc->account);
			me = g_utf8_collate(jid_norm,
			                    jabber_normalize(js->gc->account,
			                                     username));
			g_free(jid_norm);

			if(me == 0)
				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;
			/* XXX: if subscription is now "from" or "none" we need to
			 * fake a signoff, since we won't get any presence from them
			 * anymore */
			/* YYY: I was going to use this, but I'm not sure it's necessary
			 * anymore, but it's here in case it is. */
			/*
			if ((jb->subscription & JABBER_SUB_FROM) ||
					(jb->subscription & JABBER_SUB_NONE)) {
				purple_prpl_got_user_status(js->gc->account, jid, "offline", NULL);
			}
			*/
		}

		if(ask && !strcmp(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;

			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;

				if(!(group_name = xmlnode_get_data(group)))
					group_name = g_strdup("");
				else
					nGroupCnt++;	//VOXOX - JRT - 2009.05.07 

				if (g_slist_find_custom(groups, group_name, (GCompareFunc)purple_utf8_strcasecmp) == NULL)
					groups = g_slist_append(groups, group_name);
				else
					g_free(group_name);
			}
			add_purple_buddies_to_groups(js, jid, name, groups);
			nCount++;	//VOXOX - JRT - 2009.04.08 
		}
	}

	//VOXOX - JRT - 2009.05.07 - We are getting inconsistent data from server.  Log so Developers are less likely to chase wrong problem.
#ifdef _WINDOWS
	if ( nCount == 0 ) 
	{
		g_print( "(WARNING) roster.c - jabber_roster_parse() - NO contacts found.  XML appears empty.\n");
	}
	else
	{
		g_print( "(INFO) roster.c - jabber_roster_parse() - %d contacts found.\n", nCount);
		if ( nGroupCnt == 0 )
		{
			g_print( "(WARNING) roster.c - jabber_roster_parse() - NO groups found.  Found %d contacts.\n", nCount );
		}
	}
#endif
	//End VoxOx
	js->currently_parsing_roster_push = FALSE;
	//VOXOX - JRT - 2009.04.11 - So we can notify UI of initial contact list loading is complete.
	if(!js->roster_parsed) 
	{
		set_purple_initial_load( 0 );
	}
	//End VoxOx

	/* if we're just now parsing the roster for the first time,
	 * then now would be the time to send our initial presence */
	if(!js->roster_parsed) {
		js->roster_parsed = TRUE;

		jabber_presence_send(js->gc->account, NULL);
	}
}
Esempio n. 2
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);
}
Esempio n. 3
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;
}