153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2004-2006 Lennart Poettering 553a5a1b3Sopenharmony_ci 653a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 753a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as published 853a5a1b3Sopenharmony_ci by the Free Software Foundation; either version 2.1 of the License, 953a5a1b3Sopenharmony_ci or (at your option) any later version. 1053a5a1b3Sopenharmony_ci 1153a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1253a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1353a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1453a5a1b3Sopenharmony_ci General Public License for more details. 1553a5a1b3Sopenharmony_ci 1653a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1753a5a1b3Sopenharmony_ci along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1853a5a1b3Sopenharmony_ci***/ 1953a5a1b3Sopenharmony_ci 2053a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2153a5a1b3Sopenharmony_ci#include <config.h> 2253a5a1b3Sopenharmony_ci#endif 2353a5a1b3Sopenharmony_ci 2453a5a1b3Sopenharmony_ci#include <stdlib.h> 2553a5a1b3Sopenharmony_ci#include <string.h> 2653a5a1b3Sopenharmony_ci#include <string.h> 2753a5a1b3Sopenharmony_ci#include <stdio.h> 2853a5a1b3Sopenharmony_ci 2953a5a1b3Sopenharmony_ci#include <pulse/xmalloc.h> 3053a5a1b3Sopenharmony_ci 3153a5a1b3Sopenharmony_ci#include <pulsecore/source.h> 3253a5a1b3Sopenharmony_ci#include <pulsecore/sink.h> 3353a5a1b3Sopenharmony_ci#include <pulsecore/core-subscribe.h> 3453a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h> 3553a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3653a5a1b3Sopenharmony_ci 3753a5a1b3Sopenharmony_ci#include "namereg.h" 3853a5a1b3Sopenharmony_ci 3953a5a1b3Sopenharmony_cistruct namereg_entry { 4053a5a1b3Sopenharmony_ci pa_namereg_type_t type; 4153a5a1b3Sopenharmony_ci char *name; 4253a5a1b3Sopenharmony_ci void *data; 4353a5a1b3Sopenharmony_ci}; 4453a5a1b3Sopenharmony_ci 4553a5a1b3Sopenharmony_cistatic bool is_valid_char(char c) { 4653a5a1b3Sopenharmony_ci return 4753a5a1b3Sopenharmony_ci (c >= 'a' && c <= 'z') || 4853a5a1b3Sopenharmony_ci (c >= 'A' && c <= 'Z') || 4953a5a1b3Sopenharmony_ci (c >= '0' && c <= '9') || 5053a5a1b3Sopenharmony_ci c == '.' || 5153a5a1b3Sopenharmony_ci c == '-' || 5253a5a1b3Sopenharmony_ci c == '_'; 5353a5a1b3Sopenharmony_ci} 5453a5a1b3Sopenharmony_ci 5553a5a1b3Sopenharmony_cibool pa_namereg_is_valid_name(const char *name) { 5653a5a1b3Sopenharmony_ci const char *c; 5753a5a1b3Sopenharmony_ci 5853a5a1b3Sopenharmony_ci pa_assert(name); 5953a5a1b3Sopenharmony_ci 6053a5a1b3Sopenharmony_ci if (*name == 0) 6153a5a1b3Sopenharmony_ci return false; 6253a5a1b3Sopenharmony_ci 6353a5a1b3Sopenharmony_ci for (c = name; *c && (c-name < PA_NAME_MAX); c++) 6453a5a1b3Sopenharmony_ci if (!is_valid_char(*c)) 6553a5a1b3Sopenharmony_ci return false; 6653a5a1b3Sopenharmony_ci 6753a5a1b3Sopenharmony_ci if (*c) 6853a5a1b3Sopenharmony_ci return false; 6953a5a1b3Sopenharmony_ci 7053a5a1b3Sopenharmony_ci return true; 7153a5a1b3Sopenharmony_ci} 7253a5a1b3Sopenharmony_ci 7353a5a1b3Sopenharmony_cibool pa_namereg_is_valid_name_or_wildcard(const char *name, pa_namereg_type_t type) { 7453a5a1b3Sopenharmony_ci 7553a5a1b3Sopenharmony_ci pa_assert(name); 7653a5a1b3Sopenharmony_ci 7753a5a1b3Sopenharmony_ci if (pa_namereg_is_valid_name(name)) 7853a5a1b3Sopenharmony_ci return true; 7953a5a1b3Sopenharmony_ci 8053a5a1b3Sopenharmony_ci if (type == PA_NAMEREG_SINK && 8153a5a1b3Sopenharmony_ci pa_streq(name, "@DEFAULT_SINK@")) 8253a5a1b3Sopenharmony_ci return true; 8353a5a1b3Sopenharmony_ci 8453a5a1b3Sopenharmony_ci if (type == PA_NAMEREG_SOURCE && 8553a5a1b3Sopenharmony_ci (pa_streq(name, "@DEFAULT_SOURCE@") || 8653a5a1b3Sopenharmony_ci pa_streq(name, "@DEFAULT_MONITOR@"))) 8753a5a1b3Sopenharmony_ci return true; 8853a5a1b3Sopenharmony_ci 8953a5a1b3Sopenharmony_ci return false; 9053a5a1b3Sopenharmony_ci} 9153a5a1b3Sopenharmony_ci 9253a5a1b3Sopenharmony_cichar* pa_namereg_make_valid_name(const char *name) { 9353a5a1b3Sopenharmony_ci const char *a; 9453a5a1b3Sopenharmony_ci char *b, *n; 9553a5a1b3Sopenharmony_ci 9653a5a1b3Sopenharmony_ci if (*name == 0) 9753a5a1b3Sopenharmony_ci return NULL; 9853a5a1b3Sopenharmony_ci 9953a5a1b3Sopenharmony_ci n = pa_xnew(char, strlen(name)+1); 10053a5a1b3Sopenharmony_ci 10153a5a1b3Sopenharmony_ci for (a = name, b = n; *a && (a-name < PA_NAME_MAX); a++, b++) 10253a5a1b3Sopenharmony_ci *b = (char) (is_valid_char(*a) ? *a : '_'); 10353a5a1b3Sopenharmony_ci 10453a5a1b3Sopenharmony_ci *b = 0; 10553a5a1b3Sopenharmony_ci 10653a5a1b3Sopenharmony_ci return n; 10753a5a1b3Sopenharmony_ci} 10853a5a1b3Sopenharmony_ci 10953a5a1b3Sopenharmony_ciconst char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, bool fail) { 11053a5a1b3Sopenharmony_ci struct namereg_entry *e; 11153a5a1b3Sopenharmony_ci char *n = NULL; 11253a5a1b3Sopenharmony_ci 11353a5a1b3Sopenharmony_ci pa_assert(c); 11453a5a1b3Sopenharmony_ci pa_assert(name); 11553a5a1b3Sopenharmony_ci pa_assert(data); 11653a5a1b3Sopenharmony_ci 11753a5a1b3Sopenharmony_ci if (!*name) 11853a5a1b3Sopenharmony_ci return NULL; 11953a5a1b3Sopenharmony_ci 12053a5a1b3Sopenharmony_ci if ((type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE || type == PA_NAMEREG_CARD) && 12153a5a1b3Sopenharmony_ci !pa_namereg_is_valid_name(name)) { 12253a5a1b3Sopenharmony_ci 12353a5a1b3Sopenharmony_ci if (fail) 12453a5a1b3Sopenharmony_ci return NULL; 12553a5a1b3Sopenharmony_ci 12653a5a1b3Sopenharmony_ci if (!(name = n = pa_namereg_make_valid_name(name))) 12753a5a1b3Sopenharmony_ci return NULL; 12853a5a1b3Sopenharmony_ci } 12953a5a1b3Sopenharmony_ci 13053a5a1b3Sopenharmony_ci if ((e = pa_hashmap_get(c->namereg, name)) && fail) { 13153a5a1b3Sopenharmony_ci pa_xfree(n); 13253a5a1b3Sopenharmony_ci return NULL; 13353a5a1b3Sopenharmony_ci } 13453a5a1b3Sopenharmony_ci 13553a5a1b3Sopenharmony_ci if (e) { 13653a5a1b3Sopenharmony_ci unsigned i; 13753a5a1b3Sopenharmony_ci size_t l = strlen(name); 13853a5a1b3Sopenharmony_ci char *k; 13953a5a1b3Sopenharmony_ci 14053a5a1b3Sopenharmony_ci if (l+4 > PA_NAME_MAX) { 14153a5a1b3Sopenharmony_ci pa_xfree(n); 14253a5a1b3Sopenharmony_ci return NULL; 14353a5a1b3Sopenharmony_ci } 14453a5a1b3Sopenharmony_ci 14553a5a1b3Sopenharmony_ci k = pa_xmalloc(l+4); 14653a5a1b3Sopenharmony_ci 14753a5a1b3Sopenharmony_ci for (i = 2; i <= 99; i++) { 14853a5a1b3Sopenharmony_ci pa_snprintf(k, l+4, "%s.%u", name, i); 14953a5a1b3Sopenharmony_ci 15053a5a1b3Sopenharmony_ci if (!(e = pa_hashmap_get(c->namereg, k))) 15153a5a1b3Sopenharmony_ci break; 15253a5a1b3Sopenharmony_ci } 15353a5a1b3Sopenharmony_ci 15453a5a1b3Sopenharmony_ci if (e) { 15553a5a1b3Sopenharmony_ci pa_xfree(n); 15653a5a1b3Sopenharmony_ci pa_xfree(k); 15753a5a1b3Sopenharmony_ci return NULL; 15853a5a1b3Sopenharmony_ci } 15953a5a1b3Sopenharmony_ci 16053a5a1b3Sopenharmony_ci pa_xfree(n); 16153a5a1b3Sopenharmony_ci n = k; 16253a5a1b3Sopenharmony_ci } 16353a5a1b3Sopenharmony_ci 16453a5a1b3Sopenharmony_ci e = pa_xnew(struct namereg_entry, 1); 16553a5a1b3Sopenharmony_ci e->type = type; 16653a5a1b3Sopenharmony_ci e->name = n ? n : pa_xstrdup(name); 16753a5a1b3Sopenharmony_ci e->data = data; 16853a5a1b3Sopenharmony_ci 16953a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->namereg, e->name, e) >= 0); 17053a5a1b3Sopenharmony_ci 17153a5a1b3Sopenharmony_ci return e->name; 17253a5a1b3Sopenharmony_ci} 17353a5a1b3Sopenharmony_ci 17453a5a1b3Sopenharmony_civoid pa_namereg_unregister(pa_core *c, const char *name) { 17553a5a1b3Sopenharmony_ci struct namereg_entry *e; 17653a5a1b3Sopenharmony_ci 17753a5a1b3Sopenharmony_ci pa_assert(c); 17853a5a1b3Sopenharmony_ci pa_assert(name); 17953a5a1b3Sopenharmony_ci 18053a5a1b3Sopenharmony_ci pa_assert_se(e = pa_hashmap_remove(c->namereg, name)); 18153a5a1b3Sopenharmony_ci pa_xfree(e->name); 18253a5a1b3Sopenharmony_ci pa_xfree(e); 18353a5a1b3Sopenharmony_ci} 18453a5a1b3Sopenharmony_ci 18553a5a1b3Sopenharmony_civoid* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) { 18653a5a1b3Sopenharmony_ci struct namereg_entry *e; 18753a5a1b3Sopenharmony_ci uint32_t idx; 18853a5a1b3Sopenharmony_ci pa_assert(c); 18953a5a1b3Sopenharmony_ci 19053a5a1b3Sopenharmony_ci if (type == PA_NAMEREG_SOURCE && (!name || pa_streq(name, "@DEFAULT_SOURCE@"))) { 19153a5a1b3Sopenharmony_ci return c->default_source; 19253a5a1b3Sopenharmony_ci 19353a5a1b3Sopenharmony_ci } else if (type == PA_NAMEREG_SINK && (!name || pa_streq(name, "@DEFAULT_SINK@"))) { 19453a5a1b3Sopenharmony_ci return c->default_sink; 19553a5a1b3Sopenharmony_ci 19653a5a1b3Sopenharmony_ci } else if (type == PA_NAMEREG_SOURCE && name && pa_streq(name, "@DEFAULT_MONITOR@")) { 19753a5a1b3Sopenharmony_ci if (c->default_sink) 19853a5a1b3Sopenharmony_ci return c->default_sink->monitor_source; 19953a5a1b3Sopenharmony_ci else 20053a5a1b3Sopenharmony_ci return NULL; 20153a5a1b3Sopenharmony_ci } 20253a5a1b3Sopenharmony_ci 20353a5a1b3Sopenharmony_ci if (!name) 20453a5a1b3Sopenharmony_ci return NULL; 20553a5a1b3Sopenharmony_ci 20653a5a1b3Sopenharmony_ci if ((type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE || type == PA_NAMEREG_CARD) && 20753a5a1b3Sopenharmony_ci !pa_namereg_is_valid_name(name)) 20853a5a1b3Sopenharmony_ci return NULL; 20953a5a1b3Sopenharmony_ci 21053a5a1b3Sopenharmony_ci if ((e = pa_hashmap_get(c->namereg, name))) 21153a5a1b3Sopenharmony_ci if (e->type == type) 21253a5a1b3Sopenharmony_ci return e->data; 21353a5a1b3Sopenharmony_ci 21453a5a1b3Sopenharmony_ci if (pa_atou(name, &idx) < 0) 21553a5a1b3Sopenharmony_ci return NULL; 21653a5a1b3Sopenharmony_ci 21753a5a1b3Sopenharmony_ci if (type == PA_NAMEREG_SINK) 21853a5a1b3Sopenharmony_ci return pa_idxset_get_by_index(c->sinks, idx); 21953a5a1b3Sopenharmony_ci else if (type == PA_NAMEREG_SOURCE) 22053a5a1b3Sopenharmony_ci return pa_idxset_get_by_index(c->sources, idx); 22153a5a1b3Sopenharmony_ci else if (type == PA_NAMEREG_SAMPLE && c->scache) 22253a5a1b3Sopenharmony_ci return pa_idxset_get_by_index(c->scache, idx); 22353a5a1b3Sopenharmony_ci else if (type == PA_NAMEREG_CARD) 22453a5a1b3Sopenharmony_ci return pa_idxset_get_by_index(c->cards, idx); 22553a5a1b3Sopenharmony_ci 22653a5a1b3Sopenharmony_ci return NULL; 22753a5a1b3Sopenharmony_ci} 228