mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	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: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/293>
This commit is contained in:
		
							parent
							
								
									cb91d7a12e
								
							
						
					
					
						commit
						9b0ae8327d
					
				
					 4 changed files with 127 additions and 9 deletions
				
			
		| 
						 | 
					@ -2763,13 +2763,66 @@ static int path_verify(pa_alsa_path *p) {
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *get_default_paths_dir(void) {
 | 
					static char *get_path_config_path(const char *paths_dir, const char *fname) {
 | 
				
			||||||
#ifdef HAVE_RUNNING_FROM_BUILD_TREE
 | 
					    char *path_config_path;
 | 
				
			||||||
    if (pa_run_from_build_tree())
 | 
					    char *dir;
 | 
				
			||||||
        return PA_SRCDIR "/modules/alsa/mixer/paths/";
 | 
					    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
 | 
					        else
 | 
				
			||||||
 | 
					            pa_xfree(path_config_path);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_RUNNING_FROM_BUILD_TREE
 | 
				
			||||||
 | 
					    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
 | 
					#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) {
 | 
					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[2].data = &p->description;
 | 
				
			||||||
    items[3].data = &mute_during_activation;
 | 
					    items[3].data = &mute_during_activation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!paths_dir)
 | 
					    fn = get_path_config_path(paths_dir, fname);
 | 
				
			||||||
        paths_dir = get_default_paths_dir();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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);
 | 
					    r = pa_config_parse(fn, NULL, items, p->proplist, false, p);
 | 
				
			||||||
    pa_xfree(fn);
 | 
					    pa_xfree(fn);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1568,6 +1568,70 @@ int pa_get_config_home_dir(char **_r) {
 | 
				
			||||||
    return 0;
 | 
					    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 pa_append_to_config_home_dir(const char *path, char **_r) {
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
    char *config_home_dir;
 | 
					    char *config_home_dir;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@
 | 
				
			||||||
#include <pulsecore/i18n.h>
 | 
					#include <pulsecore/i18n.h>
 | 
				
			||||||
#include <pulsecore/macro.h>
 | 
					#include <pulsecore/macro.h>
 | 
				
			||||||
#include <pulsecore/socket.h>
 | 
					#include <pulsecore/socket.h>
 | 
				
			||||||
 | 
					#include <pulsecore/dynarray.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef PACKAGE
 | 
					#ifndef PACKAGE
 | 
				
			||||||
#error "Please include config.h before including this file!"
 | 
					#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);
 | 
					char *pa_get_home_dir_malloc(void);
 | 
				
			||||||
int pa_append_to_home_dir(const char *path, char **_r);
 | 
					int pa_append_to_home_dir(const char *path, char **_r);
 | 
				
			||||||
int pa_get_config_home_dir(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);
 | 
					int pa_append_to_config_home_dir(const char *path, char **_r);
 | 
				
			||||||
char *pa_get_binary_name_malloc(void);
 | 
					char *pa_get_binary_name_malloc(void);
 | 
				
			||||||
char *pa_runtime_path(const char *fn);
 | 
					char *pa_runtime_path(const char *fn);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,6 @@
 | 
				
			||||||
 * Meson. */
 | 
					 * Meson. */
 | 
				
			||||||
#ifndef MESON_BUILD
 | 
					#ifndef MESON_BUILD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This function was copied from alsa-mixer.c */
 | 
					 | 
				
			||||||
static const char *get_default_paths_dir(void) {
 | 
					static const char *get_default_paths_dir(void) {
 | 
				
			||||||
    if (pa_run_from_build_tree())
 | 
					    if (pa_run_from_build_tree())
 | 
				
			||||||
        return PA_SRCDIR "/modules/alsa/mixer/paths/";
 | 
					        return PA_SRCDIR "/modules/alsa/mixer/paths/";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue