mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-01 22:58:47 -04:00
switch-on-connect: Add blacklisting
Add a new module argument, blacklist, which is a regular expression. If the sink/source name matches the provided blacklist regex, don't automatically switch to it. By default, no devices are blacklisted. Add a new function to check whenever a regex pattern is valid, plus extra NULL asserts in pa_match.
This commit is contained in:
parent
c90894b4d5
commit
ad16d77dfe
3 changed files with 48 additions and 0 deletions
|
|
@ -40,17 +40,20 @@ PA_MODULE_LOAD_ONCE(true);
|
|||
PA_MODULE_USAGE(
|
||||
"only_from_unavailable=<boolean, only switch from unavailable ports> "
|
||||
"ignore_virtual=<boolean, ignore new virtual sinks and sources, defaults to true> "
|
||||
"blacklist=<regex, ignore matching devices> "
|
||||
);
|
||||
|
||||
static const char* const valid_modargs[] = {
|
||||
"only_from_unavailable",
|
||||
"ignore_virtual",
|
||||
"blacklist",
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct userdata {
|
||||
bool only_from_unavailable;
|
||||
bool ignore_virtual;
|
||||
char *blacklist;
|
||||
};
|
||||
|
||||
static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
|
||||
|
|
@ -80,6 +83,12 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
|
|||
}
|
||||
}
|
||||
|
||||
/* Ignore sinks matching the blacklist regex */
|
||||
if (u->blacklist && (pa_match(u->blacklist, sink->name) > 0)) {
|
||||
pa_log_info("Refusing to switch to blacklisted sink %s", sink->name);
|
||||
return PA_HOOK_OK;
|
||||
}
|
||||
|
||||
/* Ignore virtual sinks if not configured otherwise on the command line */
|
||||
if (u->ignore_virtual && !(sink->flags & PA_SINK_HARDWARE)) {
|
||||
pa_log_debug("Refusing to switch to virtual sink");
|
||||
|
|
@ -157,6 +166,12 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
|
|||
return PA_HOOK_OK;
|
||||
}
|
||||
|
||||
/* Ignore sources matching the blacklist regex */
|
||||
if (u->blacklist && (pa_match(u->blacklist, source->name) > 0)) {
|
||||
pa_log_info("Refusing to switch to blacklisted source %s", source->name);
|
||||
return PA_HOOK_OK;
|
||||
}
|
||||
|
||||
/* Ignore virtual sources if not configured otherwise on the command line */
|
||||
if (u->ignore_virtual && !(source->flags & PA_SOURCE_HARDWARE)) {
|
||||
pa_log_debug("Refusing to switch to virtual source");
|
||||
|
|
@ -234,6 +249,15 @@ int pa__init(pa_module*m) {
|
|||
goto fail;
|
||||
}
|
||||
|
||||
u->blacklist = pa_modargs_get_value(ma, "blacklist", NULL);
|
||||
if (u->blacklist != NULL && pa_is_regex_valid(u->blacklist)) {
|
||||
/* String returned above will be freed with modargs, duplicate it */
|
||||
u->blacklist = pa_xstrdup(u->blacklist);
|
||||
} else if (u->blacklist != NULL) {
|
||||
pa_log_error("A blacklist pattern was provided but is not a valid regex.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pa_modargs_free(ma);
|
||||
return 0;
|
||||
|
||||
|
|
@ -254,5 +278,8 @@ void pa__done(pa_module*m) {
|
|||
if (!(u = m->userdata))
|
||||
return;
|
||||
|
||||
if (u->blacklist)
|
||||
pa_xfree(u->blacklist);
|
||||
|
||||
pa_xfree(u);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -784,12 +784,16 @@ void pa_reset_priority(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Check whenever any substring in v matches the provided regex. */
|
||||
int pa_match(const char *expr, const char *v) {
|
||||
#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
|
||||
int k;
|
||||
regex_t re;
|
||||
int r;
|
||||
|
||||
pa_assert(expr);
|
||||
pa_assert(v);
|
||||
|
||||
if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
|
@ -814,6 +818,22 @@ int pa_match(const char *expr, const char *v) {
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Check whenever the provided regex pattern is valid. */
|
||||
bool pa_is_regex_valid(const char *expr) {
|
||||
#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
|
||||
regex_t re;
|
||||
|
||||
if (expr == NULL || regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
regfree(&re);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Try to parse a boolean string value.*/
|
||||
int pa_parse_boolean(const char *v) {
|
||||
pa_assert(v);
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
|||
char *pa_truncate_utf8(char *c, size_t l);
|
||||
|
||||
int pa_match(const char *expr, const char *v);
|
||||
bool pa_is_regex_valid(const char *expr);
|
||||
|
||||
char *pa_getcwd(void);
|
||||
char *pa_make_path_absolute(const char *p);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue