Index: protocols/yahoo/libyahoo2.c
===================================================================
--- protocols/yahoo/libyahoo2.c	(revision 6bbb939e953bbe1ca9ed3101a1569abe4521f543)
+++ protocols/yahoo/libyahoo2.c	(revision cfc8d58f4c15048e943800272017f69804bb61b7)
@@ -104,4 +104,6 @@
 #define YAHOO_CALLBACK(x)	x
 #endif
+
+static int yahoo_send_data(int fd, void *data, int len);
 
 int yahoo_log_message(char * fmt, ...)
@@ -204,5 +206,10 @@
 	YAHOO_SERVICE_CHATLOGOUT = 0xa0,
 	YAHOO_SERVICE_CHATPING,
-	YAHOO_SERVICE_COMMENT = 0xa8
+	YAHOO_SERVICE_COMMENT = 0xa8,
+	YAHOO_SERVICE_STEALTH = 0xb9,
+	YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd,
+	YAHOO_SERVICE_PICTURE = 0xbe,
+	YAHOO_SERVICE_PICTURE_UPDATE = 0xc1,
+	YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2
 };
 
@@ -741,4 +748,7 @@
 	yahoo_packet_dump(data, len);
 	
+	if( yid->type == YAHOO_CONNECTION_FT )
+		yahoo_send_data(yid->fd, data, len);
+	else
 	yahoo_add_to_send_queue(yid, data, len);
 	FREE(data);
@@ -926,4 +936,5 @@
 	char *msg = NULL;
 	char *from = NULL;
+	char *to = NULL;
 	int stat = 0;
 	int accept = 0;
@@ -934,4 +945,6 @@
 		if (pair->key == 4)
 			from = pair->value;
+		if (pair->key == 5)
+			to = pair->value;
 		if (pair->key == 49)
 			msg = pair->value;
@@ -951,11 +964,11 @@
 	
 	if (!strncasecmp(msg, "TYPING", strlen("TYPING"))) 
-		YAHOO_CALLBACK(ext_yahoo_typing_notify)(yd->client_id, from, stat);
+		YAHOO_CALLBACK(ext_yahoo_typing_notify)(yd->client_id, to, from, stat);
 	else if (!strncasecmp(msg, "GAME", strlen("GAME"))) 
-		YAHOO_CALLBACK(ext_yahoo_game_notify)(yd->client_id, from, stat);
+		YAHOO_CALLBACK(ext_yahoo_game_notify)(yd->client_id, to, from, stat);
 	else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) 
 	{
 		if (!strcmp(ind, " ")) {
-			YAHOO_CALLBACK(ext_yahoo_webcam_invite)(yd->client_id, from);
+			YAHOO_CALLBACK(ext_yahoo_webcam_invite)(yd->client_id, to, from);
 		} else {
 			accept = atoi(ind);
@@ -963,5 +976,5 @@
 			if (accept < 0)
 				accept = 0;
-			YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply)(yd->client_id, from, accept);
+			YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply)(yd->client_id, to, from, accept);
 		}
 	}
@@ -1022,5 +1035,5 @@
 	}
 	if(url && from)
-		YAHOO_CALLBACK(ext_yahoo_got_file)(yd->client_id, from, url, expires, msg, filename, filesize);
+		YAHOO_CALLBACK(ext_yahoo_got_file)(yd->client_id, to, from, url, expires, msg, filename, filesize);
 
 }
@@ -1096,7 +1109,7 @@
 			;
 		else if(members)
-			YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, host, room, msg, members);
+			YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members);
 		else if(msg)
-			YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, msg, 0);
+			YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, msg, 0, E_CONFNOTAVAIL);
 		break;
 	case YAHOO_SERVICE_CONFADDINVITE:
@@ -1104,21 +1117,21 @@
 			;
 		else
-			YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, host, room, msg, members);
+			YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members);
 		break;
 	case YAHOO_SERVICE_CONFDECLINE:
 		if(who)
-			YAHOO_CALLBACK(ext_yahoo_conf_userdecline)(yd->client_id, who, room, msg);
+			YAHOO_CALLBACK(ext_yahoo_conf_userdecline)(yd->client_id, id, who, room, msg);
 		break;
 	case YAHOO_SERVICE_CONFLOGON:
 		if(who)
-			YAHOO_CALLBACK(ext_yahoo_conf_userjoin)(yd->client_id, who, room);
+			YAHOO_CALLBACK(ext_yahoo_conf_userjoin)(yd->client_id, id, who, room);
 		break;
 	case YAHOO_SERVICE_CONFLOGOFF:
 		if(who)
-			YAHOO_CALLBACK(ext_yahoo_conf_userleave)(yd->client_id, who, room);
+			YAHOO_CALLBACK(ext_yahoo_conf_userleave)(yd->client_id, id, who, room);
 		break;
 	case YAHOO_SERVICE_CONFMSG:
 		if(who)
-			YAHOO_CALLBACK(ext_yahoo_conf_message)(yd->client_id, who, room, msg, utf8);
+			YAHOO_CALLBACK(ext_yahoo_conf_message)(yd->client_id, id, who, room, msg, utf8);
 		break;
 	}
@@ -1128,4 +1141,5 @@
 {
 	char *msg = NULL;
+	char *id = NULL;
 	char *who = NULL;
 	char *room = NULL;
@@ -1144,4 +1158,9 @@
 		struct yahoo_pair *pair = l->data;
 
+		if (pair->key == 1) {
+			/* My identity */
+			id = pair->value;
+		}
+
 		if (pair->key == 104) {
 			/* Room name */
@@ -1218,10 +1237,10 @@
 	if(!room) {
 		if (pkt->service == YAHOO_SERVICE_CHATLOGOUT) { /* yahoo originated chat logout */
-			YAHOO_CALLBACK(ext_yahoo_chat_yahoologout)(yid->yd->client_id);
+			YAHOO_CALLBACK(ext_yahoo_chat_yahoologout)(yid->yd->client_id, id);
 			return ;
 		}
 		if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr)  {
-			YAHOO_CALLBACK(ext_yahoo_chat_yahooerror)(yid->yd->client_id);
-			return ;
+			YAHOO_CALLBACK(ext_yahoo_chat_yahooerror)(yid->yd->client_id, id);
+			return;
 		}
 
@@ -1236,5 +1255,5 @@
 		}
 		if(firstjoin && members) {
-			YAHOO_CALLBACK(ext_yahoo_chat_join)(yid->yd->client_id, room, topic, members, yid->fd);
+			YAHOO_CALLBACK(ext_yahoo_chat_join)(yid->yd->client_id, id, room, topic, members, yid->fd);
 		} else if(who) {
 			if(y_list_length(members) != 1) {
@@ -1245,5 +1264,5 @@
 				YList *n = members->next;
 				currentmember = members->data;
-				YAHOO_CALLBACK(ext_yahoo_chat_userjoin)(yid->yd->client_id, room, currentmember);
+				YAHOO_CALLBACK(ext_yahoo_chat_userjoin)(yid->yd->client_id, id, room, currentmember);
 				y_list_free_1(members);
 				members=n;
@@ -1253,10 +1272,10 @@
 	case YAHOO_SERVICE_CHATEXIT:
 		if(who) {
-			YAHOO_CALLBACK(ext_yahoo_chat_userleave)(yid->yd->client_id, room, who);
+			YAHOO_CALLBACK(ext_yahoo_chat_userleave)(yid->yd->client_id, id, room, who);
 		}
 		break;
 	case YAHOO_SERVICE_COMMENT:
 		if(who) {
-			YAHOO_CALLBACK(ext_yahoo_chat_message)(yid->yd->client_id, who, room, msg, msgtype, utf8);
+			YAHOO_CALLBACK(ext_yahoo_chat_message)(yid->yd->client_id, id, who, room, msg, msgtype, utf8);
 		}
 		break;
@@ -1317,7 +1336,7 @@
 			YAHOO_CALLBACK(ext_yahoo_system_message)(yd->client_id, message->msg);
 		} else if (pkt->status <= 2 || pkt->status == 5) {
-			YAHOO_CALLBACK(ext_yahoo_got_im)(yd->client_id, message->from, message->msg, message->tm, pkt->status, message->utf8);
+			YAHOO_CALLBACK(ext_yahoo_got_im)(yd->client_id, message->to, message->from, message->msg, message->tm, pkt->status, message->utf8);
 		} else if (pkt->status == 0xffffffff) {
-			YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, message->msg, 0);
+			YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, message->msg, 0, E_SYSTEM);
 		}
 		free(message);
@@ -1332,11 +1351,30 @@
 	YList *l;
 	struct yahoo_data *yd = yid->yd;
-	char *name = NULL;
-	int state = 0;
-	int away = 0;
-	int idle = 0;
-	char *msg = NULL;
+
+	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) {
+	if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {
 		YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_DUPL, NULL);
 		return;
@@ -1362,43 +1400,62 @@
 			break;
 		case 7: /* the current buddy */
-			name = pair->value;
+			u = y_new0(struct user, 1);
+			u->name = pair->value;
+			users = y_list_prepend(users, u);
 			break;
 		case 10: /* state */
-			state = strtol(pair->value, NULL, 10);
+			((struct user*)users->data)->state = strtol(pair->value, NULL, 10);
 			break;
 		case 19: /* custom status message */
-			msg = pair->value;
+			((struct user*)users->data)->msg = pair->value;
 			break;
 		case 47: /* is it an away message or not */
-			away = atoi(pair->value);
+			((struct user*)users->data)->away = atoi(pair->value);
 			break;
 		case 137: /* seconds idle */
-			idle = atoi(pair->value);
-			break;
-		case 11: /* what is this? */
-			NOTICE(("key %d:%s", pair->key, pair->value));
+			((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? */
-			break;
-		case 13: /* in pager? */
-			if (pkt->service == YAHOO_SERVICE_LOGOFF || strtol(pair->value, NULL, 10) == 0) {
-				YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, YAHOO_STATUS_OFFLINE, NULL, 1);
-				break;
-			}
-			if (state == YAHOO_STATUS_AVAILABLE) {
-				YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, NULL, 0);
-			} else if (state == YAHOO_STATUS_CUSTOM) {
-				YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away);
-			} else {
-				YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, NULL, idle);
-			}
-
-			break;
-		case 60: 
+			((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 */
 			/* sometimes going offline makes this 2, but invisible never sends it */
-			NOTICE(("key %d:%s", pair->key, pair->value));
-			 break;
+			((struct user*)users->data)->mobile = atoi(pair->value);
+			break;
+		case 138:
+			((struct user*)users->data)->f138 = atoi(pair->value);
+			break;
+		case 184:
+			((struct user*)users->data)->f184 = pair->value;
+			break;
+		case 192:
+			((struct user*)users->data)->f192 = atoi(pair->value);
+			break;
+		case 10001:
+			((struct user*)users->data)->f10001 = atoi(pair->value);
+			break;
+		case 10002:
+			((struct user*)users->data)->f10002 = atoi(pair->value);
+			break;
+		case 198:
+			((struct user*)users->data)->f198 = atoi(pair->value);
+			break;
+		case 197:
+			((struct user*)users->data)->f197 = pair->value;
+			break;
+		case 205:
+			((struct user*)users->data)->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);
+			YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, pair->value, 0, E_CUSTOM);
 			break;
 		default:
@@ -1406,4 +1463,21 @@
 			break;
 		}
+	}
+	
+	while (users) {
+		YList *t = users;
+		struct user *u = users->data;
+
+		if (u->name != NULL) {
+			if (pkt->service == YAHOO_SERVICE_LOGOFF || u->flags == 0) {
+				YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0);
+			} else {
+				YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile);
+			}
+		}
+
+		users = y_list_remove_link(users, users);
+		y_list_free_1(t);
+		FREE(u);
 	}
 }
@@ -1510,4 +1584,111 @@
 	yahoo_packet_free(pkt);
 
+}
+
+static void yahoo_process_picture_checksum( struct yahoo_input_data *yid, struct yahoo_packet *pkt)
+{
+	struct yahoo_data *yd = yid->yd;
+	char *from = NULL;
+	char *to = NULL;
+	int checksum = 0;
+	YList *l;
+
+	for(l = pkt->hash; l; l = l->next)
+	{
+		struct yahoo_pair *pair = l->data;
+
+		switch(pair->key)
+		{
+			case 1:
+			case 4:
+				from = pair->value;
+			case 5:
+				to = pair->value;
+				break;
+			case 212:
+				break;
+			case 192:
+				checksum = atoi( pair->value );
+				break;
+		}
+	}
+
+	YAHOO_CALLBACK(ext_yahoo_got_buddyicon_checksum)(yd->client_id,to,from,checksum);
+}
+
+static void yahoo_process_picture(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
+{
+	struct yahoo_data *yd = yid->yd;
+	char *url = NULL;
+	char *from = NULL;
+	char *to = NULL;
+	int status = 0;
+	int checksum = 0;
+	YList *l;
+	
+	for(l = pkt->hash; l; l = l->next)
+	{
+		struct yahoo_pair *pair = l->data;
+
+		switch(pair->key)
+		{
+		case 1:
+		case 4:		/* sender */
+			from = pair->value;
+			break;
+		case 5:		/* we */
+			to = pair->value;
+			break;
+		case 13:		/* request / sending */
+			status = atoi( pair->value );
+			break;
+		case 20:		/* url */
+			url = pair->value;
+			break;
+		case 192:	/*checksum */
+			checksum = atoi( pair->value );
+			break;
+		}
+	}
+
+	switch( status )
+	{
+		case 1:	/* this is a request, ignore for now */
+			YAHOO_CALLBACK(ext_yahoo_got_buddyicon_request)(yd->client_id, to, from);
+			break;
+		case 2:	/* this is cool - we get a picture :) */
+			YAHOO_CALLBACK(ext_yahoo_got_buddyicon)(yd->client_id,to, from, url, checksum);
+			break;
+	}
+}
+
+static void yahoo_process_picture_upload(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
+{
+	struct yahoo_data *yd = yid->yd;
+	YList *l;
+	char *url = NULL;
+
+	if ( pkt->status != 1 )
+		return;		/* something went wrong */
+	
+	for(l = pkt->hash; l; l = l->next)
+	{
+		struct yahoo_pair *pair = l->data;
+
+		switch(pair->key)
+		{
+			case 5:		/* we */
+				break;
+			case 20:		/* url */
+				url = pair->value;
+				break;
+			case 27:		/* local filename */
+				break;
+			case 38:		/* time */
+				break;
+		}
+	}
+
+	YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded)(yd->client_id, url);
 }
 
@@ -2154,4 +2335,6 @@
 	int online = FALSE;
 	int away = 0;
+	int idle = 0;
+	int mobile = 0;
 
 	YList *l;
@@ -2175,4 +2358,9 @@
 		else if (pair->key == 47)
 			away = strtol(pair->value, NULL, 10);
+		else if (pair->key == 137)
+			idle = strtol(pair->value, NULL, 10);
+		else if (pair->key == 60)
+			mobile = strtol(pair->value, NULL, 10);
+		
 	}
 
@@ -2180,5 +2368,5 @@
 		YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, id, who, msg);
 	else if (name)
-		YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away);
+		YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away, idle, mobile);
 	else if(pkt->status == 0x07)
 		YAHOO_CALLBACK(ext_yahoo_rejected)(yd->client_id, who, msg);
@@ -2308,5 +2496,5 @@
 
 /*	if(status)
-		YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, status, who, 0);
+		YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, who, 0, status);
 */	
 }
@@ -2332,5 +2520,5 @@
 	}
 
-	NOTICE(("got voice chat invite from %s in %s", who, room));
+	NOTICE(("got voice chat invite from %s in %s to identity %s", who, room, me));
 	/* 
 	 * send: s:0 1:me 5:who 57:room 13:1
@@ -2342,4 +2530,19 @@
 	 * rejr: s:4 5:who 10:99 19:-1617114599
 	 */
+}
+
+static void yahoo_process_ping(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
+{
+	char *errormsg = NULL;
+	
+	YList *l;
+	for (l = pkt->hash; l; l = l->next) {
+		struct yahoo_pair *pair = l->data;
+		if (pair->key == 16)
+			errormsg = pair->value;
+	}
+	
+	NOTICE(("got ping packet"));
+	YAHOO_CALLBACK(ext_yahoo_got_ping)(yid->yd->client_id, errormsg);
 }
 
@@ -2519,4 +2722,7 @@
 		yahoo_process_webcam_key(yid, pkt);
 		break;
+	case YAHOO_SERVICE_PING:
+		yahoo_process_ping(yid, pkt);
+		break;
 	case YAHOO_SERVICE_IDLE:
 	case YAHOO_SERVICE_MAILSTAT:
@@ -2526,5 +2732,4 @@
 	case YAHOO_SERVICE_ADDIDENT:
 	case YAHOO_SERVICE_ADDIGNORE:
-	case YAHOO_SERVICE_PING:
 	case YAHOO_SERVICE_GOTGROUPRENAME:
 	case YAHOO_SERVICE_GROUPRENAME:
@@ -2538,4 +2743,13 @@
 		yahoo_dump_unhandled(pkt);
 		break;
+	case YAHOO_SERVICE_PICTURE:
+		yahoo_process_picture(yid, pkt);
+		break;
+	case YAHOO_SERVICE_PICTURE_CHECKSUM:
+		yahoo_process_picture_checksum(yid, pkt);
+		break;
+	case YAHOO_SERVICE_PICTURE_UPLOAD:
+		yahoo_process_picture_upload(yid, pkt);
+		break;	
 	default:
 		WARNING(("unknown service 0x%02x", pkt->service));
@@ -3347,5 +3561,5 @@
 
 		if(yid->type == YAHOO_CONNECTION_PAGER) {
-			YAHOO_CALLBACK(ext_yahoo_login_response)(yid->yd->client_id, YAHOO_LOGIN_SOCK, NULL);
+			YAHOO_CALLBACK(ext_yahoo_error)(yid->yd->client_id, "Connection closed by server", 1, E_CONNECTION);
 		}
 
@@ -3495,9 +3709,10 @@
 }
 
-void yahoo_send_im(int id, const char *from, const char *who, const char *what, int utf8)
+void yahoo_send_im(int id, const char *from, const char *who, const char *what, int utf8, int picture)
 {
 	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
 	struct yahoo_packet *pkt = NULL;
 	struct yahoo_data *yd;
+	char pic_str[10];
 
 	if(!yid)
@@ -3508,4 +3723,6 @@
 	pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, yd->session_id);
 
+	snprintf(pic_str, sizeof(pic_str), "%d", picture);
+	
 	if(from && strcmp(from, yd->user))
 		yahoo_packet_hash(pkt, 0, yd->user);
@@ -3519,4 +3736,5 @@
 	yahoo_packet_hash(pkt, 63, ";0");	/* imvironment name; or ;0 */
 	yahoo_packet_hash(pkt, 64, "0");
+	yahoo_packet_hash(pkt, 206, pic_str);
 
 
@@ -3571,10 +3789,22 @@
 	else
 		service = YAHOO_SERVICE_ISAWAY;
-	pkt = yahoo_packet_new(service, yd->current_status, yd->session_id);
-	snprintf(s, sizeof(s), "%d", yd->current_status);
-	yahoo_packet_hash(pkt, 10, s);
-	if (yd->current_status == YAHOO_STATUS_CUSTOM) {
-		yahoo_packet_hash(pkt, 19, msg);
-		yahoo_packet_hash(pkt, 47, away?"1":"0");
+	 
+	if ((away == 2) && (yd->current_status == YAHOO_STATUS_AVAILABLE)) {
+		pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_BRB, yd->session_id);
+		yahoo_packet_hash(pkt, 10, "999");
+		yahoo_packet_hash(pkt, 47, "2");
+	}else {
+		pkt = yahoo_packet_new(service, YAHOO_STATUS_AVAILABLE, yd->session_id);
+		snprintf(s, sizeof(s), "%d", yd->current_status);
+		yahoo_packet_hash(pkt, 10, s);
+		if (yd->current_status == YAHOO_STATUS_CUSTOM) {
+			yahoo_packet_hash(pkt, 19, msg);
+			yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
+		} else {
+			yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
+		}
+		
+		
+		
 	}
 
@@ -3817,5 +4047,5 @@
 }
 
-void yahoo_add_buddy(int id, const char *who, const char *group)
+void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg)
 {
 	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
@@ -3834,4 +4064,6 @@
 	yahoo_packet_hash(pkt, 7, who);
 	yahoo_packet_hash(pkt, 65, group);
+	if (msg != NULL) /* add message/request "it's me add me" */
+		yahoo_packet_hash(pkt, 14, msg);
 	yahoo_send_packet(yid, pkt, 0);
 	yahoo_packet_free(pkt);
@@ -3895,4 +4127,26 @@
 	yahoo_packet_hash(pkt, 7, who);
 	yahoo_packet_hash(pkt, 13, unignore?"2":"1");
+	yahoo_send_packet(yid, pkt, 0);
+	yahoo_packet_free(pkt);
+}
+
+void yahoo_stealth_buddy(int id, const char *who, int unstealth)
+{
+	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
+	struct yahoo_data *yd;
+	struct yahoo_packet *pkt;
+
+	if(!yid)
+		return;
+	yd = yid->yd;
+
+	if (!yd->logged_in)
+		return;
+
+	pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id);
+	yahoo_packet_hash(pkt, 1, yd->user);
+	yahoo_packet_hash(pkt, 7, who);
+	yahoo_packet_hash(pkt, 31, unstealth?"2":"1");
+	yahoo_packet_hash(pkt, 13, "2");
 	yahoo_send_packet(yid, pkt, 0);
 	yahoo_packet_free(pkt);
@@ -4202,4 +4456,98 @@
 	yahoo_packet_hash(pkt, 1, (from?from:yd->user));
 
+	yahoo_send_packet(yid, pkt, 0);
+
+	yahoo_packet_free(pkt);
+}
+
+void yahoo_buddyicon_request(int id, const char *who)
+{
+	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
+	struct yahoo_data *yd;
+	struct yahoo_packet *pkt;
+
+	if( !yid )
+		return;
+
+	yd = yid->yd;
+	
+	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0);
+	yahoo_packet_hash(pkt, 4, yd->user);
+	yahoo_packet_hash(pkt, 5, who);
+	yahoo_packet_hash(pkt, 13, "1");
+	yahoo_send_packet(yid, pkt, 0);
+
+	yahoo_packet_free(pkt);
+}
+
+void yahoo_send_picture_info(int id, const char *who, const char *url, int checksum)
+{
+	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
+	struct yahoo_data *yd;
+	struct yahoo_packet *pkt;
+	char checksum_str[10];
+
+	if( !yid )
+		return;
+
+	yd = yid->yd;
+
+	snprintf(checksum_str, sizeof(checksum_str), "%d", checksum);
+
+	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0);
+	yahoo_packet_hash(pkt, 1, yd->user);
+	yahoo_packet_hash(pkt, 4, yd->user);
+	yahoo_packet_hash(pkt, 5, who);
+	yahoo_packet_hash(pkt, 13, "2");
+	yahoo_packet_hash(pkt, 20, url);
+	yahoo_packet_hash(pkt, 192, checksum_str);
+	yahoo_send_packet(yid, pkt, 0);
+
+	yahoo_packet_free(pkt);
+}
+
+void yahoo_send_picture_update(int id, const char *who, int type)
+{
+	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
+	struct yahoo_data *yd;
+	struct yahoo_packet *pkt;
+	char type_str[10];
+
+	if( !yid )
+		return;
+
+	yd = yid->yd;
+
+	snprintf(type_str, sizeof(type_str), "%d", type);
+
+	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, YAHOO_STATUS_AVAILABLE, 0);
+	yahoo_packet_hash(pkt, 1, yd->user);
+	yahoo_packet_hash(pkt, 5, who);
+	yahoo_packet_hash(pkt, 206, type_str);
+	yahoo_send_packet(yid, pkt, 0);
+
+	yahoo_packet_free(pkt);
+}
+
+void yahoo_send_picture_checksum(int id, const char *who, int checksum)
+{
+	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
+	struct yahoo_data *yd;
+	struct yahoo_packet *pkt;
+	char checksum_str[10];
+
+	if( !yid )
+		return;
+
+	yd = yid->yd;
+	
+	snprintf(checksum_str, sizeof(checksum_str), "%d", checksum);
+
+	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, 0);
+	yahoo_packet_hash(pkt, 1, yd->user);
+	if( who != 0 )
+		yahoo_packet_hash(pkt, 5, who);
+	yahoo_packet_hash(pkt, 192, checksum_str);
+	yahoo_packet_hash(pkt, 212, "1");
 	yahoo_send_packet(yid, pkt, 0);
 
@@ -4410,4 +4758,97 @@
 };
 
+static void _yahoo_send_picture_connected(int id, int fd, int error, void *data)
+{
+	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT);
+	struct send_file_data *sfd = data;
+	struct yahoo_packet *pkt = sfd->pkt;
+	unsigned char buff[1024];
+
+	if(fd <= 0) {
+		sfd->callback(id, fd, error, sfd->user_data);
+		FREE(sfd);
+		yahoo_packet_free(pkt);
+		inputs = y_list_remove(inputs, yid);
+		FREE(yid);
+		return;
+	}
+
+	yid->fd = fd;
+	yahoo_send_packet(yid, pkt, 8);
+	yahoo_packet_free(pkt);
+
+	snprintf((char *)buff, sizeof(buff), "29");
+	buff[2] = 0xc0;
+	buff[3] = 0x80;
+	
+	write(yid->fd, buff, 4);
+
+	/*	YAHOO_CALLBACK(ext_yahoo_add_handler)(nyd->fd, YAHOO_INPUT_READ); */
+
+	sfd->callback(id, fd, error, sfd->user_data);
+	FREE(sfd);
+	inputs = y_list_remove(inputs, yid);
+	/*
+	while(yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) {
+	if(!strcmp(buff, ""))
+	break;
+}
+
+	*/
+	yahoo_input_close(yid);
+}
+
+void yahoo_send_picture(int id, const char *name, unsigned long size,
+							yahoo_get_fd_callback callback, void *data)
+{
+	struct yahoo_data *yd = find_conn_by_id(id);
+	struct yahoo_input_data *yid;
+	struct yahoo_server_settings *yss;
+	struct yahoo_packet *pkt = NULL;
+	char size_str[10];
+	char expire_str[10];
+	long content_length=0;
+	unsigned char buff[1024];
+	char url[255];
+	struct send_file_data *sfd;
+
+	if(!yd)
+		return;
+
+	yss = yd->server_settings;
+
+	yid = y_new0(struct yahoo_input_data, 1);
+	yid->yd = yd;
+	yid->type = YAHOO_CONNECTION_FT;
+
+	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, YAHOO_STATUS_AVAILABLE, yd->session_id);
+
+	snprintf(size_str, sizeof(size_str), "%ld", size);
+	snprintf(expire_str, sizeof(expire_str), "%ld", (long)604800);
+
+	yahoo_packet_hash(pkt, 0, yd->user);
+	yahoo_packet_hash(pkt, 1, yd->user);
+	yahoo_packet_hash(pkt, 14, "");
+	yahoo_packet_hash(pkt, 27, name);
+	yahoo_packet_hash(pkt, 28, size_str);
+	yahoo_packet_hash(pkt, 38, expire_str);
+	
+
+	content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt);
+
+	snprintf(url, sizeof(url), "http://%s:%d/notifyft",
+				yss->filetransfer_host, yss->filetransfer_port);
+	snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s",
+				 yd->cookie_y, yd->cookie_t);
+	inputs = y_list_prepend(inputs, yid);
+
+	sfd = y_new0(struct send_file_data, 1);
+	sfd->pkt = pkt;
+	sfd->callback = callback;
+	sfd->user_data = data;
+	yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size,
+						_yahoo_send_picture_connected, sfd);
+}
+
 static void _yahoo_send_file_connected(int id, int fd, int error, void *data)
 {
Index: protocols/yahoo/yahoo.c
===================================================================
--- protocols/yahoo/yahoo.c	(revision 6bbb939e953bbe1ca9ed3101a1569abe4521f543)
+++ protocols/yahoo/yahoo.c	(revision cfc8d58f4c15048e943800272017f69804bb61b7)
@@ -67,5 +67,5 @@
 static int byahoo_chat_id = 0;
 
-static char *byahoo_strip( char *in )
+static char *byahoo_strip( const char *in )
 {
 	int len;
@@ -86,5 +86,5 @@
 		else if( strncmp( in, "\e[", 2 ) == 0 )
 		{
-			char *s;
+			const char *s;
 			
 			for( s = in + 2; *s && *s != 'm'; s ++ );
@@ -172,5 +172,5 @@
 	struct byahoo_data *yd = ic->proto_data;
 	
-	yahoo_send_im( yd->y2_id, NULL, who, what, 1 );
+	yahoo_send_im( yd->y2_id, NULL, who, what, 1, 0 );
 	
 	return 1;
@@ -240,5 +240,5 @@
 		yd->current_status = YAHOO_STATUS_AVAILABLE;
 	
-	yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL );
+	yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL ? 2 : 0 );
 }
 
@@ -274,5 +274,5 @@
 	struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
 	
-	yahoo_add_buddy( yd->y2_id, who, group ? group : BYAHOO_DEFAULT_GROUP );
+	yahoo_add_buddy( yd->y2_id, who, group ? group : BYAHOO_DEFAULT_GROUP, NULL );
 }
 
@@ -451,5 +451,5 @@
 }
 
-void ext_yahoo_login_response( int id, int succ, char *url )
+void ext_yahoo_login_response( int id, int succ, const char *url )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -543,5 +543,5 @@
 }
 
-void ext_yahoo_status_changed( int id, char *who, int stat, char *msg, int away )
+void ext_yahoo_status_changed( int id, const char *who, int stat, const char *msg, int away, int idle, int mobile )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -607,14 +607,16 @@
 }
 
-void ext_yahoo_got_im( int id, char *who, char *msg, long tm, int stat, int utf8 )
+void ext_yahoo_got_im( int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8 )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
 	char *m = byahoo_strip( msg );
 	
-	serv_got_im( ic, who, m, 0, 0, strlen( m ) );
+	serv_got_im( ic, (char*) who, (char*) m, 0, 0, strlen( m ) );
 	g_free( m );
 }
 
-void ext_yahoo_got_file( int id, char *who, char *url, long expires, char *msg, char *fname, unsigned long fesize )
+void ext_yahoo_got_file( int id,
+                         const char *ignored,
+                         const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -623,18 +625,18 @@
 }
 
-void ext_yahoo_typing_notify( int id, char *who, int stat )
+void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int stat )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
 	if (stat == 1) {
 		/* User is typing */
-		serv_got_typing( ic, who, 1, 1 );
+		serv_got_typing( ic, (char*) who, 1, 1 );
 	}
 	else {
 		/* User stopped typing */
-		serv_got_typing( ic, who, 1, 0 );
-	}
-}
-
-void ext_yahoo_system_message( int id, char *msg )
+		serv_got_typing( ic, (char*) who, 1, 0 );
+	}
+}
+
+void ext_yahoo_system_message( int id, const char *msg )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -643,5 +645,5 @@
 }
 
-void ext_yahoo_webcam_invite( int id, char *from )
+void ext_yahoo_webcam_invite( int id, const char *ignored, const char *from )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -650,5 +652,5 @@
 }
 
-void ext_yahoo_error( int id, char *err, int fatal )
+void ext_yahoo_error( int id, const char *err, int fatal, int num )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -719,5 +721,5 @@
 }
 
-int ext_yahoo_connect_async( int id, char *host, int port, yahoo_connect_callback callback, void *data )
+int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data )
 {
 	struct byahoo_connect_callback_data *d;
@@ -740,5 +742,5 @@
 /* Because we don't want asynchronous connects in BitlBee, and because
    libyahoo doesn't seem to use this one anyway, this one is now defunct. */
-int ext_yahoo_connect(char *host, int port)
+int ext_yahoo_connect(const char *host, int port)
 {
 #if 0
@@ -796,5 +798,6 @@
 }
 
-void ext_yahoo_got_conf_invite( int id, char *who, char *room, char *msg, YList *members )
+void ext_yahoo_got_conf_invite( int id, const char *ignored,
+                                const char *who, const char *room, const char *msg, YList *members )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -806,5 +809,5 @@
 	memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
 	inv->name = g_strdup( room );
-	inv->c = serv_got_joined_chat( ic, room );
+	inv->c = serv_got_joined_chat( ic, (char*) room );
 	inv->c->data = members;
 	inv->yid = id;
@@ -821,5 +824,5 @@
 }
 
-void ext_yahoo_conf_userdecline( int id, char *who, char *room, char *msg )
+void ext_yahoo_conf_userdecline( int id, const char *ignored, const char *who, const char *room, const char *msg )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -828,5 +831,5 @@
 }
 
-void ext_yahoo_conf_userjoin( int id, char *who, char *room )
+void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, const char *room )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -836,8 +839,9 @@
 	
 	if( c )
-		add_chat_buddy( c, who );
-}
-
-void ext_yahoo_conf_userleave( int id, char *who, char *room )
+		add_chat_buddy( c, (char*) who );
+}
+
+void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, const char *room )
+
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -847,8 +851,8 @@
 	
 	if( c )
-		remove_chat_buddy( c, who, "" );
-}
-
-void ext_yahoo_conf_message( int id, char *who, char *room, char *msg, int utf8 )
+		remove_chat_buddy( c, (char*) who, "" );
+}
+
+void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const char *room, const char *msg, int utf8 )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -859,49 +863,53 @@
 	
 	if( c )
-		serv_got_chat_in( c, who, 0, m, 0 );
+		serv_got_chat_in( c, (char*) who, 0, (char*) m, 0 );
 	g_free( m );
 }
 
-void ext_yahoo_chat_cat_xml( int id, char *xml )
-{
-}
-
-void ext_yahoo_chat_join( int id, char *room, char *topic, YList *members, int fd )
-{
-}
-
-void ext_yahoo_chat_userjoin( int id, char *room, struct yahoo_chat_member *who )
-{
-}
-
-void ext_yahoo_chat_userleave( int id, char *room, char *who )
-{
-}
-
-void ext_yahoo_chat_message( int id, char *who, char *room, char *msg, int msgtype, int utf8 )
-{
-}
-
-void ext_yahoo_chat_yahoologout( int id )
-{
-}
-
-void ext_yahoo_chat_yahooerror( int id )
-{
-}
-
-void ext_yahoo_contact_added( int id, char *myid, char *who, char *msg )
-{
-}
-
-void ext_yahoo_rejected( int id, char *who, char *msg )
-{
-}
-
-void ext_yahoo_game_notify( int id, char *who, int stat )
-{
-}
-
-void ext_yahoo_mail_notify( int id, char *from, char *subj, int cnt )
+void ext_yahoo_chat_cat_xml( int id, const char *xml )
+{
+}
+
+void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, int fd )
+{
+}
+
+void ext_yahoo_chat_userjoin( int id, const char *me, const char *room, struct yahoo_chat_member *who )
+{
+	free(who->id);
+	free(who->alias);
+	free(who->location);
+        free(who);
+}
+
+void ext_yahoo_chat_userleave( int id, const char *me, const char *room, const char *who )
+{
+}
+
+void ext_yahoo_chat_message( int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8 )
+{
+}
+
+void ext_yahoo_chat_yahoologout( int id, const char *me )
+{
+}
+
+void ext_yahoo_chat_yahooerror( int id, const char *me )
+{
+}
+
+void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
+{
+}
+
+void ext_yahoo_rejected( int id, const char *who, const char *msg )
+{
+}
+
+void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat )
+{
+}
+
+void ext_yahoo_mail_notify( int id, const char *from, const char *subj, int cnt )
 {
 	struct im_connection *ic = byahoo_get_ic_by_id( id );
@@ -913,9 +921,9 @@
 }
 
-void ext_yahoo_webcam_invite_reply( int id, char *from, int accept )
-{
-}
-
-void ext_yahoo_webcam_closed( int id, char *who, int reason )
+void ext_yahoo_webcam_invite_reply( int id, const char *me, const char *from, int accept )
+{
+}
+
+void ext_yahoo_webcam_closed( int id, const char *who, int reason )
 {
 }
@@ -925,5 +933,5 @@
 }
 
-void ext_yahoo_webcam_viewer( int id, char *who, int connect )
+void ext_yahoo_webcam_viewer( int id, const char *who, int connect )
 {
 }
@@ -933,5 +941,5 @@
 }
 
-int ext_yahoo_log( char *fmt, ... )
+int ext_yahoo_log( const char *fmt, ... )
 {
 	return( 0 );
@@ -941,2 +949,12 @@
 {
 }
+
+void ext_yahoo_got_ping( int id, const char *msg)
+{
+}
+
+void ext_yahoo_got_buddyicon (int id, const char *me, const char *who, const char *url, int checksum) {}
+void ext_yahoo_got_buddyicon_checksum (int id, const char *me,const char *who, int checksum) {}
+
+void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who){}
+void ext_yahoo_buddyicon_uploaded(int id, const char *url){}
Index: protocols/yahoo/yahoo2.h
===================================================================
--- protocols/yahoo/yahoo2.h	(revision 6bbb939e953bbe1ca9ed3101a1569abe4521f543)
+++ protocols/yahoo/yahoo2.h	(revision cfc8d58f4c15048e943800272017f69804bb61b7)
@@ -120,5 +120,5 @@
 /* from is the identity you're sending from.  if NULL, the default is used */
 /* utf8 is whether msg is a utf8 string or not. */
-void yahoo_send_im(int id, const char *from, const char *who, const char *msg, int utf8);
+void yahoo_send_im(int id, const char *from, const char *who, const char *msg, int utf8, int picture);
 /* if type is true, send typing notice, else send stopped typing notice */
 void yahoo_send_typing(int id, const char *from, const char *who, int typ);
@@ -128,7 +128,8 @@
 void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away);
 
-void yahoo_add_buddy(int id, const char *who, const char *group);
+void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg);
 void yahoo_remove_buddy(int id, const char *who, const char *group);
 void yahoo_reject_buddy(int id, const char *who, const char *msg);
+void yahoo_stealth_buddy(int id, const char *who, int unstealth);
 /* if unignore is true, unignore, else ignore */
 void yahoo_ignore_buddy(int id, const char *who, int unignore);
@@ -214,4 +215,6 @@
 const char  * yahoo_get_profile_url( void );
 
+void yahoo_buddyicon_request(int id, const char *who);
+
 #include "yahoo_httplib.h"
 
Index: protocols/yahoo/yahoo2_callbacks.h
===================================================================
--- protocols/yahoo/yahoo2_callbacks.h	(revision 6bbb939e953bbe1ca9ed3101a1569abe4521f543)
+++ protocols/yahoo/yahoo2_callbacks.h	(revision cfc8d58f4c15048e943800272017f69804bb61b7)
@@ -29,5 +29,4 @@
  * declared in this file and defined in libyahoo2.c
  */
-
 
 
@@ -67,5 +66,4 @@
 
 
-
 /*
  * The following functions need to be implemented in the client
@@ -96,7 +94,5 @@
  * 	url  - url to reactivate account if locked
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_login_response)(int id, int succ, char *url);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_login_response)(int id, int succ, const char *url);
 
 
@@ -111,6 +107,4 @@
 
 
-
-
 /*
  * Name: ext_yahoo_got_ignore
@@ -123,7 +117,4 @@
 
 
-
-
-
 /*
  * Name: ext_yahoo_got_identities
@@ -136,7 +127,4 @@
 
 
-
-
-
 /*
  * Name: ext_yahoo_got_cookies
@@ -148,4 +136,12 @@
 
 
+/*
+ * Name: ext_yahoo_got_ping
+ * 	Called when the ping packet is received from the server
+ * Params:
+ * 	id   - the id that identifies the server connection
+ *  errormsg - optional error message
+ */
+void YAHOO_CALLBACK_TYPE(ext_yahoo_got_ping)(int id, const char *errormsg);
 
 
@@ -159,9 +155,9 @@
  * 	msg  - the message if stat == YAHOO_STATUS_CUSTOM
  * 	away - whether the contact is away or not (YAHOO_STATUS_CUSTOM)
- * 	       for YAHOO_STATUS_IDLE, this is the number of seconds he is idle
- */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_status_changed)(int id, char *who, int stat, char *msg, int away);
-
-
+ * 	idle - this is the number of seconds he is idle [if he is idle]
+ *	mobile - this is set for mobile users/buddies
+ *	TODO: add support for pager, chat, and game states
+ */
+void YAHOO_CALLBACK_TYPE(ext_yahoo_status_changed)(int id, const char *who, int stat, const char *msg, int away, int idle, int mobile);
 
 
@@ -171,4 +167,5 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity the message was sent to
  * 	who  - the handle of the remote user
  * 	msg  - the message - NULL if stat == 2
@@ -180,7 +177,5 @@
  * 	utf8 - whether the message is encoded as utf8 or not
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_got_im)(int id, char *who, char *msg, long tm, int stat, int utf8);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_got_im)(int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8);
 
 
@@ -190,4 +185,5 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity the invitation was sent to
  * 	who  - the user inviting you
  * 	room - the room to join
@@ -195,7 +191,5 @@
  *	members - the initial members of the conference (null terminated list)
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_got_conf_invite)(int id, char *who, char *room, char *msg, YList *members);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_got_conf_invite)(int id, const char *me, const char *who, const char *room, const char *msg, YList *members);
 
 
@@ -205,11 +199,10 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity in the conference
  * 	who  - the user who has declined
  * 	room - the room
  * 	msg  - the declining message
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userdecline)(int id, char *who, char *room, char *msg);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userdecline)(int id, const char *me, const char *who, const char *room, const char *msg);
 
 
@@ -219,10 +212,9 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity in the conference
  * 	who  - the user who has joined
  * 	room - the room joined
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userjoin)(int id, char *who, char *room);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userjoin)(int id, const char *me, const char *who, const char *room);
 
 
@@ -232,31 +224,19 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity in the conference
  * 	who  - the user who has left
  * 	room - the room left
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userleave)(int id, char *who, char *room);
-
-
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userleave)(int id, const char *me, const char *who, const char *room);
 
 
 /*
  * Name: ext_yahoo_chat_cat_xml
- * 	Called when joining the chatroom.
+ * 	Called when ?
  * Params:
  * 	id      - the id that identifies the server connection
- * 	room    - the room joined, used in all other chat calls, freed by 
- * 	          library after call
- * 	topic   - the topic of the room, freed by library after call
- *	members - the initial members of the chatroom (null terminated YList of 
- *	          yahoo_chat_member's) Must be freed by the client
- */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_cat_xml)(int id, char *xml);
-
-
-
-
-
+ * 	xml     - ?
+ */
+void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_cat_xml)(int id, const char *xml);
 
 
@@ -266,4 +246,5 @@
  * Params:
  * 	id      - the id that identifies the server connection
+ * 	me   - the identity in the chatroom
  * 	room    - the room joined, used in all other chat calls, freed by 
  * 	          library after call
@@ -273,9 +254,5 @@
  *	fd	- the socket where the connection is coming from (for tracking)
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_join)(int id, char *room, char *topic, YList *members, int fd);
-
-
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_join)(int id, const char *me, const char *room, const char *topic, YList *members, int fd);
 
 
@@ -285,10 +262,9 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity in the chatroom
  * 	room - the room joined
  * 	who  - the user who has joined, Must be freed by the client
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_userjoin)(int id, char *room, struct yahoo_chat_member *who);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_userjoin)(int id, const char *me, const char *room, struct yahoo_chat_member *who);
 
 
@@ -298,10 +274,9 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity in the chatroom
  * 	room - the room left
  * 	who  - the user who has left (Just the User ID)
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_userleave)(int id, char *room, char *who);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_userleave)(int id, const char *me, const char *room, const char *who);
 
 
@@ -311,4 +286,5 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity in the chatroom
  * 	room - the room
  * 	who  - the user who messaged (Just the user id)
@@ -318,5 +294,6 @@
  * 	utf8 - whether the message is utf8 encoded or not
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_message)(int id, char *who, char *room, char *msg, int msgtype, int utf8);
+void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_message)(int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8);
+
 
 /*
@@ -329,8 +306,10 @@
  * Params:
  *	id   - the id that identifies this connection
+ * 	me   - the identity in the chatroom
  * Returns:
  *	nothing.
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_yahoologout)(int id);
+void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_yahoologout)(int id, const char *me);
+
 
 /*
@@ -344,9 +323,10 @@
  * Params:
  *	id   - the id that identifies this connection
+ * 	me   - the identity in the chatroom
  * Returns:
  *	nothing.
  */
-
-void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_yahooerror)(int id);
+void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_yahooerror)(int id, const char *me);
+
 
 /*
@@ -355,4 +335,5 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity the conf message was sent to
  * 	who  - the user who messaged
  * 	room - the room
@@ -360,7 +341,5 @@
  * 	utf8 - whether the message is utf8 encoded or not
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_message)(int id, char *who, char *room, char *msg, int utf8);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_message)(int id, const char *me, const char *who, const char *room, const char *msg, int utf8);
 
 
@@ -370,4 +349,5 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the identity the file was sent to
  * 	who  - the user who sent the file
  * 	url  - the file url
@@ -377,7 +357,5 @@
  * 	fsize- the file size if direct transfer
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_got_file)(int id, char *who, char *url, long expires, char *msg, char *fname, unsigned long fesize);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_got_file)(int id, const char *me, const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize);
 
 
@@ -391,7 +369,5 @@
  * 	msg  - any message sent
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_added)(int id, char *myid, char *who, char *msg);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_added)(int id, const char *myid, const char *who, const char *msg);
 
 
@@ -404,7 +380,5 @@
  * 	msg  - any message sent
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_rejected)(int id, char *who, char *msg);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_rejected)(int id, const char *who, const char *msg);
 
 
@@ -414,10 +388,9 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the handle of the identity the notification is sent to
  * 	who  - the handle of the remote user
  * 	stat - 1 if typing, 0 if stopped typing
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_typing_notify)(int id, char *who, int stat);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_typing_notify)(int id, const char *me, const char *who, int stat);
 
 
@@ -427,10 +400,9 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - the handle of the identity the notification is sent to
  * 	who  - the handle of the remote user
  * 	stat - 1 if game, 0 if stopped gaming
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_game_notify)(int id, char *who, int stat);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_game_notify)(int id, const char *me, const char *who, int stat);
 
 
@@ -444,7 +416,5 @@
  * 	cnt  - mail count - 0 if new mail notification
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_mail_notify)(int id, char *from, char *subj, int cnt);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_mail_notify)(int id, const char *from, const char *subj, int cnt);
 
 
@@ -456,15 +426,47 @@
  * 	msg  - the message
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_system_message)(int id, char *msg);
-
-
-
-
-
-
-
-
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_system_message)(int id, const char *msg);
+
+/*
+ * Name: ext_yahoo_got_buddyicon
+ * 	Buddy icon received
+ * Params:
+ * 	id - the id that identifies the server connection
+ * 	me - the handle of the identity the notification is sent to
+ * 	who - the person the buddy icon is for
+ * 	url - the url to use to load the icon
+ * 	checksum - the checksum of the icon content
+ */
+void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddyicon)(int id, const char *me, const char *who, const char *url, int checksum);
+
+/*
+ * Name: ext_yahoo_got_buddyicon_checksum
+ * 	Buddy icon checksum received
+ * Params:
+ * 	id - the id that identifies the server connection
+ * 	me - the handle of the identity the notification is sent to
+ * 	who - the yahoo id of the buddy icon checksum is for
+ * 	checksum - the checksum of the icon content
+ */
+void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddyicon_checksum)(int id, const char *me,const char *who, int checksum);
+
+/*
+ * Name: ext_yahoo_got_buddyicon_request
+ * 	Buddy icon request received
+ * Params:
+ * 	id - the id that identifies the server connection
+ * 	me - the handle of the identity the notification is sent to
+ * 	who - the yahoo id of the buddy that requested the buddy icon
+ */
+void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddyicon_request)(int id, const char *me, const char *who);
+
+/*
+ * Name: ext_yahoo_got_buddyicon_request
+ * 	Buddy icon request received
+ * Params:
+ * 	id - the id that identifies the server connection
+ * 	url - remote url, the uploaded buddy icon can be fetched from
+ */
+void YAHOO_CALLBACK_TYPE(ext_yahoo_buddyicon_uploaded)(int id, const char *url);
 
 /*
@@ -496,6 +498,4 @@
 
 
-
-
 /*
  * Name: ext_yahoo_webcam_invite
@@ -503,9 +503,8 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - identity the invitation is to
  * 	from - who the invitation is from
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_invite)(int id, char *from);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_invite)(int id, const char *me, const char *from);
 
 
@@ -515,9 +514,9 @@
  * Params:
  * 	id   - the id that identifies the server connection
+ * 	me   - identity the invitation response is to
  * 	from - who the invitation response is from
  *	accept - 0 (decline), 1 (accept)
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_invite_reply)(int id, char *from, int accept);
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_invite_reply)(int id, const char *me, const char *from, int accept);
 
 
@@ -534,5 +533,5 @@
  *	         4 = user does not have webcam online
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_closed)(int id, char *who, int reason);
+void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_closed)(int id, const char *who, int reason);
 
 
@@ -552,5 +551,4 @@
 
 
-
 /*
  * Name: ext_yahoo_error
@@ -560,8 +558,7 @@
  * 	err  - the error message
  * 	fatal- whether this error is fatal to the connection or not
- */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_error)(int id, char *err, int fatal);
-
-
+ * 	num  - Which error is this
+ */
+void YAHOO_CALLBACK_TYPE(ext_yahoo_error)(int id, const char *err, int fatal, int num);
 
 
@@ -574,7 +571,5 @@
  *	connect - 0=disconnect 1=connect 2=request
  */
-void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_viewer)(int id, char *who, int connect);
-
-
+void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_viewer)(int id, const char *who, int connect);
 
 
@@ -587,6 +582,4 @@
  */
 void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_data_request)(int id, int send);
-
-
 
 
@@ -599,11 +592,5 @@
  * 	0
  */
-int YAHOO_CALLBACK_TYPE(ext_yahoo_log)(char *fmt, ...);
-
-
-
-
-
-
+int YAHOO_CALLBACK_TYPE(ext_yahoo_log)(const char *fmt, ...);
 
 
@@ -624,6 +611,4 @@
 
 
-
-
 /*
  * Name: ext_yahoo_remove_handler
@@ -634,7 +619,4 @@
  */
 void YAHOO_CALLBACK_TYPE(ext_yahoo_remove_handler)(int id, int tag);
-
-
-
 
 
@@ -648,11 +630,5 @@
  * 	a unix file descriptor to the socket
  */
-int YAHOO_CALLBACK_TYPE(ext_yahoo_connect)(char *host, int port);
-
-
-
-
-
-
+int YAHOO_CALLBACK_TYPE(ext_yahoo_connect)(const char *host, int port);
 
 
@@ -675,5 +651,5 @@
  * 	a unix file descriptor to the socket
  */
-int YAHOO_CALLBACK_TYPE(ext_yahoo_connect_async)(int id, char *host, int port, 
+int YAHOO_CALLBACK_TYPE(ext_yahoo_connect_async)(int id, const char *host, int port, 
 		yahoo_connect_callback callback, void *callback_data);
 
@@ -686,5 +662,5 @@
  */
 void yahoo_register_callbacks(struct yahoo_callbacks * tyc);
-	
+
 #undef YAHOO_CALLBACK_TYPE
 
@@ -696,2 +672,3 @@
 
 #endif
+
Index: protocols/yahoo/yahoo2_types.h
===================================================================
--- protocols/yahoo/yahoo2_types.h	(revision 6bbb939e953bbe1ca9ed3101a1569abe4521f543)
+++ protocols/yahoo/yahoo2_types.h	(revision cfc8d58f4c15048e943800272017f69804bb61b7)
@@ -30,4 +30,5 @@
 
 enum yahoo_status {
+	YAHOO_STATUS_DISCONNECTED = -1,
 	YAHOO_STATUS_AVAILABLE = 0,
 	YAHOO_STATUS_BRB,
@@ -43,6 +44,7 @@
 	YAHOO_STATUS_CUSTOM = 99,
 	YAHOO_STATUS_IDLE = 999,
+	YAHOO_STATUS_WEBLOGIN = 0x5a55aa55,
 	YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */
-	YAHOO_STATUS_NOTIFY = 0x16
+	YAHOO_STATUS_NOTIFY = 0x16 /* TYPING */
 };
 #define YAHOO_STATUS_GAME	0x2 		/* Games don't fit into the regular status model */
@@ -50,4 +52,5 @@
 enum yahoo_login_status {
 	YAHOO_LOGIN_OK = 0,
+	YAHOO_LOGIN_LOGOFF = 2,
 	YAHOO_LOGIN_UNAME = 3,
 	YAHOO_LOGIN_PASSWD = 13,
@@ -58,4 +61,7 @@
 
 enum yahoo_error {
+	E_UNKNOWN = -1,
+	E_CONNECTION = -2,
+	E_SYSTEM = -3,
 	E_CUSTOM = 0,
 
@@ -79,4 +85,5 @@
 };
 
+#define YAHOO_PROTO_VER 0x000b
 
 /* Yahoo style/color directives */
@@ -116,4 +123,10 @@
 };
 
+enum yahoo_stealth_visibility_type {
+	YAHOO_STEALTH_DEFAULT = 0,
+  	YAHOO_STEALTH_ONLINE,
+  	YAHOO_STEALTH_PERM_OFFLINE
+};
+
 /* chat member attribs */
 #define YAHOO_CHAT_MALE 0x8000
Index: protocols/yahoo/yahoo_util.c
===================================================================
--- protocols/yahoo/yahoo_util.c	(revision 6bbb939e953bbe1ca9ed3101a1569abe4521f543)
+++ protocols/yahoo/yahoo_util.c	(revision cfc8d58f4c15048e943800272017f69804bb61b7)
@@ -69,11 +69,13 @@
 	int i=0;
 	int l = strlen(sep);
-	if(nelem < 0) {
+	if(nelem <= 0) {
 		char * s;
 		nelem=0;
-		for(s=strstr(str, sep); s; s=strstr(s+l, sep),nelem++)
-			;
-		if(strcmp(str+strlen(str)-l, sep))
-			nelem++;
+		if (*str) {
+			for(s=strstr(str, sep); s; s=strstr(s+l, sep),nelem++)
+				;
+			if(strcmp(str+strlen(str)-l, sep))
+				nelem++;
+		}
 	}
 
@@ -87,5 +89,5 @@
 	}
 
-	if(i<nelem) /* str didn't end with sep */
+	if(i<nelem && *str) /* str didn't end with sep, and str isn't empty */
 		vector[i++] = strdup(p);
 			
