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) {
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);
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;
#include <pulsecore/i18n.h>
#include <pulsecore/macro.h>
#include <pulsecore/socket.h>
+#include <pulsecore/dynarray.h>
#ifndef PACKAGE
#error "Please include config.h before including this file!"
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);