changeset 23475:f85450504940

propagate from branch 'im.pidgin.pidgin' (head 5387bc28fa09b238593c3dc292863ec3ce5f3c4e) to branch 'im.pidgin.cpw.qulogic.msn' (head f2d5cd45d05d5b074677524bb08f2069d0683b09)
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sat, 14 Jun 2008 07:47:38 +0000
parents ef4dbd2bb696 (diff) 9a53c441f8c1 (current diff)
children 9fdf0accd4aa
files libpurple/protocols/msn/notification.c libpurple/protocols/msn/notification.h libpurple/protocols/msn/oim.h libpurple/protocols/msn/session.h libpurple/protocols/msn/soap2.c
diffstat 63 files changed, 784 insertions(+), 526 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Jun 14 07:26:02 2008 +0000
+++ b/ChangeLog	Sat Jun 14 07:47:38 2008 +0000
@@ -7,12 +7,18 @@
 	  Marcus Lundblad, Jorge Villaseñor and other contributors)
 	* Yahoo! Japan now uses UTF-8, matching the behavior of official clients
 	  and restoring compatibility with the web messenger (Yusuke Odate)
+	* Add a configure option, --with-system-ssl-certs to allow packagers
+	  to specify a system-wide SSL CA certificates directory.  When set,
+	  we don't install our SSL CA certs, so it's important that the
+	  libpurple package depend on the CA certificates.
 
 	Pidgin:
-	* Custom buddy icons can now be added and removed to buddy list
+	* Custom buddy icons can now be added to and removed from buddy list
 	  entries via the buddy list entry right-click menu.
 	* Resize large incoming custom smileys to a maximum of 96px on either
 	  side.
+	* Offer to add new buddies into the same contact as existing buddies
+          in the same group if the alias given is the same.
 
 	General:
 	* Group and Chat buddy list entries can now be given custom buddy
--- a/configure.ac	Sat Jun 14 07:26:02 2008 +0000
+++ b/configure.ac	Sat Jun 14 07:47:38 2008 +0000
@@ -1207,8 +1207,8 @@
 dnl # Check for D-Bus libraries
 dnl #######################################################################
 
-AC_ARG_ENABLE(dbus, [AC_HELP_STRING([--enable-dbus], [enable D-Bus support])], , enable_dbus=yes)
-AC_ARG_ENABLE(nm, [AC_HELP_STRING([--enable-nm], [enable NetworkManager support (requires D-Bus)])], enable_nm=$enableval, enable_nm=yes)
+AC_ARG_ENABLE(dbus, [AC_HELP_STRING([--disable-dbus], [disable D-Bus support])], , enable_dbus=yes)
+AC_ARG_ENABLE(nm, [AC_HELP_STRING([--disable-nm], [disable NetworkManager support (requires D-Bus)])], enable_nm=$enableval, enable_nm=yes)
 
 if test "x$enable_dbus" = "xyes" ; then
 	AC_CHECK_PROG(enable_dbus, dbus-binding-tool, yes, no)
@@ -1561,6 +1561,18 @@
 dnl # Thanks go to Evolution for the checks.
 dnl #######################################################################
 
+AC_ARG_WITH(with-system-ssl-certs, [AC_HELP_STRING([--with-system-ssl-certs=<dir>], [directory containing system-wide SSL CA certificates])])
+
+SSL_CERTIFICATES_DIR=""
+if ! test -z "$with_system_ssl_certs" ; then
+	if ! test -d "$with_system_ssl_certs" ; then
+		AC_MSG_ERROR([$with_system_ssl_certs does not exist, if this is the correct location please make sure that it exists.])
+	fi
+	SSL_CERTIFICATES_DIR="$with_system_ssl_certs"
+fi
+AC_SUBST(SSL_CERTIFICATES_DIR)
+AM_CONDITIONAL(INSTALL_SSL_CERTIFICATES, test "x$SSL_CERTIFICATES_DIR" = "x")
+
 dnl These two are inverses of each other <-- stolen from evolution!
 
 AC_ARG_ENABLE(gnutls,
@@ -2409,6 +2421,9 @@
 fi
 echo Build with NetworkManager..... : $enable_nm
 echo SSL Library/Libraries......... : $msg_ssl
+if test "x$SSL_CERTIFICATES_DIR" != "x" ; then
+	eval eval echo SSL CA certificates directory. : $SSL_CERTIFICATES_DIR
+fi
 echo Build with Cyrus SASL support. : $enable_cyrus_sasl
 echo Use kerberos 4 with zephyr.... : $kerberos
 echo Use external libzephyr........ : $zephyr
--- a/finch/gntblist.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/finch/gntblist.c	Sat Jun 14 07:47:38 2008 +0000
@@ -3033,9 +3033,6 @@
 	gnt_widget_set_position(ggblist->window, purple_prefs_get_int(PREF_ROOT "/position/x"),
 			purple_prefs_get_int(PREF_ROOT "/position/y"));
 
-	gnt_tree_set_col_width(GNT_TREE(ggblist->tree), 0,
-			purple_prefs_get_int(PREF_ROOT "/size/width") - 1);
-
 	gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree);
 
 	ggblist->status = gnt_combo_box_new();
--- a/finch/gntft.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/finch/gntft.c	Sat Jun 14 07:47:38 2008 +0000
@@ -117,7 +117,9 @@
 			total_pct = 100 * total_bytes_xferred / total_file_size;
 		}
 
-		title = g_strdup_printf(_("File Transfers - %d%% of %d files"),
+		title = g_strdup_printf(ngettext("File Transfers - %d%% of %d file",
+						 "File Transfers - %d%% of %d files",
+						 num_active_xfers),
 				total_pct, num_active_xfers);
 		gnt_screen_rename_widget((xfer_dialog->window), title);
 		g_free(title);
--- a/finch/libgnt/gntmenu.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/finch/libgnt/gntmenu.c	Sat Jun 14 07:47:38 2008 +0000
@@ -283,6 +283,8 @@
 		do sub = sub->submenu; while (sub->submenu);
 		if (gnt_widget_key_pressed(GNT_WIDGET(sub), text))
 			return TRUE;
+		if (menu->type != GNT_MENU_TOPLEVEL)
+			return FALSE;
 	}
 
 	if ((text[0] == 27 && text[1] == 0) ||
@@ -332,10 +334,12 @@
 				return TRUE;
 			}
 		}
+		if (gnt_bindable_perform_action_key(GNT_BINDABLE(widget), text))
+			return TRUE;
 		return org_key_pressed(widget, text);
 	}
 
-	return FALSE;
+	return gnt_bindable_perform_action_key(GNT_BINDABLE(widget), text);
 }
 
 static void
@@ -434,7 +438,7 @@
 {
 	GntWidget *widget = GNT_WIDGET(instance);
 	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER |
-			GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_TRANSIENT);
+			GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_TRANSIENT | GNT_WIDGET_DISABLE_ACTIONS);
 	GNTDEBUG;
 }
 
--- a/finch/libgnt/gnttree.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/finch/libgnt/gnttree.c	Sat Jun 14 07:47:38 2008 +0000
@@ -110,13 +110,14 @@
 	gnt_widget_get_size(GNT_WIDGET(tree), &width, NULL);
 	if (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER))
 		width -= 2;
+	width -= 1;  /* Exclude the scrollbar from the calculation */
 	for (i = 0, total = 0; i < tree->ncol ; i++) {
 		if (tree->columns[i].flags & GNT_TREE_COLUMN_INVISIBLE)
 			continue;
 		if (tree->columns[i].flags & GNT_TREE_COLUMN_FIXED_SIZE)
-			width -= WIDTH(i) + 1;
+			width -= WIDTH(i) + (tree->priv->lastvisible != i);
 		else
-			total += WIDTH(i) + 1;
+			total += WIDTH(i) + (tree->priv->lastvisible != i);
 	}
 
 	if (total == 0)
--- a/libpurple/Makefile.am	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/Makefile.am	Sat Jun 14 07:47:38 2008 +0000
@@ -261,3 +261,9 @@
 	$(DBUS_CFLAGS) \
 	$(LIBXML_CFLAGS) \
 	$(NETWORKMANAGER_CFLAGS)
+
+# INSTALL_SSL_CERTIFICATES is true when SSL_CERTIFICATES_DIR is empty.
+# We want to use SSL_CERTIFICATES_DIR when it's not empty.
+if ! INSTALL_SSL_CERTIFICATES
+AM_CPPFLAGS += -DSSL_CERTIFICATES_DIR=\"$(SSL_CERTIFICATES_DIR)\"
+endif
--- a/libpurple/certificate.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/certificate.c	Sat Jun 14 07:47:38 2008 +0000
@@ -745,8 +745,12 @@
 		x509_ca_paths = g_list_append(NULL, g_build_filename(DATADIR,
 						   "ca-certs", NULL));
 #else
+# ifdef SSL_CERTIFICATES_DIR
+		x509_ca_paths = g_list_append(NULL, SSL_CERTIFICATES_DIR);
+# else
 		x509_ca_paths = g_list_append(NULL, g_build_filename(DATADIR,
 						   "purple", "ca-certs", NULL));
+# endif
 #endif
 	}
 
--- a/libpurple/plugins/perl/perl-handlers.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/plugins/perl/perl-handlers.c	Sat Jun 14 07:47:38 2008 +0000
@@ -383,6 +383,9 @@
 				case PURPLE_TYPE_BOXED:
 					*((void **)copy_args[i]) = (void *)SvIV(sv_args[i]);
 					break;
+				case PURPLE_TYPE_SUBTYPE:
+					*((void **)copy_args[i]) = purple_perl_ref_object(sv_args[i]);
+					break;
 
 				default:
 					break;
--- a/libpurple/protocols/irc/msgs.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/irc/msgs.c	Sat Jun 14 07:47:38 2008 +0000
@@ -215,7 +215,9 @@
 			/* This is an extended syntax, not in RFC 1459 */
 			int t1 = atoi(args[4]);
 			time_t t2 = time(NULL);
-			msg = g_strdup_printf(_("Ban on %s by %s, set %ld seconds ago"),
+			msg = g_strdup_printf(ngettext("Ban on %s by %s, set %ld second ago",
+						       "Ban on %s by %s, set %ld seconds ago",
+						       t2 - t1),
 			                      args[2], args[3], t2 - t1);
 		} else {
 			msg = g_strdup_printf(_("Ban on %s"), args[2]);
--- a/libpurple/protocols/jabber/buddy.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Sat Jun 14 07:47:38 2008 +0000
@@ -1793,22 +1793,6 @@
 	}
 }
 
-void jabber_buddy_get_info_chat(PurpleConnection *gc, int id,
-		const char *resource)
-{
-	JabberStream *js = gc->proto_data;
-	JabberChat *chat = jabber_chat_find_by_id(js, id);
-	char *full_jid;
-
-	if(!chat)
-		return;
-
-	full_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server, resource);
-	jabber_buddy_get_info_for_jid(js, full_jid);
-	g_free(full_jid);
-}
-
-
 static void jabber_buddy_set_invisibility(JabberStream *js, const char *who,
 		gboolean invisible)
 {
--- a/libpurple/protocols/jabber/buddy.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/jabber/buddy.h	Sat Jun 14 07:47:38 2008 +0000
@@ -96,8 +96,6 @@
 void jabber_buddy_remove_resource(JabberBuddy *jb, const char *resource);
 const char *jabber_buddy_get_status_msg(JabberBuddy *jb);
 void jabber_buddy_get_info(PurpleConnection *gc, const char *who);
-void jabber_buddy_get_info_chat(PurpleConnection *gc, int id,
-		const char *resource);
 
 GList *jabber_blist_node_menu(PurpleBlistNode *node);
 
--- a/libpurple/protocols/jabber/chat.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/jabber/chat.c	Sat Jun 14 07:47:38 2008 +0000
@@ -342,12 +342,18 @@
 {
 	JabberStream *js = gc->proto_data;
 	JabberChat *chat;
+	JabberChatMember *jcm;
 
 	chat = jabber_chat_find_by_id(js, id);
 
 	if(!chat)
 		return NULL;
 
+	jcm = g_hash_table_lookup(chat->members, who);
+	if (jcm != NULL && jcm->jid)
+		return g_strdup(jcm->jid);
+	
+
 	return g_strdup_printf("%s@%s/%s", chat->room, chat->server, who);
 }
 
--- a/libpurple/protocols/jabber/libxmpp.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/jabber/libxmpp.c	Sat Jun 14 07:47:38 2008 +0000
@@ -89,7 +89,7 @@
 	jabber_message_send_chat,		/* chat_send */
 	jabber_keepalive,				/* keepalive */
 	jabber_register_account,		/* register_user */
-	jabber_buddy_get_info_chat,		/* get_cb_info */
+	NULL,							/* get_cb_info */
 	NULL,							/* get_cb_away */
 	jabber_roster_alias_change,		/* alias_buddy */
 	jabber_roster_group_change,		/* group_buddy */
--- a/libpurple/protocols/jabber/si.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/jabber/si.c	Sat Jun 14 07:47:38 2008 +0000
@@ -623,7 +623,7 @@
 		return;
 	else if(acceptfd == -1) {
 		purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno));
-		/* TODO: This should cancel the ft */
+		/* Don't cancel the ft - allow it to fall to the next streamhost.*/
 		return;
 	}
 
@@ -659,8 +659,11 @@
 
 	jsx = xfer->data;
 
-	if(!(type = xmlnode_get_attrib(packet, "type")) || strcmp(type, "result"))
+	if(!(type = xmlnode_get_attrib(packet, "type")) || strcmp(type, "result")) {
+		if (type && !strcmp(type, "error"))
+			purple_xfer_cancel_remote(xfer);
 		return;
+	}
 
 	if(!(from = xmlnode_get_attrib(packet, "from")))
 		return;
@@ -718,14 +721,17 @@
 	JabberSIXfer *jsx;
 	JabberIq *iq;
 	xmlnode *query, *streamhost;
-	char *jid, port[6];
-	const char *local_ip, *public_ip, *ft_proxies;
+	const char *ft_proxies;
+	char port[6];
 	GList *tmp;
 	JabberBytestreamsStreamhost *sh, *sh2;
+	int streamhost_count = 0;
 
 	jsx = xfer->data;
 	jsx->listen_data = NULL;
 
+	/* I'm not sure under which conditions this can happen
+	 * (it seems like it shouldn't be possible */
 	if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL) {
 		purple_xfer_unref(xfer);
 		return;
@@ -733,13 +739,6 @@
 
 	purple_xfer_unref(xfer);
 
-	if (sock < 0) {
-		purple_xfer_cancel_local(xfer);
-		return;
-	}
-
-	jsx->local_streamhost_fd = sock;
-
 	iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET,
 			"http://jabber.org/protocol/bytestreams");
 	xmlnode_set_attrib(iq->node, "to", xfer->who);
@@ -747,41 +746,45 @@
 
 	xmlnode_set_attrib(query, "sid", jsx->stream_id);
 
-	jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
+	/* If we successfully started listening locally */
+	if (sock >= 0) {
+		gchar *jid;
+		const char *local_ip, *public_ip;
+
+		jsx->local_streamhost_fd = sock;
+
+		jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
 			jsx->js->user->domain, jsx->js->user->resource);
-	xfer->local_port = purple_network_get_port_from_fd(sock);
-	g_snprintf(port, sizeof(port), "%hu", xfer->local_port);
-
-	/* TODO: Should there be an option to not use the local host as a ft proxy?
-	 *       (to prevent revealing IP address, etc.) */
+		xfer->local_port = purple_network_get_port_from_fd(sock);
+		g_snprintf(port, sizeof(port), "%hu", xfer->local_port);
 
-	/* Include the localhost's IP (for in-network transfers) */
-	local_ip = purple_network_get_local_system_ip(jsx->js->fd);
-	if (strcmp(local_ip, "0.0.0.0") != 0)
-	{
-		streamhost = xmlnode_new_child(query, "streamhost");
-		xmlnode_set_attrib(streamhost, "jid", jid);
-		xmlnode_set_attrib(streamhost, "host", local_ip);
-		xmlnode_set_attrib(streamhost, "port", port);
+		/* Include the localhost's IP (for in-network transfers) */
+		local_ip = purple_network_get_local_system_ip(jsx->js->fd);
+		if (strcmp(local_ip, "0.0.0.0") != 0) {
+			streamhost_count++;
+			streamhost = xmlnode_new_child(query, "streamhost");
+			xmlnode_set_attrib(streamhost, "jid", jid);
+			xmlnode_set_attrib(streamhost, "host", local_ip);
+			xmlnode_set_attrib(streamhost, "port", port);
+		}
+
+		/* Include the public IP (assuming that there is a port mapped somehow) */
+		public_ip = purple_network_get_my_ip(jsx->js->fd);
+		if (strcmp(public_ip, local_ip) != 0 && strcmp(public_ip, "0.0.0.0") != 0) {
+			streamhost_count++;
+			streamhost = xmlnode_new_child(query, "streamhost");
+			xmlnode_set_attrib(streamhost, "jid", jid);
+			xmlnode_set_attrib(streamhost, "host", public_ip);
+			xmlnode_set_attrib(streamhost, "port", port);
+		}
+
+		g_free(jid);
+
+		/* The listener for the local proxy */
+		xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
+				jabber_si_xfer_bytestreams_send_connected_cb, xfer);
 	}
 
-	/* Include the public IP (assuming that there is a port mapped somehow) */
-	/* TODO: Check that it isn't the same as above and is a valid IP */
-	public_ip = purple_network_get_my_ip(jsx->js->fd);
-	if (strcmp(public_ip, local_ip) != 0)
-	{
-		streamhost = xmlnode_new_child(query, "streamhost");
-		xmlnode_set_attrib(streamhost, "jid", jid);
-		xmlnode_set_attrib(streamhost, "host", public_ip);
-		xmlnode_set_attrib(streamhost, "port", port);
-	}
-
-	g_free(jid);
-
-	/* The listener for the local proxy */
-	xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
-			jabber_si_xfer_bytestreams_send_connected_cb, xfer);
-
 	/* insert proxies here */
 	ft_proxies = purple_account_get_string(xfer->account, "ft_proxies", NULL);
 	if (ft_proxies) {
@@ -806,11 +809,12 @@
 
 			g_snprintf(port, sizeof(port), "%hu", portnum);
 
-			purple_debug_info("jabber", "jabber_si_xfer_bytestreams_listen_cb() will be looking at jsx %p: jsx->streamhosts %p and ft_proxy_list[%i] %p",
+			purple_debug_info("jabber", "jabber_si_xfer_bytestreams_listen_cb() will be looking at jsx %p: jsx->streamhosts %p and ft_proxy_list[%i] %p\n",
 							  jsx, jsx->streamhosts, i, ft_proxy_list[i]);
 			if(g_list_find_custom(jsx->streamhosts, ft_proxy_list[i], jabber_si_compare_jid) != NULL)
 				continue;
 
+			streamhost_count++;
 			streamhost = xmlnode_new_child(query, "streamhost");
 			xmlnode_set_attrib(streamhost, "jid", ft_proxy_list[i]);
 			xmlnode_set_attrib(streamhost, "host", ft_proxy_list[i]);
@@ -840,6 +844,7 @@
 		if(g_list_find_custom(jsx->streamhosts, sh->jid, jabber_si_compare_jid) != NULL)
 			continue;
 
+		streamhost_count++;
 		streamhost = xmlnode_new_child(query, "streamhost");
 		xmlnode_set_attrib(streamhost, "jid", sh->jid);
 		xmlnode_set_attrib(streamhost, "host", sh->host);
@@ -855,6 +860,14 @@
 		jsx->streamhosts = g_list_prepend(jsx->streamhosts, sh2);
 	}
 
+	/* We have no way of transferring, cancel the transfer */
+	if (streamhost_count == 0) {
+		jabber_iq_free(iq);
+		/* We should probably notify the target, but this really shouldn't ever happen */
+		purple_xfer_cancel_local(xfer);
+		return;
+	}
+
 	jabber_iq_set_callback(iq, jabber_si_connect_proxy_cb, xfer);
 
 	jabber_iq_send(iq);
@@ -869,13 +882,14 @@
 	purple_xfer_ref(xfer);
 
 	jsx = xfer->data;
+
+	/* TODO: Should there be an option to not use the local host as a ft proxy?
+	 *       (to prevent revealing IP address, etc.) */
 	jsx->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
 				jabber_si_xfer_bytestreams_listen_cb, xfer);
 	if (jsx->listen_data == NULL) {
-		purple_xfer_unref(xfer);
-		/* XXX: couldn't open a port, we're fscked */
-		purple_xfer_cancel_local(xfer);
-		return;
+		/* We couldn't open a local port.  Perhaps we can use a proxy. */
+		jabber_si_xfer_bytestreams_listen_cb(-1, xfer);
 	}
 
 }
@@ -1213,9 +1227,6 @@
 
 	js = gc->proto_data;
 
-	if(!purple_find_buddy(gc->account, who) || !jabber_buddy_find(js, who, FALSE))
-		return;
-
 	xfer = jabber_si_new_xfer(gc, who);
 
 	if (file)
--- a/libpurple/protocols/jabber/xdata.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/jabber/xdata.c	Sat Jun 14 07:47:38 2008 +0000
@@ -201,7 +201,7 @@
 	xmlnode *fn, *x;
 	PurpleRequestFields *fields;
 	PurpleRequestFieldGroup *group;
-	PurpleRequestField *field;
+	PurpleRequestField *field = NULL;
 
 	char *title = NULL;
 	char *instructions = NULL;
--- a/libpurple/protocols/msn/notification.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/msn/notification.c	Sat Jun 14 07:47:38 2008 +0000
@@ -998,13 +998,13 @@
 	MsnSlpLink *slplink;
 	MsnUser *user;
 
+	/* Tell libpurple that the user has signed off */
 	user = msn_userlist_find_user(cmdproc->session->userlist, cmd->params[0]);
-
 	user->status = "offline";
 	msn_user_update(user);
 
+	/* If we have an open MsnSlpLink with the user then close it */
 	slplink = msn_session_find_slplink(cmdproc->session, cmd->params[0]);
-
 	if (slplink != NULL)
 		msn_slplink_destroy(slplink);
 
--- a/libpurple/protocols/msn/notification.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/msn/notification.h	Sat Jun 14 07:47:38 2008 +0000
@@ -46,6 +46,11 @@
 struct _MsnNotification
 {
 	MsnSession *session;
+
+	/**
+	 * This is a convenience pointer that always points to
+	 * servconn->cmdproc
+	 */
 	MsnCmdProc *cmdproc;
 	MsnServConn *servconn;
 
--- a/libpurple/protocols/msn/oim.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/msn/oim.h	Sat Jun 14 07:47:38 2008 +0000
@@ -1,7 +1,7 @@
 /**
  * @file oim.h			Header file for oim.c
  *	Author
- * 		MaYuan<mayuan2006@gmail.com>
+ *		MaYuan<mayuan2006@gmail.com>
  * purple
  *
  * Purple is the legal property of its developers, whose names are too numerous
@@ -164,4 +164,3 @@
 void msn_oim_send_msg(MsnOim *oim);
 
 #endif/* _MSN_OIM_H_*/
-/*endof oim.h*/
--- a/libpurple/protocols/msn/session.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/msn/session.h	Sat Jun 14 07:47:38 2008 +0000
@@ -102,7 +102,6 @@
 
 	int servconns_count; /**< The count of server connections. */
 	GList *switches; /**< The list of all the switchboards. */
-	GList *directconns; /**< The list of all the directconnections. */
 	GList *slplinks; /**< The list of all the slplinks. */
 
 	/*psm info*/
--- a/libpurple/protocols/msn/slplink.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/msn/slplink.c	Sat Jun 14 07:47:38 2008 +0000
@@ -58,7 +58,7 @@
  * Main
  **************************************************************************/
 
-MsnSlpLink *
+static MsnSlpLink *
 msn_slplink_new(MsnSession *session, const char *username)
 {
 	MsnSlpLink *slplink;
--- a/libpurple/protocols/msn/slplink.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/msn/slplink.h	Sat Jun 14 07:47:38 2008 +0000
@@ -59,11 +59,21 @@
 	GQueue *slp_msg_queue;
 };
 
-MsnSlpLink *msn_slplink_new(MsnSession *session, const char *username);
 void msn_slplink_destroy(MsnSlpLink *slplink);
+
+/**
+ * @return An MsnSlpLink for the given user, or NULL if there is no
+ *         existing MsnSlpLink.
+ */
 MsnSlpLink *msn_session_find_slplink(MsnSession *session,
 									 const char *who);
+
+/**
+ * @return An MsnSlpLink for the given user.  One will be created if
+ *         it does not already exist.
+ */
 MsnSlpLink *msn_session_get_slplink(MsnSession *session, const char *username);
+
 MsnSlpSession *msn_slplink_find_slp_session(MsnSlpLink *slplink,
 											long session_id);
 void msn_slplink_add_slpcall(MsnSlpLink *slplink, MsnSlpCall *slpcall);
--- a/libpurple/protocols/msn/soap2.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/msn/soap2.c	Sat Jun 14 07:47:38 2008 +0000
@@ -83,6 +83,7 @@
 static void msn_soap_request_destroy(MsnSoapRequest *req);
 static void msn_soap_connection_sanitize(MsnSoapConnection *conn, gboolean disconnect);
 static gboolean msn_soap_write_cb_internal(gpointer data, gint fd, PurpleInputCondition cond, gboolean initial);
+static void msn_soap_process(MsnSoapConnection *conn);
 
 static gboolean
 msn_soap_cleanup_each(gpointer key, gpointer value, gpointer data)
@@ -268,45 +269,53 @@
 msn_soap_read_cb(gpointer data, gint fd, PurpleInputCondition cond)
 {
 	MsnSoapConnection *conn = data;
-	int count = 0, cnt;
-	char buf[8192];
-	char *linebreak;
-	char *cursor;
-	gboolean handled = FALSE;
+	int count = 0, cnt, perrno;
+	/* This buffer needs to be larger than any packets received from
+		login.live.com or Adium will fail to receive the packet
+		(something weird with the login.live.com server). With NSS it works
+		fine, so I believe it's some bug with OS X */ 
+	char buf[16 * 1024];
 
 	if (conn->message == NULL) {
 		conn->message = msn_soap_message_new(NULL, NULL);
 	}
 
+	if (conn->buf == NULL) {
+		conn->buf = g_string_new_len(buf, 0);
+	}
+	
 	while ((cnt = purple_ssl_read(conn->ssl, buf, sizeof(buf))) > 0) {
 		purple_debug_info("soap", "read %d bytes\n", cnt);
 		count += cnt;
-		if (conn->buf == NULL) {
-			conn->buf = g_string_new_len(buf, cnt);
-		} else {
-			g_string_append_len(conn->buf, buf, cnt);
-		}
+		g_string_append_len(conn->buf, buf, cnt);
 	}
 
-	if (cnt < 0) {
-		if (errno != EAGAIN) {
-			purple_debug_info("soap", "read: %s\n", g_strerror(errno));
+	/* && count is necessary for Adium, on OS X the last read always
+	   return an error, so we want to proceed anyway. See #5212 for
+	   discussion on this and the above buffer size issues */
+	if(cnt < 0 && errno == EAGAIN && count == 0)
+		return;
+
+	// msn_soap_process could alter errno
+	perrno = errno;
+	msn_soap_process(conn);
+	
+	if (cnt < 0 && perrno != EAGAIN) {
+		purple_debug_info("soap", "read: %s\n", g_strerror(perrno));
+		// It's possible msn_soap_process closed the ssl connection
+		if (conn->ssl) {
 			purple_ssl_close(conn->ssl);
 			conn->ssl = NULL;
 			msn_soap_connection_handle_next(conn);
-			return;
-		} else if (count == 0) {
-			return;
 		}
 	}
+}
 
-	if (cnt == 0 && count == 0) {
-		purple_debug_info("soap", "msn_soap_read_cb() called, but no data available?\n");
-		purple_ssl_close(conn->ssl);
-		conn->ssl = NULL;
-		msn_soap_connection_handle_next(conn);
-		return;
-	}
+static void
+msn_soap_process(MsnSoapConnection *conn) {
+	gboolean handled = FALSE;
+	char *cursor;
+	char *linebreak;
 
 	purple_debug_info("soap", "current %s\n", conn->buf->str);
 
--- a/libpurple/protocols/msn/userlist.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/msn/userlist.h	Sat Jun 14 07:47:38 2008 +0000
@@ -45,11 +45,8 @@
 {
 	MsnSession *session;
 
-	/* MsnUsers *users; */
-	/* MsnGroups *groups; */
-
-	GList *users;
-	GList *groups;
+	GList *users; /* Contains MsnUsers */
+	GList *groups; /* Contains MsnGroups */
 
 	GQueue *buddy_icon_requests;
 	int buddy_icon_window;
--- a/libpurple/protocols/myspace/myspace.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Sat Jun 14 07:47:38 2008 +0000
@@ -1328,7 +1328,10 @@
 	delta = time(NULL) - session->last_comm;
 	/* purple_debug_info("msim", "msim_check_alive: delta=%d\n", delta); */
 	if (delta >= MSIM_KEEPALIVE_INTERVAL) {
-		errmsg = g_strdup_printf(_("Connection to server lost (no data received within %d seconds)"), (int)delta);
+	        errmsg = g_strdup_printf(ngettext("Connection to server lost (no data received within %d second)",
+						  "Connection to server lost (no data received within %d seconds)",
+						  (int)delta),
+					 (int)delta);
 
 		purple_debug_info("msim", "msim_check_alive: %s > interval of %d, presumed dead\n",
 				errmsg, MSIM_KEEPALIVE_INTERVAL);
@@ -2404,7 +2407,7 @@
 		const char *username;
 
 		/* If the account does not exist, we can't look up the user. */
-		if (!account)
+		if (!account || !account->gc)
 			return str;
 
 		id = atol(str);
@@ -2946,7 +2949,10 @@
 
 	switch (GPOINTER_TO_UINT(user_data)) {
 		case MSIM_CONTACT_LIST_IMPORT_ALL_FRIENDS:
-			msg = g_strdup_printf(_("%d buddies were added or updated from the server (including buddies already on the server-side list)"), buddy_count);
+		        msg = g_strdup_printf(ngettext("%d buddy was added or updated from the server (including buddies already on the server-side list)",
+						       "%d buddies were added or updated from the server (including buddies already on the server-side list)",
+						       buddy_count),
+					      buddy_count);
 			purple_notify_info(session->account, _("Add contacts from server"), msg, NULL);
 			g_free(msg);
 			break;
--- a/libpurple/protocols/oscar/family_admin.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_admin.c	Sat Jun 14 07:47:38 2008 +0000
@@ -47,8 +47,8 @@
 	byte_stream_put16(&bs, info);
 	byte_stream_put16(&bs, 0x0000);
 
-	snacid = aim_cachesnac(od, 0x0007, 0x0002, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0007, 0x0002, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ADMIN, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -127,8 +127,8 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -154,8 +154,8 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -177,8 +177,8 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -194,11 +194,11 @@
 void
 aim_admin_reqconfirm(OscarData *od, FlapConnection *conn)
 {
-	aim_genericreq_n(od, conn, 0x0007, 0x0006);
+	aim_genericreq_n(od, conn, SNAC_FAMILY_ADMIN, 0x0006);
 }
 
 /**
- * Subtype 0x0007 - Account confirmation request acknowledgement.
+ * Subtype SNAC_FAMILY_ADMIN - Account confirmation request acknowledgement.
  */
 static int
 accountconfirm(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
@@ -227,7 +227,7 @@
 	if ((snac->subtype == 0x0003) || (snac->subtype == 0x0005)) {
 		infochange(od, conn, mod, frame, snac, bs);
 		return 1;
-	} else if (snac->subtype == 0x0007)
+	} else if (snac->subtype == SNAC_FAMILY_ADMIN)
 		return accountconfirm(od, conn, mod, frame, snac, bs);
 
 	return 0;
@@ -235,7 +235,7 @@
 
 int admin_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0007;
+	mod->family = SNAC_FAMILY_ADMIN;
 	mod->version = 0x0001;
 	mod->toolid = 0x0010;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_advert.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_advert.c	Sat Jun 14 07:47:38 2008 +0000
@@ -28,7 +28,7 @@
 void
 aim_ads_requestads(OscarData *od, FlapConnection *conn)
 {
-	aim_genericreq_n(od, conn, 0x0005, 0x0002);
+	aim_genericreq_n(od, conn, SNAC_FAMILY_ADVERT, 0x0002);
 }
 
 static int snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs)
@@ -39,7 +39,7 @@
 int adverts_modfirst(OscarData *od, aim_module_t *mod)
 {
 
-	mod->family = 0x0005;
+	mod->family = SNAC_FAMILY_ADVERT;
 	mod->version = 0x0001;
 	mod->toolid = 0x0001;
 	mod->toolversion = 0x0001;
--- a/libpurple/protocols/oscar/family_alert.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_alert.c	Sat Jun 14 07:47:38 2008 +0000
@@ -72,8 +72,8 @@
 	byte_stream_put16(&bs, 0xb0ee);
 	byte_stream_put16(&bs, 0x0631);
 
-	snacid = aim_cachesnac(od, 0x0018, 0x0006, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0018, 0x0006, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ALERT, 0x0006, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ALERT, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -188,8 +188,8 @@
 	byte_stream_put32(&bs, 0x04000000);
 	byte_stream_put32(&bs, 0x00000000);
 
-	snacid = aim_cachesnac(od, 0x0018, 0x0016, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0018, 0x0006, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ALERT, 0x0016, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ALERT, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -225,7 +225,7 @@
 int
 email_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0018;
+	mod->family = SNAC_FAMILY_ALERT;
 	mod->version = 0x0001;
 	mod->toolid = 0x0010;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_auth.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_auth.c	Sat Jun 14 07:47:38 2008 +0000
@@ -200,9 +200,13 @@
  *        usually happens for AOL accounts.  We are told that we
  *        should truncate it if the 0x0017/0x0007 SNAC contains
  *        a TLV of type 0x0026 with data 0x0000.
+ * @param allow_multiple_logins Allow multiple logins? If TRUE, the AIM
+ *        server will prompt the user when multiple logins occur. If
+ *        FALSE, existing connections (on other clients) will be
+ *        disconnected automatically as we connect.
  */
 int
-aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key)
+aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key, gboolean allow_multiple_logins)
 {
 	FlapFrame *frame;
 	GSList *tlvlist = NULL;
@@ -221,8 +225,8 @@
 
 	frame = flap_frame_new(od, 0x02, 1152);
 
-	snacid = aim_cachesnac(od, 0x0017, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0017, 0x0002, 0x0000, snacid);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_AUTH, 0x0002, 0x0000, NULL, 0);
+	aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, 0x0002, 0x0000, snacid);
 
 	aim_tlvlist_add_str(&tlvlist, 0x0001, sn);
 
@@ -256,7 +260,7 @@
 	 * If set, old-fashioned buddy lists will not work. You will need
 	 * to use SSI.
 	 */
-	aim_tlvlist_add_8(&tlvlist, 0x004a, 0x01);
+	aim_tlvlist_add_8(&tlvlist, 0x004a, (allow_multiple_logins ? 0x01 : 0x02));
 
 	aim_tlvlist_write(&frame->data, &tlvlist);
 
@@ -403,7 +407,7 @@
 
 	od->authinfo = info;
 
-	if ((userfunc = aim_callhandler(od, snac ? snac->family : 0x0017, snac ? snac->subtype : 0x0003)))
+	if ((userfunc = aim_callhandler(od, snac ? snac->family : SNAC_FAMILY_AUTH, snac ? snac->subtype : 0x0003)))
 		ret = userfunc(od, conn, frame, info);
 
 	aim_tlvlist_free(tlvlist);
@@ -449,7 +453,7 @@
 	FlapFrame frame;
 	aim_rxcallback_t userfunc;
 
-	if ((userfunc = aim_callhandler(od, 0x0017, 0x0007)))
+	if ((userfunc = aim_callhandler(od, SNAC_FAMILY_AUTH, 0x0007)))
 		userfunc(od, conn, &frame, "");
 
 	return 0;
@@ -483,8 +487,8 @@
 
 	frame = flap_frame_new(od, 0x02, 10+2+2+strlen(sn)+8);
 
-	snacid = aim_cachesnac(od, 0x0017, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0017, 0x0006, 0x0000, snacid);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_AUTH, 0x0006, 0x0000, NULL, 0);
+	aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, 0x0006, 0x0000, snacid);
 
 	aim_tlvlist_add_str(&tlvlist, 0x0001, sn);
 
@@ -628,7 +632,7 @@
 int
 auth_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0017;
+	mod->family = SNAC_FAMILY_AUTH;
 	mod->version = 0x0000;
 	mod->flags = 0;
 	strncpy(mod->name, "auth", sizeof(mod->name));
--- a/libpurple/protocols/oscar/family_bart.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_bart.c	Sat Jun 14 07:47:38 2008 +0000
@@ -43,7 +43,7 @@
 	ByteStream bs;
 	aim_snacid_t snacid;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0010)) || !icon || !iconlen)
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_BART)) || !icon || !iconlen)
 		return -EINVAL;
 
 	byte_stream_new(&bs, 2 + 2 + iconlen);
@@ -55,8 +55,8 @@
 	byte_stream_put16(&bs, iconlen);
 	byte_stream_putraw(&bs, icon, iconlen);
 
-	snacid = aim_cachesnac(od, 0x0010, 0x0002, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0010, 0x0002, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_BART, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_BART, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -102,7 +102,7 @@
 	ByteStream bs;
 	aim_snacid_t snacid;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0010)) || !sn || !strlen(sn) || !iconcsum || !iconcsumlen)
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_BART)) || !sn || !strlen(sn) || !iconcsum || !iconcsumlen)
 		return -EINVAL;
 
 	byte_stream_new(&bs, 1+strlen(sn) + 4 + 1+iconcsumlen);
@@ -120,8 +120,8 @@
 	byte_stream_put8(&bs, iconcsumlen);
 	byte_stream_putraw(&bs, iconcsum, iconcsumlen);
 
-	snacid = aim_cachesnac(od, 0x0010, 0x0004, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0010, 0x0004, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_BART, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_BART, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -174,7 +174,7 @@
 int
 bart_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0010;
+	mod->family = SNAC_FAMILY_BART;
 	mod->version = 0x0001;
 	mod->toolid = 0x0010;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_bos.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_bos.c	Sat Jun 14 07:47:38 2008 +0000
@@ -32,7 +32,7 @@
 void
 aim_bos_reqrights(OscarData *od, FlapConnection *conn)
 {
-	aim_genericreq_n_snacid(od, conn, 0x0009, 0x0002);
+	aim_genericreq_n_snacid(od, conn, SNAC_FAMILY_BOS, 0x0002);
 }
 
 /* Subtype 0x0003 - BOS Rights. */
@@ -81,7 +81,7 @@
 void
 aim_bos_setgroupperm(OscarData *od, FlapConnection *conn, guint32 mask)
 {
-	aim_genericreq_l(od, conn, 0x0009, 0x0004, &mask);
+	aim_genericreq_l(od, conn, SNAC_FAMILY_BOS, 0x0004, &mask);
 }
 
 /*
@@ -153,8 +153,8 @@
 	}
 	g_free(localcpy);
 
-	snacid = aim_cachesnac(od, 0x0009, subtype, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0009, subtype, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_BOS, subtype, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_BOS, subtype, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -173,7 +173,7 @@
 int
 bos_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0009;
+	mod->family = SNAC_FAMILY_BOS;
 	mod->version = 0x0001;
 	mod->toolid = 0x0110;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_buddy.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_buddy.c	Sat Jun 14 07:47:38 2008 +0000
@@ -108,8 +108,8 @@
 	byte_stream_put8(&bs, strlen(sn));
 	byte_stream_putstr(&bs, sn);
 
-	snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
-	flap_connection_send_snac(od, conn, 0x0003, 0x0004, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, sn, strlen(sn)+1);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -159,8 +159,8 @@
 		tmpptr = strtok(NULL, "&");
 	}
 
-	snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0003, 0x0004, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -190,8 +190,8 @@
 	byte_stream_put8(&bs, strlen(sn));
 	byte_stream_putstr(&bs, sn);
 
-	snacid = aim_cachesnac(od, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1);
-	flap_connection_send_snac(od, conn, 0x0003, 0x0005, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_BUDDY, 0x0005, 0x0000, sn, strlen(sn)+1);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_BUDDY, 0x0005, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -243,7 +243,7 @@
 int
 buddylist_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0003;
+	mod->family = SNAC_FAMILY_BUDDY;
 	mod->version = 0x0001;
 	mod->toolid = 0x0110;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_chat.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_chat.c	Sat Jun 14 07:47:38 2008 +0000
@@ -364,7 +364,7 @@
 
 	byte_stream_new(&bs, 1142);
 
-	snacid = aim_cachesnac(od, 0x000e, 0x0005, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_CHAT, 0x0005, 0x0000, NULL, 0);
 
 	/*
 	 * Cookie
@@ -432,7 +432,7 @@
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x000e, 0x0005, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_CHAT, 0x0005, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -594,7 +594,7 @@
 int
 chat_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x000e;
+	mod->family = SNAC_FAMILY_CHAT;
 	mod->version = 0x0001;
 	mod->toolid = 0x0010;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_chatnav.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_chatnav.c	Sat Jun 14 07:47:38 2008 +0000
@@ -42,7 +42,7 @@
 		return 0;
 	}
 
-	if (snac2->family != 0x000d) {
+	if (snac2->family != SNAC_FAMILY_CHATNAV) {
 		purple_debug_warning("oscar", "chatnav error: received response that maps to corrupt request (fam=%04x)\n", snac2->family);
 		return 0;
 	}
@@ -80,7 +80,7 @@
  */
 void aim_chatnav_reqrights(OscarData *od, FlapConnection *conn)
 {
-	aim_genericreq_n_snacid(od, conn, 0x000d, 0x0002);
+	aim_genericreq_n_snacid(od, conn, SNAC_FAMILY_CHATNAV, 0x0002);
 }
 
 /*
@@ -97,7 +97,7 @@
 
 	byte_stream_new(&bs, 1142);
 
-	snacid = aim_cachesnac(od, 0x000d, 0x0008, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_CHATNAV, 0x0008, 0x0000, NULL, 0);
 
 	/* exchange */
 	byte_stream_put16(&bs, exchange);
@@ -137,7 +137,7 @@
 
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x000d, 0x0008, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_CHATNAV, 0x0008, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -460,7 +460,7 @@
 		return 0;
 	}
 
-	if (snac2->family != 0x000d) {
+	if (snac2->family != SNAC_FAMILY_CHATNAV) {
 		purple_debug_misc("oscar", "faim: chatnav_parse_info: received response that maps to corrupt request! (fam=%04x)\n", snac2->family);
 		return 0;
 	}
@@ -506,7 +506,7 @@
 int
 chatnav_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x000d;
+	mod->family = SNAC_FAMILY_CHATNAV;
 	mod->version = 0x0001;
 	mod->toolid = 0x0010;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_icbm.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Sat Jun 14 07:47:38 2008 +0000
@@ -164,7 +164,7 @@
 	ByteStream bs;
 	aim_snacid_t snacid;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
 		return -EINVAL;
 
 	if (!params)
@@ -182,8 +182,8 @@
 	byte_stream_put16(&bs, params->maxrecverwarn);
 	byte_stream_put32(&bs, params->minmsginterval);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0002, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0004, 0x0002, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -198,10 +198,10 @@
 {
 	FlapConnection *conn;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
 		return -EINVAL;
 
-	aim_genericreq_n_snacid(od, conn, 0x0004, 0x0004);
+	aim_genericreq_n_snacid(od, conn, SNAC_FAMILY_ICBM, 0x0004);
 
 	return 0;
 }
@@ -237,7 +237,7 @@
  * Possible flags:
  *   AIM_IMFLAGS_AWAY  -- Marks the message as an autoresponse
  *   AIM_IMFLAGS_ACK   -- Requests that the server send an ack
- *                        when the message is received (of type 0x0004/0x000c)
+ *                        when the message is received (of type SNAC_FAMILY_ICBM/0x000c)
  *   AIM_IMFLAGS_OFFLINE--If destination is offline, store it until they are
  *                        online (probably ICQ only).
  *
@@ -280,7 +280,7 @@
 	int msgtlvlen;
 	static const guint8 deffeatures[] = { 0x01, 0x01, 0x01, 0x02 };
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
 		return -EINVAL;
 
 	if (!args)
@@ -410,9 +410,9 @@
 	}
 
 	/* XXX - should be optional */
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, args->destsn, strlen(args->destsn)+1);
-
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &data);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, args->destsn, strlen(args->destsn)+1);
+
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &data);
 	byte_stream_destroy(&data);
 
 	/* clean out SNACs over 60sec old */
@@ -462,7 +462,7 @@
 	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
 	ByteStream hdrbs;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
 		return -EINVAL;
 
 	if (!sn || !msg || !roomname)
@@ -472,7 +472,7 @@
 
 	byte_stream_new(&bs, 1142+strlen(sn)+strlen(roomname)+strlen(msg));
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, sn, strlen(sn)+1);
 
 	/* XXX should be uncached by an unwritten 'invite accept' handler */
 	priv = g_malloc(sizeof(struct aim_invite_priv));
@@ -519,7 +519,7 @@
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -539,7 +539,7 @@
 	aim_snacid_t snacid;
 	guchar cookie[8];
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
 		return -EINVAL;
 
 	if (!sn || !icon || (iconlen <= 0) || (iconlen >= MAXICONLEN))
@@ -549,7 +549,7 @@
 
 	byte_stream_new(&bs, 8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, cookie, 0x0002, sn);
@@ -589,7 +589,7 @@
 	byte_stream_put16(&bs, 0x0003);
 	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -620,7 +620,7 @@
 	const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* OSCAR_CAPABILITY_ICQRTF capability in string form */
 	int servdatalen;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
 		return -EINVAL;
 
 	if (!args || !args->destsn || !args->rtfmsg)
@@ -632,7 +632,7 @@
 
 	byte_stream_new(&bs, 128+servdatalen);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, cookie, 0x0002, args->destsn);
@@ -682,7 +682,7 @@
 	byte_stream_putle32(&bs, strlen(rtfcap)+1);
 	byte_stream_putraw(&bs, (const guint8 *)rtfcap, strlen(rtfcap)+1);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -704,13 +704,13 @@
 	ByteStream hdrbs;
 
 	od = peer_conn->od;
-	conn = flap_connection_findbygroup(od, 0x0004);
+	conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM);
 	if (conn == NULL)
 		return;
 
 	byte_stream_new(&bs, 118+strlen(peer_conn->sn));
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->sn);
@@ -735,7 +735,7 @@
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -753,13 +753,13 @@
 	aim_snacid_t snacid;
 
 	od = peer_conn->od;
-	conn = flap_connection_findbygroup(od, 0x0004);
+	conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM);
 	if (conn == NULL)
 		return;
 
 	byte_stream_new(&bs, 11+strlen(peer_conn->sn) + 4+2+8+16);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->sn);
@@ -770,7 +770,7 @@
 	byte_stream_putraw(&bs, peer_conn->cookie, 8);
 	byte_stream_putcaps(&bs, peer_conn->type);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -791,13 +791,13 @@
 	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
 	ByteStream hdrbs;
 
-	conn = flap_connection_findbygroup(od, 0x0004);
+	conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM);
 	if (conn == NULL)
 		return;
 
 	byte_stream_new(&bs, 246+strlen(sn));
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, cookie, 0x0002, sn);
@@ -825,7 +825,7 @@
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -844,13 +844,13 @@
 	ByteStream hdrbs;
 	guint8 ip_comp[4];
 
-	conn = flap_connection_findbygroup(od, 0x0004);
+	conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM);
 	if (conn == NULL)
 		return;
 
 	byte_stream_new(&bs, 246+strlen(sn));
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, cookie, 0x0002, sn);
@@ -888,7 +888,7 @@
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -906,13 +906,13 @@
 	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
 	ByteStream hdrbs;
 
-	conn = flap_connection_findbygroup(od, 0x0004);
+	conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM);
 	if (conn == NULL)
 		return;
 
 	byte_stream_new(&bs, 1014);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, cookie, 0x0002, sn);
@@ -971,7 +971,7 @@
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -990,13 +990,13 @@
 	ByteStream hdrbs;
 	guint8 ip_comp[4];
 
-	conn = flap_connection_findbygroup(od, 0x0004);
+	conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM);
 	if (conn == NULL)
 		return;
 
 	byte_stream_new(&bs, 1014);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, cookie, 0x0002, sn);
@@ -1064,7 +1064,7 @@
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -1085,14 +1085,14 @@
 	aim_snacid_t snacid;
 	guchar cookie[8];
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)) || !sn)
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)) || !sn)
 		return -EINVAL;
 
 	aim_icbm_makecookie(cookie);
 
 	byte_stream_new(&bs, 8+2+1+strlen(sn) + 4+0x5e + 4);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	/* ICBM header */
 	aim_im_puticbm(&bs, cookie, 0x0002, sn);
@@ -1160,7 +1160,7 @@
 	byte_stream_put16(&bs, 0x0003);
 	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -1196,7 +1196,7 @@
 
 	byte_stream_new(&bs, 8+3+strlen(sn)+12+strlen(message)+1+4);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
 
 	aim_icbm_makecookie(cookie);
 
@@ -1229,7 +1229,7 @@
 	byte_stream_put16(&bs, 0x0006);
 	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -2268,13 +2268,13 @@
 
 	byte_stream_new(&bs, strlen(sn)+3);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0008, 0x0000, sn, strlen(sn)+1);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0008, 0x0000, sn, strlen(sn)+1);
 
 	byte_stream_put16(&bs, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000);
 	byte_stream_put8(&bs, strlen(sn));
 	byte_stream_putstr(&bs, sn);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0008, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0008, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -2321,12 +2321,12 @@
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
 		return -EINVAL;
 
 	byte_stream_new(&bs, 8+2+1+strlen(sn)+6);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x000b, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x000b, 0x0000, NULL, 0);
 
 	byte_stream_putraw(&bs, cookie, 8);
 
@@ -2338,7 +2338,7 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x000b, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x000b, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -2660,7 +2660,7 @@
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0002)))
 		return -EINVAL;
 
-	aim_genericreq_n(od, conn, 0x0004, 0x0010);
+	aim_genericreq_n(od, conn, SNAC_FAMILY_ICBM, 0x0010);
 
 	return 0;
 }
@@ -2686,7 +2686,7 @@
 
 	byte_stream_new(&bs, 11+strlen(sn)+2);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0014, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0014, 0x0000, NULL, 0);
 
 	/*
 	 * 8 days of light
@@ -2713,7 +2713,7 @@
 	 */
 	byte_stream_put16(&bs, type2);
 
-	flap_connection_send_snac(od, conn, 0x0004, 0x0014, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0014, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -2773,7 +2773,7 @@
 int
 msg_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0004;
+	mod->family = SNAC_FAMILY_ICBM;
 	mod->version = 0x0001;
 	mod->toolid = 0x0110;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_icq.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_icq.c	Sat Jun 14 07:47:38 2008 +0000
@@ -33,14 +33,14 @@
 	aim_snacid_t snacid;
 	int bslen;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	bslen = 2 + 4 + 2 + 2;
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -51,7 +51,7 @@
 	byte_stream_putle16(&bs, 0x003c); /* I command thee. */
 	byte_stream_putle16(&bs, snacid); /* eh. */
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -65,14 +65,14 @@
 	aim_snacid_t snacid;
 	int bslen;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	bslen = 2 + 4 + 2 + 2;
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -83,7 +83,7 @@
 	byte_stream_putle16(&bs, 0x003e); /* I command thee. */
 	byte_stream_putle16(&bs, snacid); /* eh. */
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -99,14 +99,14 @@
 	aim_snacid_t snacid;
 	int bslen;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	bslen = 2+4+2+2+2+2+2+1+1+1+1+1+1;
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -126,7 +126,7 @@
 	byte_stream_putle8(&bs, 0x00);
 	byte_stream_putle8(&bs, !auth_required);
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -151,7 +151,7 @@
 	if (!passwd)
 		return -EINVAL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	passwdlen = strlen(passwd);
@@ -161,7 +161,7 @@
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -176,7 +176,7 @@
 	byte_stream_putstr(&bs, passwd);
 	byte_stream_putle8(&bs, '\0');
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -194,14 +194,14 @@
 	if (!uin || uin[0] < '0' || uin[0] > '9')
 		return -EINVAL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	bslen = 2 + 4 + 2 + 2 + 2 + 4;
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -214,7 +214,7 @@
 	byte_stream_putle16(&bs, 0x04b2); /* shrug. */
 	byte_stream_putle32(&bs, atoi(uin));
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -239,14 +239,14 @@
 	if (!uin || uin[0] < '0' || uin[0] > '9')
 		return -EINVAL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	bslen = 2 + 4 + 2 + 2 + 2 + 4;
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -259,7 +259,7 @@
 	byte_stream_putle16(&bs, 0x04ba); /* shrug. */
 	byte_stream_putle32(&bs, atoi(uin));
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -283,14 +283,14 @@
 	if (!uin || uin[0] < '0' || uin[0] > '9')
 		return -EINVAL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	bslen = 2 + 4 + 2 + 2 + 2 + 4;
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -303,7 +303,7 @@
 	byte_stream_putle16(&bs, 0x051f); /* shrug. */
 	byte_stream_putle32(&bs, atoi(uin));
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -321,14 +321,14 @@
 	if (!xml || !strlen(xml))
 		return -EINVAL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	bslen = 2 + 10 + 2 + strlen(xml) + 1;
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -342,7 +342,7 @@
 	byte_stream_putle16(&bs, strlen(xml) + 1);
 	byte_stream_putraw(&bs, (guint8 *)xml, strlen(xml) + 1);
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -380,7 +380,7 @@
 	struct tm *tm;
 	gchar *stripped;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
 	if (!name || !msg || !alias)
@@ -411,7 +411,7 @@
 
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	/* For simplicity, don't bother using a tlvlist */
 	byte_stream_put16(&bs, 0x0001);
@@ -436,7 +436,7 @@
 	byte_stream_putstr(&bs, xml);
 	byte_stream_put8(&bs, 0x00);
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -460,7 +460,7 @@
 
 	purple_debug_misc("oscar", "aim_icq_getstatusnote: requesting status note for %s.\n", uin);
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 	{
 		purple_debug_misc("oscar", "aim_icq_getstatusnote: no connection.\n");
 		return -EINVAL;
@@ -469,7 +469,7 @@
 	bslen = 2 + 4 + 2 + 2 + 2 + 2 + 58 + strlen(uin);
 	byte_stream_new(&bs, 4 + bslen);
 
-	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
 
 	byte_stream_put16(&bs, 0x0001);
 	byte_stream_put16(&bs, bslen);
@@ -497,7 +497,7 @@
 	byte_stream_put16(&bs, strlen(uin));
 	byte_stream_putstr(&bs, uin);
 
-	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -541,7 +541,7 @@
 }
 
 /**
- * Subtype 0x0003 - Response to 0x0015/0x002, contains an ICQesque packet.
+ * Subtype 0x0003 - Response to SNAC_FAMILY_ICQ/0x002, contains an ICQesque packet.
  */
 static int
 icqresponse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
@@ -940,7 +940,7 @@
 int
 icq_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0015;
+	mod->family = SNAC_FAMILY_ICQ;
 	mod->version = 0x0001;
 	mod->toolid = 0x0110;
 	mod->toolversion = 0x047c;
--- a/libpurple/protocols/oscar/family_invite.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_invite.c	Sat Jun 14 07:47:38 2008 +0000
@@ -41,7 +41,7 @@
 int invite_modfirst(OscarData *od, aim_module_t *mod)
 {
 
-	mod->family = 0x0006;
+	mod->family = SNAC_FAMILY_INVITE;
 	mod->version = 0x0001;
 	mod->toolid = 0x0110;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_locate.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_locate.c	Sat Jun 14 07:47:38 2008 +0000
@@ -171,7 +171,7 @@
 	 {0x09, 0x46, 0xf0, 0x03, 0x4c, 0x7f, 0x11, 0xd1,
 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
 
-	{OSCAR_CAPABILITY_GENERICUNKNOWN,
+	{OSCAR_CAPABILITY_ICHAT_SCREENSHARE,
 	 {0x09, 0x46, 0xf0, 0x04, 0x4c, 0x7f, 0x11, 0xd1,
 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
 
@@ -943,7 +943,7 @@
 		return 0;
 	}
 
-	if ((snac2->family != 0x0002) && (snac2->type != 0x0015)) {
+	if ((snac2->family != SNAC_FAMILY_LOCATE) && (snac2->type != 0x0015)) {
 		purple_debug_misc("oscar", "faim: locate.c, error(): received response from invalid request! %d\n", snac2->family);
 		return 0;
 	}
@@ -1094,12 +1094,12 @@
 
 	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
-	snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, NULL, 0);
 
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0002, 0x0004, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -1124,12 +1124,12 @@
 
 	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
-	snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, NULL, 0);
 
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0002, 0x0004, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -1157,13 +1157,13 @@
 
 	byte_stream_new(&bs, 2+1+strlen(sn));
 
-	snacid = aim_cachesnac(od, 0x0002, 0x0005, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0005, 0x0000, NULL, 0);
 
 	byte_stream_put16(&bs, infotype);
 	byte_stream_put8(&bs, strlen(sn));
 	byte_stream_putstr(&bs, sn);
 
-	flap_connection_send_snac(od, conn, 0x0002, 0x0005, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0005, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -1274,12 +1274,12 @@
 
 	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
-	snacid = aim_cachesnac(od, 0x0002, 0x0009, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0009, 0x0000, NULL, 0);
 
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0002, 0x0009, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0009, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -1302,12 +1302,12 @@
 
 	byte_stream_new(&bs, 1+strlen(sn));
 
-	snacid = aim_cachesnac(od, 0x0002, 0x000b, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x000b, 0x0000, NULL, 0);
 
 	byte_stream_put8(&bs, strlen(sn));
 	byte_stream_putstr(&bs, sn);
 
-	flap_connection_send_snac(od, conn, 0x0002, 0x000b, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x000b, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -1347,12 +1347,12 @@
 
 	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
-	snacid = aim_cachesnac(od, 0x0002, 0x000f, 0x0000, NULL, 0);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x000f, 0x0000, NULL, 0);
 
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send_snac(od, conn, 0x0002, 0x000f, 0x0000, snacid, &bs);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x000f, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 	return 0;
@@ -1385,8 +1385,8 @@
 	byte_stream_put8(&bs, strlen(sn));
 	byte_stream_putstr(&bs, sn);
 
-	snacid = aim_cachesnac(od, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1);
-	flap_connection_send_snac(od, conn, 0x0002, 0x0015, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0015, 0x0000, sn, strlen(sn)+1);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0015, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
--- a/libpurple/protocols/oscar/family_odir.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_odir.c	Sat Jun 14 07:47:38 2008 +0000
@@ -45,7 +45,7 @@
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x000f)) || !region || !email)
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ODIR)) || !region || !email)
 		return -EINVAL;
 
 	/* Create a TLV chain, write it to the outgoing frame, then free the chain */
@@ -58,8 +58,8 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ODIR, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ODIR, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -94,7 +94,7 @@
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x000f)) || !region)
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ODIR)) || !region)
 		return -EINVAL;
 
 	/* Create a TLV chain, write it to the outgoing frame, then free the chain */
@@ -126,8 +126,8 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ODIR, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ODIR, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -149,7 +149,7 @@
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
-	if (!od || !(conn = flap_connection_findbygroup(od, 0x000f)) || !region)
+	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ODIR)) || !region)
 		return -EINVAL;
 
 	/* Create a TLV chain, write it to the outgoing frame, then free the chain */
@@ -163,8 +163,8 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ODIR, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_ODIR, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -252,7 +252,7 @@
 int
 odir_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x000f;
+	mod->family = SNAC_FAMILY_ODIR;
 	mod->version = 0x0001;
 	mod->toolid = 0x0010;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_oservice.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_oservice.c	Sat Jun 14 07:47:38 2008 +0000
@@ -54,8 +54,8 @@
 		}
 	}
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0002, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0001, 0x0002, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -108,7 +108,7 @@
 	if(!conn)
 		return;
 
-	aim_genericreq_s(od, conn, 0x0001, 0x0004, &serviceid);
+	aim_genericreq_s(od, conn, SNAC_FAMILY_OSERVICE, 0x0004, &serviceid);
 }
 
 /*
@@ -146,8 +146,8 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi));
-	flap_connection_send_snac(od, conn, 0x0001, 0x0004, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0004, 0x0000, &csi, sizeof(csi));
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0004, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -210,7 +210,7 @@
 void
 aim_srv_reqrates(OscarData *od, FlapConnection *conn)
 {
-	aim_genericreq_n_snacid(od, conn, 0x0001, 0x0006);
+	aim_genericreq_n_snacid(od, conn, SNAC_FAMILY_OSERVICE, 0x0006);
 }
 
 /*
@@ -389,8 +389,8 @@
 		byte_stream_put16(&bs, rateclass->classid);
 	}
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0008, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0001, 0x0008, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0008, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0008, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -412,8 +412,8 @@
 		byte_stream_put16(&bs, rateclass->classid);
 	}
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0009, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0001, 0x0009, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0009, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0009, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -503,8 +503,8 @@
 	for (cur = conn->groups; cur != NULL; cur = cur->next)
 		byte_stream_put16(&bs, GPOINTER_TO_UINT(cur->data));
 
-	snacid = aim_cachesnac(od, 0x0001, 0x000c, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0001, 0x000c, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x000c, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x000c, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -526,7 +526,7 @@
 void
 aim_srv_reqpersonalinfo(OscarData *od, FlapConnection *conn)
 {
-	aim_genericreq_n_snacid(od, conn, 0x0001, 0x000e);
+	aim_genericreq_n_snacid(od, conn, SNAC_FAMILY_OSERVICE, 0x000e);
 }
 
 /* Subtype 0x000f - Self User Info */
@@ -589,7 +589,7 @@
 	if(!conn)
 		return;
 
-	aim_genericreq_l(od, conn, 0x0001, 0x0011, &idletime);
+	aim_genericreq_l(od, conn, SNAC_FAMILY_OSERVICE, 0x0011, &idletime);
 }
 
 /*
@@ -698,7 +698,7 @@
 void
 aim_srv_setprivacyflags(OscarData *od, FlapConnection *conn, guint32 flags)
 {
-	aim_genericreq_l(od, conn, 0x0001, 0x0014, &flags);
+	aim_genericreq_l(od, conn, SNAC_FAMILY_OSERVICE, 0x0014, &flags);
 }
 
 /*
@@ -713,7 +713,7 @@
 void
 aim_srv_nop(OscarData *od, FlapConnection *conn)
 {
-	aim_genericreq_n(od, conn, 0x0001, 0x0016);
+	aim_genericreq_n(od, conn, SNAC_FAMILY_OSERVICE, 0x0016);
 }
 
 /*
@@ -753,8 +753,8 @@
 		}
 	}
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0017, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0001, 0x0017, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0017, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0017, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 }
@@ -861,8 +861,8 @@
 	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	snacid = aim_cachesnac(od, 0x0001, 0x001e, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0001, 0x001e, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x001e, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x001e, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -1012,8 +1012,8 @@
 
 	}
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0020, 0x0000, NULL, 0);
-	flap_connection_send_snac(od, conn, 0x0001, 0x0020, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0020, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0020, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -1100,7 +1100,7 @@
 
 int service_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0001;
+	mod->family = SNAC_FAMILY_OSERVICE;
 	mod->version = 0x0003;
 	mod->toolid = 0x0110;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/family_popup.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_popup.c	Sat Jun 14 07:47:38 2008 +0000
@@ -72,7 +72,7 @@
 int
 popups_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x0008;
+	mod->family = SNAC_FAMILY_POPUP;
 	mod->version = 0x0001;
 	mod->toolid = 0x0104;
 	mod->toolversion = 0x0001;
--- a/libpurple/protocols/oscar/family_stats.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_stats.c	Sat Jun 14 07:47:38 2008 +0000
@@ -52,7 +52,7 @@
 int
 stats_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x000b;
+	mod->family = SNAC_FAMILY_STATS;
 	mod->version = 0x0001;
 	mod->toolid = 0x0104;
 	mod->toolversion = 0x0001;
--- a/libpurple/protocols/oscar/family_translate.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_translate.c	Sat Jun 14 07:47:38 2008 +0000
@@ -34,7 +34,7 @@
 int translate_modfirst(OscarData *od, aim_module_t *mod)
 {
 
-	mod->family = 0x000c;
+	mod->family = SNAC_FAMILY_TRANSLATE;
 	mod->version = 0x0001;
 	mod->toolid = 0x0104;
 	mod->toolversion = 0x0001;
--- a/libpurple/protocols/oscar/family_userlookup.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/family_userlookup.c	Sat Jun 14 07:47:38 2008 +0000
@@ -74,8 +74,8 @@
 
 	byte_stream_putstr(&bs, address);
 
-	snacid = aim_cachesnac(od, 0x000a, 0x0002, 0x0000, address, strlen(address)+1);
-	flap_connection_send_snac(od, conn, 0x000a, 0x0002, 0x0000, snacid, &bs);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_USERLOOKUP, 0x0002, 0x0000, address, strlen(address)+1);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_USERLOOKUP, 0x0002, 0x0000, snacid, &bs);
 
 	byte_stream_destroy(&bs);
 
@@ -145,7 +145,7 @@
 int
 search_modfirst(OscarData *od, aim_module_t *mod)
 {
-	mod->family = 0x000a;
+	mod->family = SNAC_FAMILY_USERLOOKUP;
 	mod->version = 0x0001;
 	mod->toolid = 0x0110;
 	mod->toolversion = 0x0629;
--- a/libpurple/protocols/oscar/oscar.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Sat Jun 14 07:47:38 2008 +0000
@@ -131,8 +131,8 @@
 	N_("Busted SNAC payload"),
 	N_("Insufficient rights"),
 	N_("In local permit/deny"),
-	N_("Too evil (sender)"),
-	N_("Too evil (receiver)"),
+	N_("Warning level too high (sender)"),
+	N_("Warning level too high (receiver)"),
 	N_("User temporarily unavailable"),
 	N_("No match"),
 	N_("List overflow"),
@@ -707,6 +707,9 @@
 			case OSCAR_CAPABILITY_CAMERA:
 				tmp = _("Camera");
 				break;
+			case OSCAR_CAPABILITY_ICHAT_SCREENSHARE:
+				tmp = _("Screen Sharing");
+				break;
 			default:
 				tmp = NULL;
 				break;
@@ -841,7 +844,7 @@
 		/* Away messges are HTML, but available messages were originally plain text.
 		 * We therefore need to strip away messages but not available messages if we're asked to remove HTML tags.
 		 */
-		if (is_away) {
+		if (is_away && message) {
 			gchar *tmp2;
 			tmp = purple_markup_strip_html(message);
 			g_free(message);
@@ -851,16 +854,16 @@
 		}
 
 	} else {
-	if (itmsurl) {
-		tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
-							  itmsurl, message);
-		g_free(itmsurl);
-		g_free(message);
-		message = tmp;
-	}
-	}
-
-	if (is_away) {
+		if (itmsurl) {
+			tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
+								  itmsurl, message);
+			g_free(itmsurl);
+			g_free(message);
+			message = tmp;
+		}
+	}
+
+	if (is_away && message) {
 		tmp = purple_str_sub_away_formatters(message, purple_account_get_username(account));
 		g_free(message);
 		message = tmp;
@@ -868,8 +871,8 @@
 
 	if (b) {
 		if (purple_presence_is_online(presence)) {
-			if (aim_snvalid_icq(b->name) || !message || !(*message)) {
-				/* Append the status name for online ICQ statuses and for all buddies with no message.
+			if (aim_snvalid_icq(b->name) || is_away || !message || !(*message)) {
+				/* Append the status name for online ICQ statuses, away AIM statuses, and for all buddies with no message.
 				 * If the status name and the message are the same, only show one. */
 				const char *status_name = purple_status_get_name(status);
 				if (status_name && message && !strcmp(status_name, message))
@@ -1811,7 +1814,8 @@
 
 	aim_send_login(od, conn, purple_account_get_username(account),
 			purple_connection_get_password(gc), truncate_pass,
-			od->icq ? &icqinfo : &aiminfo, key);
+			od->icq ? &icqinfo : &aiminfo, key,
+			/* allow multple logins? */ purple_account_get_bool(account, "allow_multiple_logins", OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS));
 
 	purple_connection_update_progress(gc, _("Password sent"), 2, OSCAR_CONNECT_STEPS);
 	ck[2] = 0x6c;
@@ -1959,7 +1963,11 @@
 			itmsurl = oscar_encoding_to_utf8(account, info->itmsurl_encoding,
 					info->itmsurl, info->itmsurl_len);
 
-		tmp = g_markup_escape_text(message, -1);
+		tmp = (message ? g_markup_escape_text(message, -1) : NULL);
+
+		if (message == NULL && itmsurl != NULL)
+			message = "";
+
 		purple_prpl_got_user_status(account, info->sn, status_id,
 				"message", tmp, "itmsurl", itmsurl, NULL);
 		g_free(tmp);
@@ -2785,8 +2793,8 @@
 		case 3: /* Evil Sender */
 			buf = g_strdup_printf(
 				   dngettext(PACKAGE,
-				   "You missed %hu message from %s because he/she was too evil.",
-				   "You missed %hu messages from %s because he/she was too evil.",
+				   "You missed %hu message from %s because his/her warning level is too high.",
+				   "You missed %hu messages from %s because his/her warning level is too high.",
 				   nummissed),
 				   nummissed,
 				   userinfo->sn);
@@ -2794,8 +2802,8 @@
 		case 4: /* Evil Receiver */
 			buf = g_strdup_printf(
 				   dngettext(PACKAGE,
-				   "You missed %hu message from %s because you are too evil.",
-				   "You missed %hu messages from %s because you are too evil.",
+				   "You missed %hu message from %s because your warning level is too high.",
+				   "You missed %hu messages from %s because your warning level is too high.",
 				   nummissed),
 				   nummissed,
 				   userinfo->sn);
@@ -6768,6 +6776,10 @@
 		OSCAR_DEFAULT_ALWAYS_USE_RV_PROXY);
 	prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
 
+	option = purple_account_option_bool_new(_("Allow multiple simultaneous logins"), "allow_multiple_logins",
+											OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS);
+	prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
+	
 	if (init)
 		return;
 	init = TRUE;
--- a/libpurple/protocols/oscar/oscar.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Sat Jun 14 07:47:38 2008 +0000
@@ -353,7 +353,8 @@
 	OSCAR_CAPABILITY_ICHATAV              = 0x02000000,
 	OSCAR_CAPABILITY_LIVEVIDEO            = 0x04000000,
 	OSCAR_CAPABILITY_CAMERA               = 0x08000000,
-	OSCAR_CAPABILITY_LAST                 = 0x10000000
+	OSCAR_CAPABILITY_ICHAT_SCREENSHARE	  = 0x10000000,
+	OSCAR_CAPABILITY_LAST                 = 0x20000000
 } OscarCapability;
 
 /*
@@ -594,7 +595,7 @@
 
 void aim_clientready(OscarData *od, FlapConnection *conn);
 int aim_request_login(OscarData *od, FlapConnection *conn, const char *sn);
-int aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key);
+int aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key, gboolean allow_multiple_logins);
 /* 0x000b */ int aim_auth_securid_send(OscarData *od, const char *securid);
 
 void aim_cleansnacs(OscarData *, int maxage);
--- a/libpurple/protocols/oscar/oscarcommon.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/oscar/oscarcommon.h	Sat Jun 14 07:47:38 2008 +0000
@@ -41,6 +41,7 @@
 #define OSCAR_DEFAULT_HIDE_IP TRUE
 #define OSCAR_DEFAULT_WEB_AWARE FALSE
 #define OSCAR_DEFAULT_ALWAYS_USE_RV_PROXY FALSE
+#define OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS TRUE
 
 #ifdef _WIN32
 const char *oscar_get_locale_charset(void);
--- a/libpurple/protocols/yahoo/yahoo_picture.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoo_picture.c	Sat Jun 14 07:47:38 2008 +0000
@@ -137,6 +137,9 @@
 		if (url_data != NULL) {
 			yd = gc->proto_data;
 			yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
+		} else {
+			g_free(data->who);
+			g_free(data);
 		}
 	} else if (who && send_icon_info) {
 		yahoo_send_picture_info(gc, who);
--- a/libpurple/proxy.h	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/proxy.h	Sat Jun 14 07:47:38 2008 +0000
@@ -239,9 +239,9 @@
  *                   to something descriptive (hopefully).
  * @param data       User-defined data.
  *
- * @return NULL if there was an error, or a reference to a data
- *         structure that can be used to cancel the pending
- *         connection, if needed.
+ * @return NULL if there was an error, or a reference to an
+ *         opaque data structure that can be used to cancel
+ *         the pending connection, if needed.
  */
 PurpleProxyConnectData *purple_proxy_connect(void *handle,
 			PurpleAccount *account,
@@ -265,9 +265,9 @@
  *                   to something descriptive (hopefully).
  * @param data       User-defined data.
  *
- * @return NULL if there was an error, or a reference to a data
- *         structure that can be used to cancel the pending
- *         connection, if needed.
+ * @return NULL if there was an error, or a reference to an
+ *         opaque data structure that can be used to cancel
+ *         the pending connection, if needed.
  */
 PurpleProxyConnectData *purple_proxy_connect_socks5(void *handle,
 			PurpleProxyInfo *gpi,
--- a/libpurple/win32/global.mak	Sat Jun 14 07:26:02 2008 +0000
+++ b/libpurple/win32/global.mak	Sat Jun 14 07:47:38 2008 +0000
@@ -112,4 +112,4 @@
 MINGW_MAKEFILE := Makefile.mingw
 
 INSTALL_PIXMAPS ?= 1
-
+INSTALL_SSL_CERTIFICATES ?= 1
--- a/pidgin/gtkblist.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/gtkblist.c	Sat Jun 14 07:47:38 2008 +0000
@@ -3265,10 +3265,10 @@
 	{ N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL },
 	{ N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 1, "<Item>", NULL },
 	{ N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "<Item>", NULL },
-	{ N_("/Tools/Smile_y"), "<CTL>Y", pidgin_smiley_manager_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SMILEY },
 	{ N_("/Tools/Plu_gins"), "<CTL>U", pidgin_plugin_dialog_show, 2, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS },
 	{ N_("/Tools/Pr_eferences"), "<CTL>P", pidgin_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES },
 	{ N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "<Item>", NULL },
+	{ N_("/Tools/Smile_y"), "<CTL>Y", pidgin_smiley_manager_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SMILEY },
 	{ "/Tools/sep2", NULL, NULL, 0, "<Separator>", NULL },
 	{ N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_TRANSFER },
 	{ N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "<Item>", NULL },
@@ -5305,7 +5305,7 @@
 	tmp = g_strdup_printf(_("<span weight='bold' size='larger'>Welcome to %s!</span>\n\n"
 
 					       "You have no accounts enabled. Enable your IM accounts from the "
-					       "<b>Accounts</b> window at <b>Accounts->Manage</b>. Once you "
+					       "<b>Accounts</b> window at <b>Accounts->Manage Accounts</b>. Once you "
 					       "enable accounts, you'll be able to sign on, set your status, "
 					       "and talk to your friends."), PIDGIN_NAME);
 	pretty = pidgin_make_pretty_arrows(tmp);
@@ -6474,6 +6474,10 @@
 		purple_blist_add_buddy(b, NULL, g, NULL);
 		purple_account_add_buddy(data->account, b);
 
+		/* Offer to merge people with the same alias. */
+		if (whoalias != NULL)
+			gtk_blist_auto_personize((PurpleBlistNode *)g, whoalias);
+
 		/*
 		 * XXX
 		 * It really seems like it would be better if the call to
@@ -7609,12 +7613,58 @@
 	for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) {
 		menuitem = l->data;
 
-		if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage")))
+		if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage Accounts")))
 			gtk_widget_destroy(menuitem);
 	}
 
 	for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
 		char *buf = NULL;
+		GtkWidget *image = NULL;
+		PurpleAccount *account = NULL;
+		GdkPixbuf *pixbuf = NULL;
+
+		account = accounts->data;
+
+		if(!purple_account_get_enabled(account, PIDGIN_UI)) {
+			if (!disabled_accounts) {
+				menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
+				gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
+				gtk_widget_show(menuitem);
+
+				submenu = gtk_menu_new();
+				gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
+				gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
+				gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
+				gtk_widget_show(submenu);
+
+				disabled_accounts = TRUE;
+			}
+
+			buf = g_strconcat(purple_account_get_username(account), " (",
+				purple_account_get_protocol_name(account), ")", NULL);
+			menuitem = gtk_image_menu_item_new_with_label(buf);
+			g_free(buf);
+			pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
+			if (pixbuf != NULL)
+			{
+				if (!purple_account_is_connected(account))
+					gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
+				image = gtk_image_new_from_pixbuf(pixbuf);
+				g_object_unref(G_OBJECT(pixbuf));
+				gtk_widget_show(image);
+				gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
+			}
+			g_signal_connect(G_OBJECT(menuitem), "activate",
+				G_CALLBACK(enable_account_cb), account);
+			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
+			gtk_widget_show(menuitem);
+		}
+	}
+
+	pidgin_separator(accountmenu);
+
+	for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
+		char *buf = NULL;
 		char *accel_path_buf = NULL;
 		GtkWidget *image = NULL;
 		PurpleConnection *gc = NULL;
@@ -7684,51 +7734,6 @@
 		}
 	}
 
-	if(disabled_accounts) {
-		pidgin_separator(accountmenu);
-		menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
-		gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
-		gtk_widget_show(menuitem);
-
-		submenu = gtk_menu_new();
-		gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
-		gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
-		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-		gtk_widget_show(submenu);
-
-		for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
-			char *buf = NULL;
-			GtkWidget *image = NULL;
-			PurpleAccount *account = NULL;
-			GdkPixbuf *pixbuf = NULL;
-
-			account = accounts->data;
-
-			if(!purple_account_get_enabled(account, PIDGIN_UI)) {
-
-				disabled_accounts = TRUE;
-
-				buf = g_strconcat(purple_account_get_username(account), " (",
-						purple_account_get_protocol_name(account), ")", NULL);
-				menuitem = gtk_image_menu_item_new_with_label(buf);
-				g_free(buf);
-				pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
-				if (pixbuf != NULL)
-				{
-					if (!purple_account_is_connected(account))
-						gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
-					image = gtk_image_new_from_pixbuf(pixbuf);
-					g_object_unref(G_OBJECT(pixbuf));
-					gtk_widget_show(image);
-					gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
-				}
-				g_signal_connect(G_OBJECT(menuitem), "activate",
-						G_CALLBACK(enable_account_cb), account);
-				gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-				gtk_widget_show(menuitem);
-			}
-		}
-	}
 }
 
 static GList *plugin_submenus = NULL;
--- a/pidgin/gtkconv.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/gtkconv.c	Sat Jun 14 07:47:38 2008 +0000
@@ -1481,7 +1481,7 @@
 	PurpleAccount *account;
 	PurpleConnection *gc;
 	PurplePluginProtocolInfo *prpl_info = NULL;
-	char *real_who;
+	gchar *real_who = NULL;
 
 	account = purple_conversation_get_account(conv);
 	g_return_if_fail(account != NULL);
@@ -1494,13 +1494,11 @@
 	if (prpl_info && prpl_info->get_cb_real_name)
 		real_who = prpl_info->get_cb_real_name(gc,
 				purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
-	else
-		real_who = g_strdup(who);
-
-	if(!real_who)
+
+	if(!who && !real_who)
 		return;
 
-	pidgin_dialogs_im_with_user(account, real_who);
+	pidgin_dialogs_im_with_user(account, real_who ? real_who : who);
 
 	g_free(real_who);
 }
@@ -1539,11 +1537,22 @@
 static void
 menu_chat_send_file_cb(GtkWidget *w, PidginConversation *gtkconv)
 {
+	PurplePluginProtocolInfo *prpl_info;
 	PurpleConversation *conv = gtkconv->active_conv;
 	const char *who = g_object_get_data(G_OBJECT(w), "user_data");
 	PurpleConnection *gc  = purple_conversation_get_gc(conv);
-
-	serv_send_file(gc, who, NULL);
+	gchar *real_who = NULL;
+
+	g_return_if_fail(gc != NULL);
+
+	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+
+	if (prpl_info && prpl_info->get_cb_real_name)
+		real_who = prpl_info->get_cb_real_name(gc,
+				purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
+
+	serv_send_file(gc, real_who ? real_who : who, NULL);
+	g_free(real_who);
 }
 
 static void
@@ -1659,23 +1668,34 @@
 
 		if (gc == NULL)
 			gtk_widget_set_sensitive(button, FALSE);
-
-		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
+		else
+			g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 
 
 		if (prpl_info && prpl_info->send_file)
 		{
+			gboolean can_receive_file = TRUE;
+
 			button = pidgin_new_item_from_stock(menu, _("Send File"),
 				PIDGIN_STOCK_TOOLBAR_SEND_FILE, G_CALLBACK(menu_chat_send_file_cb),
 				PIDGIN_CONVERSATION(conv), 0, 0, NULL);
 
-			if (gc == NULL || prpl_info == NULL ||
-			    !(!prpl_info->can_receive_file || prpl_info->can_receive_file(gc, who)))
-			{
+			if (gc == NULL || prpl_info == NULL)
+				can_receive_file = FALSE;
+			else {
+				gchar *real_who = NULL;
+				if (prpl_info->get_cb_real_name)
+					real_who = prpl_info->get_cb_real_name(gc,
+						purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
+				if (!(!prpl_info->can_receive_file || prpl_info->can_receive_file(gc, real_who ? real_who : who)))
+					can_receive_file = FALSE;
+				g_free(real_who);
+			}
+
+			if (!can_receive_file)
 				gtk_widget_set_sensitive(button, FALSE);
-			}
-
-			g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
+			else
+				g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 		}
 
 
@@ -1688,8 +1708,8 @@
 
 		if (gc == NULL)
 			gtk_widget_set_sensitive(button, FALSE);
-
-		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
+		else
+			g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 	}
 
 	if (prpl_info && (prpl_info->get_info || prpl_info->get_cb_info)) {
@@ -1698,8 +1718,8 @@
 
 		if (gc == NULL)
 			gtk_widget_set_sensitive(button, FALSE);
-
-		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
+		else
+			g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 	}
 
 	if (prpl_info && prpl_info->get_cb_away) {
@@ -1708,8 +1728,8 @@
 
 		if (gc == NULL)
 			gtk_widget_set_sensitive(button, FALSE);
-
-		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
+		else
+			g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 	}
 
 	if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
@@ -1722,8 +1742,8 @@
 
 		if (gc == NULL)
 			gtk_widget_set_sensitive(button, FALSE);
-
-		g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
+		else
+			g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
 	}
 
 	button = pidgin_new_item_from_stock(menu, _("Last said"), GTK_STOCK_INDEX,
--- a/pidgin/gtkdialogs.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/gtkdialogs.c	Sat Jun 14 07:47:38 2008 +0000
@@ -75,7 +75,7 @@
 	{"Thomas Butter",				N_("developer"), NULL},
 	{"Ka-Hing Cheung",				N_("developer"), NULL},
 	{"Sadrul Habib Chowdhury",		N_("developer"), NULL},
-	{"Mark 'KingAnt' Doliner",		N_("developer"), NULL},
+	{"Mark 'KingAnt' Doliner",		N_("developer"), "mark@kingant.net"},
 	{"Sean Egan",					N_("developer"), "sean.egan@gmail.com"},
 	{"Casey Harkins",               N_("developer"),   NULL},
 	{"Gary 'grim' Kramlich",		N_("developer"), NULL},
--- a/pidgin/gtkft.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/gtkft.c	Sat Jun 14 07:47:38 2008 +0000
@@ -226,8 +226,10 @@
 			total_pct = 100 * total_bytes_xferred / total_file_size;
 		}
 
-		title = g_strdup_printf(_("File Transfers - %d%% of %d files"),
-				total_pct, num_active_xfers);
+		title = g_strdup_printf(ngettext("File Transfers - %d%% of %d file",
+						 "File Transfers - %d%% of %d files",
+						 num_active_xfers),
+					total_pct, num_active_xfers);
 		gtk_window_set_title(GTK_WINDOW(dialog->window), title);
 		g_free(title);
 	} else {
--- a/pidgin/gtkimhtml.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/gtkimhtml.c	Sat Jun 14 07:47:38 2008 +0000
@@ -5025,9 +5025,9 @@
 			str += g_snprintf(str, sizeof(buf) - (str - buf),
 					"color: #%02x%02x%02x;",
 					color->red >> 8, color->green >> 8, color->blue >> 8);
-			gdk_color_free(color);
 			empty = FALSE;
 		}
+		gdk_color_free(color);
 
 		/* Background color */
 		g_object_get(obj, "background-set", &isset, "background-gdk", &color, NULL);
@@ -5035,9 +5035,9 @@
 			str += g_snprintf(str, sizeof(buf) - (str - buf),
 					"background: #%02x%02x%02x;",
 					color->red >> 8, color->green >> 8, color->blue >> 8);
-			gdk_color_free(color);
 			empty = FALSE;
 		}
+		gdk_color_free(color);
 
 		/* Underline */
 		g_object_get(obj, "underline-set", &isset, "underline", &ivalue, NULL);
@@ -5245,8 +5245,10 @@
 
 				if (tmp == NULL)
 					purple_debug_warning("gtkimhtml", "empty queue, more closing tags than open tags!\n");
-				else
+				else {
 					g_string_append(str, tmp->end);
+					text_tag_data_destroy(tmp);
+				}
 
 				while ((tmp = g_queue_pop_head(r))) {
 					g_string_append(str, tmp->start);
--- a/pidgin/gtkimhtmltoolbar.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/gtkimhtmltoolbar.c	Sat Jun 14 07:47:38 2008 +0000
@@ -614,8 +614,7 @@
 
 static struct smiley_button_list *
 sort_smileys(struct smiley_button_list *ls, GtkIMHtmlToolbar *toolbar,
-			 int *width, const GtkIMHtmlSmiley *smiley,
-			 const GSList *custom_smileys)
+			 int *width, const GtkIMHtmlSmiley *smiley)
 {
 	GtkWidget *image;
 	GtkWidget *button;
@@ -625,6 +624,7 @@
 	const gchar *filename = smiley->file;
 	gchar *face = smiley->smile;
 	PurpleSmiley *psmiley = NULL;
+	gboolean supports_custom = (gtk_imhtml_get_format_functions(GTK_IMHTML(toolbar->imhtml)) & GTK_IMHTML_CUSTOM_SMILEY);
 
 	cur = g_new0(struct smiley_button_list, 1);
 	it = ls;
@@ -678,10 +678,12 @@
 	/* If this is a "non-custom" smiley, check to see if its shortcut is
 	  "shadowed" by any custom smiley. This can only happen if the connection
 	  is custom smiley-enabled */
-	if (psmiley && !(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) {
-		gtk_tooltips_set_tip(toolbar->tooltips, button,
-				_("This smiley is disabled because a custom smiley exists for this shortcut."),
-				NULL);
+	if (supports_custom && psmiley && !(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) {
+		gchar tip[128];
+		g_snprintf(tip, sizeof(tip), 
+			_("This smiley is disabled because a custom smiley exists for this shortcut:\n %s"),
+			face);
+		gtk_tooltips_set_tip(toolbar->tooltips, button, tip, NULL);
 		gtk_widget_set_sensitive(button, FALSE);
 	} else if (psmiley) {
 		/* Remove the button if the smiley is destroyed */
@@ -783,11 +785,14 @@
 	else
 		smileys = pidgin_themes_get_proto_smileys(NULL);
 
+	/* Note: prepend smileys to list to avoid O(n^2) overhead when there is
+	  a large number of smileys... need to revers the list after for the dialog
+	  work... */
 	while(smileys) {
 		GtkIMHtmlSmiley *smiley = (GtkIMHtmlSmiley *) smileys->data;
 		if(!smiley->hidden) {
 			if(smiley_is_unique(unique_smileys, smiley)) {
-				unique_smileys = g_slist_append(unique_smileys, smiley);
+				unique_smileys = g_slist_prepend(unique_smileys, smiley);
 			}
 		}
 		smileys = smileys->next;
@@ -800,9 +805,12 @@
 		for (iterator = custom_smileys ; iterator ;
 			 iterator = g_slist_next(iterator)) {
 			GtkIMHtmlSmiley *smiley = (GtkIMHtmlSmiley *) iterator->data;
-			unique_smileys = g_slist_append(unique_smileys, smiley);
+			unique_smileys = g_slist_prepend(unique_smileys, smiley);
 		}
 	}
+	
+	/* we need to reverse the list to get the smileys in the correct order */
+	unique_smileys = g_slist_reverse(unique_smileys);
 
 	dialog = pidgin_create_dialog(_("Smile!"), 0, "smiley_dialog", FALSE);
 	gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
@@ -834,7 +842,7 @@
 		while (unique_smileys) {
 			GtkIMHtmlSmiley *smiley = (GtkIMHtmlSmiley *) unique_smileys->data;
 			if (!smiley->hidden) {
-				ls = sort_smileys(ls, toolbar, &max_line_width, smiley, custom_smileys);
+				ls = sort_smileys(ls, toolbar, &max_line_width, smiley);
 			}
 			unique_smileys = g_slist_delete_link(unique_smileys, unique_smileys);
 		}
--- a/pidgin/gtksavedstatuses.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/gtksavedstatuses.c	Sat Jun 14 07:47:38 2008 +0000
@@ -59,6 +59,7 @@
 	STATUS_WINDOW_COLUMN_MESSAGE,
 	/** A hidden column containing a pointer to the editor for this saved status. */
 	STATUS_WINDOW_COLUMN_WINDOW,
+	STATUS_WINDOW_COLUMN_ICON,
 	STATUS_WINDOW_NUM_COLUMNS
 };
 
@@ -80,6 +81,7 @@
 	STATUS_EDITOR_COLUMN_STATUS_ID,
 	STATUS_EDITOR_COLUMN_STATUS_NAME,
 	STATUS_EDITOR_COLUMN_STATUS_MESSAGE,
+	STATUS_EDITOR_COLUMN_STATUS_ICON,
 	STATUS_EDITOR_NUM_COLUMNS
 };
 
@@ -392,12 +394,35 @@
     g_list_free(sel_paths);
 }
 
+static const gchar *
+get_stock_icon_from_primitive(PurpleStatusPrimitive type)
+{
+	switch (type) {
+		case PURPLE_STATUS_AVAILABLE:
+			return PIDGIN_STOCK_STATUS_AVAILABLE;
+		case PURPLE_STATUS_AWAY:
+			return PIDGIN_STOCK_STATUS_AWAY;
+		case PURPLE_STATUS_EXTENDED_AWAY:
+			return PIDGIN_STOCK_STATUS_XA;
+		case PURPLE_STATUS_INVISIBLE:
+			return PIDGIN_STOCK_STATUS_INVISIBLE;
+		case PURPLE_STATUS_OFFLINE:
+			return PIDGIN_STOCK_STATUS_OFFLINE;
+		case PURPLE_STATUS_UNAVAILABLE:
+			return PIDGIN_STOCK_STATUS_BUSY;
+		default:
+			/* this shouldn't happen */
+			return NULL;
+	}
+}
+
 static void
 add_status_to_saved_status_list(GtkListStore *model, PurpleSavedStatus *saved_status)
 {
 	GtkTreeIter iter;
 	const char *title;
 	const char *type;
+	const gchar *icon;
 	char *message;
 
 	if (purple_savedstatus_is_transient(saved_status))
@@ -406,14 +431,16 @@
 	title = purple_savedstatus_get_title(saved_status);
 	type = purple_primitive_get_name_from_type(purple_savedstatus_get_type(saved_status));
 	message = purple_markup_strip_html(purple_savedstatus_get_message(saved_status));
+	icon = get_stock_icon_from_primitive(purple_savedstatus_get_type(saved_status));
 
 	gtk_list_store_append(model, &iter);
 	gtk_list_store_set(model, &iter,
+					   STATUS_WINDOW_COLUMN_ICON, icon,
 					   STATUS_WINDOW_COLUMN_TITLE, title,
 					   STATUS_WINDOW_COLUMN_TYPE, type,
 					   STATUS_WINDOW_COLUMN_MESSAGE, message,
 					   -1);
-	free(message);
+	g_free(message);
 }
 
 static void
@@ -479,7 +506,8 @@
 									   G_TYPE_STRING,
 									   G_TYPE_STRING,
 									   G_TYPE_STRING,
-									   G_TYPE_POINTER);
+									   G_TYPE_POINTER,
+									   G_TYPE_STRING);
 
 	/* Create the treeview */
 	treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
@@ -517,6 +545,10 @@
 	gtk_tree_view_column_set_sort_column_id(column,
 											STATUS_WINDOW_COLUMN_TYPE);
 	gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+	renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_tree_view_column_pack_start(column, renderer, TRUE);
+	gtk_tree_view_column_add_attribute(column, renderer, "stock-id",
+									   STATUS_WINDOW_COLUMN_ICON);
 	renderer = gtk_cell_renderer_text_new();
 	gtk_tree_view_column_pack_start(column, renderer, TRUE);
 	gtk_tree_view_column_add_attribute(column, renderer, "text",
@@ -717,8 +749,8 @@
 }
 
 
-static gboolean
-status_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
+static void
+status_editor_destroy_cb(GtkWidget *widget, gpointer user_data)
 {
 	StatusEditor *dialog = user_data;
 
@@ -726,19 +758,13 @@
 	g_free(dialog->original_title);
 	g_object_unref(G_OBJECT(dialog->model));
 	g_free(dialog);
-
-	return FALSE;
 }
 
 static void
 status_editor_cancel_cb(GtkButton *button, gpointer user_data)
 {
 	StatusEditor *dialog = user_data;
-
-	status_editor_remove_dialog(dialog);
 	gtk_widget_destroy(dialog->window);
-	g_free(dialog->original_title);
-	g_free(dialog);
 }
 
 static void
@@ -842,20 +868,11 @@
 	g_free(message);
 	g_free(unformatted);
 
-	status_editor_remove_dialog(dialog);
-	gtk_widget_destroy(dialog->window);
-	g_free(dialog->original_title);
-
-/*
-	if (status_window != NULL)
-	  add_status_to_saved_status_list(status_window->model, saved_status);
-*/
-
 	/* If they clicked on "Save & Use" or "Use," then activate the status */
 	if (button != dialog->save_button)
 		purple_savedstatus_activate(saved_status);
 
-	g_free(dialog);
+	gtk_widget_destroy(dialog->window);
 }
 
 static void
@@ -871,6 +888,26 @@
 }
 
 static GtkWidget *
+create_stock_item(const gchar *str, const gchar *icon)
+{
+	GtkWidget *menuitem = gtk_menu_item_new();
+	GtkWidget *label = gtk_label_new_with_mnemonic(str);
+	GtkWidget *hbox = gtk_hbox_new(FALSE, 4);
+	GtkIconSize icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL);
+	GtkWidget *image = gtk_image_new_from_stock(icon, icon_size);;
+
+	gtk_widget_show(label);
+	gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+	gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+	gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+
+	gtk_container_add(GTK_CONTAINER(menuitem), hbox);
+
+	return menuitem;
+}
+
+static GtkWidget *
 create_status_type_menu(PurpleStatusPrimitive type)
 {
 	int i;
@@ -889,7 +926,9 @@
 			 * status types, so don't show them in the list.
 			 */
 			continue;
-		item = gtk_menu_item_new_with_label(purple_primitive_get_name_from_type(i));
+
+		item = create_stock_item(purple_primitive_get_name_from_type(i),
+					get_stock_icon_from_primitive(i));
 		gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
 	}
 
@@ -945,6 +984,7 @@
 						   STATUS_EDITOR_COLUMN_STATUS_ID, NULL,
 						   STATUS_EDITOR_COLUMN_STATUS_NAME, NULL,
 						   STATUS_EDITOR_COLUMN_STATUS_MESSAGE, NULL,
+						   STATUS_EDITOR_COLUMN_STATUS_ICON, NULL,
 						   -1);
 	}
 }
@@ -990,6 +1030,10 @@
 	gtk_tree_view_column_set_title(column, _("Status"));
 	gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
 	gtk_tree_view_column_set_resizable(column, TRUE);
+	renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_tree_view_column_pack_start(column, renderer, FALSE);
+	gtk_tree_view_column_add_attribute(column, renderer, "stock-id",
+			STATUS_EDITOR_COLUMN_STATUS_ICON);
 	renderer = gtk_cell_renderer_text_new();
 	gtk_tree_view_column_pack_start(column, renderer, TRUE);
 	gtk_tree_view_column_add_attribute(column, renderer, "text",
@@ -1016,6 +1060,7 @@
 {
 	GdkPixbuf *pixbuf;
 	const char *id = NULL, *name = NULL, *message = NULL;
+	PurpleStatusPrimitive prim = PURPLE_STATUS_UNSET;
 
 	pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM);
 	if ((pixbuf != NULL) && !purple_account_is_connected(account))
@@ -1030,6 +1075,7 @@
 		type = purple_savedstatus_substatus_get_type(substatus);
 		id = purple_status_type_get_id(type);
 		name = purple_status_type_get_name(type);
+		prim = purple_status_type_get_primitive(type);
 		if (purple_status_type_get_attr(type, "message"))
 			message = purple_savedstatus_substatus_get_message(substatus);
 	}
@@ -1042,6 +1088,7 @@
 			STATUS_EDITOR_COLUMN_STATUS_ID, id,
 			STATUS_EDITOR_COLUMN_STATUS_NAME, name,
 			STATUS_EDITOR_COLUMN_STATUS_MESSAGE, message,
+			STATUS_EDITOR_COLUMN_STATUS_ICON, get_stock_icon_from_primitive(prim),
 			-1);
 
 	if (pixbuf != NULL)
@@ -1133,7 +1180,7 @@
 
 	dialog->window = win = pidgin_create_dialog(_("Status"), PIDGIN_HIG_BORDER, "status", TRUE);
 
-	g_signal_connect(G_OBJECT(win), "delete_event",
+	g_signal_connect(G_OBJECT(win), "destroy",
 					 G_CALLBACK(status_editor_destroy_cb), dialog);
 
 	/* Setup the vbox */
@@ -1198,6 +1245,7 @@
 									   G_TYPE_STRING,
 									   G_TYPE_STRING,
 									   G_TYPE_STRING,
+									   G_TYPE_STRING,
 									   G_TYPE_STRING);
 
 	/* Create the treeview */
@@ -1325,25 +1373,20 @@
 	}
 }
 
-static gboolean
-substatus_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
+static void
+substatus_editor_destroy_cb(GtkWidget *widget, gpointer user_data)
 {
 	SubStatusEditor *dialog = user_data;
 
 	substatus_editor_remove_dialog(dialog);
 	g_free(dialog);
-
-	return FALSE;
 }
 
 static void
 substatus_editor_cancel_cb(GtkButton *button, gpointer user_data)
 {
 	SubStatusEditor *dialog = user_data;
-
-	substatus_editor_remove_dialog(dialog);
 	gtk_widget_destroy(dialog->window);
-	g_free(dialog);
 }
 
 
@@ -1356,12 +1399,11 @@
 	PurpleStatusType *type;
 	char *id = NULL;
 	char *message = NULL;
-	const char *name = NULL;
+	const char *name = NULL, *stock = NULL;
 
 	if (!gtk_combo_box_get_active_iter(dialog->box, &iter))
 	{
 		gtk_widget_destroy(dialog->window);
-		g_free(dialog);
 		return;
 	}
 
@@ -1372,6 +1414,7 @@
 	if (purple_status_type_get_attr(type, "message") != NULL)
 		message = gtk_imhtml_get_markup(GTK_IMHTML(dialog->message));
 	name = purple_status_type_get_name(type);
+	stock = get_stock_icon_from_primitive(purple_status_type_get_primitive(type));
 
 	status_editor = dialog->status_editor;
 
@@ -1383,13 +1426,13 @@
 						   STATUS_EDITOR_COLUMN_STATUS_NAME, name,
 						   STATUS_EDITOR_COLUMN_STATUS_MESSAGE, message,
 						   STATUS_EDITOR_COLUMN_WINDOW, NULL,
+						   STATUS_EDITOR_COLUMN_STATUS_ICON, stock,
 						   -1);
 	}
 
 	gtk_widget_destroy(dialog->window);
 	g_free(id);
 	g_free(message);
-	g_free(dialog);
 }
 
 static void
@@ -1438,7 +1481,7 @@
 	dialog->window = win = pidgin_create_dialog(tmp, PIDGIN_HIG_BORDER, "substatus", TRUE);
 	g_free(tmp);
 
-	g_signal_connect(G_OBJECT(win), "delete_event",
+	g_signal_connect(G_OBJECT(win), "destroy",
 					 G_CALLBACK(substatus_editor_destroy_cb), dialog);
 
 	/* Setup the vbox */
--- a/pidgin/gtkutils.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/gtkutils.c	Sat Jun 14 07:47:38 2008 +0000
@@ -1001,13 +1001,14 @@
 	}
 
 	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(conn->prpl);
+	if (prpl_info != NULL && prpl_info->get_cb_real_name)
+		who = prpl_info->get_cb_real_name(conn, chat, name);
 	if (prpl_info == NULL || prpl_info->get_cb_info == NULL) {
-		pidgin_retrieve_user_info(conn, name);
+		pidgin_retrieve_user_info(conn, who ? who : name);
+		g_free(who);
 		return;
 	}
 
-	if (prpl_info->get_cb_real_name)
-		who = prpl_info->get_cb_real_name(conn, chat, name);
 	show_retrieveing_info(conn, who ? who : name);
 	prpl_info->get_cb_info(conn, chat, name);
 	g_free(who);
--- a/pidgin/plugins/spellchk.c	Sat Jun 14 07:26:02 2008 +0000
+++ b/pidgin/plugins/spellchk.c	Sat Jun 14 07:47:38 2008 +0000
@@ -1740,6 +1740,7 @@
 			"BAD wroking\nGOOD working\n"
 			"BAD wtih\nGOOD with\n"
 			"BAD wuould\nGOOD would\n"
+			"BAD wud\nGOOD would\n"
 			"BAD wut\nGOOD what\n"
 			"BAD wya\nGOOD way\n"
 			"BAD y\nGOOD why\n"
--- a/po/de.po	Sat Jun 14 07:26:02 2008 +0000
+++ b/po/de.po	Sat Jun 14 07:47:38 2008 +0000
@@ -12,9 +12,9 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-05-31 00:16+0200\n"
-"PO-Revision-Date: 2008-05-31 00:15+0200\n"
-"Last-Translator: Bjoern Voigt <bjoern@cs.tu-berlin.de>\n"
+"POT-Creation-Date: 2008-06-12 18:33+0200\n"
+"PO-Revision-Date: 2008-06-12 18:32+0200\n"
+"Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n"
 "Language-Team: Deutsch <de@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -414,6 +414,9 @@
 msgid "View Log..."
 msgstr "Mitschnitt anzeigen..."
 
+msgid "View All Logs"
+msgstr "Alle Mitschnitte anzeigen"
+
 msgid "Show"
 msgstr "Anzeigen"
 
@@ -669,6 +672,20 @@
 "zu erhalten.\n"
 "Die folgenden Kommandos sind in diesem Kontext verfügbar:\n"
 
+#, c-format
+msgid ""
+"%s is not a valid message class. See '/help msgcolor' for valid message "
+"classes."
+msgstr ""
+"%s ist keine gültige Nachrichtenklasse. Die gültigen Nachrichtenklassen "
+"finden Sie unter '/help msgcolor'."
+
+#, c-format
+msgid "%s is not a valid color. See '/help msgcolor' for valid colors."
+msgstr ""
+"%s ist keine gültige Farbe. Die gültigen Farben finden Sie unter '/help "
+"msgcolor'."
+
 msgid ""
 "say &lt;message&gt;:  Send a message normally as if you weren't using a "
 "command."
@@ -715,6 +732,20 @@
 msgid "statuses: Show the savedstatuses window."
 msgstr "statuses: Das Fenster mit gespeicherten Status-Infos anzeigen."
 
+msgid ""
+"msgcolor &lt;class&gt; &lt;foreground&gt; &lt;background&gt;: Set the color "
+"for different classes of messages in the conversation window.<br>    &lt;"
+"class&gt;: receive, send, highlight, action, timestamp<br>    &lt;foreground/"
+"background&gt;: black, red, green, blue, white, gray, darkgray, magenta, "
+"cyan, default<br><br>EXAMPLE:<br>    msgcolor send cyan default"
+msgstr ""
+"msgcolor &lt;Klasse&gt; &lt;Vordergrund&gt; &lt;Hintergrund&gt;: Die Farbe "
+"für verschiedene Klassen von Nachrichten im Gesprächsfenster festlegen."
+"<br>    &lt;Klasse&gt;: receive, send, highlight, action, timestamp<br>    "
+"&lt;Vordergrund/Hintergrund&gt;: black, red, green, blue, white, gray, "
+"darkgray, magenta, cyan, default<br><br>BEISPIEL:<br>    msgcolor send cyan "
+"default"
+
 msgid "Unable to open file."
 msgstr "Konnte die Datei nicht öffnen."
 
@@ -735,8 +766,10 @@
 msgstr "Pause"
 
 #, c-format
-msgid "File Transfers - %d%% of %d files"
-msgstr "Dateiübertragungen - %d%% von %d Dateien"
+msgid "File Transfers - %d%% of %d file"
+msgid_plural "File Transfers - %d%% of %d files"
+msgstr[0] "Dateiübertragungen - %d%% von %d Datei"
+msgstr[1] "Dateiübertragungen - %d%% von %d Dateien"
 
 #. Create the window.
 msgid "File Transfers"
@@ -851,6 +884,9 @@
 msgid "Conversations with %s"
 msgstr "Unterhaltung mit %s"
 
+msgid "All Conversations"
+msgstr "Alle Unterhaltungen"
+
 msgid "System Log"
 msgstr "System-Mitschnitt"
 
@@ -3198,8 +3234,10 @@
 msgstr "Falscher Modus"
 
 #, c-format
-msgid "Ban on %s by %s, set %ld seconds ago"
-msgstr "Verbot zu %s von %s, gesetzt vor %ld Sekunden"
+msgid "Ban on %s by %s, set %ld second ago"
+msgid_plural "Ban on %s by %s, set %ld seconds ago"
+msgstr[0] "Verbot zu %s von %s, gesetzt vor %ld Sekunde"
+msgstr[1] "Verbot zu %s von %s, gesetzt vor %ld Sekunden"
 
 #, c-format
 msgid "Ban on %s"
@@ -4551,14 +4589,14 @@
 msgstr "Standards _akzeptieren"
 
 #, c-format
+msgid "Error joining chat %s"
+msgstr "Fehler beim Betreten des Chats %s"
+
+#, c-format
 msgid "Error in chat %s"
 msgstr "Fehler im Chat %s"
 
 #, c-format
-msgid "Error joining chat %s"
-msgstr "Fehler beim Betreten des Chats %s"
-
-#, c-format
 msgid "Unable to send file to %s, user does not support file transfers"
 msgstr ""
 "Kann die Datei nicht an %s senden, da der Client des Benutzers keine "
@@ -5384,8 +5422,11 @@
 msgstr "Logge ein"
 
 #, c-format
-msgid "Connection to server lost (no data received within %d seconds)"
-msgstr ""
+msgid "Connection to server lost (no data received within %d second)"
+msgid_plural "Connection to server lost (no data received within %d seconds)"
+msgstr[0] ""
+"Verbindung zum Server verloren (seit %d Sekunde keine Daten empfangen)"
+msgstr[1] ""
 "Verbindung zum Server verloren (seit %d Sekunden keine Daten empfangen)"
 
 #. Can't write _()'d strings in array initializers. Workaround.
@@ -5485,9 +5526,15 @@
 
 #, c-format
 msgid ""
+"%d buddy was added or updated from the server (including buddies already on "
+"the server-side list)"
+msgid_plural ""
 "%d buddies were added or updated from the server (including buddies already "
 "on the server-side list)"
-msgstr ""
+msgstr[0] ""
+"%d Buddy wurde vom Server hinzugefügt oder aktualisiert (inklusive der "
+"Buddys, die schon auf der Serverliste sind)"
+msgstr[1] ""
 "%d Buddys wurden vom Server hinzugefügt oder aktualisiert (inklusive der "
 "Buddys, die schon auf der Serverliste sind)"
 
@@ -6127,11 +6174,11 @@
 msgid "In local permit/deny"
 msgstr "In lokaler erlaubt/verboten-Liste"
 
-msgid "Too evil (sender)"
-msgstr "Zu boshaft (Sender)"
-
-msgid "Too evil (receiver)"
-msgstr "Zu boshaft (Empfänger)"
+msgid "Warning level too high (sender)"
+msgstr "Warnstufe zu hoch (Absender)"
+
+msgid "Warning level too high (receiver)"
+msgstr "Warnstufe zu hoch (Empfänger)"
 
 msgid "User temporarily unavailable"
 msgstr "Benutzer ist temporär nicht verfügbar"
@@ -6235,6 +6282,10 @@
 msgid "Camera"
 msgstr "Kamera"
 
+#, fuzzy
+msgid "Screen Sharing"
+msgstr "Screen Sharing"
+
 msgid "Free For Chat"
 msgstr "Bereit zum Chatten"
 
@@ -6367,6 +6418,7 @@
 msgid "Unable to get a valid login hash."
 msgstr "Konnte keinen gültigen Login-Hash bekommen."
 
+#. allow multple logins?
 msgid "Password sent"
 msgstr "Passwort gesendet"
 
@@ -6486,20 +6538,26 @@
 "überschritten wurde."
 
 #, c-format
-msgid "You missed %hu message from %s because he/she was too evil."
-msgid_plural "You missed %hu messages from %s because he/she was too evil."
+msgid ""
+"You missed %hu message from %s because his/her warning level is too high."
+msgid_plural ""
+"You missed %hu messages from %s because his/her warning level is too high."
 msgstr[0] ""
-"Sie haben %hu Nachricht von %s nicht erhalten, da er/sie zu boshaft war."
+"Sie haben %hu Nachricht von %s nicht erhalten, da seine/ihre Warnstufe zu "
+"hoch ist."
 msgstr[1] ""
-"Sie haben %hu Nachrichten von %s nicht erhalten,/sie zu boshaft war."
-
-#, c-format
-msgid "You missed %hu message from %s because you are too evil."
-msgid_plural "You missed %hu messages from %s because you are too evil."
+"Sie haben %hu Nachrichten von %s nicht erhalten, da seine/ihre Warnstufe zu "
+"hoch ist."
+
+#, c-format
+msgid "You missed %hu message from %s because your warning level is too high."
+msgid_plural ""
+"You missed %hu messages from %s because your warning level is too high."
 msgstr[0] ""
-"Sie haben %hu Nachricht von %s nicht erhalten, da Sie zu boshaft sind."
+"Sie haben %hu Nachricht von %s nicht erhalten, da Ihre Warnstufe zu hoch ist."
 msgstr[1] ""
-"Sie haben %hu Nachrichten von %s nicht erhalten, da Sie zu boshaft sind."
+"Sie haben %hu Nachrichten von %s nicht erhalten, da Ihre Warnstufe zu hoch "
+"ist."
 
 #, c-format
 msgid "You missed %hu message from %s for an unknown reason."
@@ -6560,6 +6618,8 @@
 msgid "Personal Web Page"
 msgstr "Persönliche Webseite"
 
+#. aim_userinfo_t
+#. strip_html_tags
 msgid "Additional Information"
 msgstr "Zusätzliche Informationen"
 
@@ -6924,6 +6984,9 @@
 "Dateiübertragungen und Direkt-IM (langsamer,\n"
 "aber zeigt Ihre IP-Adresse nicht)"
 
+msgid "Allow multiple simultaneous logins"
+msgstr "Mehrere gleichzeitige Logins erlauben"
+
 #, c-format
 msgid "Asking %s to connect to us at %s:%hu for Direct IM."
 msgstr "Frage %s, ob er sich zu uns auf %s:%hu für Direkt-IM verbinden möchte."
@@ -10193,8 +10256,8 @@
 msgid "/_Accounts"
 msgstr "/_Konten"
 
-msgid "/Accounts/Manage"
-msgstr "/Konten/Verwalten"
+msgid "/Accounts/Manage Accounts"
+msgstr "/Konten/Konten verwalten"
 
 #. Tools
 msgid "/_Tools"
@@ -10206,9 +10269,6 @@
 msgid "/Tools/_Certificates"
 msgstr "/Werkzeuge/_Zertifikate"
 
-msgid "/Tools/Smile_y"
-msgstr "/Werkzeuge/Smile_y"
-
 msgid "/Tools/Plu_gins"
 msgstr "/Werkzeuge/Plu_gins"
 
@@ -10218,6 +10278,9 @@
 msgid "/Tools/Pr_ivacy"
 msgstr "/Werkzeuge/Pri_vatsphäre"
 
+msgid "/Tools/Smile_y"
+msgstr "/Werkzeuge/Smile_y"
+
 msgid "/Tools/_File Transfers"
 msgstr "/Werkzeuge/_Dateiübertragungen"
 
@@ -10384,13 +10447,13 @@
 "<span weight='bold' size='larger'>Welcome to %s!</span>\n"
 "\n"
 "You have no accounts enabled. Enable your IM accounts from the <b>Accounts</"
-"b> window at <b>Accounts->Manage</b>. Once you enable accounts, you'll be "
-"able to sign on, set your status, and talk to your friends."
+"b> window at <b>Accounts->Manage Accounts</b>. Once you enable accounts, "
+"you'll be able to sign on, set your status, and talk to your friends."
 msgstr ""
 "<span weight='bold' size='larger'>Willkommen bei %s!</span>\n"
 "\n"
 "Sie haben keine Konten aktiviert. Aktivieren Sie Ihre IM-Konten vom "
-"<b>Konten</b>-Fenster über <b>Konten->Verwalten</b>. Wenn Sie Konten "
+"<b>Konten</b>-Fenster über <b>Konten->Konten verwalten</b>. Wenn Sie Konten "
 "aktiviert haben, können Sie sich anmelden, Ihren Status setzen und mit Ihren "
 "Freunden reden."
 
@@ -10451,6 +10514,12 @@
 msgid "Please enter the name of the group to be added."
 msgstr "Bitte geben Sie den Namen der Gruppe ein, die hinzugefügt werden soll."
 
+msgid "Enable Account"
+msgstr "Konten aktivieren"
+
+msgid "<PurpleMain>/Accounts/Enable Account"
+msgstr "<PurpleMain>/Konten/Konto aktivieren"
+
 msgid "<PurpleMain>/Accounts/"
 msgstr "<PurpleMain>/Konten/"
 
@@ -10463,12 +10532,6 @@
 msgid "_Disable"
 msgstr "_Deaktivieren"
 
-msgid "Enable Account"
-msgstr "Konten aktivieren"
-
-msgid "<PurpleMain>/Accounts/Enable Account"
-msgstr "<PurpleMain>/Konten/Konto aktivieren"
-
 msgid "/Tools"
 msgstr "/Werkzeuge"
 
@@ -11502,11 +11565,14 @@
 msgid "Insert Image"
 msgstr "Bild einfügen"
 
-msgid ""
-"This smiley is disabled because a custom smiley exists for this shortcut."
+#, c-format
+msgid ""
+"This smiley is disabled because a custom smiley exists for this shortcut:\n"
+" %s"
 msgstr ""
 "Dieser Smiley ist deaktiviert, da ein benutzerdefinierter Smiley für diese "
-"Tastenkombination existiert."
+"Tastenkombination existiert:\n"
+" %s"
 
 msgid "Smile!"
 msgstr "Lächeln!"
--- a/po/lt.po	Sat Jun 14 07:26:02 2008 +0000
+++ b/po/lt.po	Sat Jun 14 07:47:38 2008 +0000
@@ -721,8 +721,11 @@
 msgstr "Pristabdyti"
 
 #, c-format
-msgid "File Transfers - %d%% of %d files"
-msgstr "Failų perdavimai – %d%% iš %d"
+msgid "File Transfers - %d%% of %d file"
+msgid_plural "File Transfers - %d%% of %d files"
+msgstr[0] "Failų perdavimai – %d%% iš %d failo"
+msgstr[1] "Failų perdavimai – %d%% iš %d failų"
+msgstr[2] "Failų perdavimai – %d%% iš %d failų"
 
 #. Create the window.
 msgid "File Transfers"
@@ -3258,8 +3261,11 @@
 msgstr "Bloga būsena"
 
 #, c-format
-msgid "Ban on %s by %s, set %ld seconds ago"
-msgstr "Vartotojui %s uždraudė prisijungti %s prieš %ld sekundžių"
+msgid "Ban on %s by %s, set %ld second ago"
+msgid_plural "Ban on %s by %s, set %ld seconds ago"
+msgstr[0] "Vartotojui %s uždraudė prisijungti %s prieš %ld sekundę"
+msgstr[1] "Vartotojui %s uždraudė prisijungti %s prieš %ld sekundes"
+msgstr[2] "Vartotojui %s uždraudė prisijungti %s prieš %ld sekundžių"
 
 #, c-format
 msgid "Ban on %s"
@@ -5439,8 +5445,11 @@
 msgstr "Prisijungiama"
 
 #, c-format
-msgid "Connection to server lost (no data received within %d seconds)"
-msgstr "Nutrūko ryšys su serveriu (negauta jokių duomenų per %d sekundžių)"
+msgid "Connection to server lost (no data received within %d second)"
+msgid_plural "Connection to server lost (no data received within %d seconds)"
+msgstr[0] "Nutrūko ryšys su serveriu (negauta jokių duomenų per %d sekundę)"
+msgstr[1] "Nutrūko ryšys su serveriu (negauta jokių duomenų per %d sekundes)"
+msgstr[2] "Nutrūko ryšys su serveriu (negauta jokių duomenų per %d sekundžių)"
 
 #. Can't write _()'d strings in array initializers. Workaround.
 msgid "New mail messages"
@@ -5538,9 +5547,18 @@
 
 #, c-format
 msgid ""
+"%d buddy was added or updated from the server (including buddies already on "
+"the server-side list)"
+msgid_plural ""
 "%d buddies were added or updated from the server (including buddies already "
 "on the server-side list)"
-msgstr ""
+msgstr[0] ""
+"%d bičiulis buvo pridėtas ar atnaujintas iš serverio (įskaitant ir "
+"bičiulius, jau esančius serverio sąraše)"
+msgstr[1] ""
+"%d bičiuliai buvo pridėti ar atnaujinti iš serverio (įskaitant ir bičiulius, "
+"jau esančius serverio sąraše)"
+msgstr[2] ""
 "%d bičiulių buvo pridėta ar atnaujinta iš serverio (įskaitant ir bičiulius, "
 "jau esančius serverio sąraše)"
 
--- a/share/ca-certs/Makefile.am	Sat Jun 14 07:26:02 2008 +0000
+++ b/share/ca-certs/Makefile.am	Sat Jun 14 07:47:38 2008 +0000
@@ -1,5 +1,4 @@
-cacertsdir =	$(datadir)/purple/ca-certs
-cacerts_DATA =	\
+CERTIFICATES = \
 		Equifax_Secure_CA.pem \
 		GTE_CyberTrust_Global_Root.pem \
 		Microsoft_Secure_Server_Authority.pem \
@@ -7,7 +6,12 @@
 		Verisign_RSA_Secure_Server_CA.pem \
 		Verisign_Class3_Primary_CA.pem
 
+if INSTALL_SSL_CERTIFICATES
+cacertsdir =	$(datadir)/purple/ca-certs
+cacerts_DATA =	$(CERTIFICATES)
+endif
+
 EXTRA_DIST =	\
 		Makefile.mingw \
-		$(cacerts_DATA)
+		$(CERTIFICATES)
 
--- a/share/ca-certs/Makefile.mingw	Sat Jun 14 07:26:02 2008 +0000
+++ b/share/ca-certs/Makefile.mingw	Sat Jun 14 07:47:38 2008 +0000
@@ -8,14 +8,17 @@
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
 datadir := $(PIDGIN_INSTALL_DIR)
-include ./Makefile.am
+-include ./Makefile.am.mingw
 cacertsdir := $(PIDGIN_INSTALL_DIR)/ca-certs
 
 .PHONY: install
 
-install:
+install: ./Makefile.am.mingw
 	if test '$(cacerts_DATA)'; then \
 	  mkdir -p $(cacertsdir); \
 	  cp $(cacerts_DATA) $(cacertsdir); \
 	fi;
 
+./Makefile.am.mingw: ./Makefile.am
+	sed -e 's/^if\ INSTALL_SSL_CERTIFICATES/ifeq (\$$(INSTALL_SSL_CERTIFICATES), 1)/' ./Makefile.am > $@
+