changeset 4249:9c7fcb211886

[gaim-migrate @ 4499] If anyone is curious, the commit before this fixed a bug which didn't allow you to delete AIM or ICQ people from a deny list. They'll show up when you sign back online, and will be deleteable now. This is a patch from the good Mr. McQueen. "Twofold attack: 1) Make sure all the callback functions don't throw a mental if the gc the dialog was asking about has disappeared. Make sure the functions still free up the data structs as necessary in this case. 2) When setting up a ask dialog, plugins (including prpls) pass in their handle. The ask dialog struct gets kept in a slist. When unloading a plugin or prpl, Gaim checks the handle against the list, and sends a cancel-type message for any outstanding dialogs. Should avoid crashes from non-modal ask dialogs lying around." Yeah, so that's a nice lil' improvement. I also fixed a think where SSI "authorization denied" messages would be gibberish. That was a bug from just a few hours ago. Whoops. Also, since this is like a grown up version of show and tell, I thought this was funny: * Robot101 fixes idiocy <KingAnt> Does that mean I'm going to be nuetered? committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Wed, 08 Jan 2003 08:18:49 +0000
parents ea8fb193f5a0
children 3b884e35e6b5
files src/dialogs.c src/ft.c src/module.c src/multi.c src/protocols/icq/gaim_icq.c src/protocols/irc/irc.c src/protocols/jabber/jabber.c src/protocols/msn/msn.c src/protocols/oscar/oscar.c src/protocols/toc/toc.c src/prpl.c src/prpl.h
diffstat 12 files changed, 174 insertions(+), 116 deletions(-) [+]
line wrap: on
line diff
--- a/src/dialogs.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/dialogs.c	Wed Jan 08 08:18:49 2003 +0000
@@ -475,7 +475,7 @@
 		return;
 
 	text = g_strdup_printf("You are about to remove %s from your buddy list.  Do you want to continue?", name);
-	do_ask_dialog("Remove Buddy", text, bd, "Remove Buddy", do_remove_buddy, "Cancel", NULL, FALSE);
+	do_ask_dialog("Remove Buddy", text, bd, "Remove Buddy", do_remove_buddy, "Cancel", NULL, NULL, FALSE);
 	g_free(text);
 }
 
--- a/src/ft.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/ft.c	Wed Jan 08 08:18:49 2003 +0000
@@ -147,7 +147,7 @@
 		buf = newmsg;
 	}
 
-	do_ask_dialog(buf, NULL, xfer, _("Accept"), ft_choose_file, _("Cancel"), ft_cancel, FALSE);
+	do_ask_dialog(buf, NULL, xfer, _("Accept"), ft_choose_file, _("Cancel"), ft_cancel, NULL, FALSE);
 	g_free(buf);
 
 	return xfer;
--- a/src/module.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/module.c	Wed Jan 08 08:18:49 2003 +0000
@@ -284,6 +284,9 @@
 
 	debug_printf("Unloading %s\n", g_module_name(p->handle));
 
+	/* cancel any pending dialogs the plugin has */
+	do_ask_cancel_by_handle(p->handle);
+
 	/* Attempt to call the plugin's remove function (if there) */
 	if (g_module_symbol(p->handle, "gaim_plugin_remove", (gpointer *)&gaim_plugin_remove))
 		gaim_plugin_remove();
@@ -325,6 +328,9 @@
 
 	debug_printf("Unloading %s\n", g_module_name(p->handle));
 
+	/* cancel any pending dialogs the plugin has */
+	do_ask_cancel_by_handle(p->handle);
+
 	if (g_module_symbol(p->handle, "gaim_plugin_remove", (gpointer *)&gaim_plugin_remove))
 		gaim_plugin_remove();
 	plugin_remove_callbacks(p->handle);
--- a/src/multi.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/multi.c	Wed Jan 08 08:18:49 2003 +0000
@@ -1136,7 +1136,7 @@
 
 		g_snprintf(buf, sizeof(buf),
 				   _("Are you sure you want to delete %s?"), u->username);
-		do_ask_dialog(buf, NULL, u, _("Delete"), do_del_acct, _("Cancel"), NULL, FALSE);
+		do_ask_dialog(buf, NULL, u, _("Delete"), do_del_acct, _("Cancel"), NULL, NULL, FALSE);
 	}
 }
 
--- a/src/protocols/icq/gaim_icq.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/protocols/icq/gaim_icq.c	Wed Jan 08 08:18:49 2003 +0000
@@ -15,6 +15,8 @@
 
 #define USEROPT_NICK 0
 
+static struct prpl *my_protocol = NULL;
+
 struct icq_data {
 	icq_Link *link;
 	int cur_status;
@@ -254,29 +256,34 @@
 
 static void icq_add_after_auth(struct icq_auth *iq)
 {
-	char uin[16];
-	g_snprintf(uin, sizeof(uin), "%ld", iq->uin);
-	show_add_buddy(iq->gc, uin, NULL, iq->nick);
+	if (g_slist_find(connections, iq->gc)) {
+		char uin[16];
+		g_snprintf(uin, sizeof(uin), "%ld", iq->uin);
+		show_add_buddy(iq->gc, uin, NULL, iq->nick);
+	}
 	icq_den_auth(iq);
 }
 
 static void icq_acc_auth(struct icq_auth *iq)
 {
-	char msg[1024];
-	char uin[16];
-	struct icq_auth *iqnew;
-	
-	icq_SendAuthMsg(iq->link, iq->uin);
+	if (g_slist_find(connections, iq->gc)) {
+		char msg[1024];
+		char uin[16];
+		struct icq_auth *iqnew;
+
+		icq_SendAuthMsg(iq->link, iq->uin);
 
-	g_snprintf(uin, sizeof(uin), "%ld", iq->uin);
-	if (find_buddy(iq->gc, uin))
-		return;
+		g_snprintf(uin, sizeof(uin), "%ld", iq->uin);
+		if (find_buddy(iq->gc, uin))
+			return;
 
-	iqnew = g_memdup(iq, sizeof(struct icq_auth));
-	iqnew->nick = g_strdup(iq->nick);
+		iqnew = g_memdup(iq, sizeof(struct icq_auth));
+		iqnew->nick = g_strdup(iq->nick);
 
-	g_snprintf(msg, sizeof(msg), "Add %ld to your buddy list?", iq->uin);
-	do_ask_dialog(msg, NULL, iqnew, _("Add"), icq_add_after_auth, _("Cancel"), icq_den_auth, FALSE);
+		g_snprintf(msg, sizeof(msg), "Add %ld to your buddy list?", iq->uin);
+		do_ask_dialog(msg, NULL, iqnew, _("Add"), icq_add_after_auth, _("Cancel"), icq_den_auth, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
+	}
+
 	icq_den_auth(iq);
 }
 
@@ -294,7 +301,7 @@
 	g_snprintf(msg, sizeof(msg), "The user %s (%s%s%s%s%s) wants you to authorize them.",
 			nick, first ? first : "", first && last ? " " : "", last ? last : "",
 			(first || last) && email ? ", " : "", email ? email : "");
-	do_ask_dialog(msg, NULL, iq, _("Authorize"), icq_acc_auth, _("Deny"), icq_den_auth, FALSE);
+	do_ask_dialog(msg, NULL, iq, _("Authorize"), icq_acc_auth, _("Deny"), icq_den_auth, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 }
 
 static void icq_login(struct aim_user *user) {
@@ -488,8 +495,6 @@
 	return m;
 }
 
-static struct prpl *my_protocol = NULL;
-
 void icq_init(struct prpl *ret) {
 	struct proto_user_opt *puo;
 	ret->protocol = PROTO_ICQ;
--- a/src/protocols/irc/irc.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/protocols/irc/irc.c	Wed Jan 08 08:18:49 2003 +0000
@@ -58,6 +58,8 @@
 #define USEROPT_PORT      1
 #define USEROPT_CHARSET   2
 
+static struct prpl *my_protocol = NULL;
+
 /* for win32 compatability */
 G_MODULE_IMPORT GSList *connections;
 
@@ -1181,12 +1183,16 @@
 
 static void 
 dcc_chat_init(struct dcc_chat *data) {
-	proxy_connect(data->ip_address, data->port, dcc_chat_callback, data);
+	if (g_slist_find(connections, data->gc)) {
+		proxy_connect(data->ip_address, data->port, dcc_chat_callback, data);
+	} else {
+		g_free(data);
+	}
 }
 
 static void 
 dcc_chat_cancel(struct dcc_chat *data){
-	if (find_dcc_chat(data->gc, data->nick)) {
+	if (g_slist_find(connections, data->gc) && find_dcc_chat(data->gc, data->nick)) {
 		dcc_chat_list = g_slist_remove(dcc_chat_list, data); 
 		gaim_input_remove (data->inpa);
 		close (data->fd);
@@ -1255,7 +1261,7 @@
 		dccchat->port=atoi(chat_args[4]);		
 		g_snprintf(dccchat->nick, sizeof(dccchat->nick), nick);	
 		g_snprintf(ask, sizeof(ask), _("%s would like to establish a DCC chat"), nick);
-		do_ask_dialog(ask, _("This requires a direct connection to be established between the two computers.  Messages sent will not pass through the IRC server"), dccchat, _("Connect"), dcc_chat_init, _("Cancel"), dcc_chat_cancel, FALSE);
+		do_ask_dialog(ask, _("This requires a direct connection to be established between the two computers.  Messages sent will not pass through the IRC server"), dccchat, _("Connect"), dcc_chat_init, _("Cancel"), dcc_chat_cancel, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 	}
 
 
@@ -2658,8 +2664,6 @@
 	return m;
 }
 
-static struct prpl *my_protocol = NULL;
-
 G_MODULE_EXPORT void 
 irc_init(struct prpl *ret)
 {
--- a/src/protocols/jabber/jabber.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/protocols/jabber/jabber.c	Wed Jan 08 08:18:49 2003 +0000
@@ -67,11 +67,15 @@
 #include "pixmaps/protocols/jabber/available-dnd.xpm"
 #include "pixmaps/protocols/jabber/available-error.xpm"
 
+static struct prpl *my_protocol = NULL;
+
 /* for win32 compatability */
 G_MODULE_IMPORT GSList *connections;
 
 /* The priv member of gjconn's is a gaim_connection for now. */
 #define GJ_GC(x) ((struct gaim_connection *)(x)->priv)
+/* Confused? That makes three of us. -Robot101 */
+#define GC_GJ(x) ((gjconn)((struct jabber_data *)(x)->proto_data)->gjc)
 
 #define IQID_AUTH "__AUTH__"
 
@@ -1580,7 +1584,7 @@
  * Used only by Jabber accept/deny add stuff just below
  */
 struct jabber_add_permit {
-	gjconn gjc;
+	struct gaim_connection *gc;
 	gchar *user;
 };
 
@@ -1595,7 +1599,7 @@
 
 	xmlnode_put_attrib(g, "to", jap->user);
 	xmlnode_put_attrib(g, "type", type);
-	gjab_send(jap->gjc, g);
+	gjab_send(GC_GJ(jap->gc), g);
 
 	xmlnode_free(g);
 }
@@ -1605,14 +1609,17 @@
  */
 static void jabber_accept_add(struct jabber_add_permit *jap)
 {
-	jabber_accept_deny_add(jap, "subscribed");
-	/*
-	 * If we don't already have the buddy on *our* buddylist,
-	 * ask if we want him or her added.
-	 */
-	if(find_buddy(GJ_GC(jap->gjc), jap->user) == NULL) {
-		show_got_added(GJ_GC(jap->gjc), NULL, jap->user, NULL, NULL);
+	if(g_slist_find(connections, jap->gc)) {
+		jabber_accept_deny_add(jap, "subscribed");
+		/*
+		 * If we don't already have the buddy on *our* buddylist,
+		 * ask if we want him or her added.
+		 */
+		if(find_buddy(jap->gc, jap->user) == NULL) {
+			show_got_added(jap->gc, NULL, jap->user, NULL, NULL);
+		}
 	}
+
 	g_free(jap->user);
 	g_free(jap);
 }
@@ -1622,7 +1629,10 @@
  */
 static void jabber_deny_add(struct jabber_add_permit *jap)
 {
-	jabber_accept_deny_add(jap, "unsubscribed");
+	if(g_slist_find(connections, jap->gc)) {
+		jabber_accept_deny_add(jap, "unsubscribed");
+	}
+
 	g_free(jap->user);
 	g_free(jap);
 }
@@ -1647,9 +1657,9 @@
 		gchar *msg = g_strdup_printf(_("The user %s wants to add you to their buddy list."),
 				Jid);
 
-		jap->gjc = gjc;
+		jap->gc = GJ_GC(gjc);
 		jap->user = g_strdup(Jid);
-		do_ask_dialog(msg, NULL, jap, _("Authorize"), jabber_accept_add, _("Deny"), jabber_deny_add, FALSE);
+		do_ask_dialog(msg, NULL, jap, _("Authorize"), jabber_accept_add, _("Deny"), jabber_deny_add, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 
 		g_free(msg);
 		xmlnode_free(g);	/* Never needed it here anyway */
@@ -4162,8 +4172,6 @@
 	return m;
 }
 
-static struct prpl *my_protocol = NULL;
-
 G_MODULE_EXPORT void jabber_init(struct prpl *ret)
 {
 	/* the NULL's aren't required but they're nice to have */
--- a/src/protocols/msn/msn.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/protocols/msn/msn.c	Wed Jan 08 08:18:49 2003 +0000
@@ -27,6 +27,8 @@
 #include "pixmaps/protocols/msn/msn_away.xpm"
 #include "pixmaps/protocols/msn/msn_occ.xpm"
 
+static struct prpl *my_protocol = NULL;
+
 /* for win32 compatability */
 G_MODULE_IMPORT GSList *connections;
 
@@ -1066,19 +1068,22 @@
 
 static void msn_accept_add(struct msn_add_permit *map)
 {
-	struct msn_data *md = map->gc->proto_data;
-	char buf[MSN_BUF_LEN];
-	
-	g_snprintf(buf, sizeof(buf), "ADD %d AL %s %s\r\n", ++md->trId, map->user, url_encode(map->friend));
-	
-	if (msn_write(md->fd, buf, strlen(buf)) < 0) {
-		hide_login_progress(map->gc, _("Write error"));
-		signoff(map->gc);
-		return;
+	if(g_slist_find(connections, map->gc)) {
+		struct msn_data *md = map->gc->proto_data;
+		char buf[MSN_BUF_LEN];
+
+		g_snprintf(buf, sizeof(buf), "ADD %d AL %s %s\r\n", ++md->trId, map->user, url_encode(map->friend));
+
+		if (msn_write(md->fd, buf, strlen(buf)) < 0) {
+			hide_login_progress(map->gc, _("Write error"));
+			signoff(map->gc);
+			return;
+		}
+		map->gc->permit = g_slist_append(map->gc->permit, map->user);
+		build_allow_list(); /* er. right. we'll need to have a thing for this in CUI too */
+		show_got_added(map->gc, NULL, map->user, map->friend, NULL);
 	}
-	map->gc->permit = g_slist_append(map->gc->permit, map->user);
-	build_allow_list(); /* er. right. we'll need to have a thing for this in CUI too */
-	show_got_added(map->gc, NULL, map->user, map->friend, NULL);
+
 	g_free(map->user);
 	g_free(map->friend);
 	g_free(map);
@@ -1086,19 +1091,20 @@
 
 static void msn_cancel_add(struct msn_add_permit *map)
 {
-	struct msn_data *md = map->gc->proto_data;
-	char buf[MSN_BUF_LEN];
-
-	g_snprintf(buf, sizeof(buf), "ADD %d BL %s %s\r\n", ++md->trId, map->user, url_encode(map->friend));
-	if (msn_write(md->fd, buf, strlen(buf)) < 0) {
-		hide_login_progress(map->gc, _("Write error"));
-		signoff(map->gc);
-		return;
+	if(g_slist_find(connections, map->gc)) {
+		struct msn_data *md = map->gc->proto_data;
+		char buf[MSN_BUF_LEN];
+
+		g_snprintf(buf, sizeof(buf), "ADD %d BL %s %s\r\n", ++md->trId, map->user, url_encode(map->friend));
+		if (msn_write(md->fd, buf, strlen(buf)) < 0) {
+			hide_login_progress(map->gc, _("Write error"));
+			signoff(map->gc);
+			return;
+		}
+		map->gc->deny = g_slist_append(map->gc->deny, map->user);
+		build_block_list();
 	}
-	map->gc->deny = g_slist_append(map->gc->deny, map->user);
-	build_block_list();
-	
-	
+
 	g_free(map->user);
 	g_free(map->friend);
 	g_free(map);
@@ -1143,7 +1149,7 @@
 		g_snprintf(msg, sizeof(msg), _("The user %s (%s) wants to add %s to his or her buddy list."),
 				ap->user, ap->friend, ap->gc->username);
 
-		do_ask_dialog(msg, NULL, ap, _("Authorize"), msn_accept_add, _("Deny"), msn_cancel_add, FALSE);
+		do_ask_dialog(msg, NULL, ap, _("Authorize"), msn_accept_add, _("Deny"), msn_cancel_add, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 	} else if (!g_strncasecmp(buf, "BLP", 3)) {
 		char *type, *tmp = buf;
 
@@ -1292,8 +1298,8 @@
 				ap->friend = g_strdup(friend);
 				ap->gc = gc;
                          
-		                g_snprintf(msg, sizeof(msg), _("The user %s (%s) wants to add you to their buddy list"),ap->user, ap->friend);
-				do_ask_dialog(msg, NULL, ap, _("Authorize"), msn_accept_add, _("Deny"), msn_cancel_add, FALSE);
+				g_snprintf(msg, sizeof(msg), _("The user %s (%s) wants to add you to their buddy list"),ap->user, ap->friend);
+				do_ask_dialog(msg, NULL, ap, _("Authorize"), msn_accept_add, _("Deny"), msn_cancel_add, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 			}
 		    }
 			
@@ -2802,8 +2808,6 @@
 		g_free(b->proto_data);
 }
 
-static struct prpl *my_protocol = NULL;
-
 G_MODULE_EXPORT void msn_init(struct prpl *ret)
 {
 	struct proto_user_opt *puo;
--- a/src/protocols/oscar/oscar.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/protocols/oscar/oscar.c	Wed Jan 08 08:18:49 2003 +0000
@@ -83,6 +83,8 @@
 
 #define AIMHASHDATA "http://gaim.sourceforge.net/aim_data.php3"
 
+static struct prpl *my_protocol = NULL;
+
 /* For win32 compatability */
 G_MODULE_IMPORT GSList *connections;
 G_MODULE_IMPORT int report_idle;
@@ -2049,7 +2051,7 @@
 		memcpy(d->cookie, args->cookie, 8);
 		g_snprintf(buf, sizeof buf, "%s has just asked to directly connect to %s.",
 				userinfo->sn, gc->username);
-		do_ask_dialog(buf, _("This requires a direct connection between the two computers and is necessary for IM Images.  Because your IP address will be revealed, this may be considered a privacy risk."), d, _("Connect"), accept_direct_im, _("Cancel"), cancel_direct_im, FALSE);
+		do_ask_dialog(buf, _("This requires a direct connection between the two computers and is necessary for IM Images.  Because your IP address will be revealed, this may be considered a privacy risk."), d, _("Connect"), accept_direct_im, _("Cancel"), cancel_direct_im, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 	} else {
 		debug_printf("Unknown reqclass %hu\n", args->reqclass);
 	}
@@ -2118,8 +2120,8 @@
 	if (g_slist_find(connections, gc)) {
 		struct oscar_data *od = gc->proto_data;
 		gchar *message;
+		message = g_strdup_printf(_("No reason given."));
 #ifdef NOSSI
-		message = g_strdup_printf(_("No reason given."));
 		aim_send_im_ch4(od->sess, data->name, AIM_ICQMSG_AUTHDENIED, message);
 #else
 		aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x00, message);
@@ -2195,7 +2197,7 @@
 				data->gc = gc;
 				data->name = g_strdup_printf("%lu", args->uin);
 				data->nick = NULL;
-				do_ask_dialog(_("Authorization Request"), dialog_msg, data, _("Authorize"), gaim_auth_grant, _("Deny"), gaim_auth_dontgrant, FALSE);
+				do_ask_dialog(_("Authorization Request"), dialog_msg, data, _("Authorize"), gaim_auth_grant, _("Deny"), gaim_auth_dontgrant, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 				g_free(dialog_msg);
 			}
 		} break;
@@ -2249,7 +2251,7 @@
 					data->gc = gc;
 					data->name = g_strdup(text[i*2+2]);
 					data->nick = g_strdup(text[i*2+1]);
-					do_ask_dialog(message, _("Do you want to add this contact to your Buddy List?"), data, _("Add"), gaim_icq_contactadd, _("Decline"), gaim_free_name_data, FALSE);
+					do_ask_dialog(message, _("Do you want to add this contact to your Buddy List?"), data, _("Add"), gaim_icq_contactadd, _("Decline"), gaim_free_name_data, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 					g_free(message);
 				}
 				g_strfreev(text);
@@ -4253,7 +4255,7 @@
 					data->gc = gc;
 					data->name = g_strdup(retval->name);
 					data->nick = NULL;
-					do_ask_dialog(_("Request Authorization"), dialog_msg, data, _("Request Authorization"), gaim_auth_request, _("Cancel"), gaim_auth_dontrequest, FALSE);
+					do_ask_dialog(_("Request Authorization"), dialog_msg, data, _("Request Authorization"), gaim_auth_request, _("Cancel"), gaim_auth_dontrequest, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 
 					g_free(dialog_msg);
 					g_free(nombre);
@@ -4298,7 +4300,7 @@
 	data->gc = gc;
 	data->name = g_strdup(sn);
 	data->nick = NULL;
-	do_ask_dialog(_("Authorization Given"), dialog_msg, data, _("Yes"), gaim_icq_contactadd, _("No"), gaim_free_name_data, FALSE);
+	do_ask_dialog(_("Authorization Given"), dialog_msg, data, _("Yes"), gaim_icq_contactadd, _("No"), gaim_free_name_data, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 
 	g_free(dialog_msg);
 	g_free(nombre);
@@ -4332,7 +4334,7 @@
 	data->gc = gc;
 	data->name = g_strdup(sn);
 	data->nick = NULL;
-	do_ask_dialog(_("Authorization Request"), dialog_msg, data, _("Authorize"), gaim_auth_grant, _("Deny"), gaim_auth_dontgrant, FALSE);
+	do_ask_dialog(_("Authorization Request"), dialog_msg, data, _("Authorize"), gaim_auth_grant, _("Deny"), gaim_auth_dontgrant, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 
 	g_free(dialog_msg);
 	g_free(nombre);
@@ -4845,7 +4847,7 @@
 	data->who = who;
 	data->gc = gc;
 	g_snprintf(buf, sizeof(buf),  _("You have selected to open a Direct IM connection with %s."), who);
-	do_ask_dialog(buf, _("Because this reveals your IP address, it may be considered a privacy risk.  Do you wish to continue?"), data, _("Connect"), oscar_direct_im, _("Cancel"), oscar_cancel_direct_im, FALSE);
+	do_ask_dialog(buf, _("Because this reveals your IP address, it may be considered a privacy risk.  Do you wish to continue?"), data, _("Connect"), oscar_direct_im, _("Cancel"), oscar_cancel_direct_im, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 }
 
 static void oscar_get_away_msg(struct gaim_connection *gc, char *who) {
@@ -5231,8 +5233,6 @@
 	}
 }
 
-static struct prpl *my_protocol = NULL;
-
 G_MODULE_EXPORT void oscar_init(struct prpl *ret) {
 	struct proto_user_opt *puo;
 	ret->protocol = PROTO_OSCAR;
--- a/src/protocols/toc/toc.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/protocols/toc/toc.c	Wed Jan 08 08:18:49 2003 +0000
@@ -59,6 +59,8 @@
 #include "pixmaps/protocols/oscar/free_icon.xpm"
 #include "pixmaps/protocols/oscar/wireless_icon.xpm"
 
+static struct prpl *my_protocol = NULL;
+
 /* for win32 compatability */
 G_MODULE_IMPORT GSList *connections;
 
@@ -1399,8 +1401,6 @@
 	return m;
 }
 
-static struct prpl *my_protocol = NULL;
-
 G_MODULE_EXPORT void toc_init(struct prpl *ret)
 {	
 	struct proto_user_opt *puo;
@@ -1933,33 +1933,36 @@
 
 
 static void toc_accept_ft(struct ft_request *fr) {
-	GtkWidget *window;
-	char buf[BUF_LEN];
+	if(g_slist_find(connections, fr->gc)) {
+		GtkWidget *window;
+		char buf[BUF_LEN];
 
-	struct file_transfer *ft = g_new0(struct file_transfer, 1);
-	ft->gc = fr->gc;
-	ft->user = g_strdup(fr->user);
-	ft->cookie = g_strdup(fr->cookie);
-	ft->ip = g_strdup(fr->ip);
-	ft->port = fr->port;
-	ft->files = fr->files;
+		struct file_transfer *ft = g_new0(struct file_transfer, 1);
+		ft->gc = fr->gc;
+		ft->user = g_strdup(fr->user);
+		ft->cookie = g_strdup(fr->cookie);
+		ft->ip = g_strdup(fr->ip);
+		ft->port = fr->port;
+		ft->files = fr->files;
 
-	ft->window = window = gtk_file_selection_new(_("Gaim - Save As..."));
-	g_snprintf(buf, sizeof(buf), "%s/%s", gaim_home_dir(), fr->filename ? fr->filename : "");
-	gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf);
-	gtk_signal_connect(GTK_OBJECT(window), "destroy",
-			   GTK_SIGNAL_FUNC(cancel_callback), ft);
-	gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ft->window)->cancel_button), "clicked",
-			   GTK_SIGNAL_FUNC(cancel_callback), ft);
+		ft->window = window = gtk_file_selection_new(_("Gaim - Save As..."));
+		g_snprintf(buf, sizeof(buf), "%s/%s", gaim_home_dir(), fr->filename ? fr->filename : "");
+		gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf);
+		gtk_signal_connect(GTK_OBJECT(window), "destroy",
+				   GTK_SIGNAL_FUNC(cancel_callback), ft);
+		gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ft->window)->cancel_button), "clicked",
+				   GTK_SIGNAL_FUNC(cancel_callback), ft);
 
-	if (!strcmp(fr->UID, FILE_SEND_UID))
-		gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked",
-				   GTK_SIGNAL_FUNC(toc_send_file), ft);
-	else
-		gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked",
-				   GTK_SIGNAL_FUNC(toc_get_file), ft);
+		if (!strcmp(fr->UID, FILE_SEND_UID))
+			gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked",
+					   GTK_SIGNAL_FUNC(toc_send_file), ft);
+		else
+			gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked",
+					   GTK_SIGNAL_FUNC(toc_get_file), ft);
 
-	gtk_widget_show(window);
+		gtk_widget_show(window);
+	}
+
 	toc_reject_ft(fr);
 }
 
@@ -1984,5 +1987,5 @@
 	} else {
 		g_snprintf(buf, sizeof(buf), _("%s requests you to send them a file"), ft->user);
 	}
-	do_ask_dialog(buf, NULL, ft, _("Accept"), toc_accept_ft, _("Cancel"), toc_reject_ft, FALSE);
+	do_ask_dialog(buf, NULL, ft, _("Accept"), toc_accept_ft, _("Cancel"), toc_reject_ft, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE);
 }
--- a/src/prpl.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/prpl.c	Wed Jan 08 08:18:49 2003 +0000
@@ -134,12 +134,35 @@
 	gtk_widget_destroy(b);
 }
 
+static GSList *do_ask_dialogs = NULL;
+
 struct doaskstruct {
+	GtkWidget *dialog;
+	GModule *handle;
 	void (*yesfunc)(gpointer);
 	void (*nofunc)(gpointer);
 	gpointer data;
 };
 
+void do_ask_cancel_by_handle(GModule *handle)
+{
+	GSList *d = do_ask_dialogs;
+
+	debug_printf("%d dialogs to search\n", g_slist_length(d));
+
+	while (d) {
+		GSList *cur = d;
+		struct doaskstruct *doask = d->data;
+
+		d = d->next;
+
+		if (doask->handle == handle) {
+			debug_printf("removing dialog, %d remain\n", g_slist_length(d));
+			gtk_dialog_response(GTK_DIALOG(doask->dialog), GTK_RESPONSE_NONE);
+		}
+	}
+}
+
 static void do_ask_callback(GtkDialog *d, gint resp, struct doaskstruct *doask)
 {
 	switch (resp) 
@@ -148,12 +171,12 @@
 			if (doask->yesfunc)
 				doask->yesfunc(doask->data);
 			break;
-		case GTK_RESPONSE_NO:
-		case GTK_RESPONSE_DELETE_EVENT:
+		default:
 			if (doask->nofunc)
 				doask->nofunc(doask->data);
 			break;
 		}
+	do_ask_dialogs = g_slist_remove(do_ask_dialogs, doask);
 	g_free(doask);
 	gtk_widget_destroy(GTK_WIDGET(d));
 }
@@ -163,7 +186,7 @@
                                    if (!strcmp(r,notext))  \
                                            notext = l;     
 
-void do_ask_dialog(const char *prim, const char *sec, void *data, char *yestext, void *doit, char *notext, void *dont, int modal)
+void do_ask_dialog(const char *prim, const char *sec, void *data, char *yestext, void *doit, char *notext, void *dont, GModule *handle, gboolean modal)
 {
 	GtkWidget *window;
 	GtkWidget *hbox;
@@ -173,10 +196,6 @@
 	GtkWidget *img = gtk_image_new_from_file(filename);
 	struct doaskstruct *doask = g_new0(struct doaskstruct, 1);
 
-	doask->yesfunc = doit;
-	doask->nofunc  = dont;
-	doask->data    = data;
-
 	g_free(filename);
 	gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
 
@@ -200,7 +219,7 @@
 
 	gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_YES);
 	g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(do_ask_callback), doask);
-	
+
 	gtk_container_set_border_width (GTK_CONTAINER(window), 6);
 	gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
 	gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
@@ -217,7 +236,14 @@
 	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	
+
+	doask->dialog  = window;
+	doask->handle  = handle;
+	doask->yesfunc = doit;
+	doask->nofunc  = dont;
+	doask->data    = data;
+	do_ask_dialogs = g_slist_append(do_ask_dialogs, doask);
+
 	gtk_widget_show_all(window);
 }
 
@@ -641,7 +667,7 @@
 	if (find_buddy(gc, ga->who))
 		do_error_dialog(buf, NULL, GAIM_INFO);
 	else
-		do_ask_dialog(buf, NULL, ga, _("Add"), do_add, _("Cancel"), dont_add, FALSE);
+		do_ask_dialog(buf, NULL, ga, _("Add"), do_add, _("Cancel"), dont_add, NULL, FALSE);
 }
 
 static GtkWidget *regdlg = NULL;
@@ -785,6 +811,7 @@
 		debug_printf("Protocol %s now in use by %d connections.\n", p->name, prpl_accounts[p->protocol]);
 		if(prpl_accounts[p->protocol] == 0) { /* No longer needed */
 			debug_printf("Throwing out %s protocol plugin\n", p->name);
+			do_ask_cancel_by_handle(p->plug->handle);
 			g_timeout_add(0, delayed_unload, p->plug->handle);
 			p->plug->handle = NULL;
 		}
--- a/src/prpl.h	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/prpl.h	Wed Jan 08 08:18:49 2003 +0000
@@ -210,7 +210,8 @@
 extern void show_got_added(struct gaim_connection *, const char *,
 			   const char *, const char *, const char *);
 
-extern void do_ask_dialog(const char *, const char *, void *, char*, void *, char *, void *, int);
+extern void do_ask_cancel_by_handle(GModule *);
+extern void do_ask_dialog(const char *, const char *, void *, char*, void *, char *, void *, GModule *, gboolean);
 extern void do_prompt_dialog(const char *, const char *, void *, void *, void *);
 
 extern void connection_has_mail(struct gaim_connection *, int, const char *, const char *, const char *);