Merge default back in

Wed, 14 Jun 2017 23:40:17 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Wed, 14 Jun 2017 23:40:17 -0500
changeset 38569
e9f92dd1f2f4
parent 38568
9463c7db20fa (current diff)
parent 38363
876661dc1375 (diff)
child 38570
bc6bd64fc288

Merge default back in

libpurple/ntlm.c file | annotate | diff | comparison | revisions
libpurple/ntlm.h file | annotate | diff | comparison | revisions
libpurple/win32/giowin32.c file | annotate | diff | comparison | revisions
tap-driver.sh file | annotate | diff | comparison | revisions
--- a/ChangeLog	Thu Jun 08 22:51:50 2017 -0500
+++ b/ChangeLog	Wed Jun 14 23:40:17 2017 -0500
@@ -104,10 +104,22 @@
 	* A single jabber plugin provides XMPP, GTalk and Facebook protocols.
 	* A single yahoo plugin provides both Yahoo and Yahoo JAPAN protocols.
 
+version 2.12.1 (??/??/????):
+	libpurple:
+	* Unified string comparison. (PR #186) (Arkadiy Illarionov)
+
+	XMPP:
+	* Show XEP-0066 OOB URLs in any message, not just headlines
+
+	IRC:
+	* Fix "Registration timeout" on SASL auth with InspIRCd servers
+	  (and possibly others not based on charybdis/ratbox/ircd-seven)
+	* Fix issues with plugins that modify outgoing messages
+	  (such as the custom PART/QUIT feature of the IRC More plugin)
 
 version 2.12.0 (03/09/2017):
 	libpurple:
-	* Fix an out of bounds memory read in purple_markup_unescape_entity.
+	* Fix an out of bounds memory write in purple_markup_unescape_entity.
 	  CVE-2017-2640
 	* Fix use of uninitialised memory if running non-debug-enabled versions of glib
 	* Updated AIM dev and dist ID's to new ones that were assigned by AOL.
--- a/ChangeLog.API	Thu Jun 08 22:51:50 2017 -0500
+++ b/ChangeLog.API	Wed Jun 14 23:40:17 2017 -0500
@@ -462,6 +462,7 @@
 		* purple_notify_searchresults_get_columns_count
 		* purple_notify_searchresults_get_rows_count
 		* purple_notify_searchresults_row_get
+		* purple_ntlm_*
 		* PurplePluginType
 		* PurplePluginPriority
 		* PurplePluginLoaderInfo
--- a/configure.ac	Thu Jun 08 22:51:50 2017 -0500
+++ b/configure.ac	Wed Jun 14 23:40:17 2017 -0500
@@ -1189,7 +1189,7 @@
 if test "x$enable_libgadu" = "xyes"; then
 	PKG_CHECK_MODULES(LIBGADU, [libgadu >= 1.12.0], [
 		have_libgadu=yes
-		AC_CHECK_LIB(gadu, gg_is_gpl_compliant, , [
+		AC_CHECK_LIB(gadu, gg_is_gpl_compliant, [ ], [
 			LIBGADU_LIBS=""
 			LIBGADU_CFLAGS=""
 			have_libgadu=no
--- a/doc/reference/libpurple/libpurple-docs.xml	Thu Jun 08 22:51:50 2017 -0500
+++ b/doc/reference/libpurple/libpurple-docs.xml	Wed Jun 14 23:40:17 2017 -0500
@@ -59,7 +59,6 @@
       <xi:include href="xml/nat-pmp.xml" />
       <xi:include href="xml/network.xml" />
       <xi:include href="xml/notify.xml" />
-      <xi:include href="xml/ntlm.xml" />
       <xi:include href="xml/plugins.xml" />
       <xi:include href="xml/prefs.xml" />
       <xi:include href="xml/pluginpref.xml" />
--- a/finch/Makefile.am	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/Makefile.am	Wed Jun 14 23:40:17 2017 -0500
@@ -130,7 +130,9 @@
 	--warn-all \
 	--add-include-path=$(prefix)/share/gir-1.0 \
 	--add-include-path=$(builddir)/libgnt \
-	--add-include-path=$(top_builddir)/libpurple
+	--add-include-path=$(top_builddir)/libpurple \
+	--pkg=purple-$(PURPLE_MAJOR_VERSION) \
+	--pkg-export=finch
 
 INTROSPECTION_COMPILER_ARGS = \
 	--includedir=$(prefix)/share/gir-1.0 \
@@ -167,6 +169,7 @@
 Finch_3_0_gir_LIBS = $(builddir)/libfinch.la
 Finch_3_0_gir_FILES = $(introspection_sources)
 INTROSPECTION_GIRS += Finch-$(PURPLE_MAJOR_VERSION).$(PURPLE_MINOR_VERSION).gir
+INTROSPECTION_SCANNER_ENV = PKG_CONFIG_PATH=$(top_builddir)/libpurple/data/
 
 girdir = \
 	 $(prefix)/share/gir-1.0 \
--- a/finch/gntaccount.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/gntaccount.c	Wed Jun 14 23:40:17 2017 -0500
@@ -162,7 +162,7 @@
 		} else {
 			const char *old = purple_account_get_protocol_id(account);
 			char *oldproto;
-			if (strcmp(old, purple_protocol_get_id(protocol))) {
+			if (!purple_strequal(old, purple_protocol_get_id(protocol))) {
 				purple_notify_error(NULL, _("Error"),
 					_("Account was not modified"),
 					_("The account's protocol cannot be "
@@ -450,7 +450,7 @@
 					PurpleKeyValuePair *kvp = opt_iter->data;
 					gnt_combo_box_add_data(GNT_COMBO_BOX(combo), kvp->value, kvp->key);
 
-					if (g_str_equal(kvp->value, active))
+					if (purple_strequal(kvp->value, active))
 						gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), kvp->value);
 				}
 			}
--- a/finch/gntblist.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/gntblist.c	Wed Jun 14 23:40:17 2017 -0500
@@ -1875,16 +1875,16 @@
 		if (gnt_tree_is_searching(GNT_TREE(ggblist->tree)))
 			gnt_bindable_perform_action_named(GNT_BINDABLE(ggblist->tree), "end-search", NULL);
 		remove_peripherals(ggblist);
-	} else if (strcmp(text, GNT_KEY_INS) == 0) {
+	} else if (purple_strequal(text, GNT_KEY_INS)) {
 		PurpleBlistNode *node = gnt_tree_get_selection_data(GNT_TREE(ggblist->tree));
 		purple_blist_request_add_buddy(NULL, NULL,
 				node && PURPLE_IS_GROUP(node) ? purple_group_get_name(PURPLE_GROUP(node)) : NULL,
 				NULL);
 	} else if (!gnt_tree_is_searching(GNT_TREE(ggblist->tree))) {
-		if (strcmp(text, "t") == 0) {
+		if (purple_strequal(text, "t")) {
 			finch_blist_toggle_tag_buddy(gnt_tree_get_selection_data(GNT_TREE(ggblist->tree)));
 			gnt_bindable_perform_action_named(GNT_BINDABLE(ggblist->tree), "move-down", NULL);
-		} else if (strcmp(text, "a") == 0) {
+		} else if (purple_strequal(text, "a")) {
 			finch_blist_place_tagged(gnt_tree_get_selection_data(GNT_TREE(ggblist->tree)));
 		} else
 			return FALSE;
@@ -1993,13 +1993,13 @@
 	if (ggblist->manager->init)
 		ggblist->manager->init();
 
-	if (strcmp(purple_prefs_get_string(PREF_ROOT "/sort_type"), "text") == 0) {
+	if (purple_strequal(purple_prefs_get_string(PREF_ROOT "/sort_type"), "text")) {
 		gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
 			(GCompareFunc)blist_node_compare_text);
-	} else if (strcmp(purple_prefs_get_string(PREF_ROOT "/sort_type"), "status") == 0) {
+	} else if (purple_strequal(purple_prefs_get_string(PREF_ROOT "/sort_type"), "status")) {
 		gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
 			(GCompareFunc)blist_node_compare_status);
-	} else if (strcmp(purple_prefs_get_string(PREF_ROOT "/sort_type"), "log") == 0) {
+	} else if (purple_strequal(purple_prefs_get_string(PREF_ROOT "/sort_type"), "log")) {
 		gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
 			(GCompareFunc)blist_node_compare_log);
 	}
@@ -3198,7 +3198,7 @@
 	if (!g_list_find(managers, manager)) {
 		managers = g_list_append(managers, (gpointer)manager);
 		reconstruct_grouping_menu();
-		if (strcmp(manager->id, purple_prefs_get_string(PREF_ROOT "/grouping")) == 0)
+		if (purple_strequal(manager->id, purple_prefs_get_string(PREF_ROOT "/grouping")))
 			purple_prefs_trigger_callback(PREF_ROOT "/grouping");
 	}
 }
@@ -3208,7 +3208,7 @@
 	if (g_list_find(managers, manager)) {
 		managers = g_list_remove(managers, manager);
 		reconstruct_grouping_menu();
-		if (strcmp(manager->id, purple_prefs_get_string(PREF_ROOT "/grouping")) == 0)
+		if (purple_strequal(manager->id, purple_prefs_get_string(PREF_ROOT "/grouping")))
 			purple_prefs_trigger_callback(PREF_ROOT "/grouping");
 	}
 }
@@ -3221,7 +3221,7 @@
 
 	for (; iter; iter = iter->next) {
 		FinchBlistManager *m = iter->data;
-		if (strcmp(id, m->id) == 0)
+		if (purple_strequal(id, m->id))
 			return m;
 	}
 	return NULL;
--- a/finch/gntconv.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/gntconv.c	Wed Jun 14 23:40:17 2017 -0500
@@ -1368,15 +1368,15 @@
 	int *msgclass  = NULL;
 	int fg, bg;
 
-	if (strcmp(args[0], "receive") == 0)
+	if (purple_strequal(args[0], "receive"))
 		msgclass = &color_message_receive;
-	else if (strcmp(args[0], "send") == 0)
+	else if (purple_strequal(args[0], "send"))
 		msgclass = &color_message_send;
-	else if (strcmp(args[0], "highlight") == 0)
+	else if (purple_strequal(args[0], "highlight"))
 		msgclass = &color_message_highlight;
-	else if (strcmp(args[0], "action") == 0)
+	else if (purple_strequal(args[0], "action"))
 		msgclass = &color_message_action;
-	else if (strcmp(args[0], "timestamp") == 0)
+	else if (purple_strequal(args[0], "timestamp"))
 		msgclass = &color_timestamp;
 	else {
 		if (error)
--- a/finch/gntlog.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/gntlog.c	Wed Jun 14 23:40:17 2017 -0500
@@ -87,7 +87,7 @@
 	if (a->username && b->username) {
 		normal = g_strdup(purple_normalize(a->account, a->username));
 		ret = (a->account == b->account) &&
-			!strcmp(normal, purple_normalize(b->account, b->username));
+			purple_strequal(normal, purple_normalize(b->account, b->username));
 		g_free(normal);
 	} else {
 		ret = (a == b);
@@ -118,7 +118,7 @@
 		return;
 	}
 
-	if (lv->search != NULL && !strcmp(lv->search, search_term)) {
+	if (lv->search != NULL && purple_strequal(lv->search, search_term)) {
 		return;
 	}
 
@@ -234,7 +234,7 @@
 		pmonth = purple_utf8_strftime(_("%B %Y"),
 		                           log->tm ? log->tm : localtime(&log->time));
 
-		if (strcmp(pmonth, prev_top_month) != 0) {
+		if (!purple_strequal(pmonth, prev_top_month)) {
 			month = g_strdup(pmonth);
 			/* top level */
 			gnt_tree_add_row_last(GNT_TREE(lv->tree),
--- a/finch/gntplugin.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/gntplugin.c	Wed Jun 14 23:40:17 2017 -0500
@@ -697,7 +697,7 @@
 				}
 				stringlist = g_list_prepend(stringlist, value);
 				purple_request_field_list_add_icon(field, label, NULL, value);
-				if (strcmp(value, current_value) == 0)
+				if (purple_strequal(value, current_value))
 					purple_request_field_list_add_selected(field, label);
 				list = list->next->next;
 			}
--- a/finch/gntprefs.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/gntprefs.c	Wed Jun 14 23:40:17 2017 -0500
@@ -155,7 +155,7 @@
 						select = TRUE;
 					break;
 				case PURPLE_PREF_STRING:
-					if (strcmp(purple_prefs_get_string(prefs->pref), iter->data) == 0)
+					if (purple_strequal(purple_prefs_get_string(prefs->pref), iter->data))
 						select = TRUE;
 					break;
 				default:
--- a/finch/gntrequest.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/gntrequest.c	Wed Jun 14 23:40:17 2017 -0500
@@ -446,7 +446,7 @@
 		gnt_entry_set_always_suggest(GNT_ENTRY(entry), TRUE);
 		if (username)
 			*username = entry;
-	} else if (hint && !strcmp(hint, "group")) {
+	} else if (purple_strequal(hint, "group")) {
 		PurpleBlistNode *node;
 		for (node = purple_blist_get_root(); node;
 				node = purple_blist_node_get_sibling_next(node)) {
--- a/finch/gntsound.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/gntsound.c	Wed Jun 14 23:40:17 2017 -0500
@@ -465,9 +465,9 @@
 
 	method = purple_prefs_get_string(make_pref("/method"));
 
-	if (!strcmp(method, "nosound")) {
+	if (purple_strequal(method, "nosound")) {
 		return;
-	} else if (!strcmp(method, "beep")) {
+	} else if (purple_strequal(method, "beep")) {
 		beep();
 		return;
 	}
@@ -478,7 +478,7 @@
 	}
 
 #ifndef _WIN32
-	if (!strcmp(method, "custom")) {
+	if (purple_strequal(method, "custom")) {
 		const char *sound_cmd;
 		char *command;
 		char *esc_filename;
@@ -512,7 +512,7 @@
 #ifdef USE_GSTREAMER
 	if (gst_init_failed)  /* Perhaps do beep instead? */
 		return;
-	if (!strcmp(method, "automatic")) {
+	if (purple_strequal(method, "automatic")) {
 		if (purple_running_gnome()) {
 			sink = gst_element_factory_make("gconfaudiosink", "sink");
 		}
@@ -522,13 +522,13 @@
 			purple_debug_error("sound", "Unable to create GStreamer audiosink.\n");
 			return;
 		}
-	} else if (!strcmp(method, "esd")) {
+	} else if (purple_strequal(method, "esd")) {
 		sink = gst_element_factory_make("esdsink", "sink");
 		if (!sink) {
 			purple_debug_error("sound", "Unable to create GStreamer audiosink.\n");
 			return;
 		}
-	} else if (!strcmp(method, "alsa")) {
+	} else if (purple_strequal(method, "alsa")) {
 		sink = gst_element_factory_make("alsasink", "sink");
 		if (!sink) {
 			purple_debug_error("sound", "Unable to create GStreamer audiosink.\n");
@@ -814,7 +814,7 @@
 static void
 reload_pref_window(const char *profile)
 {
-	if (!strcmp(profile, finch_sound_get_active_profile()))
+	if (purple_strequal(profile, finch_sound_get_active_profile()))
 		return;
 	load_pref_window(profile);
 }
@@ -825,19 +825,19 @@
 	const char * profile = gnt_entry_get_text(GNT_ENTRY(pref_dialog->new_profile));
 	gchar * pref;
 
-	if (!strcmp(profile, DEFAULT_PROFILE))
+	if (purple_strequal(profile, DEFAULT_PROFILE))
 		return;
 
 	pref = g_strdup_printf(FINCH_PREFS_ROOT "/sound/profiles/%s", profile);
 	purple_prefs_remove(pref);
 	g_free(pref);
 
-	if (!strcmp(pref_dialog->original_profile, profile)) {
+	if (purple_strequal(pref_dialog->original_profile, profile)) {
 		g_free(pref_dialog->original_profile);
 		pref_dialog->original_profile = g_strdup(DEFAULT_PROFILE);
 	}
 
-	if(!strcmp(profile, finch_sound_get_active_profile()))
+	if(purple_strequal(profile, finch_sound_get_active_profile()))
 		reload_pref_window(DEFAULT_PROFILE);
 
 	gnt_tree_remove(GNT_TREE(pref_dialog->profiles), (gchar *) profile);
@@ -1058,7 +1058,7 @@
 
 	if (!method)
 		return FALSE;
-	if (strcmp(method, "nosound") == 0)
+	if (purple_strequal(method, "nosound"))
 		return FALSE;
 
 	return TRUE;
--- a/finch/plugins/gnthistory.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/plugins/gnthistory.c	Wed Jun 14 23:40:17 2017 -0500
@@ -157,7 +157,7 @@
 			const char *label = _(list->data);
 			list = g_list_delete_link(list, list);
 			purple_request_field_list_add_icon(field, label, NULL, list->data);
-			if (system && strcmp(system, list->data) == 0)
+			if (purple_strequal(system, list->data))
 				purple_request_field_list_add_selected(field, label);
 			list = g_list_delete_link(list, list);
 		}
--- a/finch/plugins/lastlog.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/finch/plugins/lastlog.c	Wed Jun 14 23:40:17 2017 -0500
@@ -42,13 +42,13 @@
 {
 	if (key[0] == 27)
 	{
-		if (strcmp(key, GNT_KEY_DOWN) == 0)
+		if (purple_strequal(key, GNT_KEY_DOWN))
 			gnt_text_view_scroll(view, 1);
-		else if (strcmp(key, GNT_KEY_UP) == 0)
+		else if (purple_strequal(key, GNT_KEY_UP))
 			gnt_text_view_scroll(view, -1);
-		else if (strcmp(key, GNT_KEY_PGDOWN) == 0)
+		else if (purple_strequal(key, GNT_KEY_PGDOWN))
 			gnt_text_view_scroll(view, wid->priv.height - 2);
-		else if (strcmp(key, GNT_KEY_PGUP) == 0)
+		else if (purple_strequal(key, GNT_KEY_PGUP))
 			gnt_text_view_scroll(view, -(wid->priv.height - 2));
 		else
 			return FALSE;
--- a/glib-tap.mk	Thu Jun 08 22:51:50 2017 -0500
+++ b/glib-tap.mk	Wed Jun 14 23:40:17 2017 -0500
@@ -1,6 +1,6 @@
 # GLIB - Library of useful C routines
 
-TESTS_ENVIRONMENT= \
+AM_TESTS_ENVIRONMENT= \
 	G_TEST_SRCDIR="$(abs_srcdir)" 		\
 	G_TEST_BUILDDIR="$(abs_builddir)" 	\
 	G_DEBUG=gc-friendly 			\
@@ -112,7 +112,7 @@
 installed_test_PROGRAMS += $(test_programs) $(installed_test_programs) \
                           $(test_extra_programs) $(installed_test_extra_programs)
 installed_test_SCRIPTS += $(test_scripts) $(installed_test_scripts) \
-                          $(test_extra_scripts) $(test_installed_extra_scripts)
+                          $(test_extra_scripts) $(installed_test_extra_scripts)
 installed_test_SCRIPTS += $(dist_test_scripts) $(dist_test_extra_scripts) \
                           $(dist_installed_test_scripts) $(dist_installed_test_extra_scripts)
 nobase_installed_test_DATA += $(test_data) $(installed_test_data)
@@ -132,4 +132,4 @@
 	mv $@.tmp $@)
 
 CLEANFILES += $(installed_test_meta_DATA)
-endif
\ No newline at end of file
+endif
--- a/libpurple/Makefile.am	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/Makefile.am	Wed Jun 14 23:40:17 2017 -0500
@@ -27,7 +27,6 @@
 		win32/targets.mak \
 		win32/wpurpleerror.h \
 		win32/win32dep.c \
-		win32/giowin32.c \
 		win32/win32dep.h
 
 SUBDIRS = . plugins protocols tests example
@@ -79,7 +78,6 @@
 	mime.c \
 	nat-pmp.c \
 	network.c \
-	ntlm.c \
 	notify.c \
 	plugins.c \
 	pluginpref.c \
@@ -164,7 +162,6 @@
 	nat-pmp.h \
 	network.h \
 	notify.h \
-	ntlm.h \
 	plugins.h \
 	pluginpref.h \
 	pounce.h \
@@ -214,7 +211,6 @@
 
 if IS_WIN32
 purple_coresources += \
-	win32/giowin32.c \
 	win32/libc_interface.c \
 	win32/win32dep.c
 
@@ -498,7 +494,7 @@
 
 -include $(INTROSPECTION_MAKEFILE)
 INTROSPECTION_GIRS =
-INTROSPECTION_SCANNER_ARGS = --add-include-path=$(prefix)/share/gir-1.0 --warn-all
+INTROSPECTION_SCANNER_ARGS = --add-include-path=$(prefix)/share/gir-1.0 --warn-all --pkg-export=purple-$(PURPLE_MAJOR_VERSION)
 INTROSPECTION_COMPILER_ARGS = --includedir=$(prefix)/share/gir-1.0
 
 if HAVE_INTROSPECTION
--- a/libpurple/Makefile.mingw	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/Makefile.mingw	Wed Jun 14 23:40:17 2017 -0500
@@ -102,7 +102,6 @@
 			nat-pmp.c \
 			network.c \
 			notify.c \
-			ntlm.c \
 			plugins.c \
 			pluginpref.c \
 			pounce.c \
@@ -139,7 +138,6 @@
 			whiteboard.c \
 			xfer.c \
 			xmlnode.c \
-			win32/giowin32.c \
 			win32/libc_interface.c \
 			win32/win32dep.c \
 			$(VV_SRC)
--- a/libpurple/buddylist.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/buddylist.c	Wed Jun 14 23:40:17 2017 -0500
@@ -123,7 +123,7 @@
 {
 	return (hb1->group == hb2->group &&
 	        hb1->account == hb2->account &&
-	        g_str_equal(hb1->name, hb2->name));
+	        purple_strequal(hb1->name, hb2->name));
 }
 
 static void _purple_blist_hbuddy_free_key(struct _purple_hbuddy *hb)
@@ -372,7 +372,7 @@
 	child = purple_xmlnode_new_child(node, "blist");
 
 	localized_default = localized_default_group_name;
-	if (g_strcmp0(_("Buddies"), "Buddies") != 0)
+	if (!purple_strequal(_("Buddies"), "Buddies"))
 		localized_default = _("Buddies");
 	if (localized_default != NULL) {
 		purple_xmlnode_set_attrib(child,
@@ -1636,9 +1636,9 @@
 
 	if (name == NULL || name[0] == '\0')
 		name = PURPLE_BLIST_DEFAULT_GROUP_NAME;
-	if (g_strcmp0(name, "Buddies") == 0)
+	if (purple_strequal(name, "Buddies"))
 		name = PURPLE_BLIST_DEFAULT_GROUP_NAME;
-	if (g_strcmp0(name, localized_default_group_name) == 0)
+	if (purple_strequal(name, localized_default_group_name))
 		name = PURPLE_BLIST_DEFAULT_GROUP_NAME;
 
 	key = purple_blist_fold_name(name);
@@ -1704,7 +1704,7 @@
 				g_list_free(parts);
 
 				if (purple_chat_get_account(chat) == account && chat_name != NULL &&
-					normname != NULL && !strcmp(purple_normalize(account, chat_name), normname)) {
+					purple_strequal(purple_normalize(account, chat_name), normname)) {
 					g_free(normname);
 					return chat;
 				}
--- a/libpurple/data/purple-3-uninstalled.pc.in	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/data/purple-3-uninstalled.pc.in	Wed Jun 14 23:40:17 2017 -0500
@@ -19,4 +19,4 @@
 Version: @VERSION@
 Requires: glib-2.0
 Cflags: -I${abs_top_srcdir} -I${abs_top_builddir}
-Libs: ${abs_builddir}/libpurple.la
+Libs: ${abs_top_builddir}/libpurple/libpurple.la
--- a/libpurple/dbus-server.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/dbus-server.c	Wed Jun 14 23:40:17 2017 -0500
@@ -436,7 +436,7 @@
 		return FALSE;
 
 	for (i = 0; bindings[i].name; i++)
-		if (!strcmp(name, bindings[i].name))
+		if (purple_strequal(name, bindings[i].name))
 		{
 			DBusMessage *reply;
 			DBusError error;
@@ -782,7 +782,7 @@
 	 * flag for each signal that states whether this signal is to be
 	 * dbus-propagated or not.
 	 */
-	if (!strcmp(name, "dbus-method-called"))
+	if (purple_strequal(name, "dbus-method-called"))
 		return;
 
 	newname = purple_dbus_convert_signal_name(name);
--- a/libpurple/dbus-useful.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/dbus-useful.c	Wed Jun 14 23:40:17 2017 -0500
@@ -45,10 +45,10 @@
 	for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
 		PurpleAccount *account = (PurpleAccount *)l->data;
 
-		if (who && strcmp(purple_normalize(NULL, purple_account_get_username(account)), who))
+		if (who && !purple_strequal(purple_normalize(NULL, purple_account_get_username(account)), who))
 			continue;
 
-		if (protocol_id && strcmp(purple_account_get_protocol_id(account), protocol_id))
+		if (protocol_id && !purple_strequal(purple_account_get_protocol_id(account), protocol_id))
 			continue;
 
 		if (account_test && !account_test(account))
--- a/libpurple/example/nullclient.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/example/nullclient.c	Wed Jun 14 23:40:17 2017 -0500
@@ -30,7 +30,6 @@
 #include <string.h>
 #ifdef _WIN32
 #  include <conio.h>
-#  include "win32/win32dep.h"
 #else
 #  include <unistd.h>
 #endif
@@ -86,8 +85,8 @@
 	if (condition & PURPLE_INPUT_WRITE)
 		cond |= PURPLE_GLIB_WRITE_COND;
 
-#if defined _WIN32 && !defined WINPIDGIN_USE_GLIB_IO_CHANNEL
-	channel = wpurple_g_io_channel_win32_new_socket(fd);
+#ifdef _WIN32
+	channel = g_io_channel_win32_new_socket(fd);
 #else
 	channel = g_io_channel_unix_new(fd);
 #endif
--- a/libpurple/http.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/http.c	Wed Jun 14 23:40:17 2017 -0500
@@ -26,7 +26,6 @@
 
 
 #include "debug.h"
-#include "ntlm.h"
 #include "proxy.h"
 #include "purple-gio.h"
 
@@ -230,6 +229,25 @@
 	GString *pending;
 };
 
+struct _ntlm_type1_message {
+	guint8  protocol[8];     /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0' */
+	guint32 type;            /* 0x00000001 */
+	guint32 flags;           /* 0x0000b203 */
+
+	guint16 dom_len1;        /* domain string length */
+	guint16 dom_len2;        /* domain string length */
+	guint32 dom_off;         /* domain string offset */
+
+	guint16 host_len1;       /* host string length */
+	guint16 host_len2;       /* host string length */
+	guint32 host_off;        /* host string offset (always 0x00000020) */
+
+#if 0
+	guint8  host[*];         /* host string (ASCII) */
+	guint8  dom[*];          /* domain string (ASCII) */
+#endif
+};
+
 static time_t purple_http_rfc1123_to_time(const gchar *str);
 
 static gboolean purple_http_request_is_method(PurpleHttpRequest *request,
@@ -461,6 +479,56 @@
 	g_free(gzs);
 }
 
+/*** NTLM *********************************************************************/
+
+/**
+ * purple_ntlm_gen_type1:
+ * @hostname: Your hostname
+ * @domain: The domain to authenticate to
+ *
+ * Generates the base64 encoded type 1 message needed for NTLM authentication
+ *
+ * Returns: base64 encoded string to send to the server.  This should
+ *         be g_free'd by the caller.
+ */
+static gchar *
+purple_http_ntlm_gen_type1(const gchar *hostname, const gchar *domain)
+{
+	int hostnamelen,host_off;
+	int domainlen,dom_off;
+	unsigned char *msg;
+	struct _ntlm_type1_message *tmsg;
+	gchar *tmp;
+
+	hostnamelen = strlen(hostname);
+	domainlen = strlen(domain);
+	host_off = sizeof(struct _ntlm_type1_message);
+	dom_off = sizeof(struct _ntlm_type1_message) + hostnamelen;
+	msg = g_malloc0(sizeof(struct _ntlm_type1_message) + hostnamelen + domainlen);
+	tmsg = (struct _ntlm_type1_message*)(gpointer)msg;
+	tmsg->protocol[0] = 'N';
+	tmsg->protocol[1] = 'T';
+	tmsg->protocol[2] = 'L';
+	tmsg->protocol[3] = 'M';
+	tmsg->protocol[4] = 'S';
+	tmsg->protocol[5] = 'S';
+	tmsg->protocol[6] = 'P';
+	tmsg->protocol[7] = '\0';
+	tmsg->type      = GUINT32_TO_LE(0x00000001);
+	tmsg->flags     = GUINT32_TO_LE(0x0000b203);
+	tmsg->dom_len1  = tmsg->dom_len2 = GUINT16_TO_LE(domainlen);
+	tmsg->dom_off   = GUINT32_TO_LE(dom_off);
+	tmsg->host_len1 = tmsg->host_len2 = GUINT16_TO_LE(hostnamelen);
+	tmsg->host_off  = GUINT32_TO_LE(host_off);
+	memcpy(msg + host_off, hostname, hostnamelen);
+	memcpy(msg + dom_off, domain, domainlen);
+
+	tmp = g_base64_encode(msg, sizeof(struct _ntlm_type1_message) + hostnamelen + domainlen);
+	g_free(msg);
+
+	return tmp;
+}
+
 /*** HTTP Sockets *************************************************************/
 
 static gchar *
@@ -863,7 +931,8 @@
 		memset(tmp, 0, len);
 		g_free(tmp);
 
-		ntlm_type1 = purple_ntlm_gen_type1(purple_get_host_name(), "");
+		ntlm_type1 = purple_http_ntlm_gen_type1(purple_get_host_name(),
+			"");
 
 		g_string_append_printf(h, "Proxy-Authorization: Basic %s\r\n",
 			proxy_auth);
--- a/libpurple/media.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/media.c	Wed Jun 14 23:40:17 2017 -0500
@@ -463,8 +463,8 @@
 
 	for (; streams; streams = g_list_next(streams)) {
 		PurpleMediaStream *stream = streams->data;
-		if (!strcmp(stream->session->id, session) &&
-				!strcmp(stream->participant, participant))
+		if (purple_strequal(stream->session->id, session) &&
+				purple_strequal(stream->participant, participant))
 			return stream;
 	}
 
@@ -485,9 +485,9 @@
 	for (; streams; streams = g_list_next(streams)) {
 		PurpleMediaStream *stream = streams->data;
 		if ((session == NULL ||
-				!strcmp(stream->session->id, session)) &&
+				purple_strequal(stream->session->id, session)) &&
 				(participant == NULL ||
-				!strcmp(stream->participant, participant)))
+				purple_strequal(stream->participant, participant)))
 			ret = g_list_append(ret, stream);
 	}
 
@@ -934,7 +934,7 @@
 
 	params = purple_media_backend_get_available_params(media->priv->backend);
 	for (; *params != NULL; ++params)
-		if (!strcmp(*params, param))
+		if (purple_strequal(*params, param))
 			return TRUE;
 #endif
 	return FALSE;
--- a/libpurple/media/backend-fs2.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/media/backend-fs2.c	Wed Jun 14 23:40:17 2017 -0500
@@ -840,8 +840,8 @@
 
 	for (; streams; streams = g_list_next(streams)) {
 		PurpleMediaBackendFs2Stream *stream = streams->data;
-		if (!strcmp(stream->session->id, sess_id) &&
-				!strcmp(stream->participant, name))
+		if (purple_strequal(stream->session->id, sess_id) &&
+				purple_strequal(stream->participant, name))
 			return stream;
 	}
 
@@ -863,9 +863,9 @@
 	for (; streams; streams = g_list_next(streams)) {
 		PurpleMediaBackendFs2Stream *stream = streams->data;
 
-		if (sess_id != NULL && strcmp(stream->session->id, sess_id))
+		if (sess_id != NULL && !purple_strequal(stream->session->id, sess_id))
 			continue;
-		else if (name != NULL && strcmp(stream->participant, name))
+		else if (name != NULL && !purple_strequal(stream->participant, name))
 			continue;
 		else
 			ret = g_list_prepend(ret, stream);
@@ -1724,7 +1724,7 @@
 	 * receiving the src-pad-added signal.
 	 * Only works for non-multicast FsRtpSessions.
 	 */
-	if (!!strcmp(transmitter, "multicast"))
+	if (!purple_strequal(transmitter, "multicast"))
 		g_object_set(G_OBJECT(session->session),
 				"no-rtcp-timeout", 0, NULL);
 
@@ -2003,7 +2003,7 @@
 		++_num_params;
 	}
 
-	if (turn_ip && !strcmp("nice", transmitter) && !got_turn_from_protocol) {
+	if (turn_ip && purple_strequal("nice", transmitter) && !got_turn_from_protocol) {
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		GValueArray *relay_info = g_value_array_new(0);
 G_GNUC_END_IGNORE_DEPRECATIONS
@@ -2019,7 +2019,7 @@
 			relay_info = append_relay_info(relay_info, turn_ip, port, username,
 				password, "udp");
 		}
-		
+
 		/* TCP */
 		port = purple_prefs_get_int("/purple/network/turn_port_tcp");
 		if (port > 0) {
@@ -2056,7 +2056,7 @@
 	stream->participant = g_strdup(who);
 	stream->session = session;
 	stream->stream = fsstream;
-	stream->supports_add = !strcmp(transmitter, "nice");
+	stream->supports_add = purple_strequal(transmitter, "nice");
 
 	priv->streams =	g_list_append(priv->streams, stream);
 
@@ -2463,7 +2463,7 @@
 	guint i;
 
 	for (i = 0; supported[i] != NULL; ++i) {
-		if (!strcmp(param, supported[i])) {
+		if (purple_strequal(param, supported[i])) {
 			return sdes_types[i];
 		}
 	}
--- a/libpurple/mediamanager.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/mediamanager.c	Wed Jun 14 23:40:17 2017 -0500
@@ -623,9 +623,9 @@
 		PurpleMediaAppDataInfo *info = i->data;
 
 		if (info->media == media &&
-			g_strcmp0 (info->session_id, session_id) == 0 &&
+			purple_strequal (info->session_id, session_id) &&
 			(participant == NULL ||
-				g_strcmp0 (info->participant, participant) == 0)) {
+				purple_strequal (info->participant, participant))) {
 			return info;
 		}
 	}
@@ -1236,7 +1236,7 @@
 	for (; iter; iter = g_list_next(iter)) {
 		gchar *element_id =
 				purple_media_element_info_get_id(iter->data);
-		if (!strcmp(element_id, id)) {
+		if (purple_strequal(element_id, id)) {
 			g_free(element_id);
 			g_object_ref(iter->data);
 			return iter->data;
@@ -1457,11 +1457,8 @@
 		PurpleMediaOutputWindow *ow = iter->data;
 
 		if (ow->sink == NULL && ow->media == media &&
-				((participant != NULL &&
-				ow->participant != NULL &&
-				!strcmp(participant, ow->participant)) ||
-				(participant == ow->participant)) &&
-				!strcmp(session_id, ow->session_id)) {
+				purple_strequal(participant, ow->participant) &&
+				purple_strequal(session_id, ow->session_id)) {
 			GstBus *bus;
 			GstElement *queue, *convert, *scale;
 			GstElement *tee = purple_media_get_tee(media,
@@ -1649,12 +1646,8 @@
 		iter = g_list_next(iter);
 
 	if (media == ow->media &&
-			((session_id != NULL && ow->session_id != NULL &&
-			!strcmp(session_id, ow->session_id)) ||
-			(session_id == ow->session_id)) &&
-			((participant != NULL && ow->participant != NULL &&
-			!strcmp(participant, ow->participant)) ||
-			(participant == ow->participant)))
+			purple_strequal(session_id, ow->session_id) &&
+			purple_strequal(participant, ow->participant))
 		purple_media_manager_remove_output_window(
 				manager, ow->id);
 	}
--- a/libpurple/ntlm.c	Thu Jun 08 22:51:50 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,404 +0,0 @@
-/* purple
- *
- * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
- *
- * hashing done according to description of NTLM on
- * http://www.innovation.ch/java/ntlm.html
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#include "internal.h"
-
-#include "util.h"
-#include "ntlm.h"
-#include "debug.h"
-
-#include "ciphers/descipher.h"
-#include "ciphers/md4hash.h"
-
-#include <string.h>
-
-#define NTLM_NEGOTIATE_NTLM2_KEY 0x00080000
-
-struct type1_message {
-	guint8  protocol[8];     /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0' */
-	guint32 type;            /* 0x00000001 */
-	guint32 flags;           /* 0x0000b203 */
-
-	guint16 dom_len1;        /* domain string length */
-	guint16 dom_len2;        /* domain string length */
-	guint32 dom_off;         /* domain string offset */
-
-	guint16 host_len1;       /* host string length */
-	guint16 host_len2;       /* host string length */
-	guint32 host_off;        /* host string offset (always 0x00000020) */
-
-#if 0
-	guint8  host[*];         /* host string (ASCII) */
-	guint8  dom[*];          /* domain string (ASCII) */
-#endif
-};
-
-struct type2_message {
-	guint8  protocol[8];     /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'*/
-	guint32 type;            /* 0x00000002 */
-
-	guint32 zero;
-	guint16 msg_len1;        /* target name length */
-	guint16 msg_len2;        /* target name length */
-
-	guint32 flags;           /* 0x00008201 */
-
-	guint8  nonce[8];        /* nonce */
-	guint8  context[8];
-};
-
-struct type3_message {
-	guint8  protocol[8];     /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'*/
-	guint32 type;            /* 0x00000003 */
-
-	guint16 lm_resp_len1;    /* LanManager response length (always 0x18)*/
-	guint16 lm_resp_len2;    /* LanManager response length (always 0x18)*/
-	guint32 lm_resp_off;     /* LanManager response offset */
-
-	guint16 nt_resp_len1;    /* NT response length (always 0x18) */
-	guint16 nt_resp_len2;    /* NT response length (always 0x18) */
-	guint32 nt_resp_off;     /* NT response offset */
-
-	guint16 dom_len1;        /* domain string length */
-	guint16 dom_len2;        /* domain string length */
-	guint32 dom_off;         /* domain string offset (always 0x00000040) */
-
-	guint16 user_len1;       /* username string length */
-	guint16 user_len2;       /* username string length */
-	guint32 user_off;        /* username string offset */
-
-	guint16 host_len1;       /* host string length */
-	guint16 host_len2;       /* host string length */
-	guint32 host_off;        /* host string offset */
-
-	guint16 sess_len1;
-	guint16 sess_len2;
-	guint32 sess_off;         /* message length */
-
-	guint32 flags;            /* 0x00008201 */
-	/* guint32 flags2; */     /* unknown, used in windows messenger */
-	/* guint32 flags3; */
-
-#if 0
-	guint8  dom[*];          /* domain string (unicode UTF-16LE) */
-	guint8  user[*];         /* username string (unicode UTF-16LE) */
-	guint8  host[*];         /* host string (unicode UTF-16LE) */
-	guint8  lm_resp[*];      /* LanManager response */
-	guint8  nt_resp[*];      /* NT response */
-#endif
-};
-
-gchar *
-purple_ntlm_gen_type1(const gchar *hostname, const gchar *domain)
-{
-	int hostnamelen,host_off;
-	int domainlen,dom_off;
-	unsigned char *msg;
-	struct type1_message *tmsg;
-	gchar *tmp;
-
-	hostnamelen = strlen(hostname);
-	domainlen = strlen(domain);
-	host_off = sizeof(struct type1_message);
-	dom_off = sizeof(struct type1_message) + hostnamelen;
-	msg = g_malloc0(sizeof(struct type1_message) + hostnamelen + domainlen);
-	tmsg = (struct type1_message*)(gpointer)msg;
-	tmsg->protocol[0] = 'N';
-	tmsg->protocol[1] = 'T';
-	tmsg->protocol[2] = 'L';
-	tmsg->protocol[3] = 'M';
-	tmsg->protocol[4] = 'S';
-	tmsg->protocol[5] = 'S';
-	tmsg->protocol[6] = 'P';
-	tmsg->protocol[7] = '\0';
-	tmsg->type      = GUINT32_TO_LE(0x00000001);
-	tmsg->flags     = GUINT32_TO_LE(0x0000b203);
-	tmsg->dom_len1  = tmsg->dom_len2 = GUINT16_TO_LE(domainlen);
-	tmsg->dom_off   = GUINT32_TO_LE(dom_off);
-	tmsg->host_len1 = tmsg->host_len2 = GUINT16_TO_LE(hostnamelen);
-	tmsg->host_off  = GUINT32_TO_LE(host_off);
-	memcpy(msg + host_off, hostname, hostnamelen);
-	memcpy(msg + dom_off, domain, domainlen);
-
-	tmp = g_base64_encode(msg, sizeof(struct type1_message) + hostnamelen + domainlen);
-	g_free(msg);
-
-	return tmp;
-}
-
-guint8 *
-purple_ntlm_parse_type2(const gchar *type2, guint32 *flags)
-{
-	gsize retlen;
-	guchar *buff;
-	struct type2_message tmsg;
-	static guint8 nonce[8];
-
-	buff = g_base64_decode(type2, &retlen);
-
-	if (buff != NULL && retlen >= (sizeof(struct type2_message) - 1)) {
-		memcpy(&tmsg, buff, MIN(retlen, sizeof(tmsg)));
-		memcpy(nonce, tmsg.nonce, 8);
-		if (flags != NULL)
-			*flags = GUINT16_FROM_LE(tmsg.flags);
-	} else {
-		purple_debug_error("ntlm", "Unable to parse type2 message - returning empty nonce.\n");
-		memset(nonce, 0, 8);
-	}
-	g_free(buff);
-
-	return nonce;
-}
-
-/*
- * Create a 64bit DES key by taking a 56bit key and adding
- * a parity bit after every 7th bit.
- */
-static void
-setup_des_key(const guint8 key_56[], guint8 *key)
-{
-	key[0] = key_56[0];
-	key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
-	key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
-	key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
-	key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
-	key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
-	key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
-	key[7] =  (key_56[6] << 1) & 0xFF;
-}
-
-/*
- * helper function for purple cipher.c
- */
-static void
-des_ecb_encrypt(const guint8 *plaintext, guint8 *result, const guint8 *key)
-{
-	PurpleCipher *cipher;
-	gssize encsiz;
-
-	cipher = purple_des_cipher_new();
-	purple_cipher_set_key(cipher, key, 8);
-	encsiz = purple_cipher_encrypt(cipher, plaintext, 8, result, 8);
-	g_warn_if_fail(encsiz == 8);
-	g_object_unref(cipher);
-}
-
-/*
- * takes a 21 byte array and treats it as 3 56-bit DES keys. The
- * 8 byte plaintext is encrypted with each key and the resulting 24
- * bytes are stored in the results array.
- */
-static void
-calc_resp(guint8 *keys, const guint8 *plaintext, unsigned char *results)
-{
-	guint8 key[8];
-	setup_des_key(keys, key);
-	des_ecb_encrypt(plaintext, results, key);
-
-	setup_des_key(keys + 7, key);
-	des_ecb_encrypt(plaintext, results + 8, key);
-
-	setup_des_key(keys + 14, key);
-	des_ecb_encrypt(plaintext, results + 16, key);
-}
-
-/*
- * TODO: We think we should be using cryptographically secure random numbers
- *       here.  We think the rand() function is probably bad.  We think
- *       /dev/urandom is a step up, but using a random function from an SSL
- *       library would probably be best.  In Windows we could possibly also
- *       use CryptGenRandom.
- */
-static void
-gensesskey(char *buffer)
-{
-	int fd;
-	int i;
-	ssize_t red = 0;
-
-	fd = open("/dev/urandom", O_RDONLY);
-	if (fd >= 0) {
-		red = read(fd, buffer, 16);
-		if (red < 0) {
-			purple_debug_warning("ntlm", "Error reading from /dev/urandom: %s."
-					"  Falling back to inferior method.\n", g_strerror(errno));
-			red = 0;
-		} else if (red < 16) {
-			purple_debug_warning("ntlm", "Tried reading 16 bytes from "
-					"/dev/urandom but only got %"
-					G_GSSIZE_FORMAT ".  Falling back to "
-					"inferior method\n", (gssize)red);
-		}
-		close(fd);
-	} else {
-		purple_debug_warning("ntlm", "Error opening /dev/urandom: %s."
-				"  Falling back to inferior method.\n", g_strerror(errno));
-	}
-
-	for (i = red; i < 16; i++) {
-		buffer[i] = (char)(g_random_int() & 0xff);
-	}
-}
-
-gchar *
-purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *hostname, const gchar *domain, const guint8 *nonce, guint32 *flags)
-{
-	char lm_pw[14];
-	unsigned char lm_hpw[21];
-	char sesskey[16];
-	guint8 key[8];
-	int domainlen;
-	int usernamelen;
-	int hostnamelen;
-	int msglen;
-	struct type3_message *tmsg;
-	int passwlen, lennt;
-	unsigned char lm_resp[24], nt_resp[24];
-	unsigned char magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
-	unsigned char nt_hpw[21];
-	char nt_pw[128];
-	PurpleHash *hash;
-	char *tmp;
-	int idx;
-	gchar *ucs2le;
-
-	domainlen = strlen(domain) * 2;
-	usernamelen = strlen(username) * 2;
-	hostnamelen = strlen(hostname) * 2;
-	msglen = sizeof(struct type3_message) + domainlen +
-		usernamelen + hostnamelen + 0x18 + 0x18 + ((flags) ? 0x10 : 0);
-	tmsg = g_malloc0(msglen);
-	passwlen = strlen(passw);
-
-	/* type3 message initialization */
-	tmsg->protocol[0] = 'N';
-	tmsg->protocol[1] = 'T';
-	tmsg->protocol[2] = 'L';
-	tmsg->protocol[3] = 'M';
-	tmsg->protocol[4] = 'S';
-	tmsg->protocol[5] = 'S';
-	tmsg->protocol[6] = 'P';
-	tmsg->type = GUINT32_TO_LE(0x00000003);
-	tmsg->lm_resp_len1 = tmsg->lm_resp_len2 = GUINT16_TO_LE(0x18);
-	tmsg->lm_resp_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen);
-	tmsg->nt_resp_len1 = tmsg->nt_resp_len2 = GUINT16_TO_LE(0x18);
-	tmsg->nt_resp_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen + 0x18);
-
-	tmsg->dom_len1 = tmsg->dom_len2 = GUINT16_TO_LE(domainlen);
-	tmsg->dom_off = GUINT32_TO_LE(sizeof(struct type3_message));
-
-	tmsg->user_len1 = tmsg->user_len2 = GUINT16_TO_LE(usernamelen);
-	tmsg->user_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen);
-
-	tmsg->host_len1 = tmsg->host_len2 = GUINT16_TO_LE(hostnamelen);
-	tmsg->host_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen);
-
-	if(flags) {
-		tmsg->sess_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen + 0x18 + 0x18);
-		tmsg->sess_len1 = tmsg->sess_len2 = GUINT16_TO_LE(0x0010);
-	}
-
-	tmsg->flags = GUINT32_TO_LE(0x00008201);
-
-	tmp = (char *)tmsg + sizeof(struct type3_message);
-
-	ucs2le = g_convert(domain, -1, "UTF-16LE", "UTF-8", NULL, NULL, NULL);
-	if (ucs2le != NULL) {
-		memcpy(tmp, ucs2le, domainlen);
-		g_free(ucs2le);
-		tmp += domainlen;
-	} else {
-		purple_debug_info("ntlm", "Unable to encode domain in UTF-16LE.\n");
-	}
-
-	ucs2le = g_convert(username, -1, "UTF-16LE", "UTF-8", NULL, NULL, NULL);
-	if (ucs2le != NULL) {
-		memcpy(tmp, ucs2le, usernamelen);
-		g_free(ucs2le);
-		tmp += usernamelen;
-	} else {
-		purple_debug_info("ntlm", "Unable to encode username in UTF-16LE.\n");
-	}
-
-	ucs2le = g_convert(hostname, -1, "UTF-16LE", "UTF-8", NULL, NULL, NULL);
-	if (ucs2le != NULL) {
-		memcpy(tmp, ucs2le, hostnamelen);
-		g_free(ucs2le);
-		tmp += hostnamelen;
-	} else {
-		purple_debug_info("ntlm", "Unable to encode hostname in UTF-16LE.\n");
-	}
-
-	/* LM */
-	if (passwlen > 14)
-		passwlen = 14;
-
-	for (idx = 0; idx < passwlen; idx++)
-		lm_pw[idx] = g_ascii_toupper(passw[idx]);
-	for (; idx < 14; idx++)
-		lm_pw[idx] = 0;
-
-	setup_des_key((unsigned char*)lm_pw, key);
-	des_ecb_encrypt(magic, lm_hpw, key);
-
-	setup_des_key((unsigned char*)(lm_pw + 7), key);
-	des_ecb_encrypt(magic, lm_hpw + 8, key);
-
-	memset(lm_hpw + 16, 0, 5);
-	calc_resp(lm_hpw, nonce, lm_resp);
-	memcpy(tmp, lm_resp, 0x18);
-	tmp += 0x18;
-
-	/* NTLM */
-	/* Convert the password to UTF-16LE */
-	lennt = strlen(passw);
-	for (idx = 0; idx < lennt; idx++)
-	{
-		nt_pw[2 * idx]   = passw[idx];
-		nt_pw[2 * idx + 1] = 0;
-	}
-
-	hash = purple_md4_hash_new();
-	purple_hash_append(hash, (guint8 *)nt_pw, 2 * lennt);
-	purple_hash_digest(hash, nt_hpw, sizeof(nt_hpw));
-	g_object_unref(hash);
-
-	memset(nt_hpw + 16, 0, 5);
-	calc_resp(nt_hpw, nonce, nt_resp);
-	memcpy(tmp, nt_resp, 0x18);
-	tmp += 0x18;
-
-	/* LCS Stuff */
-	if (flags) {
-		tmsg->flags = GUINT32_TO_LE(0x409082d4);
-		gensesskey(sesskey);
-		memcpy(tmp, sesskey, 0x10);
-	}
-
-	/*tmsg->flags2 = 0x0a280105;
-	tmsg->flags3 = 0x0f000000;*/
-
-	tmp = g_base64_encode((guchar *)tmsg, msglen);
-	g_free(tmsg);
-
-	return tmp;
-}
--- a/libpurple/ntlm.h	Thu Jun 08 22:51:50 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/* purple
- *
- * Copyright (C) 2005, Thomas Butter <butter@uni-mannheim.de>
- *
- * ntlm structs are taken from NTLM description on
- * http://www.innovation.ch/java/ntlm.html
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#ifndef _PURPLE_NTLM_H
-#define _PURPLE_NTLM_H
-/**
- * SECTION:ntlm
- * @section_id: libpurple-ntlm
- * @short_description: <filename>ntlm.h</filename>
- * @title: NTLM Authentication
- */
-
-G_BEGIN_DECLS
-
-/**
- * purple_ntlm_gen_type1:
- * @hostname: Your hostname
- * @domain: The domain to authenticate to
- *
- * Generates the base64 encoded type 1 message needed for NTLM authentication
- *
- * Returns: base64 encoded string to send to the server.  This should
- *         be g_free'd by the caller.
- */
-gchar *purple_ntlm_gen_type1(const gchar *hostname, const gchar *domain);
-
-/**
- * purple_ntlm_parse_type2:
- * @type2: String containing the base64 encoded type2 message
- * @flags: If not %NULL, this will store the flags for the message
- *
- * Parses the ntlm type 2 message
- *
- * Returns: The nonce for use in message type3.  This is a statically
- *         allocated 8 byte binary string.
- */
-guint8 *purple_ntlm_parse_type2(const gchar *type2, guint32 *flags);
-
-/**
- * purple_ntlm_gen_type3:
- * @username: The username
- * @passw: The password
- * @hostname: The hostname
- * @domain: The domain to authenticate against
- * @nonce: The nonce returned by purple_ntlm_parse_type2
- * @flags: Pointer to the flags returned by purple_ntlm_parse_type2
- *
- * Generates a type3 message
- *
- * Returns: A base64 encoded type3 message.  This should be g_free'd by
- *          the caller.
- */
-gchar *purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *hostname, const gchar *domain, const guint8 *nonce, guint32 *flags);
-
-G_END_DECLS
-
-#endif /* _PURPLE_NTLM_H */
--- a/libpurple/plugins/joinpart.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/plugins/joinpart.c	Wed Jun 14 23:40:17 2017 -0500
@@ -65,7 +65,7 @@
 	else if (b == NULL)
 		return FALSE;
 
-	return (a->conv == b->conv) && !strcmp(a->user, b->user);
+	return (a->conv == b->conv) && purple_strequal(a->user, b->user);
 }
 
 static void joinpart_key_destroy(struct joinpart_key *key)
--- a/libpurple/plugins/keyrings/gnomekeyring.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/plugins/keyrings/gnomekeyring.c	Wed Jun 14 23:40:17 2017 -0500
@@ -35,6 +35,8 @@
 #include <gnome-keyring.h>
 #include <gnome-keyring-memory.h>
 
+#warning Gnome-Keyring API is deprecated, please use libSecret keyring instead.
+
 #define GNOMEKEYRING_NAME        N_("GNOME Keyring")
 #define GNOMEKEYRING_DESCRIPTION N_("This plugin will store passwords in " \
 	"GNOME Keyring.")
@@ -73,7 +75,9 @@
 {
 	if (req->password != NULL) {
 		memset(req->password, 0, strlen(req->password));
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		gnome_keyring_memory_free(req->password);
+		G_GNUC_END_IGNORE_DEPRECATIONS
 	}
 	g_free(req);
 }
@@ -303,18 +307,21 @@
 	}
 
 	if (req->type == GNOMEKEYRING_REQUEST_READ) {
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		current_request = gnome_keyring_find_password(
 			GNOME_KEYRING_NETWORK_PASSWORD, gnomekeyring_read_cb,
 			req, gnomekeyring_request_cancel,
 			"user", purple_account_get_username(account),
 			"protocol", purple_account_get_protocol_id(account),
 			NULL);
+		G_GNUC_END_IGNORE_DEPRECATIONS
 	} else if (req->type == GNOMEKEYRING_REQUEST_SAVE &&
 		req->password != NULL)
 	{
 		gchar *display_name = g_strdup_printf(
 			_("Pidgin IM password for account %s"),
 			purple_account_get_username(account));
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		current_request = gnome_keyring_store_password(
 			GNOME_KEYRING_NETWORK_PASSWORD, GNOME_KEYRING_DEFAULT,
 			display_name, req->password, gnomekeyring_save_cb, req,
@@ -322,16 +329,19 @@
 			"user", purple_account_get_username(account),
 			"protocol", purple_account_get_protocol_id(account),
 			NULL);
+		G_GNUC_END_IGNORE_DEPRECATIONS
 		g_free(display_name);
 	} else if (req->type == GNOMEKEYRING_REQUEST_SAVE &&
 		req->password == NULL)
 	{
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		current_request = gnome_keyring_delete_password(
 			GNOME_KEYRING_NETWORK_PASSWORD, gnomekeyring_save_cb,
 			req, gnomekeyring_request_cancel,
 			"user", purple_account_get_username(account),
 			"protocol", purple_account_get_protocol_id(account),
 			NULL);
+		G_GNUC_END_IGNORE_DEPRECATIONS
 	} else {
 		g_return_if_reached();
 	}
@@ -365,7 +375,9 @@
 	req = g_new0(gnomekeyring_request, 1);
 	req->type = GNOMEKEYRING_REQUEST_SAVE;
 	req->account = account;
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 	req->password = gnome_keyring_memory_strdup(password);
+	G_GNUC_END_IGNORE_DEPRECATIONS
 	req->cb.save = cb;
 	req->cb_data = data;
 
@@ -375,9 +387,13 @@
 static void
 gnomekeyring_cancel(void)
 {
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 	gnomekeyring_cancel_queue();
+	G_GNUC_END_IGNORE_DEPRECATIONS
 	if (current_request) {
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		gnome_keyring_cancel_request(current_request);
+		G_GNUC_END_IGNORE_DEPRECATIONS
 		while (g_main_iteration(FALSE));
 	}
 }
@@ -430,7 +446,9 @@
 	}
 	g_module_make_resident(gkr_module);
 
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 	if (!gnome_keyring_is_available()) {
+		G_GNUC_END_IGNORE_DEPRECATIONS
 		g_set_error(error, GNOMEKEYRING_DOMAIN, 0, "GNOME Keyring service is "
 			"disabled.");
 		purple_debug_info("keyring-gnome", "GNOME Keyring service is "
--- a/libpurple/plugins/log_reader.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/plugins/log_reader.c	Wed Jun 14 23:40:17 2017 -0500
@@ -31,7 +31,7 @@
 	const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
 	for (iter = 0; months[iter]; iter++) {
-		if (strcmp(month, months[iter]) == 0)
+		if (purple_strequal(month, months[iter]))
 			break;
 	}
 	return iter;
@@ -522,7 +522,7 @@
 	g_return_val_if_fail(sn != NULL, NULL);
 	g_return_val_if_fail(account != NULL, NULL);
 
-	if (strcmp(purple_account_get_protocol_id(account), "prpl-msn"))
+	if (!purple_strequal(purple_account_get_protocol_id(account), "prpl-msn"))
 		return NULL;
 
 	logdir = purple_prefs_get_string("/plugins/core/log_reader/msn/log_directory");
@@ -670,7 +670,7 @@
 				}
 
 				path = g_build_filename(path, name, NULL);
-				if (!strcmp(c, ".xml") &&
+				if (purple_strequal(c, ".xml") &&
 				    g_file_test(path, G_FILE_TEST_EXISTS)) {
 					found = TRUE;
 					g_free(logfile);
@@ -732,7 +732,7 @@
 			continue;
 		}
 
-		if (strcmp(session_id, old_session_id)) {
+		if (!purple_strequal(session_id, old_session_id)) {
 			/*
 			 * The session ID differs from the last message.
 			 * Thus, this is the start of a new conversation.
@@ -822,7 +822,7 @@
 			break;
 		}
 
-		if (strcmp(new_session_id, data->session_id)) {
+		if (!purple_strequal(new_session_id, data->session_id)) {
 			/* The session ID differs from the first message.
 			 * Thus, this is the start of a new conversation.
 			 */
@@ -1671,7 +1671,7 @@
 	memset(&tm, 0, sizeof(tm));
 
 	/* QIP only supports ICQ. */
-	if (strcmp(purple_account_get_protocol_id(account), "prpl-icq"))
+	if (!purple_strequal(purple_account_get_protocol_id(account), "prpl-icq"))
 		return NULL;
 
 	logdir = purple_prefs_get_string("/plugins/core/log_reader/qip/log_directory");
@@ -2138,7 +2138,7 @@
 		return NULL;
 
 	/* aMSN only works with MSN/WLM */
-	if (strcmp(purple_account_get_protocol_id(account), "prpl-msn"))
+	if (!purple_strequal(purple_account_get_protocol_id(account), "prpl-msn"))
 		return NULL;
 
 	username = g_strdup(purple_normalize(account, purple_account_get_username(account)));
--- a/libpurple/plugins/one_time_password.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/plugins/one_time_password.c	Wed Jun 14 23:40:17 2017 -0500
@@ -121,7 +121,7 @@
 			options = purple_protocol_get_account_options(protocol);
 			while (options != NULL) {
 				option = (PurpleAccountOption *) options->data;
-				if (strcmp(PREF_NAME, purple_account_option_get_setting(option)) == 0) {
+				if (purple_strequal(PREF_NAME, purple_account_option_get_setting(option))) {
 					protocol->account_options = g_list_delete_link(protocol->account_options, options);
 					purple_account_option_destroy(option);
 					break;
--- a/libpurple/plugins/signals-test.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/plugins/signals-test.c	Wed Jun 14 23:40:17 2017 -0500
@@ -675,7 +675,7 @@
 	                  type, id, from, child, child->name,
 	                  purple_xmlnode_get_namespace(child));
 
-	if (g_str_equal(type, "get") || g_str_equal(type, "set")) {
+	if (purple_strequal(type, "get") || purple_strequal(type, "set")) {
 		/* Send the requisite reply */
 		PurpleXmlNode *iq = purple_xmlnode_new("iq");
 		purple_xmlnode_set_attrib(iq, "to", from);
--- a/libpurple/pounce.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/pounce.c	Wed Jun 14 23:40:17 2017 -0500
@@ -730,7 +730,7 @@
 		pouncer = purple_pounce_get_pouncer(pounce);
 		pouncee = purple_pounce_get_pouncee(pounce);
 
-		if ( (pouncer == bacct) && (strcmp(pouncee, bname) == 0) )
+		if ( (pouncer == bacct) && (purple_strequal(pouncee, bname)) )
 			purple_pounce_destroy(pounce);
 	}
 }
--- a/libpurple/protocols/bonjour/bonjour.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/bonjour/bonjour.c	Wed Jun 14 23:40:17 2017 -0500
@@ -509,9 +509,9 @@
 
 	for(; tmp != NULL; tmp = tmp->next) {
 		option = tmp->data;
-		if (strcmp("first", purple_account_option_get_setting(option)) == 0)
+		if (purple_strequal("first", purple_account_option_get_setting(option)))
 			purple_account_option_set_default_string(option, default_firstname);
-		else if (strcmp("last", purple_account_option_get_setting(option)) == 0)
+		else if (purple_strequal("last", purple_account_option_get_setting(option)))
 			purple_account_option_set_default_string(option, default_lastname);
 	}
 
--- a/libpurple/protocols/bonjour/bonjour_ft.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/bonjour/bonjour_ft.c	Wed Jun 14 23:40:17 2017 -0500
@@ -66,14 +66,14 @@
 	purple_xmlnode_set_attrib(error_node, "type", error_type);
 
 	/* TODO: Make this better */
-	if (!strcmp(error_code, "403")) {
+	if (purple_strequal(error_code, "403")) {
 		PurpleXmlNode *tmp_node = purple_xmlnode_new_child(error_node, "forbidden");
 		purple_xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
 
 		tmp_node = purple_xmlnode_new_child(error_node, "text");
 		purple_xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
 		purple_xmlnode_insert_data(tmp_node, "Offer Declined", -1);
-	} else if (!strcmp(error_code, "404")) {
+	} else if (purple_strequal(error_code, "404")) {
 		PurpleXmlNode *tmp_node = purple_xmlnode_new_child(error_node, "item-not-found");
 		purple_xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
 	}
@@ -164,8 +164,8 @@
 		xf = purple_xfer_get_protocol_data(xfer);
 		if(xf == NULL)
 			break;
-		if(xf->sid && purple_xfer_get_remote_user(xfer) && !strcmp(xf->sid, sid) &&
-				!strcmp(purple_xfer_get_remote_user(xfer), from))
+		if(xf->sid && purple_xfer_get_remote_user(xfer) && purple_strequal(xf->sid, sid) &&
+				purple_strequal(purple_xfer_get_remote_user(xfer), from))
 			return xfer;
 	}
 
@@ -451,34 +451,38 @@
 	if(!type)
 		return;
 
-	if(!strcmp(type, "set")) {
-		const char *profile;
+	if(purple_strequal(type, "set")) {
 		PurpleXmlNode *si;
 		gboolean parsed_receive = FALSE;
 
 		si = purple_xmlnode_get_child(packet, "si");
 
 		purple_debug_info("bonjour", "si offer Message type - SET.\n");
-		if (si && (profile = purple_xmlnode_get_attrib(si, "profile"))
-				&& !strcmp(profile, "http://jabber.org/protocol/si/profile/file-transfer")) {
-			const char *filename = NULL, *filesize_str = NULL;
-			goffset filesize = 0;
-			PurpleXmlNode *file;
+		if (si) {
+			const char *profile;
+
+			profile = purple_xmlnode_get_attrib(si, "profile");
 
-			const char *sid = purple_xmlnode_get_attrib(si, "id");
+			if (purple_strequal(profile, "http://jabber.org/protocol/si/profile/file-transfer")) {
+				const char *filename = NULL, *filesize_str = NULL;
+				goffset filesize = 0;
+				PurpleXmlNode *file;
+
+				const char *sid = purple_xmlnode_get_attrib(si, "id");
 
-			if ((file = purple_xmlnode_get_child(si, "file"))) {
-				filename = purple_xmlnode_get_attrib(file, "name");
-				if((filesize_str = purple_xmlnode_get_attrib(file, "size")))
-					filesize = g_ascii_strtoll(filesize_str, NULL, 10);
-			}
+				if ((file = purple_xmlnode_get_child(si, "file"))) {
+					filename = purple_xmlnode_get_attrib(file, "name");
+					if((filesize_str = purple_xmlnode_get_attrib(file, "size")))
+						filesize = g_ascii_strtoll(filesize_str, NULL, 10);
+				}
 
-			/* TODO: Make sure that it is advertising a bytestreams transfer */
+				/* TODO: Make sure that it is advertising a bytestreams transfer */
 
-			if (filename) {
-				bonjour_xfer_receive(pc, id, sid, name, filesize, filename, XEP_BYTESTREAMS);
+				if (filename) {
+					bonjour_xfer_receive(pc, id, sid, name, filesize, filename, XEP_BYTESTREAMS);
 
-				parsed_receive = TRUE;
+					parsed_receive = TRUE;
+				}
 			}
 		}
 
@@ -489,7 +493,7 @@
 			xep_ft_si_reject(bd, id, name, "403", "cancel");
 			/*TODO: Send Cancel (501) */
 		}
-	} else if(!strcmp(type, "result")) {
+	} else if(purple_strequal(type, "result")) {
 		purple_debug_info("bonjour", "si offer Message type - RESULT.\n");
 
 		xfer = bonjour_si_xfer_find(bd, id, name);
@@ -501,7 +505,7 @@
 		} else
 			bonjour_bytestreams_init(xfer);
 
-	} else if(!strcmp(type, "error")) {
+	} else if(purple_strequal(type, "error")) {
 		purple_debug_info("bonjour", "si offer Message type - ERROR.\n");
 
 		xfer = bonjour_si_xfer_find(bd, id, name);
@@ -517,7 +521,7 @@
 /**
  * Will compare a host with a buddy_ip.
  *
- * Additionally to a common '!strcmp(host, buddy_ip)', it will also return TRUE
+ * Additionally to a common 'purple_strequal(host, buddy_ip)', it will also return TRUE
  * if 'host' is a link local IPv6 address without an appended interface
  * identifier and 'buddy_ip' string is "host" + "%iface".
  *
@@ -568,7 +572,7 @@
 
 out:
 #endif
-	return !strcmp(host, buddy_ip);
+	return purple_strequal(host, buddy_ip);
 }
 
 static inline gint
@@ -723,7 +727,7 @@
 	if (!query)
 		return;
 
-	if(strcmp(type, "set")) {
+	if(!purple_strequal(type, "set")) {
 		purple_debug_info("bonjour", "bytestream offer Message type - Unknown-%s.\n", type);
 		return;
 	}
--- a/libpurple/protocols/bonjour/buddy.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/bonjour/buddy.c	Wed Jun 14 23:40:17 2017 -0500
@@ -67,31 +67,31 @@
 
 	g_return_if_fail(record_key != NULL);
 
-	if (!strcmp(record_key, "1st"))
+	if (purple_strequal(record_key, "1st"))
 		fld = &buddy->first;
-	else if(!strcmp(record_key, "email"))
+	else if(purple_strequal(record_key, "email"))
 		fld = &buddy->email;
-	else if(!strcmp(record_key, "ext"))
+	else if(purple_strequal(record_key, "ext"))
 		fld = &buddy->ext;
-	else if(!strcmp(record_key, "jid"))
+	else if(purple_strequal(record_key, "jid"))
 		fld = &buddy->jid;
-	else if(!strcmp(record_key, "last"))
+	else if(purple_strequal(record_key, "last"))
 		fld = &buddy->last;
-	else if(!strcmp(record_key, "msg"))
+	else if(purple_strequal(record_key, "msg"))
 		fld = &buddy->msg;
-	else if(!strcmp(record_key, "nick"))
+	else if(purple_strequal(record_key, "nick"))
 		fld = &buddy->nick;
-	else if(!strcmp(record_key, "node"))
+	else if(purple_strequal(record_key, "node"))
 		fld = &buddy->node;
-	else if(!strcmp(record_key, "phsh"))
+	else if(purple_strequal(record_key, "phsh"))
 		fld = &buddy->phsh;
-	else if(!strcmp(record_key, "status"))
+	else if(purple_strequal(record_key, "status"))
 		fld = &buddy->status;
-	else if(!strcmp(record_key, "vc"))
+	else if(purple_strequal(record_key, "vc"))
 		fld = &buddy->vc;
-	else if(!strcmp(record_key, "ver"))
+	else if(purple_strequal(record_key, "ver"))
 		fld = &buddy->ver;
-	else if(!strcmp(record_key, "AIM"))
+	else if(purple_strequal(record_key, "AIM"))
 		fld = &buddy->AIM;
 
 	if(fld == NULL)
@@ -193,7 +193,7 @@
 	/* Deal with the buddy icon */
 	old_hash = purple_buddy_icons_get_checksum_for_user(buddy);
 	new_hash = (bonjour_buddy->phsh && *(bonjour_buddy->phsh)) ? bonjour_buddy->phsh : NULL;
-	if (new_hash && (!old_hash || strcmp(old_hash, new_hash) != 0)) {
+	if (new_hash && !purple_strequal(old_hash, new_hash)) {
 		/* Look up the new icon data */
 		/* TODO: Make sure the hash assigned to the retrieved buddy icon is the same
 		 * as what we looked up. */
--- a/libpurple/protocols/bonjour/jabber.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/bonjour/jabber.c	Wed Jun 14 23:40:17 2017 -0500
@@ -373,9 +373,9 @@
 	g_return_if_fail(packet != NULL);
 	g_return_if_fail(pb != NULL);
 
-	if (g_strcmp0(packet->name, "message") == 0)
+	if (purple_strequal(packet->name, "message"))
 		_jabber_parse_and_write_message_to_ui(packet, pb);
-	else if (g_strcmp0(packet->name, "iq") == 0)
+	else if (purple_strequal(packet->name, "iq"))
 		xep_iq_parse(packet, pb);
 	else {
 		purple_debug_warning("bonjour", "Unknown packet: %s\n",
@@ -1168,7 +1168,7 @@
 				tmp_next = xfers->next;
 				/* We only need to cancel this if it hasn't actually started transferring. */
 				/* This will change if we ever support IBB transfers. */
-				if (strcmp(purple_xfer_get_remote_user(xfer), purple_buddy_get_name(bconv->pb)) == 0
+				if (purple_strequal(purple_xfer_get_remote_user(xfer), purple_buddy_get_name(bconv->pb))
 						&& (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_NOT_STARTED
 							|| purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_UNKNOWN)) {
 					purple_xfer_cancel_remote(xfer);
--- a/libpurple/protocols/bonjour/mdns_avahi.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/bonjour/mdns_avahi.c	Wed Jun 14 23:40:17 2017 -0500
@@ -71,9 +71,9 @@
 
 	if(rd_a->interface == rd_b->interface
 			&& rd_a->protocol == rd_b->protocol
-			&& !strcmp(rd_a->name, rd_b->name)
-			&& !strcmp(rd_a->type, rd_b->type)
-			&& !strcmp(rd_a->domain, rd_b->domain)) {
+			&& purple_strequal(rd_a->name, rd_b->name)
+			&& purple_strequal(rd_a->type, rd_b->type)
+			&& purple_strequal(rd_a->domain, rd_b->domain)) {
 		ret = 0;
 	}
 
@@ -185,7 +185,7 @@
 			purple_debug_info("bonjour", "_resolve_callback - name:%s ip:%s prev_ip:%s\n",
 				name, ip, rd->ip);
 
-			if (rd->ip == NULL || strcmp(rd->ip, ip) != 0) {
+			if (rd->ip == NULL || !purple_strequal(rd->ip, ip)) {
 				/* We store duplicates in bb->ips, so we always remove the one */
 				if (rd->ip != NULL) {
 					bb->ips = g_slist_remove(bb->ips, rd->ip);
--- a/libpurple/protocols/bonjour/mdns_dns_sd.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/bonjour/mdns_dns_sd.c	Wed Jun 14 23:40:17 2017 -0500
@@ -79,9 +79,9 @@
 	gint ret = 1;
 
 	if(rd_a->if_idx == rd_b->if_idx
-			&& !strcmp(rd_a->name, rd_b->name)
-			&& !strcmp(rd_a->type, rd_b->type)
-			&& !strcmp(rd_a->domain, rd_b->domain)) {
+			&& purple_strequal(rd_a->name, rd_b->name)
+			&& purple_strequal(rd_a->type, rd_b->type)
+			&& purple_strequal(rd_a->domain, rd_b->domain)) {
 		ret = 0;
 	}
 
@@ -358,7 +358,7 @@
 				else {
 					while (tmp) {
 						BonjourBuddy *bb_tmp = tmp->data;
-						if (!strcmp(bb_tmp->name, serviceName)) {
+						if (purple_strequal(bb_tmp->name, serviceName)) {
 							bb = bb_tmp;
 							break;
 						}
--- a/libpurple/protocols/gg/gg.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/gg/gg.c	Wed Jun 14 23:40:17 2017 -0500
@@ -706,9 +706,9 @@
 		"opportunistic_tls");
 	purple_debug_info("gg", "Requested encryption type: %s\n",
 		encryption_type);
-	if (strcmp(encryption_type, "opportunistic_tls") == 0)
+	if (purple_strequal(encryption_type, "opportunistic_tls"))
 		glp->tls = GG_SSL_ENABLED;
-	else if (strcmp(encryption_type, "require_tls") == 0) {
+	else if (purple_strequal(encryption_type, "require_tls")) {
 		if (gg_libgadu_check_feature(GG_LIBGADU_FEATURE_SSL))
 			glp->tls = GG_SSL_REQUIRED;
 		else {
@@ -728,9 +728,9 @@
 		"protocol_version", "default");
 	purple_debug_info("gg", "Requested protocol version: %s\n",
 		protocol_version);
-	if (g_strcmp0(protocol_version, "gg10") == 0)
+	if (purple_strequal(protocol_version, "gg10"))
 		glp->protocol_version = GG_PROTOCOL_VERSION_100;
-	else if (g_strcmp0(protocol_version, "gg11") == 0)
+	else if (purple_strequal(protocol_version, "gg11"))
 		glp->protocol_version = GG_PROTOCOL_VERSION_110;
 	glp->compatibility = GG_COMPAT_1_12_0;
 
@@ -828,7 +828,7 @@
 	gg_add_notify(info->session, ggp_str_to_uin(name));
 
 	/* gg server won't tell us our status here */
-	if (strcmp(purple_account_get_username(account), name) == 0)
+	if (purple_strequal(purple_account_get_username(account), name))
 		ggp_status_fake_to_self(gc);
 
 	ggp_roster_add_buddy(gc, buddy, group, message);
--- a/libpurple/protocols/irc/cmds.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/irc/cmds.c	Wed Jun 14 23:40:17 2017 -0500
@@ -51,7 +51,7 @@
 {
 	char *buf, *message;
 
-	if (args[0] && strcmp(cmd, "back")) {
+	if (args[0] && !purple_strequal(cmd, "back")) {
 		message = purple_markup_strip_html(args[0]);
 		purple_util_chrreplace(message, '\n', ' ');
 		buf = irc_format(irc, "v:", "AWAY", message);
@@ -277,7 +277,7 @@
 	if (!args)
 		return 0;
 
-	if (!strcmp(cmd, "mode")) {
+	if (purple_strequal(cmd, "mode")) {
 		if (!args[0] && irc_ischannel(target))
 			buf = irc_format(irc, "vc", "MODE", target);
 		else if (args[0] && (*args[0] == '+' || *args[0] == '-'))
@@ -286,7 +286,7 @@
 			buf = irc_format(irc, "vn", "MODE", args[0]);
 		else
 			return 0;
-	} else if (!strcmp(cmd, "umode")) {
+	} else if (purple_strequal(cmd, "umode")) {
 		if (!args[0])
 			return 0;
 		gc = purple_account_get_connection(irc->account);
@@ -340,16 +340,16 @@
 	if (!args || !args[0] || !*args[0])
 		return 0;
 
-	if (!strcmp(cmd, "op")) {
+	if (purple_strequal(cmd, "op")) {
 		sign = "+";
 		mode = "o";
-	} else if (!strcmp(cmd, "deop")) {
+	} else if (purple_strequal(cmd, "deop")) {
 		sign = "-";
 		mode = "o";
-	} else if (!strcmp(cmd, "voice")) {
+	} else if (purple_strequal(cmd, "voice")) {
 		sign = "+";
 		mode = "v";
-	} else if (!strcmp(cmd, "devoice")) {
+	} else if (purple_strequal(cmd, "devoice")) {
 		sign = "-";
 		mode = "v";
 	} else {
@@ -447,7 +447,7 @@
 
 		msg = g_strndup(cur, end - cur);
 
-		if(!strcmp(cmd, "notice"))
+		if(purple_strequal(cmd, "notice"))
 			buf = irc_format(irc, "vt:", "NOTICE", args[0], msg);
 		else
 			buf = irc_format(irc, "vt:", "PRIVMSG", args[0], msg);
@@ -619,9 +619,9 @@
 	if (!args || !args[0])
 		return 0;
 
-	if (!strcmp(cmd, "wallops"))
+	if (purple_strequal(cmd, "wallops"))
 		buf = irc_format(irc, "v:", "WALLOPS", args[0]);
-	else if (!strcmp(cmd, "operwall"))
+	else if (purple_strequal(cmd, "operwall"))
 		buf = irc_format(irc, "v:", "OPERWALL", args[0]);
 	else
 		return 0;
--- a/libpurple/protocols/irc/irc.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/irc/irc.c	Wed Jun 14 23:40:17 2017 -0500
@@ -119,12 +119,12 @@
 
 int irc_send_len(struct irc_conn *irc, const char *buf, int buflen)
 {
- 	char *tosend= g_strdup(buf);
+ 	char *tosend = g_strdup(buf);
 	int len;
 	GBytes *data;
 
 	purple_signal_emit(_irc_protocol, "irc-sending-text", purple_account_get_connection(irc->account), &tosend);
-	
+
 	if (tosend == NULL)
 		return 0;
 
@@ -529,12 +529,12 @@
 
 	args[0] = NULL;
 
-	if (!strcmp(status_id, "away")) {
+	if (purple_strequal(status_id, "away")) {
 		args[0] = purple_status_get_attr_string(status, "message");
 		if ((args[0] == NULL) || (*args[0] == '\0'))
 			args[0] = _("Away");
 		irc_cmd_away(irc, "away", NULL, args);
-	} else if (!strcmp(status_id, "available")) {
+	} else if (purple_strequal(status_id, "available")) {
 		irc_cmd_away(irc, "back", NULL, args);
 	}
 }
--- a/libpurple/protocols/irc/msgs.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/irc/msgs.c	Wed Jun 14 23:40:17 2017 -0500
@@ -220,13 +220,13 @@
 
 void irc_msg_luser(struct irc_conn *irc, const char *name, const char *from, char **args)
 {
-	if (!strcmp(name, "251")) {
+	if (purple_strequal(name, "251")) {
 		/* 251 is required, so we pluck our nick from here and
 		 * finalize connection */
 		irc_connected(irc, args[0]);
 		/* Some IRC servers seem to not send a 255 numeric, so
 		 * I guess we can't require it; 251 will do. */
-	/* } else if (!strcmp(name, "255")) { */
+	/* } else if (purple_strequal(name, "255")) { */
 	}
 }
 
@@ -265,7 +265,7 @@
 
 	chat = purple_conversations_find_chat_with_account(args[1], irc->account);
 
-	if (!strcmp(name, "367")) {
+	if (purple_strequal(name, "367")) {
 		char *msg = NULL;
 		/* Ban list entry */
 		if (args[3] && args[4]) {
@@ -286,7 +286,7 @@
 			purple_debug_info("irc", "%s\n", msg);
 		}
 		g_free(msg);
-	} else if (!strcmp(name, "368")) {
+	} else if (purple_strequal(name, "368")) {
 		if (!chat)
 			return;
 		/* End of ban list */
@@ -346,44 +346,44 @@
 void irc_msg_whois(struct irc_conn *irc, const char *name, const char *from, char **args)
 {
 	if (!irc->whois.nick) {
-		purple_debug(PURPLE_DEBUG_WARNING, "irc", "Unexpected %s reply for %s\n", !strcmp(name, "314") ? "WHOWAS" : "WHOIS"
+		purple_debug(PURPLE_DEBUG_WARNING, "irc", "Unexpected %s reply for %s\n", purple_strequal(name, "314") ? "WHOWAS" : "WHOIS"
 											   , args[1]);
 		return;
 	}
 
 	if (purple_utf8_strcasecmp(irc->whois.nick, args[1])) {
-		purple_debug(PURPLE_DEBUG_WARNING, "irc", "Got %s reply for %s while waiting for %s\n", !strcmp(name, "314") ? "WHOWAS" : "WHOIS"
+		purple_debug(PURPLE_DEBUG_WARNING, "irc", "Got %s reply for %s while waiting for %s\n", purple_strequal(name, "314") ? "WHOWAS" : "WHOIS"
 												      , args[1], irc->whois.nick);
 		return;
 	}
 
-	if (!strcmp(name, "301")) {
+	if (purple_strequal(name, "301")) {
 		irc->whois.away = g_strdup(args[2]);
-	} else if (!strcmp(name, "311") || !strcmp(name, "314")) {
+	} else if (purple_strequal(name, "311") || purple_strequal(name, "314")) {
 		irc->whois.ident = g_strdup(args[2]);
 		irc->whois.host = g_strdup(args[3]);
 		irc->whois.real = g_strdup(args[5]);
-	} else if (!strcmp(name, "312")) {
+	} else if (purple_strequal(name, "312")) {
 		irc->whois.server = g_strdup(args[2]);
 		irc->whois.serverinfo = g_strdup(args[3]);
-	} else if (!strcmp(name, "313")) {
+	} else if (purple_strequal(name, "313")) {
 		irc->whois.ircop = 1;
-	} else if (!strcmp(name, "317")) {
+	} else if (purple_strequal(name, "317")) {
 		irc->whois.idle = atoi(args[2]);
 		if (args[3])
 			irc->whois.signon = (time_t)atoi(args[3]);
-	} else if (!strcmp(name, "319")) {
+	} else if (purple_strequal(name, "319")) {
 		if (irc->whois.channels == NULL) {
 			irc->whois.channels = g_string_new(args[2]);
 		} else {
 			irc->whois.channels = g_string_append(irc->whois.channels, args[2]);
 		}
-	} else if (!strcmp(name, "320")) {
+	} else if (purple_strequal(name, "320")) {
 		irc->whois.identified = 1;
-	} else if (!strcmp(name, "330")) {
+	} else if (purple_strequal(name, "330")) {
 		purple_debug(PURPLE_DEBUG_INFO, "irc", "330 %s: 1=[%s] 2=[%s] 3=[%s]",
 				name, args[1], args[2], args[3]);
-		if (!strcmp(args[3], "is logged in as"))
+		if (purple_strequal(args[3], "is logged in as"))
 			irc->whois.login = g_strdup(args[2]);
 	}
 }
@@ -395,12 +395,12 @@
 	PurpleNotifyUserInfo *user_info;
 
 	if (!irc->whois.nick) {
-		purple_debug(PURPLE_DEBUG_WARNING, "irc", "Unexpected End of %s for %s\n", !strcmp(name, "369") ? "WHOWAS" : "WHOIS"
+		purple_debug(PURPLE_DEBUG_WARNING, "irc", "Unexpected End of %s for %s\n", purple_strequal(name, "369") ? "WHOWAS" : "WHOIS"
 											     , args[1]);
 		return;
 	}
 	if (purple_utf8_strcasecmp(irc->whois.nick, args[1])) {
-		purple_debug(PURPLE_DEBUG_WARNING, "irc", "Received end of %s for %s, expecting %s\n", !strcmp(name, "369") ? "WHOWAS" : "WHOIS"
+		purple_debug(PURPLE_DEBUG_WARNING, "irc", "Received end of %s for %s, expecting %s\n", purple_strequal(name, "369") ? "WHOWAS" : "WHOIS"
 													 , args[1], irc->whois.nick);
 		return;
 	}
@@ -453,7 +453,7 @@
 		purple_notify_user_info_add_pair_plaintext(user_info,
 														_("Online since"), purple_date_format_full(localtime(&irc->whois.signon)));
 	}
-	if (!strcmp(irc->whois.nick, "elb")) {
+	if (purple_strequal(irc->whois.nick, "elb")) {
 		purple_notify_user_info_add_pair_plaintext(user_info,
 																   _("<b>Defining adjective:</b>"), _("Glorious"));
 	}
@@ -469,12 +469,12 @@
 
 void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char **args)
 {
-	if (!strcmp(name, "352")) {
+	if (purple_strequal(name, "352")) {
 		PurpleChatConversation *chat;
 		PurpleChatUser *cb;
-		
+
 		char *cur, *userhost, *realname;
-		
+
 		PurpleChatUserFlags flags;
 
 		chat = purple_conversations_find_chat_with_account(args[1], irc->account);
@@ -500,10 +500,10 @@
 			}
 		}
 		realname = g_strdup(cur);
-		
+
 		g_object_set_data_full(G_OBJECT(cb), "userhost", userhost, (GDestroyNotify)g_free);
 		g_object_set_data_full(G_OBJECT(cb), "realname", realname, (GDestroyNotify)g_free);
-		
+
 		flags = purple_chat_user_get_flags(cb);
 
 		/* FIXME: I'm not sure this is really a good idea, now
@@ -523,19 +523,19 @@
 	if (!irc->roomlist)
 		return;
 
-	if (!strcmp(name, "321")) {
+	if (purple_strequal(name, "321")) {
 		purple_roomlist_set_in_progress(irc->roomlist, TRUE);
 		return;
 	}
 
-	if (!strcmp(name, "323")) {
+	if (purple_strequal(name, "323")) {
 		purple_roomlist_set_in_progress(irc->roomlist, FALSE);
 		g_object_unref(irc->roomlist);
 		irc->roomlist = NULL;
 		return;
 	}
 
-	if (!strcmp(name, "322")) {
+	if (purple_strequal(name, "322")) {
 		PurpleRoomlistRoom *room;
 		char *topic;
 
@@ -559,7 +559,7 @@
 	char *chan, *topic, *msg, *nick, *tmp, *tmp2;
 	PurpleChatConversation *chat;
 
-	if (!strcmp(name, "topic")) {
+	if (purple_strequal(name, "topic")) {
 		chan = args[0];
 		topic = irc_mirc2txt (args[1]);
 	} else {
@@ -578,9 +578,9 @@
 	tmp = g_markup_escape_text(topic, -1);
 	tmp2 = purple_markup_linkify(tmp);
 	g_free(tmp);
-	if (!strcmp(name, "topic")) {
+	if (purple_strequal(name, "topic")) {
 		const char *current_topic = purple_chat_conversation_get_topic(chat);
-		if (!(current_topic != NULL && strcmp(tmp2, current_topic) == 0))
+		if (!(current_topic != NULL && purple_strequal(tmp2, current_topic)))
 		{
 			char *nick_esc;
 			nick = irc_mask_nick(from);
@@ -657,7 +657,7 @@
 	char *names, *cur, *end, *tmp, *msg;
 	PurpleConversation *convo;
 
-	if (!strcmp(name, "366")) {
+	if (purple_strequal(name, "366")) {
 		convo = purple_conversations_find_with_account(args[1], irc->account);
 		if (!convo) {
 			purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a NAMES list for %s, which doesn't exist\n", args[1]);
@@ -734,17 +734,17 @@
 {
 	char *escaped;
 
-	if (!strcmp(name, "375")) {
+	if (purple_strequal(name, "375")) {
 		if (irc->motd)
 			g_string_free(irc->motd, TRUE);
 		irc->motd = g_string_new("");
 		return;
-	} else if (!strcmp(name, "376")) {
+	} else if (purple_strequal(name, "376")) {
 		/* dircproxy 1.0.5 does not send 251 on reconnection, so
 		 * finalize the connection here if it is not already done. */
 		irc_connected(irc, args[0]);
 		return;
-	} else if (!strcmp(name, "422")) {
+	} else if (purple_strequal(name, "422")) {
 		/* in case there is no 251, and no MOTD set, finalize the connection.
 		 * (and clear the motd for good measure). */
 
@@ -951,12 +951,12 @@
 		}
 		g_object_set_data(G_OBJECT(chat), IRC_NAMES_FLAG,
 					   GINT_TO_POINTER(FALSE));
-		
+
 		// Get the real name and user host for all participants.
 		buf = irc_format(irc, "vc", "WHO", args[0]);
 		irc_send(irc, buf);
 		g_free(buf);
-		
+
 		/* Until purple_conversation_present does something that
 		 * one would expect in Pidgin, this call produces buggy
 		 * behavior both for the /join and auto-join cases. */
@@ -972,15 +972,15 @@
 	}
 
 	userhost = irc_mask_userhost(from);
-	
+
 	purple_chat_conversation_add_user(chat, nick, userhost, PURPLE_CHAT_USER_NONE, TRUE);
-	
+
 	cb = purple_chat_conversation_find_user(chat, nick);
-	
+
 	if (cb) {
 		g_object_set_data_full(G_OBJECT(cb), "userhost", userhost, (GDestroyNotify)g_free);
 	}
-	
+
 	if ((ib = g_hash_table_lookup(irc->buddies, nick)) != NULL) {
 		ib->new_online_status = TRUE;
 		irc_buddy_status(nick, ib, irc);
@@ -1567,7 +1567,7 @@
 	char *pos;
 	size_t index;
 
-	if (strncmp(args[2], "sasl ", 6))
+	if (strncmp(g_strstrip(args[2]), "sasl", 5))
 		return;
 	if (strncmp(args[1], "ACK", 4)) {
 		purple_connection_take_error(gc, g_error_new_literal(
--- a/libpurple/protocols/jabber/adhoccommands.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/adhoccommands.c	Wed Jun 14 23:40:17 2017 -0500
@@ -74,7 +74,7 @@
 		JabberAdHocCommands *cmd;
 		if(item->type != PURPLE_XMLNODE_TYPE_TAG)
 			continue;
-		if(strcmp(item->name, "item"))
+		if(!purple_strequal(item->name, "item"))
 			continue;
 		cmd = g_new0(JabberAdHocCommands, 1);
 
@@ -170,7 +170,7 @@
 	if(!status)
 		return;
 
-	if(!strcmp(status,"completed")) {
+	if(purple_strequal(status,"completed")) {
 		/* display result */
 		PurpleXmlNode *note = purple_xmlnode_get_child(command,"note");
 
@@ -185,7 +185,7 @@
 			jabber_x_data_request(js, xdata, (jabber_x_data_cb)do_adhoc_ignoreme, NULL);
 		return;
 	}
-	if(!strcmp(status,"executing")) {
+	if(purple_strequal(status,"executing")) {
 		/* this command needs more steps */
 		PurpleXmlNode *actions, *action;
 		int actionindex = 0;
@@ -209,7 +209,7 @@
 					newaction->name = g_strdup(_(action->name));
 					newaction->handle = g_strdup(action->name);
 					actionslist = g_list_append(actionslist, newaction);
-					if(defaultactionhandle && !strcmp(defaultactionhandle, action->name))
+					if(defaultactionhandle && purple_strequal(defaultactionhandle, action->name))
 						actionindex = index;
 				}
 			}
@@ -260,7 +260,7 @@
 		JabberAdHocCommands *cmd;
 		if(item->type != PURPLE_XMLNODE_TYPE_TAG)
 			continue;
-		if(strcmp(item->name, "item"))
+		if(!purple_strequal(item->name, "item"))
 			continue;
 		cmd = g_new0(JabberAdHocCommands, 1);
 		cmd->jid = g_strdup(purple_xmlnode_get_attrib(item,"jid"));
--- a/libpurple/protocols/jabber/auth.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/auth.c	Wed Jun 14 23:40:17 2017 -0500
@@ -166,7 +166,7 @@
 		JabberSaslMech *possible = l->data;
 
 		/* Is this the Cyrus SASL mechanism? */
-		if (g_str_equal(possible->name, "*")) {
+		if (purple_strequal(possible->name, "*")) {
 			js->auth_mech = possible;
 			break;
 		}
@@ -223,7 +223,7 @@
 		/* FIXME: Why is this not in jabber_parse_error? */
 		if((error = purple_xmlnode_get_child(packet, "error")) &&
 					(err_code = purple_xmlnode_get_attrib(error, "code")) &&
-					g_str_equal(err_code, "401")) {
+					purple_strequal(err_code, "401")) {
 			reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
 			/* Clear the pasword if it isn't being saved */
 			if (!purple_account_get_remember_password(account))
@@ -342,7 +342,7 @@
 	 * is requiring SSL/TLS, we need to enforce it.
 	 */
 	if (!jabber_stream_is_ssl(js) &&
-			g_str_equal("require_tls",
+			purple_strequal("require_tls",
 				purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
 		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
--- a/libpurple/protocols/jabber/auth_cyrus.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/auth_cyrus.c	Wed Jun 14 23:40:17 2017 -0500
@@ -271,7 +271,7 @@
 					js->auth_fail_count++;
 
 				if (js->auth_fail_count == 1 &&
-					(js->sasl_mechs->str && g_str_equal(js->sasl_mechs->str, "GSSAPI"))) {
+					purple_strequal(js->sasl_mechs->str, "GSSAPI")) {
 					/* If we tried GSSAPI first, it failed, and it was the only method we had to try, try jabber:iq:auth
 					 * for compatibility with iChat 10.5 Server and other jabberd based servers.
 					 *
@@ -420,7 +420,7 @@
 		 * mechanisms"...  Easiest just to blacklist it (for now).
 		 */
 		if (!mech_name || !*mech_name ||
-				g_str_equal(mech_name, "EXTERNAL")) {
+				purple_strequal(mech_name, "EXTERNAL")) {
 			g_free(mech_name);
 			continue;
 		}
@@ -565,7 +565,7 @@
 			return jabber_auth_start_cyrus(js, reply, error);
 
 		} else if ((js->auth_fail_count == 1) &&
-				   (js->current_mech && g_str_equal(js->current_mech, "GSSAPI"))) {
+				   purple_strequal(js->current_mech, "GSSAPI")) {
 			/* If we tried GSSAPI first, it failed, and it was the only method we had to try, try jabber:iq:auth
 			 * for compatibility with iChat 10.5 Server and other jabberd based servers.
 			 *
--- a/libpurple/protocols/jabber/auth_scram.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/auth_scram.c	Wed Jun 14 23:40:17 2017 -0500
@@ -131,12 +131,12 @@
  * is the hash algorithm.  All buffers must be of the appropriate size
  * according to the JabberScramHash.
  *
- * "str" is a NULL-terminated string for hmac().
+ * "str" is a NULL-terminated string for jabber_scram_hmac().
  *
  * Needless to say, these are fragile.
  */
 static void
-hmac(const JabberScramHash *hash, guchar *out, const guchar *key, const gchar *str)
+jabber_scram_hmac(const JabberScramHash *hash, guchar *out, const guchar *key, const gchar *str)
 {
 	GHmac *hmac;
 	gsize digest_len = g_checksum_type_get_length(hash->type);
@@ -148,7 +148,7 @@
 }
 
 static void
-hash(const JabberScramHash *hash, guchar *out, const guchar *data)
+jabber_scram_hash(const JabberScramHash *hash, guchar *out, const guchar *data)
 {
 	GChecksum *checksum;
 	gsize digest_len = g_checksum_type_get_length(hash->type);
@@ -189,18 +189,18 @@
 	server_key = g_new0(guchar, hash_len);
 
 	/* client_key = HMAC(salted_password, "Client Key") */
-	hmac(data->hash, client_key, salted_password, "Client Key");
+	jabber_scram_hmac(data->hash, client_key, salted_password, "Client Key");
 	/* server_key = HMAC(salted_password, "Server Key") */
-	hmac(data->hash, server_key, salted_password, "Server Key");
+	jabber_scram_hmac(data->hash, server_key, salted_password, "Server Key");
 	g_free(salted_password);
 
 	/* stored_key = HASH(client_key) */
-	hash(data->hash, stored_key, client_key);
+	jabber_scram_hash(data->hash, stored_key, client_key);
 
 	/* client_signature = HMAC(stored_key, auth_message) */
-	hmac(data->hash, client_signature, stored_key, data->auth_message->str);
+	jabber_scram_hmac(data->hash, client_signature, stored_key, data->auth_message->str);
 	/* server_signature = HMAC(server_key, auth_message) */
-	hmac(data->hash, (guchar *)data->server_signature->str, server_key, data->auth_message->str);
+	jabber_scram_hmac(data->hash, (guchar *)data->server_signature->str, server_key, data->auth_message->str);
 
 	/* client_proof = client_key XOR client_signature */
 	for (i = 0; i < hash_len; ++i)
--- a/libpurple/protocols/jabber/bosh.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/bosh.c	Wed Jun 14 23:40:17 2017 -0500
@@ -203,7 +203,7 @@
 	root = purple_xmlnode_from_str(data, data_len);
 
 	type = purple_xmlnode_get_attrib(root, "type");
-	if (g_strcmp0(type, "terminate") == 0) {
+	if (purple_strequal(type, "terminate")) {
 		purple_connection_error(conn->js->gc,
 			PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("The BOSH "
 			"connection manager terminated your session."));
@@ -245,10 +245,10 @@
 		 * the right xmlns on these packets. See #11315.
 		 */
 		xmlns = purple_xmlnode_get_namespace(child);
-		if ((xmlns == NULL || g_strcmp0(xmlns, NS_BOSH) == 0) &&
-			(g_strcmp0(child->name, "iq") == 0 ||
-			g_strcmp0(child->name, "message") == 0 ||
-			g_strcmp0(child->name, "presence") == 0))
+		if ((xmlns == NULL || purple_strequal(xmlns, NS_BOSH)) &&
+			(purple_strequal(child->name, "iq") ||
+			purple_strequal(child->name, "message") ||
+			purple_strequal(child->name, "presence")))
 		{
 			purple_xmlnode_set_namespace(child, NS_XMPP_CLIENT);
 		}
--- a/libpurple/protocols/jabber/buddy.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/buddy.c	Wed Jun 14 23:40:17 2017 -0500
@@ -218,7 +218,7 @@
 	for (l = jb->resources; l; l = l->next)
 	{
 		JabberBuddyResource *jbr = l->data;
-		if (jbr->name && g_str_equal(resource, jbr->name))
+		if (purple_strequal(resource, jbr->name))
 			return jbr;
 	}
 
@@ -407,7 +407,7 @@
 		const struct vcard_template *vc_tp = vcard_template_data;
 
 		while(vc_tp->label != NULL) {
-			if(strcmp(vc_tp->tag, new_tag) == 0) {
+			if(purple_strequal(vc_tp->tag, new_tag)) {
 				parent_tag = vc_tp->ptag;
 				break;
 			}
@@ -667,7 +667,7 @@
 				cdata = purple_xmlnode_get_data(data_node);
 		}
 
-		if(strcmp(vc_tp->tag, "DESC") == 0) {
+		if(purple_strequal(vc_tp->tag, "DESC")) {
 			field = purple_request_field_string_new(vc_tp->tag,
 												  _(vc_tp->label), cdata,
 												  TRUE);
@@ -899,7 +899,7 @@
 
 	while(l) {
 		comp_id = l->data;
-		if(!strcmp(id, comp_id)) {
+		if(purple_strequal(id, comp_id)) {
 			jbi->ids = g_slist_remove(jbi->ids, comp_id);
 			g_free(comp_id);
 			return;
@@ -1042,12 +1042,12 @@
 				continue;
 
 			text = purple_xmlnode_get_data(child);
-			if(text && !strcmp(child->name, "FN")) {
+			if(text && purple_strequal(child->name, "FN")) {
 				if (!serverside_alias)
 					serverside_alias = g_strdup(text);
 
 				purple_notify_user_info_add_pair_plaintext(user_info, _("Full Name"), text);
-			} else if(!strcmp(child->name, "N")) {
+			} else if(purple_strequal(child->name, "N")) {
 				for(child2 = child->child; child2; child2 = child2->next)
 				{
 					char *text2;
@@ -1056,16 +1056,16 @@
 						continue;
 
 					text2 = purple_xmlnode_get_data(child2);
-					if(text2 && !strcmp(child2->name, "FAMILY")) {
+					if(text2 && purple_strequal(child2->name, "FAMILY")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Family Name"), text2);
-					} else if(text2 && !strcmp(child2->name, "GIVEN")) {
+					} else if(text2 && purple_strequal(child2->name, "GIVEN")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Given Name"), text2);
-					} else if(text2 && !strcmp(child2->name, "MIDDLE")) {
+					} else if(text2 && purple_strequal(child2->name, "MIDDLE")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Middle Name"), text2);
 					}
 					g_free(text2);
 				}
-			} else if(text && !strcmp(child->name, "NICKNAME")) {
+			} else if(text && purple_strequal(child->name, "NICKNAME")) {
 				/* Prefer the Nickcname to the Full Name as the serverside alias if it's not just part of the jid.
 				 * Ignore it if it's part of the jid. */
 				if (strstr(bare_jid, text) == NULL) {
@@ -1074,9 +1074,9 @@
 
 					purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), text);
 				}
-			} else if(text && !strcmp(child->name, "BDAY")) {
+			} else if(text && purple_strequal(child->name, "BDAY")) {
 				purple_notify_user_info_add_pair_plaintext(user_info, _("Birthday"), text);
-			} else if(!strcmp(child->name, "ADR")) {
+			} else if(purple_strequal(child->name, "ADR")) {
 				gboolean address_line_added = FALSE;
 
 				for(child2 = child->child; child2; child2 = child2->next)
@@ -1098,25 +1098,25 @@
 						address_line_added = TRUE;
 					}
 
-					if(!strcmp(child2->name, "POBOX")) {
+					if(purple_strequal(child2->name, "POBOX")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("P.O. Box"), text2);
-					} else if (g_str_equal(child2->name, "EXTADD") || g_str_equal(child2->name, "EXTADR")) {
+					} else if (purple_strequal(child2->name, "EXTADD") || purple_strequal(child2->name, "EXTADR")) {
 						/*
 						 * EXTADD is correct, EXTADR is generated by other
 						 * clients. The next time someone reads this, remove
 						 * EXTADR.
 						 */
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Extended Address"), text2);
-					} else if(!strcmp(child2->name, "STREET")) {
+					} else if(purple_strequal(child2->name, "STREET")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Street Address"), text2);
-					} else if(!strcmp(child2->name, "LOCALITY")) {
+					} else if(purple_strequal(child2->name, "LOCALITY")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Locality"), text2);
-					} else if(!strcmp(child2->name, "REGION")) {
+					} else if(purple_strequal(child2->name, "REGION")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Region"), text2);
-					} else if(!strcmp(child2->name, "PCODE")) {
+					} else if(purple_strequal(child2->name, "PCODE")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Postal Code"), text2);
-					} else if(!strcmp(child2->name, "CTRY")
-								|| !strcmp(child2->name, "COUNTRY")) {
+					} else if(purple_strequal(child2->name, "CTRY")
+								|| purple_strequal(child2->name, "COUNTRY")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Country"), text2);
 					}
 					g_free(text2);
@@ -1125,7 +1125,7 @@
 				if (address_line_added)
 					purple_notify_user_info_add_section_break(user_info);
 
-			} else if(!strcmp(child->name, "TEL")) {
+			} else if(purple_strequal(child->name, "TEL")) {
 				char *number;
 				if((child2 = purple_xmlnode_get_child(child, "NUMBER"))) {
 					/* show what kind of number it is */
@@ -1140,7 +1140,7 @@
 					purple_notify_user_info_add_pair_plaintext(user_info, _("Telephone"), number);
 					g_free(number);
 				}
-			} else if(!strcmp(child->name, "EMAIL")) {
+			} else if(purple_strequal(child->name, "EMAIL")) {
 				char *userid, *escaped;
 				if((child2 = purple_xmlnode_get_child(child, "USERID"))) {
 					/* show what kind of email it is */
@@ -1168,7 +1168,7 @@
 					g_free(escaped);
 					g_free(userid);
 				}
-			} else if(!strcmp(child->name, "ORG")) {
+			} else if(purple_strequal(child->name, "ORG")) {
 				for(child2 = child->child; child2; child2 = child2->next)
 				{
 					char *text2;
@@ -1177,21 +1177,21 @@
 						continue;
 
 					text2 = purple_xmlnode_get_data(child2);
-					if(text2 && !strcmp(child2->name, "ORGNAME")) {
+					if(text2 && purple_strequal(child2->name, "ORGNAME")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Organization Name"), text2);
-					} else if(text2 && !strcmp(child2->name, "ORGUNIT")) {
+					} else if(text2 && purple_strequal(child2->name, "ORGUNIT")) {
 						purple_notify_user_info_add_pair_plaintext(user_info, _("Organization Unit"), text2);
 					}
 					g_free(text2);
 				}
-			} else if(text && !strcmp(child->name, "TITLE")) {
+			} else if(text && purple_strequal(child->name, "TITLE")) {
 				purple_notify_user_info_add_pair_plaintext(user_info, _("Job Title"), text);
-			} else if(text && !strcmp(child->name, "ROLE")) {
+			} else if(text && purple_strequal(child->name, "ROLE")) {
 				purple_notify_user_info_add_pair_plaintext(user_info, _("Role"), text);
-			} else if(text && !strcmp(child->name, "DESC")) {
+			} else if(text && purple_strequal(child->name, "DESC")) {
 				purple_notify_user_info_add_pair_plaintext(user_info, _("Description"), text);
-			} else if(!strcmp(child->name, "PHOTO") ||
-					!strcmp(child->name, "LOGO")) {
+			} else if(purple_strequal(child->name, "PHOTO") ||
+					purple_strequal(child->name, "LOGO")) {
 				char *bintext = NULL;
 				PurpleXmlNode *binval;
 
@@ -1199,7 +1199,7 @@
 						(bintext = purple_xmlnode_get_data(binval))) {
 					gsize size;
 					guchar *data;
-					gboolean photo = (strcmp(child->name, "PHOTO") == 0);
+					gboolean photo = purple_strequal(child->name, "PHOTO");
 
 					data = g_base64_decode(bintext, &size);
 					if (data) {
@@ -1512,12 +1512,12 @@
 	if(!jbr->client.name)
 		return FALSE;
 
-	if(!strcmp(ns, NS_LAST_ACTIVITY)) {
-		if(!strcmp(jbr->client.name, "Trillian")) {
+	if(purple_strequal(ns, NS_LAST_ACTIVITY)) {
+		if(purple_strequal(jbr->client.name, "Trillian")) {
 			/* verified by nwalp 2007/05/09 */
-			if(!strcmp(jbr->client.version, "3.1.0.121") ||
+			if(purple_strequal(jbr->client.version, "3.1.0.121") ||
 					/* verified by nwalp 2007/09/19 */
-					!strcmp(jbr->client.version, "3.1.7.0")) {
+					purple_strequal(jbr->client.version, "3.1.7.0")) {
 				return TRUE;
 			}
 		}
@@ -2005,7 +2005,7 @@
 						field = purple_xmlnode_get_next_twin(field))
 				{
 					if ((var = purple_xmlnode_get_attrib(field, "var")) &&
-							!strcmp(var, l->data) &&
+							purple_strequal(var, l->data) &&
 							(valuenode = purple_xmlnode_get_child(field, "value")))
 					{
 						char *value = purple_xmlnode_get_data(valuenode);
@@ -2076,7 +2076,7 @@
 	 * just going to get an error if we send
 	 * a cancel, so skip it */
 	type = purple_xmlnode_get_attrib(result, "type");
-	if(type && !strcmp(type, "cancel")) {
+	if(purple_strequal(type, "cancel")) {
 		g_free(dir_server);
 		return;
 	}
@@ -2120,7 +2120,7 @@
 			const char *id = purple_request_field_get_id(field);
 			const char *value = purple_request_field_string_get_value(field);
 
-			if(value && (!strcmp(id, "first") || !strcmp(id, "last") || !strcmp(id, "nick") || !strcmp(id, "email"))) {
+			if(value && (purple_strequal(id, "first") || purple_strequal(id, "last") || purple_strequal(id, "nick") || purple_strequal(id, "email"))) {
 				PurpleXmlNode *y = purple_xmlnode_new_child(query, id);
 				purple_xmlnode_insert_data(y, value, -1);
 			}
@@ -2266,7 +2266,7 @@
 	/* If the value provided isn't the disco#info default, persist it.  Otherwise,
 	   make sure we aren't persisting an old value */
 	if(js->user_directories && js->user_directories->data &&
-	   !strcmp(directory, js->user_directories->data)) {
+	   purple_strequal(directory, js->user_directories->data)) {
 		purple_account_set_string(purple_connection_get_account(js->gc), "user_directory", "");
 	}
 	else {
@@ -2357,7 +2357,7 @@
 			const JabberIdentity *identity =
 				(JabberIdentity *) iter->data;
 
-			if (strcmp(identity->category, category) == 0) {
+			if (purple_strequal(identity->category, category)) {
 				return identity->type;
 			}
 		}
--- a/libpurple/protocols/jabber/caps.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/caps.c	Wed Jun 14 23:40:17 2017 -0500
@@ -92,8 +92,8 @@
 	const JabberCapsTuple *name1 = v1;
 	const JabberCapsTuple *name2 = v2;
 
-	return g_str_equal(name1->node, name2->node) &&
-	       g_str_equal(name1->ver, name2->ver) &&
+	return purple_strequal(name1->node, name2->node) &&
+	       purple_strequal(name1->ver, name2->ver) &&
 	       purple_strequal(name1->hash, name2->hash);
 }
 
@@ -232,7 +232,7 @@
 	if(!capsdata)
 		return;
 
-	if (!g_str_equal(capsdata->name, "capabilities")) {
+	if (!purple_strequal(capsdata->name, "capabilities")) {
 		purple_xmlnode_free(capsdata);
 		return;
 	}
@@ -240,7 +240,7 @@
 	for (client = capsdata->child; client; client = client->next) {
 		if (client->type != PURPLE_XMLNODE_TYPE_TAG)
 			continue;
-		if (g_str_equal(client->name, "client")) {
+		if (purple_strequal(client->name, "client")) {
 			JabberCapsClientInfo *value = g_new0(JabberCapsClientInfo, 1);
 			JabberCapsTuple *key = (JabberCapsTuple*)&value->tuple;
 			PurpleXmlNode *child;
@@ -256,12 +256,12 @@
 			for (child = client->child; child; child = child->next) {
 				if (child->type != PURPLE_XMLNODE_TYPE_TAG)
 					continue;
-				if (g_str_equal(child->name, "feature")) {
+				if (purple_strequal(child->name, "feature")) {
 					const char *var = purple_xmlnode_get_attrib(child, "var");
 					if(!var)
 						continue;
 					value->features = g_list_append(value->features,g_strdup(var));
-				} else if (g_str_equal(child->name, "identity")) {
+				} else if (purple_strequal(child->name, "identity")) {
 					const char *category = purple_xmlnode_get_attrib(child, "category");
 					const char *type = purple_xmlnode_get_attrib(child, "type");
 					const char *name = purple_xmlnode_get_attrib(child, "name");
@@ -278,13 +278,13 @@
 					id->lang = g_strdup(lang);
 
 					value->identities = g_list_append(value->identities,id);
-				} else if (g_str_equal(child->name, "x")) {
+				} else if (purple_strequal(child->name, "x")) {
 					/* TODO: See #7814 -- this might cause problems if anyone
 					 * ever actually specifies forms. In fact, for this to
 					 * work properly, that bug needs to be fixed in
 					 * purple_xmlnode_from_str, not the output version... */
 					value->forms = g_list_append(value->forms, purple_xmlnode_copy(child));
-				} else if (g_str_equal(child->name, "ext")) {
+				} else if (purple_strequal(child->name, "ext")) {
 					if (key->hash != NULL)
 						purple_debug_warning("jabber", "Ignoring exts when reading new-style caps\n");
 					else {
@@ -299,7 +299,7 @@
 						for (node = child->child; node; node = node->next) {
 							if (node->type != PURPLE_XMLNODE_TYPE_TAG)
 								continue;
-							if (g_str_equal(node->name, "feature")) {
+							if (purple_strequal(node->name, "feature")) {
 								const char *var = purple_xmlnode_get_attrib(node, "var");
 								if (!var)
 									continue;
@@ -356,7 +356,7 @@
 	for (i = 0; exts[i]; ++i) {
 		/* Hack since we advertise the ext along with v1.5 caps but don't
 		 * store any exts */
-		if (g_str_equal(exts[i], "voice-v1") && !info->exts)
+		if (purple_strequal(exts[i], "voice-v1") && !info->exts)
 			continue;
 		if (!info->exts ||
 				!g_hash_table_lookup(info->exts->exts, exts[i]))
@@ -457,9 +457,9 @@
 		GChecksumType hash_type;
 		gboolean supported_hash = TRUE;
 
-		if (g_str_equal(userdata->hash, "sha-1")) {
+		if (purple_strequal(userdata->hash, "sha-1")) {
 			hash_type = G_CHECKSUM_SHA1;
-		} else if (g_str_equal(userdata->hash, "md5")) {
+		} else if (purple_strequal(userdata->hash, "md5")) {
 			hash_type = G_CHECKSUM_MD5;
 		} else {
 			supported_hash = FALSE;
@@ -469,7 +469,7 @@
 			hash = jabber_caps_calculate_hash(info, hash_type);
 		}
 
-		if (!hash || !g_str_equal(hash, userdata->ver)) {
+		if (!hash || !purple_strequal(hash, userdata->ver)) {
 			purple_debug_warning("jabber", "Could not validate caps info from "
 			                     "%s. Expected %s, got %s\n",
 			                     purple_xmlnode_get_attrib(packet, "from"),
@@ -738,7 +738,7 @@
 	PurpleXmlNode *child;
 	JabberCapsClientInfo *info;
 
-	if (!query || !g_str_equal(query->name, "query") ||
+	if (!query || !purple_strequal(query->name, "query") ||
 			!purple_strequal(query->xmlns, NS_DISCO_INFO))
 		return NULL;
 
@@ -747,7 +747,7 @@
 	for(child = query->child; child; child = child->next) {
 		if (child->type != PURPLE_XMLNODE_TYPE_TAG)
 			continue;
-		if (g_str_equal(child->name, "identity")) {
+		if (purple_strequal(child->name, "identity")) {
 			/* parse identity */
 			const char *category = purple_xmlnode_get_attrib(child, "category");
 			const char *type = purple_xmlnode_get_attrib(child, "type");
@@ -765,12 +765,12 @@
 			id->lang = g_strdup(lang);
 
 			info->identities = g_list_append(info->identities, id);
-		} else if (g_str_equal(child->name, "feature")) {
+		} else if (purple_strequal(child->name, "feature")) {
 			/* parse feature */
 			const char *var = purple_xmlnode_get_attrib(child, "var");
 			if (var)
 				info->features = g_list_prepend(info->features, g_strdup(var));
-		} else if (g_str_equal(child->name, "x")) {
+		} else if (purple_strequal(child->name, "x")) {
 			if (purple_strequal(child->xmlns, "jabber:x:data")) {
 				/* x-data form */
 				PurpleXmlNode *dataform = purple_xmlnode_copy(child);
@@ -896,7 +896,7 @@
 		while (fields) {
 			JabberDataFormField *field = (JabberDataFormField*)fields->data;
 
-			if (!g_str_equal(field->var, "FORM_TYPE")) {
+			if (!purple_strequal(field->var, "FORM_TYPE")) {
 				/* Append the "var" attribute */
 				append_escaped_string(hash, field->var);
 				/* Append <value/> elements' cdata */
@@ -982,7 +982,7 @@
 	for (node = accounts; node; node = node->next) {
 		PurpleAccount *account = node->data;
 		const char *protocol_id = purple_account_get_protocol_id(account);
-		if (g_str_equal("prpl-jabber", protocol_id) && purple_account_is_connected(account)) {
+		if (purple_strequal("prpl-jabber", protocol_id) && purple_account_is_connected(account)) {
 			PurpleConnection *gc = purple_account_get_connection(account);
 			jabber_presence_send(purple_connection_get_protocol_data(gc), TRUE);
 		}
--- a/libpurple/protocols/jabber/chat.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/chat.c	Wed Jun 14 23:40:17 2017 -0500
@@ -527,7 +527,7 @@
 			if(!(xmlns = purple_xmlnode_get_namespace(x)))
 				continue;
 
-			if(!strcmp(xmlns, "jabber:x:data")) {
+			if(purple_strequal(xmlns, "jabber:x:data")) {
 				chat->config_dialog_type = PURPLE_REQUEST_FIELDS;
 				chat->config_dialog_handle = jabber_x_data_request(js, x, jabber_chat_room_configure_x_data_cb, chat);
 				return;
@@ -678,7 +678,7 @@
 			if(!(xmlns = purple_xmlnode_get_namespace(x)))
 				continue;
 
-			if(!strcmp(xmlns, "jabber:x:data")) {
+			if(purple_strequal(xmlns, "jabber:x:data")) {
 				jabber_x_data_request(js, x, jabber_chat_register_x_data_cb, chat);
 				return;
 			}
@@ -1241,7 +1241,7 @@
 	for(x = purple_xmlnode_get_child(query, "feature"); x; x = purple_xmlnode_get_next_twin(x)) {
 		const char *var = purple_xmlnode_get_attrib(x, "var");
 
-		if(var && !strcmp(var, NS_XHTML_IM)) {
+		if(purple_strequal(var, NS_XHTML_IM)) {
 			chat->xhtml = TRUE;
 		}
 	}
--- a/libpurple/protocols/jabber/data.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/data.c	Wed Jun 14 23:40:17 2017 -0500
@@ -87,7 +87,7 @@
 	g_return_val_if_fail(tag != NULL, NULL);
 
 	/* check if this is a "data" tag */
-	if (strcmp(tag->name, "data") != 0) {
+	if (!purple_strequal(tag->name, "data")) {
 		purple_debug_error("jabber", "Invalid data element\n");
 		return NULL;
 	}
--- a/libpurple/protocols/jabber/disco.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/disco.c	Wed Jun 14 23:40:17 2017 -0500
@@ -65,14 +65,14 @@
 	PurpleXmlNode *query = purple_xmlnode_get_child_with_namespace(packet, "query",
 		NS_BYTESTREAMS);
 
-	if (from && !strcmp(from, sh->jid) && query != NULL) {
+	if (from && purple_strequal(from, sh->jid) && query != NULL) {
 		PurpleXmlNode *sh_node = purple_xmlnode_get_child(query, "streamhost");
 		if (sh_node) {
 			const char *jid = purple_xmlnode_get_attrib(sh_node, "jid");
 			const char *port = purple_xmlnode_get_attrib(sh_node, "port");
 
 
-			if (jid == NULL || strcmp(jid, from) != 0)
+			if (jid == NULL || !purple_strequal(jid, from))
 				purple_debug_error("jabber", "Invalid jid(%s) for bytestream.\n",
 						   jid ? jid : "(null)");
 
@@ -123,7 +123,7 @@
 		if(node)
 			purple_xmlnode_set_attrib(query, "node", node);
 
-		if(!node || g_str_equal(node, node_uri)) {
+		if(!node || purple_strequal(node, node_uri)) {
 			GList *features, *identities;
 			for(identities = jabber_identities; identities; identities = identities->next) {
 				JabberIdentity *ident = (JabberIdentity*)identities->data;
@@ -143,7 +143,7 @@
 				}
 			}
 #ifdef USE_VV
-		} else if (g_str_equal(node, CAPS0115_NODE "#" "voice-v1")) {
+		} else if (purple_strequal(node, CAPS0115_NODE "#" "voice-v1")) {
 			/*
 			 * HUGE HACK! We advertise this ext (see jabber_presence_create_js
 			 * where we add <c/> to the <presence/>) for the Google Talk
@@ -155,7 +155,7 @@
 			 */
 			PurpleXmlNode *feature = purple_xmlnode_new_child(query, "feature");
 			purple_xmlnode_set_attrib(feature, "var", NS_GOOGLE_VOICE);
-		} else if (g_str_equal(node, CAPS0115_NODE "#" "video-v1")) {
+		} else if (purple_strequal(node, CAPS0115_NODE "#" "video-v1")) {
 			/*
 			 * HUGE HACK! We advertise this ext (see jabber_presence_create_js
 			 * where we add <c/> to the <presence/>) for the Google Talk
@@ -167,7 +167,7 @@
 			 */
 			PurpleXmlNode *feature = purple_xmlnode_new_child(query, "feature");
 			purple_xmlnode_set_attrib(feature, "var", NS_GOOGLE_VIDEO);
-		} else if (g_str_equal(node, CAPS0115_NODE "#" "camera-v1")) {
+		} else if (purple_strequal(node, CAPS0115_NODE "#" "camera-v1")) {
 			/*
 			 * HUGE HACK! We advertise this ext (see jabber_presence_create_js
 			 * where we add <c/> to the <presence/>) for the Google Talk
@@ -245,20 +245,20 @@
 			if(child->type != PURPLE_XMLNODE_TYPE_TAG)
 				continue;
 
-			if(!strcmp(child->name, "identity")) {
+			if(purple_strequal(child->name, "identity")) {
 				const char *category = purple_xmlnode_get_attrib(child, "category");
 				const char *type = purple_xmlnode_get_attrib(child, "type");
 				if(!category || !type)
 					continue;
 
-				if(!strcmp(category, "conference") && !strcmp(type, "text")) {
+				if(purple_strequal(category, "conference") && purple_strequal(type, "text")) {
 					/* we found a groupchat or MUC server, add it to the list */
 					/* XXX: actually check for protocol/muc or gc-1.0 support */
 					js->chat_servers = g_list_prepend(js->chat_servers, g_strdup(from));
-				} else if(!strcmp(category, "directory") && !strcmp(type, "user")) {
+				} else if(purple_strequal(category, "directory") && purple_strequal(type, "user")) {
 					/* we found a JUD */
 					js->user_directories = g_list_prepend(js->user_directories, g_strdup(from));
-				} else if(!strcmp(category, "proxy") && !strcmp(type, "bytestreams")) {
+				} else if(purple_strequal(category, "proxy") && purple_strequal(type, "bytestreams")) {
 					/* This is a bytestream proxy */
 					JabberIq *iq;
 					JabberBytestreamsStreamhost *sh;
@@ -276,29 +276,29 @@
 					jabber_iq_send(iq);
 				}
 
-			} else if(!strcmp(child->name, "feature")) {
+			} else if(purple_strequal(child->name, "feature")) {
 				const char *var = purple_xmlnode_get_attrib(child, "var");
 				if(!var)
 					continue;
 
-				if(!strcmp(var, "http://jabber.org/protocol/si"))
+				if(purple_strequal(var, "http://jabber.org/protocol/si"))
 					capabilities |= JABBER_CAP_SI;
-				else if(!strcmp(var, "http://jabber.org/protocol/si/profile/file-transfer"))
+				else if(purple_strequal(var, "http://jabber.org/protocol/si/profile/file-transfer"))
 					capabilities |= JABBER_CAP_SI_FILE_XFER;
-				else if(!strcmp(var, NS_BYTESTREAMS))
+				else if(purple_strequal(var, NS_BYTESTREAMS))
 					capabilities |= JABBER_CAP_BYTESTREAMS;
-				else if(!strcmp(var, "jabber:iq:search"))
+				else if(purple_strequal(var, "jabber:iq:search"))
 					capabilities |= JABBER_CAP_IQ_SEARCH;
-				else if(!strcmp(var, "jabber:iq:register"))
+				else if(purple_strequal(var, "jabber:iq:register"))
 					capabilities |= JABBER_CAP_IQ_REGISTER;
-				else if(!strcmp(var, NS_PING))
+				else if(purple_strequal(var, NS_PING))
 					capabilities |= JABBER_CAP_PING;
-				else if(!strcmp(var, NS_DISCO_ITEMS))
+				else if(purple_strequal(var, NS_DISCO_ITEMS))
 					capabilities |= JABBER_CAP_ITEMS;
-				else if(!strcmp(var, "http://jabber.org/protocol/commands")) {
+				else if(purple_strequal(var, "http://jabber.org/protocol/commands")) {
 					capabilities |= JABBER_CAP_ADHOC;
 				}
-				else if(!strcmp(var, NS_IBB)) {
+				else if(purple_strequal(var, NS_IBB)) {
 					purple_debug_info("jabber", "remote supports IBB\n");
 					capabilities |= JABBER_CAP_IBB;
 				}
@@ -463,7 +463,7 @@
 {
 	PurpleXmlNode *query, *child;
 
-	if (!from || strcmp(from, js->user->domain)) {
+	if (!from || !purple_strequal(from, js->user->domain)) {
 		jabber_disco_finish_server_info_result_cb(js);
 		return;
 	}
@@ -483,10 +483,10 @@
 
 	for (child = purple_xmlnode_get_child(query, "identity"); child;
 	     child = purple_xmlnode_get_next_twin(child)) {
-		const char *category, *type, *name;
+		const char *category, *type, *name, *stun_ip;
 		category = purple_xmlnode_get_attrib(child, "category");
 		type = purple_xmlnode_get_attrib(child, "type");
-		if(category && type && !strcmp(category, "pubsub") && !strcmp(type,"pep")) {
+		if(purple_strequal(category, "pubsub") && purple_strequal(type, "pep")) {
 			PurpleConnection *gc = js->gc;
 			js->pep = TRUE;
 			purple_connection_set_flags(gc,
@@ -494,9 +494,9 @@
 					| PURPLE_CONNECTION_FLAG_SUPPORT_MOODS
 					| PURPLE_CONNECTION_FLAG_SUPPORT_MOOD_MESSAGES);
 		}
-		if (!category || strcmp(category, "server"))
+		if (!purple_strequal(category, "server"))
 			continue;
-		if (!type || strcmp(type, "im"))
+		if (!purple_strequal(type, "im"))
 			continue;
 
 		name = purple_xmlnode_get_attrib(child, "name");
@@ -505,17 +505,16 @@
 
 		g_free(js->server_name);
 		js->server_name = g_strdup(name);
-		if (!strcmp(name, "Google Talk")) {
+		stun_ip = purple_network_get_stun_ip();
+		if (purple_strequal(name, "Google Talk")) {
 			purple_debug_info("jabber", "Google Talk!\n");
 			js->googletalk = TRUE;
 
 			/* autodiscover stun and relays */
-			if (purple_network_get_stun_ip() == NULL ||
-		    	purple_strequal(purple_network_get_stun_ip(), "")) {
+			if (!stun_ip || !*stun_ip) {
 				jabber_google_send_jingle_info(js);
 			}
-		} else if (purple_network_get_stun_ip() == NULL ||
-		    purple_strequal(purple_network_get_stun_ip(), "")) {
+		} else if (!stun_ip || !*stun_ip) {
 
 			GResolver *resolver = g_resolver_get_default();
 			g_resolver_lookup_service_async(resolver,
@@ -537,14 +536,14 @@
 		if (!var)
 			continue;
 
-		if (!strcmp(NS_GOOGLE_MAIL_NOTIFY, var)) {
+		if (purple_strequal(NS_GOOGLE_MAIL_NOTIFY, var)) {
 			js->server_caps |= JABBER_CAP_GMAIL_NOTIFY;
 			jabber_gmail_init(js);
-		} else if (!strcmp(NS_GOOGLE_ROSTER, var)) {
+		} else if (purple_strequal(NS_GOOGLE_ROSTER, var)) {
 			js->server_caps |= JABBER_CAP_GOOGLE_ROSTER;
-		} else if (!strcmp("http://jabber.org/protocol/commands", var)) {
+		} else if (purple_strequal("http://jabber.org/protocol/commands", var)) {
 			js->server_caps |= JABBER_CAP_ADHOC;
-		} else if (!strcmp(NS_SIMPLE_BLOCKING, var)) {
+		} else if (purple_strequal(NS_SIMPLE_BLOCKING, var)) {
 			js->server_caps |= JABBER_CAP_BLOCKING;
 		}
 	}
@@ -559,7 +558,7 @@
 {
 	PurpleXmlNode *query, *child;
 
-	if (!from || strcmp(from, js->user->domain) != 0)
+	if (!from || !purple_strequal(from, js->user->domain))
 		return;
 
 	if (type == JABBER_IQ_ERROR)
--- a/libpurple/protocols/jabber/google/gmail.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/google/gmail.c	Wed Jun 14 23:40:17 2017 -0500
@@ -95,7 +95,7 @@
 		sender_node  = purple_xmlnode_get_child(sender_node, "sender");
 
 		while (sender_node && (!purple_xmlnode_get_attrib(sender_node, "unread") ||
-		       !strcmp(purple_xmlnode_get_attrib(sender_node, "unread"),"0")))
+		       purple_strequal(purple_xmlnode_get_attrib(sender_node, "unread"),"0")))
 			sender_node = purple_xmlnode_get_next_twin(sender_node);
 
 		if (!sender_node) {
@@ -116,8 +116,7 @@
 		urls[i] = url;
 
 		tid = purple_xmlnode_get_attrib(message, "tid");
-		if (tid &&
-		    (js->gmail_last_tid == NULL || strcmp(tid, js->gmail_last_tid) > 0)) {
+		if (g_strcmp0(tid, js->gmail_last_tid) > 0) {
 			g_free(js->gmail_last_tid);
 			js->gmail_last_tid = g_strdup(tid);
 		}
--- a/libpurple/protocols/jabber/google/google_roster.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/google/google_roster.c	Wed Jun 14 23:40:17 2017 -0500
@@ -34,7 +34,7 @@
 	char *jid_norm = (char *)jabber_normalize(account, jid);
 
 	while (list) {
-		if (!strcmp(jid_norm, (char*)list->data)) {
+		if (purple_strequal(jid_norm, (char*)list->data)) {
 			purple_xmlnode_set_attrib(query, "xmlns:gr", NS_GOOGLE_ROSTER);
 			purple_xmlnode_set_attrib(query, "gr:ext", "2");
 			purple_xmlnode_set_attrib(item, "gr:t", "B");
@@ -56,7 +56,7 @@
 	const char *subscription = purple_xmlnode_get_attrib(item, "subscription");
 	const char *ask = purple_xmlnode_get_attrib(item, "ask");
 
-	if ((!subscription || !strcmp(subscription, "none")) && !ask) {
+	if ((!subscription || purple_strequal(subscription, "none")) && !ask) {
 		/* The Google Talk servers will automatically add people from your Gmail address book
 		 * with subscription=none. If we see someone with subscription=none, ignore them.
 		 */
--- a/libpurple/protocols/jabber/google/google_session.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/google/google_session.c	Wed Jun 14 23:40:17 2017 -0500
@@ -42,7 +42,7 @@
 	GoogleSessionId *c = (GoogleSessionId*)a;
 	GoogleSessionId *d = (GoogleSessionId*)b;
 
-	return !strcmp(c->id, d->id) && !strcmp(c->initiator, d->initiator);
+	return purple_strequal(c->id, d->id) && purple_strequal(c->initiator, d->initiator);
 }
 
 static void
@@ -91,7 +91,7 @@
 	PurpleMediaCandidate *transport;
 	gboolean video = FALSE;
 
-	if (!strcmp(session_id, "google-video"))
+	if (purple_strequal(session_id, "google-video"))
 		video = TRUE;
 
 	for (iter = candidates; iter; iter = iter->next) {
@@ -179,7 +179,7 @@
 		JabberIq *iq;
 		PurpleXmlNode *sess, *desc, *payload;
 		GList *codecs, *iter;
-		gboolean is_initiator = !strcmp(session->id.initiator, me);
+		gboolean is_initiator = purple_strequal(session->id.initiator, me);
 
 		if (!is_initiator &&
 				!purple_media_accepted(media, NULL, NULL)) {
@@ -504,7 +504,7 @@
 		const char *id, *encoding_name,  *clock_rate;
 		gboolean video;
 		if (codec_element->name &&
-				strcmp(codec_element->name, "payload-type"))
+				!purple_strequal(codec_element->name, "payload-type"))
 			continue;
 
 		xmlns = purple_xmlnode_get_namespace(codec_element);
@@ -512,7 +512,7 @@
 		id = purple_xmlnode_get_attrib(codec_element, "id");
 
 		if (!session_data->video ||
-				(xmlns && !strcmp(xmlns, NS_GOOGLE_SESSION_PHONE))) {
+				purple_strequal(xmlns, NS_GOOGLE_SESSION_PHONE)) {
 			clock_rate = purple_xmlnode_get_attrib(
 					codec_element, "clockrate");
 			video = FALSE;
@@ -638,11 +638,11 @@
 
 			g_snprintf(n, sizeof(n), "S%d", name++);
 
-			if (g_str_equal(type, "local"))
+			if (purple_strequal(type, "local"))
 				candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
-			else if (g_str_equal(type, "stun"))
+			else if (purple_strequal(type, "stun"))
 				candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX;
-			else if (g_str_equal(type, "relay"))
+			else if (purple_strequal(type, "relay"))
 				candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_RELAY;
 			else
 				candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
@@ -709,7 +709,7 @@
 	GList *codecs = NULL, *video_codecs = NULL;
 	JabberIq *result = NULL;
 	const gchar *xmlns = purple_xmlnode_get_namespace(desc_element);
-	gboolean video = (xmlns && !strcmp(xmlns, NS_GOOGLE_SESSION_VIDEO));
+	gboolean video = purple_strequal(xmlns, NS_GOOGLE_SESSION_VIDEO);
 	GoogleAVSessionData *session_data =
 		(GoogleAVSessionData *) session->session_data;
 
@@ -788,15 +788,15 @@
 {
 	const char *type = purple_xmlnode_get_attrib(sess, "type");
 
-	if (!strcmp(type, "initiate")) {
+	if (purple_strequal(type, "initiate")) {
 		google_session_handle_initiate(js, session, sess, iq_id);
-	} else if (!strcmp(type, "accept")) {
+	} else if (purple_strequal(type, "accept")) {
 		google_session_handle_accept(js, session, sess, iq_id);
-	} else if (!strcmp(type, "reject")) {
+	} else if (purple_strequal(type, "reject")) {
 		google_session_handle_reject(js, session, sess);
-	} else if (!strcmp(type, "terminate")) {
+	} else if (purple_strequal(type, "terminate")) {
 		google_session_handle_terminate(js, session, sess);
-	} else if (!strcmp(type, "candidates")) {
+	} else if (purple_strequal(type, "candidates")) {
 		google_session_handle_candidates(js, session, sess, iq_id);
 	}
 }
@@ -845,7 +845,7 @@
 	}
 
 	/* If the session doesn't exist, this has to be an initiate message */
-	if (strcmp(purple_xmlnode_get_attrib(session_node, "type"), "initiate"))
+	if (!purple_strequal(purple_xmlnode_get_attrib(session_node, "type"), "initiate"))
 		return;
 	desc_node = purple_xmlnode_get_child(session_node, "description");
 	if (!desc_node)
--- a/libpurple/protocols/jabber/ibb.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/ibb.c	Wed Jun 14 23:40:17 2017 -0500
@@ -384,9 +384,9 @@
                  const char *id, PurpleXmlNode *child)
 {
 	const char *name = child->name;
-	gboolean data  = g_str_equal(name, "data");
-	gboolean close = g_str_equal(name, "close");
-	gboolean open  = g_str_equal(name, "open");
+	gboolean data  = purple_strequal(name, "data");
+	gboolean close = purple_strequal(name, "close");
+	gboolean open  = purple_strequal(name, "open");
 	const gchar *sid = (data || close) ?
 		purple_xmlnode_get_attrib(child, "sid") : NULL;
 	JabberIBBSession *sess =
@@ -394,7 +394,7 @@
 
 	if (sess) {
 
-		if (strcmp(who, jabber_ibb_session_get_who(sess)) != 0) {
+		if (!purple_strequal(who, jabber_ibb_session_get_who(sess))) {
 			/* the iq comes from a different JID than the remote JID of the
 			  session, ignore it */
 			purple_debug_error("jabber",
--- a/libpurple/protocols/jabber/iq.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/iq.c	Wed Jun 14 23:40:17 2017 -0500
@@ -353,13 +353,13 @@
 	}
 
 	if (iq_type) {
-		if (!strcmp(iq_type, "get"))
+		if (purple_strequal(iq_type, "get"))
 			type = JABBER_IQ_GET;
-		else if (!strcmp(iq_type, "set"))
+		else if (purple_strequal(iq_type, "set"))
 			type = JABBER_IQ_SET;
-		else if (!strcmp(iq_type, "result"))
+		else if (purple_strequal(iq_type, "result"))
 			type = JABBER_IQ_RESULT;
-		else if (!strcmp(iq_type, "error"))
+		else if (purple_strequal(iq_type, "error"))
 			type = JABBER_IQ_ERROR;
 	}
 
--- a/libpurple/protocols/jabber/jabber.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/jabber.c	Wed Jun 14 23:40:17 2017 -0500
@@ -234,7 +234,7 @@
 	 */
 	{
 		const gchar *connection_security = purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS);
-		if (!g_str_equal(connection_security, "none")) {
+		if (!purple_strequal(connection_security, "none")) {
 			jabber_send_raw(js,
 					"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1);
 			return TRUE;
@@ -255,7 +255,7 @@
 		return TRUE;
 	}
 
-	if (g_str_equal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
+	if (purple_strequal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
 		purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 				_("You require encryption, but no TLS/SSL support was found."));
@@ -277,7 +277,7 @@
 			jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING_ENCRYPTION);
 			return;
 		}
-	} else if (g_str_equal(connection_security, "require_tls") && !jabber_stream_is_ssl(js)) {
+	} else if (purple_strequal(connection_security, "require_tls") && !jabber_stream_is_ssl(js)) {
 		purple_connection_error(js->gc,
 			 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
 			_("You require encryption, but it is not available on this server."));
@@ -344,33 +344,33 @@
 	name = (*packet)->name;
 	xmlns = purple_xmlnode_get_namespace(*packet);
 
-	if(!strcmp((*packet)->name, "iq")) {
+	if(purple_strequal((*packet)->name, "iq")) {
 		jabber_iq_parse(js, *packet);
-	} else if(!strcmp((*packet)->name, "presence")) {
+	} else if(purple_strequal((*packet)->name, "presence")) {
 		jabber_presence_parse(js, *packet);
-	} else if(!strcmp((*packet)->name, "message")) {
+	} else if(purple_strequal((*packet)->name, "message")) {
 		jabber_message_parse(js, *packet);
 	} else if (purple_strequal(xmlns, NS_XMPP_STREAMS)) {
-		if (g_str_equal(name, "features"))
+		if (purple_strequal(name, "features"))
 			jabber_stream_features_parse(js, *packet);
-		else if (g_str_equal(name, "error"))
+		else if (purple_strequal(name, "error"))
 			jabber_stream_handle_error(js, *packet);
 	} else if (purple_strequal(xmlns, NS_XMPP_SASL)) {
 		if (js->state != JABBER_STREAM_AUTHENTICATING)
 			purple_debug_warning("jabber", "Ignoring spurious SASL stanza %s\n", name);
 		else {
-			if (g_str_equal(name, "challenge"))
+			if (purple_strequal(name, "challenge"))
 				jabber_auth_handle_challenge(js, *packet);
-			else if (g_str_equal(name, "success"))
+			else if (purple_strequal(name, "success"))
 				jabber_auth_handle_success(js, *packet);
-			else if (g_str_equal(name, "failure"))
+			else if (purple_strequal(name, "failure"))
 				jabber_auth_handle_failure(js, *packet);
 		}
 	} else if (purple_strequal(xmlns, NS_XMPP_TLS)) {
 		if (js->state != JABBER_STREAM_INITIALIZING_ENCRYPTION || js->gsc)
 			purple_debug_warning("jabber", "Ignoring spurious %s\n", name);
 		else {
-			if (g_str_equal(name, "proceed"))
+			if (purple_strequal(name, "proceed"))
 				tls_init(js);
 			/* TODO: Handle <failure/>, I guess? */
 		}
@@ -480,7 +480,7 @@
 	g_return_if_fail(data != NULL);
 
 	/* because printing a tab to debug every minute gets old */
-	if (data && strcmp(data, "\t") != 0) {
+	if (data && !purple_strequal(data, "\t")) {
 		const char *username;
 		char *text = NULL, *last_part = NULL, *tag_start = NULL;
 
@@ -608,9 +608,9 @@
 		return;
 
 	if (js->bosh)
-		if (g_str_equal((*packet)->name, "message") ||
-				g_str_equal((*packet)->name, "iq") ||
-				g_str_equal((*packet)->name, "presence"))
+		if (purple_strequal((*packet)->name, "message") ||
+				purple_strequal((*packet)->name, "iq") ||
+				purple_strequal((*packet)->name, "presence"))
 			purple_xmlnode_set_namespace(*packet, NS_XMPP_CLIENT);
 	txt = purple_xmlnode_to_str(*packet, &len);
 	jabber_send_raw(js, txt, len);
@@ -1077,7 +1077,7 @@
 	js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain);
 
 	/* if they've got old-ssl mode going, we probably want to ignore SRV lookups */
-	if (g_str_equal("old_ssl", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
+	if (purple_strequal("old_ssl", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
 		js->gsc = purple_ssl_connect(account, js->certificate_CN,
 				purple_account_get_int(account, "port", 5223),
 				jabber_login_callback_ssl, jabber_ssl_connect_failure, gc);
@@ -1265,7 +1265,7 @@
 				flds; flds = flds->next) {
 			PurpleRequestField *field = flds->data;
 			const char *id = purple_request_field_get_id(field);
-			if(!strcmp(id,"unregister")) {
+			if(purple_strequal(id,"unregister")) {
 				gboolean value = purple_request_field_bool_get_value(field);
 				if(value) {
 					/* unregister from service. this doesn't include any of the fields, so remove them from the stanza by recreating it
@@ -1290,7 +1290,7 @@
 				const char *value = purple_request_field_string_get_value(field);
 				int i;
 				for (i = 0; ids[i]; i++) {
-					if (!strcmp(id, ids[i]))
+					if (purple_strequal(id, ids[i]))
 						break;
 				}
 
@@ -1298,11 +1298,11 @@
 					continue;
 				y = purple_xmlnode_new_child(query, ids[i]);
 				purple_xmlnode_insert_data(y, value, -1);
-				if(cbdata->js->registration && !strcmp(id, "username")) {
+				if(cbdata->js->registration && purple_strequal(id, "username")) {
 					g_free(cbdata->js->user->node);
 					cbdata->js->user->node = g_strdup(value);
 				}
-				if(cbdata->js->registration && !strcmp(id, "password"))
+				if(cbdata->js->registration && purple_strequal(id, "password"))
 					purple_account_set_password(purple_connection_get_account(cbdata->js->gc), value, NULL, NULL);
 			}
 		}
@@ -1835,7 +1835,7 @@
 	}
 
 	account = purple_connection_get_account(js->gc);
-	is_block = g_str_equal(child->name, "block");
+	is_block = purple_strequal(child->name, "block");
 
 	item = purple_xmlnode_get_child(child, "item");
 	if (!is_block && item == NULL) {
@@ -2012,7 +2012,7 @@
 	GList *feature;
 	for(feature = jabber_features; feature; feature = feature->next) {
 		JabberFeature *feat = (JabberFeature*)feature->data;
-		if(!strcmp(feat->namespace, namespace)) {
+		if(purple_strequal(feat->namespace, namespace)) {
 			g_free(feat->namespace);
 			g_free(feature->data);
 			jabber_features = g_list_delete_link(jabber_features, feature);
@@ -2042,23 +2042,17 @@
 	ac = a;
 	bc = b;
 
-	if ((cat_cmp = strcmp(ac->category, bc->category)) == 0) {
-		if ((typ_cmp = strcmp(ac->type, bc->type)) == 0) {
-			if (!ac->lang && !bc->lang) {
-				return 0;
-			} else if (ac->lang && !bc->lang) {
-				return 1;
-			} else if (!ac->lang && bc->lang) {
-				return -1;
-			} else {
-				return strcmp(ac->lang, bc->lang);
-			}
-		} else {
-			return typ_cmp;
-		}
-	} else {
+	cat_cmp = g_strcmp0(ac->category, bc->category);
+	if (cat_cmp != 0) {
 		return cat_cmp;
 	}
+
+	typ_cmp = g_strcmp0(ac->type, bc->type);
+	if (typ_cmp != 0) {
+		return typ_cmp;
+	}
+
+	return g_strcmp0(ac->lang, bc->lang);
 }
 
 void jabber_add_identity(const gchar *category, const gchar *type,
@@ -2074,8 +2068,8 @@
 	/* Check if this identity is already there... */
 	for (identity = jabber_identities; identity; identity = identity->next) {
 		JabberIdentity *id = identity->data;
-		if (g_str_equal(id->category, category) &&
-			g_str_equal(id->type, type) &&
+		if (purple_strequal(id->category, category) &&
+			purple_strequal(id->type, type) &&
 			purple_strequal(id->lang, lang))
 			return;
 	}
@@ -2171,13 +2165,13 @@
 				jabber_resource_get_identity_category_type(jbr, "client");
 
 			if (client_type) {
-				if (strcmp(client_type, "phone") == 0) {
+				if (purple_strequal(client_type, "phone")) {
 					return "mobile";
-				} else if (strcmp(client_type, "web") == 0) {
+				} else if (purple_strequal(client_type, "web")) {
 					return "external";
-				} else if (strcmp(client_type, "handheld") == 0) {
+				} else if (purple_strequal(client_type, "handheld")) {
 					return "hiptop";
-				} else if (strcmp(client_type, "bot") == 0) {
+				} else if (purple_strequal(client_type, "bot")) {
 					return "bot";
 				}
 				/* the default value "pc" falls through and has no emblem */
@@ -2532,7 +2526,7 @@
 	p1 = purple_request_fields_get_string(fields, "password1");
 	p2 = purple_request_fields_get_string(fields, "password2");
 
-	if(strcmp(p1, p2)) {
+	if(!purple_strequal(p1, p2)) {
 		purple_notify_error(js->gc, NULL,
 			_("New passwords do not match."), NULL,
 			purple_request_cpar_from_connection(js->gc));
@@ -2746,7 +2740,7 @@
 		} else if(purple_xmlnode_get_child(error, "undefined-condition")) {
 			text = _("Unknown Error");
 		}
-	} else if(xmlns && !strcmp(xmlns, NS_XMPP_SASL)) {
+	} else if(purple_strequal(xmlns, NS_XMPP_SASL)) {
 		/* Most common reason can be the default */
 		SET_REASON(PURPLE_CONNECTION_ERROR_NETWORK_ERROR);
 		if(purple_xmlnode_get_child(packet, "aborted")) {
@@ -2772,9 +2766,9 @@
 			SET_REASON(PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED);
 			text = _("Authentication Failure");
 		}
-	} else if(!strcmp(packet->name, "stream:error") ||
-			 (!strcmp(packet->name, "error") && xmlns &&
-				!strcmp(xmlns, NS_XMPP_STREAMS))) {
+	} else if(purple_strequal(packet->name, "stream:error") ||
+			 (purple_strequal(packet->name, "error") &&
+				purple_strequal(xmlns, NS_XMPP_STREAMS))) {
 		/* Most common reason as default: */
 		SET_REASON(PURPLE_CONNECTION_ERROR_NETWORK_ERROR);
 		if(purple_xmlnode_get_child(packet, "bad-format")) {
@@ -2951,11 +2945,11 @@
 	if (!chat || !args || !args[0])
 		return PURPLE_CMD_RET_FAILED;
 
-	if (strcmp(args[0], "owner") != 0 &&
-	    strcmp(args[0], "admin") != 0 &&
-	    strcmp(args[0], "member") != 0 &&
-	    strcmp(args[0], "outcast") != 0 &&
-	    strcmp(args[0], "none") != 0) {
+	if (!purple_strequal(args[0], "owner") &&
+	    !purple_strequal(args[0], "admin") &&
+	    !purple_strequal(args[0], "member") &&
+	    !purple_strequal(args[0], "outcast") &&
+	    !purple_strequal(args[0], "none")) {
 		*error = g_strdup_printf(_("Unknown affiliation: \"%s\""), args[0]);
 		return PURPLE_CMD_RET_FAILED;
 	}
@@ -2987,10 +2981,10 @@
 	if (!chat || !args || !args[0])
 		return PURPLE_CMD_RET_FAILED;
 
-	if (strcmp(args[0], "moderator") != 0 &&
-	    strcmp(args[0], "participant") != 0 &&
-	    strcmp(args[0], "visitor") != 0 &&
-	    strcmp(args[0], "none") != 0) {
+	if (!purple_strequal(args[0], "moderator") &&
+	    !purple_strequal(args[0], "participant") &&
+	    !purple_strequal(args[0], "visitor") &&
+	    !purple_strequal(args[0], "none")) {
 		*error = g_strdup_printf(_("Unknown role: \"%s\""), args[0]);
 		return PURPLE_CMD_RET_FAILED;
 	}
@@ -3830,7 +3824,7 @@
 	} else { /* Otherwise find an active account for the protocol */
 		GList *l = purple_accounts_get_all();
 		while (l) {
-			if (!strcmp(protocol, purple_account_get_protocol_id(l->data))
+			if (purple_strequal(protocol, purple_account_get_protocol_id(l->data))
 					&& purple_account_is_connected(l->data)) {
 				acct = l->data;
 				break;
@@ -3925,12 +3919,12 @@
 
 	ui_type = ui_info ? g_hash_table_lookup(ui_info, "client_type") : NULL;
 	if (ui_type) {
-		if (strcmp(ui_type, "pc") == 0 ||
-			strcmp(ui_type, "console") == 0 ||
-			strcmp(ui_type, "phone") == 0 ||
-			strcmp(ui_type, "handheld") == 0 ||
-			strcmp(ui_type, "web") == 0 ||
-			strcmp(ui_type, "bot") == 0) {
+		if (purple_strequal(ui_type, "pc") ||
+			purple_strequal(ui_type, "console") ||
+			purple_strequal(ui_type, "phone") ||
+			purple_strequal(ui_type, "handheld") ||
+			purple_strequal(ui_type, "web") ||
+			purple_strequal(ui_type, "bot")) {
 			type = ui_type;
 		}
 	}
--- a/libpurple/protocols/jabber/jingle/content.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/jingle/content.c	Wed Jun 14 23:40:17 2017 -0500
@@ -410,7 +410,7 @@
 	purple_xmlnode_set_attrib(node, "creator", creator);
 	purple_xmlnode_set_attrib(node, "name", name);
 	purple_xmlnode_set_attrib(node, "senders", senders);
-	if (strcmp("session", disposition))
+	if (!purple_strequal("session", disposition))
 		purple_xmlnode_set_attrib(node, "disposition", disposition);
 
 	g_free(disposition);
--- a/libpurple/protocols/jabber/jingle/iceudp.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/jingle/iceudp.c	Wed Jun 14 23:40:17 2017 -0500
@@ -269,7 +269,7 @@
 
 	for (iter = iceudp->priv->local_candidates; iter; iter = g_list_next(iter)) {
 		JingleIceUdpCandidate *c = iter->data;
-		if (!strcmp(c->id, id)) {
+		if (purple_strequal(c->id, id)) {
 			generation = c->generation + 1;
 
 			g_boxed_free(JINGLE_TYPE_ICEUDP_CANDIDATE, c);
@@ -304,13 +304,13 @@
 		JingleIceUdpCandidate *candidate = candidates->data;
 		PurpleMediaCandidate *new_candidate = purple_media_candidate_new(
 					candidate->foundation, candidate->component,
-					!strcmp(candidate->type, "host") ?
+					purple_strequal(candidate->type, "host") ?
 						PURPLE_MEDIA_CANDIDATE_TYPE_HOST :
-						!strcmp(candidate->type, "srflx") ?
+						purple_strequal(candidate->type, "srflx") ?
 							PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX :
-							!strcmp(candidate->type, "prflx") ?
+							purple_strequal(candidate->type, "prflx") ?
 								PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX :
-								!strcmp(candidate->type, "relay") ?
+								purple_strequal(candidate->type, "relay") ?
 									PURPLE_MEDIA_CANDIDATE_TYPE_RELAY : 0,
 					PURPLE_MEDIA_NETWORK_PROTOCOL_UDP,
 					candidate->ip, candidate->port);
@@ -334,7 +334,7 @@
 	GList *iter = iceudp->priv->remote_candidates;
 	for (; iter; iter = g_list_next(iter)) {
 		JingleIceUdpCandidate *candidate = iter->data;
-		if (!strcmp(candidate->id, id)) {
+		if (purple_strequal(candidate->id, id)) {
 			return candidate;
 		}
 	}
@@ -453,7 +453,7 @@
 			purple_xmlnode_set_attrib(xmltransport, "protocol", candidate->protocol);
 
 			if (candidate->reladdr != NULL &&
-					(strcmp(candidate->ip, candidate->reladdr) ||
+					(!purple_strequal(candidate->ip, candidate->reladdr) ||
 					(candidate->port != candidate->relport))) {
 				gchar *relport = g_strdup_printf("%d",
 						candidate->relport);
--- a/libpurple/protocols/jabber/jingle/jingle.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/jingle/jingle.c	Wed Jun 14 23:40:17 2017 -0500
@@ -47,26 +47,26 @@
 	if (type == NULL)
 		return G_TYPE_NONE;
 
-	if (!strcmp(type, JINGLE_TRANSPORT_RAWUDP))
+	if (purple_strequal(type, JINGLE_TRANSPORT_RAWUDP))
 		return JINGLE_TYPE_RAWUDP;
-	else if (!strcmp(type, JINGLE_TRANSPORT_ICEUDP))
+	else if (purple_strequal(type, JINGLE_TRANSPORT_ICEUDP))
 		return JINGLE_TYPE_ICEUDP;
 #if 0
-	else if (!strcmp(type, JINGLE_TRANSPORT_SOCKS))
+	else if (purple_strequal(type, JINGLE_TRANSPORT_SOCKS))
 		return JINGLE_TYPE_SOCKS;
-	else if (!strcmp(type, JINGLE_TRANSPORT_IBB))
+	else if (purple_strequal(type, JINGLE_TRANSPORT_IBB))
 		return JINGLE_TYPE_IBB;
 #endif
 #ifdef USE_VV
-	else if (!strcmp(type, JINGLE_APP_RTP))
+	else if (purple_strequal(type, JINGLE_APP_RTP))
 		return JINGLE_TYPE_RTP;
 	else if (!strcmp(type, NS_GOOGLE_TRANSPORT_P2P))
 		return JINGLE_TYPE_GOOGLE_P2P;
 #endif
 #if 0
-	else if (!strcmp(type, JINGLE_APP_FT))
+	else if (purple_strequal(type, JINGLE_APP_FT))
 		return JINGLE_TYPE_FT;
-	else if (!strcmp(type, JINGLE_APP_XML))
+	else if (purple_strequal(type, JINGLE_APP_XML))
 		return JINGLE_TYPE_XML;
 #endif
 	else
@@ -373,7 +373,7 @@
 	/* Start at 1 to skip the unknown-action type */
 	int i = 1;
 	for (; i < num_actions; ++i) {
-		if (!strcmp(action, jingle_actions[i].name))
+		if (purple_strequal(action, jingle_actions[i].name))
 			return i;
 	}
 	return JINGLE_UNKNOWN_TYPE;
@@ -409,7 +409,7 @@
 	}
 
 	if (!(session = jingle_session_find_by_sid(js, sid))
-			&& strcmp(action, "session-initiate")) {
+			&& !purple_strequal(action, "session-initiate")) {
 		purple_debug_error("jingle", "jabber_jingle_session_parse couldn't find session\n");
 		/* send iq error here */
 		return;
--- a/libpurple/protocols/jabber/jingle/rawudp.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/jingle/rawudp.c	Wed Jun 14 23:40:17 2017 -0500
@@ -220,7 +220,7 @@
 
 	for (iter = rawudp->priv->local_candidates; iter; iter = g_list_next(iter)) {
 		JingleRawUdpCandidate *c = iter->data;
-		if (!strcmp(c->id, id)) {
+		if (purple_strequal(c->id, id)) {
 			generation = c->generation + 1;
 
 			g_boxed_free(JINGLE_TYPE_RAWUDP_CANDIDATE, c);
@@ -269,7 +269,7 @@
 	GList *iter = rawudp->priv->remote_candidates;
 	for (; iter; iter = g_list_next(iter)) {
 		JingleRawUdpCandidate *candidate = iter->data;
-		if (!strcmp(candidate->id, id)) {
+		if (purple_strequal(candidate->id, id)) {
 			return candidate;
 		}
 	}
--- a/libpurple/protocols/jabber/jingle/rtp.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/jingle/rtp.c	Wed Jun 14 23:40:17 2017 -0500
@@ -477,7 +477,7 @@
 		transmitter = "notransmitter";
 	g_object_unref(transport);
 
-	is_audio = g_str_equal(media_type, "audio");
+	is_audio = purple_strequal(media_type, "audio");
 
 	if (purple_strequal(senders, "both"))
 		type = is_audio ? PURPLE_MEDIA_AUDIO
@@ -505,7 +505,7 @@
 		return FALSE;
 	}
 
-	if (g_str_equal(creator, "initiator"))
+	if (purple_strequal(creator, "initiator"))
 		is_creator = jingle_session_is_initiator(session);
 	else
 		is_creator = !jingle_session_is_initiator(session);
@@ -544,9 +544,9 @@
 		return NULL;
 	}
 
-	if (g_str_equal(media, "video")) {
+	if (purple_strequal(media, "video")) {
 		type = PURPLE_MEDIA_VIDEO;
-	} else if (g_str_equal(media, "audio")) {
+	} else if (purple_strequal(media, "audio")) {
 		type = PURPLE_MEDIA_AUDIO;
 	} else {
 		purple_debug_warning("jingle-rtp", "unknown media type: %s\n",
--- a/libpurple/protocols/jabber/jingle/session.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/jingle/session.c	Wed Jun 14 23:40:17 2017 -0500
@@ -361,7 +361,7 @@
 	gchar *cmp_jid = use_bare ? jabber_get_bare_jid(remote_jid)
 				  : g_strdup(remote_jid);
 	g_free(remote_jid);
-	if (g_str_equal(jid, cmp_jid)) {
+	if (purple_strequal(jid, cmp_jid)) {
 		g_free(cmp_jid);
 		return TRUE;
 	}
@@ -491,12 +491,12 @@
 	for (; iter; iter = g_list_next(iter)) {
 		JingleContent *content = iter->data;
 		gchar *cname = jingle_content_get_name(content);
-		gboolean result = g_str_equal(name, cname);
+		gboolean result = purple_strequal(name, cname);
 		g_free(cname);
 
 		if (creator != NULL) {
 			gchar *ccreator = jingle_content_get_creator(content);
-			result = (result && !strcmp(creator, ccreator));
+			result = (result && purple_strequal(creator, ccreator));
 			g_free(ccreator);
 		}
 
@@ -518,12 +518,12 @@
 	for (; iter; iter = g_list_next(iter)) {
 		JingleContent *content = iter->data;
 		gchar *cname = jingle_content_get_name(content);
-		gboolean result = g_str_equal(name, cname);
+		gboolean result = purple_strequal(name, cname);
 		g_free(cname);
 
 		if (creator != NULL) {
 			gchar *ccreator = jingle_content_get_creator(content);
-			result = (result && !strcmp(creator, ccreator));
+			result = (result && purple_strequal(creator, ccreator));
 			g_free(ccreator);
 		}
 
--- a/libpurple/protocols/jabber/jutil.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/jutil.c	Wed Jun 14 23:40:17 2017 -0500
@@ -670,7 +670,7 @@
 		return FALSE;
 
 	equal = (jid->node == NULL &&
-	         g_str_equal(jid->domain, js->user->domain) &&
+	         purple_strequal(jid->domain, js->user->domain) &&
 	         jid->resource == NULL);
 	jabber_id_free(jid);
 	return equal;
@@ -692,9 +692,9 @@
 		return FALSE;
 
 	equal = (purple_strequal(jid->node, js->user->node) &&
-	         g_str_equal(jid->domain, js->user->domain) &&
+	         purple_strequal(jid->domain, js->user->domain) &&
 	         (jid->resource == NULL ||
-	             g_str_equal(jid->resource, js->user->resource)));
+	             purple_strequal(jid->resource, js->user->resource)));
 	jabber_id_free(jid);
 	return equal;
 }
@@ -733,7 +733,7 @@
 		return JABBER_BUDDY_STATE_UNKNOWN;
 
 	for (i = 0; i < G_N_ELEMENTS(jabber_statuses); ++i)
-		if (g_str_equal(id, jabber_statuses[i].status_id))
+		if (purple_strequal(id, jabber_statuses[i].status_id))
 			return jabber_statuses[i].state;
 
 	return JABBER_BUDDY_STATE_UNKNOWN;
@@ -746,7 +746,7 @@
 	g_return_val_if_fail(id != NULL, JABBER_BUDDY_STATE_UNKNOWN);
 
 	for (i = 0; i < G_N_ELEMENTS(jabber_statuses); ++i)
-		if (jabber_statuses[i].show && g_str_equal(id, jabber_statuses[i].show))
+		if (jabber_statuses[i].show && purple_strequal(id, jabber_statuses[i].show))
 			return jabber_statuses[i].state;
 
 	purple_debug_warning("jabber", "Invalid value of presence <show/> "
--- a/libpurple/protocols/jabber/message.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/message.c	Wed Jun 14 23:40:17 2017 -0500
@@ -46,6 +46,48 @@
 	gchar *shortcut;
 } JabberMessageRemoteSmileyAddData;
 
+static GString *jm_body_with_oob(JabberMessage *jm) {
+	GList *etc;
+	GString *body = g_string_new("");
+
+	if(jm->xhtml)
+		g_string_append(body, jm->xhtml);
+	else if(jm->body)
+		g_string_append(body, jm->body);
+
+	for(etc = jm->etc; etc; etc = etc->next) {
+		PurpleXmlNode *x = etc->data;
+		const char *xmlns = purple_xmlnode_get_namespace(x);
+		if(purple_strequal(xmlns, NS_OOB_X_DATA)) {
+			PurpleXmlNode *url, *desc;
+			char *urltxt, *desctxt;
+
+			url = purple_xmlnode_get_child(x, "url");
+			desc = purple_xmlnode_get_child(x, "desc");
+
+			if(!url)
+				continue;
+
+			urltxt = purple_xmlnode_get_data(url);
+			desctxt = desc ? purple_xmlnode_get_data(desc) : urltxt;
+
+			if(body->len && !purple_strequal(body->str, urltxt))
+				g_string_append_printf(body, "<br/><a href='%s'>%s</a>",
+						urltxt, desctxt);
+			else
+				g_string_printf(body, "<a href='%s'>%s</a>",
+						urltxt, desctxt);
+
+			g_free(urltxt);
+
+			if(desctxt != urltxt)
+				g_free(desctxt);
+		}
+	}
+
+	return body;
+}
+
 void jabber_message_free(JabberMessage *jm)
 {
 	g_free(jm->from);
@@ -71,6 +113,7 @@
 	PurpleAccount *account;
 	JabberBuddy *jb;
 	JabberBuddyResource *jbr;
+	GString *body;
 
 	if(!jid)
 		return;
@@ -81,15 +124,17 @@
 	jb = jabber_buddy_find(jm->js, jm->from, TRUE);
 	jbr = jabber_buddy_find_resource(jb, jid->resource);
 
-	if(!jm->xhtml && !jm->body) {
-		if (jbr && jm->chat_state != JM_STATE_NONE)
-			jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED;
+	if (jbr && jm->chat_state != JM_STATE_NONE)
+		jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED;
 
-		if(JM_STATE_COMPOSING == jm->chat_state) {
+	switch(jm->chat_state) {
+		case JM_STATE_COMPOSING:
 			purple_serv_got_typing(gc, jm->from, 0, PURPLE_IM_TYPING);
-		} else if(JM_STATE_PAUSED == jm->chat_state) {
+			break;
+		case JM_STATE_PAUSED:
 			purple_serv_got_typing(gc, jm->from, 0, PURPLE_IM_TYPED);
-		} else if(JM_STATE_GONE == jm->chat_state) {
+			break;
+		case JM_STATE_GONE: {
 			PurpleIMConversation *im = purple_conversations_find_im_with_account(
 					jm->from, account);
 			if (im && jid->node && jid->domain) {
@@ -117,11 +162,21 @@
 				}
 			}
 			purple_serv_got_typing_stopped(gc, jm->from);
-
-		} else {
+			break;
+		}
+		default:
 			purple_serv_got_typing_stopped(gc, jm->from);
-		}
-	} else {
+	}
+
+	if (jm->js->googletalk && jm->body && jm->xhtml == NULL) {
+		char *tmp = jm->body;
+		jm->body = jabber_google_format_to_html(jm->body);
+		g_free(tmp);
+	}
+
+	body = jm_body_with_oob(jm);
+
+	if(body && body->len) {
 		if (jid->resource) {
 			/*
 			 * We received a message from a specific resource, so
@@ -135,7 +190,7 @@
 			PurpleIMConversation *im;
 
 			im = purple_conversations_find_im_with_account(jm->from, account);
-			if (im && !g_str_equal(jm->from,
+			if (im && !purple_strequal(jm->from,
 					purple_conversation_get_name(PURPLE_CONVERSATION(im)))) {
 				purple_debug_info("jabber", "Binding conversation to %s\n",
 				                  jm->from);
@@ -156,63 +211,26 @@
 			jbr->thread_id = g_strdup(jbr->thread_id);
 		}
 
-		if (jm->js->googletalk && jm->xhtml == NULL) {
-			char *tmp = jm->body;
-			jm->body = jabber_google_format_to_html(jm->body);
-			g_free(tmp);
-		}
-		purple_serv_got_im(gc, jm->from, jm->xhtml ? jm->xhtml : jm->body, 0, jm->sent);
+		purple_serv_got_im(gc, jm->from, body->str, 0, jm->sent);
 	}
 
 	jabber_id_free(jid);
+
+	if(body)
+		g_string_free(body, TRUE);
 }
 
 static void handle_headline(JabberMessage *jm)
 {
 	char *title;
 	GString *body;
-	GList *etc;
 
 	if(!jm->xhtml && !jm->body)
 		return; /* ignore headlines without any content */
 
-	body = g_string_new("");
+	body = jm_body_with_oob(jm);
 	title = g_strdup_printf(_("Message from %s"), jm->from);
 
-	if(jm->xhtml)
-		g_string_append(body, jm->xhtml);
-	else if(jm->body)
-		g_string_append(body, jm->body);
-
-	for(etc = jm->etc; etc; etc = etc->next) {
-		PurpleXmlNode *x = etc->data;
-		const char *xmlns = purple_xmlnode_get_namespace(x);
-		if(xmlns && !strcmp(xmlns, NS_OOB_X_DATA)) {
-			PurpleXmlNode *url, *desc;
-			char *urltxt, *desctxt;
-
-			url = purple_xmlnode_get_child(x, "url");
-			desc = purple_xmlnode_get_child(x, "desc");
-
-			if(!url || !desc)
-				continue;
-
-			urltxt = purple_xmlnode_get_data(url);
-			desctxt = purple_xmlnode_get_data(desc);
-
-			/* I'm all about ugly hacks */
-			if(body->len && jm->body && !strcmp(body->str, jm->body))
-				g_string_printf(body, "<a href='%s'>%s</a>",
-						urltxt, desctxt);
-			else
-				g_string_append_printf(body, "<br/><a href='%s'>%s</a>",
-						urltxt, desctxt);
-
-			g_free(urltxt);
-			g_free(desctxt);
-		}
-	}
-
 	purple_notify_formatted(jm->js->gc, title, jm->subject ? jm->subject : title,
 			NULL, body->str, NULL, NULL);
 
@@ -588,15 +606,15 @@
 	jm->chat_state = JM_STATE_NONE;
 
 	if(type) {
-		if(!strcmp(type, "normal"))
+		if(purple_strequal(type, "normal"))
 			jm->type = JABBER_MESSAGE_NORMAL;
-		else if(!strcmp(type, "chat"))
+		else if(purple_strequal(type, "chat"))
 			jm->type = JABBER_MESSAGE_CHAT;
-		else if(!strcmp(type, "groupchat"))
+		else if(purple_strequal(type, "groupchat"))
 			jm->type = JABBER_MESSAGE_GROUPCHAT;
-		else if(!strcmp(type, "headline"))
+		else if(purple_strequal(type, "headline"))
 			jm->type = JABBER_MESSAGE_HEADLINE;
-		else if(!strcmp(type, "error"))
+		else if(purple_strequal(type, "error"))
 			jm->type = JABBER_MESSAGE_ERROR;
 		else
 			jm->type = JABBER_MESSAGE_OTHER;
@@ -613,7 +631,7 @@
 		if(child->type != PURPLE_XMLNODE_TYPE_TAG)
 			continue;
 
-		if(!strcmp(child->name, "error")) {
+		if(purple_strequal(child->name, "error")) {
 			const char *code = purple_xmlnode_get_attrib(child, "code");
 			char *code_txt = NULL;
 			char *text = purple_xmlnode_get_data(child);
@@ -638,20 +656,20 @@
 		} else if (xmlns == NULL) {
 			/* QuLogic: Not certain this is correct, but it would have happened
 			   with the previous code. */
-			if(!strcmp(child->name, "x"))
+			if(purple_strequal(child->name, "x"))
 				jm->etc = g_list_append(jm->etc, child);
 			/* The following tests expect xmlns != NULL */
 			continue;
-		} else if(!strcmp(child->name, "subject") && !strcmp(xmlns, NS_XMPP_CLIENT)) {
+		} else if(purple_strequal(child->name, "subject") && purple_strequal(xmlns, NS_XMPP_CLIENT)) {
 			if(!jm->subject) {
 				jm->subject = purple_xmlnode_get_data(child);
 				if(!jm->subject)
 					jm->subject = g_strdup("");
 			}
-		} else if(!strcmp(child->name, "thread") && !strcmp(xmlns, NS_XMPP_CLIENT)) {
+		} else if(purple_strequal(child->name, "thread") && purple_strequal(xmlns, NS_XMPP_CLIENT)) {
 			if(!jm->thread_id)
 				jm->thread_id = purple_xmlnode_get_data(child);
-		} else if(!strcmp(child->name, "body") && !strcmp(xmlns, NS_XMPP_CLIENT)) {
+		} else if(purple_strequal(child->name, "body") && purple_strequal(xmlns, NS_XMPP_CLIENT)) {
 			if(!jm->body) {
 				char *msg = purple_xmlnode_get_data(child);
 				char *escaped = purple_markup_escape_text(msg, -1);
@@ -659,7 +677,7 @@
 				g_free(escaped);
 				g_free(msg);
 			}
-		} else if(!strcmp(child->name, "html") && !strcmp(xmlns, NS_XHTML_IM)) {
+		} else if(purple_strequal(child->name, "html") && purple_strequal(xmlns, NS_XHTML_IM)) {
 			if(!jm->xhtml && purple_xmlnode_get_child(child, "body")) {
 				char *c;
 
@@ -740,35 +758,35 @@
 						*c = ' ';
 				}
 			}
-		} else if(!strcmp(child->name, "active") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {
+		} else if(purple_strequal(child->name, "active") && purple_strequal(xmlns,"http://jabber.org/protocol/chatstates")) {
 			jm->chat_state = JM_STATE_ACTIVE;
-		} else if(!strcmp(child->name, "composing") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {
+		} else if(purple_strequal(child->name, "composing") && purple_strequal(xmlns,"http://jabber.org/protocol/chatstates")) {
 			jm->chat_state = JM_STATE_COMPOSING;
-		} else if(!strcmp(child->name, "paused") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {
+		} else if(purple_strequal(child->name, "paused") && purple_strequal(xmlns,"http://jabber.org/protocol/chatstates")) {
 			jm->chat_state = JM_STATE_PAUSED;
-		} else if(!strcmp(child->name, "inactive") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {
+		} else if(purple_strequal(child->name, "inactive") && purple_strequal(xmlns,"http://jabber.org/protocol/chatstates")) {
 			jm->chat_state = JM_STATE_INACTIVE;
-		} else if(!strcmp(child->name, "gone") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {
+		} else if(purple_strequal(child->name, "gone") && purple_strequal(xmlns,"http://jabber.org/protocol/chatstates")) {
 			jm->chat_state = JM_STATE_GONE;
-		} else if(!strcmp(child->name, "event") && !strcmp(xmlns,"http://jabber.org/protocol/pubsub#event")) {
+		} else if(purple_strequal(child->name, "event") && purple_strequal(xmlns,"http://jabber.org/protocol/pubsub#event")) {
 			PurpleXmlNode *items;
 			jm->type = JABBER_MESSAGE_EVENT;
 			for(items = purple_xmlnode_get_child(child,"items"); items; items = items->next)
 				jm->eventitems = g_list_append(jm->eventitems, items);
-		} else if(!strcmp(child->name, "attention") && !strcmp(xmlns, NS_ATTENTION)) {
+		} else if(purple_strequal(child->name, "attention") && purple_strequal(xmlns, NS_ATTENTION)) {
 			jm->hasBuzz = TRUE;
-		} else if(!strcmp(child->name, "delay") && !strcmp(xmlns, NS_DELAYED_DELIVERY)) {
+		} else if(purple_strequal(child->name, "delay") && purple_strequal(xmlns, NS_DELAYED_DELIVERY)) {
 			const char *timestamp = purple_xmlnode_get_attrib(child, "stamp");
 			jm->delayed = TRUE;
 			if(timestamp)
 				jm->sent = purple_str_to_time(timestamp, TRUE, NULL, NULL, NULL);
-		} else if(!strcmp(child->name, "x")) {
-			if(!strcmp(xmlns, NS_DELAYED_DELIVERY_LEGACY)) {
+		} else if(purple_strequal(child->name, "x")) {
+			if(purple_strequal(xmlns, NS_DELAYED_DELIVERY_LEGACY)) {
 				const char *timestamp = purple_xmlnode_get_attrib(child, "stamp");
 				jm->delayed = TRUE;
 				if(timestamp)
 					jm->sent = purple_str_to_time(timestamp, TRUE, NULL, NULL, NULL);
-			} else if(!strcmp(xmlns, "jabber:x:conference") &&
+			} else if(purple_strequal(xmlns, "jabber:x:conference") &&
 					jm->type != JABBER_MESSAGE_GROUPCHAT_INVITE &&
 					jm->type != JABBER_MESSAGE_ERROR) {
 				const char *jid = purple_xmlnode_get_attrib(child, "jid");
@@ -790,7 +808,7 @@
 						jm->password = g_strdup(password);
 					}
 				}
-			} else if(!strcmp(xmlns, "http://jabber.org/protocol/muc#user") &&
+			} else if(purple_strequal(xmlns, "http://jabber.org/protocol/muc#user") &&
 					jm->type != JABBER_MESSAGE_ERROR) {
 				PurpleXmlNode *invite = purple_xmlnode_get_child(child, "invite");
 				if(invite) {
@@ -813,7 +831,7 @@
 			} else {
 				jm->etc = g_list_append(jm->etc, child);
 			}
-		} else if (g_str_equal(child->name, "query")) {
+		} else if (purple_strequal(child->name, "query")) {
 			const char *node = purple_xmlnode_get_attrib(child, "node");
 			if (purple_strequal(xmlns, NS_DISCO_ITEMS)
 					&& purple_strequal(node, "http://jabber.org/protocol/commands")) {
--- a/libpurple/protocols/jabber/oob.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/oob.c	Wed Jun 14 23:40:17 2017 -0500
@@ -143,11 +143,11 @@
 	jabber_iq_set_id(iq, jox->iq_id);
 	y = purple_xmlnode_new_child(iq->node, "error");
 	purple_xmlnode_set_attrib(y, "code", code);
-	if(!strcmp(code, "406")) {
+	if(purple_strequal(code, "406")) {
 		z = purple_xmlnode_new_child(y, "not-acceptable");
 		purple_xmlnode_set_attrib(y, "type", "modify");
 		purple_xmlnode_set_namespace(z, NS_XMPP_STANZAS);
-	} else if(!strcmp(code, "404")) {
+	} else if(purple_strequal(code, "404")) {
 		z = purple_xmlnode_new_child(y, "not-found");
 		purple_xmlnode_set_attrib(y, "type", "cancel");
 		purple_xmlnode_set_namespace(z, NS_XMPP_STANZAS);
--- a/libpurple/protocols/jabber/parser.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/parser.c	Wed Jun 14 23:40:17 2017 -0500
@@ -191,8 +191,8 @@
 {
 	JabberStream *js = user_data;
 
-	if (error->level == XML_ERR_WARNING && error->message != NULL
-			&& g_str_equal(error->message, "xmlns: URI vcard-temp is not absolute\n"))
+	if (error->level == XML_ERR_WARNING
+			&& purple_strequal(error->message, "xmlns: URI vcard-temp is not absolute\n"))
 		/*
 		 * This message happens when parsing vcards, and is normal, so don't
 		 * bother logging it because people scare easily.
--- a/libpurple/protocols/jabber/presence.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/presence.c	Wed Jun 14 23:40:17 2017 -0500
@@ -69,7 +69,7 @@
 		return JABBER_PRESENCE_AVAILABLE;
 
 	for (i = 0; i < G_N_ELEMENTS(jabber_presence_types); ++i)
-		if (g_str_equal(type, jabber_presence_types[i].name))
+		if (purple_strequal(type, jabber_presence_types[i].name))
 			return jabber_presence_types[i].type;
 
 	purple_debug_warning("jabber", "Unknown presence type '%s'\n", type);
@@ -212,12 +212,10 @@
 		stripped = jabber_google_presence_outgoing(tune);
 	}
 
-#define CHANGED(a,b) ((!a && b) || (a && a[0] == '\0' && b && b[0] != '\0') || \
-					  (a && !b) || (a && a[0] != '\0' && b && b[0] == '\0') || (a && b && strcmp(a,b)))
 	/* check if there are any differences to the <presence> and send them in that case */
 	if (force || allowBuzz != js->allowBuzz || js->old_state != state ||
-		CHANGED(js->old_msg, stripped) || js->old_priority != priority ||
-		CHANGED(js->old_avatarhash, js->avatar_hash) || js->old_idle != js->idle) {
+		!purple_strequal(js->old_msg, stripped) || js->old_priority != priority ||
+		!purple_strequal(js->old_avatarhash, js->avatar_hash) || js->old_idle != js->idle) {
 		/* Need to update allowBuzz before creating the presence (with caps) */
 		js->allowBuzz = allowBuzz;
 
@@ -266,8 +264,9 @@
 				purple_status_get_attr_int(tune, PURPLE_TUNE_TIME);
 	}
 
-	if(CHANGED(artist, js->old_artist) || CHANGED(title, js->old_title) || CHANGED(source, js->old_source) ||
-	   CHANGED(uri, js->old_uri) || CHANGED(track, js->old_track) || (length != js->old_length)) {
+	if(!purple_strequal(artist, js->old_artist) || !purple_strequal(title, js->old_title) ||
+			!purple_strequal(source, js->old_source) || !purple_strequal(uri, js->old_uri) ||
+			!purple_strequal(track, js->old_track) || (length != js->old_length)) {
 		PurpleJabberTuneInfo tuneinfo = {
 			(char*)artist,
 			(char*)title,
@@ -594,7 +593,7 @@
 		}
 
 		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(110)) ||
-				g_str_equal(presence->jid_from->resource, chat->handle) ||
+				purple_strequal(presence->jid_from->resource, chat->handle) ||
 				purple_strequal(presence->to, jid))
 			is_our_resource = TRUE;
 
@@ -623,9 +622,9 @@
 		if (purple_strequal(affiliation, "owner"))
 			flags |= PURPLE_CHAT_USER_FOUNDER;
 		if (role) {
-			if (g_str_equal(role, "moderator"))
+			if (purple_strequal(role, "moderator"))
 				flags |= PURPLE_CHAT_USER_OP;
-			else if (g_str_equal(role, "participant"))
+			else if (purple_strequal(role, "participant"))
 				flags |= PURPLE_CHAT_USER_VOICE;
 		}
 
@@ -667,12 +666,12 @@
 		 */
 		if (!presence->jid_from->resource || !chat->conv || chat->left) {
 			if (chat->left &&
-					presence->jid_from->resource && chat->handle && !strcmp(presence->jid_from->resource, chat->handle))
+					presence->jid_from->resource && chat->handle && purple_strequal(presence->jid_from->resource, chat->handle))
 				jabber_chat_destroy(chat);
 			return FALSE;
 		}
 
-		is_our_resource = g_str_equal(presence->jid_from->resource, chat->handle);
+		is_our_resource = purple_strequal(presence->jid_from->resource, chat->handle);
 
 		jabber_buddy_remove_resource(presence->jb, presence->jid_from->resource);
 
@@ -701,7 +700,7 @@
 				} else {
 					nick_change = TRUE;
 
-					if (g_str_equal(presence->jid_from->resource, chat->handle)) {
+					if (purple_strequal(presence->jid_from->resource, chat->handle)) {
 						/* Changing our own nickname */
 						g_free(chat->handle);
 						/* TODO: This should be resourceprep'd */
@@ -1054,8 +1053,8 @@
 
 			/* Look it up if we don't already have all this information */
 			if (!jbr || !jbr->caps.info ||
-					!g_str_equal(node, jbr->caps.info->tuple.node) ||
-					!g_str_equal(ver, jbr->caps.info->tuple.ver) ||
+					!purple_strequal(node, jbr->caps.info->tuple.node) ||
+					!purple_strequal(ver, jbr->caps.info->tuple.ver) ||
 					!purple_strequal(hash, jbr->caps.info->tuple.hash) ||
 					!jabber_caps_exts_known(jbr->caps.info, (gchar **)exts)) {
 				JabberPresenceCapabilities *userdata = g_new0(JabberPresenceCapabilities, 1);
--- a/libpurple/protocols/jabber/roster.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/roster.c	Wed Jun 14 23:40:17 2017 -0500
@@ -232,17 +232,17 @@
 			continue;
 
 		if(subscription) {
-			if (g_str_equal(subscription, "remove"))
+			if (purple_strequal(subscription, "remove"))
 				jb->subscription = JABBER_SUB_REMOVE;
 			else if (jb == js->user_jb)
 				jb->subscription = JABBER_SUB_BOTH;
-			else if (g_str_equal(subscription, "none"))
+			else if (purple_strequal(subscription, "none"))
 				jb->subscription = JABBER_SUB_NONE;
-			else if (g_str_equal(subscription, "to"))
+			else if (purple_strequal(subscription, "to"))
 				jb->subscription = JABBER_SUB_TO;
-			else if (g_str_equal(subscription, "from"))
+			else if (purple_strequal(subscription, "from"))
 				jb->subscription = JABBER_SUB_FROM;
-			else if (g_str_equal(subscription, "both"))
+			else if (purple_strequal(subscription, "both"))
 				jb->subscription = JABBER_SUB_BOTH;
 		}
 
@@ -454,7 +454,7 @@
 	GSList *buddies, *groups = NULL;
 	PurpleBuddy *b;
 
-	if(!old_group || !new_group || !strcmp(old_group, new_group))
+	if(!old_group || !new_group || purple_strequal(old_group, new_group))
 		return;
 
 	buddies = purple_blist_find_buddies(purple_connection_get_account(gc), name);
@@ -531,9 +531,9 @@
 
 	if (name == NULL)
 		name = JABBER_ROSTER_DEFAULT_GROUP;
-	else if (g_strcmp0(name, PURPLE_BLIST_DEFAULT_GROUP_NAME) == 0)
+	else if (purple_strequal(name, PURPLE_BLIST_DEFAULT_GROUP_NAME))
 		name = JABBER_ROSTER_DEFAULT_GROUP;
-	else if (g_strcmp0(name, _purple_blist_get_localized_default_group_name()) == 0)
+	else if (purple_strequal(name, _purple_blist_get_localized_default_group_name()))
 		name = JABBER_ROSTER_DEFAULT_GROUP;
 
 	return name;
--- a/libpurple/protocols/jabber/si.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/si.c	Wed Jun 14 23:40:17 2017 -0500
@@ -89,7 +89,7 @@
 		PurpleXfer *xfer = xfers->data;
 		JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 		if(jsx->stream_id && purple_xfer_get_remote_user(xfer) &&
-				!strcmp(jsx->stream_id, sid) && !strcmp(purple_xfer_get_remote_user(xfer), from))
+				purple_strequal(jsx->stream_id, sid) && purple_strequal(purple_xfer_get_remote_user(xfer), from))
 			return xfer;
 	}
 
@@ -764,7 +764,7 @@
 	{
 		gchar *my_jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
 			jsx->js->user->domain, jsx->js->user->resource);
-		if (!strcmp(jid, my_jid)) {
+		if (purple_strequal(jid, my_jid)) {
 			purple_debug_info("jabber", "Got local SOCKS5 streamhost-used.\n");
 			purple_xfer_start(xfer, purple_xfer_get_fd(xfer), NULL, -1);
 		} else {
@@ -870,7 +870,7 @@
 		}
 
 		/* Include the public IP (assuming that there is a port mapped somehow) */
-		if (!has_public_ip && strcmp(public_ip, "0.0.0.0") != 0) {
+		if (!has_public_ip && !purple_strequal(public_ip, "0.0.0.0")) {
 			streamhost_count++;
 			streamhost = purple_xmlnode_new_child(query, "streamhost");
 			purple_xmlnode_set_attrib(streamhost, "jid", jid);
@@ -1193,14 +1193,14 @@
 		const char *var = purple_xmlnode_get_attrib(field, "var");
 		JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
-		if(var && !strcmp(var, "stream-method")) {
+		if(purple_strequal(var, "stream-method")) {
 			if((value = purple_xmlnode_get_child(field, "value"))) {
 				char *val = purple_xmlnode_get_data(value);
-				if(val && !strcmp(val, NS_BYTESTREAMS)) {
+				if(purple_strequal(val, NS_BYTESTREAMS)) {
 					jabber_si_xfer_bytestreams_send_init(xfer);
 					jsx->stream_method |= STREAM_METHOD_BYTESTREAMS;
 					found_method = TRUE;
-				} else if (val && !strcmp(val, NS_IBB)) {
+				} else if (purple_strequal(val, NS_IBB)) {
 					jsx->stream_method |= STREAM_METHOD_IBB;
 					if (!found_method) {
 						/* we haven't tried to init a bytestream session, yet
@@ -1689,7 +1689,7 @@
 	goffset filesize = 0;
 
 	if(!(profile = purple_xmlnode_get_attrib(si, "profile")) ||
-			strcmp(profile, NS_SI_FILE_TRANSFER))
+			!purple_strequal(profile, NS_SI_FILE_TRANSFER))
 		return;
 
 	if(!(stream_id = purple_xmlnode_get_attrib(si, "id")))
@@ -1726,15 +1726,15 @@
 
 	for(field = purple_xmlnode_get_child(x, "field"); field; field = purple_xmlnode_get_next_twin(field)) {
 		const char *var = purple_xmlnode_get_attrib(field, "var");
-		if(var && !strcmp(var, "stream-method")) {
+		if(purple_strequal(var, "stream-method")) {
 			for(option = purple_xmlnode_get_child(field, "option"); option;
 					option = purple_xmlnode_get_next_twin(option)) {
 				if((value = purple_xmlnode_get_child(option, "value"))) {
 					char *val;
 					if((val = purple_xmlnode_get_data(value))) {
-						if(!strcmp(val, NS_BYTESTREAMS)) {
+						if(purple_strequal(val, NS_BYTESTREAMS)) {
 							jsx->stream_method |= STREAM_METHOD_BYTESTREAMS;
-						} else if(!strcmp(val, NS_IBB)) {
+						} else if(purple_strequal(val, NS_IBB)) {
 							jsx->stream_method |= STREAM_METHOD_IBB;
 						}
 						g_free(val);
--- a/libpurple/protocols/jabber/useravatar.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/useravatar.c	Wed Jun 14 23:40:17 2017 -0500
@@ -358,17 +358,17 @@
 		for(info = metadata->child; info; info = info->next) {
 			if(info->type == PURPLE_XMLNODE_TYPE_TAG)
 				has_children = TRUE;
-			if(info->type == PURPLE_XMLNODE_TYPE_TAG && !strcmp(info->name,"info")) {
+			if(info->type == PURPLE_XMLNODE_TYPE_TAG && purple_strequal(info->name,"info")) {
 				const char *type = purple_xmlnode_get_attrib(info,"type");
 				const char *id = purple_xmlnode_get_attrib(info,"id");
 
-				if(checksum && id && !strcmp(id, checksum)) {
+				if(checksum && id && purple_strequal(id, checksum)) {
 					/* we already have that avatar, so we don't have to do anything */
 					goodinfo = NULL;
 					break;
 				}
 				/* We'll only pick the png one for now. It's a very nice image format anyways. */
-				if(type && id && !goodinfo && !strcmp(type, "image/png"))
+				if(id && !goodinfo && purple_strequal(type, "image/png"))
 					goodinfo = info;
 			}
 		}
--- a/libpurple/protocols/jabber/usermood.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/usermood.c	Wed Jun 14 23:40:17 2017 -0500
@@ -127,7 +127,7 @@
 	g_return_val_if_fail(name && *name, NULL);
 
 	for (i = 0; moods[i].mood != NULL; ++i) {
-		if (g_str_equal(name, moods[i].mood)) {
+		if (purple_strequal(name, moods[i].mood)) {
 			return &moods[i];
 		}
 	}
@@ -151,7 +151,7 @@
 		return;
 	for (moodinfo = mood->child; moodinfo; moodinfo = moodinfo->next) {
 		if (moodinfo->type == PURPLE_XMLNODE_TYPE_TAG) {
-			if (!strcmp(moodinfo->name, "text")) {
+			if (purple_strequal(moodinfo->name, "text")) {
 				if (!moodtext) /* only pick the first one */
 					moodtext = purple_xmlnode_get_data(moodinfo);
 			} else {
--- a/libpurple/protocols/jabber/usertune.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/usertune.c	Wed Jun 14 23:40:17 2017 -0500
@@ -58,11 +58,11 @@
 		return; /* huh? */
 	for (tuneinfo = tune->child; tuneinfo; tuneinfo = tuneinfo->next) {
 		if (tuneinfo->type == PURPLE_XMLNODE_TYPE_TAG) {
-			if (!strcmp(tuneinfo->name, "artist")) {
+			if (purple_strequal(tuneinfo->name, "artist")) {
 				if (tuneinfodata.artist == NULL) /* only pick the first one */
 					tuneinfodata.artist = purple_xmlnode_get_data(tuneinfo);
 				valid = TRUE;
-			} else if (!strcmp(tuneinfo->name, "length")) {
+			} else if (purple_strequal(tuneinfo->name, "length")) {
 				if (tuneinfodata.time == -1) {
 					char *length = purple_xmlnode_get_data(tuneinfo);
 					if (length)
@@ -71,19 +71,19 @@
 					if (tuneinfodata.time > 0)
 						valid = TRUE;
 				}
-			} else if (!strcmp(tuneinfo->name, "source")) {
+			} else if (purple_strequal(tuneinfo->name, "source")) {
 				if (tuneinfodata.album == NULL) /* only pick the first one */
 					tuneinfodata.album = purple_xmlnode_get_data(tuneinfo);
 				valid = TRUE;
-			} else if (!strcmp(tuneinfo->name, "title")) {
+			} else if (purple_strequal(tuneinfo->name, "title")) {
 				if (tuneinfodata.title == NULL) /* only pick the first one */
 					tuneinfodata.title = purple_xmlnode_get_data(tuneinfo);
 				valid = TRUE;
-			} else if (!strcmp(tuneinfo->name, "track")) {
+			} else if (purple_strequal(tuneinfo->name, "track")) {
 				if (tuneinfodata.track == NULL) /* only pick the first one */
 					tuneinfodata.track = purple_xmlnode_get_data(tuneinfo);
 				valid = TRUE;
-			} else if (!strcmp(tuneinfo->name, "uri")) {
+			} else if (purple_strequal(tuneinfo->name, "uri")) {
 				if (tuneinfodata.url == NULL) /* only pick the first one */
 					tuneinfodata.url = purple_xmlnode_get_data(tuneinfo);
 				valid = TRUE;
--- a/libpurple/protocols/jabber/xdata.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/jabber/xdata.c	Wed Jun 14 23:40:17 2017 -0500
@@ -64,7 +64,7 @@
 				PurpleRequestField *field = flds->data;
 				const char *id = purple_request_field_get_id(field);
 				int handleindex;
-				if(strcmp(id, "libpurple:jabber:xdata:actions"))
+				if(!purple_strequal(id, "libpurple:jabber:xdata:actions"))
 					continue;
 				handleindex = GPOINTER_TO_INT(purple_request_field_choice_get_value(field));
 				actionhandle = g_strdup(g_list_nth_data(data->actions, handleindex));
@@ -230,12 +230,12 @@
 		if(!type)
 			type = "text-single";
 
-		if(!var && strcmp(type, "fixed"))
+		if(!var && !purple_strequal(type, "fixed"))
 			continue;
 		if(!label)
 			label = var;
 
-		if(!strcmp(type, "text-private")) {
+		if(purple_strequal(type, "text-private")) {
 			if((valuenode = purple_xmlnode_get_child(fn, "value")))
 				value = purple_xmlnode_get_data(valuenode);
 
@@ -247,7 +247,7 @@
 			g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_SINGLE));
 
 			g_free(value);
-		} else if(!strcmp(type, "text-multi") || !strcmp(type, "jid-multi")) {
+		} else if(purple_strequal(type, "text-multi") || purple_strequal(type, "jid-multi")) {
 			GString *str = g_string_new("");
 
 			for(valuenode = purple_xmlnode_get_child(fn, "value"); valuenode;
@@ -267,13 +267,13 @@
 			g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_MULTI));
 
 			g_string_free(str, TRUE);
-		} else if(!strcmp(type, "list-single") || !strcmp(type, "list-multi")) {
+		} else if(purple_strequal(type, "list-single") || purple_strequal(type, "list-multi")) {
 			PurpleXmlNode *optnode;
 			GList *selected = NULL;
 
 			field = purple_request_field_list_new(var, label);
 
-			if(!strcmp(type, "list-multi")) {
+			if(purple_strequal(type, "list-multi")) {
 				purple_request_field_list_set_multi_select(field, TRUE);
 				g_hash_table_replace(data->fields, g_strdup(var),
 						GINT_TO_POINTER(JABBER_X_DATA_LIST_MULTI));
@@ -316,7 +316,7 @@
 				selected = g_list_delete_link(selected, selected);
 			}
 
-		} else if(!strcmp(type, "boolean")) {
+		} else if(purple_strequal(type, "boolean")) {
 			gboolean def = FALSE;
 
 			if((valuenode = purple_xmlnode_get_child(fn, "value")))
@@ -332,7 +332,7 @@
 			g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_BOOLEAN));
 
 			g_free(value);
-		} else if(!strcmp(type, "fixed")) {
+		} else if(purple_strequal(type, "fixed")) {
 			if((valuenode = purple_xmlnode_get_child(fn, "value")))
 				value = purple_xmlnode_get_data(valuenode);
 
@@ -342,7 +342,7 @@
 
 				g_free(value);
 			}
-		} else if(!strcmp(type, "hidden")) {
+		} else if(purple_strequal(type, "hidden")) {
 			if((valuenode = purple_xmlnode_get_child(fn, "value")))
 				value = purple_xmlnode_get_data(valuenode);
 
@@ -362,7 +362,7 @@
 					value ? value : "", FALSE);
 			purple_request_field_group_add_field(group, field);
 
-			if(!strcmp(type, "jid-single")) {
+			if(purple_strequal(type, "jid-single")) {
 				purple_request_field_set_type_hint(field, "screenname");
 				g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_JID_SINGLE));
 			} else {
--- a/libpurple/protocols/novell/nmconn.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/novell/nmconn.c	Wed Jun 14 23:40:17 2017 -0500
@@ -30,6 +30,8 @@
 #include <windows.h>
 #endif
 
+#include "util.h"
+
 #define NO_ESCAPE(ch) ((ch == 0x20) || (ch >= 0x30 && ch <= 0x39) || \
 					(ch >= 0x41 && ch <= 0x5a) || (ch >= 0x61 && ch <= 0x7a))
 
@@ -426,7 +428,7 @@
 
 	/* Write headers */
 	if (rc == NM_OK) {
-		if (strcmp("login", cmd) == 0) {
+		if (purple_strequal("login", cmd)) {
 			bytes_to_send = g_snprintf(buffer, sizeof(buffer),
 									   "Host: %s:%d\r\n\r\n", conn->addr, conn->port);
 			ret = nm_tcp_write(conn, buffer, bytes_to_send);
@@ -522,7 +524,7 @@
 
 	/* Finish reading header, in the future we might want to do more processing here */
 	/* TODO: handle more general redirects in the future */
-	while ((rc == NM_OK) && (strcmp(buffer, "\r\n") != 0)) {
+	while ((rc == NM_OK) && (!purple_strequal(buffer, "\r\n"))) {
 		rc = read_line(conn, buffer, sizeof(buffer));
 	}
 
--- a/libpurple/protocols/novell/nmcontact.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/novell/nmcontact.c	Wed Jun 14 23:40:17 2017 -0500
@@ -23,6 +23,7 @@
 #include "nmcontact.h"
 #include "nmfield.h"
 #include "nmuser.h"
+#include "util.h"
 
 struct _NMContact
 {
@@ -83,7 +84,7 @@
 	NMField *field;
 
 	if ( fields == NULL || fields->tag == NULL || fields->ptr_value == 0 ||
-		 strcmp(fields->tag, NM_A_FA_CONTACT) )
+		 !purple_strequal(fields->tag, NM_A_FA_CONTACT) )
 	{
 		return NULL;
 	}
--- a/libpurple/protocols/novell/nmrtf.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/novell/nmrtf.c	Wed Jun 14 23:40:17 2017 -0500
@@ -30,6 +30,7 @@
 #include <string.h>
 #include "nmrtf.h"
 #include "debug.h"
+#include "util.h"
 
 /* Internal RTF parser error codes */
 #define NMRTF_OK 0                      /* Everything's fine! */
@@ -707,7 +708,7 @@
     int idx;
 
     for (idx = 0; idx < table_size; idx++) {
-        if (strcmp(keyword, rtf_symbols[idx].keyword) == 0)
+        if (purple_strequal(keyword, rtf_symbols[idx].keyword))
             break;
 	}
 
--- a/libpurple/protocols/novell/nmuser.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/novell/nmuser.c	Wed Jun 14 23:40:17 2017 -0500
@@ -1449,7 +1449,7 @@
 	for (i = 0; i < num_folders; i++) {
 		temp = nm_folder_get_subfolder(user->root_folder, i);
 		tname = nm_folder_get_name(temp);
-		if (tname && (strcmp(tname, name) == 0)) {
+		if (tname && purple_strequal(tname, name)) {
 			folder = temp;
 			break;
 		}
@@ -1568,7 +1568,7 @@
 	cmd = nm_request_get_cmd(request);
 	if (ret_code == NM_OK && cmd != NULL) {
 
-		if (strcmp("login", cmd) == 0) {
+		if (purple_strequal("login", cmd)) {
 
 			user->user_record = nm_create_user_record_from_fields(fields);
 
@@ -1578,11 +1578,11 @@
 			nm_create_contact_list(user);
 			done = _create_privacy_list(user, request);
 
-		} else if (strcmp("setstatus", cmd) == 0) {
+		} else if (purple_strequal("setstatus", cmd)) {
 
 			/* Nothing to do */
 
-		} else if (strcmp("createconf", cmd) == 0) {
+		} else if (purple_strequal("createconf", cmd)) {
 
 			conf = (NMConference *) nm_request_get_data(request);
 
@@ -1599,12 +1599,12 @@
 			nm_conference_list_add(user, conf);
 			nm_release_conference(conf);
 
-		} else if (strcmp("leaveconf", cmd) == 0) {
+		} else if (purple_strequal("leaveconf", cmd)) {
 
 			conf = (NMConference *) nm_request_get_data(request);
 			nm_conference_list_remove(user, conf);
 
-		} else if (strcmp("joinconf", cmd) == 0) {
+		} else if (purple_strequal("joinconf", cmd)) {
 			GSList *list = NULL, *node;
 
 			conf = nm_request_get_data(request);
@@ -1651,7 +1651,7 @@
 				}
 			}
 
-		} else if (strcmp("getdetails", cmd) == 0) {
+		} else if (purple_strequal("getdetails", cmd)) {
 
 			locate = nm_locate_field(NM_A_FA_RESULTS, fields);
 			while (locate && locate->ptr_value != 0) {
@@ -1682,11 +1682,11 @@
 				locate = nm_locate_field(NM_A_FA_RESULTS, locate+1);
 			}
 
-		} else if (strcmp("createfolder", cmd) == 0) {
+		} else if (purple_strequal("createfolder", cmd)) {
 
 			_update_contact_list(user, fields);
 
-		} else if (strcmp("createcontact", cmd) == 0) {
+		} else if (purple_strequal("createcontact", cmd)) {
 
 			_update_contact_list(user, fields);
 
@@ -1710,15 +1710,15 @@
 
 			}
 
-		} else if (strcmp("deletecontact", cmd) == 0) {
+		} else if (purple_strequal("deletecontact", cmd)) {
 
 			_update_contact_list(user, fields);
 
-		} else if (strcmp("movecontact", cmd) == 0) {
+		} else if (purple_strequal("movecontact", cmd)) {
 
 			_update_contact_list(user, fields);
 
-		} else if (strcmp("getstatus", cmd) == 0) {
+		} else if (purple_strequal("getstatus", cmd)) {
 
 			locate = nm_locate_field(NM_A_SZ_STATUS, fields);
 			if (locate) {
@@ -1727,11 +1727,11 @@
 										  atoi((char *) locate->ptr_value), NULL);
 			}
 
-		} else if (strcmp("updateitem", cmd) == 0) {
+		} else if (purple_strequal("updateitem", cmd)) {
 
 			/* Nothing extra to do here */
 
-		} else if (strcmp("createblock", cmd) == 0) {
+		} else if (purple_strequal("createblock", cmd)) {
 			if ((locate = nm_locate_field(NM_A_BLOCKING_DENY_LIST, fields))) {
 				if (locate->ptr_value) {
 					user->deny_list = g_slist_append(user->deny_list, g_strdup((char *)locate->ptr_value));
@@ -1741,7 +1741,7 @@
 					user->allow_list = g_slist_append(user->allow_list, g_strdup((char *)locate->ptr_value));
 				}
 			}
-		} else if (strcmp("updateblocks", cmd) == 0) {
+		} else if (purple_strequal("updateblocks", cmd)) {
 			/* nothing to do here */
 		} else {
 
@@ -1969,7 +1969,7 @@
 		return;
 
 	/* Is it wrapped in a RESULTS array? */
-	if (strcmp(fields->tag, NM_A_FA_RESULTS) == 0) {
+	if (purple_strequal(fields->tag, NM_A_FA_RESULTS)) {
 		list = (NMField *) fields->ptr_value;
 	} else {
 		list = fields;
--- a/libpurple/protocols/novell/novell.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/novell/novell.c	Wed Jun 14 23:40:17 2017 -0500
@@ -294,7 +294,7 @@
 								nm_user_record_get_display_id(user_record));
 
 		alias = purple_buddy_get_alias(buddy);
-		if (alias == NULL || *alias == '\0' || (strcmp(alias, purple_buddy_get_name(buddy)) == 0)) {
+		if (alias == NULL || *alias == '\0' || purple_strequal(alias, purple_buddy_get_name(buddy))) {
 			purple_buddy_set_local_alias(buddy,
 								   nm_user_record_get_full_name(user_record));
 
@@ -360,7 +360,7 @@
 			if (display_id == NULL)
 				display_id = nm_contact_get_dn(new_contact);
 
-			if (alias && strcmp(alias, display_id)) {
+			if (alias && !purple_strequal(alias, display_id)) {
 
 				/* The user requested an alias, tell the server about it. */
 				rc = nm_send_rename_contact(user, new_contact, alias,
@@ -1267,7 +1267,7 @@
 					continue;
 				buddy = (PurpleBuddy *) bnode;
 				if (purple_buddy_get_account(buddy) == user->client_data) {
-					if (strcmp(gname, NM_ROOT_FOLDER_NAME) == 0)
+					if (purple_strequal(gname, NM_ROOT_FOLDER_NAME))
 						gname = "";
 					folder = nm_find_folder(user, gname);
 					if (folder == NULL ||
@@ -1498,19 +1498,19 @@
 {
 	if (tag == NULL) return NULL;
 
-	if (strcmp(tag, "telephoneNumber") == 0)
+	if (purple_strequal(tag, "telephoneNumber"))
 		return _("Telephone Number");
-	else if (strcmp(tag, "L") == 0)
+	else if (purple_strequal(tag, "L"))
 		return _("Location");
-	else if (strcmp(tag, "OU") == 0)
+	else if (purple_strequal(tag, "OU"))
 		return _("Department");
-	else if (strcmp(tag, "personalTitle") == 0)
+	else if (purple_strequal(tag, "personalTitle"))
 		return _("Personal Title");
-	else if (strcmp(tag, "Title") == 0)
+	else if (purple_strequal(tag, "Title"))
 		return _("Job Title");
-	else if (strcmp(tag, "mailstop") == 0)
+	else if (purple_strequal(tag, "mailstop"))
 		return _("Mailstop");
-	else if (strcmp(tag, "Internet EMail Address") == 0)
+	else if (purple_strequal(tag, "Internet EMail Address"))
 		return _("Email Address");
 	else
 		return tag;
@@ -2595,14 +2595,14 @@
 	 */
 	alias = purple_buddy_get_alias(buddy);
 	bname = purple_buddy_get_name(buddy);
-	if (alias && strcmp(alias, bname))
+	if (alias && !purple_strequal(alias, bname))
 		nm_contact_set_display_name(contact, alias);
 
 	purple_blist_remove_buddy(buddy);
 	buddy = NULL;
 
 	gname = purple_group_get_name(group);
-	if (strcmp(gname, NM_ROOT_FOLDER_NAME) == 0) {
+	if (purple_strequal(gname, NM_ROOT_FOLDER_NAME)) {
 		gname = "";
 	}
 
@@ -2639,7 +2639,7 @@
 	user = purple_connection_get_protocol_data(gc);
 	if (user && (dn = nm_lookup_dn(user, purple_buddy_get_name(buddy)))) {
 		gname = purple_group_get_name(group);
-		if (strcmp(gname, NM_ROOT_FOLDER_NAME) == 0) {
+		if (purple_strequal(gname, NM_ROOT_FOLDER_NAME)) {
 			gname = "";
 		}
 		folder = nm_find_folder(user, gname);
@@ -2721,7 +2721,7 @@
 					buddy = purple_blist_find_buddy_in_group(user->client_data,
 													 name, group);
 					balias = buddy ? purple_buddy_get_local_alias(buddy) : NULL;
-					if (balias && strcmp(balias, alias))
+					if (balias && !purple_strequal(balias, alias))
 						purple_buddy_set_local_alias(buddy, alias);
 				}
 
@@ -2756,7 +2756,7 @@
 	if (user && (dn = nm_lookup_dn(user, name))) {
 
 		/* Find the old folder */
-		if (strcmp(old_group_name, NM_ROOT_FOLDER_NAME) == 0) {
+		if (purple_strequal(old_group_name, NM_ROOT_FOLDER_NAME)) {
 			old_folder = nm_get_root_folder(user);
 			if (nm_folder_find_contact(old_folder, dn) == NULL)
 				old_folder = nm_find_folder(user, old_group_name);
@@ -2769,7 +2769,7 @@
 			/* Find the new folder */
 			new_folder = nm_find_folder(user, new_group_name);
 			if (new_folder == NULL) {
-				if (strcmp(new_group_name, NM_ROOT_FOLDER_NAME) == 0)
+				if (purple_strequal(new_group_name, NM_ROOT_FOLDER_NAME))
 					new_folder = nm_get_root_folder(user);
 			}
 
@@ -2822,7 +2822,7 @@
 			return;
 		}
 
-		if (strcmp(old_name, NM_ROOT_FOLDER_NAME) == 0) {
+		if (purple_strequal(old_name, NM_ROOT_FOLDER_NAME)) {
 			/* Can't rename the root folder ... need to revisit this */
 			return;
 		}
@@ -2916,7 +2916,7 @@
 	id = purple_status_get_id(status);
 
 	/* Only go idle if active status is available  */
-	if (!strcmp(id, NOVELL_STATUS_TYPE_AVAILABLE)) {
+	if (purple_strequal(id, NOVELL_STATUS_TYPE_AVAILABLE)) {
 		if (time > 0) {
 			rc = nm_send_set_status(user, NM_STATUS_AWAY_IDLE, NULL, NULL, NULL, NULL);
 		} else {
--- a/libpurple/protocols/null/nullprpl.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/null/nullprpl.c	Wed Jun 14 23:40:17 2017 -0500
@@ -117,7 +117,7 @@
   PurpleConnection *gc = (PurpleConnection *)(data);
   GcFuncData *gcfdata = (GcFuncData *)userdata;
 
-  if (!strcmp(purple_account_get_protocol_id(purple_connection_get_account(gc)), "null"))
+  if (purple_strequal(purple_account_get_protocol_id(purple_connection_get_account(gc)), "null"))
     gcfdata->fn(gcfdata->from, gc, gcfdata->userdata);
 }
 
@@ -171,9 +171,9 @@
     const char *status_id = purple_status_get_id(status);
     const char *message = purple_status_get_attr_string(status, "message");
 
-    if (!strcmp(status_id, NULL_STATUS_ONLINE) ||
-        !strcmp(status_id, NULL_STATUS_AWAY) ||
-        !strcmp(status_id, NULL_STATUS_OFFLINE)) {
+    if (purple_strequal(status_id, NULL_STATUS_ONLINE) ||
+        purple_strequal(status_id, NULL_STATUS_AWAY) ||
+        purple_strequal(status_id, NULL_STATUS_OFFLINE)) {
       purple_debug_info("nullprpl", "%s sees that %s is %s: %s\n",
                         from_username, to_username, status_id, message);
       purple_protocol_got_user_status(purple_connection_get_account(from), to_username, status_id,
@@ -899,8 +899,7 @@
                     purple_conversation_get_name(PURPLE_CONVERSATION(chat)), topic);
 
   last_topic = purple_chat_conversation_get_topic(chat);
-  if ((!topic && !last_topic) ||
-      (topic && last_topic && !strcmp(topic, last_topic)))
+  if (purple_strequal(topic, last_topic))
     return;  /* topic is unchanged, this is a noop */
 
   foreach_gc_in_chat(set_chat_topic_fn, gc, id, (gpointer)topic);
--- a/libpurple/protocols/oscar/clientlogin.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/oscar/clientlogin.c	Wed Jun 14 23:40:17 2017 -0500
@@ -82,17 +82,19 @@
 {
 	PurpleXmlNode *text;
 	PurpleXmlNode *status_code_node;
-	gchar *status_code;
 	gboolean have_error_code = TRUE;
 	gchar *err = NULL;
 	gchar *details = NULL;
 
 	status_code_node = purple_xmlnode_get_child(resp, "statusCode");
 	if (status_code_node) {
+		gchar *status_code;
+
 		/* We can get 200 OK here if the server omitted something we think it shouldn't have (see #12783).
 		 * No point in showing the "Ok" string to the user.
 		 */
-		if ((status_code = purple_xmlnode_get_data_unescaped(status_code_node)) && strcmp(status_code, "200") == 0) {
+		status_code = purple_xmlnode_get_data_unescaped(status_code_node);
+		if (purple_strequal(status_code, "200")) {
 			have_error_code = FALSE;
 		}
 	}
@@ -257,12 +259,12 @@
 		return FALSE;
 	}
 
-	if (strcmp(encryption_type, OSCAR_NO_ENCRYPTION) != 0) {
+	if (!purple_strequal(encryption_type, OSCAR_NO_ENCRYPTION)) {
 		tls_node = purple_xmlnode_get_child(data_node, "tlsCertName");
 		if (tls_node != NULL) {
 			*tls_certname = purple_xmlnode_get_data_unescaped(tls_node);
 		} else {
-			if (strcmp(encryption_type, OSCAR_OPPORTUNISTIC_ENCRYPTION) == 0) {
+			if (purple_strequal(encryption_type, OSCAR_OPPORTUNISTIC_ENCRYPTION)) {
 				purple_debug_warning("oscar", "We haven't received a tlsCertName to use. We will not do SSL to BOS.\n");
 			} else {
 				purple_debug_error("oscar", "startOSCARSession was missing tlsCertName: %s\n", response);
@@ -368,7 +370,7 @@
 				od->icq ? ICQ_DEFAULT_DIST_ID : AIM_DEFAULT_DIST_ID),
 			get_client_key(od),
 			(gint64)hosttime,
-			strcmp(encryption_type, OSCAR_NO_ENCRYPTION) != 0 ? 1 : 0);
+			!purple_strequal(encryption_type, OSCAR_NO_ENCRYPTION));
 	signature = generate_signature("GET", get_start_oscar_session_url(od),
 			query_string, session_key);
 
@@ -453,7 +455,7 @@
 	}
 
 	/* Make sure the status code was 200 */
-	if (strcmp(tmp, "200") != 0)
+	if (!purple_strequal(tmp, "200"))
 	{
 		int status_code, status_detail_code = 0;
 
--- a/libpurple/protocols/oscar/family_icbm.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/oscar/family_icbm.c	Wed Jun 14 23:40:17 2017 -0500
@@ -2037,7 +2037,7 @@
 	if (!account)
 		return -EINVAL;
 
-	/* if (!strcmp(account->username, sn))
+	/* if (purple_strequal(account->username, sn))
 		icq_im_xstatus_request(od, sn); */
 
 	status = purple_presence_get_active_status(purple_account_get_presence(account));
--- a/libpurple/protocols/oscar/family_locate.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/oscar/family_locate.c	Wed Jun 14 23:40:17 2017 -0500
@@ -1074,7 +1074,7 @@
 						 * with no mood icon. */
 						if (*icqmood) {
 							for (i = 0; icqmoods[i].icqmood; i++) {
-								if (!strcmp(icqmood, icqmoods[i].icqmood)) {
+								if (purple_strequal(icqmood, icqmoods[i].icqmood)) {
 									mood = icqmoods[i].mood;
 									break; /* should only match once... */
 								}
@@ -1515,7 +1515,7 @@
 		/* We check that description is not NULL to exclude
 		 * duplicates, like the typing duplicate. */
 		if (icq_purple_moods[i].description &&
-		    !strcmp(mood, icq_custom_icons[i].mood)) {
+		    purple_strequal(mood, icq_custom_icons[i].mood)) {
 			return icq_purple_moods[i].description;
 		}
 	}
@@ -1535,7 +1535,7 @@
 		/* We check that description is not NULL to exclude
 		 * duplicates, like the typing duplicate. */
 		if (icq_purple_moods[i].description &&
-		    !strcmp(mood, icq_custom_icons[i].mood)) {
+		    purple_strequal(mood, icq_custom_icons[i].mood)) {
 			return (guint8 *)icq_custom_icons[i].data;
 		}
 	}
--- a/libpurple/protocols/oscar/oscar.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/oscar/oscar.c	Wed Jun 14 23:40:17 2017 -0500
@@ -577,7 +577,7 @@
 
 	gc = data;
 	od = purple_connection_get_protocol_data(gc);
-	report_idle = strcmp((const char *)value, "none") != 0;
+	report_idle = !purple_strequal((const char *)value, "none");
 	presence = aim_ssi_getpresence(&od->ssi.local);
 
 	if (report_idle)
@@ -727,7 +727,7 @@
 	}
 
 	flags = PURPLE_CONNECTION_FLAG_HTML;
-	if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq")) {
+	if (purple_strequal(purple_account_get_protocol_id(account), "prpl-icq")) {
 		od->icq = TRUE;
 	} else {
 		flags |= PURPLE_CONNECTION_FLAG_AUTO_RESP;
@@ -735,7 +735,7 @@
 
 	/* Set this flag based on the protocol_id rather than the username,
 	   because that is what's tied to the get_moods protocol callback. */
-	if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq"))
+	if (purple_strequal(purple_account_get_protocol_id(account), "prpl-icq"))
 		flags |= PURPLE_CONNECTION_FLAG_SUPPORT_MOODS;
 
 	purple_connection_set_flags(gc, flags);
@@ -1345,7 +1345,7 @@
 		if (b != NULL)
 			saved_b16 = purple_buddy_icons_get_checksum_for_user(b);
 
-		if (!b16 || !saved_b16 || strcmp(b16, saved_b16)) {
+		if (!b16 || !saved_b16 || !purple_strequal(b16, saved_b16)) {
 			/* Invalidate the old icon for this user */
 			purple_buddy_icons_set_for_user(account, info->bn, NULL, 0, NULL);
 
@@ -1918,7 +1918,7 @@
 			smsmsg = byte_stream_getstr(&qbs, smslen);
 
 			/* Check if this is an SMS being sent from server */
-			if ((smstype == 0) && (!strcmp(tagstr, "ICQSMS")) && (smsmsg != NULL))
+			if ((smstype == 0) && (purple_strequal(tagstr, "ICQSMS")) && (smsmsg != NULL))
 			{
 				xmlroot = purple_xmlnode_from_str(smsmsg, -1);
 				if (xmlroot != NULL)
@@ -2744,7 +2744,7 @@
 		purple_serv_set_info(gc, purple_account_get_user_info(account));
 
 	username = purple_account_get_username(account);
-	if (!od->icq && strcmp(username, purple_connection_get_display_name(gc)) != 0) {
+	if (!od->icq && !purple_strequal(username, purple_connection_get_display_name(gc))) {
 		/*
 		 * Format the username for AIM accounts if it's different
 		 * than what's currently set.
@@ -3328,31 +3328,31 @@
 	if (purple_account_get_bool(account, "web_aware", OSCAR_DEFAULT_WEB_AWARE))
 		data |= AIM_ICQ_STATE_WEBAWARE;
 
-	if (!strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE))
+	if (purple_strequal(status_id, OSCAR_STATUS_ID_AVAILABLE))
 		data |= AIM_ICQ_STATE_NORMAL;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_AWAY))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_AWAY))
 		data |= AIM_ICQ_STATE_AWAY;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_DND))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_DND))
 		data |= AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_NA))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_NA))
 		data |= AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_OCCUPIED))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_OCCUPIED))
 		data |= AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_FREE4CHAT))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_FREE4CHAT))
 		data |= AIM_ICQ_STATE_CHAT;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_INVISIBLE))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_INVISIBLE))
 		data |= AIM_ICQ_STATE_INVISIBLE;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_EVIL))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_EVIL))
 		data |= AIM_ICQ_STATE_EVIL;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_DEPRESSION))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_DEPRESSION))
 		data |= AIM_ICQ_STATE_DEPRESSION;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_ATWORK))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_ATWORK))
 		data |= AIM_ICQ_STATE_ATWORK;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_ATHOME))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_ATHOME))
 		data |= AIM_ICQ_STATE_ATHOME;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_LUNCH))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_LUNCH))
 		data |= AIM_ICQ_STATE_LUNCH;
-	else if (!strcmp(status_id, OSCAR_STATUS_ID_CUSTOM))
+	else if (purple_strequal(status_id, OSCAR_STATUS_ID_CUSTOM))
 		data |= AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY;
 
 	return data;
@@ -3603,7 +3603,7 @@
 void oscar_move_buddy(PurpleConnection *gc, const char *name, const char *old_group, const char *new_group) {
 	OscarData *od = purple_connection_get_protocol_data(gc);
 
-	if (od->ssi.received_data && strcmp(old_group, new_group)) {
+	if (od->ssi.received_data && !purple_strequal(old_group, new_group)) {
 		purple_debug_info("oscar",
 				   "ssi: moving buddy %s from group %s to group %s\n", name, old_group, new_group);
 		aim_ssi_movebuddy(od, old_group, new_group, name);
@@ -3837,7 +3837,7 @@
 		gboolean report_idle;
 
 		idle_reporting_pref = purple_prefs_get_string("/purple/away/idle_reporting");
-		report_idle = strcmp(idle_reporting_pref, "none") != 0;
+		report_idle = !purple_strequal(idle_reporting_pref, "none");
 
 		if (report_idle)
 			aim_ssi_setpresence(od, tmp | AIM_SSI_PRESENCE_FLAG_SHOWIDLE);
@@ -5515,7 +5515,7 @@
 	} else { /* Otherwise find an active account for the protocol */
 		GList *l = purple_accounts_get_all();
 		while (l) {
-			if (!strcmp(protocol, purple_account_get_protocol_id(l->data))
+			if (purple_strequal(protocol, purple_account_get_protocol_id(l->data))
 					&& purple_account_is_connected(l->data)) {
 				acct = l->data;
 				break;
--- a/libpurple/protocols/oscar/peer.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/oscar/peer.c	Wed Jun 14 23:40:17 2017 -0500
@@ -843,7 +843,7 @@
 				peer_connection_verified_established_cb, conn);
 
 		if ((conn->verifiedip == NULL) ||
-			strcmp(conn->verifiedip, conn->clientip))
+			!purple_strequal(conn->verifiedip, conn->clientip))
 		{
 			conn->client_connect_data = purple_proxy_connect(NULL, account,
 					conn->clientip, conn->port,
--- a/libpurple/protocols/oscar/rxhandlers.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/oscar/rxhandlers.c	Wed Jun 14 23:40:17 2017 -0500
@@ -38,7 +38,7 @@
 	aim_module_t *cur;
 
 	for (cur = (aim_module_t *)od->modlistv; cur; cur = cur->next) {
-		if (strcmp(name, cur->name) == 0)
+		if (purple_strequal(name, cur->name))
 			return cur;
 	}
 
--- a/libpurple/protocols/oscar/userinfo.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/oscar/userinfo.c	Wed Jun 14 23:40:17 2017 -0500
@@ -250,7 +250,7 @@
 				/* 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))
+				if (status_name && message && purple_strequal(status_name, message))
 					status_name = NULL;
 
 				tmp = g_strdup_printf("%s%s%s",
--- a/libpurple/protocols/sametime/sametime.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/sametime/sametime.c	Wed Jun 14 23:40:17 2017 -0500
@@ -697,7 +697,7 @@
 
     /* if the group has an owner and we're not it, skip it */
     owner = purple_blist_node_get_string(gn, GROUP_KEY_OWNER);
-    if(owner && strcmp(owner, purple_account_get_username(acct)))
+    if(owner && !purple_strequal(owner, purple_account_get_username(acct)))
       continue;
 
     /* the group's actual name may be different from the purple group's
@@ -950,8 +950,8 @@
 
     DEBUG_INFO("found group named %s, owned by %s\n", NSTR(n), NSTR(o));
 
-    if(n && !strcmp(n, name)) {
-      if(!o || !strcmp(o, owner)) {
+    if(n && purple_strequal(n, name)) {
+      if(!o || purple_strequal(o, owner)) {
 	DEBUG_INFO("that'll work\n");
 	group = (PurpleGroup *) gn;
 	break;
@@ -1182,7 +1182,7 @@
 
     /* dynamic group belonging to this account. don't prune contents */
     owner = purple_blist_node_get_string(gn, GROUP_KEY_OWNER);
-    if(owner && !strcmp(owner, acct_n))
+    if(owner && purple_strequal(owner, acct_n))
        continue;
 
     /* we actually are synching by this key as opposed to the group
@@ -1214,7 +1214,7 @@
     gboolean del = TRUE;
 
     owner = purple_blist_node_get_string(gn, GROUP_KEY_OWNER);
-    if(owner && strcmp(owner, acct_n)) {
+    if(owner && !purple_strequal(owner, acct_n)) {
       /* it's a specialty group belonging to another account with some
 	 of our members in it, so don't fully delete it */
       del = FALSE;
@@ -1367,7 +1367,7 @@
 
   /* check if it's a NAB group for this account */
   owner = purple_blist_node_get_string(node, GROUP_KEY_OWNER);
-  if(owner && !strcmp(owner, purple_account_get_username(acct))) {
+  if(owner && purple_strequal(owner, purple_account_get_username(acct))) {
     act = purple_menu_action_new(_("Get Notes Address Book Info"),
                                PURPLE_CALLBACK(blist_menu_nab), pd, NULL);
     *menu = g_list_append(*menu, act);
@@ -1439,7 +1439,7 @@
     /* if the group is ownerless, or has an owner and we're not it,
        skip it */
     owner = purple_blist_node_get_string(l, GROUP_KEY_OWNER);
-    if(!owner || strcmp(owner, purple_account_get_username(acct)))
+    if(!owner || !purple_strequal(owner, purple_account_get_username(acct)))
       continue;
 
     gt = purple_blist_node_get_int(l, GROUP_KEY_TYPE);
@@ -1479,7 +1479,7 @@
 					 MW_PLUGIN_DEFAULT_HOST);
 
   if(purple_account_get_bool(account, MW_KEY_FORCE, FALSE) ||
-     !host || (! strcmp(current_host, host)) ||
+     !host || purple_strequal(current_host, host) ||
      (purple_proxy_connect(gc, account, host, port, connect_cb, pd) == NULL)) {
 
     /* if we're configured to force logins, or if we're being
@@ -4189,13 +4189,13 @@
   mwUserStatus_clone(&stat, mwSession_getUserStatus(session));
 
   /* determine the state */
-  if(! strcmp(state, MW_STATE_ACTIVE)) {
+  if(purple_strequal(state, MW_STATE_ACTIVE)) {
     stat.status = mwStatus_ACTIVE;
 
-  } else if(! strcmp(state, MW_STATE_AWAY)) {
+  } else if(purple_strequal(state, MW_STATE_AWAY)) {
     stat.status = mwStatus_AWAY;
 
-  } else if(! strcmp(state, MW_STATE_BUSY)) {
+  } else if(purple_strequal(state, MW_STATE_BUSY)) {
     stat.status = mwStatus_BUSY;
   }
 
@@ -4360,7 +4360,7 @@
       struct mwResolveMatch *match = res->matches->data;
 
       /* only one? that might be the right one! */
-      if(strcmp(res->name, match->id)) {
+      if(!purple_strequal(res->name, match->id)) {
 	/* uh oh, the single result isn't identical to the search
 	   term, better safe then sorry, so let's make sure it's who
 	   the user meant to add */
@@ -4649,7 +4649,7 @@
   ll = mwServiceConference_getConferences(srvc);
   for(l = ll; l; l = l->next) {
     struct mwConference *c = l->data;
-    if(! strcmp(name, mwConference_getName(c))) {
+    if(purple_strequal(name, mwConference_getName(c))) {
       conf = c;
       break;
     }
--- a/libpurple/protocols/silc/buddy.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/silc/buddy.c	Wed Jun 14 23:40:17 2017 -0500
@@ -902,13 +902,13 @@
 		unsigned char *verifyd;
 		SilcUInt32 verify_len;
 
-		if (!strcmp(serverpk.type, "silc-rsa"))
+		if (purple_strequal(serverpk.type, "silc-rsa"))
 		  type = SILC_PKCS_SILC;
-		else if (!strcmp(serverpk.type, "ssh-rsa"))
+		else if (purple_strequal(serverpk.type, "ssh-rsa"))
 		  type = SILC_PKCS_SSH2;
-		else if (!strcmp(serverpk.type, "x509v3-sign-rsa"))
+		else if (purple_strequal(serverpk.type, "x509v3-sign-rsa"))
 		  type = SILC_PKCS_X509V3;
-		else if (!strcmp(serverpk.type, "pgp-sign-rsa"))
+		else if (purple_strequal(serverpk.type, "pgp-sign-rsa"))
 		  type = SILC_PKCS_OPENPGP;
 
 		if (silc_pkcs_public_key_alloc(type, serverpk.data,
@@ -988,10 +988,10 @@
 		if (usericon) {
 			const char *type = silc_mime_get_field(usericon, "Content-Type");
 			if (type &&
-			    (!strcmp(type, "image/jpeg") ||
-			     !strcmp(type, "image/gif") ||
-			     !strcmp(type, "image/bmp") ||
-			     !strcmp(type, "image/png"))) {
+			    (purple_strequal(type, "image/jpeg") ||
+			     purple_strequal(type, "image/gif") ||
+			     purple_strequal(type, "image/bmp") ||
+			     purple_strequal(type, "image/png"))) {
 				const unsigned char *data;
 				SilcUInt32 data_len;
 				data = silc_mime_get_data(usericon, &data_len);
@@ -1741,7 +1741,7 @@
 	type = purple_image_get_mimetype(img);
 	if (type == NULL)
 		return;
-	if (g_strcmp0(purple_image_get_extension(img), "ico") == 0)
+	if (purple_strequal(purple_image_get_extension(img), "ico"))
 		return;
 
 	/* Add */
--- a/libpurple/protocols/silc/chat.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/silc/chat.c	Wed Jun 14 23:40:17 2017 -0500
@@ -375,7 +375,7 @@
 		set = 0;
 	else if (val && !curpass)
 		set = 1;
-	else if (val && curpass && strcmp(val, curpass))
+	else if (val && curpass && !purple_strequal(val, curpass))
 		set = 1;
 	else
 		set = -1;
--- a/libpurple/protocols/silc/ops.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/silc/ops.c	Wed Jun 14 23:40:17 2017 -0500
@@ -67,7 +67,7 @@
 
 	purple_debug_error("silc", "silc_say error: %s\n", tmp);
 
-	if (!strcmp(tmp, "Authentication failed"))
+	if (purple_strequal(tmp, "Authentication failed"))
 		reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
 
 	if (client != NULL)
@@ -124,7 +124,7 @@
 		const char *mtype;
 		SilcDList parts = silc_mime_get_multiparts(mime, &mtype);
 
-		if (!strcmp(mtype, "mixed")) {
+		if (purple_strequal(mtype, "mixed")) {
 			/* Contains multiple messages */
 			silc_dlist_start(parts);
 			while ((p = silc_dlist_get(parts)) != SILC_LIST_END) {
@@ -134,7 +134,7 @@
 			}
 		}
 
-		if (!strcmp(mtype, "alternative")) {
+		if (purple_strequal(mtype, "alternative")) {
 			/* Same message in alternative formats.  Kopete sends
 			   these.  Go in order from last to first. */
 			silc_dlist_end(parts);
@@ -595,7 +595,7 @@
 		tmp = va_arg(va, char *);      /* Old nick */
 		name = va_arg(va, char *);     /* New nick */
 
-		if (!strcmp(tmp, name))
+		if (purple_strequal(tmp, name))
 			break;
 
 		/* Change nick on all channels */
@@ -956,7 +956,7 @@
 	switch (command) {
 
 	case SILC_COMMAND_CMODE:
-		if (argc == 3 && !strcmp((char *)argv[2], "+C"))
+		if (argc == 3 && purple_strequal((char *)argv[2], "+C"))
 			sg->chpk = TRUE;
 		else
 			sg->chpk = FALSE;
@@ -1456,7 +1456,7 @@
 				if (!chat)
 					continue;
 				oldnick = purple_chat_conversation_get_nick(chat);
-				if (strcmp(oldnick,
+				if (!purple_strequal(oldnick,
 						purple_normalize(purple_conversation_get_account
 						(PURPLE_CONVERSATION(chat)), newnick))) {
 
--- a/libpurple/protocols/silc/silc.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/silc/silc.c	Wed Jun 14 23:40:17 2017 -0500
@@ -103,15 +103,15 @@
 		  SILC_UMODE_INDISPOSED |
 		  SILC_UMODE_PAGE);
 
-	if (!strcmp(state, "hyper"))
+	if (purple_strequal(state, "hyper"))
 		mode |= SILC_UMODE_HYPER;
-	else if (!strcmp(state, "away"))
+	else if (purple_strequal(state, "away"))
 		mode |= SILC_UMODE_GONE;
-	else if (!strcmp(state, "busy"))
+	else if (purple_strequal(state, "busy"))
 		mode |= SILC_UMODE_BUSY;
-	else if (!strcmp(state, "indisposed"))
+	else if (purple_strequal(state, "indisposed"))
 		mode |= SILC_UMODE_INDISPOSED;
-	else if (!strcmp(state, "page"))
+	else if (purple_strequal(state, "page"))
 		mode |= SILC_UMODE_PAGE;
 
 	/* Send UMODE */
@@ -602,13 +602,13 @@
 	cipher = purple_account_get_string(account, "cipher",
 					   SILC_DEFAULT_CIPHER);
 	for (i = 0; silc_default_ciphers[i].name; i++)
-		if (!strcmp(silc_default_ciphers[i].name, cipher)) {
+		if (purple_strequal(silc_default_ciphers[i].name, cipher)) {
 			silc_cipher_register(&(silc_default_ciphers[i]));
 			break;
 		}
 	hmac = purple_account_get_string(account, "hmac", SILC_DEFAULT_HMAC);
 	for (i = 0; silc_default_hmacs[i].name; i++)
-		if (!strcmp(silc_default_hmacs[i].name, hmac)) {
+		if (purple_strequal(silc_default_hmacs[i].name, hmac)) {
 			silc_hmac_register(&(silc_default_hmacs[i]));
 			break;
 		}
@@ -1159,7 +1159,7 @@
 	else
 		pass2 = "";
 
-	if (strcmp(pass1, pass2)) {
+	if (!purple_strequal(pass1, pass2)) {
 		purple_notify_error(gc, _("Create New SILC Key Pair"),
 			_("Passphrases do not match"), NULL,
 			purple_request_cpar_from_connection(gc));
--- a/libpurple/protocols/simple/Makefile.am	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/simple/Makefile.am	Wed Jun 14 23:40:17 2017 -0500
@@ -4,6 +4,8 @@
 pkgdir = @PURPLE_PLUGINDIR@
 
 SIMPLESOURCES = \
+	ntlm.c \
+	ntlm.h \
 	simple.c \
 	simple.h \
 	sipmsg.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/simple/ntlm.c	Wed Jun 14 23:40:17 2017 -0500
@@ -0,0 +1,347 @@
+/* purple
+ *
+ * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
+ *
+ * hashing done according to description of NTLM on
+ * http://www.innovation.ch/java/ntlm.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#include "internal.h"
+
+#include "util.h"
+#include "ntlm.h"
+#include "debug.h"
+
+#include "ciphers/descipher.h"
+#include "ciphers/md4hash.h"
+
+#include <string.h>
+
+#define NTLM_NEGOTIATE_NTLM2_KEY 0x00080000
+
+struct type2_message {
+	guint8  protocol[8];     /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'*/
+	guint32 type;            /* 0x00000002 */
+
+	guint32 zero;
+	guint16 msg_len1;        /* target name length */
+	guint16 msg_len2;        /* target name length */
+
+	guint32 flags;           /* 0x00008201 */
+
+	guint8  nonce[8];        /* nonce */
+	guint8  context[8];
+};
+
+struct type3_message {
+	guint8  protocol[8];     /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'*/
+	guint32 type;            /* 0x00000003 */
+
+	guint16 lm_resp_len1;    /* LanManager response length (always 0x18)*/
+	guint16 lm_resp_len2;    /* LanManager response length (always 0x18)*/
+	guint32 lm_resp_off;     /* LanManager response offset */
+
+	guint16 nt_resp_len1;    /* NT response length (always 0x18) */
+	guint16 nt_resp_len2;    /* NT response length (always 0x18) */
+	guint32 nt_resp_off;     /* NT response offset */
+
+	guint16 dom_len1;        /* domain string length */
+	guint16 dom_len2;        /* domain string length */
+	guint32 dom_off;         /* domain string offset (always 0x00000040) */
+
+	guint16 user_len1;       /* username string length */
+	guint16 user_len2;       /* username string length */
+	guint32 user_off;        /* username string offset */
+
+	guint16 host_len1;       /* host string length */
+	guint16 host_len2;       /* host string length */
+	guint32 host_off;        /* host string offset */
+
+	guint16 sess_len1;
+	guint16 sess_len2;
+	guint32 sess_off;         /* message length */
+
+	guint32 flags;            /* 0x00008201 */
+	/* guint32 flags2; */     /* unknown, used in windows messenger */
+	/* guint32 flags3; */
+
+#if 0
+	guint8  dom[*];          /* domain string (unicode UTF-16LE) */
+	guint8  user[*];         /* username string (unicode UTF-16LE) */
+	guint8  host[*];         /* host string (unicode UTF-16LE) */
+	guint8  lm_resp[*];      /* LanManager response */
+	guint8  nt_resp[*];      /* NT response */
+#endif
+};
+
+guint8 *
+purple_ntlm_parse_type2(const gchar *type2, guint32 *flags)
+{
+	gsize retlen;
+	guchar *buff;
+	struct type2_message tmsg;
+	static guint8 nonce[8];
+
+	buff = g_base64_decode(type2, &retlen);
+
+	if (buff != NULL && retlen >= (sizeof(struct type2_message) - 1)) {
+		memcpy(&tmsg, buff, MIN(retlen, sizeof(tmsg)));
+		memcpy(nonce, tmsg.nonce, 8);
+		if (flags != NULL)
+			*flags = GUINT16_FROM_LE(tmsg.flags);
+	} else {
+		purple_debug_error("ntlm", "Unable to parse type2 message - returning empty nonce.\n");
+		memset(nonce, 0, 8);
+	}
+	g_free(buff);
+
+	return nonce;
+}
+
+/*
+ * Create a 64bit DES key by taking a 56bit key and adding
+ * a parity bit after every 7th bit.
+ */
+static void
+setup_des_key(const guint8 key_56[], guint8 *key)
+{
+	key[0] = key_56[0];
+	key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
+	key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
+	key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
+	key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
+	key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
+	key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
+	key[7] =  (key_56[6] << 1) & 0xFF;
+}
+
+/*
+ * helper function for purple cipher.c
+ */
+static void
+des_ecb_encrypt(const guint8 *plaintext, guint8 *result, const guint8 *key)
+{
+	PurpleCipher *cipher;
+	gssize encsiz;
+
+	cipher = purple_des_cipher_new();
+	purple_cipher_set_key(cipher, key, 8);
+	encsiz = purple_cipher_encrypt(cipher, plaintext, 8, result, 8);
+	g_warn_if_fail(encsiz == 8);
+	g_object_unref(cipher);
+}
+
+/*
+ * takes a 21 byte array and treats it as 3 56-bit DES keys. The
+ * 8 byte plaintext is encrypted with each key and the resulting 24
+ * bytes are stored in the results array.
+ */
+static void
+calc_resp(guint8 *keys, const guint8 *plaintext, unsigned char *results)
+{
+	guint8 key[8];
+	setup_des_key(keys, key);
+	des_ecb_encrypt(plaintext, results, key);
+
+	setup_des_key(keys + 7, key);
+	des_ecb_encrypt(plaintext, results + 8, key);
+
+	setup_des_key(keys + 14, key);
+	des_ecb_encrypt(plaintext, results + 16, key);
+}
+
+/*
+ * TODO: We think we should be using cryptographically secure random numbers
+ *       here.  We think the rand() function is probably bad.  We think
+ *       /dev/urandom is a step up, but using a random function from an SSL
+ *       library would probably be best.  In Windows we could possibly also
+ *       use CryptGenRandom.
+ */
+static void
+gensesskey(char *buffer)
+{
+	int fd;
+	int i;
+	ssize_t red = 0;
+
+	fd = open("/dev/urandom", O_RDONLY);
+	if (fd >= 0) {
+		red = read(fd, buffer, 16);
+		if (red < 0) {
+			purple_debug_warning("ntlm", "Error reading from /dev/urandom: %s."
+					"  Falling back to inferior method.\n", g_strerror(errno));
+			red = 0;
+		} else if (red < 16) {
+			purple_debug_warning("ntlm", "Tried reading 16 bytes from "
+					"/dev/urandom but only got %"
+					G_GSSIZE_FORMAT ".  Falling back to "
+					"inferior method\n", (gssize)red);
+		}
+		close(fd);
+	} else {
+		purple_debug_warning("ntlm", "Error opening /dev/urandom: %s."
+				"  Falling back to inferior method.\n", g_strerror(errno));
+	}
+
+	for (i = red; i < 16; i++) {
+		buffer[i] = (char)(g_random_int() & 0xff);
+	}
+}
+
+gchar *
+purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *hostname, const gchar *domain, const guint8 *nonce, guint32 *flags)
+{
+	char lm_pw[14];
+	unsigned char lm_hpw[21];
+	char sesskey[16];
+	guint8 key[8];
+	int domainlen;
+	int usernamelen;
+	int hostnamelen;
+	int msglen;
+	struct type3_message *tmsg;
+	int passwlen, lennt;
+	unsigned char lm_resp[24], nt_resp[24];
+	unsigned char magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+	unsigned char nt_hpw[21];
+	char nt_pw[128];
+	PurpleHash *hash;
+	char *tmp;
+	int idx;
+	gchar *ucs2le;
+
+	domainlen = strlen(domain) * 2;
+	usernamelen = strlen(username) * 2;
+	hostnamelen = strlen(hostname) * 2;
+	msglen = sizeof(struct type3_message) + domainlen +
+		usernamelen + hostnamelen + 0x18 + 0x18 + ((flags) ? 0x10 : 0);
+	tmsg = g_malloc0(msglen);
+	passwlen = strlen(passw);
+
+	/* type3 message initialization */
+	tmsg->protocol[0] = 'N';
+	tmsg->protocol[1] = 'T';
+	tmsg->protocol[2] = 'L';
+	tmsg->protocol[3] = 'M';
+	tmsg->protocol[4] = 'S';
+	tmsg->protocol[5] = 'S';
+	tmsg->protocol[6] = 'P';
+	tmsg->type = GUINT32_TO_LE(0x00000003);
+	tmsg->lm_resp_len1 = tmsg->lm_resp_len2 = GUINT16_TO_LE(0x18);
+	tmsg->lm_resp_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen);
+	tmsg->nt_resp_len1 = tmsg->nt_resp_len2 = GUINT16_TO_LE(0x18);
+	tmsg->nt_resp_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen + 0x18);
+
+	tmsg->dom_len1 = tmsg->dom_len2 = GUINT16_TO_LE(domainlen);
+	tmsg->dom_off = GUINT32_TO_LE(sizeof(struct type3_message));
+
+	tmsg->user_len1 = tmsg->user_len2 = GUINT16_TO_LE(usernamelen);
+	tmsg->user_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen);
+
+	tmsg->host_len1 = tmsg->host_len2 = GUINT16_TO_LE(hostnamelen);
+	tmsg->host_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen);
+
+	if(flags) {
+		tmsg->sess_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen + 0x18 + 0x18);
+		tmsg->sess_len1 = tmsg->sess_len2 = GUINT16_TO_LE(0x0010);
+	}
+
+	tmsg->flags = GUINT32_TO_LE(0x00008201);
+
+	tmp = (char *)tmsg + sizeof(struct type3_message);
+
+	ucs2le = g_convert(domain, -1, "UTF-16LE", "UTF-8", NULL, NULL, NULL);
+	if (ucs2le != NULL) {
+		memcpy(tmp, ucs2le, domainlen);
+		g_free(ucs2le);
+		tmp += domainlen;
+	} else {
+		purple_debug_info("ntlm", "Unable to encode domain in UTF-16LE.\n");
+	}
+
+	ucs2le = g_convert(username, -1, "UTF-16LE", "UTF-8", NULL, NULL, NULL);
+	if (ucs2le != NULL) {
+		memcpy(tmp, ucs2le, usernamelen);
+		g_free(ucs2le);
+		tmp += usernamelen;
+	} else {
+		purple_debug_info("ntlm", "Unable to encode username in UTF-16LE.\n");
+	}
+
+	ucs2le = g_convert(hostname, -1, "UTF-16LE", "UTF-8", NULL, NULL, NULL);
+	if (ucs2le != NULL) {
+		memcpy(tmp, ucs2le, hostnamelen);
+		g_free(ucs2le);
+		tmp += hostnamelen;
+	} else {
+		purple_debug_info("ntlm", "Unable to encode hostname in UTF-16LE.\n");
+	}
+
+	/* LM */
+	if (passwlen > 14)
+		passwlen = 14;
+
+	for (idx = 0; idx < passwlen; idx++)
+		lm_pw[idx] = g_ascii_toupper(passw[idx]);
+	for (; idx < 14; idx++)
+		lm_pw[idx] = 0;
+
+	setup_des_key((unsigned char*)lm_pw, key);
+	des_ecb_encrypt(magic, lm_hpw, key);
+
+	setup_des_key((unsigned char*)(lm_pw + 7), key);
+	des_ecb_encrypt(magic, lm_hpw + 8, key);
+
+	memset(lm_hpw + 16, 0, 5);
+	calc_resp(lm_hpw, nonce, lm_resp);
+	memcpy(tmp, lm_resp, 0x18);
+	tmp += 0x18;
+
+	/* NTLM */
+	/* Convert the password to UTF-16LE */
+	lennt = strlen(passw);
+	for (idx = 0; idx < lennt; idx++)
+	{
+		nt_pw[2 * idx]   = passw[idx];
+		nt_pw[2 * idx + 1] = 0;
+	}
+
+	hash = purple_md4_hash_new();
+	purple_hash_append(hash, (guint8 *)nt_pw, 2 * lennt);
+	purple_hash_digest(hash, nt_hpw, sizeof(nt_hpw));
+	g_object_unref(hash);
+
+	memset(nt_hpw + 16, 0, 5);
+	calc_resp(nt_hpw, nonce, nt_resp);
+	memcpy(tmp, nt_resp, 0x18);
+	tmp += 0x18;
+
+	/* LCS Stuff */
+	if (flags) {
+		tmsg->flags = GUINT32_TO_LE(0x409082d4);
+		gensesskey(sesskey);
+		memcpy(tmp, sesskey, 0x10);
+	}
+
+	/*tmsg->flags2 = 0x0a280105;
+	tmsg->flags3 = 0x0f000000;*/
+
+	tmp = g_base64_encode((guchar *)tmsg, msglen);
+	g_free(tmsg);
+
+	return tmp;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/simple/ntlm.h	Wed Jun 14 23:40:17 2017 -0500
@@ -0,0 +1,58 @@
+/* purple
+ *
+ * Copyright (C) 2005, Thomas Butter <butter@uni-mannheim.de>
+ *
+ * ntlm structs are taken from NTLM description on
+ * http://www.innovation.ch/java/ntlm.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#ifndef _PURPLE_NTLM_H
+#define _PURPLE_NTLM_H
+
+G_BEGIN_DECLS
+
+/**
+ * purple_ntlm_parse_type2:
+ * @type2: String containing the base64 encoded type2 message
+ * @flags: If not %NULL, this will store the flags for the message
+ *
+ * Parses the ntlm type 2 message
+ *
+ * Returns: The nonce for use in message type3.  This is a statically
+ *         allocated 8 byte binary string.
+ */
+guint8 *purple_ntlm_parse_type2(const gchar *type2, guint32 *flags);
+
+/**
+ * purple_ntlm_gen_type3:
+ * @username: The username
+ * @passw: The password
+ * @hostname: The hostname
+ * @domain: The domain to authenticate against
+ * @nonce: The nonce returned by purple_ntlm_parse_type2
+ * @flags: Pointer to the flags returned by purple_ntlm_parse_type2
+ *
+ * Generates a type3 message
+ *
+ * Returns: A base64 encoded type3 message.  This should be g_free'd by
+ *          the caller.
+ */
+gchar *purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *hostname, const gchar *domain, const guint8 *nonce, guint32 *flags);
+
+G_END_DECLS
+
+#endif /* _PURPLE_NTLM_H */
--- a/libpurple/protocols/simple/simple.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/simple/simple.c	Wed Jun 14 23:40:17 2017 -0500
@@ -143,7 +143,7 @@
 	GSList *entry = sip->watcher;
 	while(entry) {
 		watcher = entry->data;
-		if(!strcmp(name, watcher->name)) return watcher;
+		if(purple_strequal(name, watcher->name)) return watcher;
 		entry = entry->next;
 	}
 	return NULL;
@@ -622,7 +622,7 @@
 	if (cseq) {
 		while(transactions) {
 			trans = transactions->data;
-			if(!strcmp(trans->cseq, cseq)) {
+			if(purple_strequal(trans->cseq, cseq)) {
 				return trans;
 			}
 			transactions = transactions->next;
@@ -645,7 +645,7 @@
 	gchar *tag = NULL;
 	char *buf;
 
-	if(!strcmp(method, "REGISTER")) {
+	if(purple_strequal(method, "REGISTER")) {
 		if(sip->regcallid) {
 			g_free(callid);
 			callid = g_strdup(sip->regcallid);
@@ -654,12 +654,12 @@
 	}
 
 	if(addheaders) addh = addheaders;
-	if(sip->registrar.type && !strcmp(method, "REGISTER")) {
+	if(sip->registrar.type && purple_strequal(method, "REGISTER")) {
 		buf = auth_header(sip, &sip->registrar, method, url);
 		auth = g_strdup_printf("Authorization: %s\r\n", buf);
 		g_free(buf);
 		purple_debug(PURPLE_DEBUG_MISC, "simple", "header %s", auth);
-	} else if(sip->proxy.type && strcmp(method, "REGISTER")) {
+	} else if(sip->proxy.type && !purple_strequal(method, "REGISTER")) {
 		buf = auth_header(sip, &sip->proxy, method, url);
 		auth = g_strdup_printf("Proxy-Authorization: %s\r\n", buf);
 		g_free(buf);
@@ -1174,9 +1174,9 @@
 	theirtag = find_tag(fromhdr);
 
 	if (ourtag && theirtag &&
-			!strcmp(dialog->callid, callid) &&
-			!strcmp(dialog->ourtag, ourtag) &&
-			!strcmp(dialog->theirtag, theirtag))
+			purple_strequal(dialog->callid, callid) &&
+			purple_strequal(dialog->ourtag, ourtag) &&
+			purple_strequal(dialog->theirtag, theirtag))
 		match = TRUE;
 
 	g_free(ourtag);
@@ -1508,13 +1508,13 @@
 static void process_input_message(struct simple_account_data *sip, struct sipmsg *msg) {
 	gboolean found = FALSE;
 	if(msg->response == 0) { /* request */
-		if(!strcmp(msg->method, "MESSAGE")) {
+		if(purple_strequal(msg->method, "MESSAGE")) {
 			process_incoming_message(sip, msg);
 			found = TRUE;
-		} else if(!strcmp(msg->method, "NOTIFY")) {
+		} else if(purple_strequal(msg->method, "NOTIFY")) {
 			process_incoming_notify(sip, msg);
 			found = TRUE;
-		} else if(!strcmp(msg->method, "SUBSCRIBE")) {
+		} else if(purple_strequal(msg->method, "SUBSCRIBE")) {
 			process_incoming_subscribe(sip, msg);
 			found = TRUE;
 		} else {
@@ -1548,7 +1548,7 @@
 					purple_debug_info("simple", "got trying response\n");
 				} else {
 					sip->proxy.retries = 0;
-					if(!strcmp(trans->msg->method, "REGISTER")) {
+					if(purple_strequal(trans->msg->method, "REGISTER")) {
 
 						/* This is encountered when a REGISTER request was ...
 						 */
--- a/libpurple/protocols/zephyr/ZAsyncLocate.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/zephyr/ZAsyncLocate.c	Wed Jun 14 23:40:17 2017 -0500
@@ -9,6 +9,7 @@
  */
 
 #include "internal.h"
+#include "util.h"
 
 Code_t ZRequestLocations(user, zald, kind, auth)
      const char *user;
@@ -69,7 +70,7 @@
     /* non-matching protocol version numbers means the
        server is probably an older version--must punt */
 
-    if (zald && strcmp(notice->z_version, zald->version))
+    if (zald && !purple_strequal(notice->z_version, zald->version))
       return(ZERR_VERS);
 
     if (notice->z_kind == SERVNAK)
@@ -77,7 +78,7 @@
 
     /* flag ACKs as special */
     if (notice->z_kind == SERVACK &&
-	!strcmp(notice->z_opcode, LOCATE_LOCATE)) {
+	purple_strequal(notice->z_opcode, LOCATE_LOCATE)) {
 	*nlocs = -1;
 	return(ZERR_NONE);
     }
@@ -133,7 +134,7 @@
     __locate_next = 0;
     *nlocs = __locate_num;
     if (user) {
-	size_t len;    
+	size_t len;
 	if (zald) {
 	    len = strlen(zald->user) + 1;
 	    if ((*user = (char *) malloc(len)) == NULL)
--- a/libpurple/protocols/zephyr/ZLocations.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/zephyr/ZLocations.c	Wed Jun 14 23:40:17 2017 -0500
@@ -10,6 +10,7 @@
  */
 
 #include "internal.h"
+#include "util.h"
 
 #ifndef WIN32
 #include <pwd.h>
@@ -127,11 +128,11 @@
 	    ZFreeNotice(&retnotice);
 	    return (ZERR_SERVNAK);
 	}
-	if (!strcmp(retnotice.z_message, ZSRVACK_NOTSENT)) {
+	if (purple_strequal(retnotice.z_message, ZSRVACK_NOTSENT)) {
 	    ZFreeNotice(&retnotice);
 	    return (ZERR_AUTHFAIL);
 	}
-	if (!strcmp(retnotice.z_message, ZSRVACK_FAIL)) {
+	if (purple_strequal(retnotice.z_message, ZSRVACK_FAIL)) {
 	    ZFreeNotice(&retnotice);
 	    return (ZERR_LOGINFAIL);
 	}
@@ -149,8 +150,8 @@
 	return (ZERR_INTERNAL);
     }
 
-    if (strcmp(retnotice.z_message, ZSRVACK_SENT) &&
-	strcmp(retnotice.z_message, ZSRVACK_NOTSENT)) {
+    if (!purple_strequal(retnotice.z_message, ZSRVACK_SENT) &&
+	!purple_strequal(retnotice.z_message, ZSRVACK_NOTSENT)) {
 	ZFreeNotice(&retnotice);
 	return (ZERR_INTERNAL);
     }
--- a/libpurple/protocols/zephyr/ZRetSubs.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/protocols/zephyr/ZRetSubs.c	Wed Jun 14 23:40:17 2017 -0500
@@ -10,6 +10,7 @@
  */
 
 #include "internal.h"
+#include "util.h"
 
 static Code_t Z_RetSubs(ZNotice_t *notice, int *nsubs, Z_AuthProc auth_routine);
 
@@ -105,12 +106,12 @@
 		}
 		/* non-matching protocol version numbers means the
 		   server is probably an older version--must punt */
-		if (strcmp(notice->z_version,retnotice.z_version)) {
+		if (!purple_strequal(notice->z_version,retnotice.z_version)) {
 			ZFreeNotice(&retnotice);
 			return(ZERR_VERS);
 		}
 		if (retnotice.z_kind == SERVACK &&
-		    !strcmp(retnotice.z_opcode,notice->z_opcode)) {
+		    purple_strequal(retnotice.z_opcode,notice->z_opcode)) {
 			ZFreeNotice(&retnotice);
 			gimmeack = 1;
 			continue;
--- a/libpurple/proxy.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/proxy.c	Wed Jun 14 23:40:17 2017 -0500
@@ -30,7 +30,6 @@
 #include "debug.h"
 #include "http.h"
 #include "notify.h"
-#include "ntlm.h"
 #include "prefs.h"
 #include "proxy.h"
 #include "purple-gio.h"
--- a/libpurple/purple.h.in	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/purple.h.in	Wed Jun 14 23:40:17 2017 -0500
@@ -70,7 +70,6 @@
 #include <nat-pmp.h>
 #include <network.h>
 #include <notify.h>
-#include <ntlm.h>
 #include <plugins.h>
 #include <pluginpref.h>
 #include <pounce.h>
--- a/libpurple/status.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/status.c	Wed Jun 14 23:40:17 2017 -0500
@@ -795,9 +795,7 @@
 			if (G_VALUE_TYPE(default_value) == G_TYPE_STRING) {
 				const char *cur = purple_status_get_attr_string(status, attr->id);
 				const char *def = g_value_get_string(default_value);
-				if ((cur == NULL && def == NULL)
-				    || (cur != NULL && def != NULL
-					&& !strcmp(cur, def))) {
+				if (purple_strequal(cur, def)) {
 					continue;
 				}
 
--- a/libpurple/tests/.hgignore	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/tests/.hgignore	Wed Jun 14 23:40:17 2017 -0500
@@ -5,6 +5,7 @@
 ^test_hmac$
 ^test_image$
 ^test_smiley$
+^test_smiley_list$
 ^test_trie$
 ^test_util$
 ^test_xmlnode$
--- a/libpurple/tests/Makefile.am	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/tests/Makefile.am	Wed Jun 14 23:40:17 2017 -0500
@@ -11,6 +11,7 @@
 	test_image \
 	test_md4 \
 	test_smiley \
+	test_smiley_list \
 	test_trie \
 	test_util \
 	test_xmlnode
@@ -30,6 +31,9 @@
 test_smiley_SOURCES=test_smiley.c
 test_smiley_LDADD=$(COMMON_LIBS)
 
+test_smiley_list_SOURCES=test_smiley_list.c
+test_smiley_list_LDADD=$(COMMON_LIBS)
+
 test_trie_SOURCES=test_trie.c
 test_trie_LDADD=$(COMMON_LIBS)
 
@@ -50,5 +54,5 @@
 	$(DBUS_CFLAGS) \
 	$(NSS_CFLAGS)
 
-EXTRA_DIST = \
+EXTRA_DIST += \
 	data/test-image.png
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/test_smiley_list.c	Wed Jun 14 23:40:17 2017 -0500
@@ -0,0 +1,94 @@
+/*
+ * Purple
+ *
+ * Purple is the legal property of its developers, whose names are too
+ * numerous to list here. Please refer to the COPYRIGHT file distributed
+ * with this source distribution
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include <glib.h>
+
+#include <purple.h>
+
+/******************************************************************************
+ * Test
+ *****************************************************************************/
+static void
+test_smiley_list_new(void) {
+	PurpleSmileyList *list = NULL;
+
+	list = purple_smiley_list_new();
+
+	g_assert(purple_smiley_list_is_empty(list));
+	g_assert(purple_smiley_list_get_unique(list) == NULL);
+	g_assert(purple_smiley_list_get_all(list) == NULL);
+
+	g_object_unref(G_OBJECT(list));
+}
+
+static void
+test_smiley_list_add_remove(void) {
+	PurpleSmileyList *list = NULL;
+	PurpleSmiley *smiley = NULL, *smiley2 = NULL;
+	PurpleTrie *trie = NULL;
+	gboolean added = FALSE;
+
+	list = purple_smiley_list_new();
+
+	g_assert(purple_smiley_list_is_empty(list));
+
+	/* create a smiley */
+	smiley = purple_smiley_new_from_data("testing", NULL, 0);
+
+	/* add the smiley to the list */
+	added = purple_smiley_list_add(list, smiley);
+	g_assert(added);
+	g_assert(!purple_smiley_list_is_empty(list));
+
+	/* make sure we can get it back out */
+	smiley2 = purple_smiley_list_get_by_shortcut(list, "testing");
+	g_assert(smiley == smiley2);
+
+	/* make sure it returns a valid trie */
+	trie = purple_smiley_list_get_trie(list);
+	g_assert(PURPLE_IS_TRIE(trie));
+	/* don't free the trie, as it's ownership is not transfered to us */
+
+	/* add it again (should fail) */
+	added = purple_smiley_list_add(list, smiley);
+	g_assert(!added);
+
+	/* now remove it and make sure the list is empty */
+	purple_smiley_list_remove(list, smiley);
+	g_assert(purple_smiley_list_is_empty(list));
+
+	g_object_unref(G_OBJECT(smiley));
+	g_object_unref(G_OBJECT(list));
+}
+
+/******************************************************************************
+ * Main
+ *****************************************************************************/
+gint
+main(gint argc, gchar **argv) {
+	g_test_init(&argc, &argv, NULL);
+
+	g_test_add_func("/smiley_list/new", test_smiley_list_new);
+	g_test_add_func("/smiley_list/add-remove", test_smiley_list_add_remove);
+
+	return g_test_run();
+}
--- a/libpurple/util.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/util.c	Wed Jun 14 23:40:17 2017 -0500
@@ -3810,7 +3810,7 @@
 
 	tmp++;
 
-	if (g_str_equal(proto, "xmpp"))
+	if (purple_strequal(proto, "xmpp"))
 		delimiter = ';';
 	else
 		delimiter = '&';
--- a/libpurple/win32/giowin32.c	Thu Jun 08 22:51:50 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,859 +0,0 @@
-/* GLIB - Library of useful routines for C programming
- * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * giowin32.c: IO Channels for Win32.
- * Copyright 1998 Owen Taylor and Tor Lillqvist
- * Copyright 1999-2000 Tor Lillqvist and Craig Setera
- * Copyright 2001-2003 Andrew Lanoix
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02111-1301, USA.
- */
-
-/*
- * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
- * file for a list of people on the GLib Team.  See the ChangeLog
- * files for a list of changes.  These files are distributed with
- * GLib at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-/* Define this to get (very) verbose logging of all channels */
-/* #define G_IO_WIN32_DEBUG */
-
-#include <config.h>
-
-#include <glib.h>
-
-#include <stdlib.h>
-#include <winsock2.h>
-#include <windows.h>
-#include <fcntl.h>
-#include <io.h>
-#include <process.h>
-#include <errno.h>
-#include <sys/stat.h>
-
-#include <glib/gstdio.h>
-
-typedef struct _GIOWin32Channel GIOWin32Channel;
-typedef struct _GIOWin32Watch GIOWin32Watch;
-
-#define BUFFER_SIZE 4096
-
-GIOChannel *wpurple_g_io_channel_win32_new_socket (int socket);
-
-typedef enum {
-  G_IO_WIN32_WINDOWS_MESSAGES,	/* Windows messages */
-  G_IO_WIN32_FILE_DESC,		/* Unix-like file descriptors from
-				 * _open() or _pipe(). Read with read().
-				 * Have to create separate thread to read.
-				 */
-  G_IO_WIN32_SOCKET		/* Sockets. A separate thread is blocked
-				 * in select() most of the time.
-				 */
-} GIOWin32ChannelType;
-
-struct _GIOWin32Channel {
-  GIOChannel channel;
-  gint fd;			/* Either a Unix-like file handle as provided
-				 * by the Microsoft C runtime, or a SOCKET
-				 * as provided by WinSock.
-				 */
-  GIOWin32ChannelType type;
-
-  gboolean debug;
-
-  CRITICAL_SECTION mutex;
-
-  /* This is used by G_IO_WIN32_WINDOWS_MESSAGES channels */
-  HWND hwnd;			/* handle of window, or NULL */
-
-  /* Following fields are used by both fd and socket channels. */
-  gboolean running;		/* Is reader thread running. FALSE if
-				 * EOF has been reached.
-				 */
-  gboolean needs_close;		/* If the channel has been closed while
-				 * the reader thread was still running.
-				 */
-  guint thread_id;		/* If non-NULL has a reader thread, or has
-				 * had.*/
-  HANDLE data_avail_event;
-
-  gushort revents;
-
-  /* Following fields used by fd channels for input */
-
-  /* Data is kept in a circular buffer. To be able to distinguish between
-   * empty and full buffer, we cannot fill it completely, but have to
-   * leave a one character gap.
-   *
-   * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
-   *
-   * Empty:    wrp == rdp
-   * Full:     (wrp + 1) % BUFFER_SIZE == rdp
-   * Partial:  otherwise
-   */
-  guchar *buffer;		/* (Circular) buffer */
-  gint wrp, rdp;		/* Buffer indices for writing and reading */
-  HANDLE space_avail_event;
-
-  /* Following fields used by socket channels */
-  GSList *watches;
-  HANDLE data_avail_noticed_event;
-  gint reset_send; /* socket used to send data so select_thread() can reset/re-loop */
-  gint reset_recv; /* socket used to recv data so select_thread() can reset/re-loop */
-};
-
-#define LOCK(mutex) EnterCriticalSection (&mutex)
-#define UNLOCK(mutex) LeaveCriticalSection (&mutex)
-
-struct _GIOWin32Watch {
-  GSource       source;
-  GPollFD       pollfd;
-  GIOChannel   *channel;
-  GIOCondition  condition;
-};
-
-static void
-g_win32_print_gioflags (GIOFlags flags)
-{
-  char *bar = "";
-
-  if (flags & G_IO_FLAG_APPEND)
-    bar = "|", g_print ("APPEND");
-  if (flags & G_IO_FLAG_NONBLOCK)
-    g_print ("%sNONBLOCK", bar), bar = "|";
-  if (flags & G_IO_FLAG_IS_READABLE)
-    g_print ("%sREADABLE", bar), bar = "|";
-  if (flags & G_IO_FLAG_IS_WRITEABLE)
-    g_print ("%sWRITEABLE", bar), bar = "|";
-  if (flags & G_IO_FLAG_IS_SEEKABLE)
-    g_print ("%sSEEKABLE", bar), bar = "|";
-}
-
-static gboolean
-g_io_win32_get_debug_flag (void)
-{
-#ifdef G_IO_WIN32_DEBUG
-  return TRUE;
-#else
-  if (getenv ("G_IO_WIN32_DEBUG") != NULL)
-    return TRUE;
-  else
-    return FALSE;
-#endif
-}
-
-static void
-g_io_channel_win32_init (GIOWin32Channel *channel)
-{
-  channel->debug = g_io_win32_get_debug_flag ();
-  channel->buffer = NULL;
-  channel->running = FALSE;
-  channel->needs_close = FALSE;
-  channel->thread_id = 0;
-  channel->data_avail_event = NULL;
-  channel->revents = 0;
-  channel->space_avail_event = NULL;
-  channel->reset_send = INVALID_SOCKET;
-  channel->reset_recv = INVALID_SOCKET;
-  channel->data_avail_noticed_event = NULL;
-  channel->watches = NULL;
-  InitializeCriticalSection (&channel->mutex);
-}
-
-static void
-create_events (GIOWin32Channel *channel)
-{
-  SECURITY_ATTRIBUTES sec_attrs;
-
-  sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES);
-  sec_attrs.lpSecurityDescriptor = NULL;
-  sec_attrs.bInheritHandle = FALSE;
-
-  /* The data available event is manual reset, the space available event
-   * is automatic reset.
-   */
-  if (!(channel->data_avail_event = CreateEvent (&sec_attrs, TRUE, FALSE, NULL))
-      || !(channel->space_avail_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL))
-      || !(channel->data_avail_noticed_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL)))
-    {
-      gchar *emsg = g_win32_error_message (GetLastError ());
-      g_error ("Error creating event: %s", emsg);
-      g_free (emsg);
-    }
-}
-
-static void
-create_thread (GIOWin32Channel     *channel,
-	       GIOCondition         condition,
-	       unsigned (__stdcall *thread) (void *parameter))
-{
-  HANDLE thread_handle;
-
-  thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0,
-					   &channel->thread_id);
-  if (thread_handle == 0)
-    g_warning (G_STRLOC ": Error creating reader thread: %s",
-	       g_strerror (errno));
-  else if (!CloseHandle (thread_handle))
-    g_warning (G_STRLOC ": Error closing thread handle: %s\n",
-	       g_win32_error_message (GetLastError ()));
-
-  WaitForSingleObject (channel->space_avail_event, INFINITE);
-}
-
-static void
-init_reset_sockets (GIOWin32Channel *channel)
-{
-  struct sockaddr_in local, local2, server;
-  int len;
-
-  channel->reset_send = (gint) socket (AF_INET, SOCK_DGRAM, 0);
-  if (channel->reset_send == (gint)INVALID_SOCKET)
-    {
-      g_warning (G_STRLOC ": Error creating reset_send socket: %s\n",
-		 g_win32_error_message (WSAGetLastError ()));
-    }
-
-  local.sin_family = AF_INET;
-  local.sin_port = 0;
-  local.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
-  if (bind (channel->reset_send, (struct sockaddr *)&local, sizeof (local)) == SOCKET_ERROR)
-    {
-      g_warning (G_STRLOC ": Error binding to reset_send socket: %s\n",
-		 g_win32_error_message (WSAGetLastError ()));
-  }
-
-  local2.sin_family = AF_INET;
-  local2.sin_port = 0;
-  local2.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
-  channel->reset_recv = (gint) socket (AF_INET, SOCK_DGRAM, 0);
-  if (channel->reset_recv == (gint)INVALID_SOCKET)
-    {
-      g_warning (G_STRLOC ": Error creating reset_recv socket: %s\n",
-		 g_win32_error_message (WSAGetLastError ()));
-  }
-
-  if (bind (channel->reset_recv, (struct sockaddr *)&local2, sizeof (local)) == SOCKET_ERROR)
-    {
-      g_warning (G_STRLOC ": Error binding to reset_recv socket: %s\n",
-		 g_win32_error_message (WSAGetLastError ()));
-    }
-
-  len = sizeof (local2);
-  if (getsockname (channel->reset_recv, (struct sockaddr *)&local2, &len) == SOCKET_ERROR)
-    {
-      g_warning (G_STRLOC ": Error getsockname with reset_recv socket: %s\n",
-		 g_win32_error_message (WSAGetLastError ()));
-    }
-
-  memset (&server, 0, sizeof (server));
-  server.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-  server.sin_family = AF_INET;
-  server.sin_port = local2.sin_port;
-
-  if (connect (channel->reset_send, (struct sockaddr  *)&server, sizeof (server)) == SOCKET_ERROR)
-    {
-      g_warning (G_STRLOC ": connect to reset_recv socket: %s\n",
-		 g_win32_error_message (WSAGetLastError ()));
-  }
-
-}
-
-static unsigned __stdcall
-select_thread (void *parameter)
-{
-  GIOWin32Channel *channel = parameter;
-  fd_set read_fds, write_fds, except_fds;
-  GSList *tmp;
-  int n;
-  char buffer[8];
-
-  g_io_channel_ref ((GIOChannel *)channel);
-
-  if (channel->debug)
-    g_print ("select_thread %#x: start fd:%d data_avail:%#x data_avail_noticed:%#x\n",
-	     channel->thread_id,
-	     channel->fd,
-	     (guint) channel->data_avail_event,
-	     (guint) channel->data_avail_noticed_event);
-
-  channel->rdp = channel->wrp = 0;
-  channel->running = TRUE;
-
-  SetEvent (channel->space_avail_event);
-
-  while (channel->running)
-    {
-      FD_ZERO (&read_fds);
-      FD_ZERO (&write_fds);
-      FD_ZERO (&except_fds);
-      FD_SET (channel->reset_recv, &read_fds);
-
-      LOCK (channel->mutex);
-      tmp = channel->watches;
-      while (tmp)
-	{
-	  GIOWin32Watch *watch = (GIOWin32Watch *)tmp->data;
-
-	  if (watch->condition & (G_IO_IN | G_IO_HUP))
-	    FD_SET (channel->fd, &read_fds);
-	  if (watch->condition & G_IO_OUT)
-	    FD_SET (channel->fd, &write_fds);
-	  if (watch->condition & G_IO_ERR)
-	    FD_SET (channel->fd, &except_fds);
-
-	  tmp = tmp->next;
-	}
-      UNLOCK (channel->mutex);
-
-      if (channel->debug)
-	g_print ("select_thread %#x: calling select() for%s%s%s\n",
-		 channel->thread_id,
-		 (FD_ISSET (channel->fd, &read_fds) ? " IN" : ""),
-		 (FD_ISSET (channel->fd, &write_fds) ? " OUT" : ""),
-		 (FD_ISSET (channel->fd, &except_fds) ? " ERR" : ""));
-
-      n = select (1, &read_fds, &write_fds, &except_fds, NULL);
-
-      LOCK (channel->mutex);
-      if (channel->needs_close)
-	{
-	  UNLOCK (channel->mutex);
-	  break;
-	}
-      UNLOCK (channel->mutex);
-
-      if (n == SOCKET_ERROR)
-	{
-	  if (channel->debug)
-	    g_print ("select_thread %#x: select returned SOCKET_ERROR\n",
-		     channel->thread_id);
-	  break;
-	}
-
-    if (FD_ISSET (channel->reset_recv, &read_fds))
-    {
-      if (channel->debug)
-        g_print ("select_thread %#x: re-looping\n",
-            channel->thread_id);
-      recv (channel->reset_recv,  (char *)&buffer, (int) sizeof (buffer), 0);
-      continue;
-    }
-
-    if (channel->debug)
-      g_print ("select_thread %#x: got%s%s%s\n",
-	       channel->thread_id,
-	       (FD_ISSET (channel->fd, &read_fds) ? " IN" : ""),
-	       (FD_ISSET (channel->fd, &write_fds) ? " OUT" : ""),
-	       (FD_ISSET (channel->fd, &except_fds) ? " ERR" : ""));
-
-    if (FD_ISSET (channel->fd, &read_fds))
-      channel->revents |= G_IO_IN;
-    if (FD_ISSET (channel->fd, &write_fds))
-      channel->revents |= G_IO_OUT;
-    if (FD_ISSET (channel->fd, &except_fds))
-      channel->revents |= G_IO_ERR;
-
-    if (channel->debug)
-      g_print ("select_thread %#x: resetting data_avail_noticed, setting data_avail\n",
-	       channel->thread_id);
-
-    LOCK (channel->mutex);
-    ResetEvent (channel->data_avail_noticed_event);
-    SetEvent (channel->data_avail_event);
-    if (channel->needs_close)
-      {
-	UNLOCK (channel->mutex);
-	break;
-      }
-    UNLOCK (channel->mutex);
-
-    if (channel->debug)
-      g_print ("select_thread %#x: waiting for data_avail_noticed\n",
-        channel->thread_id);
-
-    WaitForSingleObject (channel->data_avail_noticed_event, INFINITE);
-    if (channel->debug)
-      g_print ("select_thread %#x: got data_avail_noticed\n",
-		 channel->thread_id);
-    }
-
-  LOCK (channel->mutex);
-  channel->running = FALSE;
-  if (channel->debug)
-    g_print ("select_thread %#x: got error, setting data_avail\n",
-	     channel->thread_id);
-  SetEvent (channel->data_avail_event);
-  UNLOCK (channel->mutex);
-  g_io_channel_unref ((GIOChannel *)channel);
-
-  /* No need to call _endthreadex(), the actual thread starter routine
-   * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
-   * _endthreadex() for us.
-   */
-
-  return 0;
-}
-
-static gboolean
-g_io_win32_prepare (GSource *source,
-		    gint    *timeout)
-{
-  GIOWin32Watch *watch = (GIOWin32Watch *)source;
-  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
-  GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
-
-  *timeout = -1;
-
-  if (channel->debug)
-    g_print ("g_io_win32_prepare: for thread %#x buffer_condition:%#x\n"
-	     "  watch->pollfd.events:%#x watch->pollfd.revents:%#x channel->revents:%#x\n",
-	     channel->thread_id, buffer_condition,
-	     watch->pollfd.events, watch->pollfd.revents, channel->revents);
-
-  if (channel->type == G_IO_WIN32_FILE_DESC)
-    {
-      LOCK (channel->mutex);
-      if (channel->running && channel->wrp == channel->rdp)
-	{
-	  if (channel->debug)
-	    g_print ("g_io_win32_prepare: for thread %#x, setting channel->revents = 0\n",
-		     channel->thread_id);
-	  channel->revents = 0;
-	}
-      UNLOCK (channel->mutex);
-    }
-  else if (channel->type == G_IO_WIN32_SOCKET)
-    {
-      LOCK (channel->mutex);
-      channel->revents = 0;
-      if (channel->debug)
-	g_print ("g_io_win32_prepare: for thread %#x, setting data_avail_noticed\n",
-		 channel->thread_id);
-      SetEvent (channel->data_avail_noticed_event);
-      if (channel->debug)
-	g_print ("g_io_win32_prepare: thread %#x, there.\n",
-		 channel->thread_id);
-      UNLOCK (channel->mutex);
-    }
-
-  return ((watch->condition & buffer_condition) == watch->condition);
-}
-
-static gboolean
-g_io_win32_check (GSource *source)
-{
-  MSG msg;
-  GIOWin32Watch *watch = (GIOWin32Watch *)source;
-  GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
-  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
-
-  if (channel->debug)
-    g_print ("g_io_win32_check: for thread %#x buffer_condition:%#x\n"
-	     "  watch->pollfd.events:%#x watch->pollfd.revents:%#x channel->revents:%#x\n",
-	     channel->thread_id, buffer_condition,
-	     watch->pollfd.events, watch->pollfd.revents, channel->revents);
-
-  if (channel->type != G_IO_WIN32_WINDOWS_MESSAGES)
-    {
-      watch->pollfd.revents = (watch->pollfd.events & channel->revents);
-    }
-  else
-    {
-      return (PeekMessage (&msg, channel->hwnd, 0, 0, PM_NOREMOVE));
-    }
-
-  if (channel->type == G_IO_WIN32_SOCKET)
-    {
-      LOCK (channel->mutex);
-      if (channel->debug)
-	g_print ("g_io_win32_check: thread %#x, resetting data_avail\n",
-		 channel->thread_id);
-      ResetEvent (channel->data_avail_event);
-      if (channel->debug)
-	g_print ("g_io_win32_check: thread %#x, there.\n",
-		 channel->thread_id);
-      UNLOCK (channel->mutex);
-    }
-
-  return ((watch->pollfd.revents | buffer_condition) & watch->condition);
-}
-
-static gboolean
-g_io_win32_dispatch (GSource     *source,
-		     GSourceFunc  callback,
-		     gpointer     user_data)
-{
-  GIOFunc func = (GIOFunc)callback;
-  GIOWin32Watch *watch = (GIOWin32Watch *)source;
-  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
-
-  if (!func)
-    {
-      g_warning (G_STRLOC ": GIOWin32Watch dispatched without callback\n"
-		 "You must call g_source_connect().");
-      return FALSE;
-    }
-
-  return (*func) (watch->channel,
-		  (watch->pollfd.revents | buffer_condition) & watch->condition,
-		  user_data);
-}
-
-static void
-g_io_win32_finalize (GSource *source)
-{
-  GIOWin32Watch *watch = (GIOWin32Watch *)source;
-  GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
-  char send_buffer[] = "f";
-
-  LOCK (channel->mutex);
-  if (channel->debug)
-    g_print ("g_io_win32_finalize: channel with thread %#x\n",
-	     channel->thread_id);
-
-  channel->watches = g_slist_remove (channel->watches, watch);
-
-  SetEvent (channel->data_avail_noticed_event);
-  if (channel->type == G_IO_WIN32_SOCKET)
-  {
-    /* Tell select_thread() to exit */
-    channel->needs_close = 1;
-    /* Wake up select_thread() from its blocking select() */
-    send (channel->reset_send, send_buffer, sizeof (send_buffer), 0);
-  }
-
-  UNLOCK (channel->mutex);
-  g_io_channel_unref (watch->channel);
-}
-
-static GSourceFuncs wp_g_io_watch_funcs = {
-  g_io_win32_prepare,
-  g_io_win32_check,
-  g_io_win32_dispatch,
-  g_io_win32_finalize,
-  NULL, NULL
-};
-
-static GSource *
-g_io_win32_create_watch (GIOChannel    *channel,
-			 GIOCondition   condition,
-			 unsigned (__stdcall *thread) (void *parameter))
-{
-  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
-  GIOWin32Watch *watch;
-  GSource *source;
-  char send_buffer[] = "c";
-
-  source = g_source_new (&wp_g_io_watch_funcs, sizeof (GIOWin32Watch));
-  watch = (GIOWin32Watch *)source;
-
-  watch->channel = channel;
-  g_io_channel_ref (channel);
-
-  watch->condition = condition;
-
-  if (win32_channel->data_avail_event == NULL)
-    create_events (win32_channel);
-
-  watch->pollfd.fd = (gint) win32_channel->data_avail_event;
-  watch->pollfd.events = condition;
-
-  if (win32_channel->debug)
-    g_print ("g_io_win32_create_watch: fd:%d condition:%#x handle:%#x\n",
-	     win32_channel->fd, condition, watch->pollfd.fd);
-
-  LOCK (win32_channel->mutex);
-  win32_channel->watches = g_slist_append (win32_channel->watches, watch);
-
-  if (win32_channel->thread_id == 0)
-    create_thread (win32_channel, condition, thread);
-  else
-    send (win32_channel->reset_send, send_buffer, sizeof (send_buffer), 0);
-
-  g_source_add_poll (source, &watch->pollfd);
-  UNLOCK (win32_channel->mutex);
-
-  return source;
-}
-
-static void
-g_io_win32_free (GIOChannel *channel)
-{
-  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
-
-  if (win32_channel->debug)
-    g_print ("thread %#x: freeing channel, fd: %d\n",
-	     win32_channel->thread_id,
-	     win32_channel->fd);
-
-  if (win32_channel->reset_send && win32_channel->reset_send != (gint)INVALID_SOCKET)
-    closesocket (win32_channel->reset_send);
-  if (win32_channel->reset_recv && win32_channel->reset_recv != (gint)INVALID_SOCKET)
-    closesocket (win32_channel->reset_recv);
-  if (win32_channel->data_avail_event)
-    CloseHandle (win32_channel->data_avail_event);
-  if (win32_channel->space_avail_event)
-    CloseHandle (win32_channel->space_avail_event);
-  if (win32_channel->data_avail_noticed_event)
-    CloseHandle (win32_channel->data_avail_noticed_event);
-  DeleteCriticalSection (&win32_channel->mutex);
-
-  g_free (win32_channel->buffer);
-  g_slist_free (win32_channel->watches);
-  g_free (win32_channel);
-}
-
-static GIOStatus
-g_io_win32_sock_read (GIOChannel *channel,
-		      gchar      *buf,
-		      gsize       count,
-		      gsize      *bytes_read,
-		      GError    **err)
-{
-  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
-  gint result;
-  GIOChannelError error = G_IO_STATUS_NORMAL;
-  GIOStatus internal_status = G_IO_STATUS_NORMAL;
-  char send_buffer[] = "sr";
-
-  if (win32_channel->debug)
-    g_print ("g_io_win32_sock_read: sockfd:%d count:%d\n",
-	     win32_channel->fd, count);
-#ifdef WE_NEED_TO_HANDLE_WSAEINTR
-repeat:
-#endif
-  result = recv (win32_channel->fd, buf, count, 0);
-
-  if (win32_channel->debug)
-    g_print ("g_io_win32_sock_read: recv:%d\n", result);
-
-  if (result == SOCKET_ERROR)
-    {
-      *bytes_read = 0;
-
-      switch (WSAGetLastError ())
-	{
-	case WSAEINVAL:
-          error = G_IO_CHANNEL_ERROR_INVAL;
-          break;
-	case WSAEWOULDBLOCK:
-          return G_IO_STATUS_AGAIN;
-#ifdef WE_NEED_TO_HANDLE_WSAEINTR /* not anymore with wsock2 ? */
-	case WSAEINTR:
-          goto repeat;
-#endif
-	default:
-	  error = G_IO_CHANNEL_ERROR_FAILED;
-          break;
-	}
-      g_set_error (err, G_IO_CHANNEL_ERROR, error, "Socket read error");
-      internal_status = G_IO_STATUS_ERROR;
-      /* FIXME get all errors, better error messages */
-    }
-  else
-    {
-      *bytes_read = result;
-      if (result == 0)
-	internal_status = G_IO_STATUS_EOF;
-    }
-
-  if ((internal_status == G_IO_STATUS_EOF) ||
-      (internal_status == G_IO_STATUS_ERROR))
-    {
-      LOCK (win32_channel->mutex);
-      SetEvent (win32_channel->data_avail_noticed_event);
-      win32_channel->needs_close = 1;
-      send (win32_channel->reset_send, send_buffer, sizeof (send_buffer), 0);
-      UNLOCK (win32_channel->mutex);
-    }
-  return internal_status;
-}
-
-static GIOStatus
-g_io_win32_sock_write (GIOChannel  *channel,
-		       const gchar *buf,
-		       gsize        count,
-		       gsize       *bytes_written,
-		       GError     **err)
-{
-  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
-  gint result;
-  GIOChannelError error = G_IO_STATUS_NORMAL;
-  char send_buffer[] = "sw";
-
-  if (win32_channel->debug)
-    g_print ("g_io_win32_sock_write: sockfd:%d count:%d\n",
-	     win32_channel->fd, count);
-#ifdef WE_NEED_TO_HANDLE_WSAEINTR
-repeat:
-#endif
-  result = send (win32_channel->fd, buf, count, 0);
-
-  if (win32_channel->debug)
-    g_print ("g_io_win32_sock_write: send:%d\n", result);
-
-  if (result == SOCKET_ERROR)
-    {
-      *bytes_written = 0;
-
-      switch (WSAGetLastError ())
-	{
-	case WSAEINVAL:
-	  error = G_IO_CHANNEL_ERROR_INVAL;
-          break;
-	case WSAEWOULDBLOCK:
-          return G_IO_STATUS_AGAIN;
-#ifdef WE_NEED_TO_HANDLE_WSAEINTR /* not anymore with wsock2 ? */
-	case WSAEINTR:
-          goto repeat;
-#endif
-	default:
-	  error = G_IO_CHANNEL_ERROR_FAILED;
-          break;
-	}
-      g_set_error (err, G_IO_CHANNEL_ERROR, error, "Socket write error");
-      LOCK (win32_channel->mutex);
-      SetEvent (win32_channel->data_avail_noticed_event);
-      win32_channel->needs_close = 1;
-      send (win32_channel->reset_send, send_buffer, sizeof (send_buffer), 0);
-      UNLOCK (win32_channel->mutex);
-      return G_IO_STATUS_ERROR;
-      /* FIXME get all errors, better error messages */
-    }
-  else
-    {
-      *bytes_written = result;
-
-      return G_IO_STATUS_NORMAL;
-    }
-}
-
-static GIOStatus
-g_io_win32_sock_close (GIOChannel *channel,
-		       GError    **err)
-{
-  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
-
-  LOCK (win32_channel->mutex);
-  if (win32_channel->running)
-    {
-      if (win32_channel->debug)
-	g_print ("thread %#x: running, marking for later close\n",
-		 win32_channel->thread_id);
-      win32_channel->running = FALSE;
-      win32_channel->needs_close = TRUE;
-      SetEvent(win32_channel->data_avail_noticed_event);
-    }
-  if (win32_channel->fd != -1)
-    {
-      if (win32_channel->debug)
-	g_print ("thread %#x: closing socket %d\n",
-		 win32_channel->thread_id,
-		 win32_channel->fd);
-
-      closesocket (win32_channel->fd);
-      win32_channel->fd = -1;
-    }
-  UNLOCK (win32_channel->mutex);
-
-  /* FIXME error detection? */
-
-  return G_IO_STATUS_NORMAL;
-}
-
-static GSource *
-g_io_win32_sock_create_watch (GIOChannel    *channel,
-			      GIOCondition   condition)
-{
-  return g_io_win32_create_watch (channel, condition, select_thread);
-}
-
-static GIOStatus
-g_io_win32_set_flags (GIOChannel *channel,
-                      GIOFlags    flags,
-                      GError    **err)
-{
-  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
-
-  if (win32_channel->debug)
-    {
-      g_print ("g_io_win32_set_flags: ");
-      g_win32_print_gioflags (flags);
-      g_print ("\n");
-    }
-
-  g_warning ("g_io_win32_set_flags () not implemented.\n");
-
-  return G_IO_STATUS_NORMAL;
-}
-
-static GIOFlags
-g_io_win32_sock_get_flags (GIOChannel *channel)
-{
-  /* XXX Could do something here. */
-  return 0;
-}
-
-static GIOFuncs win32_channel_sock_funcs = {
-  g_io_win32_sock_read,
-  g_io_win32_sock_write,
-  NULL,
-  g_io_win32_sock_close,
-  g_io_win32_sock_create_watch,
-  g_io_win32_free,
-  g_io_win32_set_flags,
-  g_io_win32_sock_get_flags,
-};
-
-GIOChannel *
-wpurple_g_io_channel_win32_new_socket (int socket)
-{
-  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
-  GIOChannel *channel = (GIOChannel *)win32_channel;
-
-  g_io_channel_init (channel);
-  g_io_channel_win32_init (win32_channel);
-  init_reset_sockets (win32_channel);
-  if (win32_channel->debug)
-    g_print ("g_io_channel_win32_new_socket: sockfd:%d\n", socket);
-  channel->funcs = &win32_channel_sock_funcs;
-  win32_channel->type = G_IO_WIN32_SOCKET;
-  win32_channel->fd = socket;
-
-  /* XXX: check this */
-  channel->is_readable = TRUE;
-  channel->is_writeable = TRUE;
-
-  channel->is_seekable = FALSE;
-
-  return channel;
-}
-
-#if 0
-void
-g_io_channel_win32_set_debug (GIOChannel *channel,
-			      gboolean    flag)
-{
-  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
-
-  win32_channel->debug = flag;
-}
-#endif
-
--- a/libpurple/win32/libc_interface.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/win32/libc_interface.c	Wed Jun 14 23:40:17 2017 -0500
@@ -929,7 +929,7 @@
 
 	for (i = 0; win32_tzmap[i].wstd != NULL; i++)
 	{
-		if (strcmp(tzname, win32_tzmap[i].wstd) == 0)
+		if (purple_strequal(tzname, win32_tzmap[i].wstd))
 		{
 #if 0
 			purple_debug_info("wpurple", "TZ \"%s\" matches Windows timezone \"%s\"\n",
@@ -945,7 +945,7 @@
 
 			return win32_tzmap[i].ustd;
 		}
-		if (strcmp(tzname, win32_tzmap[i].wdst) == 0)
+		if (purple_strequal(tzname, win32_tzmap[i].wdst))
 		{
 #if 0
 			purple_debug_info("wpurple", "TZ \"%s\" matches Windows timezone \"%s\"\n",
@@ -1019,7 +1019,7 @@
 			RegCloseKey(key);
 			break;
 		}
-		if (strcmp(tzname, zonename) == 0)
+		if (purple_strequal(tzname, zonename))
 		{
 			/* Matched zone */
 			g_strlcpy(localtzname, keyname, sizeof(localtzname));
@@ -1034,7 +1034,7 @@
 			RegCloseKey(key);
 			break;
 		}
-		if (strcmp(tzname, zonename) == 0)
+		if (purple_strequal(tzname, zonename))
 		{
 			/* Matched DST zone */
 			g_strlcpy(localtzname, keyname, sizeof(localtzname));
@@ -1052,7 +1052,7 @@
 		/* Found a localized name, so scan for that one too */
 		for (i = 0; win32_tzmap[i].wstd != NULL; i++)
 		{
-			if (strcmp(localtzname, win32_tzmap[i].wstd) == 0)
+			if (purple_strequal(localtzname, win32_tzmap[i].wstd))
 			{
 #if 0
 				purple_debug_info("wpurple", "TZ \"%s\" matches localized Windows timezone \"%s\" (\"%s\")\n",
@@ -1066,7 +1066,7 @@
 
 				return win32_tzmap[i].ustd;
 			}
-			if (strcmp(localtzname, win32_tzmap[i].wdst) == 0)
+			if (purple_strequal(localtzname, win32_tzmap[i].wdst))
 			{
 #if 0
 				purple_debug_info("wpurple", "TZ \"%s\" matches localized Windows timezone \"%s\" (\"%s\")\n",
--- a/libpurple/win32/win32dep.h	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/win32/win32dep.h	Wed Jun 14 23:40:17 2017 -0500
@@ -62,7 +62,6 @@
 char *wpurple_read_reg_string(HKEY rootkey, const char *subkey, const char *valname); /* needs to be g_free'd */
 gboolean wpurple_write_reg_string(HKEY rootkey, const char *subkey, const char *valname, const char *value);
 char *wpurple_escape_dirsep(const char *filename); /* needs to be g_free'd */
-GIOChannel *wpurple_g_io_channel_win32_new_socket(int socket); /* Until we get the post-2.8 glib win32 giochannel implementation working, use the thread-based one */
 
 /* Simulate unix pipes by creating a pair of connected sockets */
 int wpurple_input_pipe(int pipefd[2]);
--- a/libpurple/xfer.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/libpurple/xfer.c	Wed Jun 14 23:40:17 2017 -0500
@@ -977,8 +977,10 @@
 
 	g_return_if_fail(priv != NULL);
 
-	g_free(priv->message);
-	priv->message = g_strdup(message);
+	if (message != priv->message) {
+		g_free(priv->message);
+		priv->message = g_strdup(message);
+	}
 
 	g_object_notify_by_pspec(G_OBJECT(xfer), properties[PROP_MESSAGE]);
 }
@@ -1000,8 +1002,10 @@
 
 	g_return_if_fail(priv != NULL);
 
-	g_free(priv->filename);
-	priv->filename = g_strdup(filename);
+	if (filename != priv->filename) {
+		g_free(priv->filename);
+		priv->filename = g_strdup(filename);
+	}
 
 	g_object_notify_by_pspec(G_OBJECT(xfer), properties[PROP_FILENAME]);
 }
@@ -1013,8 +1017,10 @@
 
 	g_return_if_fail(priv != NULL);
 
-	g_free(priv->local_filename);
-	priv->local_filename = g_strdup(filename);
+	if (filename != priv->local_filename) {
+		g_free(priv->local_filename);
+		priv->local_filename = g_strdup(filename);
+	}
 
 	g_object_notify_by_pspec(G_OBJECT(xfer), properties[PROP_LOCAL_FILENAME]);
 }
@@ -1917,8 +1923,9 @@
 
 	g_return_if_fail(priv != NULL);
 
-	g_free(priv->thumbnail_data);
-	g_free(priv->thumbnail_mimetype);
+	/* Hold onto these in case they are equal to passed-in pointers */
+	gpointer *old_thumbnail_data = priv->thumbnail_data;
+	const gchar *old_mimetype = priv->thumbnail_mimetype;
 
 	if (thumbnail && size > 0) {
 		priv->thumbnail_data = g_memdup(thumbnail, size);
@@ -1929,6 +1936,10 @@
 		priv->thumbnail_size = 0;
 		priv->thumbnail_mimetype = NULL;
 	}
+
+	/* Now it's safe to free the pointers */
+	g_free(old_thumbnail_data);
+	g_free(old_mimetype);
 }
 
 void
--- a/pidgin/Makefile.am	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/Makefile.am	Wed Jun 14 23:40:17 2017 -0500
@@ -264,7 +264,7 @@
 
 -include $(INTROSPECTION_MAKEFILE)
 INTROSPECTION_GIRS =
-INTROSPECTION_SCANNER_ARGS = --warn-all --add-include-path=$(top_builddir)/libpurple --add-include-path=$(prefix)/share/gir-1.0
+INTROSPECTION_SCANNER_ARGS = --warn-all --add-include-path=$(top_builddir)/libpurple --add-include-path=$(prefix)/share/gir-1.0 --pkg=purple-$(PURPLE_MAJOR_VERSION) --pkg-export=pidgin-$(PURPLE_MAJOR_VERSION)
 INTROSPECTION_COMPILER_ARGS = --includedir=$(top_builddir)/libpurple --includedir=$(prefix)/share/gir-1.0
 
 if HAVE_INTROSPECTION
@@ -299,6 +299,7 @@
 Pidgin_3_0_gir_LIBS = $(builddir)/libpidgin.la
 Pidgin_3_0_gir_FILES = $(introspection_sources)
 INTROSPECTION_GIRS += Pidgin-$(PURPLE_MAJOR_VERSION).$(PURPLE_MINOR_VERSION).gir
+INTROSPECTION_SCANNER_ENV = PKG_CONFIG_PATH=$(top_builddir)/libpurple/data/
 
 girdir = $(prefix)/share/gir-1.0 $(INTROSPECTION_GIRDIR)
 gir_DATA = $(INTROSPECTION_GIRS)
--- a/pidgin/gtkaccount.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkaccount.c	Wed Jun 14 23:40:17 2017 -0500
@@ -812,7 +812,7 @@
 		{
 			case PURPLE_PREF_BOOLEAN:
 				if (account == NULL ||
-					strcmp(purple_account_get_protocol_id(account),
+					!purple_strequal(purple_account_get_protocol_id(account),
 						   dialog->protocol_id))
 				{
 					bool_value = purple_account_option_get_default_bool(option);
@@ -837,7 +837,7 @@
 
 			case PURPLE_PREF_INT:
 				if (account == NULL ||
-					strcmp(purple_account_get_protocol_id(account),
+					!purple_strequal(purple_account_get_protocol_id(account),
 						   dialog->protocol_id))
 				{
 					int_value = purple_account_option_get_default_int(option);
@@ -862,7 +862,7 @@
 
 			case PURPLE_PREF_STRING:
 				if (account == NULL ||
-					strcmp(purple_account_get_protocol_id(account),
+					!purple_strequal(purple_account_get_protocol_id(account),
 						   dialog->protocol_id))
 				{
 					str_value = purple_account_option_get_default_string(option);
@@ -915,7 +915,7 @@
 				idx = 0;
 
 				if (account == NULL ||
-					strcmp(purple_account_get_protocol_id(account),
+					!purple_strequal(purple_account_get_protocol_id(account),
 						   dialog->protocol_id))
 				{
 					str_value = purple_account_option_get_default_list_value(option);
@@ -2651,7 +2651,7 @@
                  gpointer     data)
 {
 	struct auth_request *ar = data;
-	if (!strcmp(uri, "viewinfo")) {
+	if (purple_strequal(uri, "viewinfo")) {
 		pidgin_retrieve_user_info(purple_account_get_connection(ar->account), ar->username);
 		return TRUE;
 	}
--- a/pidgin/gtkblist.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkblist.c	Wed Jun 14 23:40:17 2017 -0500
@@ -1119,8 +1119,8 @@
 	g_return_if_fail(data != NULL);
 	g_return_if_fail(account != NULL);
 
-	if (strcmp(purple_account_get_protocol_id(data->rq_data.account),
-	           purple_account_get_protocol_id(account)) == 0)
+	if (purple_strequal(purple_account_get_protocol_id(data->rq_data.account),
+	                    purple_account_get_protocol_id(account)))
 	{
 		data->rq_data.account = account;
 	}
@@ -2083,7 +2083,7 @@
 {
 	gboolean sensitive = TRUE;
 
-	if(!strcmp(value, "none"))
+	if(purple_strequal(value, "none"))
 		sensitive = FALSE;
 
 	gtk_action_set_sensitive(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds"), sensitive);
@@ -2105,7 +2105,7 @@
 		gc = (PurpleConnection *)l->data;
 		account = purple_connection_get_account(gc);
 
-		if (!strcmp(purple_account_get_protocol_id(account), protocol_id))
+		if (purple_strequal(purple_account_get_protocol_id(account), protocol_id))
 			break;
 
 		account = NULL;
@@ -2169,21 +2169,21 @@
 		if (*s == '\n') *s++ = '\0';
 
 		/* We only want to worry about a few fields here. */
-		if (!strcmp(field, "FN"))
+		if (purple_strequal(field, "FN"))
 			alias = g_strdup(value);
-		else if (!strcmp(field, "X-AIM") || !strcmp(field, "X-ICQ") ||
-				 !strcmp(field, "X-JABBER"))
+		else if (purple_strequal(field, "X-AIM") || purple_strequal(field, "X-ICQ") ||
+				 purple_strequal(field, "X-JABBER"))
 		{
 			char **values = g_strsplit(value, ":", 0);
 			char **im;
 
 			for (im = values; *im != NULL; im++)
 			{
-				if (!strcmp(field, "X-AIM"))
+				if (purple_strequal(field, "X-AIM"))
 					aims = g_list_append(aims, g_strdup(*im));
-				else if (!strcmp(field, "X-ICQ"))
+				else if (purple_strequal(field, "X-ICQ"))
 					icqs = g_list_append(icqs, g_strdup(*im));
-				else if (!strcmp(field, "X-JABBER"))
+				else if (purple_strequal(field, "X-JABBER"))
 					jabbers = g_list_append(jabbers, g_strdup(*im));
 			}
 
@@ -3346,10 +3346,10 @@
 {
 	char *path;
 
-	if (!strcmp(mood, "busy")) {
+	if (purple_strequal(mood, "busy")) {
 		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin",
 			"status", "16", "busy.png", NULL);
-	} else if (!strcmp(mood, "hiptop")) {
+	} else if (purple_strequal(mood, "hiptop")) {
 		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin",
 			"emblems", "16", "hiptop.png", NULL);
 	} else {
@@ -3571,7 +3571,7 @@
 				path, (gpointer)mood->mood);
 		g_free(path);
 
-		if (current_mood && !strcmp(current_mood, mood->mood))
+		if (current_mood && purple_strequal(current_mood, mood->mood))
 			purple_request_field_list_add_selected(f, _(mood->description));
 	}
 	purple_request_field_group_add_field(g, f);
@@ -3846,7 +3846,7 @@
 		g_object_get(c, "alias", &alias, NULL);
 		if (full && c && purple_buddy_get_local_alias(b) != NULL && purple_buddy_get_local_alias(b)[0] != '\0' &&
 		    (alias != NULL && alias[0] != '\0') &&
-		    strcmp(alias, purple_buddy_get_local_alias(b)) != 0)
+		    !purple_strequal(alias, purple_buddy_get_local_alias(b)))
 		{
 			purple_notify_user_info_add_pair_plaintext(user_info,
 					_("Buddy Alias"), purple_buddy_get_local_alias(b));
@@ -4949,7 +4949,7 @@
 static void _prefs_change_sort_method(const char *pref_name, PurplePrefType type,
 									  gconstpointer val, gpointer data)
 {
-	if(!strcmp(pref_name, PIDGIN_PREFS_ROOT "/blist/sort_type"))
+	if(purple_strequal(pref_name, PIDGIN_PREFS_ROOT "/blist/sort_type"))
 		pidgin_blist_sort_method_set(val);
 }
 
@@ -5456,7 +5456,7 @@
 
 	/* else, new and old are both non-NULL */
 
-	descriptions_differ = strcmp(old->description, new->description);
+	descriptions_differ = !purple_strequal(old->description, new->description);
 	desc = new->description;
 
 	switch (new->type) {
@@ -5985,8 +5985,8 @@
 	gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview),
 			pidgin_blist_search_equal_func, NULL, NULL);
 
-	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), 
-		pidgin_make_scrollable(gtkblist->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, -1), 
+	gtk_box_pack_start(GTK_BOX(gtkblist->vbox),
+		pidgin_make_scrollable(gtkblist->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, -1),
 		TRUE, TRUE, 0);
 
 	sep = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
@@ -6026,7 +6026,7 @@
 	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowProtocolIcons")),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"));
 
-	if(!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
+	if(purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
 		gtk_action_set_sensitive(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds"), FALSE);
 
 	/* Update some dynamic things */
@@ -7632,7 +7632,7 @@
 
 	while(l) {
 		struct _PidginBlistSortMethod *method = l->data;
-		if(!strcmp(method->id, id)) {
+		if(purple_strequal(method->id, id)) {
 			pidgin_blist_sort_methods = g_list_delete_link(pidgin_blist_sort_methods, l);
 			g_free(method->id);
 			g_free(method->name);
@@ -7650,7 +7650,7 @@
 	if(!id)
 		id = "none";
 
-	while (l && strcmp(((struct _PidginBlistSortMethod*)l->data)->id, id))
+	while (l && !purple_strequal(((struct _PidginBlistSortMethod*)l->data)->id, id))
 		l = l->next;
 
 	if (l) {
@@ -7659,7 +7659,7 @@
 		pidgin_blist_sort_method_set("none");
 		return;
 	}
-	if (!strcmp(id, "none")) {
+	if (purple_strequal(id, "none")) {
 		redo_buddy_list(purple_blist_get_buddy_list(), TRUE, FALSE);
 	} else {
 		redo_buddy_list(purple_blist_get_buddy_list(), FALSE, FALSE);
@@ -8305,7 +8305,7 @@
 		gtk_radio_action_set_group(action, sl);
 		sl = gtk_radio_action_get_group(action);
 
-		if (!strcmp(m, method->id))
+		if (purple_strequal(m, method->id))
 			gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
 		else
 			gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), FALSE);
--- a/pidgin/gtkconv.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkconv.c	Wed Jun 14 23:40:17 2017 -0500
@@ -534,7 +534,7 @@
 
 		cmdline = cmd + strlen(prefix);
 
-		if (strcmp(cmdline, "xyzzy") == 0) {
+		if (purple_strequal(cmdline, "xyzzy")) {
 			purple_conversation_write_system_message(conv,
 				"Nothing happens", PURPLE_MESSAGE_NO_LOG);
 			g_free(cmd);
@@ -854,7 +854,7 @@
 		else
 			return;
 
-		if (strcmp(convprotocol, purple_account_get_protocol_id(purple_buddy_get_account(buddy))))
+		if (!purple_strequal(convprotocol, purple_account_get_protocol_id(purple_buddy_get_account(buddy))))
 		{
 			purple_notify_error(PIDGIN_CONVERSATION(PURPLE_CONVERSATION(info->chat)),
 				NULL, _("That buddy is not on the same protocol"
@@ -883,7 +883,7 @@
 					_("You are not currently signed on with an account that "
 					  "can invite that buddy."), NULL, NULL);
 			}
-			else if (strcmp(convprotocol, purple_account_get_protocol_id(account)))
+			else if (!purple_strequal(convprotocol, purple_account_get_protocol_id(account)))
 			{
 				purple_notify_error(
 					PIDGIN_CONVERSATION(PURPLE_CONVERSATION(info->chat)), NULL,
@@ -1662,7 +1662,7 @@
 	if (menu)
 		gtk_widget_destroy(menu);
 
-	if (!strcmp(purple_chat_conversation_get_nick(chat), purple_normalize(account, who)))
+	if (purple_strequal(purple_chat_conversation_get_nick(chat), purple_normalize(account, who)))
 		is_me = TRUE;
 
 	menu = gtk_menu_new();
@@ -3263,7 +3263,7 @@
 	PidginConvWindow *win = data;
 	const char *method = value;
 
-	if (!strcmp(method, "none"))
+	if (purple_strequal(method, "none"))
 	{
 		gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu->sounds),
 		                             FALSE);
@@ -3715,7 +3715,7 @@
 		gtk_ui_manager_get_action(win->menu->ui,
 		                          "/Conversation/OptionsMenu/EnableSounds");
 	method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
-	if (method != NULL && !strcmp(method, "none"))
+	if (purple_strequal(method, "none"))
 	{
 		gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu->sounds),
 		                               FALSE);
@@ -4064,7 +4064,7 @@
 	PurpleBuddy *b1 = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(p1));
 	PurpleBuddy *b2 = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(p2));
 	if (purple_buddy_get_account(b1) == purple_buddy_get_account(b2) &&
-			strcmp(purple_buddy_get_name(b1), purple_buddy_get_name(b2)) == 0)
+			purple_strequal(purple_buddy_get_name(b1), purple_buddy_get_name(b2)))
 		return FALSE;
 	return TRUE;
 }
@@ -4316,7 +4316,7 @@
 
 	stock = get_chat_user_status_icon(chat, name, flags);
 
-	if (!strcmp(purple_chat_conversation_get_nick(chat), purple_normalize(purple_conversation_get_account(conv), old_name != NULL ? old_name : name)))
+	if (purple_strequal(purple_chat_conversation_get_nick(chat), purple_normalize(purple_conversation_get_account(conv), old_name != NULL ? old_name : name)))
 		is_me = TRUE;
 
 	is_buddy = purple_chat_user_is_buddy(cb);
@@ -4451,7 +4451,7 @@
 		if (parent) {
 			name = webkit_dom_node_get_node_name(parent);
 			
-			if (!strcmp(name, "BODY")) {
+			if (purple_strequal(name, "BODY")) {
 				g_free(name);
 
 				if (webkit_dom_node_get_previous_sibling(container) == NULL)
@@ -4570,7 +4570,7 @@
 						   CHAT_USERS_ALIAS_COLUMN, &alias,
 						   -1);
 
-				if (name && alias && strcmp(name, alias))
+				if (name && alias && !purple_strequal(name, alias))
 					tab_complete_process_item(&most_matched, entered, entered_chars, &partial,
 										  &matches, alias);
 				g_free(name);
@@ -4724,16 +4724,15 @@
 	f2 &= PURPLE_CHAT_USER_VOICE | PURPLE_CHAT_USER_HALFOP | PURPLE_CHAT_USER_OP |
 			PURPLE_CHAT_USER_FOUNDER;
 
-	if (user1 == NULL || user2 == NULL) {
-		if (!(user1 == NULL && user2 == NULL))
-			ret = (user1 == NULL) ? -1: 1;
-	} else if (f1 != f2) {
-		/* sort more important users first */
-		ret = (f1 > f2) ? -1 : 1;
-	} else if (buddy1 != buddy2) {
-		ret = (buddy1 > buddy2) ? -1 : 1;
-	} else {
-		ret = strcmp(user1, user2);
+	ret = g_strcmp0(user1, user2);
+
+	if (user1 != NULL && user2 != NULL) {
+		if (f1 != f2) {
+			/* sort more important users first */
+			ret = (f1 > f2) ? -1 : 1;
+		} else if (buddy1 != buddy2) {
+			ret = (buddy1 > buddy2) ? -1 : 1;
+		}
 	}
 
 	g_free(user1);
@@ -4768,13 +4767,13 @@
 
 		gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1);
 
-		if (!strcmp(normalized_name, purple_normalize(account, name))) {
+		if (purple_strequal(normalized_name, purple_normalize(account, name))) {
 			const char *alias = name;
 			char *tmp;
 			char *alias_key = NULL;
 			PurpleBuddy *buddy2;
 
-			if (strcmp(purple_chat_conversation_get_nick(chat), purple_normalize(account, name))) {
+			if (!purple_strequal(purple_chat_conversation_get_nick(chat), purple_normalize(account, name))) {
 				/* This user is not me, so look into updating the alias. */
 
 				if ((buddy2 = purple_blist_find_buddy(account, name)) != NULL) {
@@ -4873,7 +4872,7 @@
 
 		gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1);
 
-		if (!strcmp(normalized_name, purple_normalize(purple_conversation_get_account(conv), name))) {
+		if (purple_strequal(normalized_name, purple_normalize(purple_conversation_get_account(conv), name))) {
 			gtk_list_store_set(GTK_LIST_STORE(model), &iter,
 			                   CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1);
 			g_free(name);
@@ -5744,8 +5743,8 @@
 		 */
 		if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
 				protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT_IFACE, invite) &&
-				strcmp(purple_account_get_protocol_id(convaccount),
-					purple_account_get_protocol_id(buddyaccount)) == 0) {
+				purple_strequal(purple_account_get_protocol_id(convaccount),
+					purple_account_get_protocol_id(buddyaccount))) {
 		    purple_chat_conversation_invite_user(PURPLE_CHAT_CONVERSATION(conv), buddyname, NULL, TRUE);
 		} else {
 			/*
@@ -5800,7 +5799,7 @@
 				 */
 				if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
 						protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT_IFACE, invite) &&
-						strcmp(purple_account_get_protocol_id(convaccount), protocol_id) == 0) {
+						purple_strequal(purple_account_get_protocol_id(convaccount), protocol_id)) {
 					purple_chat_conversation_invite_user(PURPLE_CHAT_CONVERSATION(conv), username, NULL, TRUE);
 				} else {
 					im = purple_im_conversation_new(account, username);
@@ -6107,11 +6106,11 @@
 	guint timer;
 
 	/* create hidden conv if hide_new pref is always */
-	if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0)
+	if (purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always"))
 		hide = TRUE;
 
 	/* create hidden conv if hide_new pref is away and account is away */
-	if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 &&
+	if (purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") &&
 	    !purple_status_is_available(purple_account_get_active_status(account)))
 		hide = TRUE;
 
@@ -7053,8 +7052,8 @@
 			history_since_tm = gmtime(&history_since);
 			history_since_s = purple_utf8_strftime(
 				"%Y-%m-%dT%H:%M:%SZ", history_since_tm);
-			if (g_strcmp0(prev_history_since_s,
-				history_since_s) != 0)
+			if (!purple_strequal(prev_history_since_s,
+				history_since_s))
 				g_hash_table_replace(comps,
 					g_strdup("history_since"),
 					g_strdup(history_since_s));
@@ -7665,7 +7664,7 @@
 		gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title);
 		if (pidgin_conv_window_is_active_conversation(conv)) {
 			const char* current_title = gtk_window_get_title(GTK_WINDOW(win->window));
-			if (current_title == NULL || g_strcmp0(current_title, title) != 0)
+			if (current_title == NULL || !purple_strequal(current_title, title))
 				gtk_window_set_title(GTK_WINDOW(win->window), title);
 		}
 
@@ -8233,7 +8232,7 @@
 	PurpleConversation *conv = NULL;
 	PidginConversation *gtkconv;
 
-	if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0)
+	if(!purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away"))
 		return;
 
 	if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus))
@@ -8268,10 +8267,10 @@
 	if(!hidden_convwin)
 		return;
 
-	if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0)
+	if(purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always"))
 		return;
 
-	if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0)
+	if(purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away"))
 		when_away = TRUE;
 
 	for (l = hidden_convwin->gtkconvs; l; )
@@ -8299,7 +8298,7 @@
 {
 	PidginConvPlacementFunc func;
 
-	if (strcmp(name, PIDGIN_PREFS_ROOT "/conversations/placement"))
+	if (!purple_strequal(name, PIDGIN_PREFS_ROOT "/conversations/placement"))
 		return;
 
 	func = pidgin_conv_placement_get_fnc(value);
@@ -9979,7 +9978,7 @@
 	pidgin_conv_switch_active_conversation(conv);
 
 	sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
-	if (strcmp(sound_method, "none") != 0)
+	if (!purple_strequal(sound_method, "none"))
 		gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu->sounds),
 		                             gtkconv->make_sound);
 
@@ -11010,7 +11009,7 @@
 
 	for (n = conv_placement_fncs; n; n = n->next) {
 		data = n->data;
-		if (!strcmp(data->id, id))
+		if (purple_strequal(data->id, id))
 			return data;
 	}
 
--- a/pidgin/gtkdialogs.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkdialogs.c	Wed Jun 14 23:40:17 2017 -0500
@@ -992,31 +992,31 @@
 	gchar *norm = purple_strreplace(ee, "rocksmyworld", "");
 
 	label = gtk_label_new(NULL);
-	if (!strcmp(norm, "zilding"))
+	if (purple_strequal(norm, "zilding"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				     "<span weight=\"bold\" size=\"large\" foreground=\"purple\">Amazing!  Simply Amazing!</span>");
-	else if (!strcmp(norm, "robflynn"))
+	else if (purple_strequal(norm, "robflynn"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				     "<span weight=\"bold\" size=\"large\" foreground=\"#1f6bad\">Pimpin\' Penguin Style! *Waddle Waddle*</span>");
-	else if (!strcmp(norm, "flynorange"))
+	else if (purple_strequal(norm, "flynorange"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				      "<span weight=\"bold\" size=\"large\" foreground=\"blue\">You should be me.  I'm so cute!</span>");
-	else if (!strcmp(norm, "ewarmenhoven"))
+	else if (purple_strequal(norm, "ewarmenhoven"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				     "<span weight=\"bold\" size=\"large\" foreground=\"orange\">Now that's what I like!</span>");
-	else if (!strcmp(norm, "markster97"))
+	else if (purple_strequal(norm, "markster97"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				     "<span weight=\"bold\" size=\"large\" foreground=\"brown\">Ahh, and excellent choice!</span>");
-	else if (!strcmp(norm, "seanegn"))
+	else if (purple_strequal(norm, "seanegn"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				     "<span weight=\"bold\" size=\"large\" foreground=\"#009900\">Everytime you click my name, an angel gets its wings.</span>");
-	else if (!strcmp(norm, "chipx86"))
+	else if (purple_strequal(norm, "chipx86"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				     "<span weight=\"bold\" size=\"large\" foreground=\"red\">This sunflower seed taste like pizza.</span>");
-	else if (!strcmp(norm, "markdoliner"))
+	else if (purple_strequal(norm, "markdoliner"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				     "<span weight=\"bold\" size=\"large\" foreground=\"#6364B1\">Hey!  I was in that tumbleweed!</span>");
-	else if (!strcmp(norm, "lschiere"))
+	else if (purple_strequal(norm, "lschiere"))
 		gtk_label_set_markup(GTK_LABEL(label),
 				     "<span weight=\"bold\" size=\"large\" foreground=\"gray\">I'm not anything.</span>");
 	g_free(norm);
--- a/pidgin/gtkdocklet.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkdocklet.c	Wed Jun 14 23:40:17 2017 -0500
@@ -147,7 +147,7 @@
 	/* determine if any ims have unseen messages */
 	convs = get_pending_list(DOCKLET_TOOLTIP_LINE_LIMIT);
 
-	if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
+	if (purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
 		if (convs && !visible) {
 			g_list_free(convs);
 			docklet_gtk_status_create(FALSE);
@@ -300,14 +300,14 @@
 			     gconstpointer value, gpointer data)
 {
 	const char *val = value;
-	if (!strcmp(val, "always")) {
+	if (purple_strequal(val, "always")) {
 		if (!visible)
 			docklet_gtk_status_create(FALSE);
 		else if (!visibility_manager) {
 			pidgin_blist_visibility_manager_add();
 			visibility_manager = TRUE;
 		}
-	} else if (!strcmp(val, "never")) {
+	} else if (purple_strequal(val, "never")) {
 		if (visible)
 			docklet_gtk_status_destroy();
 	} else {
@@ -433,7 +433,7 @@
 				if (sub) {
 					const PurpleStatusType *sub_type = purple_savedstatus_substatus_get_status_type(sub);
 					const char *subtype_status_id = purple_status_type_get_id(sub_type);
-					if (subtype_status_id && !strcmp(subtype_status_id,
+					if (subtype_status_id && purple_strequal(subtype_status_id,
 							purple_status_type_get_id(status_type)))
 						found = TRUE;
 				}
@@ -745,7 +745,7 @@
 
 	menuitem = gtk_check_menu_item_new_with_mnemonic(_("Mute _Sounds"));
 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/sound/mute"));
-	if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
+	if (purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
 		gtk_widget_set_sensitive(GTK_WIDGET(menuitem), FALSE);
 	g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_mute), NULL);
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
@@ -796,7 +796,7 @@
 pidgin_docklet_embedded(void)
 {
 	if (!visibility_manager
-	    && strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
+	    && !purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
 		pidgin_blist_visibility_manager_add();
 		visibility_manager = TRUE;
 	}
@@ -991,7 +991,7 @@
 	gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), tmp);
 	g_free(tmp);
 
-	if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always"))
+	if (purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always"))
 		docklet_gtk_status_create(FALSE);
 
 	purple_signal_connect(conn_handle, "signed-on",
--- a/pidgin/gtkeventloop.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkeventloop.c	Wed Jun 14 23:40:17 2017 -0500
@@ -75,12 +75,6 @@
 	PidginIOClosure *closure = g_new0(PidginIOClosure, 1);
 	GIOChannel *channel;
 	GIOCondition cond = 0;
-#ifdef _WIN32
-	static int use_glib_io_channel = -1;
-
-	if (use_glib_io_channel == -1)
-		use_glib_io_channel = (g_getenv("PIDGIN_GLIB_IO_CHANNEL") != NULL) ? 1 : 0;
-#endif
 
 	closure->function = function;
 	closure->data = data;
@@ -91,11 +85,10 @@
 		cond |= PIDGIN_WRITE_COND;
 
 #ifdef _WIN32
-	if (use_glib_io_channel == 0)
-		channel = wpurple_g_io_channel_win32_new_socket(fd);
-	else
+	channel = g_io_channel_win32_new_socket(fd);
+#else
+	channel = g_io_channel_unix_new(fd);
 #endif
-	channel = g_io_channel_unix_new(fd);
 
 	closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
 					      pidgin_io_invoke, closure, g_free);
--- a/pidgin/gtklog.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtklog.c	Wed Jun 14 23:40:17 2017 -0500
@@ -79,7 +79,7 @@
 
 	normal = g_strdup(purple_normalize(a->account, a->buddyname));
 	ret = (a->account == b->account) &&
-		!strcmp(normal, purple_normalize(b->account, b->buddyname));
+		purple_strequal(normal, purple_normalize(b->account, b->buddyname));
 	g_free(normal);
 
 	return ret;
@@ -132,7 +132,7 @@
 		return;
 	}
 
-	if (lv->search != NULL && !strcmp(lv->search, search_term))
+	if (lv->search != NULL && purple_strequal(lv->search, search_term))
 	{
 		/* Searching for the same term acts as "Find Next" */
 		webkit_web_view_search_text(WEBKIT_WEB_VIEW(lv->web_view), lv->search, FALSE, TRUE, TRUE);
@@ -503,7 +503,7 @@
 		month = purple_utf8_strftime(_("%B %Y"),
 		                           log->tm ? log->tm : localtime(&log->time));
 
-		if (strcmp(month, prev_top_month) != 0)
+		if (!purple_strequal(month, prev_top_month))
 		{
 			/* top level */
 			gtk_tree_store_append(lv->treestore, &toplevel, NULL);
--- a/pidgin/gtknotify.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtknotify.c	Wed Jun 14 23:40:17 2017 -0500
@@ -1361,8 +1361,8 @@
 	} else if (purple_running_osx() == TRUE) {
 		argv = g_slist_append(argv, "open");
 		argv = g_slist_append(argv, uri_escaped);
-	} else if (!strcmp(web_browser, "epiphany") ||
-		!strcmp(web_browser, "galeon"))
+	} else if (purple_strequal(web_browser, "epiphany") ||
+		purple_strequal(web_browser, "galeon"))
 	{
 		argv = g_slist_append(argv, (gpointer)web_browser);
 
@@ -1372,13 +1372,13 @@
 			argv = g_slist_append(argv, "-n");
 
 		argv = g_slist_append(argv, uri_escaped);
-	} else if (!strcmp(web_browser, "xdg-open")) {
+	} else if (purple_strequal(web_browser, "xdg-open")) {
 		argv = g_slist_append(argv, "xdg-open");
 		argv = g_slist_append(argv, uri_escaped);
-	} else if (!strcmp(web_browser, "gnome-open")) {
+	} else if (purple_strequal(web_browser, "gnome-open")) {
 		argv = g_slist_append(argv, "gnome-open");
 		argv = g_slist_append(argv, uri_escaped);
-	} else if (!strcmp(web_browser, "kfmclient")) {
+	} else if (purple_strequal(web_browser, "kfmclient")) {
 		argv = g_slist_append(argv, "kfmclient");
 		argv = g_slist_append(argv, "openURL");
 		argv = g_slist_append(argv, uri_escaped);
@@ -1386,10 +1386,10 @@
 		 * Does Konqueror have options to open in new tab
 		 * and/or current window?
 		 */
-	} else if (!strcmp(web_browser, "mozilla") ||
-		!strcmp(web_browser, "mozilla-firebird") ||
-		!strcmp(web_browser, "firefox") ||
-		!strcmp(web_browser, "seamonkey"))
+	} else if (purple_strequal(web_browser, "mozilla") ||
+		purple_strequal(web_browser, "mozilla-firebird") ||
+		purple_strequal(web_browser, "firefox") ||
+		purple_strequal(web_browser, "seamonkey"))
 	{
 		argv = g_slist_append(argv, (gpointer)web_browser);
 		argv = g_slist_append(argv, uri_escaped);
@@ -1415,7 +1415,7 @@
 			 * should probably be split apart from mozilla-firebird
 			 * and mozilla... but this is good for now.
 			 */
-			if (!strcmp(web_browser, "firefox")) {
+			if (purple_strequal(web_browser, "firefox")) {
 				argv_remote = g_slist_append(argv_remote, "-a");
 				argv_remote = g_slist_append(argv_remote,
 					"firefox");
@@ -1424,7 +1424,7 @@
 			argv_remote = g_slist_append(argv_remote, "-remote");
 			argv_remote = g_slist_append(argv_remote, uri_custom);
 		}
-	} else if (!strcmp(web_browser, "opera")) {
+	} else if (purple_strequal(web_browser, "opera")) {
 		argv = g_slist_append(argv, "opera");
 
 		if (place == PIDGIN_BROWSER_NEW_WINDOW)
@@ -1436,28 +1436,28 @@
 		 */
 
 		argv = g_slist_append(argv, uri_escaped);
-	} else if (!strcmp(web_browser, "google-chrome")) {
+	} else if (purple_strequal(web_browser, "google-chrome")) {
 		/* Google Chrome doesn't have command-line arguments that
 		 * control the opening of links from external calls. This is
 		 * controlled solely from a preference within Google Chrome.
 		 */
 		argv = g_slist_append(argv, "google-chrome");
 		argv = g_slist_append(argv, uri_escaped);
-	} else if (!strcmp(web_browser, "chrome")) {
+	} else if (purple_strequal(web_browser, "chrome")) {
 		/* Chromium doesn't have command-line arguments that control
 		 * the opening of links from external calls. This is controlled
 		 * solely from a preference within Chromium.
 		 */
 		argv = g_slist_append(argv, "chrome");
 		argv = g_slist_append(argv, uri_escaped);
-	} else if (!strcmp(web_browser, "chromium-browser")) {
+	} else if (purple_strequal(web_browser, "chromium-browser")) {
 		/* Chromium doesn't have command-line arguments that control the
 		 * opening of links from external calls. This is controlled
 		 * solely from a preference within Chromium.
 		 */
 		argv = g_slist_append(argv, "chromium-browser");
 		argv = g_slist_append(argv, uri_escaped);
-	} else if (!strcmp(web_browser, "custom")) {
+	} else if (purple_strequal(web_browser, "custom")) {
 		GError *error = NULL;
 		const char *usercmd_command;
 		gint usercmd_argc, i;
--- a/pidgin/gtkpounce.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkpounce.c	Wed Jun 14 23:40:17 2017 -0500
@@ -171,7 +171,7 @@
 
 	filename = gtk_entry_get_text(GTK_ENTRY(entry));
 
-	if (filename != NULL && *filename != '\0' && strcmp(filename, _("(default)")))
+	if (filename != NULL && *filename != '\0' && !purple_strequal(filename, _("(default)")))
 		purple_sound_play_file(filename, NULL);
 	else
 		purple_sound_play_event(PURPLE_SOUND_POUNCE_DEFAULT, NULL);
@@ -311,7 +311,7 @@
 		message = NULL;
 	}
 	if (*command == '\0') command = NULL;
-	if (*sound   == '\0' || !strcmp(sound, _("(default)"))) sound   = NULL;
+	if (*sound   == '\0' || purple_strequal(sound, _("(default)"))) sound   = NULL;
 
 	/* If the pounce has already been triggered, let's pretend it is a new one */
 	if (dialog->pounce != NULL
--- a/pidgin/gtkprefs.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkprefs.c	Wed Jun 14 23:40:17 2017 -0500
@@ -359,7 +359,7 @@
 		if ((initial.type == PURPLE_PREF_INT &&
 			initial.value.integer == int_value) ||
 			(initial.type == PURPLE_PREF_STRING &&
-			!g_strcmp0(initial.value.string, str_value)) ||
+			purple_strequal(initial.value.string, str_value)) ||
 			(initial.type == PURPLE_PREF_BOOLEAN &&
 			(initial.value.boolean == bool_value))) {
 
@@ -583,7 +583,7 @@
 		do {
 			gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &iter, 2, &name, -1);
 
-			print_custom = customized && name && g_str_equal(current_theme, name);
+			print_custom = customized && name && purple_strequal(current_theme, name);
 
 			if (!name || *name == '\0') {
 				g_free(name);
@@ -684,7 +684,7 @@
 		do {
 			gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 2, &theme, -1);
 
-			if (g_str_equal(current_theme, theme)) {
+			if (purple_strequal(current_theme, theme)) {
 				gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter);
 				unset = FALSE;
 			}
@@ -878,7 +878,7 @@
 	/* Just to be safe */
 	g_strchomp(path);
 
-	if ((is_smiley_theme = g_str_equal(info->type, "smiley")))
+	if ((is_smiley_theme = purple_strequal(info->type, "smiley")))
 		destdir = g_build_filename(purple_user_dir(), "smileys", NULL);
 	else
 		destdir = g_build_filename(purple_user_dir(), "themes", "temp", NULL);
@@ -1245,7 +1245,7 @@
 
 		gtk_tree_model_get(GTK_TREE_MODEL(prefs_blist_themes), &iter, 2, &name, -1);
 
-		if(!name || !g_str_equal(name, ""))
+		if(!name || *name)
 			theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(name, "blist"));
 
 		g_free(name);
@@ -1340,7 +1340,7 @@
 
 		gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1);
 
-		if(!name || !g_str_equal(name, ""))
+		if(!name || *name)
 			theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon"));
 
 		g_free(name);
@@ -1989,7 +1989,7 @@
 	GtkWidget *frame = data;
 	const char *proxy = value;
 
-	if (strcmp(proxy, "none") && strcmp(proxy, "envvar"))
+	if (!purple_strequal(proxy, "none") && !purple_strequal(proxy, "envvar"))
 		gtk_widget_show_all(frame);
 	else
 		gtk_widget_hide(frame);
@@ -2268,11 +2268,11 @@
 			browsers = g_list_prepend(browsers,
 									  possible_browsers[i].command);
 			browsers = g_list_prepend(browsers, (gpointer)_(possible_browsers[i].name));
-			if(browser_setting && !strcmp(possible_browsers[i].command, browser_setting))
+			if(browser_setting && purple_strequal(possible_browsers[i].command, browser_setting))
 				browser_setting = NULL;
 			/* If xdg-open is valid, prefer it over gnome-open and skip forward */
-			if(!strcmp(possible_browsers[i].command, "xdg-open")) {
-				if (browser_setting && !strcmp("gnome-open", browser_setting)) {
+			if(purple_strequal(possible_browsers[i].command, "xdg-open")) {
+				if (purple_strequal("gnome-open", browser_setting)) {
 					purple_prefs_set_string(PIDGIN_PREFS_ROOT "/browsers/browser", possible_browsers[i].command);
 					browser_setting = NULL;
 				}
@@ -2294,7 +2294,7 @@
 	GtkWidget *hbox = data;
 	const char *browser = value;
 
-	gtk_widget_set_sensitive(hbox, strcmp(browser, "custom"));
+	gtk_widget_set_sensitive(hbox, !purple_strequal(browser, "custom"));
 }
 
 static void
@@ -2304,7 +2304,7 @@
 	GtkWidget *hbox = data;
 	const char *browser = value;
 
-	gtk_widget_set_sensitive(hbox, !strcmp(browser, "custom"));
+	gtk_widget_set_sensitive(hbox, purple_strequal(browser, "custom"));
 }
 
 static GtkWidget *
@@ -2378,7 +2378,7 @@
 			gtk_size_group_add_widget(sg, label);
 			gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
-			if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom"))
+			if (purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom"))
 				gtk_widget_set_sensitive(hbox, FALSE);
 			purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser",
 										browser_changed1_cb, hbox);
@@ -2390,7 +2390,7 @@
 		g_signal_connect(G_OBJECT(entry), "focus-out-event",
 						 G_CALLBACK(manual_browser_set), NULL);
 		hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Manual:\n(%s for URL)"), sg, entry, TRUE, NULL);
-		if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom"))
+		if (!purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom"))
 			gtk_widget_set_sensitive(hbox, FALSE);
 		purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser",
 				browser_changed2_cb, hbox);
@@ -2883,7 +2883,7 @@
 	GtkWidget *hbox = data;
 	const char *method = value;
 
-	gtk_widget_set_sensitive(hbox, !strcmp(method, "custom"));
+	gtk_widget_set_sensitive(hbox, purple_strequal(method, "custom"));
 }
 
 static void
@@ -2893,7 +2893,7 @@
 	GtkWidget *vbox = data;
 	const char *method = value;
 
-	gtk_widget_set_sensitive(vbox, strcmp(method, "none"));
+	gtk_widget_set_sensitive(vbox, !purple_strequal(method, "none"));
 }
 
 
@@ -3041,7 +3041,7 @@
 	GtkToggleButton *button = data;
 	gboolean muted = GPOINTER_TO_INT(val);
 
-	g_return_if_fail(!strcmp (pref_name, PIDGIN_PREFS_ROOT "/sound/mute"));
+	g_return_if_fail(purple_strequal (pref_name, PIDGIN_PREFS_ROOT "/sound/mute"));
 
 	/* Block the handler that re-sets the preference. */
 	g_signal_handlers_block_matched(button, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, (gpointer)pref_name);
@@ -3117,7 +3117,7 @@
 	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method",
 								sound_changed1_cb, hbox);
 	gtk_widget_set_sensitive(hbox,
-			!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"),
+			purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"),
 					"custom"));
 
 	button = pidgin_prefs_checkbox(_("M_ute sounds"), PIDGIN_PREFS_ROOT "/sound/mute", vbox);
@@ -3133,7 +3133,7 @@
 				NULL);
 
 	gtk_widget_set_sensitive(vbox,
-			strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"));
+			!purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"));
 	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method",
 								sound_changed2_cb, vbox);
 	vbox = pidgin_make_frame(ret, _("Sound Events"));
@@ -3452,7 +3452,7 @@
 		GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
 		gchar *name = gst_element_get_name(src);
 
-		if (!strcmp(name, "level")) {
+		if (purple_strequal(name, "level")) {
 			gdouble percent;
 			gdouble threshold;
 			GstElement *valve;
@@ -4020,7 +4020,7 @@
 	const gchar *theme_name = value;
 	GList *themes, *it;
 
-	if (g_strcmp0(theme_name, "none") == 0) {
+	if (purple_strequal(theme_name, "none")) {
 		purple_smiley_theme_set_current(NULL);
 		return;
 	}
@@ -4031,7 +4031,7 @@
 	for (it = themes; it; it = g_list_next(it)) {
 		PidginSmileyTheme *theme = it->data;
 
-		if (g_strcmp0(pidgin_smiley_theme_get_name(theme), theme_name))
+		if (!purple_strequal(pidgin_smiley_theme_get_name(theme), theme_name))
 			continue;
 
 		purple_smiley_theme_set_current(PURPLE_SMILEY_THEME(theme));
--- a/pidgin/gtkrequest.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkrequest.c	Wed Jun 14 23:40:17 2017 -0500
@@ -148,7 +148,7 @@
 		gtk_text_buffer_get_start_iter(buffer, &start_iter);
 		gtk_text_buffer_get_end_iter(buffer, &end_iter);
 
-		if ((data->u.input.hint != NULL) && (!strcmp(data->u.input.hint, "html")))
+		if (purple_strequal(data->u.input.hint, "html"))
 			multiline_value = pidgin_webview_get_body_html(PIDGIN_WEBVIEW(data->u.input.entry));
 		else
 			multiline_value = gtk_text_buffer_get_text(buffer, &start_iter, &end_iter,
@@ -324,7 +324,7 @@
 
 
 #define STOCK_ITEMIZE(r, l) \
-	if (!strcmp((r), text) || !strcmp(_(r), text)) \
+	if (purple_strequal((r), text) || purple_strequal(_(r), text)) \
 		return (l);
 
 static const char *
@@ -607,7 +607,7 @@
 
 	gtk_widget_show_all(hbox);
 
-	if ((data->u.input.hint != NULL) && (!strcmp(data->u.input.hint, "html"))) {
+	if (purple_strequal(data->u.input.hint, "html")) {
 		GtkWidget *frame;
 
 		/* webview */
@@ -634,7 +634,7 @@
 
 			gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(entry), GTK_WRAP_WORD_CHAR);
 
-			gtk_box_pack_start(GTK_BOX(vbox), 
+			gtk_box_pack_start(GTK_BOX(vbox),
 				pidgin_make_scrollable(entry, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, 320, 130),
 				TRUE, TRUE, 0);
 		}
@@ -1131,7 +1131,7 @@
 						purple_request_field_is_visible(fld))
 				{
 					const char *type_hint = purple_request_field_get_field_type_hint(fld);
-					if (type_hint != NULL && strcmp(type_hint, "account") == 0)
+					if (purple_strequal(type_hint, "account"))
 					{
 						optmenu = GTK_WIDGET(purple_request_field_get_ui_data(fld));
 						if (optmenu == NULL) {
@@ -1142,7 +1142,7 @@
 					}
 				}
 			}
-			pidgin_setup_screenname_autocomplete(entry, optmenu, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(!strcmp(type_hint, "screenname-all")));
+			pidgin_setup_screenname_autocomplete(entry, optmenu, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(purple_strequal(type_hint, "screenname-all")));
 		}
 	}
 }
@@ -1601,7 +1601,7 @@
 	id[0] = '\0';
 	id++;
 
-	if (g_strcmp0(domain, "protocol") == 0) {
+	if (purple_strequal(domain, "protocol")) {
 		PurpleAccount *account;
 		gchar *protocol_id, *accountname;
 
@@ -1621,7 +1621,7 @@
 			image = pidgin_create_protocol_icon(account,
 				PIDGIN_PROTOCOL_ICON_SMALL);
 		}
-	} else if (g_strcmp0(domain, "e2ee") == 0) {
+	} else if (purple_strequal(domain, "e2ee")) {
 		image = pidgin_pixbuf_from_image(
 			_pidgin_e2ee_stock_icon_get(id));
 	} else {
--- a/pidgin/gtksavedstatuses.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtksavedstatuses.c	Wed Jun 14 23:40:17 2017 -0500
@@ -151,7 +151,7 @@
 
 	do {
 		gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1);
-		if (!strcmp(title, cur))
+		if (purple_strequal(title, cur))
 		{
 			g_free(cur);
 			return TRUE;
@@ -718,7 +718,7 @@
 	 */
 	if (((button == dialog->saveanduse_button) || (button == dialog->save_button)) &&
 		(purple_savedstatus_find(title) != NULL) &&
-		((dialog->original_title == NULL) || (strcmp(title, dialog->original_title))))
+		((dialog->original_title == NULL) || (!purple_strequal(title, dialog->original_title))))
 	{
 		purple_notify_error(status_window, NULL, _("Title already in use.  You must "
 						  "choose a unique title."), NULL, NULL);
@@ -756,7 +756,7 @@
 	else
 	{
 		/* Modify the old status */
-		if (strcmp(title, dialog->original_title))
+		if (!purple_strequal(title, dialog->original_title))
 			purple_savedstatus_set_title(saved_status, title);
 		purple_savedstatus_set_primitive_type(saved_status, type);
 	}
@@ -1177,7 +1177,7 @@
 	dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
 	gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE);
 	gtk_widget_set_size_request(dialog->treeview, -1, 150);
-	gtk_box_pack_start(GTK_BOX(dbox), 
+	gtk_box_pack_start(GTK_BOX(dbox),
 		pidgin_make_scrollable(dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
 		TRUE, TRUE, 0);
 
@@ -1520,7 +1520,7 @@
 						   STATUS_COLUMN_STATUS_ID, id,
 						   STATUS_COLUMN_STATUS_NAME, name,
 						   -1);
-		if ((status_id != NULL) && !strcmp(status_id, id))
+		if ((status_id != NULL) && purple_strequal(status_id, id))
 		{
 			gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter);
 			select = TRUE;
--- a/pidgin/gtksmiley-manager.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtksmiley-manager.c	Wed Jun 14 23:40:17 2017 -0500
@@ -238,8 +238,8 @@
 	if (edit_dialog->smiley == NULL)
 		shortcut_changed = image_changed = TRUE;
 	else {
-		shortcut_changed = (g_strcmp0(purple_smiley_get_shortcut(
-			edit_dialog->smiley), shortcut) != 0);
+		shortcut_changed = purple_strequal(purple_smiley_get_shortcut(
+			edit_dialog->smiley), shortcut);
 		image_changed = (edit_dialog->new_image != NULL);
 	}
 
--- a/pidgin/gtksound.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtksound.c	Wed Jun 14 23:40:17 2017 -0500
@@ -449,14 +449,14 @@
 
 	method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
 
-	if (!strcmp(method, "none")) {
+	if (purple_strequal(method, "none")) {
 		return;
-	} else if (!strcmp(method, "beep")) {
+	} else if (purple_strequal(method, "beep")) {
 		gdk_beep();
 		return;
 	}
 #ifdef _WIN32
-	else if (!strcmp(method, "playsoundw")) {
+	else if (purple_strequal(method, "playsoundw")) {
 		pidgin_sound_play_file_win32(filename);
 		return;
 	}
@@ -468,7 +468,7 @@
 	}
 
 #ifndef _WIN32
-	if (!strcmp(method, "custom")) {
+	if (purple_strequal(method, "custom")) {
 		const char *sound_cmd;
 		char *command;
 		char *esc_filename;
@@ -521,23 +521,23 @@
 	if (gst_init_failed)  /* Perhaps do gdk_beep instead? */
 		return;
 #ifdef _WIN32
-	if (!strcmp(method, "automatic")) {
+	if (purple_strequal(method, "automatic")) {
 		sink = gst_element_factory_make("directsoundsink", "sink");
 		if (sink == NULL)
 			sink = gst_element_factory_make("waveformsink", "sink");
 		if (sink == NULL)
 			sink = gst_element_factory_make("gconfaudiosink", "sink");
-	} else if (!strcmp(method, "directsound")) {
+	} else if (purple_strequal(method, "directsound")) {
 		sink = gst_element_factory_make("directsoundsink", "sink");
-	} else if (!strcmp(method, "waveform")) {
+	} else if (purple_strequal(method, "waveform")) {
 		sink = gst_element_factory_make("waveformsink", "sink");
 	}
 #else
-	if (!strcmp(method, "automatic")) {
+	if (purple_strequal(method, "automatic")) {
 		sink = gst_element_factory_make("gconfaudiosink", "sink");
-	} else if (!strcmp(method, "esd")) {
+	} else if (purple_strequal(method, "esd")) {
 		sink = gst_element_factory_make("esdsink", "sink");
-	} else if (!strcmp(method, "alsa")) {
+	} else if (purple_strequal(method, "alsa")) {
 		sink = gst_element_factory_make("alsasink", "sink");
 	}
 #endif
@@ -546,7 +546,7 @@
 		return;
 	}
 
-	if (strcmp(method, "automatic") != 0 && !sink) {
+	if (!purple_strequal(method, "automatic") && !sink) {
 		purple_debug_error("sound", "Unable to create GStreamer audiosink.\n");
 		return;
 	}
--- a/pidgin/gtkstatusbox.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkstatusbox.c	Wed Jun 14 23:40:17 2017 -0500
@@ -820,7 +820,7 @@
 							TEXT_COLUMN, &name, -1);
 
 					if (!purple_savedstatus_has_substatuses(saved_status)
-						|| !strcmp(name, acct_status_name))
+						|| purple_strequal(name, acct_status_name))
 					{
 						/* Found! */
 						path = gtk_tree_model_get_path(GTK_TREE_MODEL(status_box->dropdown_store), &iter);
@@ -956,7 +956,7 @@
 		PurpleAccount *acct2 = iter->data;
 		GList *s1, *s2;
 
-		if (!g_str_equal(proto1, purple_account_get_protocol_id(acct2))) {
+		if (!purple_strequal(proto1, purple_account_get_protocol_id(acct2))) {
 			acct1 = NULL;
 			break;
 		}
@@ -967,8 +967,8 @@
 			PurpleStatusType *st1 = s1->data, *st2 = s2->data;
 			/* TODO: Are these enough to consider the statuses identical? */
 			if (purple_status_type_get_primitive(st1) != purple_status_type_get_primitive(st2)
-				|| strcmp(purple_status_type_get_id(st1), purple_status_type_get_id(st2))
-				|| strcmp(purple_status_type_get_name(st1), purple_status_type_get_name(st2))) {
+				|| !purple_strequal(purple_status_type_get_id(st1), purple_status_type_get_id(st2))
+				|| !purple_strequal(purple_status_type_get_name(st1), purple_status_type_get_name(st2))) {
 				acct1 = NULL;
 				break;
 			}
@@ -2341,7 +2341,7 @@
 			acct_status_type = find_status_type_by_index(status_box->token_status_account, active);
 			id = purple_status_type_get_id(acct_status_type);
 
-			if (g_str_equal(id, purple_status_get_id(status)) &&
+			if (purple_strequal(id, purple_status_get_id(status)) &&
 				purple_strequal(message, purple_status_get_attr_string(status, "message")))
 			{
 				/* Selected status and previous status is the same */
@@ -2442,7 +2442,7 @@
 		status_type = find_status_type_by_index(status_box->account, active);
 		id = purple_status_type_get_id(status_type);
 
-		if (g_str_equal(id, purple_status_get_id(status)) &&
+		if (purple_strequal(id, purple_status_get_id(status)) &&
 			purple_strequal(message, purple_status_get_attr_string(status, "message")))
 		{
 			/* Selected status and previous status is the same */
--- a/pidgin/gtkutils.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/gtkutils.c	Wed Jun 14 23:40:17 2017 -0500
@@ -696,7 +696,7 @@
 		if (pixbuf)
 			g_object_unref(pixbuf);
 
-		if (default_proto_id != NULL && !strcmp(purple_protocol_get_id(protocol), default_proto_id))
+		if (default_proto_id != NULL && purple_strequal(purple_protocol_get_id(protocol), default_proto_id))
 			aop_menu->default_item = i;
 	}
 	g_list_free(list);
@@ -1061,15 +1061,15 @@
 
 				protoname = purple_protocol_class_list_icon(proto, account, NULL);
 
-				if (!strcmp(protoname, protocol))
+				if (purple_strequal(protoname, protocol))
 					break;
 
 				account = NULL;
 			}
 
 			/* Special case for AIM and ICQ */
-			if (account == NULL && (!strcmp(protocol, "aim") ||
-									!strcmp(protocol, "icq")))
+			if (account == NULL && (purple_strequal(protocol, "aim") ||
+									purple_strequal(protocol, "icq")))
 			{
 				for (l = list; l != NULL; l = l->next)
 				{
@@ -1100,7 +1100,7 @@
 
 					protoname = purple_protocol_class_list_icon(proto, account, NULL);
 
-					if (!strcmp(protoname, "aim") || !strcmp(protoname, "icq"))
+					if (purple_strequal(protoname, "aim") || purple_strequal(protoname, "icq"))
 						break;
 
 					account = NULL;
@@ -1550,7 +1550,7 @@
 	 * nothing else? Probably not.  I'll just give an error and
 	 * return. */
 	/* The original patch sent the icon used by the launcher.  That's probably wrong */
-	if (!g_strcmp0(type, "Link")) {
+	if (purple_strequal(type, "Link")) {
 		purple_notify_error(NULL, NULL, _("Cannot send launcher"),
 				_("You dragged a desktop launcher. Most "
 					"likely you wanted to send the target "
@@ -1904,7 +1904,7 @@
 
 	/* There's no sense listing things like: 'xxx "xxx"'
 	   when the name and buddy alias match. */
-	if (buddy_alias && strcmp(buddy_alias, buddyname)) {
+	if (buddy_alias && !purple_strequal(buddy_alias, buddyname)) {
 		char *completion_entry = g_strdup_printf("%s \"%s\"", buddyname, buddy_alias);
 		char *tmp2 = g_utf8_normalize(buddy_alias, -1, G_NORMALIZE_DEFAULT);
 
@@ -1926,9 +1926,9 @@
 
 	/* There's no sense listing things like: 'xxx "xxx"'
 	   when the name and contact alias match. */
-	if (contact_alias && strcmp(contact_alias, buddyname)) {
+	if (contact_alias && !purple_strequal(contact_alias, buddyname)) {
 		/* We don't want duplicates when the contact and buddy alias match. */
-		if (!buddy_alias || strcmp(contact_alias, buddy_alias)) {
+		if (!purple_strequal(contact_alias, buddy_alias)) {
 			char *completion_entry = g_strdup_printf("%s \"%s\"",
 							buddyname, contact_alias);
 			char *tmp2 = g_utf8_normalize(contact_alias, -1, G_NORMALIZE_DEFAULT);
@@ -2380,10 +2380,10 @@
 
 				purple_debug_info("buddyicon", "Converting buddy icon to %s\n", protocol_formats[i]);
 
-				if (g_str_equal(protocol_formats[i], "png")) {
+				if (purple_strequal(protocol_formats[i], "png")) {
 					key = "compression";
 					value = "9";
-				} else if (g_str_equal(protocol_formats[i], "jpeg")) {
+				} else if (purple_strequal(protocol_formats[i], "jpeg")) {
 					sprintf(tmp_buf, "%u", quality);
 					key = "quality";
 					value = tmp_buf;
@@ -2424,7 +2424,7 @@
 
 				g_free(contents);
 
-				if (!g_str_equal(protocol_formats[i], "jpeg")) {
+				if (!purple_strequal(protocol_formats[i], "jpeg")) {
 					/* File size was too big and we can't lower the quality,
 					   so skip to the next image type. */
 					break;
@@ -3501,9 +3501,9 @@
 
 	str = url + sizeof("open://") - 1;
 
-	if (strcmp(str, "accounts") == 0)
+	if (purple_strequal(str, "accounts"))
 		pidgin_accounts_window_show();
-	else if (strcmp(str, "prefs") == 0)
+	else if (purple_strequal(str, "prefs"))
 		pidgin_prefs_show();
 	else
 		return FALSE;
--- a/pidgin/pidginstock.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/pidginstock.c	Wed Jun 14 23:40:17 2017 -0500
@@ -255,7 +255,7 @@
 	if (base == NULL)
 		return NULL;
 
-	if (!strcmp(dir, "pidgin"))
+	if (purple_strequal(dir, "pidgin"))
 		filename = g_build_filename("pixmaps", "pidgin", base, NULL);
 	else
 		filename = g_build_filename("pixmaps", "pidgin", dir, base, NULL);
--- a/pidgin/plugins/cap/cap.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/cap/cap.c	Wed Jun 14 23:40:17 2017 -0500
@@ -616,7 +616,7 @@
 	/* It would seem that some protocols receive periodic updates of the buddies status.
 	 * Check to make sure the last status is not the same as current status to prevent
 	 * to many duplicated useless database entries. */
-	if(strcmp(statistics->last_status_id, purple_status_get_id(status)) == 0)
+	if(purple_strequal(statistics->last_status_id, purple_status_get_id(status)))
 		return;
 
 	status_id = purple_status_get_id(status);
--- a/pidgin/plugins/disco/xmppdisco.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/disco/xmppdisco.c	Wed Jun 14 23:40:17 2017 -0500
@@ -223,18 +223,18 @@
 	if (!category)
 		return XMPP_DISCO_SERVICE_TYPE_OTHER;
 
-	if (g_str_equal(category, "conference"))
+	if (purple_strequal(category, "conference"))
 		return XMPP_DISCO_SERVICE_TYPE_CHAT;
-	else if (g_str_equal(category, "directory"))
+	else if (purple_strequal(category, "directory"))
 		return XMPP_DISCO_SERVICE_TYPE_DIRECTORY;
-	else if (g_str_equal(category, "gateway"))
+	else if (purple_strequal(category, "gateway"))
 		return XMPP_DISCO_SERVICE_TYPE_GATEWAY;
-	else if (g_str_equal(category, "pubsub")) {
-		if (!type || g_str_equal(type, "collection"))
+	else if (purple_strequal(category, "pubsub")) {
+		if (!type || purple_strequal(type, "collection"))
 			return XMPP_DISCO_SERVICE_TYPE_PUBSUB_COLLECTION;
-		else if (g_str_equal(type, "leaf"))
+		else if (purple_strequal(type, "leaf"))
 			return XMPP_DISCO_SERVICE_TYPE_PUBSUB_LEAF;
-		else if (g_str_equal(type, "service"))
+		else if (purple_strequal(type, "service"))
 			return XMPP_DISCO_SERVICE_TYPE_OTHER;
 		else {
 			purple_debug_warning("xmppdisco", "Unknown pubsub type '%s'\n", type);
@@ -284,7 +284,7 @@
 	if (!list->in_progress)
 		goto out;
 
-	if (g_str_equal(type, "result") &&
+	if (purple_strequal(type, "result") &&
 			(query = purple_xmlnode_get_child(iq, "query"))) {
 		PurpleXmlNode *identity = purple_xmlnode_get_child(query, "identity");
 		XmppDiscoService *service;
@@ -331,11 +331,11 @@
 			if (!(var = purple_xmlnode_get_attrib(feature, "var")))
 				continue;
 
-			if (g_str_equal(var, NS_REGISTER))
+			if (purple_strequal(var, NS_REGISTER))
 				service->flags |= XMPP_DISCO_REGISTER;
-			else if (g_str_equal(var, NS_DISCO_ITEMS))
+			else if (purple_strequal(var, NS_DISCO_ITEMS))
 				service->flags |= XMPP_DISCO_BROWSE;
-			else if (g_str_equal(var, NS_MUC)) {
+			else if (purple_strequal(var, NS_MUC)) {
 				service->flags |= XMPP_DISCO_BROWSE;
 				service->type = XMPP_DISCO_SERVICE_TYPE_CHAT;
 			}
@@ -372,7 +372,7 @@
 	if (!list->in_progress)
 		goto out;
 
-	if (g_str_equal(type, "result") &&
+	if (purple_strequal(type, "result") &&
 			(query = purple_xmlnode_get_child(iq, "query"))) {
 		PurpleXmlNode *item;
 
@@ -439,7 +439,7 @@
 	g_free(cb_data);
 	--list->fetch_count;
 
-	if (g_str_equal(type, "result") &&
+	if (purple_strequal(type, "result") &&
 			(query = purple_xmlnode_get_child(iq, "query"))) {
 		PurpleXmlNode *item;
 
@@ -482,7 +482,7 @@
 
 	--list->fetch_count;
 
-	if (g_str_equal(type, "result") &&
+	if (purple_strequal(type, "result") &&
 			(query = purple_xmlnode_get_child(iq, "query"))) {
 		PurpleXmlNode *feature;
 
--- a/pidgin/plugins/gevolution/add_buddy_dialog.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/gevolution/add_buddy_dialog.c	Wed Jun 14 23:40:17 2017 -0500
@@ -176,7 +176,7 @@
 
 		account = purple_connection_get_account(gc);
 
-		if (!strcmp(purple_account_get_protocol_id(account), id))
+		if (purple_strequal(purple_account_get_protocol_id(account), id))
 			break;
 
 		account = NULL;
@@ -206,10 +206,10 @@
 						   COLUMN_DATA, contact,
 						   -1);
 
-		if (!strcmp(purple_account_get_protocol_id(account),
+		if (purple_strequal(purple_account_get_protocol_id(account),
 					purple_account_get_protocol_id(dialog->account)) &&
 			dialog->username != NULL &&
-			!strcmp(account_name, dialog->username))
+			purple_strequal(account_name, dialog->username))
 		{
 			GtkTreeSelection *selection;
 
@@ -509,8 +509,8 @@
 	dialog->treeview =
 		gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
 	gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE);
-	gtk_box_pack_start(GTK_BOX(vbox), 
-		pidgin_make_scrollable(dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), 
+	gtk_box_pack_start(GTK_BOX(vbox),
+		pidgin_make_scrollable(dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
 		TRUE, TRUE, 0);
 	gtk_widget_show(dialog->treeview);
 
--- a/pidgin/plugins/gevolution/assoc-buddy.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/gevolution/assoc-buddy.c	Wed Jun 14 23:40:17 2017 -0500
@@ -216,7 +216,7 @@
 
 			for (l = ims; l != NULL; l = l->next)
 			{
-				if (!strcmp(l->data,
+				if (purple_strequal(l->data,
 					purple_buddy_get_name(dialog->buddy)))
 				{
 					GtkTreeSelection *selection;
--- a/pidgin/plugins/gevolution/gevo-util.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/gevolution/gevo-util.c	Wed Jun 14 23:40:17 2017 -0500
@@ -99,15 +99,15 @@
 
 	protocol_id = purple_account_get_protocol_id(account);
 
-	if (!strcmp(protocol_id, "prpl-aim"))
+	if (purple_strequal(protocol_id, "prpl-aim"))
 		protocol_field = E_CONTACT_IM_AIM;
-	else if (!strcmp(protocol_id, "prpl-icq"))
+	else if (purple_strequal(protocol_id, "prpl-icq"))
 		protocol_field = E_CONTACT_IM_ICQ;
-	else if (!strcmp(protocol_id, "prpl-jabber"))
+	else if (purple_strequal(protocol_id, "prpl-jabber"))
 		protocol_field = E_CONTACT_IM_JABBER;
-	else if (!strcmp(protocol_id, "prpl-novell"))
+	else if (purple_strequal(protocol_id, "prpl-novell"))
 		protocol_field = E_CONTACT_IM_GROUPWISE;
-	else if (!strcmp(protocol_id, "prpl-gg"))
+	else if (purple_strequal(protocol_id, "prpl-gg"))
 		protocol_field = E_CONTACT_IM_GADUGADU;
 
 	return protocol_field;
--- a/pidgin/plugins/gevolution/gevolution.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/gevolution/gevolution.c	Wed Jun 14 23:40:17 2017 -0500
@@ -91,7 +91,7 @@
 		PurpleAccount *account = purple_connection_get_account(gc);
 		char *me;
 
-		if (strcmp(purple_account_get_protocol_id(account), protocol_id))
+		if (!purple_strequal(purple_account_get_protocol_id(account), protocol_id))
 			continue;
 
 		if (!purple_account_get_bool(account, "gevo-autoadd", FALSE))
@@ -101,7 +101,7 @@
 		for (l2 = ims; l2 != NULL; l2 = l2->next)
 		{
 			if (purple_blist_find_buddy(account, l2->data) != NULL ||
-				!strcmp(me, purple_normalize(account, l2->data)))
+				purple_strequal(me, purple_normalize(account, l2->data)))
 				continue;
 
 			gevo_add_buddy(account, PURPLE_BLIST_DEFAULT_GROUP_NAME,
--- a/pidgin/plugins/gevolution/new_person_dialog.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/gevolution/new_person_dialog.c	Wed Jun 14 23:40:17 2017 -0500
@@ -143,15 +143,15 @@
 		if (*email)
 			e_contact_set(contact, E_CONTACT_EMAIL_1, (gpointer)email);
 
-		if (!strcmp(im_service, "prpl-aim"))
+		if (purple_strequal(im_service, "prpl-aim"))
 			field = E_CONTACT_IM_AIM;
-		else if (!strcmp(im_service, "prpl-icq"))
+		else if (purple_strequal(im_service, "prpl-icq"))
 			field = E_CONTACT_IM_ICQ;
-		else if (!strcmp(im_service, "prpl-jabber"))
+		else if (purple_strequal(im_service, "prpl-jabber"))
 			field = E_CONTACT_IM_JABBER;
-		else if (!strcmp(im_service, "prpl-novell"))
+		else if (purple_strequal(im_service, "prpl-novell"))
 			field = E_CONTACT_IM_GROUPWISE;
-		else if (!strcmp(im_service, "prpl-gg"))
+		else if (purple_strequal(im_service, "prpl-gg"))
 			field = E_CONTACT_IM_GADUGADU;
 
 		if (field > 0)
--- a/pidgin/plugins/notify.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/notify.c	Wed Jun 14 23:40:17 2017 -0500
@@ -614,7 +614,7 @@
 
 	purple_prefs_set_bool(pref, on);
 
-	if (!strcmp(data, "method_string")) {
+	if (purple_strequal(data, "method_string")) {
 		GtkWidget *entry = g_object_get_data(G_OBJECT(widget), "title-entry");
 		gtk_widget_set_sensitive(entry, on);
 
@@ -645,7 +645,7 @@
 	if (data == NULL)
 		return FALSE;
 
-	if (!strcmp(data, "method_string")) {
+	if (purple_strequal(data, "method_string")) {
 		purple_prefs_set_string("/plugins/gtk/X11/notify/title_string",
 		                      gtk_entry_get_text(GTK_ENTRY(widget)));
 	}
--- a/pidgin/plugins/pidgininc.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/pidgininc.c	Wed Jun 14 23:40:17 2017 -0500
@@ -34,7 +34,7 @@
 
 	l = strlen(*message);
 
-	if (!strcmp(*who, purple_account_get_username(account)))
+	if (purple_strequal(*who, purple_account_get_username(account)))
 		return FALSE;
 
 	for (i = 0; i < l/2; i++) {
--- a/pidgin/plugins/raw.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/raw.c	Wed Jun 14 23:40:17 2017 -0500
@@ -72,7 +72,7 @@
 
 	purple_debug_misc("raw", "protocol_id = %s\n", protocol_id);
 
-	if (strcmp(protocol_id, "prpl-toc") == 0) {
+	if (purple_strequal(protocol_id, "prpl-toc")protocol_id) {
 		int *a = (int *)purple_connection_get_protocol_data(gc);
 		unsigned short seqno = htons(a[1]++ & 0xffff);
 		unsigned short len = htons(strlen(txt) + 1);
@@ -82,12 +82,12 @@
 		write(*a, txt, ntohs(len));
 		purple_debug(PURPLE_DEBUG_MISC, "raw", "TOC C: %s\n", txt);
 
-	} else if (strcmp(prpl_id, "prpl-irc") == 0) {
+	} else if (purple_strequal(protocol_id, "prpl-irc")) {
 		write(*(int *)gc->proto_data, txt, strlen(txt));
 		write(*(int *)gc->proto_data, "\r\n", 2);
 		purple_debug(PURPLE_DEBUG_MISC, "raw", "IRC C: %s\n", txt);
 
-	} else if (strcmp(protocol_id, "prpl-jabber") == 0) {
+	} else if (purple_strequal(protocol_id, "prpl-jabber")) {
 		jabber_send_raw((JabberStream *)purple_connection_get_protocol_data(gc), txt, -1);
 
 	} else {
--- a/pidgin/plugins/spellchk.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/spellchk.c	Wed Jun 14 23:40:17 2017 -0500
@@ -237,10 +237,10 @@
 			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, BAD_COLUMN, &val1);
 			bad = g_value_get_string(&val1);
 
-			if ((case_sensitive && !strcmp(bad, word)) ||
-			    (!case_sensitive && (!strcmp(bad, lowerword) ||
+			if ((case_sensitive && purple_strequal(bad, word)) ||
+			    (!case_sensitive && (purple_strequal(bad, lowerword) ||
 			                        (!is_word_lowercase(bad) &&
-			                         !strcmp((tmpbad = g_utf8_casefold(bad, -1)), foldedword)))))
+			                         purple_strequal((tmpbad = g_utf8_casefold(bad, -1)), foldedword)))))
 			{
 				GValue val2;
 				const char *good;
@@ -1869,7 +1869,7 @@
 	val.g_type = 0;
 	gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, GPOINTER_TO_INT(data), &val);
 
-	if (strcmp(arg2, g_value_get_string(&val))) {
+	if (!purple_strequal(arg2, g_value_get_string(&val))) {
 		gtk_list_store_set(model, &iter, GPOINTER_TO_INT(data), arg2, -1);
 		save_list();
 	}
@@ -1951,12 +1951,12 @@
 				 * Otherwise, they overlap. */
 				if (g_value_get_boolean(&case_sensitive_val))
 				{
-					match = !strcmp(g_value_get_string(&bad_val), word);
+					match = purple_strequal(g_value_get_string(&bad_val), word);
 				}
 				else
 				{
 					char *bad = g_utf8_casefold(g_value_get_string(&bad_val), -1);
-					match = !strcmp(bad, tmpword);
+					match = purple_strequal(bad, tmpword);
 					g_free(bad);
 				}
 				g_value_unset(&case_sensitive_val);
@@ -1964,7 +1964,7 @@
 			else
 			{
 				char *bad = g_utf8_casefold(g_value_get_string(&bad_val), -1);
-				match = !strcmp(bad, tmpword);
+				match = purple_strequal(bad, tmpword);
 				g_free(bad);
 			}
 
@@ -2193,8 +2193,8 @@
 
 	gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)),
 		 GTK_SELECTION_MULTIPLE);
-	gtk_box_pack_start(GTK_BOX(vbox), 
-		pidgin_make_scrollable(tree, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), 
+	gtk_box_pack_start(GTK_BOX(vbox),
+		pidgin_make_scrollable(tree, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
 		TRUE, TRUE, 0);
 	gtk_widget_show(tree);
 
--- a/pidgin/plugins/xmppconsole.c	Thu Jun 08 22:51:50 2017 -0500
+++ b/pidgin/plugins/xmppconsole.c	Wed Jun 14 23:40:17 2017 -0500
@@ -78,7 +78,7 @@
 
 	i = 0;
 	while (xmpp_prpls[i] != NULL) {
-		if (g_strcmp0(xmpp_prpls[i], prpl_name) == 0)
+		if (purple_strequal(xmpp_prpls[i], prpl_name))
 			return TRUE;
 		i++;
 	}
@@ -105,8 +105,8 @@
 	if (node->xmlns) {
 		if ((!node->parent ||
 		     !node->parent->xmlns ||
-		     strcmp(node->xmlns, node->parent->xmlns)) &&
-		    strcmp(node->xmlns, "jabber:client"))
+		     !purple_strequal(node->xmlns, node->parent->xmlns)) &&
+		    !purple_strequal(node->xmlns, "jabber:client"))
 		{
 			char *xmlns = g_markup_escape_text(node->xmlns, -1);
 			g_string_append_printf(text,
@@ -477,14 +477,14 @@
 
 	to = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(to_entry)), -1);
 	type = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(type_combo));
-	if (!strcmp(type, "default"))
+	if (purple_strequal(type, "default"))
 		type = "";
 	show = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(show_combo));
-	if (!strcmp(show, "default"))
+	if (purple_strequal(show, "default"))
 		show = "";
 	status = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(status_entry)), -1);
 	priority = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(priority_entry)), -1);
-	if (!strcmp(priority, "0"))
+	if (purple_strequal(priority, "0"))
 		*priority = '\0';
 
 	stanza = g_strdup_printf("&lt;presence %s%s%s id='console%x' %s%s%s&gt;"
@@ -789,7 +789,7 @@
 		pidgin_webview_append_html(PIDGIN_WEBVIEW(console->webview), tmp);
 		g_free(tmp);
 	}
-	gtk_box_pack_start(GTK_BOX(vbox), 
+	gtk_box_pack_start(GTK_BOX(vbox),
 		pidgin_make_scrollable(console->webview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_ETCHED_IN, -1, -1),
 		TRUE, TRUE, 0);
 

mercurial