changeset 23602:aaaff38e144f

Fix a double free when connecting to the sender of a bonjour file fails. Also plug a small leak. Fixes #5971.
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 17 Jul 2008 04:38:07 +0000
parents d3fad795bba5
children 05d3447fb34e
files ChangeLog.win32 libpurple/Makefile.mingw libpurple/connection.c libpurple/example/nullclient.c libpurple/protocols/Makefile.mingw libpurple/protocols/bonjour/bonjour_ft.c libpurple/protocols/jabber/Makefile.mingw libpurple/protocols/jabber/caps.c libpurple/protocols/jabber/caps.h libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/jabber.h libpurple/protocols/jabber/pep.c libpurple/protocols/msn/msn.c libpurple/protocols/msn/msn.h libpurple/protocols/msn/user.c libpurple/protocols/oscar/Makefile.mingw libpurple/protocols/silc/Makefile.mingw libpurple/protocols/yahoo/yahoo.c libpurple/protocols/zephyr/ZSendPkt.c pidgin/gtkblist.h pidgin/gtkcertmgr.c pidgin/gtkdocklet.c pidgin/gtkstatusbox.c pidgin/minidialog.c pidgin/plugins/win32/winprefs/gtkappbar.h pidgin/win32/winpidgin.c po/Makefile.mingw po/pl.po
diffstat 28 files changed, 168 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.win32	Wed Jul 16 09:16:52 2008 +0000
+++ b/ChangeLog.win32	Thu Jul 17 04:38:07 2008 +0000
@@ -1,5 +1,5 @@
 version 2.4.3 (07/01/2008):
-	* No changes
+	* Upgrade SILC to use the 1.1.7 toolkit
 
 version 2.4.2 (05/17/2008):
 	* No changes
--- a/libpurple/Makefile.mingw	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/Makefile.mingw	Thu Jul 17 04:38:07 2008 +0000
@@ -123,7 +123,7 @@
 $(OBJECTS): $(PURPLE_CONFIG_H) $(PURPLE_VERSION_H) $(PURPLE_PURPLE_H)
 
 $(TARGET).dll $(TARGET).dll.a: $(OBJECTS)
-	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--output-def,$(TARGET).def,--out-implib,$(TARGET).dll.a -o $(TARGET).dll
+	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--output-def,$(TARGET).def,--out-implib,$(TARGET).dll.a,--exclude-libs -o $(TARGET).dll
 
 ##
 ## CLEAN RULES
--- a/libpurple/connection.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/connection.c	Thu Jul 17 04:38:07 2008 +0000
@@ -534,6 +534,9 @@
 	if (gc->disconnect_timeout)
 		return;
 
+	purple_debug_info("connection", "Disconnecting connection %p with reason %s (%d)\n",
+					  gc, description, reason);
+
 	gc->wants_to_die = purple_connection_error_is_fatal (reason);
 
 	ops = purple_connections_get_ui_ops();
--- a/libpurple/example/nullclient.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/example/nullclient.c	Thu Jul 17 04:38:07 2008 +0000
@@ -27,7 +27,12 @@
 
 #include <signal.h>
 #include <string.h>
+#ifndef _WIN32
 #include <unistd.h>
+#else
+#include "win32/win32dep.h"
+#endif
+
 
 #include "defines.h"
 
@@ -80,7 +85,11 @@
 	if (condition & PURPLE_INPUT_WRITE)
 		cond |= PURPLE_GLIB_WRITE_COND;
 
+#if defined _WIN32 && !defined WINPIDGIN_USE_GLIB_IO_CHANNEL
+	channel = wpurple_g_io_channel_win32_new_socket(fd);
+#else
 	channel = g_io_channel_unix_new(fd);
+#endif
 	closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
 					      purple_glib_io_invoke, closure, purple_glib_io_destroy);
 
@@ -253,12 +262,14 @@
 	PurpleSavedStatus *status;
 	char *res;
 
+#ifndef _WIN32
 	/* libpurple's built-in DNS resolution forks processes to perform
 	 * blocking lookups without blocking the main process.  It does not
 	 * handle SIGCHLD itself, so if the UI does not you quickly get an army
 	 * of zombie subprocesses marching around.
 	 */
 	signal(SIGCHLD, SIG_IGN);
+#endif
 
 	init_libpurple();
 
@@ -294,7 +305,8 @@
 	account = purple_account_new(name, prpl);
 
 	/* Get the password for the account */
-	password = getpass("Password: ");
+	//password = getpass("Password: ");
+	password = "";
 	purple_account_set_password(account, password);
 
 	/* It's necessary to enable the account first. */
--- a/libpurple/protocols/Makefile.mingw	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/Makefile.mingw	Thu Jul 17 04:38:07 2008 +0000
@@ -8,7 +8,7 @@
 PIDGIN_TREE_TOP := ../..
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
-SUBDIRS = gg irc jabber msnp9 novell null oscar qq sametime silc simple yahoo bonjour myspace
+SUBDIRS = gg irc jabber msn novell null oscar qq sametime silc simple yahoo bonjour myspace
 
 .PHONY: all install clean
 
--- a/libpurple/protocols/bonjour/bonjour_ft.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.c	Thu Jul 17 04:38:07 2008 +0000
@@ -300,6 +300,8 @@
 		}
 		if (xf->proxy_connection != NULL)
 			purple_proxy_connect_cancel(xf->proxy_connection);
+		if (xf->proxy_info != NULL)
+			purple_proxy_info_destroy(xf->proxy_info);
 		if (xf->listen_data != NULL)
 			purple_network_listen_cancel(xf->listen_data);
 		g_free(xf->iq_id);
@@ -802,6 +804,8 @@
 	xmlnode *q_node, *tmp_node;
 	BonjourData *bd;
 
+	xf->proxy_connection = NULL;
+
 	if(source < 0) {
 		purple_debug_error("bonjour", "Error connecting via SOCKS5 - %s\n",
 			error_message ? error_message : "(null)");
@@ -815,9 +819,6 @@
 
 	bd = xf->data;
 
-	purple_proxy_info_destroy(xf->proxy_info);
-	xf->proxy_connection = NULL;
-	xf->proxy_info = NULL;
 	/* Here, start the file transfer.*/
 
 	/* Notify Initiator of Connection */
@@ -871,8 +872,6 @@
 		xep_ft_si_reject(xf->data, xf->iq_id, xfer->who, "404", "cancel");
 		/* Cancel the connection */
 		purple_xfer_cancel_local(xfer);
-		/*purple_proxy_info_destroy(xf->proxy_info);
-		xf->proxy_info = NULL;*/
 	}
 }
 
--- a/libpurple/protocols/jabber/Makefile.mingw	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/jabber/Makefile.mingw	Thu Jul 17 04:38:07 2008 +0000
@@ -125,7 +125,7 @@
 $(OBJECTS): $(PURPLE_CONFIG_H)
 
 $(TARGET).dll $(TARGET).dll.a: $(PURPLE_DLL).a $(OBJECTS)
-	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--out-implib,$(TARGET).dll.a -o $(TARGET).dll
+	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--output-def,$(TARGET).def,--out-implib,$(TARGET).dll.a -o $(TARGET).dll
 
 $(XMPP_TARGET).dll: $(TARGET).dll.a $(XMPP_OBJECTS)
 	$(CC) -shared $(XMPP_OBJECTS) $(LIB_PATHS) $(LIBS) -ljabber $(DLL_LD_FLAGS) -o $(XMPP_TARGET).dll
--- a/libpurple/protocols/jabber/caps.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/jabber/caps.c	Thu Jul 17 04:38:07 2008 +0000
@@ -113,6 +113,11 @@
 	jabber_caps_load();
 }
 
+void jabber_caps_uninit(void) {
+	g_hash_table_destroy(capstable);
+	capstable = NULL;
+}
+
 static void jabber_caps_load(void) {
 	xmlnode *capsdata = purple_util_read_xml_from_file(JABBER_CAPS_FILENAME, "XMPP capabilities cache");
 	xmlnode *client;
--- a/libpurple/protocols/jabber/caps.h	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/jabber/caps.h	Thu Jul 17 04:38:07 2008 +0000
@@ -42,6 +42,7 @@
 typedef void (*jabber_caps_get_info_cb)(JabberCapsClientInfo *info, gpointer user_data);
 
 void jabber_caps_init(void);
+void jabber_caps_uninit(void);
 
 void jabber_caps_get_info(JabberStream *js, const char *who, const char *node, const char *ver, const char *ext, jabber_caps_get_info_cb cb, gpointer user_data);
 void jabber_caps_free_clientinfo(JabberCapsClientInfo *clientinfo);
--- a/libpurple/protocols/jabber/jabber.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Thu Jul 17 04:38:07 2008 +0000
@@ -61,6 +61,7 @@
 
 static PurplePlugin *my_protocol = NULL;
 GList *jabber_features = NULL;
+static GSList *registered_commands = NULL;
 
 static void jabber_unregister_account_cb(JabberStream *js);
 
@@ -1390,6 +1391,15 @@
 	js->idle = idle ? time(NULL) - idle : idle;
 }
 
+void jabber_features_uninit(void) {
+	for(; jabber_features; jabber_features = g_list_delete_link(jabber_features, jabber_features)) {
+		JabberFeature *feat = (JabberFeature*)jabber_features->data;
+		g_free(feat->shortname);
+		g_free(feat->namespace);
+		g_free(feat);
+	}
+}
+
 void jabber_add_feature(const char *shortname, const char *namespace, JabberFeatureEnabled cb) {
 	JabberFeature *feat;
 
@@ -2338,88 +2348,126 @@
 	return TRUE;
 }
 
+void jabber_unregister_commands(void) {
+	for(; registered_commands; registered_commands = g_slist_delete_link(registered_commands, registered_commands)) {
+		purple_cmd_unregister(GPOINTER_TO_INT(registered_commands->data));
+	}
+}
+
 void jabber_register_commands(void)
 {
-	purple_cmd_register("config", "", PURPLE_CMD_P_PRPL,
+	PurpleCmdId cid;
+
+	cid = purple_cmd_register("config", "", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
 	                  "prpl-jabber", jabber_cmd_chat_config,
 	                  _("config:  Configure a chat room."), NULL);
-	purple_cmd_register("configure", "", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("configure", "", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
 	                  "prpl-jabber", jabber_cmd_chat_config,
 	                  _("configure:  Configure a chat room."), NULL);
-	purple_cmd_register("nick", "s", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("nick", "s", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
 	                  "prpl-jabber", jabber_cmd_chat_nick,
 	                  _("nick &lt;new nickname&gt;:  Change your nickname."),
 	                  NULL);
-	purple_cmd_register("part", "s", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("part", "s", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_part, _("part [room]:  Leave the room."),
 	                  NULL);
-	purple_cmd_register("register", "", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("register", "", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
 	                  "prpl-jabber", jabber_cmd_chat_register,
 	                  _("register:  Register with a chat room."), NULL);
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
 	/* XXX: there needs to be a core /topic cmd, methinks */
-	purple_cmd_register("topic", "s", PURPLE_CMD_P_PRPL,
+	cid = purple_cmd_register("topic", "s", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_topic,
 	                  _("topic [new topic]:  View or change the topic."),
 	                  NULL);
-	purple_cmd_register("ban", "ws", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("ban", "ws", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_ban,
 	                  _("ban &lt;user&gt; [reason]:  Ban a user from the room."),
 	                  NULL);
-	purple_cmd_register("affiliate", "ws", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("affiliate", "ws", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_affiliate,
 	                  _("affiliate &lt;user&gt; &lt;owner|admin|member|outcast|none&gt;: Set a user's affiliation with the room."),
 	                  NULL);
-	purple_cmd_register("role", "ws", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("role", "ws", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_role,
 	                  _("role &lt;user&gt; &lt;moderator|participant|visitor|none&gt;: Set a user's role in the room."),
 	                  NULL);
-	purple_cmd_register("invite", "ws", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("invite", "ws", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_invite,
 	                  _("invite &lt;user&gt; [message]:  Invite a user to the room."),
 	                  NULL);
-	purple_cmd_register("join", "ws", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("join", "ws", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_join,
 	                  _("join: &lt;room&gt; [password]:  Join a chat on this server."),
 	                  NULL);
-	purple_cmd_register("kick", "ws", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("kick", "ws", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_kick,
 	                  _("kick &lt;user&gt; [reason]:  Kick a user from the room."),
 	                  NULL);
-	purple_cmd_register("msg", "ws", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("msg", "ws", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
 	                  "prpl-jabber", jabber_cmd_chat_msg,
 	                  _("msg &lt;user&gt; &lt;message&gt;:  Send a private message to another user."),
 	                  NULL);
-	purple_cmd_register("ping", "w", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("ping", "w", PURPLE_CMD_P_PRPL,
 					  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM |
 					  PURPLE_CMD_FLAG_PRPL_ONLY,
 					  "prpl-jabber", jabber_cmd_ping,
 					  _("ping &lt;jid&gt;:	Ping a user/component/server."),
 					  NULL);
-	purple_cmd_register("buzz", "s", PURPLE_CMD_P_PRPL,
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
+	cid = purple_cmd_register("buzz", "s", PURPLE_CMD_P_PRPL,
 					  PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY,
 					  "prpl-jabber", jabber_cmd_buzz,
 					  _("buzz: Buzz a user to get their attention"), NULL);
+	if (cid > 0)
+		registered_commands = g_slist_prepend(registered_commands, GINT_TO_POINTER(cid));
 }
 
 void
--- a/libpurple/protocols/jabber/jabber.h	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.h	Thu Jul 17 04:38:07 2008 +0000
@@ -242,6 +242,7 @@
  */
 char *jabber_parse_error(JabberStream *js, xmlnode *packet, PurpleConnectionError *reason);
 
+void jabber_features_uninit(void);
 void jabber_add_feature(const gchar *shortname, const gchar *namespace, JabberFeatureEnabled cb); /* cb may be NULL */
 void jabber_remove_feature(const gchar *shortname);
 
@@ -266,6 +267,7 @@
 int jabber_prpl_send_raw(PurpleConnection *gc, const char *buf, int len);
 GList *jabber_actions(PurplePlugin *plugin, gpointer context);
 void jabber_register_commands(void);
+void jabber_unregister_commands(void);
 void jabber_init_plugin(PurplePlugin *plugin);
 
 #endif /* _PURPLE_JABBER_H_ */
--- a/libpurple/protocols/jabber/pep.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/jabber/pep.c	Thu Jul 17 04:38:07 2008 +0000
@@ -39,6 +39,13 @@
 	}
 }
 
+void jabber_pep_uninit(void) {
+	/* TODO: This should be removing the feature registered by jabber_add_feature(),
+	 * but I don't see a good way of doing that right now. */
+	g_hash_table_destroy(pep_handlers);
+	pep_handlers = NULL;
+}
+
 void jabber_pep_init_actions(GList **m) {
 	/* register the PEP-specific actions */
 	jabber_mood_init_action(m);
--- a/libpurple/protocols/msn/msn.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/msn/msn.c	Thu Jul 17 04:38:07 2008 +0000
@@ -1343,6 +1343,7 @@
 
 	if (group_id >= 0)
 	{
+		/* This is wrong... user->group_ids contains g_strdup()'d data now */
 		user->group_ids = g_list_append(user->group_ids,
 										GINT_TO_POINTER(group_id));
 	}
--- a/libpurple/protocols/msn/msn.h	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/msn/msn.h	Thu Jul 17 04:38:07 2008 +0000
@@ -28,7 +28,7 @@
 /* #define MSN_DEBUG_SLPMSG 1 */
 /* #define MSN_DEBUG_HTTP 1 */
 
-/* #define MSN_DEBUG_SLP 1 */
+#define MSN_DEBUG_SLP 1
 /* #define MSN_DEBUG_SLP_VERBOSE 1 */
 /* #define MSN_DEBUG_SLP_FILES 1 */
 
--- a/libpurple/protocols/msn/user.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/msn/user.c	Thu Jul 17 04:38:07 2008 +0000
@@ -235,21 +235,19 @@
 
 /*add group id to User object*/
 void
-msn_user_add_group_id(MsnUser *user, const char* id)
+msn_user_add_group_id(MsnUser *user, const char* group_id)
 {
 	MsnUserList *userlist;
 	PurpleAccount *account;
 	PurpleBuddy *b;
 	PurpleGroup *g;
 	const char *passport;
-	char *group_id;
 	const char *group_name;
 
 	g_return_if_fail(user != NULL);
-	g_return_if_fail(id != NULL);
+	g_return_if_fail(group_id != NULL);
 
-	group_id = g_strdup(id);
-	user->group_ids = g_list_append(user->group_ids, group_id);
+	user->group_ids = g_list_append(user->group_ids, g_strdup(group_id));
 
 	userlist = user->userlist;
 	account = userlist->session->account;
@@ -261,7 +259,7 @@
 
 	g = purple_find_group(group_name);
 
-	if ((id == NULL) && (g == NULL))
+	if ((group_id == NULL) && (g == NULL))
 	{
 		g = purple_group_new(group_name);
 		purple_blist_add_group(g, NULL);
--- a/libpurple/protocols/oscar/Makefile.mingw	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/oscar/Makefile.mingw	Thu Jul 17 04:38:07 2008 +0000
@@ -109,7 +109,7 @@
 $(OBJECTS): $(PURPLE_CONFIG_H)
 
 $(TARGET).dll.a $(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS)
-	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--out-implib,$(TARGET).dll.a -o $(TARGET).dll
+	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--output-def,$(TARGET).def,--out-implib,$(TARGET).dll.a -o $(TARGET).dll
 
 $(AIM_TARGET).dll: $(TARGET).dll.a $(AIM_OBJECTS)
 	$(CC) -shared $(AIM_OBJECTS) $(LIB_PATHS) $(LIBS) -loscar $(DLL_LD_FLAGS) -o $(AIM_TARGET).dll
--- a/libpurple/protocols/silc/Makefile.mingw	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/silc/Makefile.mingw	Thu Jul 17 04:38:07 2008 +0000
@@ -79,7 +79,7 @@
 $(OBJECTS): $(PURPLE_CONFIG_H)
 
 $(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS)
-	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--image-base,0x64000000 -o $(TARGET).dll
+	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--image-base,0x74000000 -o $(TARGET).dll
 
 ##
 ## CLEAN RULES
--- a/libpurple/protocols/yahoo/yahoo.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Thu Jul 17 04:38:07 2008 +0000
@@ -148,6 +148,14 @@
 	gboolean unicode = FALSE;
 	char *message = NULL;
 
+	if (pkt->service == YAHOO_SERVICE_LOGON && pkt->status == -1) {
+		if (!purple_account_get_remember_password(account))
+			purple_account_set_password(account, NULL);
+		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE,
+			_("System is busy, please try again later."));
+		return;
+	}
+
 	if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {
 		if (!purple_account_get_remember_password(account))
 			purple_account_set_password(account, NULL);
--- a/libpurple/protocols/zephyr/ZSendPkt.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/libpurple/protocols/zephyr/ZSendPkt.c	Thu Jul 17 04:38:07 2008 +0000
@@ -5,12 +5,12 @@
  *
  *	Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
  *	For copying and distribution information, see the file
- *	"mit-copyright.h". 
+ *	"mit-copyright.h".
  */
 
 #include "internal.h"
 #ifdef WIN32
-#include <winsock.h>
+#include <winsock2.h>
 #else
 #include <sys/socket.h>
 #endif
@@ -25,19 +25,19 @@
     Code_t retval;
     struct sockaddr_in dest;
     ZNotice_t notice, acknotice;
-	
+
     if (!packet || len < 0)
 	return (ZERR_ILLVAL);
 
     if (len > Z_MAXPKTLEN)
 	return (ZERR_PKTLEN);
-    
+
     if (ZGetFD() < 0)
 	if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE)
 	    return (retval);
 
     dest = ZGetDestAddr();
-	
+
     if (sendto(ZGetFD(), packet, len, 0, (struct sockaddr *)&dest,
 	       sizeof(dest)) < 0)
 	return (errno);
@@ -47,7 +47,7 @@
 
     if ((retval = ZParseNotice(packet, len, &notice)) != ZERR_NONE)
 	return (retval);
-    
+
     retval = Z_WaitForNotice (&acknotice, wait_for_hmack, &notice.z_uid,
 			      HM_TIMEOUT);
     if (retval == ETIMEDOUT)
--- a/pidgin/gtkblist.h	Wed Jul 16 09:16:52 2008 +0000
+++ b/pidgin/gtkblist.h	Thu Jul 17 04:38:07 2008 +0000
@@ -194,11 +194,14 @@
 void pidgin_blist_update_refresh_timeout(void);
 
 /**
- * Returns the blist emblem
+ * Returns the blist emblem.
+ *
+ * This may be an existing pixbuf that has been given an additional ref,
+ * so it shouldn't be modified.
  *
  * @param node   The node to return an emblem for
  *
- * @return  A newly created GdkPixbuf, or NULL
+ * @return  A GdkPixbuf for the emblem to show, or NULL
  */
 GdkPixbuf *
 pidgin_blist_get_emblem(PurpleBlistNode *node);
--- a/pidgin/gtkcertmgr.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/pidgin/gtkcertmgr.c	Thu Jul 17 04:38:07 2008 +0000
@@ -57,7 +57,7 @@
 	PurpleCertificatePool *tls_peers;
 } tls_peers_mgmt_data;
 
-tls_peers_mgmt_data *tpm_dat = NULL;
+static tls_peers_mgmt_data *tpm_dat = NULL;
 
 /* Columns
    See http://developer.gnome.org/doc/API/2.0/gtk/TreeWidget.html */
@@ -113,7 +113,7 @@
 static void
 tls_peers_mgmt_mod_cb(PurpleCertificatePool *pool, const gchar *id, gpointer data)
 {
-	g_assert (pool == tpm_dat->tls_peers);
+	g_return_if_fail(pool == tpm_dat->tls_peers);
 
 	tls_peers_mgmt_repopulate_list();
 }
@@ -234,7 +234,7 @@
 {
 	PurpleCertificate *crt = (PurpleCertificate *) data;
 
-	g_assert(filename);
+	g_return_if_fail(filename);
 
 	if (!purple_certificate_export(filename, crt)) {
 		/* Errors! Oh no! */
@@ -617,7 +617,6 @@
 	g_signal_connect(G_OBJECT(win), "delete_event",
 			 G_CALLBACK(certmgr_close_cb), dlg);
 
-
 	/* TODO: Retrieve the user-set window size and use it */
 	gtk_window_set_default_size(GTK_WINDOW(win), 400, 400);
 
@@ -648,10 +647,12 @@
 void
 pidgin_certmgr_hide(void)
 {
+printf("pidgin_certmgr_hide\n");
 	/* If it isn't open, do nothing */
 	if (certmgr_dialog == NULL) {
 		return;
 	}
+printf("pidgin_certmgr_hide - ref_count=%d\n", G_OBJECT(certmgr_dialog->window)->ref_count);
 
 	purple_signals_disconnect_by_handle(certmgr_dialog);
 	purple_prefs_disconnect_by_handle(certmgr_dialog);
--- a/pidgin/gtkdocklet.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/pidgin/gtkdocklet.c	Thu Jul 17 04:38:07 2008 +0000
@@ -95,6 +95,10 @@
 						       PIDGIN_UNSEEN_TEXT,
 						       FALSE, max);
 
+	/* Short circuit if we have our information already */
+	if (max == 1 && l_im != NULL)
+		return l_im;
+
 	l_chat = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_CHAT,
 		 					 PIDGIN_UNSEEN_NICK,
 							 FALSE, max);
@@ -630,6 +634,7 @@
 }
 
 
+
 static void
 docklet_plugin_actions(GtkWidget *menu)
 {
@@ -665,7 +670,6 @@
 	if(c>0)
 		pidgin_separator(menu);
 }
-
 static void
 docklet_menu(void)
 {
--- a/pidgin/gtkstatusbox.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/pidgin/gtkstatusbox.c	Thu Jul 17 04:38:07 2008 +0000
@@ -203,8 +203,8 @@
 	const PurpleStatusType *statustype = NULL;
 	const char *message;
 
-	statustype = purple_status_type_find_with_id((GList *)purple_account_get_status_types(account),
-	                                           (char *)purple_status_type_get_id(purple_status_get_type(newstatus)));
+	statustype = purple_status_type_find_with_id(purple_account_get_status_types(account),
+						     purple_status_type_get_id(purple_status_get_type(newstatus)));
 
 	for (l = purple_account_get_status_types(account); l != NULL; l = l->next) {
 		PurpleStatusType *status_type = (PurpleStatusType *)l->data;
@@ -376,7 +376,7 @@
 icon_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, PidginStatusBox *box)
 {
 	gdk_window_set_cursor(widget->window, box->arrow_cursor);
-	gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon) ;
+	gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon);
 	return FALSE;
 }
 
--- a/pidgin/minidialog.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/pidgin/minidialog.c	Thu Jul 17 04:38:07 2008 +0000
@@ -63,7 +63,7 @@
 			sizeof (PidginMiniDialog),
 			0,      /* n_preallocs */
 			(GInstanceInitFunc) pidgin_mini_dialog_init,
-			NULL,
+			NULL /* value_table */
 		};
 		g_define_type_id = g_type_register_static (GTK_TYPE_VBOX,
 			"PidginMiniDialog", &g_define_type_info, 0);
--- a/pidgin/plugins/win32/winprefs/gtkappbar.h	Wed Jul 16 09:16:52 2008 +0000
+++ b/pidgin/plugins/win32/winprefs/gtkappbar.h	Thu Jul 17 04:38:07 2008 +0000
@@ -33,7 +33,7 @@
 	/** The rectangle of the screen area used for docking */
 	RECT docked_rect;
 	/** The height of the window prior to docking */
-	UINT undocked_height;
+	int undocked_height;
 	/** The side of the screen to which the window is docked*/
 	UINT side;
 	/** Is the window currently docked? */
--- a/pidgin/win32/winpidgin.c	Wed Jul 16 09:16:52 2008 +0000
+++ b/pidgin/win32/winpidgin.c	Thu Jul 17 04:38:07 2008 +0000
@@ -89,9 +89,8 @@
 			const char *err_msg = get_win32_error_message(retv);
 
 			printf("Could not read reg key '%s' subkey '%s' value: '%s'.\nMessage: (%ld) %s\n",
-					((key == HKEY_LOCAL_MACHINE) ? "HKLM" :
-					 (key == HKEY_CURRENT_USER) ? "HKCU" :
-					 "???"),
+					(key == HKEY_LOCAL_MACHINE) ? "HKLM"
+					 : ((key == HKEY_CURRENT_USER) ? "HKCU" : "???"),
 					sub_key, val_name, retv, err_msg);
 		}
 		RegCloseKey(hkey);
@@ -216,13 +215,13 @@
 
 	/* Set up the settings dir base to be \\path\to
 	 * The actual settings dir will be \\path\to\.purple */
-	snprintf(path2, sizeof(path2), "PURPLEHOME=%s", path);
+	_snprintf(path2, sizeof(path2), "PURPLEHOME=%s", path);
 	printf("Setting settings dir: %s\n", path2);
-	putenv(path2);
+	_putenv(path2);
 
-	snprintf(path2, sizeof(path2), "PIDGIN_ASPELL_DIR=%s\\Aspell\\bin", path);
+	_snprintf(path2, sizeof(path2), "PIDGIN_ASPELL_DIR=%s\\Aspell\\bin", path);
 	printf("%s\n", path2);
-	putenv(path2);
+	_putenv(path2);
 
 	/* set the GTK+ path to be \\path\to\GTK\bin */
 	strcat(path, "\\GTK\\bin");
@@ -321,7 +320,7 @@
 			break;
 		case LANG_PUNJABI: posix = "pa"; break;
 		case LANG_POLISH: posix = "pl"; break;
-		case LANG_PASHTO: posix = "ps"; break;
+//		case LANG_PASHTO: posix = "ps"; break;
 		case LANG_PORTUGUESE:
 			switch (sub_id) {
 				case SUBLANG_PORTUGUESE_BRAZILIAN:
@@ -437,9 +436,9 @@
 
 	locale = winpidgin_get_locale();
 
-	snprintf(envstr, 25, "LANG=%s", locale);
+	_snprintf(envstr, 25, "LANG=%s", locale);
 	printf("Setting locale: %s\n", envstr);
-	putenv(envstr);
+	_putenv(envstr);
 }
 
 #define PIDGIN_WM_FOCUS_REQUEST (WM_APP + 13)
@@ -478,7 +477,7 @@
 
 static void handle_protocol(char *cmd) {
 	char *remote_msg, *tmp1, *tmp2;
-	int len;
+	SIZE_T len;
 	SIZE_T len_written;
 	HWND msg_win;
 	DWORD pid;
@@ -598,10 +597,10 @@
 	} else {
 		DWORD dw = GetLastError();
 		const char *err_msg = get_win32_error_message(dw);
-		snprintf(errbuf, 512,
+		_snprintf(errbuf, 512,
 			"Error getting module filename.\nError: (%u) %s",
 			(UINT) dw, err_msg);
-		printf("%s", errbuf);
+		printf("%s\n", errbuf);
 		MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST);
 		pidgin_dir[0] = '\0';
 	}
@@ -645,11 +644,11 @@
 		BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND);
 		const char *err_msg = get_win32_error_message(dw);
 
-		snprintf(errbuf, 512, "Error loading pidgin.dll.\nError: (%u) %s%s%s",
+		_snprintf(errbuf, 512, "Error loading pidgin.dll.\nError: (%u) %s%s%s",
 			(UINT) dw, err_msg,
 			mod_not_found ? "\n" : "",
 			mod_not_found ? "This probably means that GTK+ can't be found." : "");
-		printf("%s", errbuf);
+		printf("%s\n", errbuf);
 		MessageBox(NULL, errbuf, TEXT("Error"), MB_OK | MB_TOPMOST);
 
 		return 0;
--- a/po/Makefile.mingw	Wed Jul 16 09:16:52 2008 +0000
+++ b/po/Makefile.mingw	Thu Jul 17 04:38:07 2008 +0000
@@ -22,7 +22,7 @@
 ##
 
 .po.gmo:
-	rm -f $@ && $(GMSGFMT) --statistics -o $@ $<
+	rm -f $@ && $(GMSGFMT) -c --statistics -o $@ $<
 
 ##
 ## TARGETS
--- a/po/pl.po	Wed Jul 16 09:16:52 2008 +0000
+++ b/po/pl.po	Thu Jul 17 04:38:07 2008 +0000
@@ -169,9 +169,9 @@
 
 #. Save button
 #. Save
-#: ../finch/gntaccount.c:1 ../finch/gntcertmgr.c:1 ../finch/gntdebug.c:1
-#: ../finch/gntplugin.c:1 ../finch/gntpounce.c:1 ../finch/gntprefs.c:1
-#: ../finch/gntsound.c:1 ../finch/gntstatus.c:1 ../finch/gntstatus.c:1
+#: ../finch/gntaccount.c:1 ../finch/gntcertmgr.c:1 ../finch/gntdebug.c:1
+#: ../finch/gntplugin.c:1 ../finch/gntpounce.c:1 ../finch/gntprefs.c:1
+#: ../finch/gntsound.c:1 ../finch/gntstatus.c:1 ../finch/gntstatus.c:1
 #: ../libpurple/account.c:1 ../libpurple/plugins/buddynote.c:1
 #: ../libpurple/protocols/jabber/buddy.c:1 ../pidgin/gtkdebug.c:1
 #: ../pidgin/gtkrequest.c:1
@@ -190,7 +190,7 @@
 
 #. Delete button
 #: ../finch/gntaccount.c:1 ../finch/gntcertmgr.c:1 ../finch/gntpounce.c:1
-#: ../finch/gntpounce.c:1
 ../finch/gntstatus.c:1 ../finch/gntstatus.c:1
+#: ../finch/gntpounce.c:1
 ../finch/gntstatus.c:1 ../finch/gntstatus.c:1
 #: ../pidgin/gtkaccount.c:1 ../pidgin/gtklog.c:1
 ../pidgin/gtkpounce.c:1
 #: ../pidgin/gtkrequest.c:1
 ../pidgin/gtksavedstatuses.c:1
 #: ../pidgin/gtkstatusbox.c:1
@@ -208,7 +208,7 @@
 
 #. Add button
 #: ../finch/gntaccount.c:1 ../finch/gntblist.c:1
 ../finch/gntblist.c:1
-#: ../finch/gntcertmgr.c:1 ../finch/gntnotify.c:1 ../finch/gntpounce.c:1
+#: ../finch/gntcertmgr.c:1 ../finch/gntnotify.c:1 ../finch/gntpounce.c:1
 #: ../finch/gntstatus.c:1 ../libpurple/protocols/gg/gg.c:1
 #: ../libpurple/protocols/qq/sys_msg.c:1
 #: ../libpurple/protocols/sametime/sametime.c:1
@@ -704,7 +704,7 @@
 msgid "Hostname"
 msgstr "Nazwa hosta"
 
-#: ../finch/gntcertmgr.c:1 ../finch/gntnotify.c:1 ../pidgin/gtkconv.c:1
+#: ../finch/gntcertmgr.c:1 ../finch/gntnotify.c:1 ../pidgin/gtkconv.c:1
 #: ../pidgin/gtkdebug.c:1
 msgid "Info"
 msgstr "Informacja"
@@ -4490,7 +4490,7 @@
 msgid "CTCP PING reply"
 msgstr "Odpowiedź CTCP PING"
 
-#: ../libpurple/protocols/irc/parse.c:1 ../libpurple/protocols/toc/toc.c:1
+#: ../libpurple/protocols/irc/parse.c:1 ../libpurple/protocols/toc/toc.c:1
 #: ../libpurple/protocols/toc/toc.c:1
 msgid "Disconnected."
 msgstr "Rozłączony."
@@ -8149,7 +8149,7 @@
 msgid "Web Aware"
 msgstr "Strona WWW"
 
-#: ../libpurple/protocols/oscar/oscar.c:1 ../libpurple/protocols/qq/qq.c:1
+#: ../libpurple/protocols/oscar/oscar.c:1 ../libpurple/protocols/qq/qq.c:1
 #: ../libpurple/protocols/qq/qq.c:1 ../libpurple/protocols/yahoo/yahoo.c:1
 #: ../libpurple/status.c:1 ../pidgin/gtkdocklet.c:1 ../pidgin/gtkstatusbox.c:1
 #, c-format
@@ -12602,7 +12602,7 @@
 msgid "Exposure"
 msgstr "Ekspozycja"
 
-#: ../libpurple/proxy.c:1 ../libpurple/proxy.c:1
+#: ../libpurple/proxy.c:1 ../libpurple/proxy.c:1
 #, c-format
 msgid ""
 "Unable to create socket:\n"