diff libgaim/blist.c @ 14752:4124030c3f3a

[gaim-migrate @ 17509] Fix the situation (I think it will only happen while shutting down) where GaimBuddy->proto_data could be accessed after it is freed. Specifically, it happened when gtkblist was requesting the emblems from the msn prpl. Big thanks to henningn for noticing the funkiness in valgrind. I discovered that there is no function to retrieve all the buddies for an account (shock, horror) - so I modified gaim_find_buddies() to return all the account buddies if "name" is NULL. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Wed, 18 Oct 2006 03:32:14 +0000
parents 11fd4148f9da
children 56dbadfa6543
line wrap: on
line diff
--- a/libgaim/blist.c	Wed Oct 18 03:27:43 2006 +0000
+++ b/libgaim/blist.c	Wed Oct 18 03:32:14 2006 +0000
@@ -65,6 +65,11 @@
 	return gaim_blist_get_last_sibling(node->child);
 }
 
+struct _list_account_buddies {
+	GSList *list;
+	GaimAccount *account;
+};
+
 struct _gaim_hbuddy {
 	char *name;
 	GaimAccount *account;
@@ -2119,26 +2124,46 @@
 	return ret;
 }
 
+static void find_acct_buddies(gpointer key, gpointer value, gpointer data)
+{
+	struct _gaim_hbuddy *hb = key;
+	GaimBuddy *buddy = value;
+	struct _list_account_buddies *ab = data;
+
+	if (hb->account == ab->account) {
+		ab->list = g_slist_prepend(ab->list, buddy);
+	}
+}
+
 GSList *gaim_find_buddies(GaimAccount *account, const char *name)
 {
-	struct buddy *buddy;
-	struct _gaim_hbuddy hb;
+	GaimBuddy *buddy;
 	GaimBlistNode *node;
 	GSList *ret = NULL;
 
 	g_return_val_if_fail(gaimbuddylist != NULL, NULL);
 	g_return_val_if_fail(account != NULL, NULL);
-	g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
-
-	hb.name = g_strdup(gaim_normalize(account, name));
-	hb.account = account;
-
-	for (node = gaimbuddylist->root; node != NULL; node = node->next) {
-		hb.group = node;
-		if ((buddy = g_hash_table_lookup(gaimbuddylist->buddies, &hb)) != NULL)
-			ret = g_slist_append(ret, buddy);
+
+
+	if ((name != NULL) && (*name != '\0')) {
+		struct _gaim_hbuddy hb;
+
+		hb.name = g_strdup(gaim_normalize(account, name));
+		hb.account = account;
+
+		for (node = gaimbuddylist->root; node != NULL; node = node->next) {
+			hb.group = node;
+			if ((buddy = g_hash_table_lookup(gaimbuddylist->buddies, &hb)) != NULL)
+				ret = g_slist_prepend(ret, buddy);
+		}
+		g_free(hb.name);
+	} else {
+		struct _list_account_buddies *ab = g_new0(struct _list_account_buddies, 1);
+		ab->account = account;
+		g_hash_table_foreach(gaimbuddylist->buddies, find_acct_buddies, ab);
+		ret = ab->list;
+		g_free(ab);
 	}
-	g_free(hb.name);
 
 	return ret;
 }