summaryrefslogtreecommitdiffstats
path: root/polyp/conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'polyp/conf.c')
-rw-r--r--polyp/conf.c279
1 files changed, 104 insertions, 175 deletions
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 <stdio.h>
#include <string.h>
#include <assert.h>
-#include <sys/stat.h>
+#include <unistd.h>
+#include <samplerate.h>
#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);