changeset 27445:eff7db4db632

Various minor changes to jabber_presence_parse. No functionality changes. This will spit out a few more warnings and refuse to handle a presence with a non-standard type. There is no actual 'available' type, so don't bother checking for it in the last chunk in presence.c
author Paul Aurich <paul@darkrain42.org>
date Mon, 06 Jul 2009 00:45:54 +0000
parents c4196cd47602
children 735e58197140
files libpurple/protocols/jabber/buddy.c libpurple/protocols/jabber/presence.c
diffstat 2 files changed, 77 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/buddy.c	Sun Jul 05 23:55:56 2009 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Mon Jul 06 00:45:54 2009 +0000
@@ -1820,45 +1820,45 @@
 	return JABBER_BUDDY_STATE_UNKNOWN;
 }
 
-JabberBuddyState jabber_buddy_show_get_state(const char *id) {
-	if(!id)
-		return JABBER_BUDDY_STATE_UNKNOWN;
-	if(!strcmp(id, "available"))
-		return JABBER_BUDDY_STATE_ONLINE;
-	if(!strcmp(id, "chat"))
-		return JABBER_BUDDY_STATE_CHAT;
-	if(!strcmp(id, "away"))
-		return JABBER_BUDDY_STATE_AWAY;
-	if(!strcmp(id, "xa"))
-		return JABBER_BUDDY_STATE_XA;
-	if(!strcmp(id, "dnd"))
-		return JABBER_BUDDY_STATE_DND;
-	if(!strcmp(id, "offline"))
-		return JABBER_BUDDY_STATE_UNAVAILABLE;
-	if(!strcmp(id, "error"))
-		return JABBER_BUDDY_STATE_ERROR;
+const struct {
+	const char *name;
+	JabberBuddyState state;
+} show_state_pairs[] = {
+	{ "available", JABBER_BUDDY_STATE_ONLINE },
+	{ "chat",      JABBER_BUDDY_STATE_CHAT },
+	{ "away",      JABBER_BUDDY_STATE_AWAY },
+	{ "xa",        JABBER_BUDDY_STATE_XA },
+	{ "dnd",       JABBER_BUDDY_STATE_DND },
+	{ "offline",   JABBER_BUDDY_STATE_UNAVAILABLE },
+	{ "error",     JABBER_BUDDY_STATE_ERROR },
+	{ NULL,        JABBER_BUDDY_STATE_UNKNOWN }
+};
 
+JabberBuddyState jabber_buddy_show_get_state(const char *id)
+{
+	int i;
+
+	g_return_val_if_fail(id != NULL, JABBER_BUDDY_STATE_UNKNOWN);
+
+	for (i = 0; show_state_pairs[i].name; ++i)
+		if (g_str_equal(id, show_state_pairs[i].name))
+			return show_state_pairs[i].state;
+
+	purple_debug_warning("jabber", "Invalid value of presence <show/> "
+	                     "attribute: %s\n", id);
 	return JABBER_BUDDY_STATE_UNKNOWN;
 }
 
-const char *jabber_buddy_state_get_show(JabberBuddyState state) {
-	switch(state) {
-		case JABBER_BUDDY_STATE_CHAT:
-			return "chat";
-		case JABBER_BUDDY_STATE_AWAY:
-			return "away";
-		case JABBER_BUDDY_STATE_XA:
-			return "xa";
-		case JABBER_BUDDY_STATE_DND:
-			return "dnd";
-		case JABBER_BUDDY_STATE_ONLINE:
-			return "available";
-		case JABBER_BUDDY_STATE_UNKNOWN:
-		case JABBER_BUDDY_STATE_ERROR:
-			return NULL;
-		case JABBER_BUDDY_STATE_UNAVAILABLE:
-			return "offline";
-	}
+const char *
+jabber_buddy_state_get_show(JabberBuddyState state)
+{
+	int i;
+
+	for (i = 0; show_state_pairs[i].name; ++i)
+		if (state == show_state_pairs[i].state)
+			return show_state_pairs[i].name;
+
+/*	purple_debug_warning("jabber", "Unknown buddy state: %d\n", state); */
 	return NULL;
 }
 
--- a/libpurple/protocols/jabber/presence.c	Sun Jul 05 23:55:56 2009 +0000
+++ b/libpurple/protocols/jabber/presence.c	Mon Jul 06 00:45:54 2009 +0000
@@ -486,34 +486,57 @@
 	from = xmlnode_get_attrib(packet, "from");
 	type = xmlnode_get_attrib(packet, "type");
 
-	if(!(jb = jabber_buddy_find(js, from, TRUE)))
-		return;
+	jb = jabber_buddy_find(js, from, TRUE);
+	g_return_if_fail(jb != NULL);
 
 	signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(jabber_plugin,
 			"jabber-receiving-presence", js->gc, type, from, packet));
 	if (signal_return)
 		return;
 
-	if(!(jid = jabber_id_new(from)))
+	jid = jabber_id_new(from);
+	if (jid == NULL) {
+		purple_debug_error("jabber", "Ignoring presence with malformed 'from' "
+		                   "JID: %s\n", from);
 		return;
+	}
 
 	if(jb->error_msg) {
 		g_free(jb->error_msg);
 		jb->error_msg = NULL;
 	}
 
-	if(type && !strcmp(type, "error")) {
+	if (type == NULL) {
+		xmlnode *show;
+		char *show_data = NULL;
+
+		state = JABBER_BUDDY_STATE_ONLINE;
+
+		show = xmlnode_get_child(packet, "show");
+		if (show) {
+			show_data = xmlnode_get_data(show);
+			if (show_data) {
+				state = jabber_buddy_show_get_state(show_data);
+				g_free(show_data);
+			} else
+				purple_debug_warning("jabber", "<show/> present on presence, "
+				                     "but no contents!\n");
+		}
+	} else if (g_str_equal(type, "error")) {
 		char *msg = jabber_parse_error(js, packet, NULL);
 
 		state = JABBER_BUDDY_STATE_ERROR;
 		jb->error_msg = msg ? msg : g_strdup(_("Unknown Error in presence"));
-	} else if(type && !strcmp(type, "subscribe")) {
+	} else if (g_str_equal(type, "subscribe")) {
 		struct _jabber_add_permit *jap = g_new0(struct _jabber_add_permit, 1);
 		gboolean onlist = FALSE;
-		PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(js->gc), from);
+		PurpleAccount *account;
+		PurpleBuddy *buddy;
 		JabberBuddy *jb = NULL;
 		xmlnode *nick;
 
+		account = purple_connection_get_account(js->gc);
+		buddy = purple_find_buddy(account, from);
 		nick = xmlnode_get_child_with_namespace(packet, "nick", "http://jabber.org/protocol/nick");
 		if (nick)
 			nickname = xmlnode_get_data(nick);
@@ -528,16 +551,17 @@
 		jap->who = g_strdup(from);
 		jap->js = js;
 
-		purple_account_request_authorization(purple_connection_get_account(js->gc), from, NULL, nickname, NULL, onlist,
-				authorize_add_cb, deny_add_cb, jap);
+		purple_account_request_authorization(account, from, NULL, nickname,
+				NULL, onlist, authorize_add_cb, deny_add_cb, jap);
+
 		g_free(nickname);
 		jabber_id_free(jid);
 		return;
-	} else if(type && !strcmp(type, "subscribed")) {
+	} else if (g_str_equal(type, "subscribed")) {
 		/* we've been allowed to see their presence, but we don't care */
 		jabber_id_free(jid);
 		return;
-	} else if(type && !strcmp(type, "unsubscribe")) {
+	} else if (g_str_equal(type, "unsubscribe")) {
 		/* XXX I'm not sure this is the right way to handle this, it
 		 * might be better to add "unsubscribe" to the presence status
 		 * if lower down, but I'm not sure. */
@@ -547,13 +571,10 @@
 		jabber_id_free(jid);
 		return;
 	} else {
-		if((y = xmlnode_get_child(packet, "show"))) {
-			char *show = xmlnode_get_data(y);
-			state = jabber_buddy_show_get_state(show);
-			g_free(show);
-		} else {
-			state = JABBER_BUDDY_STATE_ONLINE;
-		}
+		purple_debug_warning("jabber", "Ignoring presence with invalid type "
+		                     "'%s'\n", type);
+		jabber_id_free(jid);
+		return;
 	}
 
 
@@ -688,7 +709,7 @@
 		}
 
 
-		if(type && !strcmp(type, "unavailable")) {
+		if (type && g_str_equal(type, "unavailable")) {
 			gboolean nick_change = FALSE;
 			gboolean kick = FALSE;
 			gboolean is_our_resource = FALSE; /* Is the presence about us? */
@@ -887,8 +908,8 @@
 		}
 
 		if(state == JABBER_BUDDY_STATE_ERROR ||
-				(type && (!strcmp(type, "unavailable") ||
-						  !strcmp(type, "unsubscribed")))) {
+				(type && (g_str_equal(type, "unavailable") ||
+				          g_str_equal(type, "unsubscribed")))) {
 			PurpleConversation *conv;
 
 			jabber_buddy_remove_resource(jb, jid->resource);
@@ -917,7 +938,7 @@
 		g_free(buddy_name);
 	}
 
-	if (caps && (!type || g_str_equal(type, "available"))) {
+	if (caps && !type) {
 		/* handle Entity Capabilities (XEP-0115) */
 		const char *node = xmlnode_get_attrib(caps, "node");
 		const char *ver  = xmlnode_get_attrib(caps, "ver");