diff --git a/libpurple/purpleconversationmanager.h b/libpurple/purpleconversationmanager.h
--- a/libpurple/purpleconversationmanager.h
+++ b/libpurple/purpleconversationmanager.h
@@ -44,6 +44,18 @@
                      PURPLE, CONVERSATION_MANAGER, GObject)
 
 /**
+ * PurpleConversationManagerForeachFunc:
+ * @conversation: The #PurpleConversation instance.
+ * @data: User supplied data.
+ *
+ * A function to be used as a callback with
+ * purple_conversation_manager_foreach().
+ *
+ * Since: 3.0.0
+ */
+typedef void (*PurpleConversationManagerForeachFunc)(PurpleConversation *conversation, gpointer data);
+
+/**
  * purple_conversation_manager_get_default:
  *
  * Gets the default instance of #PurpleConversationManager.  This instance
@@ -96,6 +108,18 @@
 gboolean purple_conversation_manager_is_registered(PurpleConversationManager *manager, PurpleConversation *conversation);
 
 /**
+ * purple_conversation_manager_foreach:
+ * @manager: The #PurpleConversationManager instance.
+ * @func: (scope call): The #PurpleConversationManagerForeachFunc to call.
+ * @data: User data to pass to @func.
+ *
+ * Calls @func for each #PurpleConversation that @manager knows about.
+ *
+ * Since: 3.0.0
+ */
+void purple_conversation_manager_foreach(PurpleConversationManager *manager, PurpleConversationManagerForeachFunc func, gpointer data);
+
+/**
  * purple_conversation_manager_get_all:
  * @manager: The #PurpleConversationManager instance.
  *
diff --git a/libpurple/purpleconversationmanager.c b/libpurple/purpleconversationmanager.c
--- a/libpurple/purpleconversationmanager.c
+++ b/libpurple/purpleconversationmanager.c
@@ -178,6 +178,23 @@
 	                                    NULL, NULL);
 }
 
+void
+purple_conversation_manager_foreach(PurpleConversationManager *manager,
+                                    PurpleConversationManagerForeachFunc func,
+                                    gpointer data)
+{
+	GHashTableIter iter;
+	gpointer key;
+
+	g_return_if_fail(PURPLE_IS_CONVERSATION_MANAGER(manager));
+	g_return_if_fail(func != NULL);
+
+	g_hash_table_iter_init(&iter, manager->conversations);
+	while(g_hash_table_iter_next(&iter, &key, NULL)) {
+		func(PURPLE_CONVERSATION(key), data);
+	}
+}
+
 GList *
 purple_conversation_manager_get_all(PurpleConversationManager *manager) {
 	g_return_val_if_fail(PURPLE_IS_CONVERSATION_MANAGER(manager), NULL);
diff --git a/libpurple/purpleprotocolmanager.h b/libpurple/purpleprotocolmanager.h
--- a/libpurple/purpleprotocolmanager.h
+++ b/libpurple/purpleprotocolmanager.h
@@ -88,6 +88,17 @@
 };
 
 /**
+ * PurpleProtocolManagerForeachFunc:
+ * @protocol: The #PurpleProtocol instance.
+ * @data: User supplied data.
+ *
+ * A function to be used as a callback with purple_protocol_manager_foreach().
+ *
+ * Since: 3.0.0
+ */
+typedef void (*PurpleProtocolManagerForeachFunc)(PurpleProtocol *protocol, gpointer data);
+
+/**
  * purple_protocol_manager_get_default:
  *
  * Gets the default #PurpleProtocolManager instance.
@@ -142,6 +153,18 @@
 PurpleProtocol *purple_protocol_manager_find(PurpleProtocolManager *manager, const gchar *id);
 
 /**
+ * purple_protocol_manager_foreach:
+ * @manager: The #PurpleProtocolManager instance.
+ * @func: (scope call): The #PurpleProtocolManagerForeachFunc to call.
+ * @data: User data to pass to @func.
+ *
+ * Calls @func for each #PurpleProtocol that @manager knows about.
+ *
+ * Since: 3.0.0
+ */
+void purple_protocol_manager_foreach(PurpleProtocolManager *manager, PurpleProtocolManagerForeachFunc func, gpointer data);
+
+/**
  * purple_protocol_manager_get_all:
  * @manager: The #PurpleProtocolManager instance.
  *
diff --git a/libpurple/purpleprotocolmanager.c b/libpurple/purpleprotocolmanager.c
--- a/libpurple/purpleprotocolmanager.c
+++ b/libpurple/purpleprotocolmanager.c
@@ -218,6 +218,26 @@
 	return PURPLE_PROTOCOL(value);
 }
 
+void
+purple_protocol_manager_foreach(PurpleProtocolManager *manager,
+                                PurpleProtocolManagerForeachFunc func,
+                                gpointer data)
+{
+	GHashTableIter iter;
+	PurpleProtocolManagerPrivate *priv = NULL;
+	gpointer value;
+
+	g_return_if_fail(PURPLE_IS_PROTOCOL_MANAGER(manager));
+	g_return_if_fail(func != NULL);
+
+	priv = purple_protocol_manager_get_instance_private(manager);
+
+	g_hash_table_iter_init(&iter, priv->protocols);
+	while(g_hash_table_iter_next(&iter, NULL, &value)) {
+		func(PURPLE_PROTOCOL(value), data);
+	}
+}
+
 GList *
 purple_protocol_manager_get_all(PurpleProtocolManager *manager) {
 	PurpleProtocolManagerPrivate *priv = NULL;
