changeset 27844:f7944b0ffe46

propagate from branch 'im.pidgin.pidgin' (head 9ebef7dc91fd3f43f016ceeee02e0a15e2008868) to branch 'im.pidgin.pidgin.yaz' (head 976545343d21fb851d14f436cb36acbf27b0bc98)
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 27 May 2008 14:14:40 +0000
parents 30eaeb7cc076 (current diff) e166f9e91d6d (diff)
children 0aa090fde749
files configure.ac libpurple/notify.c libpurple/protocols/oscar/oscar.c
diffstat 21 files changed, 297 insertions(+), 241 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Mon May 26 04:04:39 2008 +0000
+++ b/COPYRIGHT	Tue May 27 14:14:40 2008 +0000
@@ -278,6 +278,7 @@
 Novell
 Padraig O'Briain
 Christopher O'Brien (siege)
+Peter O'Gorman
 Jon Oberheide
 Yusuke Odate
 Ruediger Oertel
@@ -449,6 +450,8 @@
 Matt Wilson
 Dan Winship
 Scott Wolchok
+The Written Word, Inc.
+Kevin Wu Won
 Pui Lam Wong
 Justin Wood
 Ximian
--- a/ChangeLog.API	Mon May 26 04:04:39 2008 +0000
+++ b/ChangeLog.API	Tue May 27 14:14:40 2008 +0000
@@ -15,6 +15,8 @@
 		* purple_buddy_icons_node_find_custom_icon
 		* purple_buddy_icons_node_set_custom_icon
 		* purple_buddy_icons_node_set_custom_icon_from_file
+		* purple_notify_user_info_prepend_section_break
+		* purple_notify_user_info_prepend_section_header
 
 		Deprecated:
 		* purple_blist_update_buddy_icon
--- a/configure.ac	Mon May 26 04:04:39 2008 +0000
+++ b/configure.ac	Tue May 27 14:14:40 2008 +0000
@@ -108,13 +108,14 @@
 
 dnl Checks for programs.
 AC_PROG_CC
+AM_PROG_CC_C_O
 AC_DISABLE_STATIC
-AM_PROG_LIBTOOL
+AC_PROG_LIBTOOL
 LIBTOOL="$LIBTOOL --silent"
 AC_PROG_INSTALL
 AC_PROG_INTLTOOL
 PKG_PROG_PKG_CONFIG
-
+AC_FUNC_ALLOCA
 GETTEXT_PACKAGE=pidgin
 AC_SUBST(GETTEXT_PACKAGE)
 
@@ -210,7 +211,7 @@
 		[Define to 1 if you have the getaddrinfo function.])],
 	[AC_CHECK_LIB(socket, getaddrinfo,
 		[AC_DEFINE([HAVE_GETADDRINFO]) LIBS="-lsocket -lsnl $LIBS"], , , -lnsl)])
-
+AC_CHECK_FUNCS(inet_ntop)
 dnl Check for socklen_t (in Unix98)
 AC_MSG_CHECKING(for socklen_t)
 AC_TRY_COMPILE([
@@ -234,6 +235,12 @@
 	])
 ])
 
+dnl Some systems do not have sa_len field for struct sockaddr.
+AC_CHECK_MEMBER([struct sockaddr.sa_len],
+	[AC_DEFINE([HAVE_STRUCT_SOCKADDR_SA_LEN],[1],
+	[Define if struct sockaddr has an sa_len member])],[:],
+	[#include <sys/socket.h>])
+
 dnl to prevent the g_stat()/g_unlink() crash,
 dnl (09:50:07) Robot101: LSchiere2: it's easy. +LC_SYS_LARGEFILE somewhere in configure.ac
 AC_SYS_LARGEFILE
@@ -1622,14 +1629,14 @@
 			*) with_gnutls_libs="-L$with_gnutls_libs" ;;
 		esac
 
-		AC_CACHE_CHECK([for GnuTLS libraries], gnutls_libs,
+		AC_CACHE_CHECK([for GnuTLS libraries], ac_cv_gnutls_libs,
 		[
 			LIBS="$LIBS $with_gnutls_libs -lgnutls -lgcrypt"
-			AC_TRY_LINK_FUNC(gnutls_init, gnutls_libs="yes", gnutls_libs="no")
+			AC_TRY_LINK_FUNC(gnutls_init, ac_cv_gnutls_libs="yes", ac_cv_gnutls_libs="no")
 			LIBS="$LIBS_save"
 		])
 
-		if test "x$gnutls_libs" != "xno"; then
+		if test "x$ac_cv_gnutls_libs" != "xno"; then
 			AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GnuTLS])
 			AC_DEFINE(HAVE_SSL)
 			msg_gnutls="GnuTLS"
@@ -1782,7 +1789,7 @@
 				nsprlibs="$LIBDL -lplc4 -lplds4 -lnspr4 $PTHREAD_LIB"
 			fi
 
-			AC_CACHE_CHECK([for Mozilla nspr libraries], moz_nspr_libs,
+			AC_CACHE_CHECK([for Mozilla nspr libraries], ac_cv_moz_nspr_libs,
 			[
 				LIBS_save=$LIBS
 				CFLAGS="$CFLAGS $NSPR_CFLAGS"
@@ -1796,15 +1803,15 @@
 				fi
 
 				AC_TRY_LINK_FUNC(PR_Init,
-					[moz_nspr_libs="yes"],
-					[moz_nspr_libs="no"])
+					[ac_cv_moz_nspr_libs="yes"],
+					[ac_cv_moz_nspr_libs="no"])
 
 				CFLAGS=$CFLAGS_save
 				LDFLAGS=$LDFLAGS_save
 				LIBS=$LIBS_save
 			])
 
-			if test "x$moz_nspr_libs" != "xno"; then
+			if test "x$ac_cv_moz_nspr_libs" != "xno"; then
 				have_nspr_libs="yes"
 				NSPR_LIBS="-L$with_nspr_libs $nsprlibs"
 			else
@@ -1877,30 +1884,30 @@
 				nsslibs="-lssl3 -lsmime3 -lnss3 -lsoftokn3"
 			fi
 
-			AC_CACHE_CHECK([for Mozilla nss libraries], moz_nss_libs,
+			AC_CACHE_CHECK([for Mozilla nss libraries], ac_cv_moz_nss_libs,
 			[
 				LIBS_save=$LIBS
 				LDFLAGS="$LDFLAGS -L$with_nspr_libs -L$with_nss_libs"
 				LIBS="$nsslibs $nsprlibs"
 
 				AC_TRY_LINK_FUNC(NSS_Init,
-					[moz_nss_libs="yes"],
-					[moz_nss_libs="no"])
+					[ac_cv_moz_nss_libs="yes"],
+					[ac_cv_moz_nss_libs="no"])
 
-				if test "x$moz_nss_libs" = "xno"; then
+				if test "x$ac_cv_moz_nss_libs" = "xno"; then
 					nsslibs="-lssl3 -lsmime3 -lnss3 -lsoftokn3"
 					LDFLAGS="$LDFLAGS -L$with_nspr_libs -L$with_nss_libs" 
 					LIBS="$LIBS $nsslibs"
 					AC_TRY_LINK_FUNC(NSS_Init,
-						[moz_nss_libs="yes"],
-						[moz_nss_libs="no"])
+						[ac_cv_moz_nss_libs="yes"],
+						[ac_cv_moz_nss_libs="no"])
 				fi
 
 				LDFLAGS=$LDFLAGS_save
 				LIBS=$LIBS_save
 			])
 
-			if test "x$moz_nss_libs" != "xno"; then
+			if test "x$ac_cv_moz_nss_libs" != "xno"; then
 				AC_DEFINE(HAVE_NSS)
 				AC_DEFINE(HAVE_SSL)
 
@@ -2229,11 +2236,7 @@
 dnl #######################################################################
 dnl # Check for check
 dnl #######################################################################
-PKG_CHECK_MODULES(CHECK,[check >= 0.9.4],:,[
-					ifdef([[AM_PATH_CHECK]],
-					[AM_PATH_CHECK(0.8.2,:,:)],
-					[AC_MSG_RESULT([no, testing is disabled])])
-				  ])
+PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], , [AC_MSG_RESULT([no, testing is disabled])])
 AM_CONDITIONAL(HAVE_CHECK, [test "x$CHECK_LIBS" != "x"])
 AC_SUBST(CHECK_CFLAGS)
 AC_SUBST(CHECK_LIBS)
--- a/libpurple/buddyicon.h	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/buddyicon.h	Tue May 27 14:14:40 2008 +0000
@@ -26,6 +26,11 @@
 #ifndef _PURPLE_BUDDYICON_H_
 #define _PURPLE_BUDDYICON_H_
 
+/** An opaque structure representing a buddy icon for a particular user on a
+ *  particular #PurpleAccount.  Instances are reference-counted; use
+ *  purple_buddy_icon_ref() and purple_buddy_icon_unref() to take and release
+ *  references.
+ */
 typedef struct _PurpleBuddyIcon PurpleBuddyIcon;
 
 #include "account.h"
--- a/libpurple/core.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/core.c	Tue May 27 14:14:40 2008 +0000
@@ -131,13 +131,14 @@
 
 	purple_ciphers_init();
 
-	/* Initialize all static protocols. */
-	static_proto_init();
-
 	/* Since plugins get probed so early we should probably initialize their
 	 * subsystem right away too.
 	 */
 	purple_plugins_init();
+	
+	/* Initialize all static protocols. */
+	static_proto_init();
+
 	purple_plugins_probe(G_MODULE_SUFFIX);
 
 	/* The buddy icon code uses the imgstore, so init it early. */
@@ -211,6 +212,7 @@
 	purple_savedstatuses_uninit();
 	purple_status_uninit();
 	purple_prefs_uninit();
+	purple_sound_uninit();
 	purple_xfers_uninit();
 	purple_proxy_uninit();
 	purple_dnsquery_uninit();
@@ -223,19 +225,6 @@
 	if (ops != NULL && ops->quit != NULL)
 		ops->quit();
 
-	/*
-	 * purple_sound_uninit() should be called as close to
-	 * shutdown as possible.  This is because the call
-	 * to ao_shutdown() can sometimes leave our
-	 * environment variables in an unusable state, which
-	 * can cause a crash when getenv is called (by gettext
-	 * for example).  See the complete bug report at
-	 * http://trac.xiph.org/cgi-bin/trac.cgi/ticket/701
-	 *
-	 * TODO: Eventually move this call higher up with the others.
-	 */
-	purple_sound_uninit();
-
 	purple_plugins_uninit();
 #ifdef HAVE_DBUS
 	purple_dbus_uninit();
--- a/libpurple/dnsquery.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/dnsquery.c	Tue May 27 14:14:40 2008 +0000
@@ -32,6 +32,9 @@
 #include "prefs.h"
 #include "util.h"
 
+#if (defined(__APPLE__) || defined (__unix__)) && !defined(__osf__)
+#define PURPLE_DNSQUERY_USE_FORK
+#endif
 /**************************************************************************
  * DNS query API
  **************************************************************************/
@@ -47,16 +50,16 @@
 	gpointer data;
 	guint timeout;
 
-#if defined(__unix__) || defined(__APPLE__)
+#if defined(PURPLE_DNSQUERY_USE_FORK)
 	PurpleDnsQueryResolverProcess *resolver;
-#elif defined _WIN32 /* end __unix__ || __APPLE__ */
+#elif defined _WIN32 /* end PURPLE_DNSQUERY_USE_FORK  */
 	GThread *resolver;
 	GSList *hosts;
 	gchar *error_message;
 #endif
 };
 
-#if defined(__unix__) || defined(__APPLE__)
+#if defined(PURPLE_DNSQUERY_USE_FORK)
 
 #define MAX_DNS_CHILDREN 4
 
@@ -131,7 +134,7 @@
 	return FALSE;
 }
 
-#if defined(__unix__) || defined(__APPLE__)
+#if defined(PURPLE_DNSQUERY_USE_FORK)
 
 /*
  * Unix!
@@ -649,7 +652,7 @@
 	return query_data;
 }
 
-#elif defined _WIN32 /* end __unix__ || __APPLE__ */
+#elif defined _WIN32 /* end PURPLE_DNSQUERY_USE_FORK  */
 
 /*
  * Windows!
@@ -821,7 +824,7 @@
 	return query_data;
 }
 
-#else /* not __unix__ or __APPLE__ or _WIN32 */
+#else /* not PURPLE_DNSQUERY_USE_FORK or _WIN32 */
 
 /*
  * We weren't able to do anything fancier above, so use the
@@ -897,7 +900,7 @@
 	return query_data;
 }
 
-#endif /* not __unix__ or __APPLE__ or _WIN32 */
+#endif /* not PURPLE_DNSQUERY_USE_FORK or _WIN32 */
 
 void
 purple_dnsquery_destroy(PurpleDnsQueryData *query_data)
@@ -907,7 +910,7 @@
 	if (ops && ops->destroy)
 		ops->destroy(query_data);
 
-#if defined(__unix__) || defined(__APPLE__)
+#if defined(PURPLE_DNSQUERY_USE_FORK)
 	queued_requests = g_slist_remove(queued_requests, query_data);
 
 	if (query_data->resolver != NULL)
@@ -918,7 +921,7 @@
 		 * they just don't listen.
 		 */
 		purple_dnsquery_resolver_destroy(query_data->resolver);
-#elif defined _WIN32 /* end __unix__ || __APPLE__ */
+#elif defined _WIN32 /* end PURPLE_DNSQUERY_USE_FORK */
 	if (query_data->resolver != NULL)
 	{
 		/*
@@ -987,7 +990,7 @@
 void
 purple_dnsquery_uninit(void)
 {
-#if defined(__unix__) || defined(__APPLE__)
+#if defined(PURPLE_DNSQUERY_USE_FORK)
 	while (free_dns_children != NULL)
 	{
 		purple_dnsquery_resolver_destroy(free_dns_children->data);
--- a/libpurple/dnssrv.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/dnssrv.c	Tue May 27 14:14:40 2008 +0000
@@ -25,8 +25,8 @@
 #include "util.h"
 
 #ifndef _WIN32
+#include <arpa/nameser.h>
 #include <resolv.h>
-#include <arpa/nameser.h>
 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
 #include <arpa/nameser_compat.h>
 #endif
--- a/libpurple/internal.h	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/internal.h	Tue May 27 14:14:40 2008 +0000
@@ -102,7 +102,7 @@
 #include <gmodule.h>
 
 #ifdef PURPLE_PLUGINS
-# ifndef _WIN32
+# ifdef HAVE_DLFCN_H 
 #  include <dlfcn.h>
 # endif
 #endif
--- a/libpurple/nat-pmp.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/nat-pmp.c	Tue May 27 14:14:40 2008 +0000
@@ -125,7 +125,16 @@
 		if (bitmask & (1 << i)) 
 		{
 			addrs[i] = sa;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 			sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
+#else
+			if (sa->sa_family == AF_INET)
+				sa = (struct sockaddr*)(sizeof(struct sockaddr_in) + (char *)sa);
+#ifdef AF_INET6
+			else if (sa->sa_family == AF_INET6)
+				sa = (struct sockaddr*)(sizeof(struct sockaddr_in6) + (char *)sa);
+#endif
+#endif
 		} 
 		else
 		{
@@ -146,7 +155,12 @@
     if ((sin->sin_addr.s_addr == INADDR_ANY) &&
 		mask &&
 		(ntohl(((struct sockaddr_in *)mask)->sin_addr.s_addr) == 0L ||
-		 mask->sa_len == 0))
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+		 mask->sa_len == 0
+#else
+		0
+#endif
+		))
 		return 1;
     else
 		return 0;
--- a/libpurple/network.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/network.c	Tue May 27 14:14:40 2008 +0000
@@ -27,9 +27,9 @@
 #include "internal.h"
 
 #ifndef _WIN32
+#include <arpa/nameser.h>
 #include <resolv.h>
 #include <netinet/in.h>
-#include <arpa/nameser.h>
 #include <net/if.h>
 #include <sys/ioctl.h>
 #else
--- a/libpurple/notify.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/notify.c	Tue May 27 14:14:40 2008 +0000
@@ -632,6 +632,17 @@
 }
 
 void
+purple_notify_user_info_prepend_section_header(PurpleNotifyUserInfo *user_info, const char *label)
+{
+	PurpleNotifyUserInfoEntry *entry;
+	
+	entry = purple_notify_user_info_entry_new(label, NULL);
+	entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER;
+	
+	user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry);
+}
+
+void
 purple_notify_user_info_add_section_break(PurpleNotifyUserInfo *user_info)
 {
 	PurpleNotifyUserInfoEntry *entry;
@@ -643,6 +654,17 @@
 }
 
 void
+purple_notify_user_info_prepend_section_break(PurpleNotifyUserInfo *user_info)
+{
+	PurpleNotifyUserInfoEntry *entry;
+	
+	entry = purple_notify_user_info_entry_new(NULL, NULL);
+	entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK;
+	
+	user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry);
+}
+
+void
 purple_notify_user_info_remove_last_item(PurpleNotifyUserInfo *user_info)
 {
 	GList *last = g_list_last(user_info->user_info_entries);
--- a/libpurple/notify.h	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/notify.h	Tue May 27 14:14:40 2008 +0000
@@ -577,13 +577,30 @@
 void purple_notify_user_info_add_section_break(PurpleNotifyUserInfo *user_info);
 
 /**
+ * Prepend a section break.  A UI might display this as a horizontal line.
+ *
+ * @param user_info          The PurpleNotifyUserInfo
+ * @since 2.5.0
+ */
+void purple_notify_user_info_prepend_section_break(PurpleNotifyUserInfo *user_info);
+	
+/**
  * Add a section header.  A UI might display this in a different font from other text.
  *
  * @param user_info          The PurpleNotifyUserInfo
  * @param label              The name of the section
  */
 void purple_notify_user_info_add_section_header(PurpleNotifyUserInfo *user_info, const char *label);
-
+	
+/**
+ * Prepend a section header.  A UI might display this in a different font from other text.
+ *
+ * @param user_info          The PurpleNotifyUserInfo
+ * @param label              The name of the section
+ * @since 2.5.0
+ */
+void purple_notify_user_info_prepend_section_header(PurpleNotifyUserInfo *user_info, const char *label);
+	
 /**
  * Remove the last item which was added to a PurpleNotifyUserInfo. This could be used to remove a section header which is not needed.
  */
--- a/libpurple/protocols/jabber/buddy.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Tue May 27 14:14:40 2008 +0000
@@ -48,8 +48,8 @@
 	GSList *ids;
 	GHashTable *resources;
 	int timeout_handle;
-	char *vcard_text;
 	GSList *vcard_imgids;
+	PurpleNotifyUserInfo *user_info;
 } JabberBuddyInfo;
 
 void jabber_buddy_free(JabberBuddy *jb)
@@ -777,7 +777,7 @@
 
 	g_free(jbi->jid);
 	g_hash_table_destroy(jbi->resources);
-	g_free(jbi->vcard_text);
+	purple_notify_user_info_destroy(jbi->user_info);
 	g_free(jbi);
 }
 
@@ -793,12 +793,35 @@
 	if(jbi->ids)
 		return;
 
-	user_info = purple_notify_user_info_new();
+	user_info = jbi->user_info;
 	resource_name = jabber_get_resource(jbi->jid);
 
+	/* If we have one or more pairs from the vcard, put a section break above it */
+	if (purple_notify_user_info_get_entries(user_info))
+		purple_notify_user_info_prepend_section_break(user_info);
+
+	/* Prepend the primary buddy info to user_info so that it goes before the vcard. */
 	if(resource_name) {
 		jbr = jabber_buddy_find_resource(jbi->jb, resource_name);
 		jbir = g_hash_table_lookup(jbi->resources, resource_name);
+		if(jbr && jbr->client.name) {
+			tmp = g_strdup_printf("%s%s%s", jbr->client.name,
+								  (jbr->client.version ? " " : ""),
+								  (jbr->client.version ? jbr->client.version : ""));
+			purple_notify_user_info_add_pair(user_info, _("Client"), tmp);
+			g_free(tmp);
+			
+			if(jbr->client.os) {
+				purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
+			}
+		}		
+		if(jbir) {
+			if(jbir->idle_seconds > 0) {
+				char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
+				purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle);
+				g_free(idle);
+			}
+		}		
 		if(jbr) {
 			char *purdy = NULL;
 			if(jbr->status)
@@ -806,29 +829,11 @@
 			tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state),
 							(purdy ? ": " : ""),
 							(purdy ? purdy : ""));
-			purple_notify_user_info_add_pair(user_info, _("Status"), tmp);
+			purple_notify_user_info_prepend_pair(user_info, _("Status"), tmp);
 			g_free(tmp);
 			g_free(purdy);
 		} else {
-			purple_notify_user_info_add_pair(user_info, _("Status"), _("Unknown"));
-		}
-		if(jbir) {
-			if(jbir->idle_seconds > 0) {
-				char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
-				purple_notify_user_info_add_pair(user_info, _("Idle"), idle);
-				g_free(idle);
-			}
-		}
-		if(jbr && jbr->client.name) {
-			tmp = g_strdup_printf("%s%s%s", jbr->client.name,
-								  (jbr->client.version ? " " : ""),
-								  (jbr->client.version ? jbr->client.version : ""));
-			purple_notify_user_info_add_pair(user_info, _("Client"), tmp);
-			g_free(tmp);
-
-			if(jbr->client.os) {
-				purple_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os);
-			}
+			purple_notify_user_info_prepend_pair(user_info, _("Status"), _("Unknown"));
 		}
 #if 0 
 		/* #if 0 this for now; I think this would be far more useful if we limited this to a particular set of features
@@ -949,52 +954,56 @@
 			}
 
 			if(strlen(tmp->str) > 0)
-				purple_notify_user_info_add_pair(user_info, _("Capabilities"), tmp->str);
+				purple_notify_user_info_prepend_pair(user_info, _("Capabilities"), tmp->str);
 			
 			g_string_free(tmp, TRUE);
 		}
 #endif
 	} else {
+		gboolean multiple_resources = jbi->jb->resources && (g_list_length(jbi->jb->resources) > 1);
+
 		for(resources = jbi->jb->resources; resources; resources = resources->next) {
 			char *purdy = NULL;
 			jbr = resources->data;
+
+			if(jbr->client.name) {
+				tmp = g_strdup_printf("%s%s%s", jbr->client.name,
+									  (jbr->client.version ? " " : ""),
+									  (jbr->client.version ? jbr->client.version : ""));
+				purple_notify_user_info_prepend_pair(user_info,
+												 _("Client"), tmp);
+				g_free(tmp);
+				
+				if(jbr->client.os) {
+					purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
+				}
+			}
+
+			if(jbr->name && (jbir = g_hash_table_lookup(jbi->resources, jbr->name))) {
+				if(jbir->idle_seconds > 0) {
+					char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
+					purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle);
+					g_free(idle);
+				}
+			}
+
 			if(jbr->status)
 				purdy = purple_strdup_withhtml(jbr->status);
-			if(jbr->name)
-				purple_notify_user_info_add_pair(user_info, _("Resource"), jbr->name);
-			tmp = g_strdup_printf("%d", jbr->priority);
-			purple_notify_user_info_add_pair(user_info, _("Priority"), tmp);
-			g_free(tmp);
-
 			tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state),
 								  (purdy ? ": " : ""),
 								  (purdy ? purdy : ""));
-			purple_notify_user_info_add_pair(user_info, _("Status"), tmp);
+			purple_notify_user_info_prepend_pair(user_info, _("Status"), tmp);
 			g_free(tmp);
 			g_free(purdy);
+			
+			if(multiple_resources) {
+				tmp = g_strdup_printf("%d", jbr->priority);
+				purple_notify_user_info_prepend_pair(user_info, _("Priority"), tmp);
+				g_free(tmp);
+			}
 
 			if(jbr->name)
-				jbir = g_hash_table_lookup(jbi->resources, jbr->name);
-
-			if(jbir) {
-				if(jbir->idle_seconds > 0) {
-					char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
-					purple_notify_user_info_add_pair(user_info, _("Idle"), idle);
-					g_free(idle);
-				}
-			}
-			if(jbr && jbr->client.name) {
-				tmp = g_strdup_printf("%s%s%s", jbr->client.name,
-									  (jbr->client.version ? " " : ""),
-									  (jbr->client.version ? jbr->client.version : ""));
-				purple_notify_user_info_add_pair(user_info,
-											   _("Client"), tmp);
-				g_free(tmp);
-
-				if(jbr->client.os) {
-					purple_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os);
-				}
-			}
+				purple_notify_user_info_prepend_pair(user_info, _("Resource"), jbr->name);
 #if 0
 			if(jbr && jbr->caps) {
 				GString *tmp = g_string_new("");
@@ -1109,7 +1118,7 @@
 						g_string_append_printf(tmp, "%s\n", feature);
 				}
 				if(strlen(tmp->str) > 0)
-					purple_notify_user_info_add_pair(user_info, _("Capabilities"), tmp->str);
+					purple_notify_user_info_prepend_pair(user_info, _("Capabilities"), tmp->str);
 				
 				g_string_free(tmp, TRUE);
 			}
@@ -1119,14 +1128,7 @@
 
 	g_free(resource_name);
 
-	if (jbi->vcard_text != NULL) {
-		purple_notify_user_info_add_section_break(user_info);
-		/* Should this have some sort of label? */
-		purple_notify_user_info_add_pair(user_info, NULL, jbi->vcard_text);
-	}
-
 	purple_notify_userinfo(jbi->js->gc, jbi->jid, user_info, NULL, NULL);
-	purple_notify_user_info_destroy(user_info);
 
 	while(jbi->vcard_imgids) {
 		purple_imgstore_unref_by_id(GPOINTER_TO_INT(jbi->vcard_imgids->data));
@@ -1193,27 +1195,16 @@
 	jabber_iq_send(iq);
 }
 
-static void
-jabber_string_escape_and_append(GString *string, const char *name, const char *value, gboolean indent)
-{
-	gchar *escaped;
-
-	escaped = g_markup_escape_text(value, -1);
-	g_string_append_printf(string, "%s<b>%s:</b> %s<br/>",
-			indent ? "&nbsp;&nbsp;" : "", name, escaped);
-	g_free(escaped);
-}
-
 static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data)
 {
 	const char *id, *from;
-	GString *info_text;
 	char *bare_jid;
 	char *text;
 	char *serverside_alias = NULL;
 	xmlnode *vcard;
 	PurpleBuddy *b;
 	JabberBuddyInfo *jbi = data;
+	PurpleNotifyUserInfo *user_info;
 
 	from = xmlnode_get_attrib(packet, "from");
 	id = xmlnode_get_attrib(packet, "id");
@@ -1231,12 +1222,11 @@
 
 	/* XXX: handle the error case */
 
+	user_info = jbi->user_info;
 	bare_jid = jabber_get_bare_jid(from);
 
 	b = purple_find_buddy(js->gc->account, bare_jid);
 
-	info_text = g_string_new("");
-
 	if((vcard = xmlnode_get_child(packet, "vCard")) ||
 			(vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) {
 		xmlnode *child;
@@ -1253,8 +1243,7 @@
 				if (!serverside_alias)
 					serverside_alias = g_strdup(text);
 
-				jabber_string_escape_and_append(info_text,
-						_("Full Name"), text, FALSE);
+				purple_notify_user_info_add_pair(user_info, _("Full Name"), text);
 			} else if(!strcmp(child->name, "N")) {
 				for(child2 = child->child; child2; child2 = child2->next)
 				{
@@ -1265,14 +1254,11 @@
 
 					text2 = xmlnode_get_data(child2);
 					if(text2 && !strcmp(child2->name, "FAMILY")) {
-						jabber_string_escape_and_append(info_text,
-								_("Family Name"), text2, FALSE);
+						purple_notify_user_info_add_pair(user_info, _("Family Name"), text2);
 					} else if(text2 && !strcmp(child2->name, "GIVEN")) {
-						jabber_string_escape_and_append(info_text,
-								_("Given Name"), text2, FALSE);
+						purple_notify_user_info_add_pair(user_info, _("Given Name"), text2);
 					} else if(text2 && !strcmp(child2->name, "MIDDLE")) {
-						jabber_string_escape_and_append(info_text,
-								_("Middle Name"), text2, FALSE);
+						purple_notify_user_info_add_pair(user_info, _("Middle Name"), text2);
 					}
 					g_free(text2);
 				}
@@ -1281,11 +1267,9 @@
 				g_free(serverside_alias);
 				serverside_alias = g_strdup(text);
 
-				jabber_string_escape_and_append(info_text,
-						_("Nickname"), text, FALSE);
+				purple_notify_user_info_add_pair(user_info, _("Nickname"), text);
 			} else if(text && !strcmp(child->name, "BDAY")) {
-				jabber_string_escape_and_append(info_text,
-						_("Birthday"), text, FALSE);
+				purple_notify_user_info_add_pair(user_info, _("Birthday"), text);
 			} else if(!strcmp(child->name, "ADR")) {
 				gboolean address_line_added = FALSE;
 
@@ -1304,51 +1288,45 @@
 					 * elements are empty. */
 					if (!address_line_added)
 					{
-						g_string_append_printf(info_text, "<b>%s:</b><br/>",
-								_("Address"));
+						purple_notify_user_info_add_section_header(user_info, _("Address"));
 						address_line_added = TRUE;
 					}
 
 					if(!strcmp(child2->name, "POBOX")) {
-						jabber_string_escape_and_append(info_text,
-								_("P.O. Box"), text2, TRUE);
+						purple_notify_user_info_add_pair(user_info, _("P.O. Box"), text2);
 					} else if(!strcmp(child2->name, "EXTADR")) {
-						jabber_string_escape_and_append(info_text,
-								_("Extended Address"), text2, TRUE);
+						purple_notify_user_info_add_pair(user_info, _("Extended Address"), text2);
 					} else if(!strcmp(child2->name, "STREET")) {
-						jabber_string_escape_and_append(info_text,
-								_("Street Address"), text2, TRUE);
+						purple_notify_user_info_add_pair(user_info, _("Street Address"), text2);
 					} else if(!strcmp(child2->name, "LOCALITY")) {
-						jabber_string_escape_and_append(info_text,
-								_("Locality"), text2, TRUE);
+						purple_notify_user_info_add_pair(user_info, _("Locality"), text2);
 					} else if(!strcmp(child2->name, "REGION")) {
-						jabber_string_escape_and_append(info_text,
-								_("Region"), text2, TRUE);
+						purple_notify_user_info_add_pair(user_info, _("Region"), text2);
 					} else if(!strcmp(child2->name, "PCODE")) {
-						jabber_string_escape_and_append(info_text,
-								_("Postal Code"), text2, TRUE);
+						purple_notify_user_info_add_pair(user_info, _("Postal Code"), text2);
 					} else if(!strcmp(child2->name, "CTRY")
 								|| !strcmp(child2->name, "COUNTRY")) {
-						jabber_string_escape_and_append(info_text,
-								_("Country"), text2, TRUE);
+						purple_notify_user_info_add_pair(user_info, _("Country"), text2);
 					}
 					g_free(text2);
 				}
+				
+				if (address_line_added)
+					purple_notify_user_info_add_section_break(user_info);
+
 			} else if(!strcmp(child->name, "TEL")) {
 				char *number;
 				if((child2 = xmlnode_get_child(child, "NUMBER"))) {
 					/* show what kind of number it is */
 					number = xmlnode_get_data(child2);
 					if(number) {
-						jabber_string_escape_and_append(info_text,
-								_("Telephone"), number, FALSE);
+						purple_notify_user_info_add_pair(user_info, _("Telephone"), number);
 						g_free(number);
 					}
 				} else if((number = xmlnode_get_data(child))) {
 					/* lots of clients (including purple) do this, but it's
 					 * out of spec */
-					jabber_string_escape_and_append(info_text,
-							_("Telephone"), number, FALSE);
+					purple_notify_user_info_add_pair(user_info, _("Telephone"), number);
 					g_free(number);
 				}
 			} else if(!strcmp(child->name, "EMAIL")) {
@@ -1357,20 +1335,25 @@
 					/* show what kind of email it is */
 					userid = xmlnode_get_data(child2);
 					if(userid) {
+						char *mailto;
 						escaped = g_markup_escape_text(userid, -1);
-						g_string_append_printf(info_text,
-								"<b>%s:</b> <a href=\"mailto:%s\">%s</a><br/>",
-								_("Email"), escaped, escaped);
+						mailto = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", escaped, escaped);
+						purple_notify_user_info_add_pair(user_info, _("Email"), mailto);
+
+						g_free(mailto);
 						g_free(escaped);
 						g_free(userid);
 					}
 				} else if((userid = xmlnode_get_data(child))) {
 					/* lots of clients (including purple) do this, but it's
 					 * out of spec */
+					char *mailto;
+
 					escaped = g_markup_escape_text(userid, -1);
-					g_string_append_printf(info_text,
-							"<b>%s:</b> <a href=\"mailto:%s\">%s</a><br/>",
-							_("Email"), escaped, escaped);
+					mailto = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", escaped, escaped);
+					purple_notify_user_info_add_pair(user_info, _("Email"), mailto);
+					
+					g_free(mailto);					
 					g_free(escaped);
 					g_free(userid);
 				}
@@ -1384,23 +1367,18 @@
 
 					text2 = xmlnode_get_data(child2);
 					if(text2 && !strcmp(child2->name, "ORGNAME")) {
-						jabber_string_escape_and_append(info_text,
-								_("Organization Name"), text2, FALSE);
+						purple_notify_user_info_add_pair(user_info, _("Organization Name"), text2);
 					} else if(text2 && !strcmp(child2->name, "ORGUNIT")) {
-						jabber_string_escape_and_append(info_text,
-								_("Organization Unit"), text2, FALSE);
+						purple_notify_user_info_add_pair(user_info, _("Organization Unit"), text2);
 					}
 					g_free(text2);
 				}
 			} else if(text && !strcmp(child->name, "TITLE")) {
-				jabber_string_escape_and_append(info_text,
-						_("Title"), text, FALSE);
+				purple_notify_user_info_add_pair(user_info, _("Title"), text);
 			} else if(text && !strcmp(child->name, "ROLE")) {
-				jabber_string_escape_and_append(info_text,
-						_("Role"), text, FALSE);
+				purple_notify_user_info_add_pair(user_info, _("Role"), text);
 			} else if(text && !strcmp(child->name, "DESC")) {
-				jabber_string_escape_and_append(info_text,
-						_("Description"), text, FALSE);
+				purple_notify_user_info_add_pair(user_info, _("Description"), text);
 			} else if(!strcmp(child->name, "PHOTO") ||
 					!strcmp(child->name, "LOGO")) {
 				char *bintext = NULL;
@@ -1418,12 +1396,13 @@
 
 					data = purple_base64_decode(bintext, &size);
 					if (data) {
+						char *img_text;
+
 						jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png")));
-						g_string_append_printf(info_text,
-								"<b>%s:</b> <img id='%d'><br/>",
-								photo ? _("Photo") : _("Logo"),
-								GPOINTER_TO_INT(jbi->vcard_imgids->data));
-	
+						img_text = g_strdup_printf("<img id='%d'>", GPOINTER_TO_INT(jbi->vcard_imgids->data));
+
+						purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text);
+
 						purple_cipher_digest_region("sha1", (guchar *)data, size,
 								sizeof(hashval), hashval, NULL);
 						p = hash;
@@ -1433,6 +1412,7 @@
 						purple_buddy_icons_set_for_user(js->gc->account, bare_jid,
 								data, size, hash);
 						g_free(bintext);
+						g_free(img_text);
 					}
 				}
 			}
@@ -1450,8 +1430,6 @@
 		g_free(serverside_alias);
 	}
 
-	jbi->vcard_text = purple_strdup_withhtml(info_text->str);
-	g_string_free(info_text, TRUE);
 	g_free(bare_jid);
 
 	jabber_buddy_info_show_if_ready(jbi);
@@ -1735,6 +1713,7 @@
 	jbi->js = js;
 	jbi->jb = jb;
 	jbi->resources = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, jabber_buddy_info_resource_free);
+	jbi->user_info = purple_notify_user_info_new();
 
 	iq = jabber_iq_new(js, JABBER_IQ_GET);
 
--- a/libpurple/protocols/oscar/oscar.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Tue May 27 14:14:40 2008 +0000
@@ -2976,10 +2976,6 @@
 	user_info = purple_notify_user_info_new();
 	purple_notify_user_info_add_pair(user_info, _("Username"), userinfo->sn);
 
-	tmp = g_strdup_printf("%d", (int)((userinfo->warnlevel/10.0) + 0.5));
-	purple_notify_user_info_add_pair(user_info, _("Warning Level"), tmp);
-	g_free(tmp);
-
 	if (userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) {
 		time_t t = userinfo->onlinesince;
 		oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
@@ -3034,8 +3030,7 @@
 		g_free(tmp);
 		if (away_utf8 != NULL) {
 			tmp = purple_str_sub_away_formatters(away_utf8, purple_account_get_username(account));
-			purple_notify_user_info_add_section_break(user_info);
-			oscar_user_info_add_pair(user_info, NULL, tmp);
+			oscar_user_info_add_pair(user_info, _("Away Message"), tmp);
 			g_free(tmp);
 			g_free(away_utf8);
 		}
--- a/libpurple/protocols/zephyr/Makefile.am	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/protocols/zephyr/Makefile.am	Tue May 27 14:14:40 2008 +0000
@@ -104,7 +104,7 @@
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/libpurple/protocols \
-	-DCONFDIR=\"$(confdir)\" \
+	-DCONFDIR=\"$(sysconfdir)\" \
 	$(GLIB_CFLAGS) \
 	$(KRB4_CFLAGS) \
 	$(DEBUG_CFLAGS)
--- a/libpurple/protocols/zephyr/zephyr.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Tue May 27 14:14:40 2008 +0000
@@ -892,11 +892,16 @@
 			gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
 														 zt2->name, gc->account);
 			gcc = purple_conversation_get_chat_data(gconv1);
-
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
 			if (!purple_conv_chat_find_user(gcc, sendertmp)) {
 				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);
 			}
 			g_free(sendertmp);
--- a/libpurple/proxy.c	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/proxy.c	Tue May 27 14:14:40 2008 +0000
@@ -1726,6 +1726,10 @@
  * resolved, and each time a connection attempt fails (assuming there
  * is another IP address to try).
  */
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
 static void try_connect(PurpleProxyConnectData *connect_data)
 {
 	size_t addrlen;
@@ -1736,9 +1740,13 @@
 	connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
 	addr = connect_data->hosts->data;
 	connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
-
+#ifdef HAVE_INET_NTOP
 	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),
+			sizeof(ipaddr));
+#endif
 	purple_debug_info("proxy", "Attempting connection to %s\n", ipaddr);
 
 	switch (purple_proxy_info_get_type(connect_data->gpi)) {
--- a/libpurple/prpl.h	Mon May 26 04:04:39 2008 +0000
+++ b/libpurple/prpl.h	Tue May 27 14:14:40 2008 +0000
@@ -71,16 +71,22 @@
 #include "status.h"
 #include "whiteboard.h"
 
+
+/** @copydoc PurpleBuddyIconSpec */
 struct _PurpleBuddyIconSpec {
-	char *format;                       /**< This is a comma-delimited list of image formats or NULL if icons are not supported.
-					     * Neither the core nor the prpl will actually check to see if the data it's given matches this; it's
-					     * entirely up to the UI to do what it wants */
-	int min_width;                          /**< The minimum width of this icon  */
-	int min_height;                         /**< The minimum height of this icon */
-	int max_width;                          /**< The maximum width of this icon  */
-	int max_height;                         /**< The maximum height of this icon */
-	size_t max_filesize;                     /**< The maximum number of bytes    */
-	PurpleIconScaleRules scale_rules;		/**< How to stretch this icon */
+	/** This is a comma-delimited list of image formats or @c NULL if icons
+	 *  are not supported.  Neither the core nor the prpl will actually
+	 *  check to see if the data it's given matches this; it's entirely up
+	 *  to the UI to do what it wants
+	 */
+	char *format;
+
+	int min_width;                     /**< Minimum width of this icon  */
+	int min_height;                    /**< Minimum height of this icon */
+	int max_width;                     /**< Maximum width of this icon  */
+	int max_height;                    /**< Maximum height of this icon */
+	size_t max_filesize;               /**< Maximum size in bytes */
+	PurpleIconScaleRules scale_rules;  /**< How to stretch this icon */
 };
 
 struct proto_chat_entry {
--- a/pidgin/gtkdocklet.c	Mon May 26 04:04:39 2008 +0000
+++ b/pidgin/gtkdocklet.c	Tue May 27 14:14:40 2008 +0000
@@ -530,7 +530,7 @@
 	PidginStatusBox *statusbox = NULL;
 
 	submenu = gtk_menu_new();
-	menuitem = gtk_menu_item_new_with_label(_("Change Status"));
+	menuitem = gtk_menu_item_new_with_mnemonic(_("_Change Status"));
 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
 
 	if(pidgin_blist_get_default_gtk_blist() != NULL) {
@@ -678,12 +678,12 @@
 
 	menu = gtk_menu_new();
 
-	menuitem = gtk_check_menu_item_new_with_label(_("Show Buddy List"));
+	menuitem = gtk_check_menu_item_new_with_mnemonic(_("Show Buddy _List"));
 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/list_visible"));
 	g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_blist), NULL);
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
-	menuitem = gtk_menu_item_new_with_label(_("Unread Messages"));
+	menuitem = gtk_menu_item_new_with_mnemonic(_("_Unread Messages"));
 
 	if (pending) {
 		GtkWidget *submenu = gtk_menu_new();
@@ -704,7 +704,7 @@
 
 	pidgin_separator(menu);
 
-	menuitem = pidgin_new_item_from_stock(menu, _("New Message..."), PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, G_CALLBACK(pidgin_dialogs_im), NULL, 0, 0, NULL);
+	menuitem = pidgin_new_item_from_stock(menu, _("New _Message..."), PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, G_CALLBACK(pidgin_dialogs_im), NULL, 0, 0, NULL);
 	if (status == PURPLE_STATUS_OFFLINE)
 		gtk_widget_set_sensitive(menuitem, FALSE);
 
@@ -713,20 +713,20 @@
 
 	pidgin_separator(menu);
 
-	pidgin_new_item_from_stock(menu, _("Accounts"), NULL, G_CALLBACK(pidgin_accounts_window_show), NULL, 0, 0, NULL);
-	pidgin_new_item_from_stock(menu, _("Plugins"), PIDGIN_STOCK_TOOLBAR_PLUGINS, G_CALLBACK(pidgin_plugin_dialog_show), NULL, 0, 0, NULL);
-	pidgin_new_item_from_stock(menu, _("Preferences"), GTK_STOCK_PREFERENCES, G_CALLBACK(pidgin_prefs_show), NULL, 0, 0, NULL);
+	pidgin_new_item_from_stock(menu, _("_Accounts"), NULL, G_CALLBACK(pidgin_accounts_window_show), NULL, 0, 0, NULL);
+	pidgin_new_item_from_stock(menu, _("Plu_gins"), PIDGIN_STOCK_TOOLBAR_PLUGINS, G_CALLBACK(pidgin_plugin_dialog_show), NULL, 0, 0, NULL);
+	pidgin_new_item_from_stock(menu, _("Pr_eferences"), GTK_STOCK_PREFERENCES, G_CALLBACK(pidgin_prefs_show), NULL, 0, 0, NULL);
 
 	pidgin_separator(menu);
 
-	menuitem = gtk_check_menu_item_new_with_label(_("Mute Sounds"));
+	menuitem = gtk_check_menu_item_new_with_mnemonic(_("Mute _Sounds"));
 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/sound/mute"));
 	if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
 		gtk_widget_set_sensitive(GTK_WIDGET(menuitem), FALSE);
 	g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_mute), NULL);
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
-	menuitem = gtk_check_menu_item_new_with_label(_("Blink on New Message"));
+	menuitem = gtk_check_menu_item_new_with_mnemonic(_("_Blink on New Message"));
 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink"));
 	g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_blink), NULL);
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
@@ -736,7 +736,7 @@
 	/* add plugin actions */
 	docklet_plugin_actions(menu);
 
-	pidgin_new_item_from_stock(menu, _("Quit"), GTK_STOCK_QUIT, G_CALLBACK(purple_core_quit), NULL, 0, 0, NULL);
+	pidgin_new_item_from_stock(menu, _("_Quit"), GTK_STOCK_QUIT, G_CALLBACK(purple_core_quit), NULL, 0, 0, NULL);
 
 #ifdef _WIN32
 	g_signal_connect(menu, "leave-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL);
--- a/pidgin/gtkmain.c	Mon May 26 04:04:39 2008 +0000
+++ b/pidgin/gtkmain.c	Tue May 27 14:14:40 2008 +0000
@@ -187,7 +187,6 @@
 	switch (sig) {
 	case SIGHUP:
 		purple_debug_warning("sighandler", "Caught signal %d\n", sig);
-		purple_connections_disconnect_all();
 		break;
 	case SIGSEGV:
 		fprintf(stderr, "%s", segfault_message);
@@ -217,13 +216,7 @@
 		break;
 	default:
 		purple_debug_warning("sighandler", "Caught signal %d\n", sig);
-		purple_connections_disconnect_all();
-
-		purple_plugins_unload_all();
-
-		if (gtk_main_level())
-			gtk_main_quit();
-		exit(0);
+		purple_core_quit();
 	}
 }
 #endif
--- a/po/de.po	Mon May 26 04:04:39 2008 +0000
+++ b/po/de.po	Tue May 27 14:14:40 2008 +0000
@@ -11,8 +11,8 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-05-24 10:32+0200\n"
-"PO-Revision-Date: 2008-05-24 10:31+0200\n"
+"POT-Creation-Date: 2008-05-26 21:14+0200\n"
+"PO-Revision-Date: 2008-05-26 21:14+0200\n"
 "Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n"
 "Language-Team: Deutsch <de@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -10813,9 +10813,6 @@
 msgid "Fatal Error"
 msgstr "Schwerer Fehler"
 
-msgid "lead developer"
-msgstr "Hauptentwickler"
-
 msgid "developer"
 msgstr "Entwickler"
 
@@ -10850,6 +10847,9 @@
 msgid "original author"
 msgstr "Originalautor"
 
+msgid "lead developer"
+msgstr "Hauptentwickler"
+
 msgid "Afrikaans"
 msgstr "Afrikaans"
 
@@ -11229,23 +11229,35 @@
 msgid "Right-click for more unread messages...\n"
 msgstr "Rechtsklicken für weitere ungelesene Nachrichten...\n"
 
-msgid "Change Status"
-msgstr "Ändere Status"
-
-msgid "Show Buddy List"
-msgstr "Buddy-Liste anzeigen"
-
-msgid "New Message..."
-msgstr "Neue Nachricht..."
-
-msgid "Mute Sounds"
-msgstr "Stummschalten"
-
-msgid "Blink on New Message"
-msgstr "Bei neuen Nachrichten blinken"
-
-msgid "Quit"
-msgstr "Beenden"
+msgid "_Change Status"
+msgstr "Ändere _Status"
+
+msgid "Show Buddy _List"
+msgstr "Buddy-_Liste anzeigen"
+
+msgid "_Unread Messages"
+msgstr "_Ungelesene Nachrichten"
+
+msgid "New _Message..."
+msgstr "_Neue Nachricht..."
+
+msgid "_Accounts"
+msgstr "_Konten"
+
+msgid "Plu_gins"
+msgstr "_Plugins"
+
+msgid "Pr_eferences"
+msgstr "_Einstellungen"
+
+msgid "Mute _Sounds"
+msgstr "Stu_mmschalten"
+
+msgid "_Blink on New Message"
+msgstr "Be_i neuen Nachrichten blinken"
+
+msgid "_Quit"
+msgstr "_Beenden"
 
 msgid "Not started"
 msgstr "Nicht gestartet"