Blob Blame History Raw
From 420e714464f6ab6f943de7ef99b92b5d3f4814e2 Mon Sep 17 00:00:00 2001
From: Wim Taymans <wtaymans@redhat.com>
Date: Tue, 7 Apr 2015 16:53:09 +0200
Subject: [PATCH 10/18] Don't access pa_core structures directly

First step to allowing access control. Make sure we only use the
methods to get core datastructures so that we can do access control
later.
---
 src/pulsecore/cli-command.c     |  72 ++++++++++++--------
 src/pulsecore/cli-text.c        |  85 ++++++++++++++++-------
 src/pulsecore/core.c            | 102 ++++++++++++++++++++++++++++
 src/pulsecore/core.h            |  30 ++++++++
 src/pulsecore/namereg.c         |  35 +++++++---
 src/pulsecore/protocol-esound.c |  29 ++++----
 src/pulsecore/protocol-http.c   |  12 +++-
 src/pulsecore/protocol-native.c | 147 ++++++++++++++++++++++------------------
 src/pulsecore/protocol-simple.c |   5 +-
 src/pulsecore/sink.c            |   6 +-
 src/pulsecore/source.c          |   6 +-
 11 files changed, 380 insertions(+), 149 deletions(-)

diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index 05c2b8f..138881c 100644
--- a/src/pulsecore/cli-command.c
+++ b/src/pulsecore/cli-command.c
@@ -47,7 +47,6 @@
 #include <pulsecore/strbuf.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/cli-text.h>
-#include <pulsecore/core-struct.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/sound-file.h>
 #include <pulsecore/play-memchunk.h>
@@ -362,7 +361,7 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
     pa_assert(buf);
     pa_assert(fail);
 
-    mstat = pa_mempool_get_stat(c->mempool);
+    mstat = pa_mempool_get_stat(pa_core_get_mempool(c));
 
     pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n",
                      (unsigned) pa_atomic_load(&mstat->n_allocated),
@@ -384,10 +383,10 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
                      pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_scache_total_size(c)));
 
     pa_strbuf_printf(buf, "Default sample spec: %s\n",
-                     pa_sample_spec_snprint(ss, sizeof(ss), &c->default_sample_spec));
+                     pa_sample_spec_snprint(ss, sizeof(ss), pa_core_get_sample_spec(c)));
 
     pa_strbuf_printf(buf, "Default channel map: %s\n",
-                     pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
+                     pa_channel_map_snprint(cm, sizeof(cm), pa_core_get_channel_map(c)));
 
     def_sink = pa_namereg_get_default_sink(c);
     def_source = pa_namereg_get_default_source(c);
@@ -437,7 +436,7 @@ static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
         return -1;
     }
 
-    if (!pa_module_load(c, name,  pa_tokenizer_get(t, 2))) {
+    if (!pa_module_load(c, name, pa_tokenizer_get(t, 2))) {
         pa_strbuf_puts(buf, "Module load failed.\n");
         return -1;
     }
@@ -462,7 +461,7 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bo
     }
 
     if (pa_atou(i, &idx) >= 0) {
-        if (!(m = pa_idxset_get_by_index(c->modules, idx))) {
+        if (!(m = pa_core_get_module(c, idx))) {
             pa_strbuf_puts(buf, "Invalid module index.\n");
             return -1;
         }
@@ -470,12 +469,15 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bo
         pa_module_unload_request(m, false);
 
     } else {
-        PA_IDXSET_FOREACH(m, c->modules, idx)
+        pa_idxset *modules = pa_core_get_modules(c);
+        PA_IDXSET_FOREACH(m, modules, idx)
             if (pa_streq(i, m->name)) {
                 unloaded = true;
                 pa_module_unload_request(m, false);
             }
 
+        pa_idxset_free(modules, NULL);
+
         if (unloaded == false) {
             pa_strbuf_printf(buf, "Module %s not loaded.\n", i);
             return -1;
@@ -604,7 +606,7 @@ static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strb
         return -1;
     }
 
-    if (!(si = pa_idxset_get_by_index(c->sink_inputs, idx))) {
+    if (!(si = pa_core_get_sink_input(c, idx))) {
         pa_strbuf_puts(buf, "No sink input found with this index.\n");
         return -1;
     }
@@ -697,7 +699,7 @@ static int pa_cli_command_source_output_volume(pa_core *c, pa_tokenizer *t, pa_s
         return -1;
     }
 
-    if (!(so = pa_idxset_get_by_index(c->source_outputs, idx))) {
+    if (!(so = pa_core_get_source_output(c, idx))) {
         pa_strbuf_puts(buf, "No source output found with this index.\n");
         return -1;
     }
@@ -880,7 +882,7 @@ static int pa_cli_command_update_sink_input_proplist(pa_core *c, pa_tokenizer *t
         return -1;
     }
 
-    if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
+    if (!(si = pa_core_get_sink_input(c, (uint32_t) idx))) {
         pa_strbuf_puts(buf, "No sink input found with this index.\n");
         return -1;
     }
@@ -923,7 +925,7 @@ static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer
         return -1;
     }
 
-    if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
+    if (!(so = pa_core_get_source_output(c, (uint32_t) idx))) {
         pa_strbuf_puts(buf, "No source output found with this index.\n");
         return -1;
     }
@@ -971,7 +973,7 @@ static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf
         return -1;
     }
 
-    if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
+    if (!(si = pa_core_get_sink_input(c, (uint32_t) idx))) {
         pa_strbuf_puts(buf, "No sink input found with this index.\n");
         return -1;
     }
@@ -1011,7 +1013,7 @@ static int pa_cli_command_source_output_mute(pa_core *c, pa_tokenizer *t, pa_str
         return -1;
     }
 
-    if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
+    if (!(so = pa_core_get_source_output(c, (uint32_t) idx))) {
         pa_strbuf_puts(buf, "No source output found with this index.\n");
         return -1;
     }
@@ -1065,7 +1067,7 @@ static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf
 
 static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool *fail) {
     const char *n;
-    pa_client *client;
+    pa_client *cl;
     uint32_t idx;
 
     pa_core_assert_ref(c);
@@ -1083,12 +1085,12 @@ static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *bu
         return -1;
     }
 
-    if (!(client = pa_idxset_get_by_index(c->clients, idx))) {
+    if (!(cl = pa_core_get_client(c, idx))) {
         pa_strbuf_puts(buf, "No client found by this index.\n");
         return -1;
     }
 
-    pa_client_kill(client);
+    pa_client_kill(cl);
     return 0;
 }
 
@@ -1112,7 +1114,7 @@ static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf
         return -1;
     }
 
-    if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx))) {
+    if (!(sink_input = pa_core_get_sink_input(c, idx))) {
         pa_strbuf_puts(buf, "No sink input found by this index.\n");
         return -1;
     }
@@ -1141,7 +1143,7 @@ static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_str
         return -1;
     }
 
-    if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx))) {
+    if (!(source_output = pa_core_get_source_output(c, idx))) {
         pa_strbuf_puts(buf, "No source output found by this index.\n");
         return -1;
     }
@@ -1300,7 +1302,7 @@ static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bo
     pa_assert(buf);
     pa_assert(fail);
 
-    pa_mempool_vacuum(c->mempool);
+    pa_mempool_vacuum(pa_core_get_mempool(c));
 
     return 0;
 }
@@ -1331,7 +1333,7 @@ static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf
         return -1;
     }
 
-    if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
+    if (!(si = pa_core_get_sink_input(c, (uint32_t) idx))) {
         pa_strbuf_puts(buf, "No sink input found with this index.\n");
         return -1;
     }
@@ -1374,7 +1376,7 @@ static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_str
         return -1;
     }
 
-    if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
+    if (!(so = pa_core_get_source_output(c, (uint32_t) idx))) {
         pa_strbuf_puts(buf, "No source output found with this index.\n");
         return -1;
     }
@@ -1789,6 +1791,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
 #ifdef HAVE_CTIME_R
     char txt[256];
 #endif
+    pa_idxset *i;
 
     pa_core_assert_ref(c);
     pa_assert(t);
@@ -1802,8 +1805,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
 #else
     pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now));
 #endif
-
-    PA_IDXSET_FOREACH(m, c->modules, idx) {
+    i = pa_core_get_modules(c);
+    PA_IDXSET_FOREACH(m, i, idx) {
 
         pa_strbuf_printf(buf, "load-module %s", m->name);
 
@@ -1812,9 +1815,11 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
 
         pa_strbuf_puts(buf, "\n");
     }
+    pa_idxset_free(i, NULL);
 
     nl = false;
-    PA_IDXSET_FOREACH(sink, c->sinks, idx) {
+    i = pa_core_get_sinks(c);
+    PA_IDXSET_FOREACH(sink, i, idx) {
 
         if (!nl) {
             pa_strbuf_puts(buf, "\n");
@@ -1825,9 +1830,11 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
         pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, false)));
         pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED));
     }
+    pa_idxset_free(i, NULL);
 
     nl = false;
-    PA_IDXSET_FOREACH(source, c->sources, idx) {
+    i = pa_core_get_sources(c);
+    PA_IDXSET_FOREACH(source, i, idx) {
 
         if (!nl) {
             pa_strbuf_puts(buf, "\n");
@@ -1838,9 +1845,11 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
         pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, false)));
         pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED));
     }
+    pa_idxset_free(i, NULL);
 
     nl = false;
-    PA_IDXSET_FOREACH(card, c->cards, idx) {
+    i = pa_core_get_cards(c);
+    PA_IDXSET_FOREACH(card, i, idx) {
 
         if (!nl) {
             pa_strbuf_puts(buf, "\n");
@@ -1849,6 +1858,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
 
         pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
     }
+    pa_idxset_free(i, NULL);
 
     nl = false;
     if ((sink = pa_namereg_get_default_sink(c))) {
@@ -1880,13 +1890,16 @@ static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *b
     uint32_t s_idx, i_idx;
     char v_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
     pa_channel_map *map;
+    pa_idxset *sinks, *sources;
 
     pa_core_assert_ref(c);
     pa_assert(t);
     pa_assert(buf);
     pa_assert(fail);
 
-    PA_IDXSET_FOREACH(s, c->sinks, s_idx) {
+    sinks = pa_core_get_sinks(c);
+
+    PA_IDXSET_FOREACH(s, sinks, s_idx) {
         map = &s->channel_map;
         pa_strbuf_printf(buf, "Sink %d: ", s_idx);
         pa_strbuf_printf(buf,
@@ -1937,8 +1950,10 @@ static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *b
             pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(i->save_volume));
         }
     }
+    pa_idxset_free(sinks, NULL);
 
-    PA_IDXSET_FOREACH(so, c->sources, s_idx) {
+    sources = pa_core_get_sources(c);
+    PA_IDXSET_FOREACH(so, sources, s_idx) {
         map = &so->channel_map;
         pa_strbuf_printf(buf, "Source %d: ", s_idx);
         pa_strbuf_printf(buf,
@@ -1989,6 +2004,7 @@ static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *b
             pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(o->save_volume));
         }
     }
+    pa_idxset_free(sources, NULL);
 
     return 0;
 }
diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c
index 9e32524..239ab5d 100644
--- a/src/pulsecore/cli-text.c
+++ b/src/pulsecore/cli-text.c
@@ -32,7 +32,6 @@
 #include <pulsecore/sink-input.h>
 #include <pulsecore/source-output.h>
 #include <pulsecore/strbuf.h>
-#include <pulsecore/core-struct.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
@@ -44,13 +43,17 @@ char *pa_module_list_to_string(pa_core *c) {
     pa_strbuf *s;
     pa_module *m;
     uint32_t idx = PA_IDXSET_INVALID;
+    pa_idxset *modules;
+
     pa_assert(c);
 
     s = pa_strbuf_new();
 
-    pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(c->modules));
+    modules = pa_core_get_modules(c);
+
+    pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(modules));
 
-    PA_IDXSET_FOREACH(m, c->modules, idx) {
+    PA_IDXSET_FOREACH(m, modules, idx) {
         char *t;
 
         pa_strbuf_printf(s, "    index: %u\n"
@@ -68,36 +71,42 @@ char *pa_module_list_to_string(pa_core *c) {
         pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
         pa_xfree(t);
     }
+    pa_idxset_free(modules, NULL);
 
     return pa_strbuf_to_string_free(s);
 }
 
 char *pa_client_list_to_string(pa_core *c) {
     pa_strbuf *s;
-    pa_client *client;
+    pa_client *cl;
     uint32_t idx = PA_IDXSET_INVALID;
+    pa_idxset *clients;
+
     pa_assert(c);
 
     s = pa_strbuf_new();
 
-    pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(c->clients));
+    clients = pa_core_get_clients(c);
+
+    pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(clients));
 
-    PA_IDXSET_FOREACH(client, c->clients, idx) {
+    PA_IDXSET_FOREACH(cl, clients, idx) {
         char *t;
         pa_strbuf_printf(
                 s,
                 "    index: %u\n"
                 "\tdriver: <%s>\n",
-                client->index,
-                client->driver);
+                cl->index,
+                cl->driver);
 
-        if (client->module)
-            pa_strbuf_printf(s, "\towner module: %u\n", client->module->index);
+        if (cl->module)
+            pa_strbuf_printf(s, "\towner module: %u\n", cl->module->index);
 
-        t = pa_proplist_to_string_sep(client->proplist, "\n\t\t");
+        t = pa_proplist_to_string_sep(cl->proplist, "\n\t\t");
         pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
         pa_xfree(t);
     }
+    pa_idxset_free(clients, NULL);
 
     return pa_strbuf_to_string_free(s);
 }
@@ -139,13 +148,17 @@ char *pa_card_list_to_string(pa_core *c) {
     pa_strbuf *s;
     pa_card *card;
     uint32_t idx = PA_IDXSET_INVALID;
+    pa_idxset *cards;
+
     pa_assert(c);
 
     s = pa_strbuf_new();
 
-    pa_strbuf_printf(s, "%u card(s) available.\n", pa_idxset_size(c->cards));
+    cards = pa_core_get_cards(c);
+
+    pa_strbuf_printf(s, "%u card(s) available.\n", pa_idxset_size(cards));
 
-    PA_IDXSET_FOREACH(card, c->cards, idx) {
+    PA_IDXSET_FOREACH(card, cards, idx) {
         char *t;
         pa_sink *sink;
         pa_source *source;
@@ -193,6 +206,7 @@ char *pa_card_list_to_string(pa_core *c) {
 
         append_port_list(s, card->ports);
     }
+    pa_idxset_free(cards, NULL);
 
     return pa_strbuf_to_string_free(s);
 }
@@ -235,15 +249,19 @@ char *pa_sink_list_to_string(pa_core *c) {
     pa_strbuf *s;
     pa_sink *sink, *default_sink;
     uint32_t idx = PA_IDXSET_INVALID;
+    pa_idxset *sinks;
+
     pa_assert(c);
 
     s = pa_strbuf_new();
 
-    pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks));
+    sinks = pa_core_get_sinks(c);
+
+    pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(sinks));
 
     default_sink = pa_namereg_get_default_sink(c);
 
-    PA_IDXSET_FOREACH(sink, c->sinks, idx) {
+    PA_IDXSET_FOREACH(sink, sinks, idx) {
         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX],
             cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX],
             v[PA_VOLUME_SNPRINT_VERBOSE_MAX],
@@ -345,6 +363,7 @@ char *pa_sink_list_to_string(pa_core *c) {
                     "\tactive port: <%s>\n",
                     sink->active_port->name);
     }
+    pa_idxset_free(sinks, NULL);
 
     return pa_strbuf_to_string_free(s);
 }
@@ -353,15 +372,19 @@ char *pa_source_list_to_string(pa_core *c) {
     pa_strbuf *s;
     pa_source *source, *default_source;
     uint32_t idx = PA_IDXSET_INVALID;
+    pa_idxset *sources;
+
     pa_assert(c);
 
     s = pa_strbuf_new();
 
-    pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources));
+    sources = pa_core_get_sources(c);
+
+    pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(sources));
 
     default_source = pa_namereg_get_default_source(c);
 
-    PA_IDXSET_FOREACH(source, c->sources, idx) {
+    PA_IDXSET_FOREACH(source, sources, idx) {
         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX],
             cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX],
             v[PA_VOLUME_SNPRINT_VERBOSE_MAX],
@@ -460,6 +483,7 @@ char *pa_source_list_to_string(pa_core *c) {
                     "\tactive port: <%s>\n",
                     source->active_port->name);
     }
+    pa_idxset_free(sources, NULL);
 
     return pa_strbuf_to_string_free(s);
 }
@@ -474,13 +498,16 @@ char *pa_source_output_list_to_string(pa_core *c) {
         [PA_SOURCE_OUTPUT_CORKED] = "CORKED",
         [PA_SOURCE_OUTPUT_UNLINKED] = "UNLINKED"
     };
+    pa_idxset *source_outputs;
     pa_assert(c);
 
     s = pa_strbuf_new();
 
-    pa_strbuf_printf(s, "%u source output(s) available.\n", pa_idxset_size(c->source_outputs));
+    source_outputs = pa_core_get_source_outputs(c);
+
+    pa_strbuf_printf(s, "%u source output(s) available.\n", pa_idxset_size(source_outputs));
 
-    PA_IDXSET_FOREACH(o, c->source_outputs, idx) {
+    PA_IDXSET_FOREACH(o, source_outputs, idx) {
         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], *t, clt[28];
         pa_usec_t cl;
         const char *cmn;
@@ -557,6 +584,7 @@ char *pa_source_output_list_to_string(pa_core *c) {
         pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
         pa_xfree(t);
     }
+    pa_idxset_free(source_outputs, NULL);
 
     return pa_strbuf_to_string_free(s);
 }
@@ -572,13 +600,16 @@ char *pa_sink_input_list_to_string(pa_core *c) {
         [PA_SINK_INPUT_CORKED] = "CORKED",
         [PA_SINK_INPUT_UNLINKED] = "UNLINKED"
     };
+    pa_idxset *sink_inputs;
 
     pa_assert(c);
     s = pa_strbuf_new();
 
-    pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(c->sink_inputs));
+    sink_inputs = pa_core_get_sink_inputs(c);
 
-    PA_IDXSET_FOREACH(i, c->sink_inputs, idx) {
+    pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(sink_inputs));
+
+    PA_IDXSET_FOREACH(i, sink_inputs, idx) {
         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], *t, clt[28];
         pa_usec_t cl;
         const char *cmn;
@@ -653,23 +684,28 @@ char *pa_sink_input_list_to_string(pa_core *c) {
         pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
         pa_xfree(t);
     }
+    pa_idxset_free(sink_inputs, NULL);
 
     return pa_strbuf_to_string_free(s);
 }
 
 char *pa_scache_list_to_string(pa_core *c) {
     pa_strbuf *s;
+    pa_idxset *scache;
+
     pa_assert(c);
 
     s = pa_strbuf_new();
 
-    pa_strbuf_printf(s, "%u cache entrie(s) available.\n", c->scache ? pa_idxset_size(c->scache) : 0);
+    scache = pa_core_get_scache(c);
+
+    pa_strbuf_printf(s, "%u cache entrie(s) available.\n", scache ? pa_idxset_size(scache) : 0);
 
-    if (c->scache) {
+    if (scache) {
         pa_scache_entry *e;
         uint32_t idx = PA_IDXSET_INVALID;
 
-        PA_IDXSET_FOREACH(e, c->scache, idx) {
+        PA_IDXSET_FOREACH(e, scache, idx) {
             double l = 0;
             char ss[PA_SAMPLE_SPEC_SNPRINT_MAX] = "n/a", cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX] = "n/a", *t;
             const char *cmn;
@@ -711,6 +747,7 @@ char *pa_scache_list_to_string(pa_core *c) {
             pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
             pa_xfree(t);
         }
+        pa_idxset_free(scache, NULL);
     }
 
     return pa_strbuf_to_string_free(s);
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index b8dbde9..b068f5d 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -262,6 +262,11 @@ int pa_core_exit(pa_core *c, bool force, int retval) {
     return 0;
 }
 
+pa_hook_result_t pa_core_hook_fire(pa_core *c, pa_core_hook_t hook, void *data) {
+    pa_assert(c);
+    return pa_hook_fire(&c->hooks[hook], data);
+}
+
 void pa_core_maybe_vacuum(pa_core *c) {
     pa_assert(c);
 
@@ -305,3 +310,100 @@ void pa_core_rttime_restart(pa_core *c, pa_time_event *e, pa_usec_t usec) {
 
     c->mainloop->time_restart(e, pa_timeval_rtstore(&tv, usec, true));
 }
+
+pa_mainloop_api* pa_core_get_mainloop(pa_core *c) {
+    pa_assert(c);
+    pa_assert(c->mainloop);
+
+    return c->mainloop;
+}
+
+/* FIXME: Should we expose this at all? */
+pa_mempool* pa_core_get_mempool(pa_core *c) {
+    pa_assert(c);
+    pa_assert(c->mempool);
+
+    return c->mempool;
+}
+
+pa_mempool* pa_core_new_mempool(pa_core *c, pa_mem_type_t shm_type, bool per_client) {
+    return pa_mempool_new(shm_type, c->shm_size, per_client);
+}
+
+/* FIXME: Should these be taking a ref during the copy? */
+
+pa_idxset* pa_core_get_modules(pa_core *c) {
+    return pa_idxset_copy(c->modules, NULL);
+}
+
+pa_idxset* pa_core_get_clients(pa_core *c) {
+    return pa_idxset_copy(c->clients, NULL);
+}
+
+pa_idxset* pa_core_get_cards(pa_core *c) {
+    return pa_idxset_copy(c->cards, NULL);
+}
+
+pa_idxset* pa_core_get_sinks(pa_core *c) {
+    return pa_idxset_copy(c->sinks, NULL);
+}
+
+pa_idxset* pa_core_get_sources(pa_core *c) {
+    return pa_idxset_copy(c->sources, NULL);
+}
+
+pa_idxset* pa_core_get_sink_inputs(pa_core *c) {
+    return pa_idxset_copy(c->sink_inputs, NULL);
+}
+
+pa_idxset* pa_core_get_source_outputs(pa_core *c) {
+    return pa_idxset_copy(c->source_outputs, NULL);
+}
+
+pa_idxset* pa_core_get_scache(pa_core *c) {
+    return pa_idxset_copy(c->scache, NULL);
+}
+
+pa_module* pa_core_get_module(pa_core *c, uint32_t idx) {
+    return pa_idxset_get_by_index(c->modules, idx);
+}
+
+pa_client* pa_core_get_client(pa_core *c, uint32_t idx) {
+    return pa_idxset_get_by_index(c->clients, idx);
+}
+
+pa_card* pa_core_get_card(pa_core *c, uint32_t idx) {
+    return pa_idxset_get_by_index(c->cards, idx);
+}
+
+pa_sink* pa_core_get_sink(pa_core *c, uint32_t idx) {
+    return pa_idxset_get_by_index(c->sinks, idx);
+}
+
+pa_source* pa_core_get_source(pa_core *c, uint32_t idx) {
+    return pa_idxset_get_by_index(c->sources, idx);
+}
+
+pa_sink_input* pa_core_get_sink_input(pa_core *c, uint32_t idx) {
+    return pa_idxset_get_by_index(c->sink_inputs, idx);
+}
+
+pa_source_output* pa_core_get_source_output(pa_core *c, uint32_t idx) {
+    return pa_idxset_get_by_index(c->source_outputs, idx);
+}
+
+pa_scache_entry* pa_core_get_scache_entry(pa_core *c, uint32_t idx) {
+    return pa_idxset_get_by_index(c->scache, idx);
+}
+
+const pa_sample_spec* pa_core_get_sample_spec(pa_core *c) {
+    return &c->default_sample_spec;
+}
+
+const pa_channel_map* pa_core_get_channel_map(pa_core *c) {
+    return &c->default_channel_map;
+}
+
+uint32_t pa_core_get_cookie(pa_core *c) {
+    return c->cookie;
+}
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 955db89..87b055d 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -158,8 +158,38 @@ int pa_core_exit(pa_core *c, bool force, int retval);
 
 void pa_core_maybe_vacuum(pa_core *c);
 
+pa_hook_result_t pa_core_hook_fire(pa_core *c, pa_core_hook_t hook, void *data);
+
 /* wrapper for c->mainloop->time_*() RT time events */
 pa_time_event* pa_core_rttime_new(pa_core *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata);
 void pa_core_rttime_restart(pa_core *c, pa_time_event *e, pa_usec_t usec);
 
+pa_mainloop_api* pa_core_get_mainloop(pa_core *c);
+pa_mempool* pa_core_get_mempool(pa_core *c);
+pa_mempool* pa_core_new_mempool(pa_core *c, pa_mem_type_t shm_type, bool per_client);
+
+pa_idxset* pa_core_get_modules(pa_core *c);
+pa_idxset* pa_core_get_clients(pa_core *c);
+pa_idxset* pa_core_get_cards(pa_core *c);
+pa_idxset* pa_core_get_sinks(pa_core *c);
+pa_idxset* pa_core_get_sources(pa_core *c);
+pa_idxset* pa_core_get_sink_inputs(pa_core *c);
+pa_idxset* pa_core_get_source_outputs(pa_core *c);
+pa_idxset* pa_core_get_scache(pa_core *c);
+
+pa_module* pa_core_get_module(pa_core *c, uint32_t idx);
+pa_client* pa_core_get_client(pa_core *c, uint32_t idx);
+pa_card* pa_core_get_card(pa_core *c, uint32_t idx);
+pa_sink* pa_core_get_sink(pa_core *c, uint32_t idx);
+pa_source* pa_core_get_source(pa_core *c, uint32_t idx);
+pa_sink_input* pa_core_get_sink_input(pa_core *c, uint32_t idx);
+pa_source_output* pa_core_get_source_output(pa_core *c, uint32_t idx);
+typedef struct pa_scache_entry pa_scache_entry;
+pa_scache_entry* pa_core_get_scache_entry(pa_core *c, uint32_t idx);
+
+const pa_sample_spec* pa_core_get_sample_spec(pa_core *c);
+const pa_channel_map* pa_core_get_channel_map(pa_core *c);
+
+uint32_t pa_core_get_cookie(pa_core *c);
+
 #endif
diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c
index dfdcc43..699fa1b 100644
--- a/src/pulsecore/namereg.c
+++ b/src/pulsecore/namereg.c
@@ -31,6 +31,7 @@
 #include <pulsecore/source.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/core-struct.h>
+#include <pulsecore/core-scache.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
@@ -239,13 +240,13 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) {
         return NULL;
 
     if (type == PA_NAMEREG_SINK)
-        return pa_idxset_get_by_index(c->sinks, idx);
+        return pa_core_get_sink(c, idx);
     else if (type == PA_NAMEREG_SOURCE)
-        return pa_idxset_get_by_index(c->sources, idx);
-    else if (type == PA_NAMEREG_SAMPLE && c->scache)
-        return pa_idxset_get_by_index(c->scache, idx);
+        return pa_core_get_source(c, idx);
+    else if (type == PA_NAMEREG_SAMPLE)
+        return pa_core_get_scache_entry(c, idx);
     else if (type == PA_NAMEREG_CARD)
-        return pa_idxset_get_by_index(c->cards, idx);
+        return pa_core_get_card(c, idx);
 
     return NULL;
 }
@@ -258,7 +259,7 @@ pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) {
 
     if (c->default_sink != s) {
         c->default_sink = s;
-        pa_hook_fire(&c->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], c->default_sink);
+        pa_core_hook_fire(c, PA_CORE_HOOK_DEFAULT_SINK_CHANGED, c->default_sink);
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
     }
 
@@ -273,7 +274,7 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
 
     if (c->default_source != s) {
         c->default_source = s;
-        pa_hook_fire(&c->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], c->default_source);
+        pa_core_hook_fire(c, PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED, c->default_source);
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
     }
 
@@ -283,41 +284,50 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
 pa_sink *pa_namereg_get_default_sink(pa_core *c) {
     pa_sink *s, *best = NULL;
     uint32_t idx;
+    pa_idxset *sinks;
 
     pa_assert(c);
 
     if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)))
         return c->default_sink;
 
-    PA_IDXSET_FOREACH(s, c->sinks, idx)
+    sinks = pa_core_get_sinks(c);
+
+    PA_IDXSET_FOREACH(s, sinks, idx)
         if (PA_SINK_IS_LINKED(pa_sink_get_state(s)))
             if (!best || s->priority > best->priority)
                 best = s;
 
+    pa_idxset_free(sinks, NULL);
+
     return best;
 }
 
 pa_source *pa_namereg_get_default_source(pa_core *c) {
     pa_source *s, *best = NULL;
     uint32_t idx;
+    pa_idxset *sources;
 
     pa_assert(c);
 
     if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source)))
         return c->default_source;
 
+    sources = pa_core_get_sources(c);
+
     /* First, try to find one that isn't a monitor */
-    PA_IDXSET_FOREACH(s, c->sources, idx)
+    PA_IDXSET_FOREACH(s, sources, idx)
         if (!s->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
             if (!best ||
                 s->priority > best->priority)
                 best = s;
 
+
     if (best)
-        return best;
+        goto done;
 
     /* Then, fallback to a monitor */
-    PA_IDXSET_FOREACH(s, c->sources, idx)
+    PA_IDXSET_FOREACH(s, sources, idx)
         if (PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
             if (!best ||
                 s->priority > best->priority ||
@@ -327,5 +337,8 @@ pa_source *pa_namereg_get_default_source(pa_core *c) {
                  s->monitor_of->priority > best->monitor_of->priority))
                 best = s;
 
+done:
+    pa_idxset_free(sources, NULL);
+
     return best;
 }
diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c
index ead1d81..0d76525 100644
--- a/src/pulsecore/protocol-esound.c
+++ b/src/pulsecore/protocol-esound.c
@@ -41,7 +41,6 @@
 #include <pulsecore/sink.h>
 #include <pulsecore/source-output.h>
 #include <pulsecore/source.h>
-#include <pulsecore/core-struct.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/sample-util.h>
 #include <pulsecore/namereg.h>
@@ -240,12 +239,12 @@ static void connection_unlink(connection *c) {
     }
 
     if (c->defer_event) {
-        c->protocol->core->mainloop->defer_free(c->defer_event);
+        pa_core_get_mainloop (c->protocol->core)->defer_free(c->defer_event);
         c->defer_event = NULL;
     }
 
     if (c->auth_timeout_event) {
-        c->protocol->core->mainloop->time_free(c->auth_timeout_event);
+        pa_core_get_mainloop (c->protocol->core)->time_free(c->auth_timeout_event);
         c->auth_timeout_event = NULL;
     }
 
@@ -293,7 +292,7 @@ static void connection_write(connection *c, const void *data, size_t length) {
     size_t i;
     pa_assert(c);
 
-    c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
+    pa_core_get_mainloop (c->protocol->core)->defer_enable(c->defer_event, 1);
 
     connection_write_prepare(c, length);
 
@@ -355,7 +354,7 @@ static int esd_proto_connect(connection *c, esd_proto_t request, const void *dat
     }
 
     if (c->auth_timeout_event) {
-        c->protocol->core->mainloop->time_free(c->auth_timeout_event);
+        pa_core_get_mainloop (c->protocol->core)->time_free(c->auth_timeout_event);
         c->auth_timeout_event = NULL;
     }
 
@@ -614,6 +613,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
     uint32_t idx = PA_IDXSET_INVALID;
     unsigned nsamples;
     char terminator[sizeof(int32_t)*6+ESD_NAME_MAX];
+    pa_idxset *scache;
 
     connection_assert_ref(c);
     pa_assert(data);
@@ -624,7 +624,8 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
 
     k = sizeof(int32_t)*5+ESD_NAME_MAX;
     s = sizeof(int32_t)*6+ESD_NAME_MAX;
-    nsamples = pa_idxset_size(c->protocol->core->scache);
+    scache = pa_core_get_scache(c->protocol->core);
+    nsamples = pa_idxset_size(scache);
     t = s*(nsamples+1) + k*(c->protocol->n_player+1);
 
     connection_write_prepare(c, t);
@@ -690,7 +691,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
 
         idx = PA_IDXSET_INVALID;
 
-        PA_IDXSET_FOREACH(ce, c->protocol->core->scache, idx) {
+        PA_IDXSET_FOREACH(ce, scache, idx) {
             int32_t id, rate, lvolume, rvolume, format, len;
             char name[ESD_NAME_MAX];
             pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } };
@@ -748,6 +749,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
             t -= s;
         }
     }
+    pa_idxset_free(scache, NULL);
 
     pa_assert(t == s);
 
@@ -817,7 +819,7 @@ static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *
     volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
     volume.channels = 2;
 
-    if ((ce = pa_idxset_get_by_index(c->protocol->core->scache, idx))) {
+    if ((ce = pa_core_get_scache_entry(c->protocol->core, idx))) {
         pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } };
 
         pa_cvolume_remap(&volume, &stereo, &ce->channel_map);
@@ -866,7 +868,7 @@ static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void
     CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name.");
 
     pa_assert(!c->scache.memchunk.memblock);
-    c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) sc_length);
+    c->scache.memchunk.memblock = pa_memblock_new(pa_core_get_mempool (c->protocol->core), (size_t) sc_length);
     c->scache.memchunk.index = 0;
     c->scache.memchunk.length = (size_t) sc_length;
     c->scache.sample_spec = ss;
@@ -1150,7 +1152,7 @@ static int do_read(connection *c) {
         }
 
         if (!c->playback.current_memblock) {
-            pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) -1));
+            pa_assert_se(c->playback.current_memblock = pa_memblock_new(pa_core_get_mempool(c->protocol->core), (size_t) -1));
             c->playback.memblock_index = 0;
 
             space = pa_memblock_get_length(c->playback.current_memblock);
@@ -1237,7 +1239,7 @@ static int do_write(connection *c) {
 static void do_work(connection *c) {
     connection_assert_ref(c);
 
-    c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
+    pa_core_get_mainloop(c->protocol->core)->defer_enable(c->defer_event, 0);
 
     if (c->dead)
         return;
@@ -1273,6 +1275,7 @@ fail:
         pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, 0, NULL, NULL);
     } else
         connection_unlink(c);
+
 }
 
 static void io_callback(pa_iochannel*io, void *userdata) {
@@ -1562,8 +1565,8 @@ void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esou
     else
         c->auth_timeout_event = NULL;
 
-    c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c);
-    p->core->mainloop->defer_enable(c->defer_event, 0);
+    c->defer_event = pa_core_get_mainloop(p->core)->defer_new(pa_core_get_mainloop(p->core), defer_callback, c);
+    pa_core_get_mainloop(p->core)->defer_enable(c->defer_event, 0);
 
     pa_idxset_put(p->connections, c, &c->index);
 }
diff --git a/src/pulsecore/protocol-http.c b/src/pulsecore/protocol-http.c
index bbb03c3..64024df 100644
--- a/src/pulsecore/protocol-http.c
+++ b/src/pulsecore/protocol-http.c
@@ -30,7 +30,6 @@
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 
-#include <pulsecore/core-struct.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/ioline.h>
 #include <pulsecore/thread-mq.h>
@@ -458,6 +457,7 @@ static void handle_listen(struct connection *c) {
     pa_source *source;
     pa_sink *sink;
     uint32_t idx;
+    pa_idxset *sinks, *sources;
 
     http_response(c, 200, "OK", MIME_HTML);
 
@@ -471,7 +471,9 @@ static void handle_listen(struct connection *c) {
         return;
     }
 
-    PA_IDXSET_FOREACH(sink, c->protocol->core->sinks, idx) {
+    sinks = pa_core_get_sinks(c->protocol->core);
+
+    PA_IDXSET_FOREACH(sink, sinks, idx) {
         char *t, *m;
 
         t = escape_html(pa_strna(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
@@ -484,13 +486,16 @@ static void handle_listen(struct connection *c) {
         pa_xfree(t);
         pa_xfree(m);
     }
+    pa_idxset_free(sinks, NULL);
 
     pa_ioline_puts(c->line,
                    "</p>\n"
                    "<h2>Sources</h2>\n"
                    "<p>\n");
 
-    PA_IDXSET_FOREACH(source, c->protocol->core->sources, idx) {
+    sources = pa_core_get_sources(c->protocol->core);
+
+    PA_IDXSET_FOREACH(source, sources, idx) {
         char *t, *m;
 
         if (source->monitor_of)
@@ -507,6 +512,7 @@ static void handle_listen(struct connection *c) {
         pa_xfree(t);
 
     }
+    pa_idxset_free(sources, NULL);
 
     pa_ioline_puts(c->line,
                    "</p>\n"
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index cbb6ae6..4cae6df 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -45,7 +45,6 @@
 #include <pulsecore/pdispatch.h>
 #include <pulsecore/pstream-util.h>
 #include <pulsecore/namereg.h>
-#include <pulsecore/core-struct.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/log.h>
@@ -1204,7 +1203,7 @@ static void native_connection_unlink(pa_native_connection *c) {
         pa_pstream_unlink(c->pstream);
 
     if (c->auth_timeout_event) {
-        c->protocol->core->mainloop->time_free(c->auth_timeout_event);
+        pa_core_get_mainloop(c->protocol->core)->time_free(c->auth_timeout_event);
         c->auth_timeout_event = NULL;
     }
 
@@ -1875,7 +1874,7 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
     int ret = PA_ERR_INVALID;
     uint8_t n_formats = 0;
     pa_format_info *format;
-    pa_idxset *formats = NULL;
+    pa_idxset *sinks = NULL, *formats = NULL;
     uint32_t i;
 
     pa_native_connection_assert_ref(c);
@@ -2014,8 +2013,9 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
     }
 
     if (sink_index != PA_INVALID_INDEX) {
+        sinks = pa_core_get_sinks(c->protocol->core);
 
-        if (!(sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index))) {
+        if (!(sink = pa_idxset_get_by_index(sinks, sink_index))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
             goto finish;
         }
@@ -2105,6 +2105,8 @@ finish:
         pa_proplist_free(p);
     if (formats)
         pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+    if (sinks)
+        pa_idxset_free(sinks, NULL);
 }
 
 static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -2203,7 +2205,7 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
     int ret = PA_ERR_INVALID;
     uint8_t n_formats = 0;
     pa_format_info *format;
-    pa_idxset *formats = NULL;
+    pa_idxset *sources = NULL, *sink_inputs = NULL, *formats = NULL;
     uint32_t i;
 
     pa_native_connection_assert_ref(c);
@@ -2333,8 +2335,9 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
     }
 
     if (source_index != PA_INVALID_INDEX) {
+        sources = pa_core_get_sources(c->protocol->core);
 
-        if (!(source = pa_idxset_get_by_index(c->protocol->core->sources, source_index))) {
+        if (!(source = pa_idxset_get_by_index(sources, source_index))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
             goto finish;
         }
@@ -2348,8 +2351,9 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
     }
 
     if (direct_on_input_idx != PA_INVALID_INDEX) {
+        sink_inputs = pa_core_get_sink_inputs(c->protocol->core);
 
-        if (!(direct_on_input = pa_idxset_get_by_index(c->protocol->core->sink_inputs, direct_on_input_idx))) {
+        if (!(direct_on_input = pa_idxset_get_by_index(sink_inputs, direct_on_input_idx))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
             goto finish;
         }
@@ -2419,6 +2423,10 @@ finish:
         pa_proplist_free(p);
     if (formats)
         pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+    if (sources)
+        pa_idxset_free(sources, NULL);
+    if (sink_inputs)
+        pa_idxset_free(sink_inputs, NULL);
 }
 
 static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -2475,7 +2483,7 @@ static void setup_srbchannel(pa_native_connection *c, pa_mem_type_t shm_type) {
         return;
     }
 
-    if (!(c->rw_mempool = pa_mempool_new(shm_type, c->protocol->core->shm_size, true))) {
+    if (!(c->rw_mempool = pa_core_new_mempool(c->protocol->core, shm_type, true))) {
         pa_log_warn("Disabling srbchannel, reason: Failed to allocate shared "
                     "writable memory pool.");
         return;
@@ -2490,7 +2498,7 @@ static void setup_srbchannel(pa_native_connection *c, pa_mem_type_t shm_type) {
     }
     pa_mempool_set_is_remote_writable(c->rw_mempool, true);
 
-    srb = pa_srbchannel_new(c->protocol->core->mainloop, c->rw_mempool);
+    srb = pa_srbchannel_new(pa_core_get_mainloop(c->protocol->core), c->rw_mempool);
     if (!srb) {
         pa_log_debug("Failed to create srbchannel");
         goto fail;
@@ -2634,14 +2642,14 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
 
         c->authorized = true;
         if (c->auth_timeout_event) {
-            c->protocol->core->mainloop->time_free(c->auth_timeout_event);
+            pa_core_get_mainloop(c->protocol->core)->time_free(c->auth_timeout_event);
             c->auth_timeout_event = NULL;
         }
     }
 
     /* Enable shared memory and memfd support if possible */
     do_shm =
-        pa_mempool_is_shared(c->protocol->core->mempool) &&
+        pa_mempool_is_shared(pa_core_get_mempool(c->protocol->core)) &&
         c->is_local;
 
     pa_log_debug("SHM possible: %s", pa_yes_no(do_shm));
@@ -2668,7 +2676,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
      * 64-bit kernel. Thus influence them to use the POSIX shared memory model
      * instead. Check commit 451d1d676237c81 for further details. */
     do_memfd =
-        c->version >= 32 && do_shm && pa_mempool_is_memfd_backed(c->protocol->core->mempool);
+        c->version >= 32 && do_shm && pa_mempool_is_memfd_backed(pa_core_get_mempool(c->protocol->core));
 
     shm_type = PA_MEM_TYPE_PRIVATE;
     if (do_shm) {
@@ -2710,13 +2718,13 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
     if (shm_type == PA_MEM_TYPE_SHARED_MEMFD) {
         const char *reason;
 
-        if (pa_pstream_register_memfd_mempool(c->pstream, c->protocol->core->mempool, &reason))
+        if (pa_pstream_register_memfd_mempool(c->pstream, pa_core_get_mempool(c->protocol->core), &reason))
             pa_log("Failed to register memfd mempool. Reason: %s", reason);
     }
 
     setup_srbchannel(c, shm_type);
 
-    pa_hook_fire(&c->protocol->core->hooks[PA_CORE_HOOK_CLIENT_AUTH], c->client);
+    pa_core_hook_fire(c->protocol->core, PA_CORE_HOOK_CLIENT_AUTH, c->client);
 }
 
 static void command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -2842,7 +2850,7 @@ static void command_stat(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
 
     CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
 
-    stat = pa_mempool_get_stat(c->protocol->core->mempool);
+    stat = pa_mempool_get_stat(pa_core_get_mempool(c->protocol->core));
 
     reply = reply_new(tag);
     pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->n_allocated));
@@ -3059,7 +3067,7 @@ static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag
     CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
 
     if (sink_index != PA_INVALID_INDEX)
-        sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index);
+        sink = pa_core_get_sink(c->protocol->core, sink_index);
     else
         sink = pa_namereg_get(c->protocol->core, sink_name, PA_NAMEREG_SINK);
 
@@ -3522,31 +3530,31 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
 
     if (command == PA_COMMAND_GET_SINK_INFO) {
         if (idx != PA_INVALID_INDEX)
-            sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
+            sink = pa_core_get_sink(c->protocol->core, idx);
         else
             sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK);
     } else if (command == PA_COMMAND_GET_SOURCE_INFO) {
         if (idx != PA_INVALID_INDEX)
-            source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
+            source = pa_core_get_source(c->protocol->core, idx);
         else
             source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE);
     } else if (command == PA_COMMAND_GET_CARD_INFO) {
         if (idx != PA_INVALID_INDEX)
-            card = pa_idxset_get_by_index(c->protocol->core->cards, idx);
+            card = pa_core_get_card(c->protocol->core, idx);
         else
             card = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_CARD);
     } else if (command == PA_COMMAND_GET_CLIENT_INFO)
-        client = pa_idxset_get_by_index(c->protocol->core->clients, idx);
+        client = pa_core_get_client(c->protocol->core, idx);
     else if (command == PA_COMMAND_GET_MODULE_INFO)
-        module = pa_idxset_get_by_index(c->protocol->core->modules, idx);
+        module = pa_core_get_module(c->protocol->core, idx);
     else if (command == PA_COMMAND_GET_SINK_INPUT_INFO)
-        si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
+        si = pa_core_get_sink_input(c->protocol->core, idx);
     else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO)
-        so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
+        so = pa_core_get_source_output(c->protocol->core, idx);
     else {
         pa_assert(command == PA_COMMAND_GET_SAMPLE_INFO);
         if (idx != PA_INVALID_INDEX)
-            sce = pa_idxset_get_by_index(c->protocol->core->scache, idx);
+            sce = pa_core_get_scache_entry(c->protocol->core, idx);
         else
             sce = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SAMPLE);
     }
@@ -3596,22 +3604,22 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t
     reply = reply_new(tag);
 
     if (command == PA_COMMAND_GET_SINK_INFO_LIST)
-        i = c->protocol->core->sinks;
+        i = pa_core_get_sinks(c->protocol->core);
     else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST)
-        i = c->protocol->core->sources;
+        i = pa_core_get_sources(c->protocol->core);
     else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
-        i = c->protocol->core->clients;
+        i = pa_core_get_clients(c->protocol->core);
     else if (command == PA_COMMAND_GET_CARD_INFO_LIST)
-        i = c->protocol->core->cards;
+        i = pa_core_get_cards(c->protocol->core);
     else if (command == PA_COMMAND_GET_MODULE_INFO_LIST)
-        i = c->protocol->core->modules;
+        i = pa_core_get_modules(c->protocol->core);
     else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST)
-        i = c->protocol->core->sink_inputs;
+        i = pa_core_get_sink_inputs(c->protocol->core);
     else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST)
-        i = c->protocol->core->source_outputs;
+        i = pa_core_get_source_outputs(c->protocol->core);
     else {
         pa_assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST);
-        i = c->protocol->core->scache;
+        i = pa_core_get_scache(c->protocol->core);
     }
 
     if (i) {
@@ -3635,9 +3643,12 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t
                 scache_fill_tagstruct(c, reply, p);
             }
         }
+
+        pa_idxset_free(i, NULL);
     }
 
     pa_pstream_send_tagstruct(c->pstream, reply);
+    return;
 }
 
 static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -3658,6 +3669,9 @@ static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t
 
     CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
 
+    def_sink = pa_namereg_get_default_sink(c->protocol->core);
+    def_source = pa_namereg_get_default_source(c->protocol->core);
+
     reply = reply_new(tag);
     pa_tagstruct_puts(reply, PACKAGE_NAME);
     pa_tagstruct_puts(reply, PACKAGE_VERSION);
@@ -3670,18 +3684,16 @@ static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t
     pa_tagstruct_puts(reply, h);
     pa_xfree(h);
 
-    fixup_sample_spec(c, &fixed_ss, &c->protocol->core->default_sample_spec);
+    fixup_sample_spec(c, &fixed_ss, pa_core_get_sample_spec(c->protocol->core));
     pa_tagstruct_put_sample_spec(reply, &fixed_ss);
 
-    def_sink = pa_namereg_get_default_sink(c->protocol->core);
     pa_tagstruct_puts(reply, def_sink ? def_sink->name : NULL);
-    def_source = pa_namereg_get_default_source(c->protocol->core);
     pa_tagstruct_puts(reply, def_source ? def_source->name : NULL);
 
-    pa_tagstruct_putu32(reply, c->protocol->core->cookie);
+    pa_tagstruct_putu32(reply, pa_core_get_cookie(c->protocol->core));
 
     if (c->version >= 15)
-        pa_tagstruct_put_channel_map(reply, &c->protocol->core->default_channel_map);
+        pa_tagstruct_put_channel_map(reply, pa_core_get_channel_map(c->protocol->core));
 
     pa_pstream_send_tagstruct(c->pstream, reply);
 }
@@ -3766,24 +3778,24 @@ static void command_set_volume(
 
         case PA_COMMAND_SET_SINK_VOLUME:
             if (idx != PA_INVALID_INDEX)
-                sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
+                sink = pa_core_get_sink(c->protocol->core, idx);
             else
                 sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK);
             break;
 
         case PA_COMMAND_SET_SOURCE_VOLUME:
             if (idx != PA_INVALID_INDEX)
-                source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
+                source = pa_core_get_source(c->protocol->core, idx);
             else
                 source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE);
             break;
 
         case PA_COMMAND_SET_SINK_INPUT_VOLUME:
-            si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
+            si = pa_core_get_sink_input(c->protocol->core, idx);
             break;
 
         case PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME:
-            so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
+            so = pa_core_get_source_output(c->protocol->core, idx);
             break;
 
         default:
@@ -3861,7 +3873,7 @@ static void command_set_mute(
 
         case PA_COMMAND_SET_SINK_MUTE:
             if (idx != PA_INVALID_INDEX)
-                sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
+                sink = pa_core_get_sink(c->protocol->core, idx);
             else
                 sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK);
 
@@ -3869,18 +3881,18 @@ static void command_set_mute(
 
         case PA_COMMAND_SET_SOURCE_MUTE:
             if (idx != PA_INVALID_INDEX)
-                source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
+                source = pa_core_get_source(c->protocol->core, idx);
             else
                 source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE);
 
             break;
 
         case PA_COMMAND_SET_SINK_INPUT_MUTE:
-            si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
+            si = pa_core_get_sink_input(c->protocol->core, idx);
             break;
 
         case PA_COMMAND_SET_SOURCE_OUTPUT_MUTE:
-            so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
+            so = pa_core_get_source_output(c->protocol->core, idx);
             break;
 
         default:
@@ -4425,7 +4437,7 @@ static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
     if (command == PA_COMMAND_KILL_CLIENT) {
         pa_client *client;
 
-        client = pa_idxset_get_by_index(c->protocol->core->clients, idx);
+        client = pa_core_get_client(c->protocol->core, idx);
         CHECK_VALIDITY(c->pstream, client, tag, PA_ERR_NOENTITY);
 
         pa_native_connection_ref(c);
@@ -4434,7 +4446,7 @@ static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
     } else if (command == PA_COMMAND_KILL_SINK_INPUT) {
         pa_sink_input *s;
 
-        s = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
+        s = pa_core_get_sink_input(c->protocol->core, idx);
         CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
 
         pa_native_connection_ref(c);
@@ -4444,7 +4456,7 @@ static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
 
         pa_assert(command == PA_COMMAND_KILL_SOURCE_OUTPUT);
 
-        s = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
+        s = pa_core_get_source_output(c->protocol->core, idx);
         CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
 
         pa_native_connection_ref(c);
@@ -4500,7 +4512,7 @@ static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t t
     }
 
     CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
-    m = pa_idxset_get_by_index(c->protocol->core->modules, idx);
+    m = pa_core_get_module(c->protocol->core, idx);
     CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY);
 
     pa_module_unload_request(m, false);
@@ -4533,10 +4545,10 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag
         pa_sink_input *si = NULL;
         pa_sink *sink = NULL;
 
-        si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
+        si = pa_core_get_sink_input(c->protocol->core, idx);
 
         if (idx_device != PA_INVALID_INDEX)
-            sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx_device);
+            sink = pa_core_get_sink(c->protocol->core, idx_device);
         else
             sink = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SINK);
 
@@ -4552,10 +4564,10 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag
 
         pa_assert(command == PA_COMMAND_MOVE_SOURCE_OUTPUT);
 
-        so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
+        so = pa_core_get_source_output(c->protocol->core, idx);
 
         if (idx_device != PA_INVALID_INDEX)
-            source = pa_idxset_get_by_index(c->protocol->core->sources, idx_device);
+            source = pa_core_get_source(c->protocol->core, idx_device);
         else
             source = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SOURCE);
 
@@ -4605,7 +4617,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
             pa_sink *sink = NULL;
 
             if (idx != PA_INVALID_INDEX)
-                sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
+                sink = pa_core_get_sink(c->protocol->core, idx);
             else
                 sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK);
 
@@ -4636,7 +4648,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
             pa_source *source;
 
             if (idx != PA_INVALID_INDEX)
-                source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
+                source = pa_core_get_source(c->protocol->core, idx);
             else
                 source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE);
 
@@ -4676,12 +4688,17 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag,
     CHECK_VALIDITY(c->pstream, (idx != PA_INVALID_INDEX) ^ (name != NULL), tag, PA_ERR_INVALID);
 
     if (idx != PA_INVALID_INDEX)
-        m = pa_idxset_get_by_index(c->protocol->core->modules, idx);
-    else
-        PA_IDXSET_FOREACH(m, c->protocol->core->modules, idx)
+        m = pa_core_get_module(c->protocol->core, idx);
+    else {
+        pa_idxset *modules = pa_core_get_modules (c->protocol->core);
+
+        PA_IDXSET_FOREACH(m, modules, idx)
             if (pa_streq(name, m->name))
                 break;
 
+        pa_idxset_free (modules, NULL);
+    }
+
     CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOEXTENSION);
     CHECK_VALIDITY(c->pstream, m->load_once || idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
 
@@ -4717,7 +4734,7 @@ static void command_set_card_profile(pa_pdispatch *pd, uint32_t command, uint32_
     CHECK_VALIDITY(c->pstream, profile_name, tag, PA_ERR_INVALID);
 
     if (idx != PA_INVALID_INDEX)
-        card = pa_idxset_get_by_index(c->protocol->core->cards, idx);
+        card = pa_core_get_card(c->protocol->core, idx);
     else
         card = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_CARD);
 
@@ -4761,7 +4778,7 @@ static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command,
         pa_sink *sink;
 
         if (idx != PA_INVALID_INDEX)
-            sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
+            sink = pa_core_get_sink(c->protocol->core, idx);
         else
             sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK);
 
@@ -4777,7 +4794,7 @@ static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command,
         pa_assert(command == PA_COMMAND_SET_SOURCE_PORT);
 
         if (idx != PA_INVALID_INDEX)
-            source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
+            source = pa_core_get_source(c->protocol->core, idx);
         else
             source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE);
 
@@ -4818,7 +4835,7 @@ static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command,
     CHECK_VALIDITY(c->pstream, port_name, tag, PA_ERR_INVALID);
 
     if (idx != PA_INVALID_INDEX)
-        card = pa_idxset_get_by_index(c->protocol->core->cards, idx);
+        card = pa_core_get_card(c->protocol->core, idx);
     else
         card = pa_namereg_get(c->protocol->core, card_name, PA_NAMEREG_CARD);
 
@@ -5003,7 +5020,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o
                 pa_memblock_ref(u->memchunk.memblock);
                 u->length = 0;
             } else {
-                u->memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, u->length);
+                u->memchunk.memblock = pa_memblock_new(pa_core_get_mempool(c->protocol->core), u->length);
                 u->memchunk.index = u->memchunk.length = 0;
             }
         }
@@ -5181,7 +5198,7 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati
 
     c->rw_mempool = NULL;
 
-    c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool);
+    c->pstream = pa_pstream_new(pa_core_get_mainloop(p->core), io, pa_core_get_mempool(p->core));
     pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c);
     pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c);
     pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
@@ -5189,7 +5206,7 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati
     pa_pstream_set_revoke_callback(c->pstream, pstream_revoke_callback, c);
     pa_pstream_set_release_callback(c->pstream, pstream_release_callback, c);
 
-    c->pdispatch = pa_pdispatch_new(p->core->mainloop, true, command_table, PA_COMMAND_MAX);
+    c->pdispatch = pa_pdispatch_new(pa_core_get_mainloop(p->core), true, command_table, PA_COMMAND_MAX);
 
     c->record_streams = pa_idxset_new(NULL, NULL);
     c->output_streams = pa_idxset_new(NULL, NULL);
diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c
index bd9136b..e1ead2f 100644
--- a/src/pulsecore/protocol-simple.c
+++ b/src/pulsecore/protocol-simple.c
@@ -34,7 +34,6 @@
 #include <pulsecore/sample-util.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-struct.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/atomic.h>
 #include <pulsecore/thread-mq.h>
@@ -169,7 +168,7 @@ static int do_read(connection *c) {
     }
 
     if (!c->playback.current_memblock) {
-        pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) -1));
+        pa_assert_se(c->playback.current_memblock = pa_memblock_new(pa_core_get_mempool(c->protocol->core), (size_t) -1));
         c->playback.memblock_index = 0;
 
         space = pa_memblock_get_length(c->playback.current_memblock);
@@ -737,7 +736,7 @@ int pa_simple_options_parse(pa_simple_options *o, pa_core *c, pa_modargs *ma) {
     pa_assert(PA_REFCNT_VALUE(o) >= 1);
     pa_assert(ma);
 
-    o->sample_spec = c->default_sample_spec;
+    o->sample_spec = *pa_core_get_sample_spec(c);
     if (pa_modargs_get_sample_spec_and_channel_map(ma, &o->sample_spec, &o->channel_map, PA_CHANNEL_MAP_DEFAULT) < 0) {
         pa_log("Failed to parse sample type specification.");
         return -1;
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 20249ec..a5cb1ee 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -2892,17 +2892,21 @@ int pa_sink_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) {
     pa_sink *sink;
     uint32_t idx;
     int ret = 0;
+    pa_idxset *sinks;
 
     pa_core_assert_ref(c);
     pa_assert_ctl_context();
     pa_assert(cause != 0);
 
-    PA_IDXSET_FOREACH(sink, c->sinks, idx) {
+    sinks = pa_core_get_sinks(c);
+
+    PA_IDXSET_FOREACH(sink, sinks, idx) {
         int r;
 
         if ((r = pa_sink_suspend(sink, suspend, cause)) < 0)
             ret = r;
     }
+    pa_idxset_free(sinks, NULL);
 
     return ret;
 }
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 7a33d5b..5f42965 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -2254,12 +2254,15 @@ int pa_source_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) {
     pa_source *source;
     uint32_t idx;
     int ret = 0;
+    pa_idxset *sources;
 
     pa_core_assert_ref(c);
     pa_assert_ctl_context();
     pa_assert(cause != 0);
 
-    for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) {
+    sources = pa_core_get_sources(c);
+
+    PA_IDXSET_FOREACH(source, sources, idx) {
         int r;
 
         if (source->monitor_of)
@@ -2268,6 +2271,7 @@ int pa_source_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) {
         if ((r = pa_source_suspend(source, suspend, cause)) < 0)
             ret = r;
     }
+    pa_idxset_free(sources, NULL);
 
     return ret;
 }
-- 
2.9.3