Index: protocols/yahoo/libyahoo2.c
===================================================================
--- protocols/yahoo/libyahoo2.c	(revision 8b6b7405d3844271f7bff56e527bfeb1a4872975)
+++ protocols/yahoo/libyahoo2.c	(revision 547c94cf6b3654997ef2570d398468af75380b26)
@@ -855,53 +855,4 @@
 }
 
-static YList * bud_str2list(char *rawlist)
-{
-	YList * l = NULL;
-
-	char **lines;
-	char **split;
-	char **buddies;
-	char **tmp, **bud;
-
-	lines = y_strsplit(rawlist, "\n", -1);
-	for (tmp = lines; *tmp; tmp++) {
-		struct yahoo_buddy *newbud;
-
-		split = y_strsplit(*tmp, ":", 2);
-		if (!split)
-			continue;
-		if (!split[0] || !split[1]) {
-			y_strfreev(split);
-			continue;
-		}
-		buddies = y_strsplit(split[1], ",", -1);
-
-		for (bud = buddies; bud && *bud; bud++) {
-			newbud = y_new0(struct yahoo_buddy, 1);
-			newbud->id = strdup(*bud);
-			newbud->group = strdup(split[0]);
-
-			if(y_list_find_custom(l, newbud, is_same_bud)) {
-				FREE(newbud->id);
-				FREE(newbud->group);
-				FREE(newbud);
-				continue;
-			}
-
-			newbud->real_name = NULL;
-
-			l = y_list_append(l, newbud);
-
-			NOTICE(("Added buddy %s to group %s", newbud->id, newbud->group));
-		}
-
-		y_strfreev(buddies);
-		y_strfreev(split);
-	}
-	y_strfreev(lines);
-
-	return l;
-}
-
 static char * getcookie(char *rawcookie)
 {
@@ -1360,38 +1311,40 @@
 }
 
-
-static void yahoo_process_status(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
+static void yahoo_process_status(struct yahoo_input_data *yid,
+	struct yahoo_packet *pkt)
 {
 	YList *l;
 	struct yahoo_data *yd = yid->yd;
 
-	struct user
-	{
-		char *name;	/* 7	name */
-		int   state;	/* 10	state */
-		int   flags;	/* 13	flags, bit 0 = pager, bit 1 = chat, bit 2 = game */
-		int   mobile;	/* 60	mobile */
-		char *msg;	/* 19	custom status message */
-		int   away;	/* 47	away (or invisible)*/
-		int   buddy_session;	/* 11	state */
-		int   f17;	/* 17	in chat? then what about flags? */
-		int   idle;	/* 137	seconds idle */
-		int   f138;	/* 138	state */
-		char *f184;	/* 184	state */
-		int   f192;	/* 192	state */
-		int   f10001;	/* 10001	state */
-		int   f10002;	/* 10002	state */
-		int   f198;	/* 198	state */
-		char *f197;	/* 197	state */
-		char *f205;	/* 205	state */
-		int   f213;	/* 213	state */
+	struct user {
+		char *name;	/* 7      name */
+		int state;	/* 10     state */
+		int flags;	/* 13     flags, bit 0 = pager, bit 1 = chat, bit 2 = game */
+		int mobile;	/* 60     mobile */
+		char *msg;	/* 19     custom status message */
+		int away;	/* 47     away (or invisible) */
+		int buddy_session; /* 11  state */
+		int f17;	/* 17     in chat? then what about flags? */
+		int idle;	/* 137    seconds idle */
+		int f138;	/* 138    state */
+		char *f184;	/* 184    state */
+		int f192;	/* 192    state */
+		int f10001;	/* 10001  state */
+		int f10002;	/* 10002  state */
+		int f198;	/* 198    state */
+		char *f197;	/* 197    state */
+		char *f205;	/* 205    state */
+		int f213;	/* 213    state */
 	} *u;
 
 	YList *users = 0;
-	
+
 	if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {
-		YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_DUPL, NULL);
-		return;
-	}
+		YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id,
+			YAHOO_LOGIN_DUPL, NULL);
+		return;
+	}
+
+	u = NULL;
 
 	for (l = pkt->hash; l; l = l->next) {
@@ -1399,84 +1352,101 @@
 
 		switch (pair->key) {
-		case 0: /* we won't actually do anything with this */
+		case 300:	/* Begin buddy */
+			if (!strcmp(pair->value, "315") && !u) {
+				u = y_new0(struct user, 1);
+			}
+			break;
+		case 301:	/* End buddy */
+			if (!strcmp(pair->value, "315") && u) {
+				users = y_list_prepend(users, u);
+				u = NULL;
+			}
+			break;
+		case 0:	/* we won't actually do anything with this */
 			NOTICE(("key %d:%s", pair->key, pair->value));
 			break;
-		case 1: /* we don't get the full buddy list here. */
+		case 1:	/* we don't get the full buddy list here. */
 			if (!yd->logged_in) {
-				yd->logged_in = TRUE;
-				if(yd->current_status < 0)
+				yd->logged_in = 1;
+				if (yd->current_status < 0)
 					yd->current_status = yd->initial_status;
-				YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL);
+				YAHOO_CALLBACK(ext_yahoo_login_response) (yd->
+					client_id, YAHOO_LOGIN_OK, NULL);
 			}
 			break;
-		case 8: /* how many online buddies we have */
+		case 8:	/* how many online buddies we have */
 			NOTICE(("key %d:%s", pair->key, pair->value));
 			break;
-		case 7: /* the current buddy */
-			u = y_new0(struct user, 1);
+		case 7:	/* the current buddy */
+			if (!u) {
+				/* This will only happen in case of a single level message */
+				u = y_new0(struct user, 1);
+				users = y_list_prepend(users, u);
+			}
 			u->name = pair->value;
-			users = y_list_prepend(users, u);
-			break;
-		case 10: /* state */
-			((struct user*)users->data)->state = strtol(pair->value, NULL, 10);
-			break;
-		case 19: /* custom status message */
-			((struct user*)users->data)->msg = pair->value;
-			break;
-		case 47: /* is it an away message or not */
-			((struct user*)users->data)->away = atoi(pair->value);
-			break;
-		case 137: /* seconds idle */
-			((struct user*)users->data)->idle = atoi(pair->value);
-			break;
-		case 11: /* this is the buddy's session id */
-			((struct user*)users->data)->buddy_session = atoi(pair->value);
-			break;
-		case 17: /* in chat? */
-			((struct user*)users->data)->f17 = atoi(pair->value);
-			break;
-		case 13: /* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */
-			((struct user*)users->data)->flags = atoi(pair->value);
-			break;
-		case 60: /* SMS -> 1 MOBILE USER */
+			break;
+		case 10:	/* state */
+			u->state = strtol(pair->value, NULL, 10);
+			break;
+		case 19:	/* custom status message */
+			u->msg = pair->value;
+			break;
+		case 47:	/* is it an away message or not. Not applicable for YMSG16 anymore */
+			u->away = atoi(pair->value);
+			break;
+		case 137:	/* seconds idle */
+			u->idle = atoi(pair->value);
+			break;
+		case 11:	/* this is the buddy's session id */
+			u->buddy_session = atoi(pair->value);
+			break;
+		case 17:	/* in chat? */
+			u->f17 = atoi(pair->value);
+			break;
+		case 13:	/* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */
+			u->flags = atoi(pair->value);
+			break;
+		case 60:	/* SMS -> 1 MOBILE USER */
 			/* sometimes going offline makes this 2, but invisible never sends it */
-			((struct user*)users->data)->mobile = atoi(pair->value);
+			u->mobile = atoi(pair->value);
 			break;
 		case 138:
-			((struct user*)users->data)->f138 = atoi(pair->value);
+			u->f138 = atoi(pair->value);
 			break;
 		case 184:
-			((struct user*)users->data)->f184 = pair->value;
+			u->f184 = pair->value;
 			break;
 		case 192:
-			((struct user*)users->data)->f192 = atoi(pair->value);
+			u->f192 = atoi(pair->value);
 			break;
 		case 10001:
-			((struct user*)users->data)->f10001 = atoi(pair->value);
+			u->f10001 = atoi(pair->value);
 			break;
 		case 10002:
-			((struct user*)users->data)->f10002 = atoi(pair->value);
+			u->f10002 = atoi(pair->value);
 			break;
 		case 198:
-			((struct user*)users->data)->f198 = atoi(pair->value);
+			u->f198 = atoi(pair->value);
 			break;
 		case 197:
-			((struct user*)users->data)->f197 = pair->value;
+			u->f197 = pair->value;
 			break;
 		case 205:
-			((struct user*)users->data)->f205 = pair->value;
+			u->f205 = pair->value;
 			break;
 		case 213:
-			((struct user*)users->data)->f213 = atoi(pair->value);
-			break;
-		case 16: /* Custom error message */
-			YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, pair->value, 0, E_CUSTOM);
+			u->f213 = atoi(pair->value);
+			break;
+		case 16:	/* Custom error message */
+			YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id,
+				pair->value, 0, E_CUSTOM);
 			break;
 		default:
-			WARNING(("unknown status key %d:%s", pair->key, pair->value));
-			break;
-		}
-	}
-	
+			WARNING(("unknown status key %d:%s", pair->key,
+					pair->value));
+			break;
+		}
+	}
+
 	while (users) {
 		YList *t = users;
@@ -1484,14 +1454,20 @@
 
 		if (u->name != NULL) {
-			if (pkt->service == YAHOO_SERVICE_LOGOFF) { /* || u->flags == 0) { Not in YMSG16 */
-				YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0);
+			if (pkt->service ==
+				YAHOO_SERVICE_LOGOFF
+				/*|| u->flags == 0 No flags for YMSG16 */ ) {
+				YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->
+					client_id, u->name,
+					YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0);
 			} else {
 				/* Key 47 always seems to be 1 for YMSG16 */
-				if(!u->state)
+				if (!u->state)
 					u->away = 0;
 				else
 					u->away = 1;
 
-				YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile);
+				YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->
+					client_id, u->name, u->state, u->msg,
+					u->away, u->idle, u->mobile);
 			}
 		}
@@ -1503,5 +1479,6 @@
 }
 
-static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
+static void yahoo_process_buddy_list(struct yahoo_input_data *yid,
+	struct yahoo_packet *pkt)
 {
 	struct yahoo_data *yd = yid->yd;
@@ -1515,14 +1492,14 @@
 		struct yahoo_pair *pair = l->data;
 
-		switch(pair->key) {
+		switch (pair->key) {
 		case 300:
 		case 301:
 		case 302:
+			break;	/* Separators. Our logic does not need them */
 		case 303:
-			if ( 315 == atoi(pair->value) )
+			if (318 == atoi(pair->value))
 				last_packet = 1;
 			break;
 		case 65:
-			g_free(cur_group);
 			cur_group = strdup(pair->value);
 			break;
@@ -1530,17 +1507,12 @@
 			newbud = y_new0(struct yahoo_buddy, 1);
 			newbud->id = strdup(pair->value);
-			if (cur_group) {
+			if (cur_group)
 				newbud->group = strdup(cur_group);
-			} else {
-				YList *last;
-				struct yahoo_buddy *lastbud;
-				
-				for (last = yd->buddies; last && last->next; last = last->next);
-				if (last) {
-					lastbud = last->data;
-					newbud->group = strdup(lastbud->group);
-				} else {
-					newbud->group = strdup("Buddies");
-				}
+			else {
+				struct yahoo_buddy *lastbud =
+					(struct yahoo_buddy *)y_list_nth(yd->
+					buddies,
+					y_list_length(yd->buddies) - 1)->data;
+				newbud->group = strdup(lastbud->group);
 			}
 
@@ -1550,76 +1522,56 @@
 		}
 	}
-	
-	g_free(cur_group);
 
 	/* we could be getting multiple packets here */
-	if (last_packet)
-		return;
-
-	YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies);
-
-	/*** We login at the very end of the packet communication */
+	if (pkt->hash && !last_packet)
+		return;
+
+	YAHOO_CALLBACK(ext_yahoo_got_buddies) (yd->client_id, yd->buddies);
+
+	/* Logged in */
 	if (!yd->logged_in) {
-		yd->logged_in = TRUE;
-		if(yd->current_status < 0)
+		yd->logged_in = 1;
+		if (yd->current_status < 0)
 			yd->current_status = yd->initial_status;
-		YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL);
-	}
-}
-
-static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
+		YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id,
+			YAHOO_LOGIN_OK, NULL);
+
+		/*
+		yahoo_set_away(yd->client_id, yd->initial_status, NULL,
+			(yd->initial_status == YAHOO_STATUS_AVAILABLE) ? 0 : 1);
+
+		yahoo_get_yab(yd->client_id);
+		*/
+	}
+
+}
+
+static void yahoo_process_list(struct yahoo_input_data *yid,
+	struct yahoo_packet *pkt)
 {
 	struct yahoo_data *yd = yid->yd;
 	YList *l;
 
-	if (!yd->logged_in) {
-		yd->logged_in = TRUE;
-		if(yd->current_status < 0)
-			yd->current_status = yd->initial_status;
-		YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL);
-	}
-
+	/* we could be getting multiple packets here */
 	for (l = pkt->hash; l; l = l->next) {
 		struct yahoo_pair *pair = l->data;
 
-		switch(pair->key) {
-		case 87: /* buddies */
-			if(!yd->rawbuddylist)
-				yd->rawbuddylist = strdup(pair->value);
-			else {
-				yd->rawbuddylist = y_string_append(yd->rawbuddylist, pair->value);
+		switch (pair->key) {
+		case 89:	/* identities */
+			{
+				char **identities =
+					y_strsplit(pair->value, ",", -1);
+				int i;
+				for (i = 0; identities[i]; i++)
+					yd->identities =
+						y_list_append(yd->identities,
+						strdup(identities[i]));
+				y_strfreev(identities);
 			}
-			break;
-
-		case 88: /* ignore list */
-			if(!yd->ignorelist)
-				yd->ignorelist = strdup("Ignore:");
-			yd->ignorelist = y_string_append(yd->ignorelist, pair->value);
-			break;
-
-		case 89: /* identities */
-			{
-			char **identities = y_strsplit(pair->value, ",", -1);
-			int i;
-			for(i=0; identities[i]; i++)
-				yd->identities = y_list_append(yd->identities, 
-						strdup(identities[i]));
-			y_strfreev(identities);
-			}
-			YAHOO_CALLBACK(ext_yahoo_got_identities)(yd->client_id, yd->identities);
-			break;
-		case 59: /* cookies */
-			if(yd->ignorelist) {
-				yd->ignore = bud_str2list(yd->ignorelist);
-				FREE(yd->ignorelist);
-				YAHOO_CALLBACK(ext_yahoo_got_ignore)(yd->client_id, yd->ignore);
-			}
-			if(yd->rawbuddylist) {
-				yd->buddies = bud_str2list(yd->rawbuddylist);
-				FREE(yd->rawbuddylist);
-				YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies);
-			}
-
-			if(pair->value[0]=='Y') {
+			YAHOO_CALLBACK(ext_yahoo_got_identities) (yd->client_id,
+				yd->identities);
+			break;
+		case 59:	/* cookies */
+			if (pair->value[0] == 'Y') {
 				FREE(yd->cookie_y);
 				FREE(yd->login_cookie);
@@ -1628,26 +1580,26 @@
 				yd->login_cookie = getlcookie(yd->cookie_y);
 
-			} else if(pair->value[0]=='T') {
+			} else if (pair->value[0] == 'T') {
 				FREE(yd->cookie_t);
 				yd->cookie_t = getcookie(pair->value);
 
-			} else if(pair->value[0]=='C') {
+			} else if (pair->value[0] == 'C') {
 				FREE(yd->cookie_c);
 				yd->cookie_c = getcookie(pair->value);
-			} 
-
-			if(yd->cookie_y && yd->cookie_t)
-				YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id);
-
-			break;
-		case 3: /* my id */
-		case 90: /* 1 */
-		case 100: /* 0 */
-		case 101: /* NULL */
-		case 102: /* NULL */
-		case 93: /* 86400/1440 */
-			break;
-		}
-	}
+			}
+
+			break;
+		case 3:	/* my id */
+		case 90:	/* 1 */
+		case 100:	/* 0 */
+		case 101:	/* NULL */
+		case 102:	/* NULL */
+		case 93:	/* 86400/1440 */
+			break;
+		}
+	}
+
+	if (yd->cookie_y && yd->cookie_t)	/* We don't get cookie_c anymore */
+		YAHOO_CALLBACK(ext_yahoo_got_cookies) (yd->client_id);
 }
 
