From 5844a33f0be1af942ee33feae38b9d46169fd61c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 4 Nov 2004 21:27:12 +0000 Subject: some commenting change alogrithm for checking for configuration files git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@273 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/Makefile.am | 4 +-- polyp/client-conf.c | 48 +++++++++++++++------------------ polyp/conf-parser.c | 8 +++--- polyp/conf-parser.h | 4 ++- polyp/daemon-conf.c | 76 +++++++++++++++++++++++----------------------------- polyp/daemon-conf.h | 1 + polyp/module-match.c | 19 +++++++++++-- polyp/util.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++--- polyp/util.h | 5 +++- 9 files changed, 156 insertions(+), 84 deletions(-) (limited to 'polyp') diff --git a/polyp/Makefile.am b/polyp/Makefile.am index e97ed94d..1ed1b28f 100644 --- a/polyp/Makefile.am +++ b/polyp/Makefile.am @@ -24,9 +24,7 @@ modlibdir=$(libdir)/polypaudio-@PA_MAJORMINOR@ AM_CFLAGS=-D_GNU_SOURCE -I$(top_srcdir) $(PTHREAD_CFLAGS) AM_CFLAGS+=-DDLSEARCHPATH=\"$(modlibdir)\" -AM_CFLAGS+=-DDEFAULT_SCRIPT_FILE=\"$(polypconfdir)/default.pa\" -AM_CFLAGS+=-DDEFAULT_CONFIG_FILE=\"$(polypconfdir)/daemon.conf\" -AM_CFLAGS+=-DDEFAULT_CLIENT_CONFIG_FILE=\"$(polypconfdir)/client.conf\" +AM_CFLAGS+=-DDEFAULT_CONFIG_DIR=\"$(polypconfdir)\" AM_CFLAGS+=-DPOLYPAUDIO_BINARY=\"$(bindir)/polypaudio\" AM_LDADD=$(PTHREAD_LIBS) -lm diff --git a/polyp/client-conf.c b/polyp/client-conf.c index b8a4c778..47c5b49c 100644 --- a/polyp/client-conf.c +++ b/polyp/client-conf.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "client-conf.h" #include "xmalloc.h" @@ -29,13 +31,12 @@ #include "conf-parser.h" #include "util.h" -#ifndef DEFAULT_CLIENT_CONFIG_FILE -#define DEFAULT_CLIENT_CONFIG_FILE "/etc/polypaudio/client.conf" +#ifndef DEFAULT_CONFIG_DIR +#define DEFAULT_CONFIG_DIR "/etc/polypaudio" #endif -#ifndef DEFAULT_CLIENT_CONFIG_FILE_USER +#define DEFAULT_CLIENT_CONFIG_FILE DEFAULT_CONFIG_DIR"/client.conf" #define DEFAULT_CLIENT_CONFIG_FILE_USER ".polypaudio/client.conf" -#endif #define ENV_CLIENT_CONFIG_FILE "POLYP_CLIENTCONFIG" #define ENV_DEFAULT_SINK "POLYP_SINK" @@ -71,8 +72,9 @@ void pa_client_conf_free(struct pa_client_conf *c) { pa_xfree(c); } int pa_client_conf_load(struct pa_client_conf *c, const char *filename) { - char *def = NULL; - int r; + FILE *f = NULL; + char *fn = NULL; + int r = -1; struct pa_config_item table[] = { { "daemon-binary", pa_config_parse_string, NULL }, @@ -91,29 +93,23 @@ int pa_client_conf_load(struct pa_client_conf *c, const char *filename) { table[4].data = &c->default_server; table[5].data = &c->autospawn; - if (!filename) - filename = getenv(ENV_CLIENT_CONFIG_FILE); - - if (!filename) { - char *h; - - if ((h = getenv("HOME"))) { - def = pa_sprintf_malloc("%s/%s", h, DEFAULT_CLIENT_CONFIG_FILE_USER); - - if (!access(def, F_OK)) - filename = def; - else { - pa_xfree(def); - def = NULL; - } - } + f = filename ? + fopen((fn = pa_xstrdup(filename)), "r") : + pa_open_config_file(DEFAULT_CLIENT_CONFIG_FILE, DEFAULT_CLIENT_CONFIG_FILE_USER, ENV_CLIENT_CONFIG_FILE, &fn); + + if (!f && errno != EINTR) { + pa_log(__FILE__": WARNING: failed to open configuration file '%s': %s\n", filename, strerror(errno)); + goto finish; } + + r = pa_config_parse(fn, f, table, NULL); + +finish: + pa_xfree(fn); - if (!filename) - filename = DEFAULT_CLIENT_CONFIG_FILE; + if (f) + fclose(f); - r = pa_config_parse(filename, table, NULL); - pa_xfree(def); return r; } diff --git a/polyp/conf-parser.c b/polyp/conf-parser.c index 20e8e723..3d922c20 100644 --- a/polyp/conf-parser.c +++ b/polyp/conf-parser.c @@ -89,13 +89,13 @@ static int parse_line(const char *filename, unsigned line, const struct pa_confi } -int pa_config_parse(const char *filename, const struct pa_config_item *t, void *userdata) { - FILE *f; +int pa_config_parse(const char *filename, FILE *f, const struct pa_config_item *t, void *userdata) { int r = -1; unsigned line = 0; + int do_close = !f; assert(filename && t); - if (!(f = fopen(filename, "r"))) { + if (!f && !(f = fopen(filename, "r"))) { if (errno == ENOENT) { r = 0; goto finish; @@ -123,7 +123,7 @@ int pa_config_parse(const char *filename, const struct pa_config_item *t, void * finish: - if (f) + if (do_close && f) fclose(f); return r; diff --git a/polyp/conf-parser.h b/polyp/conf-parser.h index a0eb52d0..30330860 100644 --- a/polyp/conf-parser.h +++ b/polyp/conf-parser.h @@ -22,13 +22,15 @@ USA. ***/ +#include + struct pa_config_item { const char *lvalue; int (*parse)(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); void *data; }; -int pa_config_parse(const char *filename, const struct pa_config_item *t, void *userdata); +int pa_config_parse(const char *filename, FILE *f, const struct pa_config_item *t, void *userdata); int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); diff --git a/polyp/daemon-conf.c b/polyp/daemon-conf.c index 8a0f94ac..e87acd1d 100644 --- a/polyp/daemon-conf.c +++ b/polyp/daemon-conf.c @@ -36,21 +36,14 @@ #include "strbuf.h" #include "conf-parser.h" -#ifndef DEFAULT_SCRIPT_FILE -#define DEFAULT_SCRIPT_FILE "/etc/polypaudio/default.pa" +#ifndef DEFAULT_CONFIG_DIR +#define DEFAULT_CONFIG_DIR "/etc/polypaudio" #endif -#ifndef DEFAULT_SCRIPT_FILE_USER +#define DEFAULT_SCRIPT_FILE DEFAULT_CONFIG_DIR"/default.pa" #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 DEFAULT_CONFIG_DIR"/daemon.conf" #define DEFAULT_CONFIG_FILE_USER ".polypaudio/daemon.conf" -#endif #define ENV_SCRIPT_FILE "POLYP_SCRIPT" #define ENV_CONFIG_FILE "POLYP_CONFIG" @@ -71,31 +64,17 @@ static const struct pa_daemon_conf default_conf = { .dl_search_path = NULL, .default_script_file = NULL, .log_target = PA_LOG_SYSLOG, - .resample_method = SRC_SINC_FASTEST + .resample_method = SRC_SINC_FASTEST, + .config_file = NULL, }; -char* default_file(const char *envvar, const char *global, const char *local) { - char *p, *h; - - assert(envvar && global && local); - - if ((p = getenv(envvar))) - return pa_xstrdup(p); - - if ((h = getenv("HOME"))) { - p = pa_sprintf_malloc("%s/%s", h, local); - if (!access(p, F_OK)) - return p; - - pa_xfree(p); - } - - return pa_xstrdup(global); -} - struct pa_daemon_conf* pa_daemon_conf_new(void) { + FILE *f; struct pa_daemon_conf *c = pa_xmemdup(&default_conf, sizeof(default_conf)); - c->default_script_file = default_file(ENV_SCRIPT_FILE, DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER); + + if ((f = pa_open_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE, &c->default_script_file))) + fclose(f); + #ifdef DLSEARCHPATH c->dl_search_path = pa_xstrdup(DLSEARCHPATH); #endif @@ -107,6 +86,7 @@ void pa_daemon_conf_free(struct pa_daemon_conf *c) { pa_xfree(c->script_commands); pa_xfree(c->dl_search_path); pa_xfree(c->default_script_file); + pa_xfree(c->config_file); pa_xfree(c); } @@ -163,8 +143,8 @@ int parse_resample_method(const char *filename, unsigned line, const char *lvalu } int pa_daemon_conf_load(struct pa_daemon_conf *c, const char *filename) { - char *def = NULL; - int r; + int r = -1; + FILE *f = NULL; struct pa_config_item table[] = { { "verbose", pa_config_parse_bool, NULL }, @@ -195,11 +175,24 @@ int pa_daemon_conf_load(struct pa_daemon_conf *c, const char *filename) { table[10].data = c; table[11].data = c; - if (!filename) - filename = def = default_file(ENV_CONFIG_FILE, DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER); + pa_xfree(c->config_file); + c->config_file = NULL; + + f = filename ? + fopen(c->config_file = pa_xstrdup(filename), "r") : + pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file); + + if (!f && errno != EINTR) { + pa_log(__FILE__": WARNING: failed to open configuration file '%s': %s\n", filename, strerror(errno)); + goto finish; + } + + r = pa_config_parse(c->config_file, f, table, NULL); + +finish: + if (f) + fclose(f); - r = pa_config_parse(filename, table, NULL); - pa_xfree(def); return r; } @@ -220,7 +213,6 @@ int pa_daemon_conf_env(struct pa_daemon_conf *c) { char *pa_daemon_conf_dump(struct pa_daemon_conf *c) { struct pa_strbuf *s = pa_strbuf_new(); - char *d; static const char const* resample_methods[] = { "sinc-best-quality", @@ -230,8 +222,8 @@ char *pa_daemon_conf_dump(struct pa_daemon_conf *c) { "linear" }; - d = default_file(ENV_CONFIG_FILE, DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER); - pa_strbuf_printf(s, "### Default configuration file: %s ###\n", d); + if (c->config_file) + pa_strbuf_printf(s, "### Read from configuration file: %s ###\n", c->config_file); pa_strbuf_printf(s, "verbose = %i\n", !!c->verbose); pa_strbuf_printf(s, "daemonize = %i\n", !!c->daemonize); @@ -248,7 +240,5 @@ char *pa_daemon_conf_dump(struct pa_daemon_conf *c) { 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); - return pa_strbuf_tostring_free(s); } diff --git a/polyp/daemon-conf.h b/polyp/daemon-conf.h index 8be989da..fc31117f 100644 --- a/polyp/daemon-conf.h +++ b/polyp/daemon-conf.h @@ -46,6 +46,7 @@ struct pa_daemon_conf { char *script_commands, *dl_search_path, *default_script_file; enum pa_log_target log_target; int resample_method; + char *config_file; }; struct pa_daemon_conf* pa_daemon_conf_new(void); diff --git a/polyp/module-match.c b/polyp/module-match.c index 6689cc59..176c338f 100644 --- a/polyp/module-match.c +++ b/polyp/module-match.c @@ -48,6 +48,13 @@ PA_MODULE_VERSION(PACKAGE_VERSION) #define WHITESPACE "\n\r \t" +#ifndef DEFAULT_CONFIG_DIR +#define DEFAULT_CONFIG_DIR "/etc/polypaudio" +#endif + +#define DEFAULT_MATCH_TABLE_FILE DEFAULT_CONFIG_DIR"/match.table" +#define DEFAULT_MATCH_TABLE_FILE_USER ".polypaudio/.match.table" + static const char* const valid_modargs[] = { "table", NULL, @@ -69,9 +76,14 @@ static int load_rules(struct userdata *u, const char *filename) { int n = 0; int ret = -1; struct rule *end = NULL; + char *fn = NULL; - if (!(f = fopen(filename, "r"))) { - pa_log(__FILE__": failed to open file '%s': %s\n", filename, strerror(errno)); + f = filename ? + fopen(fn = pa_xstrdup(filename), "r") : + pa_open_config_file(DEFAULT_MATCH_TABLE_FILE, DEFAULT_MATCH_TABLE_FILE_USER, NULL, &fn); + + if (!f) { + pa_log(__FILE__": failed to open file '%s': %s\n", fn, strerror(errno)); goto finish; } @@ -135,6 +147,9 @@ finish: if (f) fclose(f); + if (fn) + pa_xfree(fn); + return ret; } diff --git a/polyp/util.c b/polyp/util.c index 794ae514..6e97bae4 100644 --- a/polyp/util.c +++ b/polyp/util.c @@ -254,7 +254,7 @@ char *pa_get_host_name(char *s, size_t l) { } /* Return the home directory of the current user */ -char *pa_get_home(char *s, size_t l) { +char *pa_get_home_dir(char *s, size_t l) { char *e; char buf[1024]; struct passwd pw, *r; @@ -353,8 +353,7 @@ void pa_timeval_add(struct timeval *tv, pa_usec_t v) { /* Raise the priority of the current process as much as possible and sensible: set the nice level to -15 and enable realtime scheduling if -supportted.*/ - +supported.*/ void pa_raise_priority(void) { if (setpriority(PRIO_PROCESS, 0, NICE_LEVEL) < 0) @@ -381,6 +380,7 @@ void pa_raise_priority(void) { #endif } +/* Reset the priority to normal, inverting the changes made by pa_raise_priority() */ void pa_reset_priority(void) { #ifdef _POSIX_PRIORITY_SCHEDULING { @@ -394,6 +394,7 @@ void pa_reset_priority(void) { setpriority(PRIO_PROCESS, 0, 0); } +/* Set the FD_CLOEXEC flag for a fd */ int pa_fd_set_cloexec(int fd, int b) { int v; assert(fd >= 0); @@ -409,6 +410,9 @@ int pa_fd_set_cloexec(int fd, int b) { return 0; } +/* Return the binary file name of the current process. Works on Linux + * only. This shoul be used for eyecandy only, don't rely on return + * non-NULL! */ char *pa_get_binary_name(char *s, size_t l) { char path[PATH_MAX]; int i; @@ -424,6 +428,8 @@ char *pa_get_binary_name(char *s, size_t l) { return s; } +/* Return a pointer to the filename inside a path (which is the last + * component). */ char *pa_path_get_filename(const char *p) { char *fn; @@ -433,6 +439,7 @@ char *pa_path_get_filename(const char *p) { return (char*) p; } +/* Try to parse a boolean string value.*/ int pa_parse_boolean(const char *v) { if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on")) @@ -443,6 +450,10 @@ int pa_parse_boolean(const char *v) { return -1; } +/* Split the specified string wherever one of the strings in delimiter + * occurs. Each time it is called returns a newly allocated string + * with pa_xmalloc(). The variable state points to, should be + * initiallized to NULL before the first call. */ char *pa_split(const char *c, const char *delimiter, const char**state) { const char *current = *state ? *state : c; size_t l; @@ -459,8 +470,10 @@ char *pa_split(const char *c, const char *delimiter, const char**state) { return pa_xstrndup(current, l); } +/* What is interpreted as whitespace? */ #define WHITESPACE " \t\n" +/* Split a string into words. Otherwise similar to pa_split(). */ char *pa_split_spaces(const char *c, const char **state) { const char *current = *state ? *state : c; size_t l; @@ -476,6 +489,7 @@ char *pa_split_spaces(const char *c, const char **state) { return pa_xstrndup(current, l); } +/* Return the name of an UNIX signal. Similar to GNU's strsignal() */ const char *pa_strsignal(int sig) { switch(sig) { case SIGINT: return "SIGINT"; @@ -490,6 +504,7 @@ const char *pa_strsignal(int sig) { } } +/* Parse a libsamplrate compatible resampling implementation */ int pa_parse_resample_method(const char *string) { assert(string); @@ -507,6 +522,7 @@ int pa_parse_resample_method(const char *string) { return -1; } +/* Check whether the specified GID and the group name match */ static int is_group(gid_t gid, const char *name) { struct group group, *result = NULL; long n; @@ -548,6 +564,7 @@ finish: return r; } +/* Check the current user is member of the specified group */ int pa_uid_in_group(const char *name, gid_t *gid) { gid_t *gids, tgid; long n = sysconf(_SC_NGROUPS_MAX); @@ -584,6 +601,7 @@ finish: return r; } +/* Lock or unlock a file entirely. (advisory) */ int pa_lock_fd(int fd, int b) { struct flock flock; @@ -601,6 +619,7 @@ int pa_lock_fd(int fd, int b) { return 0; } +/* Remove trailing newlines from a string */ char* pa_strip_nl(char *s) { assert(s); @@ -608,6 +627,7 @@ char* pa_strip_nl(char *s) { return s; } +/* Create a temporary lock file and lock it. */ int pa_lock_lockfile(const char *fn) { int fd; assert(fn); @@ -630,7 +650,7 @@ fail: return -1; } - +/* Unlock a temporary lcok file */ int pa_unlock_lockfile(int fd) { int r = 0; assert(fd >= 0); @@ -648,3 +668,50 @@ int pa_unlock_lockfile(int fd) { return r; } +/* Try to open a configuration file. If "env" is specified, open the + * value of the specified environment variable. Otherwise look for a + * file "local" in the home directory or a file "global" in global + * file system. If "result" is non-NULL, a pointer to a newly + * allocated buffer containing the used configuration file is + * stored there.*/ +FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) { + const char *e; + char h[PATH_MAX]; + + if (env && (e = getenv(env))) { + if (result) + *result = pa_xstrdup(e); + return fopen(e, "r"); + } + + if (local && pa_get_home_dir(h, sizeof(h))) { + FILE *f; + char *l; + + l = pa_sprintf_malloc("%s/%s", h, local); + f = fopen(l, "r"); + + if (f || errno != ENOENT) { + if (result) + *result = l; + else + pa_xfree(l); + return f; + } + + pa_xfree(l); + } + + if (!global) { + if (result) + *result = NULL; + errno = ENOENT; + return NULL; + } + + if (result) + *result = pa_xstrdup(global); + + return fopen(global, "r"); +} + diff --git a/polyp/util.h b/polyp/util.h index 85da38d0..0299148e 100644 --- a/polyp/util.h +++ b/polyp/util.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "gcc-printf.h" #include "sample.h" @@ -46,7 +47,7 @@ char *pa_strlcpy(char *b, const char *s, size_t l); char *pa_get_user_name(char *s, size_t l); char *pa_get_host_name(char *s, size_t l); char *pa_get_binary_name(char *s, size_t l); -char *pa_get_home(char *s, size_t l); +char *pa_get_home_dir(char *s, size_t l); char *pa_path_get_filename(const char *p); @@ -78,4 +79,6 @@ int pa_lock_fd(int fd, int b); int pa_lock_lockfile(const char *fn); int pa_unlock_lockfile(int fd); +FILE *pa_open_config_file(const char *env, const char *global, const char *local, char **result); + #endif -- cgit