/*** This file is part of PulseAudio. Copyright 2004-2006 Lennart Poettering Copyright 2006 Pierre Ossman 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 . ***/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "client-conf.h" #ifdef HAVE_X11 #include #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, .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 }, { "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, 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); }