changeset 10504:1a97d5e88d12

[gaim-migrate @ 11796] Lots of things here: - Several memory leak fixes - A few invalid memory access fixes - Fix a yahoo crash going idle when away - Fix Add user in chats to actually fill in the screenname - Add gaim_account_{get,set}_enabled to perl - Fix command priorities (fixes /me in IRC) - Fix MSN notification server transfer to be quiet about it - Fix MSN blist sync if user has insane friendly name - Make the docklet less crash-happy if it fails to embed in 3 seconds - Only probe for native plugins with the correct file extension - 1 typo fix :) ... and quite possibly something else I forgot. committer: Tailor Script <tailor@pidgin.im>
author Stu Tomlinson <stu@nosnilmot.com>
date Tue, 11 Jan 2005 17:25:06 +0000
parents 776586d647e3
children 91f17026b693
files plugins/docklet/docklet-x11.c plugins/docklet/docklet.c plugins/docklet/docklet.h plugins/perl/common/Account.xs plugins/tcl/tcl_signals.c src/blist.c src/cmds.c src/conversation.c src/core.c src/ft.c src/gtkblist.c src/gtkconn.c src/gtkconv.c src/gtkimhtml.c src/gtkimhtmltoolbar.c src/gtkstatusselector.c src/gtkutils.c src/plugin.c src/plugin.h src/protocols/irc/irc.c src/protocols/irc/msgs.c src/protocols/irc/parse.c src/protocols/jabber/buddy.c src/protocols/jabber/chat.c src/protocols/jabber/jabber.c src/protocols/msn/cmdproc.c src/protocols/msn/httpconn.c src/protocols/msn/msn.c src/protocols/msn/msn.h src/protocols/msn/nexus.c src/protocols/msn/notification.c src/protocols/msn/session.c src/protocols/msn/slpcall.c src/protocols/msn/switchboard.c src/protocols/msn/userlist.c src/protocols/oscar/msgcookie.c src/protocols/oscar/oscar.c src/protocols/yahoo/util.c src/protocols/yahoo/yahoo.c src/protocols/yahoo/yahoochat.c src/status.c
diffstat 41 files changed, 201 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/docklet/docklet-x11.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/plugins/docklet/docklet-x11.c	Tue Jan 11 17:25:06 2005 +0000
@@ -88,6 +88,8 @@
 {
 	const gchar *icon_name = NULL;
 
+	g_return_if_fail(image != NULL);
+
 	switch (icon) {
 		case offline:
 			icon_name = GAIM_STOCK_ICON_OFFLINE;
@@ -152,9 +154,11 @@
 	*push_in = TRUE;
 }
 
-static gboolean
+static void
 docklet_x11_destroy()
 {
+	g_return_if_fail(docklet != NULL);
+
 	docklet_remove(GTK_WIDGET_VISIBLE(docklet));
 
 	g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_x11_destroyed_cb), NULL);
@@ -167,7 +171,18 @@
 		g_object_unref(G_OBJECT(blank_icon));
 	blank_icon = NULL;
 
+	if (image)
+		gtk_widget_destroy(image);
+	image = NULL;
+
 	gaim_debug(GAIM_DEBUG_INFO, "tray icon", "destroyed\n");
+}
+
+static gboolean
+docklet_x11_embed_timeout_cb()
+{
+	docklet_unload();
+
 	return FALSE;
 }
 
@@ -203,7 +218,7 @@
 	/* ref the docklet before we bandy it about the place */
 	g_object_ref(G_OBJECT(docklet));
 	docklet_embedded();
-	embed_timeout = g_timeout_add(EMBED_TIMEOUT, docklet_x11_destroy, NULL);
+	embed_timeout = g_timeout_add(EMBED_TIMEOUT, docklet_x11_embed_timeout_cb, NULL);
 
 	gaim_debug(GAIM_DEBUG_INFO, "tray icon", "created\n");
 }
--- a/plugins/docklet/docklet.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/plugins/docklet/docklet.c	Tue Jan 11 17:25:06 2005 +0000
@@ -402,6 +402,12 @@
 }
 
 void
+docklet_unload()
+{
+	gaim_plugin_unload(handle);
+}
+
+void
 docklet_set_ui_ops(struct docklet_ui_ops *ops)
 {
 	ui_ops = ops;
--- a/plugins/docklet/docklet.h	Tue Jan 11 02:00:44 2005 +0000
+++ b/plugins/docklet/docklet.h	Tue Jan 11 17:25:06 2005 +0000
@@ -53,6 +53,7 @@
 extern void docklet_embedded();
 extern void docklet_remove(gboolean);
 extern void docklet_set_ui_ops(struct docklet_ui_ops *);
+extern void docklet_unload();
 
 /* function in docklet-{x11,win32}.c */
 extern void docklet_ui_init();
--- a/plugins/perl/common/Account.xs	Tue Jan 11 02:00:44 2005 +0000
+++ b/plugins/perl/common/Account.xs	Tue Jan 11 17:25:06 2005 +0000
@@ -59,6 +59,12 @@
 	Gaim::Account account
 	gboolean value
 
+void
+gaim_account_set_enabled(account, ui, value)
+	Gaim::Account account
+	const char *ui
+	gboolean value
+
 gboolean
 gaim_account_is_connected(account)
 	Gaim::Account account
@@ -99,6 +105,11 @@
 gaim_account_get_check_mail(account)
 	Gaim::Account account
 
+gboolean
+gaim_account_get_enabled(account, ui)
+	Gaim::Account account
+	const char *ui
+
 
 MODULE = Gaim::Account  PACKAGE = Gaim::Accounts  PREFIX = gaim_accounts_
 
--- a/plugins/tcl/tcl_signals.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/plugins/tcl/tcl_signals.c	Tue Jan 11 17:25:06 2005 +0000
@@ -310,7 +310,7 @@
 	}
 
 	g_string_free(name, TRUE);
-	g_string_free(val, FALSE);
+	g_string_free(val, TRUE);
 	g_free(vars);
 
 	return retval;
--- a/src/blist.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/blist.c	Tue Jan 11 17:25:06 2005 +0000
@@ -1686,6 +1686,7 @@
 			ops->remove(gaimbuddylist, node);
 
 		/* Delete the node */
+		g_hash_table_destroy(contact->node.settings);
 		g_free(contact);
 	}
 }
@@ -1757,6 +1758,7 @@
 	gaim_presence_destroy(buddy->presence);
 	g_free(buddy->name);
 	g_free(buddy->alias);
+	g_free(buddy->server_alias);
 	g_free(buddy);
 
 	/* If the contact is empty then remove it */
@@ -1799,6 +1801,7 @@
 
 	/* Delete the node */
 	g_hash_table_destroy(chat->components);
+	g_hash_table_destroy(chat->node.settings);
 	g_free(chat->alias);
 	g_free(chat);
 }
@@ -1860,6 +1863,7 @@
 	}
 
 	/* Delete the node */
+	g_hash_table_destroy(group->node.settings);
 	g_free(group->name);
 	g_free(group);
 }
--- a/src/cmds.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/cmds.c	Tue Jan 11 17:25:06 2005 +0000
@@ -44,9 +44,9 @@
 
 static gint cmds_compare_func(const GaimCmd *a, const GaimCmd *b)
 {
-	if (a->id > b->id)
+	if (a->priority > b->priority)
 		return -1;
-	else if (a->id < b->id)
+	else if (a->priority < b->priority)
 		return 1;
 	else return 0;
 }
--- a/src/conversation.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/conversation.c	Tue Jan 11 17:25:06 2005 +0000
@@ -976,7 +976,7 @@
 
 		for (node = conv->u.chat->in_room; node != NULL; node = node->next) {
 			if (node->data != NULL)
-				g_free(node->data);
+				gaim_conv_chat_cb_destroy((GaimConvChatBuddy *)node->data);
 			node->data = NULL;
 		}
 
@@ -1000,6 +1000,9 @@
 			g_free(conv->u.chat->topic);
 		conv->u.chat->topic = NULL;
 
+		if(conv->u.chat->nick)
+			g_free(conv->u.chat->nick);
+
 		g_free(conv->u.chat);
 		conv->u.chat = NULL;
 
--- a/src/core.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/core.c	Tue Jan 11 17:25:06 2005 +0000
@@ -82,7 +82,7 @@
 	 * subsystem right away too.
 	 */
 	gaim_plugins_init();
-	gaim_plugins_probe(NULL);
+	gaim_plugins_probe(GAIM_PLUGIN_EXT);
 
 	if (ops != NULL)
 	{
--- a/src/ft.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/ft.c	Tue Jan 11 17:25:06 2005 +0000
@@ -987,12 +987,12 @@
 		escaped = g_markup_escape_text(gaim_xfer_get_filename(xfer), -1);
 		msg = g_strdup_printf(_("%s canceled the transfer of %s"),
 							  xfer->who, escaped);
+		g_free(escaped);
 	}
 	else
 	{
 		msg = g_strdup_printf(_("%s canceled the file transfer"), xfer->who);
 	}
-	g_free(escaped);
 	gaim_xfer_conversation_write(xfer, msg, TRUE);
 	gaim_xfer_error(gaim_xfer_get_type(xfer), xfer->who, msg);
 	g_free(msg);
--- a/src/gtkblist.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/gtkblist.c	Tue Jan 11 17:25:06 2005 +0000
@@ -2227,8 +2227,10 @@
 	gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val);
 	node = g_value_get_pointer(&val);
 
-	if(!GAIM_BLIST_NODE_IS_CONTACT(node))
+	if(!GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		gtk_tree_path_free(path);
 		return FALSE;
+	}
 
 	gtknode = node->ui_data;
 
@@ -2278,14 +2280,14 @@
 	gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val);
 	node = g_value_get_pointer(&val);
 
+	gtk_tree_path_free(path);
+
 	if(!GAIM_BLIST_NODE_IS_CONTACT(node) && !GAIM_BLIST_NODE_IS_BUDDY(node)
 			&& !GAIM_BLIST_NODE_IS_CHAT(node))
 		return FALSE;
 
 	gtknode = node->ui_data;
 
-	gtk_tree_path_free(path);
-
 	tooltiptext = gaim_get_tooltip_text(node);
 
 	if(!tooltiptext)
@@ -3634,9 +3636,13 @@
 	if(node->parent)
 		gaim_gtk_blist_update(list, node->parent);
 
-	/* There's something I don't understand here */
-	/* g_free(node->ui_data);
-	node->ui_data = NULL; */
+	/* There's something I don't understand here - Ethan */
+	/* Ethan said that back in 2003, but this g_free has been left commented
+	 * out ever since. I can't find any reason at all why this is bad and
+	 * valgrind found several reasons why it's good. If this causes problems
+	 * comment it out again. Stu */
+	g_free(node->ui_data);
+	node->ui_data = NULL;
 }
 
 static gboolean do_selection_changed(GaimBlistNode *new_selection)
--- a/src/gtkconn.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/gtkconn.c	Tue Jan 11 17:25:06 2005 +0000
@@ -112,7 +112,7 @@
 {
 	GtkTreeIter iter;
 	GtkTreeSelection *sel;
-	const char *label_text;
+	char *label_text;
 	GaimAccount *account = NULL;
 
 	if ((disconnect_window == NULL) || (model == NULL))
@@ -161,6 +161,7 @@
 		gtk_widget_hide(disconnect_window->reconnect_btn);
 	else
 		gtk_widget_show(disconnect_window->reconnect_btn);
+	g_free(label_text);
 }
 
 static void disconnect_response_cb(GtkDialog *dialog, gint id, GtkWidget *widget)
--- a/src/gtkconv.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/gtkconv.c	Tue Jan 11 17:25:06 2005 +0000
@@ -1300,7 +1300,7 @@
 	GtkTreeIter iter;
 	GtkTreeModel *model;
 	GtkTreeSelection *sel;
-	const char *name;
+	char *name;
 
 	chat    = GAIM_CONV_CHAT(conv);
 	gtkconv = GAIM_GTK_CONVERSATION(conv);
@@ -1322,6 +1322,7 @@
 		gaim_conv_chat_ignore(chat, name);
 
 	add_chat_buddy_common(conv, name);
+	g_free(name);
 }
 
 static void
@@ -1396,7 +1397,7 @@
 }
 
 static GtkWidget *
-create_chat_menu(GaimConversation *conv, gchar *who,
+create_chat_menu(GaimConversation *conv, const char *who,
 				 GaimPluginProtocolInfo *prpl_info, GaimConnection *gc)
 {
 	static GtkWidget *menu = NULL;
@@ -1413,14 +1414,14 @@
 
 	button = gaim_new_item_from_stock(menu, _("IM"), GAIM_STOCK_IM,
 				G_CALLBACK(menu_chat_im_cb), conv, 0, 0, NULL);
-	g_object_set_data(G_OBJECT(button), "user_data", who);
+	g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 
 	if (gc && prpl_info && prpl_info->send_file
 			&& (!prpl_info->can_receive_file || prpl_info->can_receive_file(gc, who))) {
 		button = gaim_new_item_from_stock(menu, _("Send File"), 
 			GAIM_STOCK_FILE_TRANSFER, G_CALLBACK(menu_chat_send_file_cb),
 			conv, 0, 0, NULL);
-		g_object_set_data(G_OBJECT(button), "user_data", who);
+		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 	}
 
 	if (gaim_conv_chat_is_user_ignored(GAIM_CONV_CHAT(conv), who))
@@ -1429,18 +1430,18 @@
 	else
 		button = gaim_new_item_from_stock(menu, _("Ignore"), GAIM_STOCK_IGNORE,
 						G_CALLBACK(ignore_cb), conv, 0, 0, NULL);
-	g_object_set_data(G_OBJECT(button), "user_data", who);
+	g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 
 	if (gc && (prpl_info->get_info || prpl_info->get_cb_info)) {
 		button = gaim_new_item_from_stock(menu, _("Info"), GAIM_STOCK_INFO,
 						G_CALLBACK(menu_chat_info_cb), conv, 0, 0, NULL);
-		g_object_set_data(G_OBJECT(button), "user_data", who);
+		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 	}
 
 	if (gc && prpl_info->get_cb_away) {
 		button = gaim_new_item_from_stock(menu, _("Get Away Message"), GAIM_STOCK_AWAY,
 					G_CALLBACK(menu_chat_get_away_cb), conv, 0, 0, NULL);
-		g_object_set_data(G_OBJECT(button), "user_data", who);
+		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 	}
 
 	/* XXX: jabber can only add buddies from here in certain circumstances */
@@ -1452,6 +1453,7 @@
 		else
 			button = gaim_new_item_from_stock(menu, _("Add"), GTK_STOCK_ADD,
 						G_CALLBACK(menu_chat_add_remove_cb), conv, 0, 0, NULL);
+		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 	}
 	/* End Jonas */
 
@@ -1492,6 +1494,7 @@
 	gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
 				   gaim_gtk_treeview_popup_menu_position_func, widget,
 				   0, GDK_CURRENT_TIME);
+	g_free(who);
 
 	return TRUE;
 }
@@ -1537,13 +1540,15 @@
 
 	if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
 		chat_do_im(conv, who);
-		g_free(who);
 	} else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
 		GtkWidget *menu = create_chat_menu (conv, who, prpl_info, gc);
 		gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
 					   event->button, event->time);
 	}
 
+	g_free(who);
+	gtk_tree_path_free(path);
+
 	return TRUE;
 }
 
@@ -2342,7 +2347,8 @@
 		g_object_unref(status);
 
 	if (gaim_conv_window_get_active_conversation(win) == conv &&
-		gtkconv->u.im->anim == NULL)
+		(gaim_conversation_get_type(conv) != GAIM_CONV_IM ||
+		 gtkconv->u.im->anim == NULL))
 	{
 		status = get_tab_icon(conv, FALSE);
 
@@ -4798,7 +4804,7 @@
 			str = g_malloc(1024);
 
 			/* If we're whispering, it's not an autoresponse. */
-			if (gaim_message_meify(new_message, length)) {
+			if (gaim_message_meify(new_message, -1 )) {
 				g_snprintf(str, 1024, "***%s", who_escaped);
 				strcpy(color, "#6C2585");
 			}
@@ -4808,7 +4814,7 @@
 			}
 		}
 		else {
-			if (gaim_message_meify(new_message, length)) {
+			if (gaim_message_meify(new_message, -1)) {
 				str = g_malloc(1024);
 
 				if (flags & GAIM_MESSAGE_AUTO_RESP)
@@ -4857,7 +4863,7 @@
 				   "<FONT COLOR=\"%s\" %s><FONT SIZE=\"2\">(%s)</FONT> "
 				   "<B>%s</B></FONT> ", color,
 				   sml_attrib ? sml_attrib : "", mdate, str);
-		
+
 		g_snprintf(buf2, BUF_LONG,
 			   "<FONT COLOR=\"%s\" %s><FONT SIZE=\"2\"><!--(%s) --></FONT>"
 			   "<B>%s</B></FONT> ",
--- a/src/gtkimhtml.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/gtkimhtml.c	Tue Jan 11 17:25:06 2005 +0000
@@ -1355,6 +1355,7 @@
 					return;
 				}
 			}
+			g_strfreev(links);
 			break;
 		case GTK_IMHTML_DRAG_HTML:
 			{
@@ -2345,6 +2346,8 @@
 							ws[0] = '\0'; wpos = 0;
 							gtk_imhtml_toggle_link(imhtml, href);
 						}
+						if (href)
+							g_free(href);
 					}
 					break;
 				case 46:	/* IMG (opt) */
--- a/src/gtkimhtmltoolbar.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/gtkimhtmltoolbar.c	Tue Jan 11 17:25:06 2005 +0000
@@ -170,7 +170,7 @@
 static void
 toggle_font(GtkWidget *font, GtkIMHtmlToolbar *toolbar)
 {
-	const char *fontname;
+	char *fontname;
 
 	g_return_if_fail(toolbar);
 
@@ -186,6 +186,7 @@
 			g_snprintf(fonttif, sizeof(fonttif), "%s 12", fontname);
 			gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog),
 													fonttif);
+			g_free(fontname);
 		} else {
 			gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog),
 													DEFAULT_FONT_FACE);
@@ -251,7 +252,7 @@
 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(color))) {
 		GtkWidget *colorsel;
 		GdkColor fgcolor;
-		const char *color = gtk_imhtml_get_current_forecolor(GTK_IMHTML(toolbar->imhtml));
+		char *color = gtk_imhtml_get_current_forecolor(GTK_IMHTML(toolbar->imhtml));
 
 		if (!toolbar->fgcolor_dialog) {
 
@@ -260,6 +261,7 @@
 			if (color) {
 				gdk_color_parse(color, &fgcolor);
 				gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &fgcolor);
+				g_free(color);
 			}
 
 			g_object_set_data(G_OBJECT(colorsel), "gaim_toolbar", toolbar);
@@ -325,7 +327,7 @@
 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(color))) {
 		GtkWidget *colorsel;
 		GdkColor bgcolor;
-		const char *color = gtk_imhtml_get_current_backcolor(GTK_IMHTML(toolbar->imhtml));
+		char *color = gtk_imhtml_get_current_backcolor(GTK_IMHTML(toolbar->imhtml));
 
 		if (!toolbar->bgcolor_dialog) {
 
@@ -334,6 +336,7 @@
 			if (color) {
 				gdk_color_parse(color, &bgcolor);
 				gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &bgcolor);
+				g_free(color);
 			}
 
 			g_object_set_data(G_OBJECT(colorsel), "gaim_toolbar", toolbar);
--- a/src/gtkstatusselector.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/gtkstatusselector.c	Tue Jan 11 17:25:06 2005 +0000
@@ -234,7 +234,7 @@
 }
 
 static gboolean
-get_selected_data(GaimGtkStatusSelector *selector, const char **text, const char **status_type_id)
+get_selected_data(GaimGtkStatusSelector *selector, char **text, const char **status_type_id)
 {
 #if GTK_CHECK_VERSION(2,4,0)
 	GtkTreeIter iter;
@@ -256,7 +256,7 @@
 	i = gtk_option_menu_get_history(GTK_OPTION_MENU(selector->priv->optmenu));
 	l = GTK_MENU_SHELL(selector->priv->menu)->children;
 	item = g_list_nth_data(l, i);
-	*text = g_object_get_data(G_OBJECT(item), GAIM_SELECTOR_TEXT);
+	*text = g_strdup(g_object_get_data(G_OBJECT(item), GAIM_SELECTOR_TEXT));
 	*status_type_id = g_object_get_data(G_OBJECT(item), GAIM_SELECTOR_STATUS_TYPE_ID);
 	return TRUE;
 #endif
@@ -270,7 +270,7 @@
 status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector)
 {
 	const char *status_type_id = NULL;
-	const char *text = NULL;
+	char *text = NULL;
 
 	/* Reset the status selector */
 	if (selector->priv->entry_timer != 0)
@@ -334,6 +334,7 @@
 			key_press_cb(NULL, NULL, selector);
 		}
 	}
+	g_free(text);
 }
 
 /**
@@ -348,7 +349,7 @@
 {
 	GaimGtkStatusSelector *selector = (GaimGtkStatusSelector *)data;
 	const char *status_type_id;
-	const char *text;
+	char *text;
 	gchar *message;
 	GList *l;
 
@@ -358,7 +359,10 @@
 		return FALSE;
 
 	if (status_type_id == NULL)
+	{
+		g_free(text);
 		return FALSE;
+	}
 
 	message = gtk_imhtml_get_markup(GTK_IMHTML(selector->priv->entry));
 
@@ -385,6 +389,9 @@
 		}
 	}
 
+	g_free(text);
+	g_free(message);
+
 	return FALSE;
 }
 
--- a/src/gtkutils.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/gtkutils.c	Tue Jan 11 17:25:06 2005 +0000
@@ -300,18 +300,20 @@
 gaim_pixbuf_button_from_stock(const char *text, const char *icon,
 							  GaimButtonOrientation style)
 {
-	GtkWidget *button, *image, *label, *bbox, *ibox, *lbox;
+	GtkWidget *button, *image, *label, *bbox, *ibox, *lbox = NULL;
 
 	button = gtk_button_new();
 
 	if (style == GAIM_BUTTON_HORIZONTAL) {
 		bbox = gtk_hbox_new(FALSE, 0);
 		ibox = gtk_hbox_new(FALSE, 0);
-		lbox = gtk_hbox_new(FALSE, 0);
+		if (text)
+			lbox = gtk_hbox_new(FALSE, 0);
 	} else {
 		bbox = gtk_vbox_new(FALSE, 0);
 		ibox = gtk_vbox_new(FALSE, 0);
-		lbox = gtk_vbox_new(FALSE, 0);
+		if (text)
+			lbox = gtk_vbox_new(FALSE, 0);
 	}
 
 	gtk_container_add(GTK_CONTAINER(button), bbox);
--- a/src/plugin.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/plugin.c	Tue Jan 11 17:25:06 2005 +0000
@@ -30,16 +30,6 @@
 #include "signals.h"
 #include "version.h"
 
-#ifdef _WIN32
-# define PLUGIN_EXT ".dll"
-#else
-# ifdef __hpux
-#  define PLUGIN_EXT ".sl"
-# else
-#  define PLUGIN_EXT ".so"
-# endif
-#endif
-
 typedef struct
 {
 	GHashTable *commands;
@@ -182,7 +172,7 @@
 	if (plugin != NULL)
 		return plugin;
 
-	plugin = gaim_plugin_new(has_file_extension(filename, PLUGIN_EXT), filename);
+	plugin = gaim_plugin_new(has_file_extension(filename, GAIM_PLUGIN_EXT), filename);
 
 	if (plugin->native_plugin) {
 		const char *error;
--- a/src/plugin.h	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/plugin.h	Tue Jan 11 17:25:06 2005 +0000
@@ -30,6 +30,16 @@
 #include "signals.h"
 #include "value.h"
 
+#ifdef _WIN32
+# define GAIM_PLUGIN_EXT ".dll"
+#else
+# ifdef __hpux
+#  define GAIM_PLUGIN_EXT ".sl"
+# else
+#  define GAIM_PLUGIN_EXT ".so"
+# endif
+#endif
+
 typedef struct _GaimPlugin           GaimPlugin;
 typedef struct _GaimPluginInfo       GaimPluginInfo;
 typedef struct _GaimPluginUiInfo     GaimPluginUiInfo;
--- a/src/protocols/irc/irc.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/irc/irc.c	Tue Jan 11 17:25:06 2005 +0000
@@ -399,6 +399,7 @@
 		gaim_timeout_remove(irc->timer);
 	g_hash_table_destroy(irc->cmds);
 	g_hash_table_destroy(irc->msgs);
+	g_hash_table_destroy(irc->buddies);
 	if (irc->motd)
 		g_string_free(irc->motd, TRUE);
 	g_free(irc->server);
@@ -435,10 +436,13 @@
 	const char *args[1];
 	const char *status_id = gaim_status_get_id(status);
 
+	if (!gaim_status_is_active(status))
+		return;
+
+	args[0] = NULL;
+
 	if (!strcmp(status_id, "away"))
 		args[0] = gaim_status_get_attr_string(status, "message");
-	else if (!strcmp(status_id, "available"))
-		args[0] = NULL;
 
 	irc_cmd_away(irc, "away", NULL, args);
 }
--- a/src/protocols/irc/msgs.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/irc/msgs.c	Tue Jan 11 17:25:06 2005 +0000
@@ -224,6 +224,7 @@
 			   _("Buddy Information for %s"), irc->whois.nick);
 	gaim_notify_userinfo(gc, irc->whois.nick, NULL, buffer, NULL, str, NULL, NULL);
 
+	g_free(irc->whois.nick);
 	g_free(str);
 	memset(&irc->whois, 0, sizeof(irc->whois));
 }
@@ -736,6 +737,7 @@
 	buf = irc_format(irc, "vn", "NICK", newnick);
 	irc_send(irc, buf);
 	g_free(buf);
+	g_free(newnick);
 }
 
 void irc_msg_notice(struct irc_conn *irc, const char *name, const char *from, char **args)
--- a/src/protocols/irc/parse.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/irc/parse.c	Tue Jan 11 17:25:06 2005 +0000
@@ -235,8 +235,10 @@
 	enclist = gaim_account_get_string(irc->account, "encoding", IRC_DEFAULT_CHARSET);
 	encodings = g_strsplit(enclist, ",", -1);
 
-	if (encodings[0] == NULL)
+	if (encodings[0] == NULL) {
+		g_strfreev(encodings);
 		return gaim_utf8_salvage(string);
+	}
 
 	for (i = 0; encodings[i] != NULL; i++) {
 		charset = encodings[i];
@@ -255,6 +257,7 @@
 			return utf8;
 		}
 	}
+	g_strfreev(encodings);
 
 	return gaim_utf8_salvage(string);
 }
--- a/src/protocols/jabber/buddy.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/jabber/buddy.c	Tue Jan 11 17:25:06 2005 +0000
@@ -402,7 +402,7 @@
 				xmlnode_insert_data(photo, enc, -1);
 				g_free(enc);
 				g_free(avatar_data);
-			} else {
+			} else if (error != NULL) {
 				g_error_free(error);
 			}
 
--- a/src/protocols/jabber/chat.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/jabber/chat.c	Tue Jan 11 17:25:06 2005 +0000
@@ -302,6 +302,8 @@
 
 	g_free(chat->room);
 	g_free(chat->server);
+	g_free(chat->handle);
+	g_hash_table_destroy(chat->members);
 	g_free(chat);
 }
 
--- a/src/protocols/jabber/jabber.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/jabber/jabber.c	Tue Jan 11 17:25:06 2005 +0000
@@ -109,6 +109,7 @@
 			}
 			if((my_jb = jabber_buddy_find(js, full_jid, TRUE)))
 				my_jb->subscription |= JABBER_SUB_BOTH;
+			g_free(full_jid);
 		}
 	} else {
 		char *msg = jabber_parse_error(js, packet);
--- a/src/protocols/msn/cmdproc.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/cmdproc.c	Tue Jan 11 17:25:06 2005 +0000
@@ -49,6 +49,10 @@
 	g_queue_free(cmdproc->txqueue);
 
 	msn_history_destroy(cmdproc->history);
+
+	if (cmdproc->last_cmd != NULL)
+		msn_command_destroy(cmdproc->last_cmd);
+
 	g_free(cmdproc);
 }
 
--- a/src/protocols/msn/httpconn.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/httpconn.c	Tue Jan 11 17:25:06 2005 +0000
@@ -68,6 +68,15 @@
 	if (httpconn->connected)
 		msn_httpconn_disconnect(httpconn);
 
+	if (httpconn->full_session_id != NULL)
+		g_free(httpconn->full_session_id);
+
+	if (httpconn->session_id != NULL)
+		g_free(httpconn->session_id);
+
+	if (httpconn->host != NULL)
+		g_free(httpconn->host);
+
 	g_free(httpconn);
 }
 
@@ -669,17 +678,17 @@
 
 		if (!wasted)
 		{
-			if (httpconn->full_session_id != NULL);
+			if (httpconn->full_session_id != NULL)
 				g_free(httpconn->full_session_id);
 
 			httpconn->full_session_id = full_session_id;
 
-			if (httpconn->session_id != NULL);
+			if (httpconn->session_id != NULL)
 				g_free(httpconn->session_id);
 
 			httpconn->session_id = session_id;
 
-			if (httpconn->host != NULL);
+			if (httpconn->host != NULL)
 				g_free(httpconn->host);
 
 			httpconn->host = gw_ip;
@@ -689,6 +698,7 @@
 			MsnServConn *servconn;
 
 			/* It's going to die. */
+			/* poor thing */
 
 			servconn = httpconn->servconn;
 
@@ -696,6 +706,7 @@
 				servconn->wasted = TRUE;
 
 			g_free(full_session_id);
+			g_free(session_id);
 			g_free(gw_ip);
 		}
 	}
--- a/src/protocols/msn/msn.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/msn.c	Tue Jan 11 17:25:06 2005 +0000
@@ -47,8 +47,6 @@
 #include "imgstore.h"
 #endif
 
-#define BUDDY_ALIAS_MAXLEN 387
-
 typedef struct
 {
 	GaimConnection *gc;
--- a/src/protocols/msn/msn.h	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/msn.h	Tue Jan 11 17:25:06 2005 +0000
@@ -69,6 +69,7 @@
 
 #define USEROPT_HOTMAIL 0
 
+#define BUDDY_ALIAS_MAXLEN 387
 
 #define MSN_FT_GUID "{5D3E02AB-6190-11d3-BBBB-00C04F795683}"
 
--- a/src/protocols/msn/nexus.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/nexus.c	Tue Jan 11 17:25:06 2005 +0000
@@ -132,7 +132,8 @@
 	session = nexus->session;
 	g_return_if_fail(session != NULL);
 
-	msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);
+	if (!session->logged_in)
+		msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);
 
 	username =
 		g_strdup(gaim_url_encode(gaim_account_get_username(session->account)));
@@ -312,7 +313,8 @@
 	session = nexus->session;
 	g_return_if_fail(session != NULL);
 
-	msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH);
+	if (!session->logged_in)
+		msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH);
 
 	request_str = g_strdup_printf("GET /rdr/pprdr.asp\r\n\r\n");
 
--- a/src/protocols/msn/notification.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/notification.c	Tue Jan 11 17:25:06 2005 +0000
@@ -111,7 +111,8 @@
 
 	vers = g_strjoinv(" ", a);
 
-	msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE);
+	if (!session->logged_in)
+		msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE);
 	msn_cmdproc_send(cmdproc, "VER", "%s", vers);
 
 	g_strfreev(a);
@@ -199,7 +200,8 @@
 
 	cmdproc = session->notification->cmdproc;
 
-	msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_END);
+	if (!session->logged_in)
+		msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_END);
 
 	msn_cmdproc_send(cmdproc, "USR", "TWN S %s", login_params);
 }
@@ -233,7 +235,8 @@
 
 		gaim_connection_set_display_name(gc, friendly);
 
-		msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN);
+		if (!session->logged_in)
+			msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN);
 
 		msn_cmdproc_send(cmdproc, "SYN", "%s", "0");
 	}
@@ -258,7 +261,8 @@
 
 		g_strfreev(elems);
 
-		msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_START);
+		if (!session->logged_in)
+			msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_START);
 
 		msn_nexus_connect(session->nexus);
 	}
--- a/src/protocols/msn/session.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/session.c	Tue Jan 11 17:25:06 2005 +0000
@@ -364,6 +364,9 @@
 	account = session->account;
 	gc = gaim_account_get_connection(account);
 
+	if (session->logged_in)
+		return;
+
 	msn_user_set_buddy_icon(session->user,
 							gaim_account_get_buddy_icon(session->account));
 
--- a/src/protocols/msn/slpcall.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/slpcall.c	Tue Jan 11 17:25:06 2005 +0000
@@ -192,9 +192,9 @@
 {
 	MsnSlpCall *slpcall;
 
-	gaim_debug_info("msn", "slpcall timeout (%p)\n", slpcall);
+	slpcall = data;
 
-	slpcall = data;
+	gaim_debug_info("msn", "slpcall timeout (%p)\n", slpcall);
 
 	if (!slpcall->pending && !slpcall->progress)
 	{
--- a/src/protocols/msn/switchboard.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/switchboard.c	Tue Jan 11 17:25:06 2005 +0000
@@ -354,9 +354,8 @@
 
 	if (msg->type == MSN_MSG_TEXT)
 	{
-		const char *format;
+		const char *format, *str_reason;
 		char *body_str, *body_enc, *pre, *post;
-		char *str_reason;
 
 #if 0
 		if (swboard->conv == NULL)
@@ -622,21 +621,9 @@
 	{
 		/* This is a switchboard used for a im session */
 
-		char *str = NULL;
-
-		if (cmd->param_count == 2 && atoi(cmd->params[1]) == 1)
+		if (cmd->param_count == 1)
 		{
-#if 0
-			if (gaim_prefs_get_bool("/plugins/prpl/msn/conv_timeout_notice"))
-			{
-				str = g_strdup_printf(_("The conversation has become "
-										"inactive and timed out."));
-			}
-#endif
-		}
-		else
-		{
-			char *username;
+			char *username, *str;
 			GaimAccount *account;
 			GaimBuddy *b;
 
@@ -647,16 +634,14 @@
 			else
 				username = gaim_escape_html(user);
 
-			str = g_strdup_printf(_("%s has closed the conversation "
-						"window."), username);
-		      
+			str = g_strdup_printf(_("%s has closed the conversation window."),
+								  username);
+
 			g_free(username);
-			
+			msn_switchboard_report_user(swboard, GAIM_MESSAGE_SYSTEM, str);
+			g_free(str);
 		}
 
-		if (str != NULL)
-			msn_switchboard_report_user(swboard, GAIM_MESSAGE_SYSTEM, str);
-
 		msn_switchboard_destroy(swboard);
 	}
 }
--- a/src/protocols/msn/userlist.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/msn/userlist.c	Tue Jan 11 17:25:06 2005 +0000
@@ -466,6 +466,7 @@
 msn_userlist_remove_group(MsnUserList *userlist, MsnGroup *group)
 {
 	userlist->groups = g_list_remove(userlist->groups, group);
+	msn_group_destroy(group);
 }
 
 MsnGroup *
@@ -629,6 +630,13 @@
 
 	store_name = (user != NULL) ? get_store_name(user) : who;
 
+	/* this might be a bit of a hack, but it should prevent notification server
+	 * disconnections for people who have buddies with insane friendly names
+	 * who added you to their buddy list from being disconnected. Stu. */
+	/* ... No, that sentence didn't parse for me either. Stu. */
+	if (strlen(store_name) > BUDDY_ALIAS_MAXLEN)
+		store_name = who;
+
 	/* Then request the add to the server. */
 	list = lists[list_id];
 
--- a/src/protocols/oscar/msgcookie.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/oscar/msgcookie.c	Tue Jan 11 17:25:06 2005 +0000
@@ -144,7 +144,7 @@
 /**
  * aim_cookie_free - free an aim_msgcookie_t struct
  *
- * this function removes the cookie *cookie from teh list of cookies
+ * this function removes the cookie *cookie from the list of cookies
  * in sess, and then frees all memory associated with it. including
  * its data! if you want to use the private data after calling this,
  * make sure you copy it first.
--- a/src/protocols/oscar/oscar.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/oscar/oscar.c	Tue Jan 11 17:25:06 2005 +0000
@@ -1251,7 +1251,8 @@
 		/* for each valid image tag... */
 		while (gaim_markup_find_tag("img", tmp, &start, &end, &attribs)) {
 			const char *id, *src, *datasize;
-			const char *tag = NULL, *data = NULL;
+			const char *data = NULL;
+			char *tag = NULL;
 			size_t size;
 			int imgid = 0;
 
@@ -1271,6 +1272,8 @@
 			if (tag && (data = gaim_strcasestr(binary, tag)))
 				data += strlen(tag);
 
+			g_free(tag);
+
 			/* check the data is here and store it */
 			if (data + (size = atoi(datasize)) <= msgend)
 				imgid = gaim_imgstore_add(data, size, src);
--- a/src/protocols/yahoo/util.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/yahoo/util.c	Tue Jan 11 17:25:06 2005 +0000
@@ -48,7 +48,7 @@
 {
 	struct yahoo_data *yd = gc->proto_data;
 	char *ret;
-	char *to_codeset;
+	const char *to_codeset;
 
 	if (yd->jp && utf8 && *utf8)
 		*utf8 = FALSE;
--- a/src/protocols/yahoo/yahoo.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/yahoo/yahoo.c	Tue Jan 11 17:25:06 2005 +0000
@@ -2841,10 +2841,16 @@
 
 	yahoo_packet_hash_int(pkt, 10, yd->current_status);
 	if (yd->current_status == YAHOO_STATUS_CUSTOM) {
+		const char *tmp;
 		GaimStatus *status = gaim_presence_get_active_status(gaim_account_get_presence(gaim_connection_get_account(gc)));
-		msg = yahoo_string_encode(gc, gaim_status_get_attr_string(status, "message"), NULL); //this line crashes, fix it
-		msg2 = gaim_unescape_html(msg);
-		yahoo_packet_hash_str(pkt, 19, msg2);
+		tmp = gaim_status_get_attr_string(status, "message");
+		if (tmp != NULL) {
+			msg = yahoo_string_encode(gc, tmp, NULL);
+			msg2 = gaim_unescape_html(msg);
+			yahoo_packet_hash_str(pkt, 19, msg2);
+		} else {
+			yahoo_packet_hash_str(pkt, 19, "");
+		}
 	} else {
 		yahoo_packet_hash_str(pkt, 19, "");
 	}
--- a/src/protocols/yahoo/yahoochat.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/protocols/yahoo/yahoochat.c	Tue Jan 11 17:25:06 2005 +0000
@@ -1065,6 +1065,7 @@
 		g_free(yrl->host);
 	if (yrl->parse)
 		g_markup_parse_context_free(yrl->parse);
+	g_free(yrl);
 }
 
 enum yahoo_room_type {
--- a/src/status.c	Tue Jan 11 02:00:44 2005 +0000
+++ b/src/status.c	Tue Jan 11 17:25:06 2005 +0000
@@ -1031,7 +1031,7 @@
 	g_return_val_if_fail(id     != NULL, FALSE);
 
 	if ((value = gaim_status_get_attr_value(status, id)) == NULL)
-		return FALSE;
+		return NULL;
 
 	g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL);