changeset 25771:e1f363f8fd6b

propagate from branch 'im.pidgin.pidgin' (head 280dc76b99f56c1c9e8c8c8175e03b356f27f757) to branch 'org.darkrain42.pidgin.xmpp' (head 8c7ebef63cff9084aa9cb6c67abf84ede85e9308)
author Paul Aurich <paul@darkrain42.org>
date Sat, 29 Nov 2008 02:18:37 +0000
parents 9bb624e345aa (diff) b1b1b75a922e (current diff)
children c4eb9f10ecb5
files libpurple/protocols/jabber/buddy.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/libxmpp.c libpurple/protocols/jabber/pep.c libpurple/protocols/jabber/presence.c
diffstat 37 files changed, 216 insertions(+), 121 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Wed Nov 26 22:06:46 2008 +0000
+++ b/COPYRIGHT	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/ChangeLog	Sat Nov 29 02:18:37 2008 +0000
@@ -15,6 +15,13 @@
 	* The Buddy State Notification plugin no longer turns JID's, MSN Passport
 	  ID's, etc. into links (Florian Quèze)
 	* Fix a crash in SIMPLE when a malformed message is received.
+	* Fix the namespace URL we look for in PEP reply stanzas to match the URL
+	  used in the 'get' requests (Paul Aurich)
+	* XMPP resources can be set to the local machine's hostname by using
+	  __HOSTNAME__ as the resource string (Jonathan Sailor)
+	* XMPP resources can now be left blank, causing the server to generate a
+	  resource for us (Jonathan Sailor)
+	* XMPP resources now default to no value
 
 	Pidgin:
 	* On GTK+ 2.14 and higher, we're using the gtk-tooltip-delay setting
--- a/Makefile.am	Wed Nov 26 22:06:46 2008 +0000
+++ b/Makefile.am	Sat Nov 29 02:18:37 2008 +0000
@@ -59,7 +59,7 @@
 # Ensure we're working from a tag...
 	test x`mtn automate select t:v$(PACKAGE_VERSION)` = x`mtn automate get_base_revision_id`
 # ... and have no changes in the working copy.
-	test x`mtn diff | grep -v '^#'` = x
+	test "x`mtn diff | grep -v '^#'`" = x
 
 release: version-check distcheck packages
 
--- a/autogen.sh	Wed Nov 26 22:06:46 2008 +0000
+++ b/autogen.sh	Sat Nov 29 02:18:37 2008 +0000
@@ -66,7 +66,7 @@
 	CMD=$1
 
 	printf "%s" "checking for ${CMD}... "
-	BIN=`which ${CMD} 2> /dev/null`
+	BIN=`which ${CMD} 2>/dev/null`
 
 	if [ x"${BIN}" = x"" ] ; then
 		echo "not found."
--- a/finch/gntdebug.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/gntdebug.c	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/Makefile.am	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntbindable.c	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntcolors.c	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntentry.c	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntfilesel.c	Sat Nov 29 02:18:37 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	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntkeys.c	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntmain.c	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntstyle.c	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gnttextview.c	Sat Nov 29 02:18:37 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"
@@ -67,6 +71,7 @@
 gnt_text_view_draw(GntWidget *widget)
 {
 	GntTextView *view = GNT_TEXT_VIEW(widget);
+	int n;
 	int i = 0;
 	GList *lines;
 	int rows, scrcol;
@@ -76,10 +81,11 @@
 	wbkgd(widget->window, gnt_color_pair(GNT_COLOR_NORMAL));
 	werase(widget->window);
 
+	n = g_list_length(view->list);
 	if ((view->flags & GNT_TEXT_VIEW_TOP_ALIGN) &&
-			g_list_length(view->list) < widget->priv.height) {
+			n < widget->priv.height) {
 		GList *now = view->list;
-		comp = widget->priv.height - g_list_length(view->list);
+		comp = widget->priv.height - n;
 		view->list = g_list_nth_prev(view->list, comp);
 		if (!view->list) {
 			view->list = g_list_first(now);
@@ -236,6 +242,7 @@
 static char *
 gnt_text_view_get_p(GntTextView *view, int x, int y)
 {
+	int n;
 	int i = 0;
 	GntWidget *wid = GNT_WIDGET(view);
 	GntTextLine *line;
@@ -244,10 +251,11 @@
 	GntTextSegment *seg;
 	gchar *pos;
 
+	n = g_list_length(view->list);
 	y = wid->priv.height - y;
-	if (g_list_length(view->list) < y) {
+	if (n < y) {
 		x = 0;
-		y = g_list_length(view->list) - 1;
+		y = n - 1;
 	}
 
 	lines = g_list_nth(view->list, y - 1);
@@ -776,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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntutils.c	Sat Nov 29 02:18:37 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	Wed Nov 26 22:06:46 2008 +0000
+++ b/finch/libgnt/gntwm.c	Sat Nov 29 02:18:37 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"
@@ -201,7 +205,7 @@
 	GString *text = g_string_new("act: ");
 	if (message)
 		gnt_widget_destroy(message);
-	if (g_list_length(act) == 0)
+	if (!act)
 		return;
 	for (iter = act; iter; iter = iter->next) {
 		GntWS *ws = iter->data;
@@ -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);
 		}
@@ -927,6 +931,7 @@
 	GntWidget *tree, *win;
 	GList *iter;
 	GntWM *wm = GNT_WM(bindable);
+	int n;
 	if (wm->_list.window || wm->menu)
 		return TRUE;
 
@@ -950,8 +955,9 @@
 				gnt_tree_create_row(GNT_TREE(tree), action->label), NULL);
 	}
 	g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(action_list_activate), wm);
-	gnt_widget_set_size(tree, 0, g_list_length(wm->acts));
-	gnt_widget_set_position(win, 0, getmaxy(stdscr) - 3 - g_list_length(wm->acts));
+	n = g_list_length(wm->acts);
+	gnt_widget_set_size(tree, 0, n);
+	gnt_widget_set_position(win, 0, getmaxy(stdscr) - 3 - n);
 
 	gnt_widget_show(win);
 	return TRUE;
@@ -2093,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/jabber/buddy.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Sat Nov 29 02:18:37 2008 +0000
@@ -960,7 +960,7 @@
 		}
 #endif
 	} else {
-		gboolean multiple_resources = jbi->jb->resources && (g_list_length(jbi->jb->resources) > 1);
+		gboolean multiple_resources = jbi->jb->resources && jbi->jb->resources->next;
 
 		for(resources = jbi->jb->resources; resources; resources = resources->next) {
 			char *purdy = NULL;
--- a/libpurple/protocols/jabber/jabber.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Sat Nov 29 02:18:37 2008 +0000
@@ -149,10 +149,34 @@
 	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' || strstr(input, "__HOSTNAME__") == NULL)
+		return NULL;
+
+	/* 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);
+}
+
 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,
@@ -167,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);
 
@@ -730,19 +760,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;
 
@@ -1210,19 +1227,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	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/jabber/libxmpp.c	Sat Nov 29 02:18:37 2008 +0000
@@ -217,7 +217,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	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/jabber/pep.c	Sat Nov 29 02:18:37 2008 +0000
@@ -62,7 +62,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	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/jabber/presence.c	Sat Nov 29 02:18:37 2008 +0000
@@ -512,7 +512,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/libpurple/protocols/jabber/si.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/jabber/si.c	Sat Nov 29 02:18:37 2008 +0000
@@ -1085,7 +1085,7 @@
 
 			purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg);
 			g_free(msg);
-		} else if(g_list_length(jb->resources) == 1) {
+		} else if(!jb->resources->next) {
 			/* only 1 resource online (probably our most common case)
 			 * so no need to ask who to send to */
 			jbr = jb->resources->data;
--- a/libpurple/protocols/myspace/README	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/myspace/README	Sat Nov 29 02:18:37 2008 +0000
@@ -10,9 +10,6 @@
 
 For features and TODO, see http://developer.pidgin.im/wiki/MySpaceIM
 
-Windows installation: Unzip the archive to C:\Program Files\Pidgin
-Unix/source installation: run "make install"
-
 Usage:
 
 Login using your _email address_ you use to login to myspace.com. You can't
--- a/libpurple/protocols/myspace/message.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/myspace/message.c	Sat Nov 29 02:18:37 2008 +0000
@@ -613,6 +613,7 @@
 		const gchar *sep, 
 		const gchar *begin, const gchar *end)
 {
+	int num_items;
 	gchar **strings;
 	gchar **strings_tmp;
 	gchar *joined;
@@ -621,8 +622,10 @@
 
 	g_return_val_if_fail(msg != NULL, NULL);
 
+	num_items = g_list_length(msg);
+
 	/* Add one for NULL terminator for g_strjoinv(). */
-	strings = (gchar **)g_new0(gchar *, g_list_length(msg) + 1);
+	strings = (gchar **)g_new0(gchar *, num_items + 1);
 
 	strings_tmp = strings;
 	g_list_foreach(msg, gf, &strings_tmp);
@@ -632,7 +635,7 @@
 	g_free(joined);
 
 	/* Clean up. */
-	for (i = 0; i < g_list_length(msg); ++i) {
+	for (i = 0; i < num_items; ++i) {
 		g_free(strings[i]);
 	}
 
--- a/libpurple/protocols/qq/qq_network.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/qq/qq_network.c	Sat Nov 29 02:18:37 2008 +0000
@@ -126,8 +126,8 @@
 	/* get new server */
 	index  = rand() % count;
 	it = g_list_nth(qd->servers, index);
-    qd->curr_server = it->data;		/* do not free server_name */
-    if (qd->curr_server == NULL || strlen(qd->curr_server) <= 0 ) {
+	qd->curr_server = it->data;		/* do not free server_name */
+	if (qd->curr_server == NULL || strlen(qd->curr_server) <= 0 ) {
 		purple_debug_info("QQ", "Server name at %d is empty\n", index);
 		return FALSE;
 	}
--- a/libpurple/protocols/sametime/sametime.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Sat Nov 29 02:18:37 2008 +0000
@@ -4415,7 +4415,7 @@
     res = results->data;
 
   if(!code && res && res->matches) {
-    if(g_list_length(res->matches) == 1) {
+    if(!res->matches->next) {
       struct mwResolveMatch *match = res->matches->data;
       
       /* only one? that might be the right one! */
--- a/libpurple/protocols/yahoo/yahoochat.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.c	Sat Nov 29 02:18:37 2008 +0000
@@ -513,12 +513,12 @@
 
 	c = purple_find_chat(gc, YAHOO_CHAT_ID);
 
-	if (room && (!c || purple_conv_chat_has_left(PURPLE_CONV_CHAT(c))) && members &&
-	   ((g_list_length(members) > 1) ||
+	if (room && (!c || purple_conv_chat_has_left(PURPLE_CONV_CHAT(c))) &&
+	    members && (members->next ||
 	     !g_ascii_strcasecmp(members->data, purple_connection_get_display_name(gc)))) {
-		int i;
+		GList *l;
 		GList *flags = NULL;
-		for (i = 0; i < g_list_length(members); i++)
+		for (l = members; l; l = l->next)
 			flags = g_list_append(flags, GINT_TO_POINTER(PURPLE_CBFLAGS_NONE));
 		if (c && purple_conv_chat_has_left(PURPLE_CONV_CHAT(c))) {
 			/* this might be a hack, but oh well, it should nicely */
--- a/libpurple/protocols/zephyr/zephyr.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Sat Nov 29 02:18:37 2008 +0000
@@ -343,15 +343,15 @@
    Converts strings to utf-8 if necessary using user specified encoding
 */
 
-static gchar *zephyr_recv_convert(PurpleConnection *gc,gchar *string, int len)
+static gchar *zephyr_recv_convert(PurpleConnection *gc, gchar *string)
 {
 	gchar *utf8;
 	GError *err = NULL;
 	zephyr_account *zephyr = gc->proto_data;
-	if (g_utf8_validate(string, len, NULL)) {
+	if (g_utf8_validate(string, -1, NULL)) {
 		return g_strdup(string);
 	} else {
-		utf8 = g_convert(string, len, "UTF-8", zephyr->encoding, NULL, NULL, &err);
+		utf8 = g_convert(string, -1, "UTF-8", zephyr->encoding, NULL, NULL, &err);
 		if (err) {
 			purple_debug_error("zephyr", "recv conversion error: %s\n", err->message);
 			utf8 = g_strdup(_("(There was an error converting this message.	 Check the 'Encoding' option in the Account Editor)"));
@@ -820,7 +820,7 @@
 		PurpleConvChat *gcc;
 		char *ptr = (char *) notice.z_message + (strlen(notice.z_message) + 1);
 		int len; 
-		char *sendertmp = g_strdup_printf("%s", zephyr->username);
+		char *stripped_sender;
 		int signature_length = strlen(notice.z_message);
 		int message_has_no_body = 0;
 		PurpleMessageFlags flags = 0;
@@ -843,24 +843,23 @@
 			tmpescape = g_markup_escape_text(buf, -1);
 			g_free(buf);
 			buf2 = zephyr_to_html(tmpescape);
-			buf3 = zephyr_recv_convert(gc,buf2, strlen(buf2));
+			buf3 = zephyr_recv_convert(gc, buf2);
 			g_free(buf2);
 			g_free(tmpescape);
 		}
 
+		stripped_sender = zephyr_strip_local_realm(zephyr,notice.z_sender);
+
 		if (!g_ascii_strcasecmp(notice.z_class, "MESSAGE") && !g_ascii_strcasecmp(notice.z_class_inst, "PERSONAL") 
 		    && !g_ascii_strcasecmp(notice.z_recipient,zephyr->username)) {
-			gchar* stripped_sender;
 			if (!g_ascii_strcasecmp(notice.z_message, "Automated reply:"))
 				flags |= PURPLE_MESSAGE_AUTO_RESP;
-			stripped_sender = zephyr_strip_local_realm(zephyr,notice.z_sender);
 			
 			if (!g_ascii_strcasecmp(notice.z_opcode,"PING"))
 				serv_got_typing(gc,stripped_sender,ZEPHYR_TYPING_RECV_TIMEOUT, PURPLE_TYPING);
 			else
 				serv_got_im(gc, stripped_sender, buf3, flags, time(NULL));
 
-			g_free(stripped_sender);
 		} else {
 			zephyr_triple *zt1, *zt2;
 			gchar *send_inst_utf8;
@@ -878,15 +877,17 @@
 				serv_got_joined_chat(gc, zt2->id, zt2->name);
 				zephyr_chat_set_topic(gc,zt2->id,notice.z_class_inst);
 			}
-			g_free(sendertmp); /* fix memory leak? */
-			/* If the person is in the default Realm, then strip the 
-			   Realm from the sender field */
-			sendertmp = zephyr_strip_local_realm(zephyr,notice.z_sender);
-			send_inst = g_strdup_printf("%s %s",sendertmp,notice.z_class_inst);					
-			send_inst_utf8 = zephyr_recv_convert(gc,send_inst, strlen(send_inst));
-			if (!send_inst_utf8) {
-				purple_debug_error("zephyr","send_inst %s became null\n", send_inst);
-				send_inst_utf8 = "malformed instance";
+
+			if (!g_ascii_strcasecmp(notice.z_class_inst,"PERSONAL"))
+				send_inst_utf8 = g_strdup(stripped_sender);
+			else {
+				send_inst = g_strdup_printf("[%s] %s",notice.z_class_inst,stripped_sender);
+				send_inst_utf8 = zephyr_recv_convert(gc,send_inst);
+				g_free(send_inst);
+				if (!send_inst_utf8) {
+					purple_debug_error("zephyr","Failed to convert instance for sender %s.\n", stripped_sender);
+					send_inst_utf8 = g_strdup(stripped_sender);
+				}
 			}
 
 			gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
@@ -895,24 +896,22 @@
 #ifndef INET_ADDRSTRLEN
 #define INET_ADDRSTRLEN 16
 #endif
-			if (!purple_conv_chat_find_user(gcc, sendertmp)) {
+			if (!purple_conv_chat_find_user(gcc, stripped_sender)) {
 				gchar ipaddr[INET_ADDRSTRLEN];
 #ifdef HAVE_INET_NTOP
 				inet_ntop(AF_INET, &notice.z_sender_addr.s_addr, ipaddr, sizeof(ipaddr));
 #else
 				memcpy(ipaddr,inet_ntoa(notice.z_sender_addr),sizeof(ipaddr));
 #endif
-				purple_conv_chat_add_user(gcc, sendertmp, ipaddr, PURPLE_CBFLAGS_NONE, TRUE);
+				purple_conv_chat_add_user(gcc, stripped_sender, ipaddr, PURPLE_CBFLAGS_NONE, TRUE);
 			}
-			g_free(sendertmp);
 			serv_got_chat_in(gc, zt2->id, send_inst_utf8, 0, buf3, time(NULL));
-			g_free(send_inst);
 			g_free(send_inst_utf8);
-				
+
 			free_triple(zt1);
 		}
+		g_free(stripped_sender);
 		g_free(buf3);
-		
 	}
 }
 
@@ -2580,7 +2579,7 @@
 												gc->account);
 	gcc = purple_conversation_get_chat_data(gconv);
 
-	topic_utf8 = zephyr_recv_convert(gc,(gchar *)topic,strlen(topic));
+	topic_utf8 = zephyr_recv_convert(gc,(gchar *)topic);
 	purple_conv_chat_set_topic(gcc,sender,topic_utf8);
 	g_free(topic_utf8);
 	return;
--- a/libpurple/request.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/request.c	Sat Nov 29 02:18:37 2008 +0000
@@ -887,7 +887,7 @@
 	purple_request_field_list_clear_selected(field);
 
 	if (!purple_request_field_list_get_multi_select(field) &&
-		g_list_length(items) > 1)
+		items && items->next)
 	{
 		purple_debug_warning("request",
 						   "More than one item added to non-multi-select "
--- a/libpurple/roomlist.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/libpurple/roomlist.c	Sat Nov 29 02:18:37 2008 +0000
@@ -265,6 +265,11 @@
 	g_return_if_fail(room != NULL);
 	g_return_if_fail(list->fields != NULL);
 
+	/* If this is the first call for this room, grab the first field in
+	 * the Roomlist's fields.  Otherwise, grab the field that is one
+	 * more than the number of fields already present for the room.
+         * (This works because g_list_nth_data() is zero-indexed and
+         * g_list_length() is one-indexed.) */
 	if (!room->fields)
 		f = list->fields->data;
 	else
--- a/pidgin/Makefile.am	Wed Nov 26 22:06:46 2008 +0000
+++ b/pidgin/Makefile.am	Sat Nov 29 02:18:37 2008 +0000
@@ -5,7 +5,6 @@
 		Makefile.mingw \
 		pidgin.pc.in \
 		pidgin-uninstalled.pc.in \
-		pidginstock-artwork.c \
 		win32/IdleTracker/Makefile.mingw \
 		win32/IdleTracker/idletrack.c \
 		win32/IdleTracker/idletrack.h \
--- a/pidgin/gtkblist.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/pidgin/gtkblist.c	Sat Nov 29 02:18:37 2008 +0000
@@ -3320,6 +3320,7 @@
 	if (PURPLE_BLIST_NODE_IS_CHAT(node))
 	{
 		PurpleChat *chat;
+		GList *connections;
 		GList *cur;
 		struct proto_chat_entry *pce;
 		char *name, *value;
@@ -3330,7 +3331,8 @@
 		prpl = purple_find_prpl(purple_account_get_protocol_id(chat->account));
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-		if (g_list_length(purple_connections_get_all()) > 1)
+		connections = purple_connections_get_all();
+		if (connections && connections->next)
 		{
 			tmp = g_markup_escape_text(chat->account->username, -1);
 			g_string_append_printf(str, _("<b>Account:</b> %s"), tmp);
@@ -3400,6 +3402,7 @@
 		PurpleBuddy *b;
 		PurplePresence *presence;
 		PurpleNotifyUserInfo *user_info;
+		GList *connections;
 		char *tmp;
 		time_t idle_secs, signon;
 
@@ -3421,7 +3424,8 @@
 		user_info = purple_notify_user_info_new();
 
 		/* Account */
-		if (full && g_list_length(purple_connections_get_all()) > 1)
+		connections = purple_connections_get_all();
+		if (full && connections && connections->next)
 		{
 			tmp = g_markup_escape_text(purple_account_get_username(
 									   purple_buddy_get_account(b)), -1);
--- a/pidgin/gtknotify.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/pidgin/gtknotify.c	Sat Nov 29 02:18:37 2008 +0000
@@ -730,7 +730,6 @@
 	GtkListStore *model = data->model;
 	GtkTreeIter iter;
 	GdkPixbuf *pixbuf;
-	guint col_num;
 	GList *row, *column;
 	guint n;
 
@@ -738,9 +737,6 @@
 
 	pixbuf = pidgin_create_prpl_icon(purple_connection_get_account(gc), 0.5);
 
-	/* +1 is for the automagically created Status column. */
-	col_num = g_list_length(results->columns) + 1;
-
 	for (row = results->rows; row != NULL; row = row->next) {
 
 		gtk_list_store_append(model, &iter);
@@ -776,6 +772,7 @@
 	guint col_num;
 	GList *columniter;
 	guint i;
+	GList *l;
 
 	GtkWidget *vbox;
 	GtkWidget *label;
@@ -869,8 +866,8 @@
 		i++;
 	}
 
-	for (i = 0; i < g_list_length(results->buttons); i++) {
-		PurpleNotifySearchButton *b = g_list_nth_data(results->buttons, i);
+	for (l = results->buttons; l; l = l->next) {
+		PurpleNotifySearchButton *b = l->data;
 		GtkWidget *button = NULL;
 		switch (b->type) {
 			case PURPLE_NOTIFY_BUTTON_LABELED:
--- a/pidgin/gtkrequest.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/pidgin/gtkrequest.c	Sat Nov 29 02:18:37 2008 +0000
@@ -853,12 +853,11 @@
 create_choice_field(PurpleRequestField *field)
 {
 	GtkWidget *widget;
-	GList *labels;
+	GList *labels = purple_request_field_choice_get_labels(field);
+	int num_labels = g_list_length(labels);
 	GList *l;
 
-	labels = purple_request_field_choice_get_labels(field);
-
-	if (g_list_length(labels) > 5)
+	if (num_labels > 5)
 	{
 		GtkWidget *menu;
 		GtkWidget *item;
@@ -892,7 +891,7 @@
 		GtkWidget *radio;
 		gint i;
 
-		if (g_list_length(labels) == 2)
+		if (num_labels == 2)
 			box = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
 		else
 			box = gtk_vbox_new(FALSE, 0);
--- a/pidgin/gtksavedstatuses.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/pidgin/gtksavedstatuses.c	Sat Nov 29 02:18:37 2008 +0000
@@ -331,7 +331,8 @@
 	}
 	g_list_free(sel_paths);
 
-	if (g_list_length(sel_titles) == 1) {
+	g_return_if_fail(sel_titles != NULL);
+	if (!sel_titles->next) {
 		title = g_strdup_printf(_("Are you sure you want to delete %s?"),
 				(const gchar *)sel_titles->data);
 		handle = purple_savedstatus_find(sel_titles->data);
--- a/pidgin/plugins/history.c	Wed Nov 26 22:06:46 2008 +0000
+++ b/pidgin/plugins/history.c	Sat Nov 29 02:18:37 2008 +0000
@@ -47,10 +47,11 @@
 
 	convtype = purple_conversation_get_type(c);
 	gtkconv = PIDGIN_CONVERSATION(c);
-	if (gtkconv == NULL)
-		return;
+	g_return_if_fail(gtkconv != NULL);
 
-	if (convtype == PURPLE_CONV_TYPE_IM && g_list_length(gtkconv->convs) < 2)
+	/* An IM which is the first active conversation. */
+	g_return_if_fail(gtkconv->convs != NULL);
+	if (convtype == PURPLE_CONV_TYPE_IM && !gtkconv->convs->next)
 	{
 		GSList *buddies;
 		GSList *cur;