diff options
Diffstat (limited to 'src/pulse/client-conf.c')
-rw-r--r-- | src/pulse/client-conf.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c new file mode 100644 index 0000000..1daaf91 --- /dev/null +++ b/src/pulse/client-conf.c @@ -0,0 +1,240 @@ +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio 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.1 of the License, + or (at your option) any later version. + + PulseAudio 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 Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +#include <pulse/xmalloc.h> + +#include <pulsecore/i18n.h> +#include <pulsecore/macro.h> +#include <pulsecore/core-error.h> +#include <pulsecore/log.h> +#include <pulsecore/conf-parser.h> +#include <pulsecore/core-util.h> +#include <pulsecore/authkey.h> + +#include "client-conf.h" + +#ifdef HAVE_X11 +#include <pulse/client-conf-x11.h> +#endif + +#define DEFAULT_CLIENT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "client.conf" +#define DEFAULT_CLIENT_CONFIG_FILE_USER "client.conf" + +#define ENV_CLIENT_CONFIG_FILE "PULSE_CLIENTCONFIG" +#define ENV_DEFAULT_SINK "PULSE_SINK" +#define ENV_DEFAULT_SOURCE "PULSE_SOURCE" +#define ENV_DEFAULT_SERVER "PULSE_SERVER" +#define ENV_DAEMON_BINARY "PULSE_BINARY" +#define ENV_COOKIE_FILE "PULSE_COOKIE" + +static const pa_client_conf default_conf = { + .daemon_binary = NULL, + .extra_arguments = NULL, + .default_sink = NULL, + .default_source = NULL, + .default_server = NULL, + .default_dbus_server = NULL, + .cookie_file_from_env = NULL, + .cookie_from_x11_valid = false, + .cookie_file_from_application = NULL, + .cookie_file_from_client_conf = NULL, + .autospawn = true, + .disable_shm = false, + .disable_memfd = false, + .shm_size = 0, + .auto_connect_localhost = false, + .auto_connect_display = false +}; + +pa_client_conf *pa_client_conf_new(void) { + pa_client_conf *c = pa_xmemdup(&default_conf, sizeof(default_conf)); + + c->daemon_binary = pa_xstrdup(PA_BINARY); + c->extra_arguments = pa_xstrdup("--log-target=syslog"); + + return c; +} + +void pa_client_conf_free(pa_client_conf *c) { + pa_assert(c); + pa_xfree(c->daemon_binary); + pa_xfree(c->extra_arguments); + pa_xfree(c->default_sink); + pa_xfree(c->default_source); + pa_xfree(c->default_server); + pa_xfree(c->default_dbus_server); + pa_xfree(c->cookie_file_from_env); + pa_xfree(c->cookie_file_from_application); + pa_xfree(c->cookie_file_from_client_conf); + pa_xfree(c); +} + +static void load_env(pa_client_conf *c) { + char *e; + + if ((e = getenv(ENV_DEFAULT_SINK))) { + pa_xfree(c->default_sink); + c->default_sink = pa_xstrdup(e); + } + + if ((e = getenv(ENV_DEFAULT_SOURCE))) { + pa_xfree(c->default_source); + c->default_source = pa_xstrdup(e); + } + + if ((e = getenv(ENV_DEFAULT_SERVER))) { + pa_xfree(c->default_server); + c->default_server = pa_xstrdup(e); + + /* We disable autospawning automatically if a specific server was set */ + c->autospawn = false; + } + + if ((e = getenv(ENV_DAEMON_BINARY))) { + pa_xfree(c->daemon_binary); + c->daemon_binary = pa_xstrdup(e); + } + + if ((e = getenv(ENV_COOKIE_FILE)) && *e) { + pa_xfree(c->cookie_file_from_env); + c->cookie_file_from_env = pa_xstrdup(e); + } +} + +void pa_client_conf_load(pa_client_conf *c, bool load_from_x11, bool load_from_env) { + FILE *f = NULL; + char *fn = NULL; + + /* Prepare the configuration parse table */ + pa_config_item table[] = { + { "daemon-binary", pa_config_parse_string, &c->daemon_binary, NULL }, + { "extra-arguments", pa_config_parse_string, &c->extra_arguments, NULL }, + { "default-sink", pa_config_parse_string, &c->default_sink, NULL }, + { "default-source", pa_config_parse_string, &c->default_source, NULL }, + { "default-server", pa_config_parse_string, &c->default_server, NULL }, + { "default-dbus-server", pa_config_parse_string, &c->default_dbus_server, NULL }, + { "autospawn", pa_config_parse_bool, &c->autospawn, NULL }, + { "cookie-file", pa_config_parse_string, &c->cookie_file_from_client_conf, NULL }, + { "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL }, + { "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL }, + { "enable-memfd", pa_config_parse_not_bool, &c->disable_memfd, NULL }, + { "shm-size-bytes", pa_config_parse_size, &c->shm_size, NULL }, + { "auto-connect-localhost", pa_config_parse_bool, &c->auto_connect_localhost, NULL }, + { "auto-connect-display", pa_config_parse_bool, &c->auto_connect_display, NULL }, + { NULL, NULL, NULL, NULL }, + }; + + f = pa_open_config_file(DEFAULT_CLIENT_CONFIG_FILE, DEFAULT_CLIENT_CONFIG_FILE_USER, ENV_CLIENT_CONFIG_FILE, &fn); + if (f) { + pa_config_parse(fn, f, table, NULL, true, NULL); + pa_xfree(fn); + fclose(f); + } + + if (load_from_x11) { +#ifdef HAVE_X11 + pa_client_conf_from_x11(c); +#endif + } + + if (load_from_env) + load_env(c); +} + +int pa_client_conf_load_cookie(pa_client_conf *c, uint8_t *cookie, size_t cookie_length) { + int r; + char *fallback_path; + + pa_assert(c); + pa_assert(cookie); + pa_assert(cookie_length > 0); + + if (c->cookie_file_from_env) { + r = pa_authkey_load(c->cookie_file_from_env, true, cookie, cookie_length); + if (r >= 0) + return 0; + + pa_log_warn("Failed to load cookie from %s (configured with environment variable PULSE_COOKIE): %s", + c->cookie_file_from_env, pa_cstrerror(errno)); + } + + if (c->cookie_from_x11_valid) { + if (cookie_length == sizeof(c->cookie_from_x11)) { + memcpy(cookie, c->cookie_from_x11, cookie_length); + return 0; + } + + pa_log_warn("Failed to load cookie from X11 root window property PULSE_COOKIE: size mismatch."); + } + + if (c->cookie_file_from_application) { + r = pa_authkey_load(c->cookie_file_from_application, true, cookie, cookie_length); + if (r >= 0) + return 0; + + pa_log_warn("Failed to load cookie from %s (configured by the application): %s", c->cookie_file_from_application, + pa_cstrerror(errno)); + } + + if (c->cookie_file_from_client_conf) { + r = pa_authkey_load(c->cookie_file_from_client_conf, true, cookie, cookie_length); + if (r >= 0) + return 0; + + pa_log_warn("Failed to load cookie from %s (configured in client.conf): %s", c->cookie_file_from_client_conf, + pa_cstrerror(errno)); + } + + r = pa_authkey_load(PA_NATIVE_COOKIE_FILE, false, cookie, cookie_length); + if (r >= 0) + return 0; + + if (pa_append_to_home_dir(PA_NATIVE_COOKIE_FILE_FALLBACK, &fallback_path) >= 0) { + r = pa_authkey_load(fallback_path, false, cookie, cookie_length); + pa_xfree(fallback_path); + if (r >= 0) + return 0; + } + + r = pa_authkey_load(PA_NATIVE_COOKIE_FILE, true, cookie, cookie_length); + if (r >= 0) + return 0; + + pa_log("Failed to load cookie file from %s: %s", PA_NATIVE_COOKIE_FILE, pa_cstrerror(errno)); + memset(cookie, 0, cookie_length); + + return -1; +} + +void pa_client_conf_set_cookie_file_from_application(pa_client_conf *c, const char *cookie_file) { + pa_assert(c); + pa_assert(!cookie_file || *cookie_file); + + pa_xfree(c->cookie_file_from_application); + c->cookie_file_from_application = pa_xstrdup(cookie_file); +} |