From: SimonP Date: Thu, 7 May 2020 15:13:27 +0000 (+0100) Subject: alsa-mixer: Respect XDG base directory spec when loading path configs X-Git-Tag: v14.99.1~251 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9b0ae8327d990584bb9a966d8d7bee6badbdb8c0;p=platform%2Fupstream%2Fpulseaudio.git alsa-mixer: Respect XDG base directory spec when loading path configs Try $XDG_DATA_HOME, then $XDG_DATA_DIRS, and finally fall back to old behaviour (prefix-defined directory). core-util: Ignore non-absolute XDG base dirs These are invalid per the spec. Fixes: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/862 Part-of: --- diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index f978f71..c406297 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -2763,13 +2763,66 @@ static int path_verify(pa_alsa_path *p) { return 0; } -static const char *get_default_paths_dir(void) { +static char *get_path_config_path(const char *paths_dir, const char *fname) { + char *path_config_path; + char *dir; + char *data_home; + pa_dynarray *data_dirs; + + if (paths_dir) { + path_config_path = pa_maybe_prefix_path(fname, paths_dir); + if (access(path_config_path, R_OK) == 0) + return path_config_path; + else + pa_xfree(path_config_path); + } + #ifdef HAVE_RUNNING_FROM_BUILD_TREE - if (pa_run_from_build_tree()) - return PA_SRCDIR "/modules/alsa/mixer/paths/"; - else + if (pa_run_from_build_tree()) { + path_config_path = pa_maybe_prefix_path(fname, PA_SRCDIR "/modules/alsa/mixer/paths/"); + if (access(path_config_path, R_OK) == 0) + return path_config_path; + else + pa_xfree(path_config_path); + } #endif - return PA_ALSA_PATHS_DIR; + + if (pa_get_data_home_dir(&data_home) == 0) { + dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "paths", data_home); + pa_xfree(data_home); + + path_config_path = pa_maybe_prefix_path(fname, dir); + pa_xfree(dir); + + if (access(path_config_path, R_OK) == 0) + return path_config_path; + else + pa_xfree(path_config_path); + } + + if (pa_get_data_dirs(&data_dirs) == 0) { + int idx; + const char *n; + + PA_DYNARRAY_FOREACH(n, data_dirs, idx) { + dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "paths", n); + path_config_path = pa_maybe_prefix_path(fname, dir); + pa_xfree(dir); + + if (access(path_config_path, R_OK) == 0) { + pa_dynarray_free(data_dirs); + return path_config_path; + } + else { + pa_xfree(path_config_path); + } + } + + pa_dynarray_free(data_dirs); + } + + path_config_path = pa_maybe_prefix_path(fname, PA_ALSA_PATHS_DIR); + return path_config_path; } pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction) { @@ -2827,10 +2880,9 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa items[2].data = &p->description; items[3].data = &mute_during_activation; - if (!paths_dir) - paths_dir = get_default_paths_dir(); + fn = get_path_config_path(paths_dir, fname); - fn = pa_maybe_prefix_path(fname, paths_dir); + pa_log_info("Loading path config: %s", fn); r = pa_config_parse(fn, NULL, items, p->proplist, false, p); pa_xfree(fn); diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 25498c5..0da5c09 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1568,6 +1568,70 @@ int pa_get_config_home_dir(char **_r) { return 0; } +int pa_get_data_home_dir(char **_r) { + const char *e; + char *home_dir; + + pa_assert(_r); + + e = getenv("XDG_DATA_HOME"); + if (e && *e) { + if (pa_is_path_absolute(e)) { + *_r = pa_sprintf_malloc("%s" PA_PATH_SEP "pulseaudio", e); + return 0; + } + else + pa_log_warn("Ignored non-absolute XDG_DATA_HOME value '%s'", e); + } + + home_dir = pa_get_home_dir_malloc(); + if (!home_dir) + return -PA_ERR_NOENTITY; + + *_r = pa_sprintf_malloc("%s" PA_PATH_SEP ".local" PA_PATH_SEP "share" PA_PATH_SEP "pulseaudio", home_dir); + pa_xfree(home_dir); + return 0; +} + +int pa_get_data_dirs(pa_dynarray **_r) { + const char *e; + const char *def = "/usr/local/share/:/usr/share/"; + const char *p; + const char *split_state = NULL; + char *n; + pa_dynarray *paths; + + pa_assert(_r); + + e = getenv("XDG_DATA_DIRS"); + p = e && *e ? e : def; + + paths = pa_dynarray_new((pa_free_cb_t) pa_xfree); + + while ((n = pa_split(p, ":", &split_state))) { + char *path; + + if (!pa_is_path_absolute(n)) { + pa_log_warn("Ignored non-absolute path '%s' in XDG_DATA_DIRS", n); + pa_xfree(n); + continue; + } + + path = pa_sprintf_malloc("%s" PA_PATH_SEP "pulseaudio", n); + pa_xfree(n); + pa_dynarray_append(paths, path); + } + + if (pa_dynarray_size(paths) == 0) { + pa_log_warn("XDG_DATA_DIRS contains no valid paths"); + pa_dynarray_free(paths); + return -PA_ERR_INVALID; + } + + *_r = paths; + return 0; +} + int pa_append_to_config_home_dir(const char *path, char **_r) { int r; char *config_home_dir; diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 3117df8..ed123c7 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -37,6 +37,7 @@ #include #include #include +#include #ifndef PACKAGE #error "Please include config.h before including this file!" @@ -142,6 +143,8 @@ char *pa_get_state_dir(void); char *pa_get_home_dir_malloc(void); int pa_append_to_home_dir(const char *path, char **_r); int pa_get_config_home_dir(char **_r); +int pa_get_data_home_dir(char **_r); +int pa_get_data_dirs(pa_dynarray **_r); int pa_append_to_config_home_dir(const char *path, char **_r); char *pa_get_binary_name_malloc(void); char *pa_runtime_path(const char *fn); diff --git a/src/tests/alsa-mixer-path-test.c b/src/tests/alsa-mixer-path-test.c index 75cf086..91e4d0d 100644 --- a/src/tests/alsa-mixer-path-test.c +++ b/src/tests/alsa-mixer-path-test.c @@ -17,7 +17,6 @@ * Meson. */ #ifndef MESON_BUILD -/* This function was copied from alsa-mixer.c */ static const char *get_default_paths_dir(void) { if (pa_run_from_build_tree()) return PA_SRCDIR "/modules/alsa/mixer/paths/";