changeset 20686:fd664b4aa4f1

merge of '41f188f15baaa4c23c5c2ec80a04faff63ee1977' and 'ff01e2a2ebb49e3467357819cb6522baa4c9207c'
author Richard Laager <rlaager@wiktel.com>
date Fri, 28 Sep 2007 16:51:19 +0000
parents 0c868dfe2343 (diff) 02df6998b466 (current diff)
children b1a42d258a14
files libpurple/protocols/msn/userlist.c pidgin/gtknotify.c
diffstat 11 files changed, 237 insertions(+), 170 deletions(-) [+]
line wrap: on
line diff
--- a/finch/gntdebug.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/finch/gntdebug.c	Fri Sep 28 16:51:19 2007 +0000
@@ -28,12 +28,14 @@
 #include <gntbutton.h>
 #include <gntcheckbox.h>
 #include <gntentry.h>
+#include <gntfilesel.h>
 #include <gntlabel.h>
 #include <gntline.h>
 #include <gnttextview.h>
 
 #include "gntdebug.h"
 #include "finch.h"
+#include "notify.h"
 #include "util.h"
 
 #include <stdio.h>
@@ -220,9 +222,43 @@
 					(GDestroyNotify)g_source_remove);
 }
 
+static void
+file_save(GntFileSel *fs, const char *path, const char *file, GntTextView *tv)
+{
+	FILE *fp;
+
+	if ((fp = g_fopen(path, "w+")) == NULL) {
+		purple_notify_error(NULL, NULL, _("Unable to open file."), NULL);
+		return;
+	}
+
+	fprintf(fp, "Finch Debug Log : %s\n", purple_date_format_full(NULL));
+	fprintf(fp, tv->string->str);
+	fclose(fp);
+	gnt_widget_destroy(GNT_WIDGET(fs));
+}
+
+static void
+file_cancel(GntWidget *w, GntFileSel *fs)
+{
+	gnt_widget_destroy(GNT_WIDGET(fs));
+}
+
+static void
+save_debug_win(GntWidget *w, GntTextView *tv)
+{
+	GntWidget *window = gnt_file_sel_new();
+	GntFileSel *sel = GNT_FILE_SEL(window);
+	gnt_file_sel_set_current_location(sel, purple_home_dir());
+	gnt_file_sel_set_suggested_filename(sel, "debug.txt");
+	g_signal_connect(G_OBJECT(sel), "file_selected", G_CALLBACK(file_save), tv);
+	g_signal_connect(G_OBJECT(sel->cancel), "activate", G_CALLBACK(file_cancel), sel);
+	gnt_widget_show(window);
+}
+
 void finch_debug_window_show()
 {
-	GntWidget *wid, *box;
+	GntWidget *wid, *box, *label;
 
 	debug.paused = FALSE;
 	if (debug.window) {
@@ -258,8 +294,15 @@
 	GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
 	gnt_box_add_widget(GNT_BOX(box), wid);
 
+	wid = gnt_button_new(_("Save"));
+	g_signal_connect(G_OBJECT(wid), "activate", G_CALLBACK(save_debug_win), debug.tview);
+	GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
+	gnt_box_add_widget(GNT_BOX(box), wid);
+
 	debug.search = gnt_entry_new(purple_prefs_get_string(PREF_ROOT "/filter"));
-	gnt_box_add_widget(GNT_BOX(box), gnt_label_new(_("Filter: ")));
+	label = gnt_label_new(_("Filter:"));
+	GNT_WIDGET_UNSET_FLAGS(label, GNT_WIDGET_GROW_X);
+	gnt_box_add_widget(GNT_BOX(box), label);
 	gnt_box_add_widget(GNT_BOX(box), debug.search);
 	g_signal_connect(G_OBJECT(debug.search), "text_changed", G_CALLBACK(update_filter_string), NULL);
 
--- a/libpurple/plugins/ssl/ssl-gnutls.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/plugins/ssl/ssl-gnutls.c	Fri Sep 28 16:51:19 2007 +0000
@@ -111,7 +111,7 @@
 	PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc);
 	ssize_t ret;
 
-	purple_debug_info("gnutls", "Handshaking with %s\n", gsc->host);
+	/*purple_debug_info("gnutls", "Handshaking with %s\n", gsc->host);*/
 	ret = gnutls_handshake(gnutls_data->session);
 
 	if(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
@@ -271,6 +271,8 @@
 	gnutls_data->handshake_handler = purple_input_add(gsc->fd,
 		PURPLE_INPUT_READ, ssl_gnutls_handshake_cb, gsc);
 
+	purple_debug_info("gnutls", "Starting handshake with %s\n", gsc->host);
+
 	/* Orborde asks: Why are we configuring a callback, then
 	   immediately calling it?
 
@@ -434,9 +436,6 @@
 
 	/* If the refcount reaches zero, kill the structure */
 	if (cd->refcount <= 0) {
-		purple_debug_info("gnutls/x509",
-				  "Freeing unused cert data at %p\n",
-				  cd);
 		/* Kill the internal data */
 		gnutls_x509_crt_deinit( cd->crt );
 		/* And kill the struct */
--- a/libpurple/protocols/msn/contact.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/protocols/msn/contact.c	Fri Sep 28 16:51:19 2007 +0000
@@ -474,10 +474,10 @@
 					gchar *type, *membershipId = NULL;
 					const char *member_type = xmlnode_get_attrib(member, "type");
 
-					purple_debug_info("MSNCL","Member type: %s\n", member_type ? member_type : "(null)");
-
-					if (!member_type)
+					if (!member_type) {
+						purple_debug_error("msn", "No Member Type specified for Member.\n");
 						continue;
+					}
 
 					if(!g_strcasecmp(member_type, "PassportMember") ) {
 						passport = type = NULL;
@@ -504,6 +504,7 @@
 						msn_got_lst_user(session, user, list_op, NULL);
 					}
 					else if (!g_strcasecmp(member_type, "PhoneMember")) {
+						purple_debug_info("msn", "Recieved Phone Member; ignoring.\n");
 					}
 					else if (!g_strcasecmp(member_type, "EmailMember")) {
 						xmlnode *emailNode;
@@ -526,6 +527,8 @@
 						}
 
 						msn_got_lst_user(session, user, list_op, NULL);
+					} else {
+						purple_debug_info("msn", "Unknown Member type: %s\n", member_type);
 					}
 				}
 			}
@@ -594,8 +597,8 @@
 msn_get_contact_list(MsnContact * contact, const MsnSoapPartnerScenario partner_scenario, const char *update_time)
 {
 	MsnSoapReq *soap_request;
-	gchar *body = NULL;
-	gchar * update_str;
+	gchar *body;
+	gchar *update_str = NULL;
 	const gchar *partner_scenario_str = MsnSoapPartnerScenarioText[partner_scenario];
 
 	purple_debug_misc("MSNCL","Getting Contact List.\n");
@@ -603,11 +606,9 @@
 	if ( update_time != NULL ) {
 		purple_debug_info("MSNCL","Last update time: %s\n",update_time);
 		update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML,update_time);
-	} else {
-		update_str = g_strdup("");
 	}
 
-	body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str, update_str);
+	body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str, update_str ? update_str : "");
 	g_free(update_str);
 
 	soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
@@ -633,13 +634,12 @@
 	for(group = xmlnode_get_child(node, "Group"); group;
 					group = xmlnode_get_next_twin(group)){
 		xmlnode *groupId, *groupInfo, *groupname;
-		char *group_id, *group_name;
+		char *group_id = NULL, *group_name = NULL;
 
-		groupId = xmlnode_get_child(group,"groupId");
-		group_id = xmlnode_get_data(groupId);
-		groupInfo = xmlnode_get_child(group,"groupInfo");
-		groupname = xmlnode_get_child(groupInfo,"name");
-		group_name = xmlnode_get_data(groupname);
+		if ((groupId = xmlnode_get_child(group, "groupId")))
+			group_id = xmlnode_get_data(groupId);
+		if ((groupInfo = xmlnode_get_child(group, "groupInfo")) && (groupname = xmlnode_get_child(groupInfo, "name")))
+			group_name = xmlnode_get_data(groupname);
 
 		msn_group_new(session->userlist, group_id, group_name);
 
@@ -649,7 +649,7 @@
 			continue;
 		}
 
-		purple_debug_info("MsnAB","group_id: %s, name: %s\n",group_id,group_name);
+		purple_debug_info("MsnAB","group_id: %s, name: %s\n", group_id, group_name ? group_name : "(null)");
 		if ((purple_find_group(group_name)) == NULL){
 			PurpleGroup *g = purple_group_new(group_name);
 			purple_blist_add_group(g, NULL);
@@ -756,7 +756,6 @@
 		msn_user_set_uid(user, uid);
 		msn_user_set_type(user, usertype);
 
-		purple_debug_misc("MsnAB","parse guid...\n");
 		groupIds = xmlnode_get_child(contactInfo, "groupIds");
 		if (groupIds) {
 			for (guid = xmlnode_get_child(groupIds, "guid"); guid;
@@ -767,6 +766,7 @@
 				g_free(group_id);
 			}
 		} else {
+			purple_debug_info("msn", "User not in any groups, adding to default group.\n");
 			/*not in any group,Then set default group*/
 			msn_user_add_group_id(user, MSN_INDIVIDUALS_GROUP_ID);
 		}
@@ -783,17 +783,15 @@
 static gboolean
 msn_parse_addressbook(MsnContact * contact)
 {
-	MsnSession * session;
+	MsnSession *session;
 	xmlnode * node,*body,*response,*result;
 	xmlnode *groups;
-	xmlnode	*contacts;
+	xmlnode *contacts;
 	xmlnode *abNode;
 	xmlnode *fault, *faultstringnode, *faultdetail, *errorcode;
 
 	session = contact->session;
 
-	
-
 	node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len);
 	if ( node == NULL ) {
 		purple_debug_error("MSN AddressBook","Error parsing Address Book with size %d\n", contact->soapconn->body_len);
@@ -802,8 +800,11 @@
 
 	purple_debug_misc("MSN AddressBook", "Parsing Address Book with size %d\n", contact->soapconn->body_len);
 
-	purple_debug_misc("MSN AddressBook","node{%p},name:%s,child:%s,last:%s\n",node,node->name,node->child->name,node->lastchild->name);
-	
+	purple_debug_misc("MSN AddressBook","node{%p},name:%s,child:%s,last:%s\n", node,
+		node->name ? node->name : "(null)",
+		(node->child && node->child->name) ? node->child->name : "(null)",
+		(node->lastchild && node->lastchild->name) ? node->lastchild->name : "(null)");
+
 	body = xmlnode_get_child(node,"Body");
 	purple_debug_misc("MSN AddressBook","body{%p},name:%s\n",body,body->name);
 
@@ -1401,14 +1402,17 @@
 msn_update_contact(MsnContact *contact, const char* nickname)
 {
 	MsnSoapReq *soap_request;
-	gchar *body = NULL, *escaped_nickname;
+	gchar *body, *escaped_nickname;
+
+	/* I'm not sure this is right, but if it isn't, the rest of this function will need to be fixed */
+	g_return_if_fail(nickname != NULL);
 
 	purple_debug_info("MSN CL","Update contact information with new friendly name: %s\n", nickname);
-	
+
 	escaped_nickname = g_markup_escape_text(nickname, -1);
 
 	body = g_strdup_printf(MSN_CONTACT_UPDATE_TEMPLATE, escaped_nickname);
-	
+
 	g_free(escaped_nickname);
 	/*build SOAP and POST it*/
 	soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
--- a/libpurple/protocols/msn/notification.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/protocols/msn/notification.c	Fri Sep 28 16:51:19 2007 +0000
@@ -101,7 +101,8 @@
 	MsnCmdProc *cmdproc;
 	MsnSession *session;
 	PurpleAccount *account;
-	char **a, **c, *vers;
+	GString *vers;
+	const char *ver_str;
 	int i;
 
 	g_return_if_fail(servconn != NULL);
@@ -110,31 +111,24 @@
 	session = servconn->session;
 	account = session->account;
 
-	/* Allocate an array for CVR0, NULL, and all the versions */
-//	a = c = g_new0(char *, session->protocol_ver - WLM_MIN_PROTOCOL + 3);
-	a = c = g_new0(char *, WLM_MAX_PROTOCOL - WLM_MIN_PROTOCOL + 3);
+	vers = g_string_new("");
 
-//	for (i = session->protocol_ver; i >= WLM_MIN_PROTOCOL; i--)
+/*	for (i = session->protocol_ver; i >= WLM_MIN_PROTOCOL; i--) */
 	for (i = WLM_MAX_PROTOCOL; i >= WLM_MIN_PROTOCOL; i--)
-		*c++ = g_strdup_printf("MSNP%d", i);
+		g_string_append_printf(vers, " MSNP%d", i);
 
-	*c++ = g_strdup("CVR0");
-
-	vers = g_strjoinv(" ", a);
+	g_string_append(vers, " CVR0");
 
 	if (session->login_step == MSN_LOGIN_STEP_START)
-	{
 		msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE);
-	}
 	else
-	{
 		msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE2);
-	}
 
-	msn_cmdproc_send(cmdproc, "VER", "%s", vers);
+	/* Skip the initial space */
+	ver_str = (vers->str + 1);
+	msn_cmdproc_send(cmdproc, "VER", "%s", ver_str);
 
-	g_strfreev(a);
-	g_free(vers);
+	g_string_free(vers, TRUE);
 }
 
 gboolean
@@ -189,7 +183,7 @@
 			const char *group_name;
 			group_name = msn_userlist_find_group_name(session->userlist,group_id);
 			reason = g_strdup_printf(_("%s is not a valid group."),
-									 group_name);
+									 group_name ? group_name : "");
 		}
 	}
 	else
@@ -590,57 +584,59 @@
 {
 	xmlnode *d_node,*c_node;
 	char **tokens;
-	char *email,*domain;
-	char *list_op_str,*type_str;
+	const char *email,*domain;
+	char fmt_str[3];
+
+	g_return_if_fail(passport != NULL);
 
 	purple_debug_info("MSNP14","Passport: %s, type: %d\n", passport, type);
 	tokens = g_strsplit(passport, "@", 2);
 	email = tokens[0];
 	domain = tokens[1];
 
+	if (email == NULL || domain == NULL) {
+		purple_debug_error("msn", "Invalid passport (%s) specified to add to contact xml.\n", passport);
+		g_strfreev(tokens);
+		g_return_if_reached();
+	}
+
 	/*find a domain Node*/
 	for(d_node = xmlnode_get_child(mlNode,"d"); d_node; d_node = xmlnode_get_next_twin(d_node))
 	{
-		const char * attr = NULL;
-		purple_debug_info("MSNP14","d_node: %s\n",d_node->name);
-		attr = xmlnode_get_attrib(d_node,"n");
-		if(attr == NULL){
+		const char *attr = xmlnode_get_attrib(d_node,"n");
+		if (attr == NULL)
 			continue;
-		}
-		if(!strcmp(attr,domain)){
+		if (!strcmp(attr,domain))
 			break;
-		}
 	}
+
 	if(d_node == NULL)
 	{
 		/*domain not found, create a new domain Node*/
-		purple_debug_info("MSNP14","get No d_node\n");
+		purple_debug_info("msn", "Didn't find existing domain node, adding one.\n");
 		d_node = xmlnode_new("d");
-		xmlnode_set_attrib(d_node,"n",domain);
-		xmlnode_insert_child(mlNode,d_node);
+		xmlnode_set_attrib(d_node, "n", domain);
+		xmlnode_insert_child(mlNode, d_node);
 	}
 
 	/*create contact node*/
 	c_node = xmlnode_new("c");
-	xmlnode_set_attrib(c_node,"n",email);
+	xmlnode_set_attrib(c_node, "n", email);
 
-	list_op_str = g_strdup_printf("%d",list_op);
-	purple_debug_info("MSNP14","list_op: %d\n",list_op);
-	xmlnode_set_attrib(c_node,"l",list_op_str);
-	g_free(list_op_str);
+	purple_debug_info("MSNP14", "list_op: %d\n", list_op);
+	g_snprintf(fmt_str, sizeof(fmt_str), "%d", list_op);
+	xmlnode_set_attrib(c_node, "l", fmt_str);
 
-	if (type != MSN_USER_TYPE_UNKNOWN) {
-		type_str = g_strdup_printf("%d", type);
-	} else {
-		if (msn_user_is_yahoo(session->account, passport))
-			type_str = g_strdup_printf("%d", MSN_USER_TYPE_YAHOO);
-		else
-			type_str = g_strdup_printf("%d", MSN_USER_TYPE_PASSPORT);
-	}
+	if (type != MSN_USER_TYPE_UNKNOWN)
+		g_snprintf(fmt_str, sizeof(fmt_str), "%d", type);
+	else if (msn_user_is_yahoo(session->account, passport))
+		g_snprintf(fmt_str, sizeof(fmt_str), "%d", MSN_USER_TYPE_YAHOO);
+	else
+		g_snprintf(fmt_str, sizeof(fmt_str), "%d", MSN_USER_TYPE_PASSPORT);
+
 	/*mobile*/
 	//type_str = g_strdup_printf("4");
-	xmlnode_set_attrib(c_node,"t",type_str);
-	g_free(type_str);
+	xmlnode_set_attrib(c_node, "t", fmt_str);
 
 	xmlnode_insert_child(d_node, c_node);
 
--- a/libpurple/protocols/msn/switchboard.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/protocols/msn/switchboard.c	Fri Sep 28 16:51:19 2007 +0000
@@ -958,25 +958,14 @@
 nudge_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
 {
 	MsnSwitchBoard *swboard;
-	char *username, *str;
 	PurpleAccount *account;
-	PurpleBuddy *buddy;
 	const char *user;
 
-	str = NULL;
-
 	swboard = cmdproc->data;
 	account = cmdproc->session->account;
 	user = msg->remote_user;
 
-	if ((buddy = purple_find_buddy(account, user)) != NULL)
-		username = g_markup_escape_text(purple_buddy_get_alias(buddy), -1);
-	else
-		username = g_markup_escape_text(user, -1);
-
-	serv_got_attention(account->gc, buddy->name, MSN_NUDGE);
-	g_free(username);
-	g_free(str);
+	serv_got_attention(account->gc, user, MSN_NUDGE);
 }
 
 /**************************************************************************
--- a/libpurple/protocols/msn/userlist.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/protocols/msn/userlist.c	Fri Sep 28 16:51:19 2007 +0000
@@ -41,16 +41,20 @@
 msn_accept_add_cb(gpointer data)
 {
 	MsnPermitAdd *pa = data;
-	MsnSession *session = pa->gc->proto_data;
-	MsnUserList *userlist = session->userlist;
-	MsnUser *user = msn_userlist_find_add_user(userlist, pa->who, pa->who);
-	
+
 	purple_debug_misc("MSN Userlist", "Accepted the new buddy: %s\n", pa->who);
 
-	msn_userlist_add_buddy_to_list(userlist, pa->who, MSN_LIST_AL);
+	if (PURPLE_CONNECTION_IS_VALID(pa->gc))
+	{
+		MsnSession *session = pa->gc->proto_data;
+		MsnUserList *userlist = session->userlist;
+		MsnUser *user = msn_userlist_find_add_user(userlist, pa->who, pa->who);
 
-	if (msn_userlist_user_is_in_list(user, MSN_LIST_FL)) {
-		msn_del_contact_from_list(session->contact, NULL, pa->who, MSN_LIST_PL);
+
+		msn_userlist_add_buddy_to_list(userlist, pa->who, MSN_LIST_AL);
+
+		if (msn_userlist_user_is_in_list(user, MSN_LIST_FL))
+			msn_del_contact_from_list(session->contact, NULL, pa->who, MSN_LIST_PL);
 	}
 
 	g_free(pa->who);
@@ -63,14 +67,14 @@
 {
 	MsnPermitAdd *pa = data;
 
-	purple_debug_misc("MSN Userlist", "Deniedthe new buddy: %s\n", pa->who);
+	purple_debug_misc("MSN Userlist", "Denied the new buddy: %s\n", pa->who);
 
-	if (g_list_find(purple_connections_get_all(), pa->gc) != NULL)
+	if (PURPLE_CONNECTION_IS_VALID(pa->gc))
 	{
 		MsnSession *session = pa->gc->proto_data;
 		MsnUserList *userlist = session->userlist;
 		MsnCallbackState *state = msn_callback_state_new();
-	
+
 		msn_callback_state_set_action(state, MSN_DENIED_BUDDY);
 
 		msn_userlist_add_buddy_to_list(userlist, pa->who, MSN_LIST_BL);
@@ -85,16 +89,18 @@
 static void
 got_new_entry(PurpleConnection *gc, const char *passport, const char *friendly)
 {
+	PurpleAccount *acct;
 	MsnPermitAdd *pa;
 
 	pa = g_new0(MsnPermitAdd, 1);
 	pa->who = g_strdup(passport);
 	pa->friendly = g_strdup(friendly);
 	pa->gc = gc;
-	
-	purple_account_request_authorization(purple_connection_get_account(gc), passport, NULL, friendly, NULL,
-					   purple_find_buddy(purple_connection_get_account(gc), passport) != NULL,
-					   msn_accept_add_cb, msn_cancel_add_cb, pa);
+
+	acct = purple_connection_get_account(gc);
+	purple_account_request_authorization(acct, passport, NULL, friendly, NULL,
+										 purple_find_buddy(acct, passport) != NULL,
+										 msn_accept_add_cb, msn_cancel_add_cb, pa);
 
 }
 
--- a/libpurple/protocols/yahoo/yahoo.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Fri Sep 28 16:51:19 2007 +0000
@@ -862,10 +862,13 @@
 			/* If a Doodle session doesn't exist between this user */
 			if(wb == NULL)
 			{
+				doodle_session *ds;
 				wb = purple_whiteboard_create(gc->account, im->from, DOODLE_STATE_REQUESTED);
-
-				yahoo_doodle_command_send_request(gc, im->from);
-				yahoo_doodle_command_send_ready(gc, im->from);
+				ds = wb->proto_data;
+				ds->imv_key = g_strdup(imv);
+
+				yahoo_doodle_command_send_request(gc, im->from, imv);
+				yahoo_doodle_command_send_ready(gc, im->from, imv);
 			}
 		}
 	}
--- a/libpurple/protocols/yahoo/yahoo_doodle.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_doodle.c	Fri Sep 28 16:51:19 2007 +0000
@@ -118,19 +118,19 @@
 		/* Insert this 'session' in the list.  At this point, it's only a
 		 * requested session.
 		 */
-		purple_whiteboard_create(account, to, DOODLE_STATE_REQUESTING);
+		wb = purple_whiteboard_create(account, to, DOODLE_STATE_REQUESTING);
 	}
 
 	/* NOTE Perhaps some careful handling of remote assumed established
 	 * sessions
 	 */
 
-	yahoo_doodle_command_send_ready(gc, to);
-	yahoo_doodle_command_send_request(gc, to);
+	yahoo_doodle_command_send_ready(gc, to, DOODLE_IMV_KEY);
+	yahoo_doodle_command_send_request(gc, to, DOODLE_IMV_KEY);
 
 }
 
-static void yahoo_doodle_command_got_request(PurpleConnection *gc, const char *from)
+static void yahoo_doodle_command_got_request(PurpleConnection *gc, const char *from, const char *imv_key)
 {
 	PurpleAccount *account;
 	PurpleWhiteboard *wb;
@@ -147,6 +147,7 @@
 	/* If a session with the remote user doesn't exist */
 	if(wb == NULL)
 	{
+		doodle_session *ds;
 		/* Ask user if they wish to accept the request for a doodle session */
 		/* TODO Ask local user to start Doodle session with remote user */
 		/* NOTE This if/else statement won't work right--must use dialog
@@ -160,9 +161,11 @@
 		dialog_message, NULL, NULL, NULL);
 		*/
 
-		purple_whiteboard_create(account, from, DOODLE_STATE_REQUESTED);
+		wb = purple_whiteboard_create(account, from, DOODLE_STATE_REQUESTED);
+		ds = wb->proto_data;
+		ds->imv_key = g_strdup(imv_key);
 
-		yahoo_doodle_command_send_ready(gc, from);
+		yahoo_doodle_command_send_ready(gc, from, imv_key);
 	}
 
 	/* TODO Might be required to clear the canvas of an existing doodle
@@ -170,7 +173,7 @@
 	 */
 }
 
-static void yahoo_doodle_command_got_ready(PurpleConnection *gc, const char *from)
+static void yahoo_doodle_command_got_ready(PurpleConnection *gc, const char *from, const char *imv_key)
 {
 	PurpleAccount *account;
 	PurpleWhiteboard *wb;
@@ -189,11 +192,15 @@
 
 	if(wb->state == DOODLE_STATE_REQUESTING)
 	{
+		doodle_session *ds = wb->proto_data;
 		purple_whiteboard_start(wb);
 
 		wb->state = DOODLE_STATE_ESTABLISHED;
 
-		yahoo_doodle_command_send_confirm(gc, from);
+		yahoo_doodle_command_send_confirm(gc, from, imv_key);
+		/* Let's steal the imv_key and reuse it */
+		g_free(ds->imv_key);
+		ds->imv_key = g_strdup(imv_key);
 	}
 	else if(wb->state == DOODLE_STATE_ESTABLISHED)
 	{
@@ -208,7 +215,7 @@
 	else if(wb->state == DOODLE_STATE_REQUESTED)
 	{
 		/* purple_whiteboard_start(wb); */
-		yahoo_doodle_command_send_ready(gc, from);
+		yahoo_doodle_command_send_ready(gc, from, imv_key);
 	}
 }
 
@@ -296,14 +303,14 @@
 
 
 static void
-yahoo_doodle_command_got_extra(PurpleConnection *gc, const char *from, const char *message)
+yahoo_doodle_command_got_extra(PurpleConnection *gc, const char *from, const char *message, const char *imv_key)
 {
 	purple_debug_info("yahoo", "doodle: Got Extra (%s)\n", from);
 
 	/* I do not like these 'extra' features, so I'll only handle them in one
 	 * way, which is returning them with the command/packet to turn them off
 	 */
-	yahoo_doodle_command_send_extra(gc, from, DOODLE_EXTRA_NONE);
+	yahoo_doodle_command_send_extra(gc, from, DOODLE_EXTRA_NONE, imv_key);
 }
 
 static void yahoo_doodle_command_got_confirm(PurpleConnection *gc, const char *from)
@@ -399,34 +406,34 @@
 	yahoo_packet_send_and_free(pkt, yd);
 }
 
-void yahoo_doodle_command_send_ready(PurpleConnection *gc, const char *to)
+void yahoo_doodle_command_send_ready(PurpleConnection *gc, const char *to, const char *imv_key)
 {
-	yahoo_doodle_command_send_generic("Ready", gc, to, "1", DOODLE_CMD_READY, NULL, "1");
+	yahoo_doodle_command_send_generic("Ready", gc, to, "1", DOODLE_CMD_READY, imv_key, "1");
 }
 
-void yahoo_doodle_command_send_request(PurpleConnection *gc, const char *to)
+void yahoo_doodle_command_send_request(PurpleConnection *gc, const char *to, const char *imv_key)
 {
-	yahoo_doodle_command_send_generic("Request", gc, to, "", DOODLE_CMD_REQUEST, NULL, "0");
+	yahoo_doodle_command_send_generic("Request", gc, to, "", DOODLE_CMD_REQUEST, imv_key, "0");
 }
 
-void yahoo_doodle_command_send_draw(PurpleConnection *gc, const char *to, const char *message)
+void yahoo_doodle_command_send_draw(PurpleConnection *gc, const char *to, const char *message, const char *imv_key)
 {
-	yahoo_doodle_command_send_generic("Draw", gc, to, message, DOODLE_CMD_DRAW, NULL, "1");
+	yahoo_doodle_command_send_generic("Draw", gc, to, message, DOODLE_CMD_DRAW, imv_key, "1");
 }
 
-void yahoo_doodle_command_send_clear(PurpleConnection *gc, const char *to)
+void yahoo_doodle_command_send_clear(PurpleConnection *gc, const char *to, const char *imv_key)
 {
-	yahoo_doodle_command_send_generic("Clear", gc, to, " ", DOODLE_CMD_CLEAR, NULL, "1");
+	yahoo_doodle_command_send_generic("Clear", gc, to, " ", DOODLE_CMD_CLEAR, imv_key, "1");
 }
 
-void yahoo_doodle_command_send_extra(PurpleConnection *gc, const char *to, const char *message)
+void yahoo_doodle_command_send_extra(PurpleConnection *gc, const char *to, const char *message, const char *imv_key)
 {
-	yahoo_doodle_command_send_generic("Extra", gc, to, message, DOODLE_CMD_EXTRA, NULL, "1");
+	yahoo_doodle_command_send_generic("Extra", gc, to, message, DOODLE_CMD_EXTRA, imv_key, "1");
 }
 
-void yahoo_doodle_command_send_confirm(PurpleConnection *gc, const char *to)
+void yahoo_doodle_command_send_confirm(PurpleConnection *gc, const char *to, const char *imv_key)
 {
-	yahoo_doodle_command_send_generic("Confirm", gc, to, "1", DOODLE_CMD_CONFIRM, NULL, "1");
+	yahoo_doodle_command_send_generic("Confirm", gc, to, "1", DOODLE_CMD_CONFIRM, imv_key, "1");
 }
 
 void yahoo_doodle_command_send_shutdown(PurpleConnection *gc, const char *to)
@@ -450,12 +457,14 @@
 void yahoo_doodle_end(PurpleWhiteboard *wb)
 {
 	PurpleConnection *gc = purple_account_get_connection(wb->account);
+	doodle_session *ds = wb->proto_data;
 
 	/* g_debug_debug("yahoo", "doodle: yahoo_doodle_end()\n"); */
 
 	if (gc && wb->state != DOODLE_STATE_CANCELED)
 		yahoo_doodle_command_send_shutdown(gc, wb->who);
 
+	g_free(ds->imv_key);
 	g_free(wb->proto_data);
 }
 
@@ -492,13 +501,14 @@
 	g_return_if_fail(draw_list != NULL);
 
 	message = yahoo_doodle_build_draw_string(ds, draw_list);
-	yahoo_doodle_command_send_draw(wb->account->gc, wb->who, message);
+	yahoo_doodle_command_send_draw(wb->account->gc, wb->who, message, ds->imv_key);
 	g_free(message);
 }
 
 void yahoo_doodle_clear(PurpleWhiteboard *wb)
 {
-	yahoo_doodle_command_send_clear(wb->account->gc, wb->who);
+	doodle_session *ds = wb->proto_data;
+	yahoo_doodle_command_send_clear(wb->account->gc, wb->who, ds->imv_key);
 }
 
 
@@ -551,14 +561,14 @@
 
 void yahoo_doodle_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
 {
-	doodle_session *ds = (doodle_session *)wb->proto_data;
+	doodle_session *ds = wb->proto_data;
 	*size = ds->brush_size;
 	*color = ds->brush_color;
 }
 
 void yahoo_doodle_set_brush(PurpleWhiteboard *wb, int size, int color)
 {
-	doodle_session *ds = (doodle_session *)wb->proto_data;
+	doodle_session *ds = wb->proto_data;
 	ds->brush_size = size;
 	ds->brush_color = color;
 
@@ -567,7 +577,7 @@
 }
 
 void yahoo_doodle_process(PurpleConnection *gc, const char *me, const char *from,
-						  const char *command, const char *message)
+						  const char *command, const char *message, const char *imv_key)
 {
 	if(!command)
 		return;
@@ -576,11 +586,11 @@
 	switch(atoi(command))
 	{
 		case DOODLE_CMD_REQUEST:
-			yahoo_doodle_command_got_request(gc, from);
+			yahoo_doodle_command_got_request(gc, from, imv_key);
 			break;
 
 		case DOODLE_CMD_READY:
-			yahoo_doodle_command_got_ready(gc, from);
+			yahoo_doodle_command_got_ready(gc, from, imv_key);
 			break;
 
 		case DOODLE_CMD_CLEAR:
@@ -592,7 +602,7 @@
 			break;
 
 		case DOODLE_CMD_EXTRA:
-			yahoo_doodle_command_got_extra(gc, from, message);
+			yahoo_doodle_command_got_extra(gc, from, message, imv_key);
 			break;
 
 		case DOODLE_CMD_CONFIRM:
--- a/libpurple/protocols/yahoo/yahoo_doodle.h	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_doodle.h	Fri Sep 28 16:51:19 2007 +0000
@@ -31,7 +31,7 @@
 #include "whiteboard.h"
 #include "cmds.h"
 
-#define DOODLE_IMV_KEY "doodle;103"
+#define DOODLE_IMV_KEY "doodle;106"
 
 /******************************************************************************
  * Defines
@@ -94,6 +94,7 @@
 {
 	int brush_size;  /* Size of drawing brush */
 	int brush_color; /* Color of drawing brush */
+	gchar *imv_key;
 } doodle_session;
 
 /******************************************************************************
@@ -104,17 +105,17 @@
 									   char **error, void *data);
 
 void yahoo_doodle_process(PurpleConnection *gc, const char *me, const char *from,
-						  const char *command, const char *message);
+						  const char *command, const char *message, const char *imv_key);
 void yahoo_doodle_initiate(PurpleConnection *gc, const char *to);
 
 void yahoo_doodle_command_got_shutdown(PurpleConnection *gc, const char *from);
 
-void yahoo_doodle_command_send_request(PurpleConnection *gc, const char *to);
-void yahoo_doodle_command_send_ready(PurpleConnection *gc, const char *to);
-void yahoo_doodle_command_send_draw(PurpleConnection *gc, const char *to, const char *message);
-void yahoo_doodle_command_send_clear(PurpleConnection *gc, const char *to);
-void yahoo_doodle_command_send_extra(PurpleConnection *gc, const char *to, const char *message);
-void yahoo_doodle_command_send_confirm(PurpleConnection *gc, const char *to);
+void yahoo_doodle_command_send_request(PurpleConnection *gc, const char *to, const char *imv_key);
+void yahoo_doodle_command_send_ready(PurpleConnection *gc, const char *to, const char *imv_key);
+void yahoo_doodle_command_send_draw(PurpleConnection *gc, const char *to, const char *message, const char *imv_key);
+void yahoo_doodle_command_send_clear(PurpleConnection *gc, const char *to, const char *imv_key);
+void yahoo_doodle_command_send_extra(PurpleConnection *gc, const char *to, const char *message, const char *imv_key);
+void yahoo_doodle_command_send_confirm(PurpleConnection *gc, const char *to, const char *imv_key);
 void yahoo_doodle_command_send_shutdown(PurpleConnection *gc, const char *to);
 
 void yahoo_doodle_start(PurpleWhiteboard *wb);
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c	Fri Sep 28 16:51:19 2007 +0000
@@ -452,26 +452,29 @@
 	{
 		struct yahoo_pair *pair = l->data;
 
-		if(pair->key == 5)         /* Get who the packet is for */
+		switch(pair->key) {
+		case 5:         /* Get who the packet is for */
 			me = pair->value;
-
-		if(pair->key == 4)         /* Get who the packet is from */
+			break;
+		case 4:         /* Get who the packet is from */
 			from = pair->value;
-
-		if(pair->key == 49)        /* Get the type of service */
+			break;
+		case 49:        /* Get the type of service */
 			service = pair->value;
-
-		if(pair->key == 14)        /* Get the 'message' of the packet */
+			break;
+		case 14:        /* Get the 'message' of the packet */
 			message = pair->value;
-
-		if(pair->key == 13)        /* Get the command associated with this packet */
+			break;
+		case 13:        /* Get the command associated with this packet */
 			command = pair->value;
-
-		if(pair->key == 63)        /* IMVironment name and version */
+			break;
+		case 63:        /* IMVironment name and version */
 			imv = pair->value;
-
-		if(pair->key == 64)        /* Not sure, but it does vary with initialization of Doodle */
+			break;
+		case 64:        /* Not sure, but it does vary with initialization of Doodle */
 			unknown = pair->value; /* So, I'll keep it (for a little while atleast) */
+			break;
+		}
 
 		l = l->next;
 	}
@@ -481,7 +484,7 @@
 	{
 		/* Check for a Doodle packet and handle it accordingly */
 		if(strstr(imv, "doodle;") != NULL)
-			yahoo_doodle_process(gc, me, from, command, message);
+			yahoo_doodle_process(gc, me, from, command, message, imv);
 
 		/* If an IMVIRONMENT packet comes without a specific imviroment name */
 		if(!strcmp(imv, ";0"))
@@ -513,24 +516,35 @@
 	for (l = pkt->hash; l; l = l->next) {
 		struct yahoo_pair *pair = l->data;
 
-		if (pair->key == 4)
+		switch (pair->key) {
+		case 4:
 			from = pair->value;
-		if (pair->key == 5)
+			break;
+		case 5:
 			to = pair->value;
-		if (pair->key == 14)
+			break;
+		case 14:
 			msg = pair->value;
-		if (pair->key == 20)
+			break;
+		case 20:
 			url = pair->value;
-		if (pair->key == 38)
+			break;
+		case 38:
 			expires = strtol(pair->value, NULL, 10);
-		if (pair->key == 27)
+			break;
+		case 27:
 			filename = pair->value;
-		if (pair->key == 28)
+			break;
+		case 28:
 			filesize = atol(pair->value);
-		if (pair->key == 49)
+			break;
+		case 49:
 			service = pair->value;
-		if (pair->key == 63)
+			break;
+		case 63:
 			imv = pair->value;
+			break;
+		}
 	}
 
 	/*
--- a/pidgin/gtknotify.c	Fri Sep 28 16:34:43 2007 +0000
+++ b/pidgin/gtknotify.c	Fri Sep 28 16:51:19 2007 +0000
@@ -420,8 +420,6 @@
 	GdkPixbuf *icon;
 	gboolean new_n = TRUE;
 
-	icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM);
-
 	if (count > 0 || clear) {
 		/* Allow only one non-detailed email notification for each account */
 		if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(treemodel), &iter)) {
@@ -449,6 +447,11 @@
 		}
 	}
 
+	if (clear)
+		return NULL;
+
+	icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM);
+
 	if (new_n) {
 		data = g_new0(PidginNotifyMailData, 1);
 		gtk_tree_store_append(treemodel, &iter, NULL);
@@ -550,9 +553,8 @@
 				/* There is no API to clear the headline specifically */
 				/* This will trigger reset_mail_dialog() */
 				pidgin_blist_set_headline(NULL, NULL, NULL, NULL, NULL);
+				return NULL;
 			}
-
-			return NULL;
 		}
 	}