changeset 4770:c4c28874ecd3

[gaim-migrate @ 5088] I want to go to sleep. This is drag-n-drop moving of buddies in the list. I think it works, but I didn't actually test it... I really should have though; I can't imagine it working fine as-is. ;) I'm holding off on the rest of my Edit Buddy List stuff for tomorrow... I love last minute things, don't I? Note: I created gaim_blist_members and gaim_blist_groups to reproduce the effects of the old groups GSList and the members GSList of the group struct that I removed. This is really sub-optimal and should be replaced to iterate the Buddy List directly. If someone wants to do that, please do. Even if you don't want to do that, just review the changes I made and make sure I didn't do anything stupid. It is past 6am and I'm a bit tired and prone to mistake making. Thanks. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Fri, 14 Mar 2003 11:38:21 +0000
parents e0afac5f85bd
children 912bacf989d7
files plugins/ticker/ticker.c src/buddy.c src/core.c src/core.h src/dialogs.c src/gtkconv.c src/list.c src/list.h src/multi.c src/perl.c src/protocols/gg/gg.c src/protocols/irc/irc.c src/protocols/oscar/oscar.c src/protocols/toc/toc.c src/protocols/zephyr/zephyr.c src/server.c
diffstat 16 files changed, 286 insertions(+), 159 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/ticker/ticker.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/plugins/ticker/ticker.c	Fri Mar 14 11:38:21 2003 +0000
@@ -330,11 +330,11 @@
 
 void BuddyTickerShow()
 {
+	/* Someone should fix the ticker
 	struct group *g;
 	struct buddy *b;
 	GSList *grps, *buds;
 	const char *xpm;
-
 	for( grps = groups; grps; grps = grps->next ) {
 		g = (struct group *)grps->data;
 		for( buds = g->members; buds; buds = buds->next ) {
@@ -347,6 +347,7 @@
 			}
 		}
 	}
+	*/
 }
 
 void signon_cb(struct gaim_connection *gc, char *who) {
--- a/src/buddy.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/buddy.c	Fri Mar 14 11:38:21 2003 +0000
@@ -345,6 +345,21 @@
 		memcpy(&b, sd->data, sizeof(b));
 		if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) {
 			/* if we're here, I think it means the drop is ok */
+			GtkTreeIter iter;
+			GaimBlistNode *node;
+			GValue val = {0};
+			gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path);
+			gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val);
+			node = g_value_get_pointer(&val);
+			if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
+				if (position == GTK_TREE_VIEW_DROP_AFTER) {
+					gaim_blist_add_buddy(b, node->parent, node);
+				} else if (position == GTK_TREE_VIEW_DROP_BEFORE) {
+					gaim_blist_add_buddy(b, node->parent, node->prev);
+				}
+			} else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
+				gaim_blist_add_buddy(b, node, NULL);
+			}	
 			gtk_tree_path_free(path);
 		}
 	}
@@ -1214,6 +1229,8 @@
 
 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list)
 {
+	if (!gtkblist)
+		return;
 	gtk_widget_destroy(gtkblist->window);
 
 	gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL;
--- a/src/core.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/core.c	Fri Mar 14 11:38:21 2003 +0000
@@ -56,7 +56,6 @@
 #endif
 int gaim_session = 0;
 GSList *uis = NULL;
-GSList *groups = NULL;
 
 static guchar *UI_build(guint32 *len, guchar type, guchar subtype, va_list args)
 {
--- a/src/core.h	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/core.h	Fri Mar 14 11:38:21 2003 +0000
@@ -160,7 +160,6 @@
 
 /* Globals in core.c */
 extern GSList *uis;
-extern GSList *groups;
 extern int gaim_session;
 
 /* Globals in plugins.c */
--- a/src/dialogs.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/dialogs.c	Fri Mar 14 11:38:21 2003 +0000
@@ -933,18 +933,20 @@
 	GList *tmp = NULL;
 	char *tmp2;
 	struct group *g;
-	GSList *grp = groups;
+	GSList *grp = gaim_blist_groups();
+	GSList *grp1 = grp;
 
 	if (!grp) {
 		tmp2 = g_strdup(_("Buddies"));
 		tmp = g_list_append(tmp, tmp2);
 	} else {
-		while (grp) {
-			g = (struct group *)grp->data;
+		while (grp1) {
+			g = (struct group *)grp1->data;
 			tmp2 = g->name;
 			tmp = g_list_append(tmp, tmp2);
-			grp = g_slist_next(grp);
+			grp1 = g_slist_next(grp);
 		}
+		g_slist_free(grp);
 	}
 	return tmp;
 }
@@ -3901,9 +3903,7 @@
 			char *prevname;
 	
 			if ((orig = gaim_find_group(new_name)) != NULL && g_strcasecmp(new_name, g->name)) {
-				orig->members = g_slist_concat(orig->members, g->members);
 				gaim_blist_rename_group(orig, g->name);
-				groups = g_slist_remove(groups, g);
 				accts = gaim_group_get_accounts(g);
 				while(accts) {
 					struct gaim_account *account = accts->data;
@@ -3999,7 +3999,7 @@
 {
 	const char *new_name;
 	struct buddy *b;
-	GSList *gr;
+	GSList *gr, *gr1;
 
 	new_name = gtk_entry_get_text(GTK_ENTRY(entry));
 	b = g_object_get_data(obj, "buddy");
@@ -4009,12 +4009,16 @@
 		return;
 	}
 
-	gr = groups;
-	while (gr) {
-		if (g_slist_find(((struct group *)gr->data)->members, b))
+	gr = gaim_blist_groups();
+	gr1 = gr;
+	while (gr1) {
+		GSList *mem = gaim_blist_members((struct group*)gr->data);
+		if (g_slist_find(mem, b))
 			break;
-		gr = gr->next;
+		gr1 = gr1->next;
+		g_slist_free(mem);
 	}
+	g_slist_free(gr);
 	if (!gr) {
 		destroy_dialog(rename_bud_dialog, rename_bud_dialog);
 		return;
--- a/src/gtkconv.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/gtkconv.c	Fri Mar 14 11:38:21 2003 +0000
@@ -2202,8 +2202,8 @@
 static GList *
 generate_invite_user_names(struct gaim_connection *gc)
 {
-	GSList *grp;
-	GSList *bl;
+	GSList *grp = gaim_blist_groups(), *grp1;
+	GSList *bl, *bl1;
 	struct group *g;
 	struct buddy *buddy;
 	static GList *tmp = NULL;
@@ -2214,16 +2214,18 @@
 	tmp = g_list_append(NULL, "");
 
 	if (gc != NULL) {
-		for (grp = groups; grp != NULL; grp = grp->next) {
-			g = (struct group *)grp->data;
-
-			for (bl = g->members; bl != NULL; bl = bl->next) {
-				buddy = (struct buddy *)bl->data;
+		for (grp1 = grp; grp1 != NULL; grp1 = grp1->next) {
+			g = (struct group *)grp1->data;
+			bl = gaim_blist_members(g);
+			for (bl1 = bl; bl1 != NULL; bl1 = bl1->next) {
+				buddy = (struct buddy *)bl1->data;
 
 				if (buddy->present)
 					tmp = g_list_append(tmp, buddy->name);
 			}
+			g_slist_free(bl);
 		}
+		g_slist_free(grp);
 	}
 
 	return tmp;
--- a/src/list.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/list.c	Fri Mar 14 11:38:21 2003 +0000
@@ -83,6 +83,34 @@
 }
 
 /*****************************************************************************
+ * Public Utility Functions                                                  *
+ *****************************************************************************/
+
+GSList *gaim_blist_members(struct group *g)
+{
+	GaimBlistNode *group = (GaimBlistNode*)g;
+	GSList *list = NULL;
+	GaimBlistNode *child = group->child;
+	while (child) {
+		list = g_slist_append(list, child);
+		child = child->next;
+	}
+	return list;
+}
+
+GSList *gaim_blist_groups()
+{
+	struct gaim_buddy_list *gaimbuddylist = gaim_get_blist();
+	GSList *list = NULL;
+	GaimBlistNode *g = gaimbuddylist->root;
+	while (g) {
+		list = g_slist_append(list, g);
+		g = g->next;
+	}
+	return list;
+}
+
+/*****************************************************************************
  * Public API functions                                                      *
  *****************************************************************************/
 
@@ -217,6 +245,7 @@
 	GaimBlistNode *n = node, *node2, *node3;
 	struct group *g = group;
 	struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
+	gboolean save = FALSE;
 	if (!n) {
 		if (!g) {
 			g = gaim_group_new(_("Buddies"));
@@ -225,13 +254,24 @@
 		n = gaim_blist_get_last_child((GaimBlistNode*)g);
 	}
 
-	node2 = ((GaimBlistNode*)buddy)->next;
-	node3 = ((GaimBlistNode*)buddy)->prev;
-	
-	if (node2)
-		node2->prev = node3;
-	if (node3)
-		node3->next = node2;
+	if (((GaimBlistNode*)buddy)->parent) {
+		/* This buddy was already in the list and is
+		 * being moved.
+		 */
+		ops->remove(gaimbuddylist, (GaimBlistNode*)buddy);
+		node2 = ((GaimBlistNode*)buddy)->next;
+		node3 = ((GaimBlistNode*)buddy)->prev;
+		
+		if (node2)
+			node2->prev = node3;
+		if (node3)
+			node3->next = node2;
+
+		if (((GaimBlistNode*)buddy)->parent != n->parent)
+			serv_move_buddy(buddy, (struct group*)((GaimBlistNode*)buddy)->parent, 
+					(struct group*)n->parent);
+		save = TRUE;
+	}
 
 	if (n) {
 		((GaimBlistNode*)buddy)->next = n->next;
@@ -245,10 +285,10 @@
 		((GaimBlistNode*)buddy)->parent = (GaimBlistNode*)g;
 	}
 
-	g->members = g_slist_append(g->members, buddy);
-	
 	if (ops)
 		ops->update(gaimbuddylist, (GaimBlistNode*)buddy);
+	if (save) 
+		gaim_blist_save();
 }
 
 struct group *gaim_group_new(const char *name)
@@ -314,8 +354,6 @@
 	if (node->next)
 		node->next->prev = node->prev;
 
-	group->members = g_slist_remove(group->members, buddy);
-
 	ops->remove(gaimbuddylist, node);
 	g_free(buddy->name);
 	g_free(buddy->alias);
@@ -781,13 +819,15 @@
 }
 
 gboolean gaim_group_on_account(struct group *g, struct gaim_account *account) {
-	GSList *buds = g->members;
-	while(buds) {
+	GSList *buds = gaim_blist_members(g);
+	GSList *buds1 = buds;
+	while(buds1) {
 		struct buddy *b = buds->data;
 		if((!account && b->account->gc) || b->account == account)
 			return TRUE;
-		buds = buds->next;
+		buds1 = buds1->next;
 	}
+	g_slist_free(buds);
 	return FALSE;
 }
 
@@ -1121,9 +1161,11 @@
 	for(group = (struct group*)gaimbuddylist->root; group; group = (struct group*)((GaimBlistNode*)group)->next) {
 		if(!exp_acct || gaim_group_on_account(group, exp_acct)) {
 			char *group_name = g_markup_escape_text(group->name, -1);
+			GSList *buds1;
 			fprintf(file, "\t\t<group name=\"%s\">\n", group_name);
-			for(buds = group->members; buds; buds = buds->next) {
-				bud = buds->data;
+			buds = gaim_blist_members(group);
+			for(buds1 = buds; buds1; buds1 = buds1->next) {
+				bud = buds1->data;
 				if(!exp_acct || bud->account == exp_acct) {
 					char *bud_name = g_markup_escape_text(bud->name, -1);
 					char *bud_alias = NULL;
@@ -1149,6 +1191,7 @@
 					g_free(acct_name);
 				}
 			}
+			g_slist_free(buds);
 			fprintf(file, "\t\t</group>\n");
 			g_free(group_name);
 		}
@@ -1189,7 +1232,6 @@
 
 	if(!user_dir)
 		return;
-
 	if(!blist_safe_to_write) {
 		debug_printf("AHH!! tried to write the blist before we read it!\n");
 		return;
--- a/src/list.h	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/list.h	Fri Mar 14 11:38:21 2003 +0000
@@ -82,8 +82,6 @@
 struct group {
 	GaimBlistNode node;                    /**< The node that this group inherits from */
 	char *name;                            /**< The name of this group. */
-	GSList *members;                       /**< The buddies in this group.  This is different from node.child in that it will only
-						  contain buddies. */
 };
 
 
@@ -119,6 +117,29 @@
 }; 
 
 /**************************************************************************/
+/** Public Utility Functions                                              */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns a GSList of the groups
+ */
+GSList *gaim_blist_groups();
+
+/**
+ *  Returns a GSList of the members of a group node.
+ *
+ * It's obviously much faster to recurse the GaimBlistNode linked list
+ * then using this function.  You should try to avoid using it.  Only use it
+ * when you're about to make a milestone release in a few hours and are desperately
+ * trying to add a critical feature
+ *
+ * @param group The group
+ */
+GSList *gaim_blist_members(struct group *group);
+/*@}*/
+
+/**************************************************************************/
 /** @name Buddy List API                                                  */
 /**************************************************************************/
 /*@{*/
@@ -294,7 +315,6 @@
  */
 void gaim_blist_remove_group(struct group *group);
 
-
 /**
  * Returns the alias of a buddy.
  *
--- a/src/multi.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/multi.c	Fri Mar 14 11:38:21 2003 +0000
@@ -154,22 +154,24 @@
 
 void destroy_gaim_conn(struct gaim_connection *gc)
 {
-	GSList *g = groups;
-	GSList *h;
+	GSList *g = gaim_blist_groups(), *g1 = g;
+	GSList *h, *h1;
 	struct group *m;
 	struct buddy *n;
-	while (g) {
-		m = (struct group *)g->data;
-		g = g_slist_next(g);
-		h = m->members;
-		while (h) {
-			n = (struct buddy *)h->data;
-			h = g_slist_next(h);
+	while (g1) {
+		m = (struct group *)g1->data;
+		g1 = g_slist_next(g1);
+		h1 = h = gaim_blist_members(m);
+		while (h1) {
+			n = (struct buddy *)h1->data;
+			h1 = g_slist_next(h1);
 			if(n->account == gc->account) {
 				n->present = 0;
 			}
 		}
+		g_slist_free(h);
 	}
+	g_slist_free(g);
 	g_free(gc->away);
 	g_free(gc->away_state);
 	g_free(gc);
@@ -1312,7 +1314,8 @@
 static void do_del_acct(struct gaim_account *account)
 {
 	GtkTreeIter iter;
-	GSList *grps = groups, *buds;
+	GSList *grps1, *grps, *buds;
+	grps1 = grps = gaim_blist_groups();
 
 	if (account->gc) {
 		account->gc->wants_to_die = TRUE;
@@ -1325,24 +1328,24 @@
 
 
 	/* remove the buddies for the account we just destroyed */
-	while(grps) {
-		struct group *g = grps->data;
-		grps = grps->next;
-		buds = g->members;
-		while(buds) {
-			struct buddy *b = buds->data;
-			buds = buds->next;
+	while(grps1) {
+		struct group *g = grps1->data;
+		GSList *buds1, *buds = gaim_blist_members(g);
+		buds1 = buds;
+		grps1 = grps1->next;
+		while(buds1) {
+			struct buddy *b = buds1->data;
+			buds1 = buds1->next;
 			if(b->account == account) {
-				/* sigh, someday we'll get a central gaim_buddy_free() */
-				g->members = g_slist_remove(g->members, b);
-				g_hash_table_destroy(b->settings);
-				g_free(b);
+				gaim_blist_remove_buddy(b);
 			}
 		}
-		if(!g->members) {
+		g_slist_free(buds);
+		if(!((GaimBlistNode*)g)->child) {
 			gaim_blist_remove_group(g);
 		}
 	}
+	g_slist_free(grps);
 
 	gaim_accounts = g_slist_remove(gaim_accounts, account);
 
@@ -1519,7 +1522,7 @@
 	struct signon_meter *meter = find_signon_meter(gc);
 	GList *wins;
 	GtkTreeIter iter;
-	GSList *grps, *buds;
+	GSList *grps, *grps1, *buds, *buds1;
 	GList *add_buds=NULL;
 	GList *l;
 
@@ -1576,16 +1579,19 @@
 	}
 
 	/* let the prpl know what buddies we pulled out of the local list */
-
-	for(grps = groups; grps; grps = grps->next) {
-		struct group *g = grps->data;
-		for(buds = g->members; buds; buds = buds->next) {
-			struct buddy *b = buds->data;
+	grps = gaim_blist_groups();
+	for(grps1 = grps; grps1; grps1 = grps1->next) {
+		struct group *g = grps1->data;
+		buds = gaim_blist_members(g);
+		for(buds1 = buds; buds1; buds1 = buds1->next) {
+			struct buddy *b = buds1->data;
 			if(b->account == gc->account) {
 				add_buds = g_list_append(add_buds, b->name);
 			}
 		}
+		g_slist_free(buds);
 	}
+	g_slist_free(grps);
 
 	if(add_buds) {
 		serv_add_buddies(gc, add_buds);
--- a/src/perl.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/perl.c	Fri Mar 14 11:38:21 2003 +0000
@@ -666,25 +666,27 @@
 	struct gaim_connection *gc;
 	struct buddy *buddy;
 	struct group *g;
-	GSList *list = groups;
-	GSList *mem;
+	GSList *list = gaim_blist_groups(), *list1 = list;
+	GSList *mem, *mem1;
 	int i = 0;
 	dXSARGS;
 	items = 0;
 
 	gc = (struct gaim_connection *)SvIV(ST(0));
 
-	while (list) {
-		g = (struct group *)list->data;
-		mem = g->members;
-		while (mem) {
-			buddy = (struct buddy *)mem->data;
+	while (list1) {
+		g = (struct group *)list1->data;
+		mem1 = mem = gaim_blist_members(g);
+		while (mem1) {
+			buddy = (struct buddy *)mem1->data;
 			if(buddy->account == gc->account)
 				XST_mPV(i++, buddy->name);
-			mem = mem->next;
+			mem1 = mem1->next;
 		}
-		list = g_slist_next(list);
+		g_slist_free(mem);
+		list1 = g_slist_next(list1);
 	}
+	g_slist_free(list);
 	XSRETURN(i);
 }
 
@@ -693,24 +695,27 @@
 	struct gaim_connection *gc;
 	struct buddy *b;
 	struct group *g;
-	GSList *list = groups;
-	GSList *mem;
+	GSList *list = gaim_blist_groups(), *list1 = list;
+	GSList *mem, *mem1;
 	int i = 0;
 	dXSARGS;
 	items = 0;
 
 	gc = (struct gaim_connection *)SvIV(ST(0));
 
-	while (list) {
-		g = (struct group *)list->data;
-		mem = g->members;
-		while (mem) {
-			b = (struct buddy *)mem->data;
+	while (list1) {
+		g = (struct group *)list1->data;
+		mem = gaim_blist_members(g);
+		mem1 = mem;
+		while (mem1) {
+			b = (struct buddy *)mem1->data;
 			if (b->account == gc->account && b->present) XST_mPV(i++, b->name);
-			mem = mem->next;
+			mem1 = mem1->next;
 		}
-		list = g_slist_next(list);
+		g_slist_free(mem);
+		list1 = g_slist_next(list1);
 	}
+	g_slist_free(list);
 	XSRETURN(i);
 }
 
--- a/src/protocols/gg/gg.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/protocols/gg/gg.c	Fri Mar 14 11:38:21 2003 +0000
@@ -1,6 +1,6 @@
 /*
  * gaim - Gadu-Gadu Protocol Plugin
- * $Id: gg.c 5047 2003-03-13 06:08:56Z faceprint $
+ * $Id: gg.c 5088 2003-03-14 11:38:21Z seanegan $
  *
  * Copyright (C) 2001 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
  * 
@@ -85,7 +85,6 @@
 
 /* for win32 compatability */
 G_MODULE_IMPORT GSList *connections;
-G_MODULE_IMPORT GSList *groups;
 
 struct agg_data {
 	struct gg_session *sess;
@@ -1005,7 +1004,8 @@
 	gchar *u = gg_urlencode(gc->username);
 	gchar *p = gg_urlencode(gc->password);
 
-	GSList *gr = groups;
+	GSList *gr = gaim_blist_groups();
+	GSList *gr1 = gr;
 
 	he->gc = gc;
 	he->type = AGG_HTTP_USERLIST_EXPORT;
@@ -1016,12 +1016,13 @@
 	g_free(u);
 	g_free(p);
 
-	while (gr) {
-		struct group *g = gr->data;
-		GSList *m = g->members;
+	while (gr1) {
+		struct group *g = gr1->data;
+		GSList *m = gaim_blist_members(g);
+		GSList *m1 = m;
 		int num_added=0;
-		while (m) {
-			struct buddy *b = m->data;
+		while (m1) {
+			struct buddy *b = m1->data;
 
 			if(b->account == gc->account) {
 				gchar *newdata;
@@ -1050,10 +1051,12 @@
 				g_free(show);
 				g_free(name);
 			}
-			m = g_slist_next(m);
+			m1 = g_slist_next(m1);
 		}
-		gr = g_slist_next(gr);
+		g_slist_free(m);
+		gr = g_slist_next(gr1);
 	}
+	g_slist_free(gr);
 
 	if (proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, he) < 0) {
 		do_error_dialog(_("Couldn't export buddy list"), 
--- a/src/protocols/irc/irc.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/protocols/irc/irc.c	Fri Mar 14 11:38:21 2003 +0000
@@ -61,7 +61,6 @@
 
 /* for win32 compatability */
 G_MODULE_IMPORT GSList *connections;
-G_MODULE_IMPORT GSList *groups;
 
 #ifndef INET6_ADDRSTRLEN
 #define INET6_ADDRSTRLEN 46
@@ -570,7 +569,7 @@
 handle_list(struct gaim_connection *gc, char *list)
 {
 	struct irc_data *id = gc->proto_data;
-	GSList *gr;
+	GSList *gr, *gr1;
 
 	id->str = g_string_append_c(id->str, ' ');
 	id->str = g_string_append(id->str, list);
@@ -579,10 +578,12 @@
 		return;
 
 	g_strdown(id->str->str);
-	gr = groups;
-	while (gr) {
-		GSList *m = ((struct group *)gr->data)->members;
-		while (m) {
+	gr = gaim_blist_groups();
+	gr1 = gr;
+	while (gr1) {
+		GSList *m = gaim_blist_members((struct group *)gr1->data);
+		GSList *m1 = m;
+		while (m1) {
 			struct buddy *b = m->data;
 			if(b->account->gc == gc) {
 				char *tmp = g_strdup(b->name);
@@ -598,10 +599,12 @@
 					serv_got_update(gc, b->name, 0, 0, 0, 0, 0);
 				g_free(tmp);
 			}
-			m = m->next;
+			m1 = m1->next;
 		}
-		gr = gr->next;
+		g_slist_free(m);
+		gr1 = gr1->next;
 	}
+	g_slist_free(gr);
 	g_string_free(id->str, TRUE);
 	id->str = g_string_new("");
 }
@@ -615,14 +618,16 @@
 	int n = g_snprintf(buf, sizeof(buf), "ISON");
 	gboolean found = FALSE;
 
-	GSList *gr = groups;
+	GSList *gr = gaim_blist_groups();
+	GSList *gr1 = gr;
 	if (!gr || id->bc)
 		return TRUE;
 
-	while (gr) {
+	while (gr1) {
 		struct group *g = gr->data;
-		GSList *m = g->members;
-		while (m) {
+		GSList *m = gaim_blist_members(g);
+		GSList *m1 = m;
+		while (m1) {
 			struct buddy *b = m->data;
 			if(b->account->gc == gc) {
 				if (n + strlen(b->name) + 2 > sizeof(buf)) {
@@ -635,10 +640,12 @@
 
 				found = TRUE;
 			}
-			m = m->next;
+			m1 = m1->next;
 		}
-		gr = gr->next;
+		g_slist_free(m);
+		gr1 = gr1->next;
 	}
+	g_slist_free(gr);
 
 	if (found) {
 		g_snprintf(buf + n, sizeof(buf) - n, "\r\n");
--- a/src/protocols/oscar/oscar.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/protocols/oscar/oscar.c	Fri Mar 14 11:38:21 2003 +0000
@@ -73,7 +73,6 @@
 /* For win32 compatability */
 G_MODULE_IMPORT GSList *connections;
 G_MODULE_IMPORT int report_idle;
-G_MODULE_IMPORT GSList *groups;
 
 static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_IMIMAGE | AIM_CAPS_SENDFILE;
 static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_IMIMAGE | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8;
@@ -4494,6 +4493,7 @@
 		struct group *group;
 		struct buddy *buddy;
 		struct gaim_buddy_list *blist;
+		GSList *groups = gaim_blist_groups();
 		GSList *cur;
 
 		/* Buddies */
@@ -4548,14 +4548,18 @@
 		/* Check for maximum number of buddies */
 		for (cur=groups, tmp=0; cur; cur=g_slist_next(cur)) {
 			struct group* gr = (struct group*)cur->data;
-			GSList *buds = gr->members;
-			while(buds) {
-				struct buddy *b = buds->data;
+			GSList *buds = gaim_blist_members(gr);
+			GSList *buds1 = buds;
+			while(buds1) {
+				struct buddy *b = buds1->data;
 				if(b->account == gc->account)
 					tmp++;
-				buds = buds->next;
+				buds1 = buds1->next;
 			}
+			g_slist_free(buds);
 		}
+		g_slist_free(groups);
+
 		if (tmp > od->rights.maxbuddies) {
 			char *dialog_msg = g_strdup_printf(_("The maximum number of buddies allowed in your buddy list is %d, and you have %d."
 							     "  Until you are below the limit, some buddies will not show up as online."), 
@@ -5143,7 +5147,7 @@
 static void oscar_set_permit_deny(struct gaim_connection *gc) {
 	struct oscar_data *od = (struct oscar_data *)gc->proto_data;
 #ifdef NOSSI
-	GSList *list, *g;
+	GSList *list, *g = gaim_blist_groups(), *g1;
 	char buf[MAXMSGLEN];
 	int at;
 
@@ -5173,18 +5177,21 @@
 		aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, buf);
 		break;
 	case 5:
-		g = groups;
+		g1 = g;
 		at = 0;
-		while (g) {
-			list = ((struct group *)g->data)->members;
-			while (list) {
-				struct buddy *b = list->data;
+		while (g1) {
+			list = gaim_blist_members((struct group *)g->data);
+			GSList list1 = list;
+			while (list1) {
+				struct buddy *b = list1->data;
 				if(b->account == gc->account)
 					at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", b->name);
-				list = list->next;
+				list1 = list1->next;
 			}
-			g = g->next;
+			g_slist_free(list);
+			g1 = g1->next;
 		}
+		g_slist_free(g);
 		aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, buf);
 		break;
 	default:
@@ -5412,15 +5419,17 @@
 {
 	struct oscar_data *od = gc->proto_data;
 	gchar *nombre, *text, *tmp;
-	GSList *curg, *curb;
+	GSList *curg = gaim_blist_groups(), *curg1, *curb;
 	int num=0;
 
 	text = g_strdup(_("You are awaiting authorization from the following buddies:<BR>"));
 
-	for (curg=groups; curg; curg=g_slist_next(curg)) {
-		struct group *group = curg->data;
-		for (curb=group->members; curb; curb=g_slist_next(curb)) {
-			struct buddy *buddy = curb->data;
+	for (curg1 = curg; curg1; curg1=g_slist_next(curg1)) {
+		struct group *group = curg1->data;
+		GSList *curb = gaim_blist_members(group);
+		GSList *curb1;
+		for (curb1=curb; curb1; curb1=g_slist_next(curb1)) {
+			struct buddy *buddy = curb1->data;
 			if (buddy->account == gc->account && aim_ssi_waitingforauth(od->sess->ssi.local, group->name, buddy->name)) {
 				if (gaim_get_buddy_alias_only(buddy))
 					nombre = g_strdup_printf(" %s (%s)", buddy->name, gaim_get_buddy_alias_only(buddy));
@@ -5433,7 +5442,9 @@
 				num++;
 			}
 		}
+		g_slist_free(curb);
 	}
+	g_slist_free(curg);
 
 	if (!num) {
 		tmp = g_strdup_printf("%s<BR>%s", text, _("<i>you are not waiting for authorization</i>"));
--- a/src/protocols/toc/toc.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/protocols/toc/toc.c	Fri Mar 14 11:38:21 2003 +0000
@@ -56,7 +56,6 @@
 
 /* for win32 compatability */
 G_MODULE_IMPORT GSList *connections;
-G_MODULE_IMPORT GSList *groups;
 
 #define REVISION "penguin"
 
@@ -268,8 +267,9 @@
 
 static void toc_build_config(struct gaim_account *account, char *s, int len, gboolean show)
 {
-	GSList *grp = groups;
-	GSList *mem;
+	GSList *grp = gaim_blist_groups();
+	GSList *grp1 = grp;
+	GSList *mem, *mem1;
 	struct group *g;
 	struct buddy *b;
 	GSList *plist = account->permit;
@@ -281,23 +281,26 @@
 		account->permdeny = 1;
 
 	pos += g_snprintf(&s[pos], len - pos, "m %d\n", account->permdeny);
-	while (len > pos && grp) {
-		g = (struct group *)grp->data;
+	while (len > pos && grp1) {
+		g = (struct group *)grp1->data;
 		if(gaim_group_on_account(g, account)) {
 			pos += g_snprintf(&s[pos], len - pos, "g %s\n", g->name);
-			mem = g->members;
-			while (len > pos && mem) {
-				b = (struct buddy *)mem->data;
+			mem = gaim_blist_members(g);
+			mem1 = mem;
+			while (len > pos && mem1) {
+				b = (struct buddy *)mem1->data;
 				if(b->account == account) {
 					pos += g_snprintf(&s[pos], len - pos, "b %s%s%s\n", b->name,
 							(show && b->alias) ? ":" : "",
 							(show && b->alias) ? b->alias : "");
 				}
-				mem = mem->next;
+				mem1 = mem1->next;
 			}
+			g_slist_free(mem);
 		}
-		grp = g_slist_next(grp);
+		grp1 = g_slist_next(grp1);
 	}
+	g_slist_free(grp);
 
 	while (len > pos && plist) {
 		pos += g_snprintf(&s[pos], len - pos, "p %s\n", (char *)plist->data);
--- a/src/protocols/zephyr/zephyr.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/protocols/zephyr/zephyr.c	Fri Mar 14 11:38:21 2003 +0000
@@ -440,19 +440,21 @@
 
 static gint check_loc(gpointer data)
 {
-	GSList *gr, *m;
+	GSList *gr, *gr1, *m, *m1;
 	ZAsyncLocateData_t ald;
 
 	ald.user = NULL;
 	memset(&(ald.uid), 0, sizeof(ZUnique_Id_t));
 	ald.version = NULL;
 
-	gr = groups;
-	while (gr) {
-		struct group *g = gr->data;
-		m = g->members;
-		while (m) {
-			struct buddy *b = m->data;
+	gr = gaim_blist_groups();
+        gr1 = gr;
+	while (gr1) {
+		struct group *g = gr1->data;
+		m = gaim_blist_members(g);
+                m1 = m;
+		while (m1) {
+			struct buddy *b = m1->data;
 			if(b->account->gc == zgc) {
 				char *chk;
 				chk = zephyr_normalize(b->name);
@@ -461,10 +463,12 @@
 				free(ald.user);
 				free(ald.version);
 			}
-			m = m->next;
+			m1 = m1->next;
 		}
-		gr = gr->next;
+                g_slist_free(m);
+		gr1 = gr1->next;
 	}
+        g_slist_free(gr1);
 
 	return TRUE;
 }
@@ -660,7 +664,7 @@
 
 static void write_anyone()
 {
-	GSList *gr, *m;
+	GSList *gr, *gr1, *m, *m1;
 	struct group *g;
 	struct buddy *b;
 	char *ptr, *fname, *ptr2;
@@ -673,12 +677,14 @@
 		return;
 	}
 
-	gr = groups;
-	while (gr) {
-		g = gr->data;
-		m = g->members;
-		while (m) {
-			b = m->data;
+	gr = gaim_blist_groups();
+	gr1 = gr;
+        while (gr1) {
+		g = gr1->data;
+		m = gaim_blist_members(g);
+                m1 = m;
+		while (m1) {
+			b = m1->data;
 			if(b->account->gc == zgc) {
 				if ((ptr = strchr(b->name, '@')) != NULL) {
 					ptr2 = ptr + 1;
@@ -693,10 +699,12 @@
 				if (ptr)
 					*ptr = '@';
 			}
-			m = m->next;
+			m1 = m1->next;
 		}
-		gr = gr->next;
+                g_slist_free(m);
+		gr1 = gr1->next;
 	}
+        g_slist_free(gr);
 
 	fclose(fd);
 	g_free(fname);
--- a/src/server.c	Fri Mar 14 08:27:13 2003 +0000
+++ b/src/server.c	Fri Mar 14 11:38:21 2003 +0000
@@ -393,11 +393,11 @@
 		GList *tobemoved = NULL;
 		GSList *original;
 
-		for (original=old_group->members; original; original=g_slist_next(original)) {
+		/*		for (original=old_group->members; original; original=g_slist_next(original)) {
 			struct buddy *b = original->data;
 			if(b->account == g->account)
 				tobemoved = g_list_append(tobemoved, b->name);
-		}
+				} */
 
 		if (g->prpl->rename_group) {
 			/* prpl's might need to check if the group already