diff --git a/spa/plugins/filter-graph/plugin_ladspa.c b/spa/plugins/filter-graph/plugin_ladspa.c index 1aebafe35..51167827b 100644 --- a/spa/plugins/filter-graph/plugin_ladspa.c +++ b/spa/plugins/filter-graph/plugin_ladspa.c @@ -233,43 +233,49 @@ static inline const char *split_walk(const char *str, const char *delimiter, siz return s; } -static int load_ladspa_plugin(struct plugin *impl, const char *path) +static void make_search_paths(const char **path, const char **search_dirs) +{ + const char *p; + + while ((p = strstr(*path, "../")) != NULL) + *path = p + 3; + + *search_dirs = getenv("LADSPA_PATH"); + if (!*search_dirs) + *search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR; +} + +static int load_ladspa_plugin(struct plugin *impl, const char *path, const char *search_dirs) { int res = -ENOENT; + const char *p, *state = NULL; + char filename[PATH_MAX]; + size_t len; - if (path[0] != '/') { - const char *search_dirs, *p, *state = NULL; - char filename[PATH_MAX]; - size_t len; + /* + * set the errno for the case when `ladspa_handle_load_by_path()` + * is never called, which can only happen if the supplied + * LADSPA_PATH contains too long paths + */ + res = -ENAMETOOLONG; - search_dirs = getenv("LADSPA_PATH"); - if (!search_dirs) - search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR; + while ((p = split_walk(search_dirs, ":", &len, &state))) { + int namelen; - /* - * set the errno for the case when `ladspa_handle_load_by_path()` - * is never called, which can only happen if the supplied - * LADSPA_PATH contains too long paths - */ - res = -ENAMETOOLONG; - - while ((p = split_walk(search_dirs, ":", &len, &state))) { - int namelen; - - if (len >= sizeof(filename)) - continue; + if (len >= sizeof(filename)) + continue; + if (strncmp(path, p, len) == 0) + namelen = snprintf(filename, sizeof(filename), "%s", path); + else namelen = snprintf(filename, sizeof(filename), "%.*s/%s.so", (int) len, p, path); - if (namelen < 0 || (size_t) namelen >= sizeof(filename)) - continue; - res = ladspa_handle_load_by_path(impl, filename); - if (res >= 0) - break; - } - } - else { - res = ladspa_handle_load_by_path(impl, path); + if (namelen < 0 || (size_t) namelen >= sizeof(filename)) + continue; + + res = ladspa_handle_load_by_path(impl, filename); + if (res >= 0) + break; } return res; } @@ -317,7 +323,7 @@ impl_init(const struct spa_handle_factory *factory, struct plugin *impl; uint32_t i; int res; - const char *path = NULL; + const char *path = NULL, *search_dirs; handle->get_interface = impl_get_interface; handle->clear = impl_clear; @@ -335,9 +341,11 @@ impl_init(const struct spa_handle_factory *factory, if (path == NULL) return -EINVAL; - if ((res = load_ladspa_plugin(impl, path)) < 0) { - spa_log_error(impl->log, "failed to load plugin '%s': %s", - path, spa_strerror(res)); + make_search_paths(&path, &search_dirs); + + if ((res = load_ladspa_plugin(impl, path, search_dirs)) < 0) { + spa_log_error(impl->log, "failed to load plugin '%s' in '%s': %s", + path, search_dirs, spa_strerror(res)); return res; } diff --git a/src/daemon/filter-chain/source-rnnoise.conf b/src/daemon/filter-chain/source-rnnoise.conf index f3c2c71be..83142dd29 100644 --- a/src/daemon/filter-chain/source-rnnoise.conf +++ b/src/daemon/filter-chain/source-rnnoise.conf @@ -21,7 +21,6 @@ context.modules = [ # listed in the environment variable LADSPA_PATH or # /usr/lib64/ladspa, /usr/lib/ladspa or the system library directory # as a fallback. - # You might want to use an absolute path here to avoid problems. plugin = "librnnoise_ladspa" label = noise_suppressor_stereo control = { diff --git a/src/modules/module-filter-chain.c b/src/modules/module-filter-chain.c index 64a92c5ac..97baa8f5f 100644 --- a/src/modules/module-filter-chain.c +++ b/src/modules/module-filter-chain.c @@ -128,7 +128,7 @@ extern struct spa_handle_factory spa_filter_graph_factory; * # an example ladspa plugin * type = ladspa * name = pitch - * plugin = "/usr/lib64/ladspa/ladspa-rubberband.so" + * plugin = "ladspa-rubberband" * label = "rubberband-r3-pitchshifter-mono" * control = { * # controls are using the ladspa port names as seen in analyseplugin diff --git a/src/modules/module-jack-tunnel.c b/src/modules/module-jack-tunnel.c index 0c0cee034..8237d0a08 100644 --- a/src/modules/module-jack-tunnel.c +++ b/src/modules/module-jack-tunnel.c @@ -50,7 +50,6 @@ * * - `jack.library`: the libjack to load, by default libjack.so.0 is searched in * LIBJACK_PATH directories and then some standard library paths. - * Can be an absolute path. * - `jack.server`: the name of the JACK server to tunnel to. * - `jack.client-name`: the name of the JACK client. * - `jack.connect`: if jack ports should be connected automatically. Can also be diff --git a/src/modules/module-jack-tunnel/weakjack.h b/src/modules/module-jack-tunnel/weakjack.h index 6d5b5503e..f5c6361ad 100644 --- a/src/modules/module-jack-tunnel/weakjack.h +++ b/src/modules/module-jack-tunnel/weakjack.h @@ -158,34 +158,36 @@ static inline int weakjack_load_by_path(struct weakjack *jack, const char *path) static inline int weakjack_load(struct weakjack *jack, const char *lib) { int res = -ENOENT; + const char *search_dirs, *p, *state = NULL; + char path[PATH_MAX]; + size_t len; - if (lib[0] != '/') { - const char *search_dirs, *p, *state = NULL; - char path[PATH_MAX]; - size_t len; + while ((p = strstr(lib, "../")) != NULL) + lib = p + 3; - search_dirs = getenv("LIBJACK_PATH"); - if (!search_dirs) - search_dirs = PREFIX "/lib64/:" PREFIX "/lib/:" - "/usr/lib64/:/usr/lib/:" LIBDIR; + search_dirs = getenv("LIBJACK_PATH"); + if (!search_dirs) + search_dirs = PREFIX "/lib64/:" PREFIX "/lib/:" + "/usr/lib64/:/usr/lib/:" LIBDIR; - while ((p = pw_split_walk(search_dirs, ":", &len, &state))) { - int pathlen; + res = -ENAMETOOLONG; - if (len >= sizeof(path)) { - res = -ENAMETOOLONG; - continue; - } + while ((p = pw_split_walk(search_dirs, ":", &len, &state))) { + int pathlen; + + if (len >= sizeof(path)) + continue; + + if (strncmp(lib, p, len) == 0) + pathlen = snprintf(path, sizeof(path), "%s", lib); + else pathlen = snprintf(path, sizeof(path), "%.*s/%s", (int) len, p, lib); - if (pathlen < 0 || (size_t) pathlen >= sizeof(path)) { - res = -ENAMETOOLONG; - continue; - } - if ((res = weakjack_load_by_path(jack, path)) == 0) - break; - } - } else { - res = weakjack_load_by_path(jack, lib); + + if (pathlen < 0 || (size_t) pathlen >= sizeof(path)) + continue; + + if ((res = weakjack_load_by_path(jack, path)) == 0) + break; } return res; } diff --git a/src/pipewire/impl-module.c b/src/pipewire/impl-module.c index 22c8e91fa..d670f883a 100644 --- a/src/pipewire/impl-module.c +++ b/src/pipewire/impl-module.c @@ -154,6 +154,9 @@ pw_context_load_module(struct pw_context *context, NULL }; + while ((p = strstr(name, "../")) != NULL) + name = p + 3; + pw_log_info("%p: name:%s args:%s", context, name, args); module_dir = getenv("PIPEWIRE_MODULE_DIR"); diff --git a/src/pipewire/pipewire.c b/src/pipewire/pipewire.c index 4451fa525..bccd48f35 100644 --- a/src/pipewire/pipewire.c +++ b/src/pipewire/pipewire.c @@ -232,6 +232,9 @@ static struct spa_handle *load_spa_handle(const char *lib, if (lib == NULL) lib = sup->support_lib; + while ((p = strstr(lib, "../")) != NULL) + lib = p + 3; + pw_log_debug("load lib:'%s' factory-name:'%s'", lib, factory_name); plugin = NULL;