changeset 26195:9fcff08ce726

propagate from branch 'im.pidgin.pidgin' (head e39dfbe6c3a61b035fc764dfaad7b49c84666d14) to branch 'im.pidgin.pidgin.vv' (head 22553645a6b7273105d6333de2a0cec0f32b8478)
author Mike Ruprecht <maiku@soc.pidgin.im>
date Thu, 19 Feb 2009 11:29:08 +0000
parents 1fa62c559a78 (current diff) b93f3d152de6 (diff)
children 730e760ca39f
files libpurple/protocols/jabber/jabber.c libpurple/protocols/myspace/myspace.c libpurple/protocols/qq/qq.c libpurple/protocols/silc10/silc.c libpurple/protocols/simple/simple.c pidgin/gtkblist.c pidgin/gtkconv.c pidgin/gtkdialogs.c pidgin/gtkprefs.c
diffstat 64 files changed, 597 insertions(+), 273 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Thu Feb 19 11:28:01 2009 +0000
+++ b/COPYRIGHT	Thu Feb 19 11:29:08 2009 +0000
@@ -14,6 +14,7 @@
 Patrick Aussems
 Anibal Avelar
 Ali Albazaz
+Kosta Arvanitis
 Christopher Ayoup
 Alex Badea
 John Bailey
@@ -66,6 +67,7 @@
 Ludovico Cavedon
 Steve Cavilia
 Julien Cegarra
+Matěj Cepl
 Cerulean Studios, LLC
 Jonathan Champ
 Christophe Chapuis
@@ -204,6 +206,7 @@
 Intel Corporation
 Scott Jackson
 Hans Petter Jansson
+David Jedelsky
 Henry Jen
 Benjamin Kahn
 Anders Kaseorg
@@ -212,6 +215,7 @@
 John Kelm
 Jochen Kemnade
 Yann Kerherve
+Gordian Klein
 Akuke Kok
 Kir Kolyshkin
 Konstantin Korikov
@@ -418,6 +422,7 @@
 Andreas Stührk
 Oleg Sukhodolsky
 Sun Microsystems
+Marcus Sundberg
 Mårten Svantesson (fursten)
 Amir Szekely (kichik)
 Robert T.
--- a/ChangeLog	Thu Feb 19 11:28:01 2009 +0000
+++ b/ChangeLog	Thu Feb 19 11:29:08 2009 +0000
@@ -7,6 +7,9 @@
 	  enable, check the "Use SSL" option from the Advanced tab when
 	  editing your AIM or ICQ account. (Paul Aurich)
 	* Fix a memory leak in SILC. (Luke Petre)
+	* Fix some string handling in the SIMPLE prpl, which fixes some buddy name
+	  handling and other issues. (Paul Aurich, Marcus Sundberg)
+	* Implement support for resolving DNS via the SOCKS4 proxy (SOCKS4a).
 
 	ICQ:
 	* Fix retrieval of status messages from users of ICQ 6.x, Miranda, and
@@ -15,6 +18,7 @@
 	  of buddy icons and available messages.
 	* Properly publish status messages for statuses other than Available.
 	  ICQ 6.x users can now see these status messages. (Daniel Ljungborg)
+	* Fix recipt of messages from the mobile client Slick. (David Jedelsky)
 
 	MSN:
 	* Fix transfer of buddy icons, custom smileys, and files from the
@@ -23,8 +27,45 @@
 	* Large (multi-part) messages are now correctly re-combined.
 	* Federated/Yahoo! buddies should now stop creating sync issues at
 	  every signin.  You may need to remove duplicates in the Address
-	  Book.  See the FAQ for more information.
+	  Book.  See the FAQ for more information.  Thanks to Jason Lingohr
+	  for lots of debugging and testing.
 	* Messages from Yahoo! buddies are no longer silently dropped.
+	* We now save and use the CacheKey for ABCH SOAP requests.
+	* Don't try to parse Personal Status Messages or Current Media if they
+	  don't exist.
+	* Convert from ISO-8859-1 encoding to UTF-8 when no charset is specified
+	  on incoming messages.  This should fix some issues with messages from
+	  older clients.
+	* Force sending the font "Segoe UI" if outgoing formatting doesn't specify
+	  a font already.
+	* Queue callbacks when token updates are in progress to prevent two token
+	  update attempts from trampling each other.
+	* Fixed a crash on Windows when removing a buddy's alias.
+	* Update the Address Book when buddies' friendly names change.  This
+	  prevents seeing an outdated alias or not seeing an alias at all for
+	  buddies who are offline when you sign in.
+	* Update tokens for FindMembership and ABFindAll SOAP requests.
+	* We no longer try to send empty messages.  This could happen when a
+	  message contained only formatting and that formatting was not supported
+	  on MSN.
+	* Buddies on both the Allow and Block list are now automatically
+	  removed from the Allow list.  Users with this problem will now no
+	  longer receive an ADL 241 error.  The problematic buddy should now
+	  appear on the buddy list and can be removed or unblocked as desired.
+
+	XMPP:
+	* Resources using __HOSTNAME__ substitution will now grab only the short
+	  hostname instead of the FQDN on systems which put the FQDN in the
+	  hostname. (Matěj Cepl)
+	* No longer send a 'to' attribute on an outgoing stanza when we haven't
+	  received one.  This fixes a registration bug as described in ticket
+	  #6635.
+
+	Pidgin:
+	* Tooltip windows now appear below the mouse cursor. (Kosta Arvanitis)
+	* Tooltip windows now disappear on keypress events. (Kosta Arvanitis)
+	* Tooltip windows no longer linger when scrolling the buddy list. (Kosta
+	  Arvanitis)
 
 	Finch:
 	* Allow rebinding keys to change the focused widget (details in the
--- a/Makefile.am	Thu Feb 19 11:28:01 2009 +0000
+++ b/Makefile.am	Thu Feb 19 11:29:08 2009 +0000
@@ -99,7 +99,7 @@
 	@echo "Not generating devhelp index: xsltproc was not found by configure"
 endif
 else
-	@echo "doxygen was not found during configure.  Aborting."
+	@echo "doxygen was not found during configure.  Unable to build documentation."
 	@echo;
 endif
 
--- a/finch/finch.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/finch/finch.c	Thu Feb 19 11:29:08 2009 +0000
@@ -210,7 +210,7 @@
 		text = g_strdup_printf(_("%s\n"
 		       "Usage: %s [OPTION]...\n\n"
 		       "  -c, --config=DIR    use DIR for config files\n"
-		       "  -d, --debug         print debugging messages to stdout\n"
+		       "  -d, --debug         print debugging messages to stderr\n"
 		       "  -h, --help          display this help and exit\n"
 		       "  -n, --nologin       don't automatically login\n"
 		       "  -v, --version       display the current version and exit\n"), DISPLAY_VERSION, name);
--- a/finch/libgnt/gntkeys.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/finch/libgnt/gntkeys.c	Thu Feb 19 11:29:08 2009 +0000
@@ -163,7 +163,8 @@
 			(*(text + 2) >= 'A' && *(text + 2) <= 'D')) {
 		/* Apparently this is necessary for urxvt and screen and xterm */
 		if (strstr(term, "screen") == term || strcmp(term, "rxvt-unicode") == 0 ||
-				strstr(term, "xterm") == term)
+				strstr(term, "xterm") == term ||
+				strstr(term, "vt100") == term)
 			*(text + 1) = 'O';
 	} else if (*(unsigned char*)text == 195) {
 		if (*(text + 2) == 0 && strstr(term, "xterm") == term) {
--- a/finch/libgnt/gntwm.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/finch/libgnt/gntwm.c	Thu Feb 19 11:29:08 2009 +0000
@@ -353,7 +353,8 @@
 				p->y = y;
 				g_hash_table_replace(wm->positions, g_strdup(title + 1), p);
 			} else {
-				gnt_warning("Invalid number of arguments (%d) for positioning a window.", l);
+				gnt_warning("Invalid number of arguments (%" G_GSIZE_FORMAT
+						") for positioning a window.", l);
 			}
 			g_strfreev(coords);
 		}
--- a/finch/plugins/gntclipboard.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/finch/plugins/gntclipboard.c	Thu Feb 19 11:29:08 2009 +0000
@@ -22,7 +22,7 @@
 #include "internal.h"
 #include <glib.h>
 
-#define PLUGIN_STATIC_NAME	"GntClipboard"
+#define PLUGIN_STATIC_NAME	GntClipboard
 
 #ifdef HAVE_X11
 #include <X11/Xlib.h>
--- a/finch/plugins/gntgf.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/finch/plugins/gntgf.c	Thu Feb 19 11:29:08 2009 +0000
@@ -21,7 +21,7 @@
 
 #include "internal.h"
 
-#define PLUGIN_STATIC_NAME	"GntGf"
+#define PLUGIN_STATIC_NAME	GntGf
 
 #define PREFS_PREFIX          "/plugins/gnt/gntgf"
 #define PREFS_EVENT           PREFS_PREFIX "/events"
--- a/finch/plugins/grouping.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/finch/plugins/grouping.c	Thu Feb 19 11:29:08 2009 +0000
@@ -383,6 +383,6 @@
 {
 }
 
-PURPLE_INIT_PLUGIN(ignore, init_plugin, info)
+PURPLE_INIT_PLUGIN(grouping, init_plugin, info)
 
 
--- a/finch/plugins/lastlog.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/finch/plugins/lastlog.c	Thu Feb 19 11:29:08 2009 +0000
@@ -19,7 +19,7 @@
  */
 
 
-#define PLUGIN_STATIC_NAME	"GntLastlog"
+#define PLUGIN_STATIC_NAME	GntLastlog
 
 #include "internal.h"
 
--- a/libpurple/account.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/account.h	Thu Feb 19 11:29:08 2009 +0000
@@ -132,6 +132,14 @@
 								/*   to NULL when the account inherits      */
 								/*   proxy settings from global prefs.      */
 
+	/*
+	 * TODO: Supplementing the next two linked lists with hash tables
+	 * should help performance a lot when these lists are long.  This
+	 * matters quite a bit for protocols like MSN, where all your
+	 * buddies are added to your permit list.  Currently we have to
+	 * iterate through the entire list if we want to check if someone
+	 * is permitted or denied.  We should do this for 3.0.0.
+	 */
 	GSList *permit;             /**< Permit list.                           */
 	GSList *deny;               /**< Deny list.                             */
 	int perm_deny;              /**< The permit/deny setting.               */
--- a/libpurple/plugin.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/plugin.h	Thu Feb 19 11:29:08 2009 +0000
@@ -34,11 +34,16 @@
 #include "signals.h"
 #include "value.h"
 
+/** @copydoc _PurplePlugin */
 typedef struct _PurplePlugin           PurplePlugin;
+/** @copydoc _PurplePluginInfo */
 typedef struct _PurplePluginInfo       PurplePluginInfo;
+/** @copydoc _PurplePluginUiInfo */
 typedef struct _PurplePluginUiInfo     PurplePluginUiInfo;
+/** @copydoc _PurplePluginLoaderInfo */
 typedef struct _PurplePluginLoaderInfo PurplePluginLoaderInfo;
 
+/** @copydoc _PurplePluginAction */
 typedef struct _PurplePluginAction     PurplePluginAction;
 
 typedef int PurplePluginPriority; /**< Plugin priority. */
--- a/libpurple/plugins/autoaccept.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/plugins/autoaccept.c	Thu Feb 19 11:29:08 2009 +0000
@@ -21,7 +21,7 @@
 
 #define PLUGIN_ID			"core-plugin_pack-autoaccept"
 #define PLUGIN_NAME			N_("Autoaccept")
-#define PLUGIN_STATIC_NAME	"Autoaccept"
+#define PLUGIN_STATIC_NAME	Autoaccept
 #define PLUGIN_SUMMARY		N_("Auto-accept file transfer requests from selected users.")
 #define PLUGIN_DESCRIPTION	N_("Auto-accept file transfer requests from selected users.")
 #define PLUGIN_AUTHOR		"Sadrul H Chowdhury <sadrul@users.sourceforge.net>"
--- a/libpurple/plugins/codeinline.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/plugins/codeinline.c	Thu Feb 19 11:29:08 2009 +0000
@@ -95,4 +95,4 @@
  {
  }
 
-PURPLE_INIT_PLUGIN(urlcatcher, init_plugin, info)
+PURPLE_INIT_PLUGIN(codeinline, init_plugin, info)
--- a/libpurple/plugins/newline.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/plugins/newline.c	Thu Feb 19 11:29:08 2009 +0000
@@ -133,4 +133,4 @@
 	purple_prefs_add_bool("/plugins/core/newline/chat", TRUE);
 }
 
-PURPLE_INIT_PLUGIN(lastseen, init_plugin, info)
+PURPLE_INIT_PLUGIN(newline, init_plugin, info)
--- a/libpurple/plugins/offlinemsg.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/plugins/offlinemsg.c	Thu Feb 19 11:29:08 2009 +0000
@@ -21,7 +21,7 @@
 
 #define PLUGIN_ID			"core-plugin_pack-offlinemsg"
 #define PLUGIN_NAME			N_("Offline Message Emulation")
-#define PLUGIN_STATIC_NAME	"offlinemsg"
+#define PLUGIN_STATIC_NAME	offlinemsg
 #define PLUGIN_SUMMARY		N_("Save messages sent to an offline user as pounce.")
 #define PLUGIN_DESCRIPTION	N_("Save messages sent to an offline user as pounce.")
 #define PLUGIN_AUTHOR		"Sadrul H Chowdhury <sadrul@users.sourceforge.net>"
--- a/libpurple/plugins/perl/common/Server.xs	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/plugins/perl/common/Server.xs	Thu Feb 19 11:29:08 2009 +0000
@@ -122,29 +122,28 @@
 	Purple::Connection gc
 	const char *name
 
-void 
-serv_join_chat(con, components)
-	Purple::Connection con 
-	SV * components
-INIT:
-	HV * t_HV;
-	HE * t_HE;
-	SV * t_SV;
-	GHashTable * t_GHash;
+void
+serv_join_chat(conn, components)
+	Purple::Connection conn
+	HV * components
+PREINIT:
+	HE *t_HE;
+	SV *t_SV;
 	I32 len;
+	GHashTable *t_GHash;
 	char *t_key, *t_value;
 CODE:
-	t_HV =  (HV *)SvRV(components);
 	t_GHash = g_hash_table_new(g_str_hash, g_str_equal);
 
-	for (t_HE = hv_iternext(t_HV); t_HE != NULL; t_HE = hv_iternext(t_HV) ) {
+	for (t_HE = hv_iternext(components); t_HE != NULL;
+	     t_HE = hv_iternext(components)) {
 		t_key = hv_iterkey(t_HE, &len);
-		t_SV = *hv_fetch(t_HV, t_key, len, 0);
- 		t_value = SvPVutf8_nolen(t_SV);
+		t_SV = *hv_fetch(components, t_key, len, 0);
+		t_value = SvPVutf8_nolen(t_SV);
 
 		g_hash_table_insert(t_GHash, t_key, t_value);
 	}
-	serv_join_chat(con, t_GHash);
+	serv_join_chat(conn, t_GHash);
 
 void 
 serv_move_buddy(buddy, group1, group2)
--- a/libpurple/prefs.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/prefs.h	Thu Feb 19 11:29:08 2009 +0000
@@ -30,17 +30,17 @@
 #include <glib.h>
 
 /**
- * Pref data types.
+ * Preference data types.
  */
 typedef enum _PurplePrefType
 {
-	PURPLE_PREF_NONE,
-	PURPLE_PREF_BOOLEAN,
-	PURPLE_PREF_INT,
-	PURPLE_PREF_STRING,
-	PURPLE_PREF_STRING_LIST,
-	PURPLE_PREF_PATH,
-	PURPLE_PREF_PATH_LIST
+	PURPLE_PREF_NONE,        /**< No type.         */
+	PURPLE_PREF_BOOLEAN,     /**< Boolean.         */
+	PURPLE_PREF_INT,         /**< Integer.         */
+	PURPLE_PREF_STRING,      /**< String.          */
+	PURPLE_PREF_STRING_LIST, /**< List of strings. */
+	PURPLE_PREF_PATH,        /**< Path.            */
+	PURPLE_PREF_PATH_LIST    /**< List of paths.   */
 
 } PurplePrefType;
 
--- a/libpurple/privacy.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/privacy.c	Thu Feb 19 11:29:08 2009 +0000
@@ -42,12 +42,14 @@
 	name = g_strdup(purple_normalize(account, who));
 
 	for (l = account->permit; l != NULL; l = l->next) {
-		if (!purple_utf8_strcasecmp(name, (char *)l->data))
+		if (g_str_equal(name, l->data))
+			/* This buddy already exists */
 			break;
 	}
 
 	if (l != NULL)
 	{
+		/* This buddy already exists, so bail out */
 		g_free(name);
 		return FALSE;
 	}
@@ -86,11 +88,13 @@
 	name = purple_normalize(account, who);
 
 	for (l = account->permit; l != NULL; l = l->next) {
-		if (!purple_utf8_strcasecmp(name, (char *)l->data))
+		if (g_str_equal(name, l->data))
+			/* We found the buddy we were looking for */
 			break;
 	}
 
 	if (l == NULL)
+		/* We didn't find the buddy we were looking for, so bail out */
 		return FALSE;
 
 	/* We should not free l->data just yet. There can be occasions where
@@ -130,12 +134,14 @@
 	name = g_strdup(purple_normalize(account, who));
 
 	for (l = account->deny; l != NULL; l = l->next) {
-		if (!purple_utf8_strcasecmp(name, purple_normalize(account, (char *)l->data)))
+		if (g_str_equal(name, l->data))
+			/* This buddy already exists */
 			break;
 	}
 
 	if (l != NULL)
 	{
+		/* This buddy already exists, so bail out */
 		g_free(name);
 		return FALSE;
 	}
@@ -173,14 +179,16 @@
 	normalized = purple_normalize(account, who);
 
 	for (l = account->deny; l != NULL; l = l->next) {
-		if (!purple_utf8_strcasecmp(normalized, (char *)l->data))
+		if (g_str_equal(normalized, l->data))
+			/* We found the buddy we were looking for */
 			break;
 	}
 
-	buddy = purple_find_buddy(account, normalized);
+	if (l == NULL)
+		/* We didn't find the buddy we were looking for, so bail out */
+		return FALSE;
 
-	if (l == NULL)
-		return FALSE;
+	buddy = purple_find_buddy(account, normalized);
 
 	name = l->data;
 	account->deny = g_slist_delete_link(account->deny, l);
@@ -349,7 +357,7 @@
 		case PURPLE_PRIVACY_ALLOW_USERS:
 			who = purple_normalize(account, who);
 			for (list=account->permit; list!=NULL; list=list->next) {
-				if (!purple_utf8_strcasecmp(who, (char *)list->data))
+				if (g_str_equal(who, list->data))
 					return TRUE;
 			}
 			return FALSE;
@@ -357,7 +365,7 @@
 		case PURPLE_PRIVACY_DENY_USERS:
 			who = purple_normalize(account, who);
 			for (list=account->deny; list!=NULL; list=list->next) {
-				if (!purple_utf8_strcasecmp(who, (char *)list->data ))
+				if (g_str_equal(who, list->data))
 					return FALSE;
 			}
 			return TRUE;
--- a/libpurple/protocols/jabber/adhoccommands.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/jabber/adhoccommands.c	Thu Feb 19 11:29:08 2009 +0000
@@ -229,7 +229,7 @@
 		JabberAdHocCommands *cmd = js->commands->data;
 		g_free(cmd->jid);
 		g_free(cmd->node);
-		g_free(cmd->node);
+		g_free(cmd->name);
 		g_free(cmd);
 		js->commands = g_list_delete_link(js->commands, js->commands);
 	}
--- a/libpurple/protocols/jabber/buddy.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Thu Feb 19 11:29:08 2009 +0000
@@ -1786,7 +1786,7 @@
 	if (!jid)
 		return;
 
-	if (jabber_chat_find(js, jid->node, jid->domain)) {
+	if (jid->node && jabber_chat_find(js, jid->node, jid->domain)) {
 		/* For a conversation, include the resource (indicates the user). */
 		jabber_buddy_get_info_for_jid(js, who);
 	} else {
--- a/libpurple/protocols/jabber/jabber.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Thu Feb 19 11:29:08 2009 +0000
@@ -157,7 +157,8 @@
 }
 
 static char *jabber_prep_resource(char *input) {
-	char hostname[256]; /* current hostname */
+	char hostname[256], /* current hostname */
+		 *dot = NULL;
 
 	/* Empty resource == don't send any */
 	if (input == NULL || *input == '\0')
@@ -179,6 +180,12 @@
 	}
 	hostname[sizeof(hostname) - 1] = '\0';
 
+	/* We want only the short hostname, not the FQDN - this will prevent the
+	 * resource string from being unreasonably long on systems which stuff the
+	 * whole FQDN in the hostname */
+	if((dot = strchr(hostname, '.')))
+			dot = '\0';
+
 	return purple_strreplace(input, "__HOSTNAME__", hostname);
 }
 
@@ -818,10 +825,11 @@
 				js->user->node, js->user->domain);
 			if(account->registration_cb)
 				(account->registration_cb)(account, TRUE, account->registration_cb_user_data);
-		}
-		else
+		} else {
+			g_return_if_fail(to != NULL);
 			buf = g_strdup_printf(_("Registration to %s successful"),
 				to);
+		}
 		purple_notify_info(NULL, _("Registration Successful"),
 				_("Registration Successful"), buf);
 		g_free(buf);
@@ -848,7 +856,11 @@
 	const char *type = xmlnode_get_attrib(packet, "type");
 	char *buf;
 	char *to = data;
-	
+
+	/* This function is never called for unregistering our XMPP account from
+	 * the server, so there should always be a 'to' address. */
+	g_return_if_fail(to != NULL);
+
 	if(!strcmp(type, "result")) {
 		buf = g_strdup_printf(_("Registration from %s successfully removed"),
 							  to);
@@ -883,7 +895,8 @@
 
 	iq = jabber_iq_new_query(cbdata->js, JABBER_IQ_SET, "jabber:iq:register");
 	query = xmlnode_get_child(iq->node, "query");
-	xmlnode_set_attrib(iq->node, "to", cbdata->who);
+	if (cbdata->who)
+		xmlnode_set_attrib(iq->node, "to", cbdata->who);
 
 	for(groups = purple_request_fields_get_groups(fields); groups;
 			groups = groups->next) {
@@ -899,7 +912,8 @@
 					jabber_iq_free(iq);
 					iq = jabber_iq_new_query(cbdata->js, JABBER_IQ_SET, "jabber:iq:register");
 					query = xmlnode_get_child(iq->node, "query");
-					xmlnode_set_attrib(iq->node,"to",cbdata->who);
+					if (cbdata->who)
+						xmlnode_set_attrib(iq->node,"to",cbdata->who);
 					xmlnode_new_child(query, "remove");
 					
 					jabber_iq_set_callback(iq, jabber_unregistration_result_cb, cbdata->who);
@@ -944,8 +958,7 @@
 			}
 			xmlnode_insert_data(y, value, -1);
 				if(cbdata->js->registration && !strcmp(id, "username")) {
-					if(cbdata->js->user->node)
-						g_free(cbdata->js->user->node);
+					g_free(cbdata->js->user->node);
 					cbdata->js->user->node = g_strdup(value);
 			}
 				if(cbdata->js->registration && !strcmp(id, "password"))
@@ -988,7 +1001,8 @@
 
 	iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register");
 	query = xmlnode_get_child(iq->node, "query");
-	xmlnode_set_attrib(iq->node,"to",to);
+	if (to)
+		xmlnode_set_attrib(iq->node,"to",to);
 
 	xmlnode_insert_child(query, result);
 
@@ -1013,10 +1027,7 @@
 		return;
 
 	from = xmlnode_get_attrib(packet, "from");
-	if (!from)
-		from = js->serverFQDN;
-	g_return_if_fail(from != NULL);
-	
+
 	if(js->registration) {
 		/* get rid of the login thingy */
 		purple_connection_set_state(js->gc, PURPLE_CONNECTED);
@@ -1037,11 +1048,11 @@
 		}
 	}
 	
-	if((x = xmlnode_get_child_with_namespace(packet, "x", "jabber:x:data"))) {
+	if((x = xmlnode_get_child_with_namespace(query, "x", "jabber:x:data"))) {
 		jabber_x_data_request(js, x, jabber_register_x_data_cb, g_strdup(from));
 		return;
 
-	} else if((x = xmlnode_get_child_with_namespace(packet, "x", "jabber:x:oob"))) {
+	} else if((x = xmlnode_get_child_with_namespace(query, "x", "jabber:x:oob"))) {
 		xmlnode *url;
 
 		if((url = xmlnode_get_child(x, "url"))) {
@@ -1161,7 +1172,9 @@
 				purple_connection_get_account(js->gc), NULL, NULL,
 				cbdata);
 	else {
-		char *title = registered?g_strdup_printf(_("Change Account Registration at %s"), from)
+		char *title;
+		g_return_if_fail(from != NULL);
+		title = registered ? g_strdup_printf(_("Change Account Registration at %s"), from)
 								:g_strdup_printf(_("Register New Account at %s"), from);
 		purple_request_fields(js->gc, title,
 			  title, instructions, fields,
--- a/libpurple/protocols/jabber/parser.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/jabber/parser.c	Thu Feb 19 11:29:08 2009 +0000
@@ -86,15 +86,10 @@
 			}
 		}
 		for(i=0; i < nb_attributes * 5; i+=5) {
-			const char *prefix = (const char *)attributes[i + 1];
+			const char *attrib_ns = (const char *)attributes[i+2];
 			char *txt;
 			int attrib_len = attributes[i+4] - attributes[i+3];
 			char *attrib = g_malloc(attrib_len + 1);
-			char *attrib_ns = NULL;
-
-			if (attributes[i+2]) {
-				attrib_ns = g_strdup((char*)attributes[i+2]);
-			}
 
 			memcpy(attrib, attributes[i+3], attrib_len);
 			attrib[attrib_len] = '\0';
@@ -103,11 +98,7 @@
 			attrib = purple_unescape_html(txt);
 			g_free(txt);
 			xmlnode_set_attrib_with_namespace(node, (const char*) attributes[i], attrib_ns, attrib);
-			if (prefix && *prefix) {
-				node->prefix = g_strdup(prefix);
-			}
 			g_free(attrib);
-			g_free(attrib_ns);
 		}
 
 		js->current = node;
--- a/libpurple/protocols/msn/contact.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/contact.c	Thu Feb 19 11:29:08 2009 +0000
@@ -198,20 +198,38 @@
 	MsnCallbackState *state = data;
 	xmlnode *fault;
 	char *faultcode_str;
+	xmlnode *cachekey;
+	char *changed;
 
 	if (resp == NULL) {
 		purple_debug_error("msn",
 		                   "Operation {%s} failed. No response received from server.\n",
 		                   msn_contact_operation_str(state->action));
+		msn_session_set_error(state->session, MSN_ERROR_BAD_BLIST, NULL);
 		return;
 	}
 
+ 	/* Update CacheKey if necessary */
+ 	cachekey = xmlnode_get_child(resp->xml, "Header/ServiceHeader/CacheKeyChanged");
+ 	if (cachekey != NULL) {
+ 		changed = xmlnode_get_data(cachekey);
+ 		if (changed && !strcmp(changed, "true")) {
+ 			cachekey = xmlnode_get_child(resp->xml, "Header/ServiceHeader/CacheKey");
+ 			g_free(state->session->abch_cachekey);
+ 			state->session->abch_cachekey = xmlnode_get_data(cachekey);
+ 			purple_debug_info("msn", "Updated CacheKey for %s to '%s'.\n",
+ 			                  purple_account_get_username(state->session->account),
+ 			                  state->session->abch_cachekey);
+ 		}
+ 		g_free(changed);
+ 	}
+
 	fault = xmlnode_get_child(resp->xml, "Body/Fault");
 
 	if (fault == NULL) {
 		/* No errors */
 		if (state->cb)
-			((MsnSoapCallback)state->cb)(req, resp, data);
+			state->cb(req, resp, data);
 		msn_callback_state_free(state);
 		return;
 	}
@@ -230,7 +248,7 @@
 	else
 	{
 		if (state->cb) {
-			((MsnSoapCallback)state->cb)(req, resp, data);
+			state->cb(req, resp, data);
 		} else {
 			/* We don't know how to respond to this faultcode, so log it */
 			char *str = xmlnode_to_str(fault, NULL);
@@ -247,6 +265,14 @@
 static gboolean
 msn_contact_request(MsnCallbackState *state)
 {
+	xmlnode *cachekey = xmlnode_get_child(state->body,
+	                                      "Header/ABApplicationHeader/CacheKey");
+	if (cachekey != NULL)
+		xmlnode_free(cachekey);
+	if (state->session->abch_cachekey != NULL) {
+		cachekey = xmlnode_new_child(xmlnode_get_child(state->body, "Header/ABApplicationHeader"), "CacheKey");
+		xmlnode_insert_data(cachekey, state->session->abch_cachekey, -1);
+	}
 	if (state->token == NULL)
 		state->token = xmlnode_get_child(state->body,
 			"Header/ABAuthHeader/TicketToken");
@@ -891,8 +917,7 @@
 		/*
 		msn_get_address_book(session, NULL, NULL);
 		*/
-		msn_session_disconnect(session);
-		purple_connection_error_reason(session->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to retrieve MSN Address Book"));
+		msn_session_set_error(session, MSN_ERROR_BAD_BLIST, NULL);
 	}
 }
 
--- a/libpurple/protocols/msn/msg.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/msg.c	Thu Feb 19 11:29:08 2009 +0000
@@ -80,7 +80,7 @@
 	msg->ref_count++;
 
 #ifdef MSN_DEBUG_MSG
-	purple_debug_info("msn", "message ref (%p)[%d]\n", msg, msg->ref_count);
+	purple_debug_info("msn", "message ref (%p)[%" G_GSIZE_FORMAT "]\n", msg, msg->ref_count);
 #endif
 
 	return msg;
@@ -95,7 +95,7 @@
 	msg->ref_count--;
 
 #ifdef MSN_DEBUG_MSG
-	purple_debug_info("msn", "message unref (%p)[%d]\n", msg, msg->ref_count);
+	purple_debug_info("msn", "message unref (%p)[%" G_GSIZE_FORMAT "]\n", msg, msg->ref_count);
 #endif
 
 	if (msg->ref_count == 0)
@@ -352,6 +352,14 @@
 			memcpy(msg->body, tmp, msg->body_len);
 			msg->body[msg->body_len] = '\0';
 		}
+		
+		if (msg->charset == NULL) {
+			char *body = g_convert(msg->body, msg->body_len, "UTF-8",
+			                       "ISO-8859-1", NULL, &msg->body_len, NULL);
+			g_free(msg->body);
+			msg->body = body;
+			msg->charset = g_strdup("UTF-8");
+		}
 	}
 
 	g_free(tmp_base);
--- a/libpurple/protocols/msn/msnutils.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/msnutils.c	Thu Feb 19 11:29:08 2009 +0000
@@ -446,7 +446,7 @@
 	}
 
 	if (fontface == NULL)
-		fontface = g_strdup("MS Sans Serif");
+		fontface = g_strdup("Segoe UI");
 
 	*attributes = g_strdup_printf("FN=%s; EF=%s; CO=%s; PF=0; RL=%c",
 								  encode_spaces(fontface),
--- a/libpurple/protocols/msn/nexus.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/nexus.c	Thu Feb 19 11:29:08 2009 +0000
@@ -74,6 +74,7 @@
 	for (i = 0; i < nexus->token_len; i++) {
 		g_hash_table_destroy(nexus->tokens[i].token);
 		g_free(nexus->tokens[i].secret);
+		g_slist_free(nexus->tokens[i].updates);
 	}
 
 	g_free(nexus->tokens);
@@ -235,6 +236,10 @@
 struct _MsnNexusUpdateData {
 	MsnNexus *nexus;
 	int id;
+};
+
+typedef struct _MsnNexusUpdateCallback MsnNexusUpdateCallback;
+struct _MsnNexusUpdateCallback {
 	GSourceFunc cb;
 	gpointer data;
 };
@@ -428,6 +433,7 @@
 	char *nonce;
 	gsize len;
 	char *key;
+	GSList *updates;
 
 #if 0
 	char *decrypted_pp;
@@ -489,8 +495,15 @@
 		g_free(decrypted_data);
 	}
 
-	if (ud->cb)
-		purple_timeout_add(0, ud->cb, ud->data);
+	updates = nexus->tokens[ud->id].updates;
+	nexus->tokens[ud->id].updates = NULL;
+	while (updates != NULL) {
+		MsnNexusUpdateCallback *update = updates->data;
+		if (update->cb)
+			purple_timeout_add(0, update->cb, update->data);
+		g_free(update);
+		updates = g_slist_delete_link(updates, updates);
+	}
 
 	g_free(ud);
 }
@@ -500,6 +513,7 @@
 {
 	MsnSession *session = nexus->session;
 	MsnNexusUpdateData *ud;
+	MsnNexusUpdateCallback *update;
 	PurpleCipherContext *sha1;
 	PurpleCipherContext *hmac;
 
@@ -526,16 +540,31 @@
 	char *request;
 	MsnSoapMessage *soap;
 
-	purple_debug_info("msn",
-	                  "Updating ticket for user '%s' on domain '%s'\n",
-	                  purple_account_get_username(session->account),
-	                  ticket_domains[id][SSO_VALID_TICKET_DOMAIN]);
+	update = g_new0(MsnNexusUpdateCallback, 1);
+	update->cb = cb;
+	update->data = data;
+
+	if (nexus->tokens[id].updates != NULL) {
+		/* Update already in progress. Just add to list and return. */
+		purple_debug_info("msn",
+		                  "Ticket update for user '%s' on domain '%s' in progress. Adding request to queue.\n",
+		                  purple_account_get_username(session->account),
+		                  ticket_domains[id][SSO_VALID_TICKET_DOMAIN]);
+		nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates,
+		                                            update);
+		return;
+	} else {
+		purple_debug_info("msn",
+		                  "Updating ticket for user '%s' on domain '%s'\n",
+		                  purple_account_get_username(session->account),
+		                  ticket_domains[id][SSO_VALID_TICKET_DOMAIN]);
+		nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates,
+		                                            update);
+	}
 
 	ud = g_new0(MsnNexusUpdateData, 1);
 	ud->nexus = nexus;
 	ud->id = id;
-	ud->cb = cb;
-	ud->data = data;
 
 	sha1 = purple_cipher_context_new_by_name("sha1", NULL);
 
--- a/libpurple/protocols/msn/nexus.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/nexus.h	Thu Feb 19 11:29:08 2009 +0000
@@ -204,6 +204,7 @@
 	GHashTable *token;
 	char *secret;
 	time_t expiry;
+	GSList *updates;
 };
 
 typedef struct _MsnNexus MsnNexus;
--- a/libpurple/protocols/msn/notification.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/notification.c	Thu Feb 19 11:29:08 2009 +0000
@@ -623,6 +623,18 @@
 		if (user->passport && !strcmp(user->passport, "messenger@microsoft.com"))
 			continue;
 
+		if ((user->list_op & MSN_LIST_OP_MASK) == (MSN_LIST_AL_OP | MSN_LIST_BL_OP)) {
+			/* The server will complain if we send it a user on both the
+			   Allow and Block lists. So assume they're on the Block list
+			   and remove them from the Allow list in the membership lists to
+			   stop this from happening again. */
+			purple_debug_warning("msn",
+			                     "User %s is on both Allow and Block list,"
+			                     "removing from Allow list.\n",
+			                     user->passport);
+			msn_userlist_rem_buddy_from_list(session->userlist, user->passport, MSN_LIST_AL);
+		}
+
 		msn_add_contact_xml(session, adl_node, user->passport,
 			user->list_op & MSN_LIST_OP_MASK, user->networkid);
 
@@ -1619,19 +1631,25 @@
 		return;
 	}
 
-	psm_str = msn_get_psm(cmd->payload,len);
-	msn_user_set_statusline(user, psm_str);
-	g_free(psm_str);
+	if (len != 0) {
+		psm_str = msn_get_psm(cmd->payload,len);
+		msn_user_set_statusline(user, psm_str);
+		g_free(psm_str);
 
-	str = msn_get_currentmedia(cmd->payload, len);
-	if (msn_parse_currentmedia(str, &media))
-		msn_user_set_currentmedia(user, &media);
-	else
+		str = msn_get_currentmedia(cmd->payload, len);
+		if (msn_parse_currentmedia(str, &media))
+			msn_user_set_currentmedia(user, &media);
+		else
+			msn_user_set_currentmedia(user, NULL);
+		g_free(media.title);
+		g_free(media.album);
+		g_free(media.artist);
+		g_free(str);
+
+	} else {
+		msn_user_set_statusline(user, NULL);
 		msn_user_set_currentmedia(user, NULL);
-	g_free(media.title);
-	g_free(media.album);
-	g_free(media.artist);
-	g_free(str);
+	}
 
 	msn_user_update(user);
 }
--- a/libpurple/protocols/msn/session.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/session.c	Thu Feb 19 11:29:08 2009 +0000
@@ -90,8 +90,10 @@
 	msn_userlist_destroy(session->userlist);
 
 	g_free(session->psm);
-
+	g_free(session->abch_cachekey);
+#if 0
 	g_free(session->blocked_text);
+#endif
 
 	g_free(session->passport_info.kv);
 	g_free(session->passport_info.sid);
--- a/libpurple/protocols/msn/session.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/session.h	Thu Feb 19 11:29:08 2009 +0000
@@ -94,11 +94,11 @@
 	gboolean http_method;
 
 	MsnNotification *notification;
-	MsnNexus *nexus;
-	MsnOim		*oim;
-	MsnSync *sync;
-
-	MsnUserList *userlist;
+	MsnNexus        *nexus;
+	MsnOim          *oim;
+	MsnSync         *sync;
+	MsnUserList     *userlist;
+	char            *abch_cachekey;
 
 	int servconns_count; /**< The count of server connections. */
 	GList *switches; /**< The list of all the switchboards. */
@@ -107,7 +107,9 @@
 	/*psm info*/
 	char *psm;
 
+#if 0
 	char *blocked_text;
+#endif
 
 	struct
 	{
--- a/libpurple/protocols/msn/slpcall.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Thu Feb 19 11:29:08 2009 +0000
@@ -47,6 +47,7 @@
 	if (!slpcall->pending && !slpcall->progress)
 	{
 		msn_slpcall_destroy(slpcall);
+		slpcall->timer = 0;
 		return FALSE;
 	}
 
@@ -222,8 +223,10 @@
 
 		if (slpcall != NULL)
 		{
-			if (slpcall->timer)
+			if (slpcall->timer) {
 				purple_timeout_remove(slpcall->timer);
+				slpcall->timer = 0;
+			}
 
 			slpcall->cb(slpcall, body, body_len);
 
--- a/libpurple/protocols/msn/state.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/state.c	Thu Feb 19 11:29:08 2009 +0000
@@ -189,12 +189,12 @@
 
 	purple_debug_info("msn", "msn get PSM\n");
 	payloadNode = xmlnode_from_str(xml_str, len);
-	if (!payloadNode){
+	if (!payloadNode) {
 		purple_debug_error("msn", "PSM XML parse Error!\n");
 		return NULL;
 	}
 	psmNode = xmlnode_get_child(payloadNode, "PSM");
-	if (psmNode == NULL){
+	if (psmNode == NULL) {
 		purple_debug_info("msn", "No PSM status Node");
 		xmlnode_free(payloadNode);
 		return NULL;
@@ -213,7 +213,7 @@
 	char *ret;
 	PurpleStatus *status = purple_presence_get_status(presence, "tune");
 	if (!status || !purple_status_is_active(status))
-		return g_strdup_printf("\\0Music\\00\\0\\0");
+		return NULL;
 
 	title = purple_status_get_attr_string(status, PURPLE_TUNE_TITLE);
 	game = purple_status_get_attr_string(status, "game");
@@ -234,7 +234,7 @@
 	else if (office && *office)
 		ret = g_strdup_printf("\\0Office\\01\\0Editing {0}\\0%s\\0", office);
 	else
-		ret = g_strdup_printf("\\0Music\\00\\0\\0");
+		ret = NULL;
 
 	return ret;
 }
--- a/libpurple/protocols/msn/transaction.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/msn/transaction.c	Thu Feb 19 11:29:08 2009 +0000
@@ -199,6 +199,7 @@
 	if (trans->timeout_cb != NULL)
 		trans->timeout_cb(trans->cmdproc, trans);
 
+	trans->timer = 0;
 	return FALSE;
 }
 
--- a/libpurple/protocols/myspace/myspace.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Thu Feb 19 11:29:08 2009 +0000
@@ -1146,7 +1146,11 @@
 			break;
 
 		case MSIM_CONTACT_LIST_INITIAL_FRIENDS:
-			/* Nothing */
+			/* The session is now set up, ready to be connected. This emits the
+			 * signedOn signal, so clients can now do anything with msimprpl, and
+			 * we're ready for it (session key, userid, username all setup). */
+			purple_connection_update_progress(session->gc, _("Connected"), 3, 4);
+			purple_connection_set_state(session->gc, PURPLE_CONNECTED);
 			break;
 	}
 
@@ -1185,12 +1189,6 @@
 	/* Set display name to username (otherwise will show email address) */
 	purple_connection_set_display_name(session->gc, session->username);
 
-	/* The session is now set up, ready to be connected. This emits the
-	 * signedOn signal, so clients can now do anything with msimprpl, and
-	 * we're ready for it (session key, userid, username all setup). */
-	purple_connection_update_progress(session->gc, _("Connected"), 3, 4);
-	purple_connection_set_state(session->gc, PURPLE_CONNECTED);
-
 	body = msim_msg_new(
 			"UserID", MSIM_TYPE_INTEGER, session->userid,
 			NULL);
--- a/libpurple/protocols/oscar/family_icbm.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Thu Feb 19 11:29:08 2009 +0000
@@ -1566,9 +1566,10 @@
 
 static int incomingim_ch1(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, ByteStream *bs, guint8 *cookie)
 {
-	guint16 type, length;
+	guint16 type, length, magic1, msglen;
 	aim_rxcallback_t userfunc;
 	int ret = 0;
+	int rev = 0;
 	struct aim_incomingim_ch1_args args;
 	unsigned int endpos;
 
@@ -1603,10 +1604,30 @@
 			 *   - 0101 -- Unknown
 			 *   - Message
 			 *
+			 * Slick and possible others reverse 'Features' and 'Messages' section.
+			 * Thus, the TLV could have following layout:
+			 *   - 0101 -- Unknown (possibly magic for message section)
+			 *   - Message
+			 *   - 0501 -- Unknown (possibly magic for features section)
+			 *   - Features: Don't know how to interpret these
 			 */
 
-			byte_stream_get8(bs); /* 05 */
-			byte_stream_get8(bs); /* 01 */
+			magic1 = byte_stream_get16(bs); /* 0501 or 0101 */
+			if (magic1 == 0x101) /* Bad, message comes before attributes */
+			{
+				/* Jump to the features section */
+				msglen = byte_stream_get16(bs);
+				bs->offset += msglen;
+				rev = 1;
+
+				magic1 = byte_stream_get16(bs); /* 0501 */
+			}
+
+			if (magic1 != 0x501)
+			{
+				purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s.  They are probably trying to do something malicious.\n", userinfo->sn);
+				break;
+			}
 
 			args.featureslen = byte_stream_get16(bs);
 			if (args.featureslen > byte_stream_empty(bs))
@@ -1624,11 +1645,25 @@
 				args.icbmflags |= AIM_IMFLAGS_CUSTOMFEATURES;
 			}
 
+			if (rev)
+			{
+				/* Fix buffer back to message */
+				bs->offset -= args.featureslen + 2 + 2 + msglen + 2 + 2;
+			}
+
+			magic1 = byte_stream_get16(bs); /* 01 01 */
+			if (magic1 != 0x101) /* Bad, message comes before attributes */
+			{
+				purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s.  They are probably trying to do something malicious.\n", userinfo->sn);
+				break;
+			}
+			msglen = byte_stream_get16(bs);
+
 			/*
 			 * The rest of the TLV contains one or more message
 			 * blocks...
 			 */
-			incomingim_ch1_parsemsgs(od, userinfo, bs->data + bs->offset /* XXX evil!!! */, length - 2 - 2 - args.featureslen, &args);
+			incomingim_ch1_parsemsgs(od, userinfo, bs->data + bs->offset - 2 - 2 /* XXX evil!!! */, msglen + 2 + 2, &args);
 
 		} else if (type == 0x0003) { /* Server Ack Requested */
 
--- a/libpurple/protocols/qq/ChangeLog	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/qq/ChangeLog	Thu Feb 19 11:29:08 2009 +0000
@@ -1,3 +1,6 @@
+2009.02.08 - flos <lonicerae(at)gmail.com>
+	* Fixed showing message of chat room when message comes in
+
 2008.12.28 - flos <lonicerae(at)gmail.com>
 	* Fixes #7908
 
--- a/libpurple/protocols/qq/buddy_info.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Thu Feb 19 11:29:08 2009 +0000
@@ -108,41 +108,41 @@
 } QQ_FIELD_INFO;
 
 static const QQ_FIELD_INFO field_infos[] = {
-	{ QQ_FIELD_BASE, 		QQ_FIELD_STRING, "uid", 			N_("QQ Number"), NULL, 0 },
-	{ QQ_FIELD_BASE, 		QQ_FIELD_STRING, "nick", 			N_("Nickname"), NULL, 0 },
-	{ QQ_FIELD_ADDR, 		QQ_FIELD_STRING, "country", 	N_("Country/Region"), NULL, 0 },
-	{ QQ_FIELD_ADDR, 		QQ_FIELD_STRING, "province", 	N_("Province/State"), NULL, 0 },
-	{ QQ_FIELD_ADDR, 		QQ_FIELD_STRING, "zipcode", 	N_("Zipcode"), NULL, 0 },
-	{ QQ_FIELD_ADDR, 		QQ_FIELD_STRING, "address", 	N_("Address"), NULL, 0 },
-	{ QQ_FIELD_CONTACT, QQ_FIELD_STRING, "tel", 				N_("Phone Number"), NULL, 0 },
-	{ QQ_FIELD_BASE, 		QQ_FIELD_STRING, "age", 			N_("Age"), NULL, 0 },
-	{ QQ_FIELD_BASE, 		QQ_FIELD_CHOICE, "gender", 		N_("Gender"), genders, QQ_GENDER_SIZE },
-	{ QQ_FIELD_BASE, 		QQ_FIELD_STRING, "name", 			N_("Name"), NULL, 0 },
-	{ QQ_FIELD_CONTACT, QQ_FIELD_STRING, "email", 			N_("Email"), NULL, 0 },
-	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "pg_sn",		"Pager Serial Num", NULL, 0 },
+	{ QQ_FIELD_BASE, 	QQ_FIELD_STRING, "uid", 	N_("QQ Number"), NULL, 0 },
+	{ QQ_FIELD_BASE, 	QQ_FIELD_STRING, "nick", 	N_("Nickname"), NULL, 0 },
+	{ QQ_FIELD_ADDR, 	QQ_FIELD_STRING, "country", 	N_("Country/Region"), NULL, 0 },
+	{ QQ_FIELD_ADDR, 	QQ_FIELD_STRING, "province", 	N_("Province/State"), NULL, 0 },
+	{ QQ_FIELD_ADDR, 	QQ_FIELD_STRING, "zipcode", 	N_("Zipcode"), NULL, 0 },
+	{ QQ_FIELD_ADDR, 	QQ_FIELD_STRING, "address", 	N_("Address"), NULL, 0 },
+	{ QQ_FIELD_CONTACT, 	QQ_FIELD_STRING, "tel", 	N_("Phone Number"), NULL, 0 },
+	{ QQ_FIELD_BASE, 	QQ_FIELD_STRING, "age", 	N_("Age"), NULL, 0 },
+	{ QQ_FIELD_BASE, 	QQ_FIELD_CHOICE, "gender", 	N_("Gender"), genders, QQ_GENDER_SIZE },
+	{ QQ_FIELD_BASE, 	QQ_FIELD_STRING, "name", 	N_("Name"), NULL, 0 },
+	{ QQ_FIELD_CONTACT, 	QQ_FIELD_STRING, "email", 	N_("Email"), NULL, 0 },
+	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "pg_sn",	"Pager Serial Num", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "pg_num",	"Pager Num", NULL, 0 },
-	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "pg_sp",		"Pager Serivce Provider", NULL, 0 },
-	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "pg_sta",		"Pager Station Num", NULL, 0 },
+	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "pg_sp",	"Pager Serivce Provider", NULL, 0 },
+	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "pg_sta",	"Pager Station Num", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "pg_type",	"Pager Type", NULL, 0 },
-	{ QQ_FIELD_BASE, 		QQ_FIELD_STRING, "occupation", 	N_("Occupation"), NULL, 0 },
-	{ QQ_FIELD_CONTACT, QQ_FIELD_STRING, "homepage", 		N_("Homepage"), NULL, 0 },
-	{ QQ_FIELD_BASE, 		QQ_FIELD_BOOL, 	"auth", 				N_("Authorize adding"), NULL, 0 },
+	{ QQ_FIELD_BASE, 	QQ_FIELD_STRING, "occupation", 	N_("Occupation"), NULL, 0 },
+	{ QQ_FIELD_CONTACT, 	QQ_FIELD_STRING, "homepage", 	N_("Homepage"), NULL, 0 },
+	{ QQ_FIELD_BASE, 	QQ_FIELD_BOOL, 	"auth", 	N_("Authorize adding"), NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "unknow1",	"Unknow1", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "unknow2",	"Unknow2", NULL, 0 },
-	{ QQ_FIELD_UNUSED, 		QQ_FIELD_STRING, "face",				"Face", NULL, 0 },
-	{ QQ_FIELD_CONTACT, QQ_FIELD_STRING, "mobile",		N_("Cellphone Number"), NULL, 0 },
-	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "mobile_type","Cellphone Type", NULL, 0 },
-	{ QQ_FIELD_BASE, 		QQ_FIELD_MULTI, 	"intro", 		N_("Personal Introduction"), NULL, 0 },
-	{ QQ_FIELD_ADDR, 		QQ_FIELD_STRING, "city",			N_("City/Area"), NULL, 0 },
+	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "face",	"Face", NULL, 0 },
+	{ QQ_FIELD_CONTACT, 	QQ_FIELD_STRING, "mobile",	N_("Cellphone Number"), NULL, 0 },
+	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "mobile_type", "Cellphone Type", NULL, 0 },
+	{ QQ_FIELD_BASE, 	QQ_FIELD_MULTI,  "intro", 	N_("Personal Introduction"), NULL, 0 },
+	{ QQ_FIELD_ADDR, 	QQ_FIELD_STRING, "city",	N_("City/Area"), NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "unknow3",	"Unknow3", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "unknow4",	"Unknow4", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "unknow5",	"Unknow5", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_CHOICE, "pub_mobile",	N_("Publish Mobile"), publish_types, QQ_PUBLISH_SIZE },
-	{ QQ_FIELD_CONTACT, QQ_FIELD_CHOICE, "pub_contact",	N_("Publish Contact"), publish_types, QQ_PUBLISH_SIZE },
-	{ QQ_FIELD_EXT, 		QQ_FIELD_STRING, "college",			N_("College"), NULL, 0 },
-	{ QQ_FIELD_EXT, 		QQ_FIELD_CHOICE, "horoscope",	N_("Horoscope"), horoscope_names, QQ_HOROSCOPE_SIZE },
-	{ QQ_FIELD_EXT, 		QQ_FIELD_CHOICE, "zodiac",		N_("Zodiac"), zodiac_names, QQ_ZODIAC_SIZE },
-	{ QQ_FIELD_EXT, 		QQ_FIELD_CHOICE, "blood",			N_("Blood"), blood_types, QQ_BLOOD_SIZE },
+	{ QQ_FIELD_CONTACT, 	QQ_FIELD_CHOICE, "pub_contact",	N_("Publish Contact"), publish_types, QQ_PUBLISH_SIZE },
+	{ QQ_FIELD_EXT, 	QQ_FIELD_STRING, "college",	N_("College"), NULL, 0 },
+	{ QQ_FIELD_EXT, 	QQ_FIELD_CHOICE, "horoscope",	N_("Horoscope"), horoscope_names, QQ_HOROSCOPE_SIZE },
+	{ QQ_FIELD_EXT, 	QQ_FIELD_CHOICE, "zodiac",	N_("Zodiac"), zodiac_names, QQ_ZODIAC_SIZE },
+	{ QQ_FIELD_EXT, 	QQ_FIELD_CHOICE, "blood",	N_("Blood"), blood_types, QQ_BLOOD_SIZE },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "qq_show",	"QQ Show", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "unknow6",	"Unknow6", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "LAST_2005",	"LAST_2005", NULL, 0 }
@@ -196,7 +196,9 @@
 				break;
 			case QQ_FIELD_CHOICE:
 				choice_num = strtol(segments[index], NULL, 10);
-				if (choice_num < 0 || choice_num >= field_infos[index].choice_size)	choice_num = 0;
+				if (choice_num < 0 || choice_num >= field_infos[index].choice_size) {
+					choice_num = 0;
+				}
 
 				purple_notify_user_info_add_pair(user_info, field_infos[index].text, field_infos[index].choice[choice_num]);
 				break;
--- a/libpurple/protocols/qq/buddy_info.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/qq/buddy_info.h	Thu Feb 19 11:29:08 2009 +0000
@@ -31,7 +31,7 @@
 #include "buddy_opt.h"
 #include "qq.h"
 
-/* use is openq2005
+/* use in qq2005
  * ext_flag: (0-7)
  *        bit1 => qq space
  * comm_flag: (0-7)
--- a/libpurple/protocols/qq/group_im.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/qq/group_im.c	Thu Feb 19 11:29:08 2009 +0000
@@ -165,6 +165,7 @@
 		guint32 room_id, guint32 uid_from, const gchar *msg, time_t in_time)
 {
 	PurpleConversation *conv;
+	qq_data *qd;
 	qq_buddy_data *bd;
 	qq_room_data *rmd;
 	gchar *from;
@@ -172,15 +173,17 @@
 	g_return_if_fail(gc != NULL && room_id != 0);
 	g_return_if_fail(msg != NULL);
 
+	qd = (qq_data *)gc->proto_data;
 	conv = purple_find_chat(gc, room_id);
 	rmd = qq_room_data_find(gc, room_id);
 	g_return_if_fail(rmd != NULL);
 
-	if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/auto_popup_conversation")) {
+	purple_debug_info("QQ", "is_show_chat:%d\n", qd->is_show_chat);
+	if (NULL == conv && qd->is_show_chat) {
 		conv = qq_room_conv_open(gc, rmd);
 	}
 
-	if (conv == NULL) {
+	if (NULL == conv) {
 		purple_debug_info("QQ", "Conversion of %u is not open, missing from %d:/n%s/v",
 				room_id, uid_from, msg);
 		return;
--- a/libpurple/protocols/qq/qq.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/qq/qq.c	Thu Feb 19 11:29:08 2009 +0000
@@ -173,6 +173,7 @@
 
 	qd->is_show_notice = purple_account_get_bool(account, "show_notice", TRUE);
 	qd->is_show_news = purple_account_get_bool(account, "show_news", TRUE);
+	qd->is_show_chat = purple_account_get_bool(account, "show_chat", TRUE);
 
 	qd->resend_times = purple_prefs_get_int("/plugins/prpl/qq/resend_times");
 	if (qd->resend_times <= 1) qd->itv_config.resend = 4;
@@ -1097,6 +1098,9 @@
 	option = purple_account_option_bool_new(_("Show server news"), "show_news", TRUE);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
+	option = purple_account_option_bool_new(_("Show chat room when msg comes"), "show_chat", TRUE);
+	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
+
 	option = purple_account_option_int_new(_("Keep alive interval (seconds)"), "keep_alive_interval", 60);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
@@ -1106,7 +1110,6 @@
 	purple_prefs_add_none("/plugins/prpl/qq");
 	purple_prefs_add_bool("/plugins/prpl/qq/show_status_by_icon", TRUE);
 	purple_prefs_add_bool("/plugins/prpl/qq/show_fake_video", FALSE);
-	purple_prefs_add_bool("/plugins/prpl/qq/auto_popup_conversation", TRUE);
 	purple_prefs_add_bool("/plugins/prpl/qq/auto_get_authorize_info", TRUE);
 	purple_prefs_add_int("/plugins/prpl/qq/resend_interval", 3);
 	purple_prefs_add_int("/plugins/prpl/qq/resend_times", 10);
--- a/libpurple/protocols/qq/qq.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/qq/qq.h	Thu Feb 19 11:29:08 2009 +0000
@@ -182,6 +182,7 @@
 
 	gboolean is_show_notice;
 	gboolean is_show_news;
+	gboolean is_show_chat;
 
 	guint16 send_im_id;		/* send IM sequence number */
 };
--- a/libpurple/protocols/qq/qq_network.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/qq/qq_network.c	Thu Feb 19 11:29:08 2009 +0000
@@ -214,7 +214,7 @@
 		qd->connect_retry = QQ_CONNECT_MAX;
 	}
 
-	segments = g_strsplit(qd->curr_server, ":", 0);
+	segments = g_strsplit_set(qd->curr_server, ":", 0);
 	tmp_server = g_strdup(segments[0]);
 	if (NULL != segments[1]) {
 		port = atoi(segments[1]);
--- a/libpurple/protocols/silc10/silc.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/silc10/silc.c	Thu Feb 19 11:29:08 2009 +0000
@@ -1957,4 +1957,4 @@
 #endif
 }
 
-PURPLE_INIT_PLUGIN(silc, init_plugin, info);
+PURPLE_INIT_PLUGIN(silc10, init_plugin, info);
--- a/libpurple/protocols/simple/simple.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/protocols/simple/simple.c	Thu Feb 19 11:29:08 2009 +0000
@@ -196,7 +196,7 @@
 {
 	struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data;
 	struct simple_buddy *b;
-	if(strcmp("sip:", buddy->name)) {
+	if(strncmp(buddy->name, "sip:", 4)) {
 		gchar *buf = g_strdup_printf("sip:%s", buddy->name);
 		purple_blist_rename_buddy(buddy, buf);
 		g_free(buf);
@@ -834,10 +834,10 @@
 		"Event: presence\r\n",
 		expiration);
 
-	if(strstr(buddy->name, "sip:"))
+	if(strncmp(buddy->name, "sip:", 4))
+		to = g_strdup_printf("sip:%s", buddy->name);
+	else
 		to = g_strdup(buddy->name);
-	else
-		to = g_strdup_printf("sip:%s", buddy->name);
 
 	tmp = get_contact(sip);
 	contact = g_strdup_printf("%sContact: %s\r\n", tmp2, tmp);
@@ -881,7 +881,7 @@
 
 
 	tmp = sipmsg_find_header(msg, "Event");
-	if(tmp && !strcmp(tmp, "vnd-microsoft-roaming-contacts")){
+	if(tmp && !strncmp(tmp, "vnd-microsoft-roaming-contacts", 30)){
 
 		purple_debug_info("simple", "simple_add_lcs_contacts->%s-%d\n", msg->body, len);
 		/*Convert the contact from XML to Purple Buddies*/
@@ -1013,11 +1013,11 @@
 static void simple_send_message(struct simple_account_data *sip, const char *to, const char *msg, const char *type) {
 	gchar *hdr;
 	gchar *fullto;
-	if(strcmp("sip:", to)) {
+	if(strncmp(to, "sip:", 4))
 		fullto = g_strdup_printf("sip:%s", to);
-	} else {
+	else
 		fullto = g_strdup(to);
-	}
+
 	if(type) {
 		hdr = g_strdup_printf("Content-Type: %s\r\n", type);
 	} else {
@@ -1050,12 +1050,12 @@
 	purple_debug(PURPLE_DEBUG_MISC, "simple", "got message from %s: %s\n", from, msg->body);
 
 	contenttype = sipmsg_find_header(msg, "Content-Type");
-	if(!contenttype || !strcmp(contenttype, "text/plain") || !strcmp(contenttype, "text/html")) {
+	if(!contenttype || !strncmp(contenttype, "text/plain", 10) || !strncmp(contenttype, "text/html", 9)) {
 		serv_got_im(sip->gc, from, msg->body, 0, time(NULL));
 		send_sip_response(sip->gc, msg, 200, "OK", NULL);
 		found = TRUE;
 	}
-	else if(!strcmp(contenttype, "application/im-iscomposing+xml")) {
+	else if(!strncmp(contenttype, "application/im-iscomposing+xml", 30)) {
 		xmlnode *isc = xmlnode_from_str(msg->body, msg->bodylen);
 		xmlnode *state;
 		gchar *statedata;
--- a/libpurple/proxy.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/proxy.c	Thu Feb 19 11:29:08 2009 +0000
@@ -1177,56 +1177,47 @@
 }
 
 static void
-s4_canwrite(gpointer data, gint source, PurpleInputCondition cond)
+s4_host_resolved(GSList *hosts, gpointer data, const char *error_message)
 {
-	unsigned char packet[9];
-	struct hostent *hp;
 	PurpleProxyConnectData *connect_data = data;
-	int error = ETIMEDOUT;
-	int ret;
-
-	purple_debug_info("socks4 proxy", "Connected.\n");
+	unsigned char packet[9];
+	struct sockaddr *addr;
 
-	if (connect_data->inpa > 0)
-	{
-		purple_input_remove(connect_data->inpa);
-		connect_data->inpa = 0;
-	}
+	connect_data->query_data = NULL;
 
-	ret = purple_input_get_error(connect_data->fd, &error);
-	if ((ret != 0) || (error != 0))
-	{
-		if (ret != 0)
-			error = errno;
-		purple_proxy_connect_data_disconnect(connect_data, g_strerror(error));
+	if (error_message != NULL) {
+		purple_proxy_connect_data_disconnect(connect_data, error_message);
 		return;
 	}
 
-	/*
-	 * The socks4 spec doesn't include support for doing host name
-	 * lookups by the proxy.  Some socks4 servers do this via
-	 * extensions to the protocol.  Since we don't know if a
-	 * server supports this, it would need to be implemented
-	 * with an option, or some detection mechanism - in the
-	 * meantime, stick with plain old SOCKS4.
-	 */
-	/* TODO: Use purple_dnsquery_a() */
-	hp = gethostbyname(connect_data->host);
-	if (hp == NULL) {
+	if (hosts == NULL) {
 		purple_proxy_connect_data_disconnect_formatted(connect_data,
 				_("Error resolving %s"), connect_data->host);
 		return;
 	}
 
-	packet[0] = 4;
-	packet[1] = 1;
+	/* Discard the length... */
+	hosts = g_slist_delete_link(hosts, hosts);
+	addr = hosts->data;
+	hosts = g_slist_delete_link(hosts, hosts);
+
+	packet[0] = 0x04;
+	packet[1] = 0x01;
 	packet[2] = connect_data->port >> 8;
 	packet[3] = connect_data->port & 0xff;
-	packet[4] = (unsigned char)(hp->h_addr_list[0])[0];
-	packet[5] = (unsigned char)(hp->h_addr_list[0])[1];
-	packet[6] = (unsigned char)(hp->h_addr_list[0])[2];
-	packet[7] = (unsigned char)(hp->h_addr_list[0])[3];
-	packet[8] = 0;
+	memcpy(packet + 4, &((struct sockaddr_in *)addr)->sin_addr.s_addr, 4);
+	packet[8] = 0x00;
+
+	g_free(addr);
+
+	/* We could try the other hosts, but hopefully that shouldn't be necessary */
+	while (hosts != NULL) {
+		/* Discard the length... */
+		hosts = g_slist_delete_link(hosts, hosts);
+		/* Free the address... */
+		g_free(hosts->data);
+		hosts = g_slist_delete_link(hosts, hosts);
+	}
 
 	connect_data->write_buffer = g_memdup(packet, sizeof(packet));
 	connect_data->write_buf_len = sizeof(packet);
@@ -1235,7 +1226,74 @@
 
 	connect_data->inpa = purple_input_add(connect_data->fd, PURPLE_INPUT_WRITE, proxy_do_write, connect_data);
 
-	proxy_do_write(connect_data, connect_data->fd, cond);
+	proxy_do_write(connect_data, connect_data->fd, PURPLE_INPUT_WRITE);
+}
+
+static void
+s4_canwrite(gpointer data, gint source, PurpleInputCondition cond)
+{
+	PurpleProxyConnectData *connect_data = data;
+	int error = ETIMEDOUT;
+	int ret;
+
+	purple_debug_info("socks4 proxy", "Connected.\n");
+
+	if (connect_data->inpa > 0) {
+		purple_input_remove(connect_data->inpa);
+		connect_data->inpa = 0;
+	}
+
+	ret = purple_input_get_error(connect_data->fd, &error);
+	if ((ret != 0) || (error != 0)) {
+		if (ret != 0)
+			error = errno;
+		purple_proxy_connect_data_disconnect(connect_data, g_strerror(error));
+		return;
+	}
+
+	/*
+	 * The socks4 spec doesn't include support for doing host name lookups by
+	 * the proxy.  Many socks4 servers do this via the "socks4a" extension to
+	 * the protocol.  There doesn't appear to be a way to detect if a server
+	 * supports this, so we require that the user set a global option.
+	 */
+	if (purple_prefs_get_bool("/purple/proxy/socks4_remotedns")) {
+		unsigned char packet[9];
+		int len;
+
+		purple_debug_info("socks4 proxy", "Attempting to use remote DNS.\n");
+
+		packet[0] = 0x04;
+		packet[1] = 0x01;
+		packet[2] = connect_data->port >> 8;
+		packet[3] = connect_data->port & 0xff;
+		packet[4] = 0x00;
+		packet[5] = 0x00;
+		packet[6] = 0x00;
+		packet[7] = 0x01;
+		packet[8] = 0x00;
+
+		len = sizeof(packet) + strlen(connect_data->host) + 1;
+
+		connect_data->write_buffer = g_malloc0(len);
+		memcpy(connect_data->write_buffer, packet, sizeof(packet));
+		memcpy(connect_data->write_buffer + sizeof(packet), connect_data->host, strlen(connect_data->host));
+		connect_data->write_buf_len = len;
+		connect_data->written_len = 0;
+		connect_data->read_cb = s4_canread;
+
+		connect_data->inpa = purple_input_add(connect_data->fd, PURPLE_INPUT_WRITE, proxy_do_write, connect_data);
+
+		proxy_do_write(connect_data, connect_data->fd, PURPLE_INPUT_WRITE);
+	} else {
+		connect_data->query_data = purple_dnsquery_a(connect_data->host,
+				connect_data->port, s4_host_resolved, connect_data);
+
+		if (connect_data->query_data == NULL) {
+			purple_debug_error("proxy", "dns query failed unexpectedly.\n");
+			purple_proxy_connect_data_destroy(connect_data);
+		}
+	}
 }
 
 static void
@@ -1396,7 +1454,7 @@
 s5_sendconnect(gpointer data, int source)
 {
 	PurpleProxyConnectData *connect_data = data;
-	int hlen = strlen(connect_data->host);
+	size_t hlen = strlen(connect_data->host);
 	connect_data->write_buf_len = 5 + hlen + 2;
 	connect_data->write_buffer = g_malloc(connect_data->write_buf_len);
 	connect_data->written_len = 0;
@@ -1479,7 +1537,7 @@
 	int i;
 	unsigned char Kxoripad[65];
 	unsigned char Kxoropad[65];
-	int pwlen;
+	size_t pwlen;
 
 	cipher = purple_ciphers_find_cipher("md5");
 	ctx = purple_cipher_context_new(cipher, NULL);
@@ -1697,7 +1755,7 @@
 			return;
 
 		msg_ret = s5_parse_chap_msg(connect_data);
-	
+
 		if (msg_ret < 0)
 			return;
 
@@ -1777,7 +1835,7 @@
 	}
 
 	if (connect_data->read_buffer[1] == 0x02) {
-		gsize i, j;
+		size_t i, j;
 		const char *u, *p;
 
 		u = purple_proxy_info_get_username(connect_data->gpi);
@@ -1810,7 +1868,7 @@
 
 		return;
 	} else if (connect_data->read_buffer[1] == 0x03) {
-		gsize userlen;
+		size_t userlen;
 		userlen = strlen(purple_proxy_info_get_username(connect_data->gpi));
 
 		connect_data->write_buf_len = 7 + userlen;
@@ -1957,7 +2015,7 @@
 
 static void try_connect(PurpleProxyConnectData *connect_data)
 {
-	size_t addrlen;
+	socklen_t addrlen;
 	struct sockaddr *addr;
 	char ipaddr[INET6_ADDRSTRLEN];
 
@@ -1969,7 +2027,7 @@
 	inet_ntop(addr->sa_family, &((struct sockaddr_in *)addr)->sin_addr,
 			ipaddr, sizeof(ipaddr));
 #else
-	memcpy(ipaddr,inet_ntoa(((struct sockaddr_in *)addr)->sin_addr),
+	memcpy(ipaddr, inet_ntoa(((struct sockaddr_in *)addr)->sin_addr),
 			sizeof(ipaddr));
 #endif
 	purple_debug_info("proxy", "Attempting connection to %s\n", ipaddr);
@@ -2293,6 +2351,7 @@
 	purple_prefs_add_int("/purple/proxy/port", 0);
 	purple_prefs_add_string("/purple/proxy/username", "");
 	purple_prefs_add_string("/purple/proxy/password", "");
+	purple_prefs_add_bool("/purple/proxy/socks4_remotedns", FALSE);
 
 	/* Setup callbacks for the preferences. */
 	handle = purple_proxy_get_handle();
--- a/libpurple/savedstatuses.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/savedstatuses.c	Thu Feb 19 11:29:08 2009 +0000
@@ -148,11 +148,11 @@
 	/* Avoid using 0 because it's an invalid hash key */
 	status->creation_time = creation_time != 0 ? creation_time : 1;
 
-	while (g_hash_table_lookup(creation_times, &status->creation_time) != NULL)
+	while (g_hash_table_lookup(creation_times, (gconstpointer)status->creation_time) != NULL)
 		status->creation_time++;
 
 	g_hash_table_insert(creation_times,
-						&status->creation_time,
+						(gpointer)status->creation_time,
 						status);
 }
 
@@ -217,7 +217,7 @@
 				{
 					saved_statuses = g_list_remove(saved_statuses, saved_status);
 					creation_time = purple_savedstatus_get_creation_time(saved_status);
-					g_hash_table_remove(creation_times, &creation_time);
+					g_hash_table_remove(creation_times, (gconstpointer)creation_time);
 					free_saved_status(saved_status);
 				}
 			}
@@ -713,7 +713,7 @@
 
 	saved_statuses = g_list_remove(saved_statuses, status);
 	creation_time = purple_savedstatus_get_creation_time(status);
-	g_hash_table_remove(creation_times, &creation_time);
+	g_hash_table_remove(creation_times, (gconstpointer)creation_time);
 	free_saved_status(status);
 
 	schedule_save();
@@ -801,13 +801,13 @@
 PurpleSavedStatus *
 purple_savedstatus_get_default()
 {
-	int creation_time;
+	time_t creation_time;
 	PurpleSavedStatus *saved_status = NULL;
 
 	creation_time = purple_prefs_get_int("/purple/savedstatus/default");
 
 	if (creation_time != 0)
-		saved_status = g_hash_table_lookup(creation_times, &creation_time);
+		saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time);
 
 	if (saved_status == NULL)
 	{
@@ -828,13 +828,13 @@
 PurpleSavedStatus *
 purple_savedstatus_get_idleaway()
 {
-	int creation_time;
+	time_t creation_time;
 	PurpleSavedStatus *saved_status = NULL;
 
 	creation_time = purple_prefs_get_int("/purple/savedstatus/idleaway");
 
 	if (creation_time != 0)
-		saved_status = g_hash_table_lookup(creation_times, &creation_time);
+		saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time);
 
 	if (saved_status == NULL)
 	{
@@ -907,13 +907,13 @@
 PurpleSavedStatus *
 purple_savedstatus_get_startup()
 {
-	int creation_time;
+	time_t creation_time;
 	PurpleSavedStatus *saved_status = NULL;
 
 	creation_time = purple_prefs_get_int("/purple/savedstatus/startup");
 
 	if (creation_time != 0)
-		saved_status = g_hash_table_lookup(creation_times, &creation_time);
+		saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time);
 
 	if (saved_status == NULL)
 	{
@@ -1187,7 +1187,7 @@
 {
 	void *handle = purple_savedstatuses_get_handle();
 
-	creation_times = g_hash_table_new(g_int_hash, g_int_equal);
+	creation_times = g_hash_table_new(g_direct_hash, g_direct_equal);
 
 	/*
 	 * Using 0 as the creation_time is a special case.
--- a/libpurple/sslconn.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/sslconn.h	Thu Feb 19 11:29:08 2009 +0000
@@ -39,6 +39,7 @@
 
 #define PURPLE_SSL_DEFAULT_PORT 443
 
+/** @copydoc _PurpleSslConnection */
 typedef struct _PurpleSslConnection PurpleSslConnection;
 
 typedef void (*PurpleSslInputFunction)(gpointer, PurpleSslConnection *,
--- a/libpurple/upnp.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/upnp.c	Thu Feb 19 11:29:08 2009 +0000
@@ -567,7 +567,7 @@
 purple_upnp_discover_send_broadcast(UPnPDiscoveryData *dd)
 {
 	gchar *sendMessage = NULL;
-	gsize totalSize;
+	size_t totalSize;
 	gboolean sentSuccess;
 
 	/* because we are sending over UDP, if there is a failure
@@ -693,6 +693,7 @@
 		/* XXX: This should probably be async */
 		if(cb)
 			cb(NULL, cb_data, NULL, 0, NULL);
+		return NULL;
 	}
 	if(port == 0 || port == -1) {
 		port = DEFAULT_HTTP_PORT;
@@ -711,11 +712,11 @@
 	g_free(soapMessage);
 
 	gfud = purple_util_fetch_url_request_len(control_info.control_url, FALSE, NULL, TRUE,
-				totalSendMessage,  TRUE, MAX_UPNP_DOWNLOAD, cb, cb_data);
+				totalSendMessage, TRUE, MAX_UPNP_DOWNLOAD, cb, cb_data);
 
 	g_free(totalSendMessage);
 	g_free(addressOfControl);
-	
+
 	return gfud;
 }
 
--- a/libpurple/util.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/util.h	Thu Feb 19 11:29:08 2009 +0000
@@ -1207,7 +1207,7 @@
 G_CONST_RETURN gchar *purple_gai_strerror(gint errnum);
 
 /**
- * Compares two UTF-8 strings case-insensitively.  This string is
+ * Compares two UTF-8 strings case-insensitively.  This comparison is
  * more expensive than a simple g_utf8_collate() comparison because
  * it calls g_utf8_casefold() on each string, which allocates new
  * strings.
--- a/libpurple/version.h.in	Thu Feb 19 11:28:01 2009 +0000
+++ b/libpurple/version.h.in	Thu Feb 19 11:29:08 2009 +0000
@@ -24,8 +24,11 @@
 #ifndef _PURPLE_VERSION_H_
 #define _PURPLE_VERSION_H_
 
+/** The major version of the running libpurple. */
 #define PURPLE_MAJOR_VERSION (@PURPLE_MAJOR_VERSION@)
+/** The minor version of the running libpurple. */
 #define PURPLE_MINOR_VERSION (@PURPLE_MINOR_VERSION@)
+/** The micro version of the running libpurple. */
 #define PURPLE_MICRO_VERSION (@PURPLE_MICRO_VERSION@)
 
 #define PURPLE_VERSION_CHECK(x,y,z) ((x) == PURPLE_MAJOR_VERSION && \
--- a/pidgin/gtkblist.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/gtkblist.c	Thu Feb 19 11:29:08 2009 +0000
@@ -66,7 +66,7 @@
 #include <gtk/gtk.h>
 #include <gdk/gdk.h>
 
-#define HEADLINE_CLOSE_SIZE 12
+#define HEADLINE_CLOSE_SIZE 11
 
 typedef struct
 {
@@ -4602,6 +4602,9 @@
 	if (!gtkblist)
 		return FALSE;
 
+	/* clear any tooltips */
+	pidgin_blist_tooltip_destroy();
+
 	widget = gtk_window_get_focus(GTK_WINDOW(gtkblist->window));
 
 	if (GTK_IS_IMHTML(widget) || GTK_IS_ENTRY(widget)) {
@@ -5435,7 +5438,8 @@
 			  NULL);
 	gtk_widget_set_name(gtkblist->headline_hbox, "gtk-tooltips");
 
-	gtkblist->headline_close = gtk_widget_render_icon(ebox, GTK_STOCK_CLOSE, HEADLINE_CLOSE_SIZE, NULL);
+	gtkblist->headline_close = gtk_widget_render_icon(ebox, GTK_STOCK_CLOSE,
+		gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC), NULL);
 	gtkblist->hand_cursor = gdk_cursor_new (GDK_HAND2);
 	gtkblist->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR);
 
@@ -7724,13 +7728,11 @@
 			if (!disabled_accounts) {
 				menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
 				gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
-				gtk_widget_show(menuitem);
 
 				submenu = gtk_menu_new();
 				gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
 				gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
 				gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-				gtk_widget_show(submenu);
 
 				disabled_accounts = TRUE;
 			}
@@ -7752,7 +7754,6 @@
 			g_signal_connect(G_OBJECT(menuitem), "activate",
 				G_CALLBACK(enable_account_cb), account);
 			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-			gtk_widget_show(menuitem);
 		} else {
 			enabled_accounts = TRUE;
 		}
@@ -7794,21 +7795,18 @@
 			gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
 		}
 		gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
-		gtk_widget_show(menuitem);
 
 		submenu = gtk_menu_new();
 		gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
 		gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path_buf);
 		g_free(accel_path_buf);
 		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-		gtk_widget_show(submenu);
 
 
 		menuitem = gtk_menu_item_new_with_mnemonic(_("_Edit Account"));
 		g_signal_connect(G_OBJECT(menuitem), "activate",
 				G_CALLBACK(modify_account_cb), account);
 		gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-		gtk_widget_show(menuitem);
 
 		pidgin_separator(submenu);
 
@@ -7820,7 +7818,6 @@
 			menuitem = gtk_menu_item_new_with_label(_("No actions available"));
 			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
 			gtk_widget_set_sensitive(menuitem, FALSE);
-			gtk_widget_show(menuitem);
 		}
 
 		pidgin_separator(submenu);
@@ -7829,8 +7826,8 @@
 		g_signal_connect(G_OBJECT(menuitem), "activate",
 				G_CALLBACK(disable_account_cb), account);
 		gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-		gtk_widget_show(menuitem);
-	}
+	}
+	gtk_widget_show_all(accountmenu);
 }
 
 static GList *plugin_submenus = NULL;
@@ -7869,13 +7866,11 @@
 
 		menuitem = gtk_image_menu_item_new_with_label(_(plugin->info->name));
 		gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem);
-		gtk_widget_show(menuitem);
 
 		plugin_submenus = g_list_append(plugin_submenus, menuitem);
 
 		submenu = gtk_menu_new();
 		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-		gtk_widget_show(submenu);
 
 		gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
 		path = g_strdup_printf("%s/Tools/%s", gtkblist->ift->path, plugin->info->name);
@@ -7884,6 +7879,7 @@
 
 		build_plugin_actions(submenu, plugin, NULL);
 	}
+	gtk_widget_show_all(pluginmenu);
 }
 
 static void
--- a/pidgin/gtkblist.h	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/gtkblist.h	Thu Feb 19 11:29:08 2009 +0000
@@ -27,6 +27,7 @@
 #ifndef _PIDGINBLIST_H_
 #define _PIDGINBLIST_H_
 
+/** @copydoc _PidginBuddyList */
 typedef struct _PidginBuddyList PidginBuddyList;
 
 enum {
--- a/pidgin/gtkconv.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/gtkconv.c	Thu Feb 19 11:29:08 2009 +0000
@@ -1976,6 +1976,9 @@
 	win      = gtkconv->win;
 	curconv = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->notebook));
 
+	/* clear any tooltips */
+	pidgin_tooltip_destroy();
+
 	/* If CTRL was held down... */
 	if (event->state & GDK_CONTROL_MASK) {
 		switch (event->keyval) {
--- a/pidgin/gtkdialogs.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/gtkdialogs.c	Thu Feb 19 11:29:08 2009 +0000
@@ -457,12 +457,17 @@
 		  "warranty for this program.<BR><BR>"), PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME);
 
 	g_string_append(str, "<FONT SIZE=\"4\">URL:</FONT> <A HREF=\""
-					PURPLE_WEBSITE "\">" PURPLE_WEBSITE "</A><BR/><BR/>");
-	g_string_append(str, "<FONT SIZE=\"4\">FAQ:</FONT> <A HREF=\""
-			"http://developer.pidgin.im/wiki/FAQ\">"
-			"http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>");
-	g_string_append_printf(str, _("<FONT SIZE=\"4\">IRC:</FONT> "
-						   "#pidgin on irc.freenode.net<BR><BR>"));
+				PURPLE_WEBSITE "\">" PURPLE_WEBSITE "</A><BR/><BR/>");
+	g_string_append_printf(str, _("<FONT SIZE=\"4\">FAQ:</FONT> <A HREF=\""
+				"http://developer.pidgin.im/wiki/FAQ\">"
+				"http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>"));
+	g_string_append_printf(str, _("<FONT SIZE=\"4\">Help via e-mail:</FONT>"
+				" <A HREF=\"mailto:support@pidgin.im\">support@pidgin.im</A>"
+				"<BR/><BR/>"));
+	g_string_append_printf(str, _("<FONT SIZE=\"4\">IRC Channel:</FONT> "
+				"#pidgin on irc.freenode.net<BR><BR>"));
+	g_string_append_printf(str, _("<FONT SIZE=\"4\">XMPP MUC:</FONT> "
+				"devel@conference.pidgin.im<BR><BR>"));
 
 	/* Current Developers */
 	g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
--- a/pidgin/gtkdocklet.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/gtkdocklet.c	Thu Feb 19 11:29:08 2009 +0000
@@ -88,13 +88,16 @@
 static GList *
 get_pending_list(guint max)
 {
-	GList *l_im = NULL;
-	GList *l_chat = NULL;
+	GList *l_im, *l_chat;
 
 	l_im = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM,
 						       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);
@@ -344,7 +347,9 @@
 docklet_menu_leave_enter(GtkWidget *menu, GdkEventCrossing *event, void *data)
 {
 	static guint hide_docklet_timer = 0;
-	if (event->type == GDK_LEAVE_NOTIFY && event->detail == GDK_NOTIFY_ANCESTOR) {
+
+	if (event->type == GDK_LEAVE_NOTIFY && (event->detail == GDK_NOTIFY_ANCESTOR ||
+			event->detail == GDK_NOTIFY_UNKNOWN)) {
 		purple_debug(PURPLE_DEBUG_INFO, "docklet", "menu leave-notify-event\n");
 		/* Add some slop so that the menu doesn't annoyingly disappear when mousing around */
 		if (hide_docklet_timer == 0) {
@@ -652,11 +657,9 @@
 
 		menuitem = gtk_image_menu_item_new_with_label(_(plugin->info->name));
 		gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-		gtk_widget_show(menuitem);
 
 		submenu = gtk_menu_new();
 		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-		gtk_widget_show(submenu);
 
 		build_plugin_actions(submenu, plugin, NULL);
 
--- a/pidgin/gtkprefs.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/gtkprefs.c	Thu Feb 19 11:29:08 2009 +0000
@@ -1439,6 +1439,10 @@
 		purple_prefs_connect_callback(prefs, "/purple/proxy/type",
 					    proxy_changed_cb, prefs_proxy_frame);
 
+		/* This is a global option that affects SOCKS4 usage even with account-specific proxy settings */
+		pidgin_prefs_checkbox(_("Use remote DNS with SOCKS4 proxies"),
+							  "/purple/proxy/socks4_remotedns", prefs_proxy_frame);
+
 		table = gtk_table_new(4, 2, FALSE);
 		gtk_container_set_border_width(GTK_CONTAINER(table), 0);
 		gtk_table_set_col_spacings(GTK_TABLE(table), 5);
--- a/pidgin/pidgintooltip.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/pidgintooltip.c	Thu Feb 19 11:29:08 2009 +0000
@@ -135,14 +135,14 @@
 setup_tooltip_window_position(gpointer data, int w, int h)
 {
 	int sig;
-	int scr_w, scr_h, x, y;
+	int scr_w, scr_h, x, y, dy;
 #if GTK_CHECK_VERSION(2,2,0)
 	int mon_num;
 	GdkScreen *screen = NULL;
 #endif
 	GdkRectangle mon_size;
 	GtkWidget *tipwindow = pidgin_tooltip.tipwindow;
-
+	
 #if GTK_CHECK_VERSION(2,2,0)
 	gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, NULL);
 	mon_num = gdk_screen_get_monitor_at_point(screen, x, y);
@@ -158,6 +158,12 @@
 	mon_size.y = 0;
 #endif
 
+#if GTK_CHECK_VERSION(2,4,0)
+	dy = gdk_display_get_default_cursor_size(gdk_display_get_default()) / 2;
+#else
+	dy = 0;
+#endif
+
 #if GTK_CHECK_VERSION(2,2,0)
 	if (w > mon_size.width)
 		w = mon_size.width - 10;
@@ -168,9 +174,9 @@
 	x -= ((w >> 1) + 4);
 
 	if ((y + h + 4) > scr_h)
-		y = y - h - 5;
+		y = y - h - dy - 5;
 	else
-		y = y + 6;
+		y = y + dy + 6;
 
 	if (y < mon_size.y)
 		y = mon_size.y;
@@ -353,6 +359,7 @@
 
 	g_signal_connect(G_OBJECT(tree), "motion-notify-event", G_CALLBACK(row_motion_cb), tdata);
 	g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL);
+	g_signal_connect(G_OBJECT(tree), "scroll-event", G_CALLBACK(widget_leave_cb), NULL);
 	g_signal_connect_swapped(G_OBJECT(tree), "destroy", G_CALLBACK(destroy_tooltip_data), tdata);
 	return TRUE;
 }
@@ -381,6 +388,7 @@
 
 	g_signal_connect(G_OBJECT(widget), "motion-notify-event", G_CALLBACK(widget_motion_cb), wdata);
 	g_signal_connect(G_OBJECT(widget), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL);
+	g_signal_connect(G_OBJECT(widget), "scroll-event", G_CALLBACK(widget_leave_cb), NULL);
 	g_signal_connect_swapped(G_OBJECT(widget), "destroy", G_CALLBACK(destroy_tooltip_data), wdata);
 	return TRUE;
 }
--- a/pidgin/plugins/convcolors.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/plugins/convcolors.c	Thu Feb 19 11:29:08 2009 +0000
@@ -21,7 +21,7 @@
 
 #define PLUGIN_ID			"gtk-plugin_pack-convcolors"
 #define PLUGIN_NAME			N_("Conversation Colors")
-#define PLUGIN_STATIC_NAME	"Conversation Colors"
+#define PLUGIN_STATIC_NAME	ConversationColors
 #define PLUGIN_SUMMARY		N_("Customize colors in the conversation window")
 #define PLUGIN_DESCRIPTION	N_("Customize colors in the conversation window")
 #define PLUGIN_AUTHOR		"Sadrul H Chowdhury <sadrul@users.sourceforge.net>"
--- a/pidgin/plugins/markerline.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/plugins/markerline.c	Thu Feb 19 11:29:08 2009 +0000
@@ -21,7 +21,7 @@
 
 #define PLUGIN_ID			"gtk-plugin_pack-markerline"
 #define PLUGIN_NAME			N_("Markerline")
-#define PLUGIN_STATIC_NAME	"Markerline"
+#define PLUGIN_STATIC_NAME	Markerline
 #define PLUGIN_SUMMARY		N_("Draw a line to indicate new messages in a conversation.")
 #define PLUGIN_DESCRIPTION	N_("Draw a line to indicate new messages in a conversation.")
 #define PLUGIN_AUTHOR		"Sadrul H Chowdhury <sadrul@users.sourceforge.net>"
--- a/pidgin/plugins/pidgininc.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/plugins/pidgininc.c	Thu Feb 19 11:29:08 2009 +0000
@@ -6,7 +6,7 @@
 #include "conversation.h"
 #include "version.h"
 
-/* include UI for pidgindialogs_about() */
+/* include UI for pidgin_dialogs_about() */
 #include "gtkplugin.h"
 #include "gtkdialogs.h"
 
@@ -16,7 +16,7 @@
 echo_hi(PurpleConnection *gc)
 {
 	/* this doesn't do much, just lets you know who we are :) */
-	pidgindialogs_about();
+	pidgin_dialogs_about();
 }
 
 static gboolean
@@ -108,7 +108,12 @@
 	NULL,                                             /**< ui_info        */
 	NULL,                                             /**< extra_info     */
 	NULL,                                             /**< prefs_info     */
-	NULL                                              /**< actions        */
+	NULL,                                             /**< actions        */
+	/* padding */
+	NULL,
+	NULL,
+	NULL,
+	NULL
 };
 
 static void
--- a/pidgin/plugins/timestamp.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/plugins/timestamp.c	Thu Feb 19 11:29:08 2009 +0000
@@ -229,4 +229,4 @@
 	purple_prefs_add_int("/plugins/gtk/timestamp/interval", interval * 1000);
 }
 
-PURPLE_INIT_PLUGIN(interval, init_plugin, info)
+PURPLE_INIT_PLUGIN(timestamp, init_plugin, info)
--- a/pidgin/plugins/xmppconsole.c	Thu Feb 19 11:28:01 2009 +0000
+++ b/pidgin/plugins/xmppconsole.c	Thu Feb 19 11:29:08 2009 +0000
@@ -890,4 +890,4 @@
 {
 }
 
-PURPLE_INIT_PLUGIN(interval, init_plugin, info)
+PURPLE_INIT_PLUGIN(xmppconsole, init_plugin, info)
--- a/po/de.po	Thu Feb 19 11:28:01 2009 +0000
+++ b/po/de.po	Thu Feb 19 11:29:08 2009 +0000
@@ -11,15 +11,15 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-09 00:39+0100\n"
-"PO-Revision-Date: 2009-01-09 00:38+0100\n"
-"Last-Translator: Bjoern Voigt <bjoern@cs.tu-berlin.de>\n"
-"Language-Team: Deutsch <de@li.org>\n"
+"POT-Creation-Date: 2009-02-18 21:09+0100\n"
+"PO-Revision-Date: 2009-02-18 21:09+0100\n"
+"Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n"
+"Language-Team: German <de@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: KBabel 1.11.4\n"
+"X-Generator: Lokalize 0.2\n"
 
 #. Translators may want to transliterate the name.
 #. It is not to be translated.
@@ -36,7 +36,7 @@
 "Usage: %s [OPTION]...\n"
 "\n"
 "  -c, --config=DIR    use DIR for config files\n"
-"  -d, --debug         print debugging messages to stdout\n"
+"  -d, --debug         print debugging messages to stderr\n"
 "  -h, --help          display this help and exit\n"
 "  -n, --nologin       don't automatically login\n"
 "  -v, --version       display the current version and exit\n"
@@ -45,7 +45,7 @@
 "Benutzung: %s [OPTION]...\n"
 "\n"
 "  -c, --config=VERZ   benutze VERZ als Konfigurationsverzeichnis\n"
-"  -d, --debug         drucke Debugging-Meldungen nach stdout\n"
+"  -d, --debug         drucke Debugging-Meldungen nach stderr\n"
 "  -h, --help          zeigt diese Hilfe und beendet das Programm\n"
 "  -n, --nologin       nicht automatisch anmelden\n"
 "  -v, --version       zeigt aktuelle Version und beendet das Programm\n"
@@ -1172,7 +1172,6 @@
 msgid "Change status to"
 msgstr "Ändere Status zu"
 
-#. Conversations
 msgid "Conversations"
 msgstr "Unterhaltungen"
 
@@ -4033,7 +4032,7 @@
 
 msgid "Nick changing not supported in non-MUC chatrooms"
 msgstr ""
-"Die Änderung des Nick-Namens wird in nicht-MUC Chaträumen nicht unterstützt"
+"Die Änderung des Nick-Namens wird in nicht-MUC-Chaträumen nicht unterstützt"
 
 msgid "Error retrieving room list"
 msgstr "Fehler beim Empfangen der Raumliste"
@@ -6975,6 +6974,7 @@
 msgid "Get AIM Info"
 msgstr "AIM-Info"
 
+#. We only do this if the user is in our buddy list
 msgid "Edit Buddy Comment"
 msgstr "Buddy-Kommentar bearbeiten"
 
@@ -7626,6 +7626,9 @@
 msgid "Show server news"
 msgstr "Server-News anzeigen"
 
+msgid "Show chat room when msg comes"
+msgstr "Chatraum zeigen, wenn Nachricht empfangen wird"
+
 msgid "Keep alive interval (seconds)"
 msgstr "Intervall zum Aufrechterhalten der Verbindung (Sekunden)"
 
@@ -11365,6 +11368,9 @@
 msgid "Macedonian"
 msgstr "Makedonisch"
 
+msgid "Mongolian"
+msgstr "Mongolisch"
+
 msgid "Bokmål Norwegian"
 msgstr "Bokmål Norwegisch"
 
@@ -11478,8 +11484,27 @@
 "geschützt.  Die Datei 'COPYRIGHT' enthält die komplette Liste der "
 "Mitwirkenden.  Wir übernehmen keine Haftung für dieses Programm.<BR><BR>"
 
-msgid "<FONT SIZE=\"4\">IRC:</FONT> #pidgin on irc.freenode.net<BR><BR>"
-msgstr "<FONT SIZE=\"4\">IRC:</FONT> #pidgin auf irc.freenode.net<BR><BR>"
+msgid ""
+"<FONT SIZE=\"4\">FAQ:</FONT> <A HREF=\"http://developer.pidgin.im/wiki/FAQ"
+"\">http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>"
+msgstr ""
+"<FONT SIZE=\"4\">FAQ:</FONT> <A HREF=\"http://developer.pidgin.im/wiki/FAQ"
+"\">http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>"
+
+msgid ""
+"<FONT SIZE=\"4\">Help via e-mail:</FONT> <A HREF=\"mailto:support@pidgin.im"
+"\">support@pidgin.im</A><BR/><BR/>"
+msgstr ""
+"<FONT SIZE=\"4\">Hilfe per E-Mail:</FONT> <A HREF=\"mailto:support@pidgin.im"
+"\">support@pidgin.im</A><BR/><BR/>"
+
+msgid ""
+"<FONT SIZE=\"4\">IRC Channel:</FONT> #pidgin on irc.freenode.net<BR><BR>"
+msgstr ""
+"<FONT SIZE=\"4\">IRC-Kanal:</FONT> #pidgin auf irc.freenode.net<BR><BR>"
+
+msgid "<FONT SIZE=\"4\">XMPP MUC:</FONT> devel@conference.pidgin.im<BR><BR>"
+msgstr "<FONT SIZE=\"4\">XMPP-MUC:</FONT> devel@conference.pidgin.im<BR><BR>"
 
 msgid "Current Developers"
 msgstr "Aktuelle Entwickler"
@@ -11908,7 +11933,7 @@
 msgstr "Dieses Thema verfügt über keine Smileys."
 
 msgid "_Font"
-msgstr "_Schrift"
+msgstr "S_chrift"
 
 msgid "Group Items"
 msgstr "Elemente gruppieren"
@@ -12143,6 +12168,9 @@
 msgid "Pidgin"
 msgstr "Pidgin"
 
+msgid "Exiting because another libpurple client is already running.\n"
+msgstr "Wird geschlossen, da bereits ein anderer libpurple-Client läuft\n"
+
 msgid "Open All Messages"
 msgstr "Alle Nachrichten öffnen"
 
@@ -12482,6 +12510,10 @@
 msgid "No proxy"
 msgstr "Kein Proxy"
 
+#. This is a global option that affects SOCKS4 usage even with account-specific proxy settings
+msgid "Use remote DNS with SOCKS4 proxies"
+msgstr "Remote-DNS mit SOCKS4-Proxys benuten"
+
 msgid "_User:"
 msgstr "_Benutzer:"
 
@@ -13938,9 +13970,6 @@
 msgid "Only when docked"
 msgstr "Nur wenn angedockt"
 
-msgid "_Flash window when chat messages are received"
-msgstr "_Fenster blinkt, wenn Chat-Nachrichten empfangen werden"
-
 msgid "Windows Pidgin Options"
 msgstr "Windows-Pidgin-Optionen"