changeset 25853:aa1fe87558d8

propagate from branch 'im.pidgin.pidgin' (head c3f6487e649e7fe5c5f960b9c86a256e09b3976e) to branch 'im.pidgin.pidgin.next.minor' (head 4a65748e82aa462266320a3bbb78e0170a25ff4b)
author Richard Laager <rlaager@wiktel.com>
date Sun, 30 Nov 2008 06:25:26 +0000
parents b38cbefca6ad (current diff) 59c3a33ba3b6 (diff)
children a2da249d14a0
files libpurple/protocols/gg/buddylist.c libpurple/protocols/jabber/buddy.c libpurple/protocols/jabber/jabber.c pidgin/gtkconv.c pidgin/pidginstock.c pidgin/pixmaps/status/48/rtl/login.png pidgin/pixmaps/status/48/rtl/logout.png
diffstat 34 files changed, 201 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Fri Nov 28 06:06:35 2008 +0000
+++ b/COPYRIGHT	Sun Nov 30 06:25:26 2008 +0000
@@ -349,6 +349,7 @@
 Michael Ruprecht
 Sam S.
 Thanumalayan S.
+Jonathan Sailor
 Elliott Sales de Andrade
 Tomasz Sałaciński <tsalacinski@gmail.com>
 Pradyumna Sampath
--- a/ChangeLog	Fri Nov 28 06:06:35 2008 +0000
+++ b/ChangeLog	Sun Nov 30 06:25:26 2008 +0000
@@ -8,7 +8,6 @@
 	  --with-system-ssl-certs and GnuTLS need to include these in the
 	  system certs directory.
 	* Corrected maximum message lengths for Yahoo!
-	* Fix some problems with Gadu-Gadu buddy icons (Adam Strzelecki)
 	* Enable auto-reply on Zephyr, to emulate 'zaway' (Toby Schaffer)
 	* The Buddy State Notification plugin no longer prints duplicate
 	  notifications when the same buddy is in multiple groups (Florian Quèze)
@@ -16,6 +15,25 @@
 	  ID's, etc. into links (Florian Quèze)
 	* Fix a crash in SIMPLE when a malformed message is received.
 
+	Gadu-Gadu:
+	* Fix some problems with Gadu-Gadu buddy icons (Adam Strzelecki)
+	* Gadu-Gadu now validates that UID's are valid (Adam Strzelecki)
+	* Gadu-Gadu now does proper charset translations where needed (Adam
+	  Strzelecki)
+
+	XMPP:
+	* Fix the namespace URL we look for in PEP reply stanzas to match the URL
+	  used in the 'get' requests (Paul Aurich)
+	* Resources can be set to the local machine's hostname by using
+	  __HOSTNAME__ as the resource string (Jonathan Sailor)
+	* Resources can now be left blank, causing the server to generate a
+	  resource for us where supported (Jonathan Sailor)
+	* Resources now default to no value
+	* Quit trying to get user info for MUC's (Paul Aurich)
+	* Send "client-accepts-full-bind-result" attribute during SASL login.
+	  This will fix Google Talk login failures if the user configures the
+	  wrong domain for his/her account.
+
 	Pidgin:
 	* On GTK+ 2.14 and higher, we're using the gtk-tooltip-delay setting
 	  instead of our own (hidden) tooltip_delay pref.  If you had
--- a/finch/gntdebug.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/gntdebug.c	Sun Nov 30 06:25:26 2008 +0000
@@ -344,6 +344,7 @@
 	REGISTER_G_LOG_HANDLER("GModule");
 	REGISTER_G_LOG_HANDLER("GLib-GObject");
 	REGISTER_G_LOG_HANDLER("GThread");
+	REGISTER_G_LOG_HANDLER("Gnt");
 #ifdef USE_GSTREAMER
 	REGISTER_G_LOG_HANDLER("GStreamer");
 #endif
--- a/finch/libgnt/Makefile.am	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/Makefile.am	Sun Nov 30 06:25:26 2008 +0000
@@ -6,6 +6,8 @@
 
 lib_LTLIBRARIES = libgnt.la
 
+noinst_HEADERS = gntinternal.h
+
 BUILT_SOURCES = gntmarshal.h
 
 libgnt_la_SOURCES = \
--- a/finch/libgnt/gntbindable.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntbindable.c	Sun Nov 30 06:25:26 2008 +0000
@@ -22,6 +22,10 @@
 
 #include <string.h>
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "Bindable"
+
 #include "gntbindable.h"
 #include "gntstyle.h"
 #include "gnt.h"
@@ -360,7 +364,7 @@
 
 	action = g_hash_table_lookup(klass->actions, name);
 	if (!action) {
-		g_printerr("GntBindable: Invalid action name %s for %s\n",
+		gnt_warning("Invalid action name %s for %s",
 				name, g_type_name(G_OBJECT_CLASS_TYPE(klass)));
 		if (list)
 			g_list_free(list);
--- a/finch/libgnt/gntcolors.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntcolors.c	Sun Nov 30 06:25:26 2008 +0000
@@ -24,6 +24,10 @@
 
 #include <ncurses.h>
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "Colors"
+
 #include "gntcolors.h"
 #include "gntstyle.h"
 
@@ -182,7 +186,7 @@
 
 	if (error)
 	{
-		g_printerr("GntColors: %s\n", error->message);
+		gnt_warning("%s", error->message);
 		g_error_free(error);
 		error = NULL;
 	}
@@ -226,7 +230,7 @@
 
 	if (error)
 	{
-		g_printerr("GntColors: %s\n", error->message);
+		gnt_warning("%s", error->message);
 		g_error_free(error);
 		return;
 	}
--- a/finch/libgnt/gntentry.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntentry.c	Sun Nov 30 06:25:26 2008 +0000
@@ -365,7 +365,7 @@
 		return TRUE;
 
 	len = entry->cursor - g_utf8_find_prev_char(entry->start, entry->cursor);
-	update_kill_ring(entry, ENTRY_DEL_BWD_CHAR, entry->cursor, -len);
+	update_kill_ring(entry, ENTRY_JAIL, entry->cursor, -len);
 	entry->cursor -= len;
 
 	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor);
@@ -391,7 +391,7 @@
 		return FALSE;
 
 	len = g_utf8_find_next_char(entry->cursor, NULL) - entry->cursor;
-	update_kill_ring(entry, ENTRY_DEL_FWD_CHAR, entry->cursor, len);
+	update_kill_ring(entry, ENTRY_JAIL, entry->cursor, len);
 	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor - len + 1);
 	entry->end -= len;
 	entry_redraw(GNT_WIDGET(entry));
--- a/finch/libgnt/gntfilesel.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntfilesel.c	Sun Nov 30 06:25:26 2008 +0000
@@ -20,6 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "FileSel"
+
 #include "gntbutton.h"
 #include "gntentry.h"
 #include "gntfilesel.h"
@@ -254,7 +258,7 @@
 		struct stat st;
 
 		if (stat(fp, &st)) {
-			g_printerr("Error stating location %s\n", fp);
+			gnt_warning("Error stating location %s", fp);
 		} else {
 			if (S_ISDIR(st.st_mode)) {
 				file = gnt_file_new_dir(str);
@@ -309,7 +313,7 @@
 		success = local_read_fn(sel->current, &files, err);
 	
 	if (!success || *err) {
-		g_printerr("GntFileSel: error opening location %s (%s)\n",
+		gnt_warning("error opening location %s (%s)",
 			sel->current, *err ? (*err)->message : "reason unknown");
 		return FALSE;
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/libgnt/gntinternal.h	Sun Nov 30 06:25:26 2008 +0000
@@ -0,0 +1,33 @@
+/*
+ * GNT - The GLib Ncurses Toolkit
+ *
+ * GNT is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "Gnt"
+
+#ifdef __GNUC__
+# ifndef GNT_LOG_DOMAIN
+#  define GNT_LOG_DOMAIN ""
+# endif
+# define gnt_warning(format, args...)  g_warning("(%s) %s: " format, GNT_LOG_DOMAIN, __PRETTY_FUNCTION__, args)
+#else /* __GNUC__ */
+# define gnt_warning g_warning
+#endif
+
--- a/finch/libgnt/gntkeys.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntkeys.c	Sun Nov 30 06:25:26 2008 +0000
@@ -20,6 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "Keys"
+
 #include "gntkeys.h"
 
 #include <glib.h>
--- a/finch/libgnt/gntmain.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntmain.c	Sun Nov 30 06:25:26 2008 +0000
@@ -32,6 +32,10 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "Main"
+
 #include "gnt.h"
 #include "gntbox.h"
 #include "gntbutton.h"
@@ -319,7 +323,7 @@
 	                                 But irssi does this, so I am going to assume the
 	                                 crashes were caused by some other stuff. */
 
-	g_printerr("gntmain: setting up IO (%d)\n", channel_read_callback);
+	gnt_warning("setting up IO (%d)", channel_read_callback);
 }
 
 static gboolean
--- a/finch/libgnt/gntstyle.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntstyle.c	Sun Nov 30 06:25:26 2008 +0000
@@ -20,6 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "Style"
+
 #include "gntstyle.h"
 #include "gntcolors.h"
 #include "gntws.h"
@@ -226,7 +230,7 @@
 		keys = g_key_file_get_keys(gkfile, name, &len, &error);
 		if (error)
 		{
-			g_printerr("GntStyle: %s\n", error->message);
+			gnt_warning("%s", error->message);
 			g_error_free(error);
 			g_free(name);
 			return;
@@ -241,7 +245,7 @@
 
 			if (error)
 			{
-				g_printerr("GntStyle: %s\n", error->message);
+				gnt_warning("%s", error->message);
 				g_error_free(error);
 				error = NULL;
 			}
@@ -249,7 +253,7 @@
 			{
 				const char *keycode = parse_key(key);
 				if (keycode == NULL) {
-					g_printerr("GntStyle: Invalid key-binding %s\n", key);
+					gnt_warning("Invalid key-binding %s", key);
 				} else {
 					gnt_bindable_register_binding(klass, action, keycode, NULL);
 				}
@@ -280,7 +284,7 @@
 		keys = g_key_file_get_keys(gkfile, kname, &len, &error);
 		if (error)
 		{
-			g_printerr("GntStyle: %s\n", error->message);
+			gnt_warning("%s", error->message);
 			g_error_free(error);
 			g_free(kname);
 			return ret;
@@ -295,7 +299,7 @@
 
 			if (error)
 			{
-				g_printerr("GntStyle: %s\n", error->message);
+				gnt_warning("%s", error->message);
 				g_error_free(error);
 				error = NULL;
 			}
@@ -303,7 +307,7 @@
 			{
 				const char *keycode = parse_key(key);
 				if (keycode == NULL) {
-					g_printerr("GntStyle: Invalid key-binding %s\n", key);
+					gnt_warning("Invalid key-binding %s", key);
 				} else {
 					ret = TRUE;
 					g_hash_table_replace(table, g_strdup(keycode), menuid);
@@ -338,7 +342,7 @@
 		keys = g_key_file_get_keys(gkfile, name, &len, &error);
 		if (error)
 		{
-			g_printerr("GntStyle: %s\n", error->message);
+			gnt_warning("%s", error->message);
 			g_error_free(error);
 			g_free(name);
 			return;
@@ -353,7 +357,7 @@
 
 			if (error)
 			{
-				g_printerr("GntStyle: %s\n", error->message);
+				gnt_warning("%s", error->message);
 				g_error_free(error);
 				error = NULL;
 				g_free(key);
@@ -402,7 +406,7 @@
 
 	if (error)
 	{
-		g_printerr("GntStyle: %s\n", error->message);
+		gnt_warning("%s", error->message);
 		g_error_free(error);
 	}
 	else
@@ -426,7 +430,7 @@
 	if (!g_key_file_load_from_file(gkfile, filename,
                 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error))
 	{
-		g_printerr("GntStyle: %s\n", error->message);
+		gnt_warning("%s", error->message);
 		g_error_free(error);
 		return;
 	}
--- a/finch/libgnt/gnttextview.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gnttextview.c	Sun Nov 30 06:25:26 2008 +0000
@@ -20,6 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "TextView"
+
 #include "gntstyle.h"
 #include "gnttextview.h"
 #include "gntutils.h"
@@ -780,7 +784,7 @@
 						/* XXX: Make things work if the tagged text spans over several lines. */
 					} else {
 						/* XXX: handle the rest of the conditions */
-						g_printerr("WTF! This needs to be handled properly!!\n");
+						gnt_warning("WTF! This needs to be handled properly!!%s", "");
 					}
 				}
 			}
--- a/finch/libgnt/gntutils.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntutils.c	Sun Nov 30 06:25:26 2008 +0000
@@ -20,6 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "Utils"
+
 #include "gntbutton.h"
 #include "gntcheckbox.h"
 #include "gntcombobox.h"
@@ -306,7 +310,7 @@
 	xmlFree(content);
 
 	if (widget == NULL) {
-		g_printerr("Invalid widget name %s\n", name);
+		gnt_warning("Invalid widget name %s", name);
 		return NULL;
 	}
 
--- a/finch/libgnt/gntwm.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/finch/libgnt/gntwm.c	Sun Nov 30 06:25:26 2008 +0000
@@ -46,6 +46,10 @@
 #include <string.h>
 #include <time.h>
 
+#include "gntinternal.h"
+#undef GNT_LOG_DOMAIN
+#define GNT_LOG_DOMAIN "WM"
+
 #include "gntwm.h"
 #include "gntstyle.h"
 #include "gntmarshal.h"
@@ -325,7 +329,7 @@
 	gsize nk;
 
 	if (!g_key_file_load_from_file(gfile, filename, G_KEY_FILE_NONE, &error)) {
-		g_printerr("GntWM: %s\n", error->message);
+		gnt_warning("%s", error->message);
 		g_error_free(error);
 		g_free(filename);
 		return;
@@ -333,7 +337,7 @@
 
 	keys = g_key_file_get_keys(gfile, "positions", &nk, &error);
 	if (error) {
-		g_printerr("GntWM: %s\n", error->message);
+		gnt_warning("%s", error->message);
 		g_error_free(error);
 		error = NULL;
 	} else {
@@ -349,7 +353,7 @@
 				p->y = y;
 				g_hash_table_replace(wm->positions, g_strdup(title + 1), p);
 			} else {
-				g_printerr("GntWM: Invalid number of arguments for positioing a window.\n");
+				gnt_warning("Invalid number of arguments (%d) for positioning a window.", l);
 			}
 			g_strfreev(coords);
 		}
@@ -2095,7 +2099,7 @@
 
 	file = fopen(filename, "wb");
 	if (file == NULL) {
-		g_printerr("GntWM: error opening file to save positions\n");
+		gnt_warning("error opening file (%s) to save positions", filename);
 	} else {
 		fprintf(file, "[positions]\n");
 		g_hash_table_foreach(wm->positions, write_gdi, file);
--- a/libpurple/protocols/gg/buddylist.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/libpurple/protocols/gg/buddylist.c	Sun Nov 30 06:25:26 2008 +0000
@@ -105,9 +105,10 @@
 	PurpleGroup *group;
 	gchar **users_tbl;
 	int i;
+	char *utf8buddylist = charset_convert(buddylist, "CP1250", "UTF-8");
 
 	/* Don't limit the number of records in a buddylist. */
-	users_tbl = g_strsplit(buddylist, "\r\n", -1);
+	users_tbl = g_strsplit(utf8buddylist, "\r\n", -1);
 
 	for (i = 0; users_tbl[i] != NULL; i++) {
 		gchar **data_tbl;
@@ -124,23 +125,22 @@
 			continue;
 		}
 
-		show = charset_convert(data_tbl[F_NICKNAME], "CP1250", "UTF-8");
+		show = data_tbl[F_NICKNAME];
 		name = data_tbl[F_UIN];
-		if ('\0' == *name) {
+		if ('\0' == *name || !atol(name)) {
 			purple_debug_warning("gg",
-				"Something is wrong on line %d of the buddylist. Skipping.\n",
+				"Identifier on line %d of the buddylist is not a number. Skipping.\n",
 				i + 1);
 			continue;
 		}
 
 		if ('\0' == *show) {
-			show = g_strdup(name);
+			show = name;
 		}
 
 		purple_debug_info("gg", "got buddy: name=%s; show=%s\n", name, show);
 
 		if (purple_find_buddy(purple_connection_get_account(gc), name)) {
-			g_free(show);
 			g_strfreev(data_tbl);
 			continue;
 		}
@@ -153,7 +153,7 @@
 			gchar **group_tbl = g_strsplit(data_tbl[F_GROUP], ",", 50);
 			if (ggp_array_size(group_tbl) > 0) {
 				g_free(g);
-				g = charset_convert(group_tbl[0], "CP1250", "UTF-8");
+				g = g_strdup(group_tbl[0]);
 			}
 			g_strfreev(group_tbl);
 		}
@@ -169,10 +169,10 @@
 		purple_blist_add_buddy(buddy, NULL, group, NULL);
 		g_free(g);
 
-		g_free(show);
 		g_strfreev(data_tbl);
 	}
 	g_strfreev(users_tbl);
+	g_free(utf8buddylist);
 
 	ggp_buddylist_send(gc);
 }
@@ -257,9 +257,7 @@
 			     bnode != NULL;
 			     bnode = purple_blist_node_get_sibling_next(bnode))
 			{
-				gchar *newdata;
 				const gchar *name, *alias, *gname;
-				gchar *cp_alias, *cp_gname;
 
 				if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
 					continue;
@@ -274,27 +272,22 @@
 					alias = name;
 				gname = purple_group_get_name(group);
 
-				cp_gname = charset_convert(gname, "UTF-8", "CP1250");
-				cp_alias = charset_convert(alias, "UTF-8", "CP1250");
-				newdata = g_strdup_printf(
-						"%s;%s;%s;%s;%s;%s;%s;%s%s\r\n",
-						cp_alias, cp_alias, cp_alias, cp_alias,
-						"", cp_gname, name, "", "");
+				ptr = buddylist;
+				buddylist = g_strdup_printf(
+						"%s%s;%s;%s;%s;%s;%s;%s;%s%s\r\n",
+						ptr, alias, alias, alias, alias,
+						"", gname, name, "", "");
 
-				ptr = buddylist;
-				buddylist = g_strconcat(ptr, newdata, NULL);
-
-				g_free(newdata);
 				g_free(ptr);
-				g_free(cp_gname);
-				g_free(cp_alias);
 			}
 		}
 	}
 
-	return buddylist;
+	ptr = charset_convert(buddylist, "UTF-8", "CP1250");
+	g_free(buddylist);
+	return ptr;
 }
 /* }}} */
 
 
-/* vim: set ts=8 sts=0 sw=8 noet: */
+/* vim: set ts=8 sts=0 sw=8 noet: */
\ No newline at end of file
--- a/libpurple/protocols/jabber/auth.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/libpurple/protocols/jabber/auth.c	Sun Nov 30 06:25:26 2008 +0000
@@ -397,6 +397,10 @@
 		auth = xmlnode_new("auth");
 		xmlnode_set_namespace(auth, "urn:ietf:params:xml:ns:xmpp-sasl");
 		xmlnode_set_attrib(auth, "mechanism", js->current_mech);
+		
+		xmlnode_set_attrib(auth, "xmlns:ga", "http://www.google.com/talk/protocol/auth");
+		xmlnode_set_attrib(auth, "ga:client-uses-full-bind-result", "true");
+
 		if (clientout) {
 			if (coutlen == 0) {
 				xmlnode_insert_data(auth, "=", -1);
--- a/libpurple/protocols/jabber/buddy.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Sun Nov 30 06:25:26 2008 +0000
@@ -115,14 +115,18 @@
 						break;
 					case JABBER_BUDDY_STATE_AWAY:
 					case JABBER_BUDDY_STATE_DND:
-					case JABBER_BUDDY_STATE_UNAVAILABLE:
-						/* This resource is away/dnd/unavailable. Prefer to one which is extended away or unknown. */
-						if ((jbr->state == JABBER_BUDDY_STATE_XA) || 
+						/* This resource is away/dnd. Prefer to one which is extended away, unavailable, or unknown. */
+						if ((jbr->state == JABBER_BUDDY_STATE_XA) || (jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) ||
 							(jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR))
 							jbr = l->data;
 						break;
 					case JABBER_BUDDY_STATE_XA:
-						/* This resource is extended away. That's better than unknown. */
+						/* This resource is extended away. That's better than unavailable or unknown. */
+						if ((jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR))
+							jbr = l->data;
+						break;
+					case JABBER_BUDDY_STATE_UNAVAILABLE:
+						/* This resource is unavailable. That's better than unknown. */
 						if ((jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR))
 							jbr = l->data;
 						break;
@@ -1798,12 +1802,21 @@
 void jabber_buddy_get_info(PurpleConnection *gc, const char *who)
 {
 	JabberStream *js = purple_connection_get_protocol_data(gc);
-	char *bare_jid = jabber_get_bare_jid(who);
+	JabberID *jid = jabber_id_new(who);
+
+	if (!jid)
+		return;
 
-	if(bare_jid) {
+	if (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 {
+		char *bare_jid = jabber_get_bare_jid(who);
 		jabber_buddy_get_info_for_jid(js, bare_jid);
 		g_free(bare_jid);
 	}
+
+	jabber_id_free(jid);
 }
 
 static void jabber_buddy_set_invisibility(JabberStream *js, const char *who,
--- a/libpurple/protocols/jabber/jabber.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Sun Nov 30 06:25:26 2008 +0000
@@ -146,10 +146,37 @@
 	jabber_session_init(js);
 }
 
+static char *jabber_prep_resource(char *input) {
+	char hostname[256]; /* current hostname */
+
+	/* Empty resource == don't send any */
+	if (*input == '\0')
+		return NULL;
+
+	if (strstr(input, "__HOSTNAME__") == NULL)
+		return input;
+
+	/* Replace __HOSTNAME__ with hostname */
+	if (gethostname(hostname, sizeof(hostname) - 1)) {
+		purple_debug_warning("jabber", "gethostname: %s\n", g_strerror(errno));
+		/* according to glibc doc, the only time an error is returned
+		   is if the hostname is longer than the buffer, in which case
+		   glibc 2.2+ would still fill the buffer with partial
+		   hostname, so maybe we want to detect that and use it
+		   instead
+		*/
+		strcpy(hostname, "localhost");
+	}
+	hostname[sizeof(hostname) - 1] = '\0';
+
+	return purple_strreplace(input, "__HOSTNAME__", hostname);
+}
+
 static void jabber_stream_features_parse(JabberStream *js, xmlnode *packet)
 {
 	if(xmlnode_get_child(packet, "starttls")) {
 		if(jabber_process_starttls(js, packet))
+	
 			return;
 	} else if(purple_account_get_bool(js->gc->account, "require_tls", FALSE) && !js->gsc) {
 		purple_connection_error_reason (js->gc,
@@ -164,11 +191,17 @@
 		jabber_auth_start(js, packet);
 	} else if(xmlnode_get_child(packet, "bind")) {
 		xmlnode *bind, *resource;
+		char *requested_resource;
 		JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET);
 		bind = xmlnode_new_child(iq->node, "bind");
 		xmlnode_set_namespace(bind, "urn:ietf:params:xml:ns:xmpp-bind");
-		resource = xmlnode_new_child(bind, "resource");
-		xmlnode_insert_data(resource, js->user->resource, -1);
+		requested_resource = jabber_prep_resource(js->user->resource);
+
+		if (requested_resource != NULL) {
+			resource = xmlnode_new_child(bind, "resource");
+			xmlnode_insert_data(resource, requested_resource, -1);
+			free(requested_resource);
+		}
 
 		jabber_iq_set_callback(iq, jabber_bind_result_cb, NULL);
 
@@ -679,19 +712,6 @@
 		return;
 	}
 	
-	if(!js->user->resource) {
-		char *me;
-		js->user->resource = g_strdup("Home");
-		if(!js->user->node) {
-			js->user->node = js->user->domain;
-			js->user->domain = g_strdup("jabber.org");
-		}
-		me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain,
-				js->user->resource);
-		purple_account_set_username(account, me);
-		g_free(me);
-	}
-
 	if((my_jb = jabber_buddy_find(js, purple_account_get_username(account), TRUE)))
 		my_jb->subscription |= JABBER_SUB_BOTH;
 
@@ -1159,19 +1179,6 @@
 
 	js->write_buffer = purple_circ_buffer_new(512);
 
-	if(!js->user->resource) {
-		char *me;
-		js->user->resource = g_strdup("Home");
-		if(!js->user->node) {
-			js->user->node = js->user->domain;
-			js->user->domain = g_strdup("jabber.org");
-		}
-		me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain,
-				js->user->resource);
-		purple_account_set_username(account, me);
-		g_free(me);
-	}
-
 	if((my_jb = jabber_buddy_find(js, purple_account_get_username(account), TRUE)))
 		my_jb->subscription |= JABBER_SUB_BOTH;
 
--- a/libpurple/protocols/jabber/libxmpp.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/libpurple/protocols/jabber/libxmpp.c	Sun Nov 30 06:25:26 2008 +0000
@@ -209,7 +209,7 @@
 	purple_account_user_split_set_reverse(split, FALSE);
 	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
 	
-	split = purple_account_user_split_new(_("Resource"), "Home", '/');
+	split = purple_account_user_split_new(_("Resource"), NULL, '/');
 	purple_account_user_split_set_reverse(split, FALSE);
 	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
 	
--- a/libpurple/protocols/jabber/pep.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/libpurple/protocols/jabber/pep.c	Sun Nov 30 06:25:26 2008 +0000
@@ -54,7 +54,7 @@
 
 static void do_pep_iq_request_item_callback(JabberStream *js, xmlnode *packet, gpointer data) {
 	const char *from = xmlnode_get_attrib(packet,"from");
-	xmlnode *pubsub = xmlnode_get_child_with_namespace(packet,"pubsub","http://jabber.org/protocol/pubsub#event");
+	xmlnode *pubsub = xmlnode_get_child_with_namespace(packet,"pubsub","http://jabber.org/protocol/pubsub");
 	xmlnode *items = NULL;
 	JabberPEPHandler *cb = data;
 	
--- a/libpurple/protocols/jabber/presence.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/libpurple/protocols/jabber/presence.c	Sun Nov 30 06:25:26 2008 +0000
@@ -513,7 +513,7 @@
 		} else if(!strcmp(y->name, "delay") && !strcmp(xmlns, "urn:xmpp:delay")) {
 			/* XXX: compare the time.  jabber:x:delay can happen on presence packets that aren't really and truly delayed */
 			delayed = TRUE;
-		} else if(!strcmp(y->name, "c") && !strcmp(xmlns, "http://jabber.org/protocol/caps")) {
+		} else if(xmlns && !strcmp(y->name, "c") && !strcmp(xmlns, "http://jabber.org/protocol/caps")) {
 			caps = y; /* store for later, when creating buddy resource */
 		} else if(!strcmp(y->name, "x")) {
 			const char *xmlns = xmlnode_get_namespace(y);
--- a/pidgin/gtkconv.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/pidgin/gtkconv.c	Sun Nov 30 06:25:26 2008 +0000
@@ -2759,26 +2759,16 @@
 {
 	PidginConversation *gtkconv = (PidginConversation *)user_data;
 	PurpleConversation *conv = gtkconv->active_conv;
-	FILE *fp;
 	PurpleBuddyIcon *icon;
 	const void *data;
 	size_t len;
 
-	if ((fp = g_fopen(filename, "wb")) == NULL) {
-		purple_notify_error(gtkconv, NULL, _("Unable to open file."), NULL);
-		return;
-	}
-
 	icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
 	data = purple_buddy_icon_get_data(icon, &len);
 
-	if ((len <= 0) || (data == NULL) || (fwrite(data, 1, len, fp) != len)) {
+	if ((len <= 0) || (data == NULL) || !purple_util_write_data_to_file_absolute(filename, data, len)) {
 		purple_notify_error(gtkconv, NULL, _("Unable to save icon file to disk."), NULL);
-		fclose(fp);
-		g_unlink(filename);
-		return;
-	}
-	fclose(fp);
+	}
 }
 
 static void
--- a/pidgin/pidginstock.c	Fri Nov 28 06:06:35 2008 +0000
+++ b/pidgin/pidginstock.c	Sun Nov 30 06:25:26 2008 +0000
@@ -181,7 +181,6 @@
 	{ PIDGIN_STOCK_ANIMATION_TYPING4,  "animations", "typing4.png",FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_ANIMATION_TYPING5,  "animations", "typing5.png",FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 
-	{ PIDGIN_STOCK_TOOLBAR_ACCOUNTS,	"toolbar", "accounts.png",	 FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_BGCOLOR,		"toolbar", "change-bgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_BLOCK,		"emblems", "blocked.png",	 FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_FGCOLOR,		"toolbar", "change-fgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
@@ -195,7 +194,6 @@
 	{ PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW,	"toolbar", "message-new.png",	 FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_PENDING,		"toolbar", "message-new.png",	 FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_PLUGINS,		"toolbar", "plugins.png",	 FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
-	{ PIDGIN_STOCK_TOOLBAR_TYPING,		"toolbar", "typing.png",	 FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_UNBLOCK,		"toolbar", "unblock.png",	 FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR,	"toolbar", "select-avatar.png",	 FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_SEND_FILE,	"toolbar", "send-file.png",	 FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
--- a/pidgin/pixmaps/Makefile.am	Fri Nov 28 06:06:35 2008 +0000
+++ b/pidgin/pixmaps/Makefile.am	Sun Nov 30 06:25:26 2008 +0000
@@ -347,6 +347,8 @@
 
 STATUS_11_RTL = \
 		status/11/rtl/extended-away.png
+		status/11/rtl/log-in.png
+		status/11/rtl/log-out.png
 
 STATUS_16 = \
 		status/16/available.png \
@@ -405,6 +407,7 @@
 		status/48/busy.png \
 		status/48/chat.png \
 		status/48/extended-away.png \
+		status/48/invisible.png \
 		status/48/log-in.png \
 		status/48/log-out.png \
 		status/48/offline.png \
@@ -412,8 +415,8 @@
 
 STATUS_48_RTL = \
 		status/48/rtl/extended-away.png \
-		status/48/rtl/login.png \
-		status/48/rtl/logout.png
+		status/48/rtl/log-in.png \
+		status/48/rtl/log-out.png
 
 TOOLBAR_11 = \
 		toolbar/11/message-new.png
Binary file pidgin/pixmaps/status/11/rtl/log-in.png has changed
Binary file pidgin/pixmaps/status/11/rtl/log-out.png has changed
Binary file pidgin/pixmaps/status/48/invisible.png has changed
Binary file pidgin/pixmaps/status/48/log-in.png has changed
Binary file pidgin/pixmaps/status/48/log-out.png has changed
Binary file pidgin/pixmaps/status/48/rtl/log-in.png has changed
Binary file pidgin/pixmaps/status/48/rtl/log-out.png has changed
Binary file pidgin/pixmaps/status/48/rtl/login.png has changed
Binary file pidgin/pixmaps/status/48/rtl/logout.png has changed