From 63b35d002aa6902618235e1a30dca37de52ff65e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 17 Sep 2004 19:45:44 +0000 Subject: new configuration subsystem git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@210 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/conf.c | 279 ++++++++++++++++++++++------------------------------------- 1 file changed, 104 insertions(+), 175 deletions(-) (limited to 'polyp/conf.c') diff --git a/polyp/conf.c b/polyp/conf.c index b74a5ede..efc471af 100644 --- a/polyp/conf.c +++ b/polyp/conf.c @@ -27,12 +27,34 @@ #include #include #include -#include +#include +#include #include "conf.h" #include "util.h" #include "xmalloc.h" #include "strbuf.h" +#include "confparser.h" + +#ifndef DEFAULT_SCRIPT_FILE +#define DEFAULT_SCRIPT_FILE "/etc/polypaudio/default.pa" +#endif + +#ifndef DEFAULT_SCRIPT_FILE_USER +#define DEFAULT_SCRIPT_FILE_USER ".polypaudio/default.pa" +#endif + +#ifndef DEFAULT_CONFIG_FILE +#define DEFAULT_CONFIG_FILE "/etc/polypaudio/daemon.conf" +#endif + +#ifndef DEFAULT_CONFIG_FILE_USER +#define DEFAULT_CONFIG_FILE_USER ".polypaudio/daemon.conf" +#endif + +#define ENV_SCRIPT_FILE "POLYP_SCRIPT" +#define ENV_CONFIG_FILE "POLYP_CONFIG" +#define ENV_DL_SEARCH_PATH "POLYP_DLPATH" static const struct pa_conf default_conf = { .cmd = PA_CMD_DAEMON, @@ -49,28 +71,9 @@ static const struct pa_conf default_conf = { .dl_search_path = NULL, .default_script_file = NULL, .log_target = PA_LOG_SYSLOG, + .resample_method = SRC_SINC_FASTEST }; -#define ENV_SCRIPT_FILE "POLYP_SCRIPT" -#define ENV_CONFIG_FILE "POLYP_CONFIG" -#define ENV_AUTOSPAWNED "POLYP_AUTOSPAWNED" - -#ifndef DEFAULT_SCRIPT_FILE -#define DEFAULT_SCRIPT_FILE "/etc/polypaudio/default.pa" -#endif - -#ifndef DEFAULT_CONFIG_FILE -#define DEFAULT_CONFIG_FILE "/etc/polypaudio/default.conf" -#endif - -#ifndef AUTOSPAWN_CONFIG_FILE -#define AUTOSPAWN_CONFIG_FILE "/etc/polypaudio/autospawn.conf" -#endif - -#define DEFAULT_SCRIPT_FILE_LOCAL ".polypaudio.pa" -#define DEFAULT_CONFIG_FILE_LOCAL ".polypaudio.conf" -#define AUTOSPAWN_CONFIG_FILE_LOCAL ".polypaudio-autospawn.conf" - char* default_file(const char *envvar, const char *global, const char *local) { char *p, *h; @@ -80,9 +83,8 @@ char* default_file(const char *envvar, const char *global, const char *local) { return pa_xstrdup(p); if ((h = getenv("HOME"))) { - struct stat st; p = pa_sprintf_malloc("%s/%s", h, local); - if (stat(p, &st) >= 0) + if (!access(p, F_OK)) return p; pa_xfree(p); @@ -91,26 +93,12 @@ char* default_file(const char *envvar, const char *global, const char *local) { return pa_xstrdup(global); } -char *default_config_file(void) { - char *b; - int autospawned = 0; - - if ((b = getenv(ENV_AUTOSPAWNED))) - autospawned = pa_parse_boolean(b) > 0; - - return default_file(ENV_CONFIG_FILE, - autospawned ? AUTOSPAWN_CONFIG_FILE : DEFAULT_CONFIG_FILE, - autospawned ? AUTOSPAWN_CONFIG_FILE_LOCAL : DEFAULT_CONFIG_FILE_LOCAL); - -} - -char *default_script_file(void) { - return default_file(ENV_SCRIPT_FILE, DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_LOCAL); -} - struct pa_conf* pa_conf_new(void) { struct pa_conf *c = pa_xmemdup(&default_conf, sizeof(default_conf)); - c->default_script_file = default_script_file(); + c->default_script_file = default_file(ENV_SCRIPT_FILE, DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER); +#ifdef DLSEARCHPATH + c->dl_search_path = pa_xstrdup(DLSEARCHPATH); +#endif return c; } @@ -122,166 +110,104 @@ void pa_conf_free(struct pa_conf *c) { pa_xfree(c); } -#define WHITESPACE " \t\n" -#define COMMENTS "#;\n" - -#define PARSE_BOOLEAN(t, v) \ - do { \ - if (!strcmp(lvalue, t)) { \ - int b; \ - if ((b = pa_parse_boolean(rvalue)) < 0) \ - goto fail; \ - c->v = b; \ - return 0; \ - } \ - } while (0) - -#define PARSE_STRING(t, v) \ - do { \ - if (!strcmp(lvalue, t)) { \ - pa_xfree(c->v); \ - c->v = *rvalue ? pa_xstrdup(rvalue) : NULL; \ - return 0; \ - } \ - } while (0) - -#define PARSE_INTEGER(t, v) \ - do { \ - if (!strcmp(lvalue, t)) { \ - char *x = NULL; \ - int i = strtol(rvalue, &x, 0); \ - if (!x || *x) \ - goto fail; \ - c->v = i; \ - return 0; \ - } \ - } while(0) - -static int next_assignment(struct pa_conf *c, char *lvalue, char *rvalue, unsigned n) { - PARSE_BOOLEAN("daemonize", daemonize); - PARSE_BOOLEAN("fail", fail); - PARSE_BOOLEAN("verbose", verbose); - PARSE_BOOLEAN("high-priority", high_priority); - PARSE_BOOLEAN("disallow-module-loading", disallow_module_loading); - - PARSE_INTEGER("exit-idle-time", exit_idle_time); - PARSE_INTEGER("module-idle-time", module_idle_time); - PARSE_INTEGER("scache-idle-time", scache_idle_time); +int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { + struct pa_conf *c = data; + assert(filename && lvalue && rvalue && data); - PARSE_STRING("dl-search-path", dl_search_path); - PARSE_STRING("default-script-file", default_script_file); - - if (!strcmp(lvalue, "log-target")) { - if (!strcmp(rvalue, "auto")) - c->auto_log_target = 1; - else if (!strcmp(rvalue, "syslog")) { - c->auto_log_target = 0; - c->log_target = PA_LOG_SYSLOG; - } else if (!strcmp(rvalue, "stderr")) { - c->auto_log_target = 0; - c->log_target = PA_LOG_STDERR; - } else - goto fail; - - return 0; + if (!strcmp(rvalue, "auto")) + c->auto_log_target = 1; + else if (!strcmp(rvalue, "syslog")) { + c->auto_log_target = 0; + c->log_target = PA_LOG_SYSLOG; + } else if (!strcmp(rvalue, "stderr")) { + c->auto_log_target = 0; + c->log_target = PA_LOG_STDERR; + } else { + pa_log(__FILE__": [%s:%u] Invalid log target '%s'.\n", filename, line, rvalue); + return -1; } - -fail: - pa_log(__FILE__": line %u: parse error.\n", n); - return -1; -} - -#undef PARSE_STRING -#undef PARSE_BOOLEAN - -static int in_string(char c, const char *s) { - for (; *s; s++) - if (*s == c) - return 1; return 0; } -static char *strip(char *s) { - char *b = s+strspn(s, WHITESPACE); - char *e, *l = NULL; - - for (e = b; *e; e++) - if (!in_string(*e, WHITESPACE)) - l = e; - - if (l) - *(l+1) = 0; - - return b; -} - -static int parse_line(struct pa_conf *conf, char *l, unsigned n) { - char *e, *c, *b = l+strspn(l, WHITESPACE); - - if ((c = strpbrk(b, COMMENTS))) - *c = 0; - - if (!*b) - return 0; - - if (!(e = strchr(b, '='))) { - pa_log(__FILE__": line %u: missing '='.\n", n); +int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { + struct pa_conf *c = data; + assert(filename && lvalue && rvalue && data); + + if (!strcmp(rvalue, "sinc-best-quality")) + c->resample_method = SRC_SINC_BEST_QUALITY; + else if (!strcmp(rvalue, "sinc-medium-quality")) + c->resample_method = SRC_SINC_MEDIUM_QUALITY; + else if (!strcmp(rvalue, "sinc-fastest")) + c->resample_method = SRC_SINC_FASTEST; + else if (!strcmp(rvalue, "zero-order-hold")) + c->resample_method = SRC_ZERO_ORDER_HOLD; + else if (!strcmp(rvalue, "linear")) + c->resample_method = SRC_LINEAR; + else { + pa_log(__FILE__": [%s:%u] Inavalid resample method '%s'.\n", filename, line, rvalue); return -1; } - *e = 0; - e++; - - return next_assignment(conf, strip(b), strip(e), n); + return 0; } - int pa_conf_load(struct pa_conf *c, const char *filename) { - FILE *f; - int r = 0; - unsigned n = 0; char *def = NULL; - assert(c); + int r; + const struct pa_config_item table[] = { + { "verbose", pa_config_parse_bool, &c->verbose }, + { "daemonize", pa_config_parse_bool, &c->daemonize }, + { "fail", pa_config_parse_bool, &c->fail }, + { "high-priority", pa_config_parse_bool, &c->high_priority }, + { "disallow-module-loading", pa_config_parse_bool, &c->disallow_module_loading }, + { "exit-idle-time", pa_config_parse_int, &c->exit_idle_time }, + { "module-idle-time", pa_config_parse_int, &c->module_idle_time }, + { "scache-idle-time", pa_config_parse_int, &c->scache_idle_time }, + { "dl-search-path", pa_config_parse_string, &c->dl_search_path }, + { "default-script-file", pa_config_parse_string, &c->default_script_file }, + { "log-target", parse_log_target, c }, + { "resample-method", parse_resample_method, c }, + { NULL, NULL, NULL }, + }; + if (!filename) - filename = def = default_config_file(); + filename = def = default_file(ENV_CONFIG_FILE, DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER); + + r = pa_config_parse(filename, table, NULL); + pa_xfree(def); + return r; +} - if (!(f = fopen(filename, "r"))) { - if (errno != ENOENT) - pa_log(__FILE__": WARNING: failed to open configuration file '%s': %s\n", filename, strerror(errno)); +int pa_conf_env(struct pa_conf *c) { + char *e; - goto finish; + if ((e = getenv(ENV_DL_SEARCH_PATH))) { + pa_xfree(c->dl_search_path); + c->dl_search_path = pa_xstrdup(e); } - - while (!feof(f)) { - char l[256]; - if (!fgets(l, sizeof(l), f)) { - if (!feof(f)) - pa_log(__FILE__": WARNING: failed to read configuration file '%s': %s\n", filename, strerror(errno)); - - break; - } - - if (parse_line(c, l, ++n) < 0) - r = -1; + if ((e = getenv(ENV_SCRIPT_FILE))) { + pa_xfree(c->default_script_file); + c->default_script_file = pa_xstrdup(e); } - -finish: - if (f) - fclose(f); - - pa_xfree(def); - - return r; + return 0; } char *pa_conf_dump(struct pa_conf *c) { struct pa_strbuf *s = pa_strbuf_new(); char *d; - d = default_config_file(); + static const char const* resample_methods[] = { + "sinc-best-quality", + "sinc-medium-quality", + "sinc-fastest", + "zero-order-hold", + "linear" + }; + + d = default_file(ENV_CONFIG_FILE, DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER); pa_strbuf_printf(s, "### Default configuration file: %s ###\n", d); pa_strbuf_printf(s, "verbose = %i\n", !!c->verbose); @@ -295,6 +221,9 @@ char *pa_conf_dump(struct pa_conf *c) { pa_strbuf_printf(s, "dl-search-path = %s\n", c->dl_search_path ? c->dl_search_path : ""); pa_strbuf_printf(s, "default-script-file = %s\n", c->default_script_file); pa_strbuf_printf(s, "log-target = %s\n", c->auto_log_target ? "auto" : (c->log_target == PA_LOG_SYSLOG ? "syslog" : "stderr")); + + assert(c->resample_method <= 4 && c->resample_method >= 0); + pa_strbuf_printf(s, "resample-method = %s\n", resample_methods[c->resample_method]); pa_xfree(d); -- cgit