diff options
38 files changed, 467 insertions, 280 deletions
| diff --git a/configure.ac b/configure.ac index 3ab9491f..5a4a4646 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@  # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.  AC_PREREQ(2.57) -AC_INIT([polypaudio],[0.7],[mzcbylcnhqvb (at) 0pointer (dot) de]) +AC_INIT([polypaudio],[0.7.1],[mzcbylcnhqvb (at) 0pointer (dot) de])  AC_CONFIG_SRCDIR([polyp/main.c])  AC_CONFIG_HEADERS([config.h])  AM_INIT_AUTOMAKE([foreign -Wall]) @@ -125,6 +125,12 @@ AC_SUBST(GLIB12_LIBS)  AC_SUBST(HAVE_GLIB12)  AM_CONDITIONAL([HAVE_GLIB12], [test "x$HAVE_GLIB12" = x1]) +PKG_CHECK_MODULES(HOWL, [ howl >= 0.9.8 ], HAVE_HOWL=1, HAVE_HOWL=0) +AC_SUBST(HOWL_CFLAGS) +AC_SUBST(HOWL_LIBS) +AC_SUBST(HAVE_HOWL) +AM_CONDITIONAL([HAVE_HOWL], [test "x$HAVE_HOWL" = x1]) +  AC_PATH_PROG([M4], [m4 gm4], [no])  if test "x$M4" = xno ; then     AC_MSG_ERROR([m4 missing]) diff --git a/polyp/Makefile.am b/polyp/Makefile.am index 7338b9e6..83b5670a 100644 --- a/polyp/Makefile.am +++ b/polyp/Makefile.am @@ -156,7 +156,8 @@ SYMDEF_FILES= \  		module-tunnel-sink-symdef.h \  		module-tunnel-source-symdef.h \  		module-null-sink-symdef.h \ -		module-esound-sink-symdef.h +		module-esound-sink-symdef.h \ +		module-zeroconf-publish-symdef.h  EXTRA_DIST+=$(SYMDEF_FILES)  BUILT_SOURCES+=$(SYMDEF_FILES) @@ -596,6 +597,24 @@ module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la  module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)  endif +### HOWL modules +if HAVE_HOWL +modlib_LTLIBRARIES+= \ +		libhowl-wrap.la \ +		module-zeroconf-publish.la + +libhowl_wrap_la_SOURCES = howl-wrap.c howl-wrap.h +libhowl_wrap_la_LDFLAGS = -avoid-version +libhowl_wrap_la_LIBADD = $(AM_LIBADD) $(HOWL_LIBS) +libhowl_wrap_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS) + +module_zeroconf_publish_la_SOURCES = module-zeroconf-publish.c +module_zeroconf_publish_la_LDFLAGS = -module -avoid-version +module_zeroconf_publish_la_LIBADD = $(AM_LIBADD) $(HOWL_LIBS) libhowl-wrap.la +module_zeroconf_publish_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS) + +endif +  ### GLIB 2.0 support  if HAVE_GLIB20 diff --git a/polyp/caps.c b/polyp/caps.c index 93fca89f..01ed1519 100644 --- a/polyp/caps.c +++ b/polyp/caps.c @@ -45,7 +45,7 @@ void pa_drop_root(void) {      if (uid == 0 || geteuid() != 0)          return; -    /*     pa_log(__FILE__": dropping root rights.\n"); */ +    pa_log_info(__FILE__": dropping root rights.\n");  #if defined(HAVE_SETRESUID)      setresuid(uid, uid, uid); @@ -76,7 +76,7 @@ int pa_limit_caps(void) {      if (cap_set_proc(caps) < 0)          goto fail; -/*     pa_log(__FILE__": dropped capabilities successfully.\n"); */ +    pa_log_info(__FILE__": dropped capabilities successfully.\n");       r = 0; diff --git a/polyp/cli-command.c b/polyp/cli-command.c index 72e04bf8..0e8e09a5 100644 --- a/polyp/cli-command.c +++ b/polyp/cli-command.c @@ -48,45 +48,50 @@  #include "xmalloc.h"  #include "sound-file-stream.h"  #include "props.h" +#include "util.h"  struct command {      const char *name; -    int (*proc) (struct pa_core *c, struct pa_tokenizer*t, struct pa_strbuf *buf, int *fail, int *verbose); +    int (*proc) (struct pa_core *c, struct pa_tokenizer*t, struct pa_strbuf *buf, int *fail);      const char *help;      unsigned args;  }; +#define INCLUDE_META ".include" +#define FAIL_META ".fail" +#define NOFAIL_META ".nofail" +  /* Prototypes for all available commands */ -static int pa_cli_command_exit(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_help(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_modules(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_clients(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_sinks(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_sources(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_sink_inputs(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_source_outputs(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_stat(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_info(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_load(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_unload(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_sink_volume(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_sink_input_volume(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_sink_default(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_source_default(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_kill_client(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_kill_sink_input(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_kill_source_output(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_scache_play(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_scache_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_scache_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_scache_load(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_scache_load_dir(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_play_file(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_autoload_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_autoload_add(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_autoload_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_dump(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); -static int pa_cli_command_list_props(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose); +static int pa_cli_command_exit(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_help(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_modules(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_clients(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_sinks(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_sources(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_sink_inputs(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_source_outputs(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_stat(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_info(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_load(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_unload(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_sink_volume(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_sink_input_volume(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_sink_default(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_source_default(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_kill_client(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_kill_sink_input(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_kill_source_output(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_scache_play(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_scache_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_scache_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_scache_load(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_scache_load_dir(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_play_file(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_autoload_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_autoload_add(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_autoload_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_dump(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail); +static int pa_cli_command_list_props(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail);  /* A method table for all available commands */ @@ -134,22 +139,21 @@ static const char whitespace[] = " \t\n\r";  static const char linebreak[] = "\n\r";  static uint32_t parse_index(const char *n) { -    long index; -    char *x; -    index = strtol(n, &x, 0); -    if (!x || *x != 0 || index < 0) +    uint32_t index; + +    if (pa_atou(n, &index) < 0)          return (uint32_t) PA_IDXSET_INVALID; -    return (uint32_t) index; +    return index;  } -static int pa_cli_command_exit(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_exit(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      assert(c && c->mainloop && t);      c->mainloop->quit(c->mainloop, 0);      return 0;  } -static int pa_cli_command_help(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_help(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const struct command*command;      assert(c && t && buf); @@ -161,7 +165,7 @@ static int pa_cli_command_help(struct pa_core *c, struct pa_tokenizer *t, struct      return 0;  } -static int pa_cli_command_modules(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_modules(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char *s;      assert(c && t);      s = pa_module_list_to_string(c); @@ -171,7 +175,7 @@ static int pa_cli_command_modules(struct pa_core *c, struct pa_tokenizer *t, str      return 0;  } -static int pa_cli_command_clients(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_clients(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char *s;      assert(c && t);      s = pa_client_list_to_string(c); @@ -181,7 +185,7 @@ static int pa_cli_command_clients(struct pa_core *c, struct pa_tokenizer *t, str      return 0;  } -static int pa_cli_command_sinks(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_sinks(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char *s;      assert(c && t);      s = pa_sink_list_to_string(c); @@ -191,7 +195,7 @@ static int pa_cli_command_sinks(struct pa_core *c, struct pa_tokenizer *t, struc      return 0;  } -static int pa_cli_command_sources(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_sources(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char *s;      assert(c && t);      s = pa_source_list_to_string(c); @@ -201,7 +205,7 @@ static int pa_cli_command_sources(struct pa_core *c, struct pa_tokenizer *t, str      return 0;  } -static int pa_cli_command_sink_inputs(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_sink_inputs(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char *s;      assert(c && t);      s = pa_sink_input_list_to_string(c); @@ -211,7 +215,7 @@ static int pa_cli_command_sink_inputs(struct pa_core *c, struct pa_tokenizer *t,      return 0;  } -static int pa_cli_command_source_outputs(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_source_outputs(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char *s;      assert(c && t);      s = pa_source_output_list_to_string(c); @@ -221,7 +225,7 @@ static int pa_cli_command_source_outputs(struct pa_core *c, struct pa_tokenizer      return 0;  } -static int pa_cli_command_stat(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_stat(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char s[256];      assert(c && t); @@ -249,24 +253,23 @@ static int pa_cli_command_stat(struct pa_core *c, struct pa_tokenizer *t, struct      return 0;  } -static int pa_cli_command_info(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_info(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      assert(c && t); -    pa_cli_command_stat(c, t, buf, fail, verbose); -    pa_cli_command_modules(c, t, buf, fail, verbose); -    pa_cli_command_sinks(c, t, buf, fail, verbose); -    pa_cli_command_sources(c, t, buf, fail, verbose); -    pa_cli_command_clients(c, t, buf, fail, verbose); -    pa_cli_command_sink_inputs(c, t, buf, fail, verbose); -    pa_cli_command_source_outputs(c, t, buf, fail, verbose); -    pa_cli_command_scache_list(c, t, buf, fail, verbose); -    pa_cli_command_autoload_list(c, t, buf, fail, verbose); +    pa_cli_command_stat(c, t, buf, fail); +    pa_cli_command_modules(c, t, buf, fail); +    pa_cli_command_sinks(c, t, buf, fail); +    pa_cli_command_sources(c, t, buf, fail); +    pa_cli_command_clients(c, t, buf, fail); +    pa_cli_command_sink_inputs(c, t, buf, fail); +    pa_cli_command_source_outputs(c, t, buf, fail); +    pa_cli_command_scache_list(c, t, buf, fail); +    pa_cli_command_autoload_list(c, t, buf, fail);      return 0;  } -static int pa_cli_command_load(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_load(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      struct pa_module *m;      const char *name; -    char txt[256];      assert(c && t);      if (!(name = pa_tokenizer_get(t, 1))) { @@ -279,14 +282,10 @@ static int pa_cli_command_load(struct pa_core *c, struct pa_tokenizer *t, struct          return -1;      } -    if (*verbose) { -        snprintf(txt, sizeof(txt), "Module successfully loaded, index: %u.\n", m->index); -        pa_strbuf_puts(buf, txt); -    }      return 0;  } -static int pa_cli_command_unload(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_unload(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      struct pa_module *m;      uint32_t index;      const char *i; @@ -308,11 +307,10 @@ static int pa_cli_command_unload(struct pa_core *c, struct pa_tokenizer *t, stru      return 0;  } -static int pa_cli_command_sink_volume(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_sink_volume(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n, *v; -    char *x = NULL;      struct pa_sink *sink; -    long volume; +    uint32_t volume;      if (!(n = pa_tokenizer_get(t, 1))) {          pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); @@ -324,8 +322,7 @@ static int pa_cli_command_sink_volume(struct pa_core *c, struct pa_tokenizer *t,          return -1;      } -    volume = strtol(v, &x, 0); -    if (!x || *x != 0 || volume < 0) { +    if (pa_atou(v, &volume) < 0) {          pa_strbuf_puts(buf, "Failed to parse volume.\n");          return -1;      } @@ -339,12 +336,11 @@ static int pa_cli_command_sink_volume(struct pa_core *c, struct pa_tokenizer *t,      return 0;  } -static int pa_cli_command_sink_input_volume(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_sink_input_volume(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n, *v;      struct pa_sink_input *si; -    long volume; +    uint32_t volume;      uint32_t index; -    char *x;      if (!(n = pa_tokenizer_get(t, 1))) {          pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n"); @@ -361,9 +357,7 @@ static int pa_cli_command_sink_input_volume(struct pa_core *c, struct pa_tokeniz          return -1;      } -    x = NULL; -    volume = strtol(v, &x, 0); -    if (!x || *x != 0 || volume < 0) { +    if (pa_atou(v, &volume) < 0) {          pa_strbuf_puts(buf, "Failed to parse volume.\n");          return -1;      } @@ -377,7 +371,7 @@ static int pa_cli_command_sink_input_volume(struct pa_core *c, struct pa_tokeniz      return 0;  } -static int pa_cli_command_sink_default(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_sink_default(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n;      assert(c && t); @@ -390,7 +384,7 @@ static int pa_cli_command_sink_default(struct pa_core *c, struct pa_tokenizer *t      return 0;  } -static int pa_cli_command_source_default(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_source_default(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n;      assert(c && t); @@ -403,7 +397,7 @@ static int pa_cli_command_source_default(struct pa_core *c, struct pa_tokenizer      return 0;  } -static int pa_cli_command_kill_client(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_kill_client(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n;      struct pa_client *client;      uint32_t index; @@ -428,7 +422,7 @@ static int pa_cli_command_kill_client(struct pa_core *c, struct pa_tokenizer *t,      return 0;  } -static int pa_cli_command_kill_sink_input(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_kill_sink_input(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n;      struct pa_sink_input *sink_input;      uint32_t index; @@ -453,7 +447,7 @@ static int pa_cli_command_kill_sink_input(struct pa_core *c, struct pa_tokenizer      return 0;  } -static int pa_cli_command_kill_source_output(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_kill_source_output(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n;      struct pa_source_output *source_output;      uint32_t index; @@ -478,7 +472,7 @@ static int pa_cli_command_kill_source_output(struct pa_core *c, struct pa_tokeni      return 0;  } -static int pa_cli_command_scache_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_scache_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char *s;      assert(c && t);      s = pa_scache_list_to_string(c); @@ -488,10 +482,10 @@ static int pa_cli_command_scache_list(struct pa_core *c, struct pa_tokenizer *t,      return 0;  } -static int pa_cli_command_scache_play(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_scache_play(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n, *sink_name;      struct pa_sink *sink; -    assert(c && t && buf && fail && verbose); +    assert(c && t && buf && fail);      if (!(n = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) {          pa_strbuf_puts(buf, "You need to specify a sample name and a sink name.\n"); @@ -511,9 +505,9 @@ static int pa_cli_command_scache_play(struct pa_core *c, struct pa_tokenizer *t,      return 0;  } -static int pa_cli_command_scache_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_scache_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *n; -    assert(c && t && buf && fail && verbose); +    assert(c && t && buf && fail);      if (!(n = pa_tokenizer_get(t, 1))) {          pa_strbuf_puts(buf, "You need to specify a sample name.\n"); @@ -528,10 +522,10 @@ static int pa_cli_command_scache_remove(struct pa_core *c, struct pa_tokenizer *      return 0;  } -static int pa_cli_command_scache_load(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_scache_load(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *fname, *n;      int r; -    assert(c && t && buf && fail && verbose); +    assert(c && t && buf && fail);      if (!(fname = pa_tokenizer_get(t, 2)) || !(n = pa_tokenizer_get(t, 1))) {          pa_strbuf_puts(buf, "You need to specify a file name and a sample name.\n"); @@ -549,9 +543,9 @@ static int pa_cli_command_scache_load(struct pa_core *c, struct pa_tokenizer *t,      return 0;  } -static int pa_cli_command_scache_load_dir(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_scache_load_dir(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *pname; -    assert(c && t && buf && fail && verbose); +    assert(c && t && buf && fail);      if (!(pname = pa_tokenizer_get(t, 1))) {          pa_strbuf_puts(buf, "You need to specify a path name.\n"); @@ -566,10 +560,10 @@ static int pa_cli_command_scache_load_dir(struct pa_core *c, struct pa_tokenizer      return 0;  } -static int pa_cli_command_play_file(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_play_file(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *fname, *sink_name;      struct pa_sink *sink; -    assert(c && t && buf && fail && verbose); +    assert(c && t && buf && fail);      if (!(fname = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) {          pa_strbuf_puts(buf, "You need to specify a file name and a sink name.\n"); @@ -585,9 +579,9 @@ static int pa_cli_command_play_file(struct pa_core *c, struct pa_tokenizer *t, s      return pa_play_file(sink, fname, PA_VOLUME_NORM);  } -static int pa_cli_command_autoload_add(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_autoload_add(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *a, *b; -    assert(c && t && buf && fail && verbose); +    assert(c && t && buf && fail);      if (!(a = pa_tokenizer_get(t, 1)) || !(b = pa_tokenizer_get(t, 2))) {          pa_strbuf_puts(buf, "You need to specify a device name, a filename or a module name and optionally module arguments\n"); @@ -599,9 +593,9 @@ static int pa_cli_command_autoload_add(struct pa_core *c, struct pa_tokenizer *t      return 0;  } -static int pa_cli_command_autoload_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_autoload_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      const char *name; -    assert(c && t && buf && fail && verbose); +    assert(c && t && buf && fail);      if (!(name = pa_tokenizer_get(t, 1))) {          pa_strbuf_puts(buf, "You need to specify a device name\n"); @@ -616,7 +610,7 @@ static int pa_cli_command_autoload_remove(struct pa_core *c, struct pa_tokenizer      return 0;          } -static int pa_cli_command_autoload_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_autoload_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      char *s;      assert(c && t);      s = pa_autoload_list_to_string(c); @@ -626,13 +620,13 @@ static int pa_cli_command_autoload_list(struct pa_core *c, struct pa_tokenizer *      return 0;  } -static int pa_cli_command_list_props(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_list_props(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      assert(c && t);      pa_property_dump(c, buf);      return 0;  } -static int pa_cli_command_dump(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) { +static int pa_cli_command_dump(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail) {      struct pa_module *m;      struct pa_sink *s;      int nl; @@ -724,7 +718,7 @@ static int pa_cli_command_dump(struct pa_core *c, struct pa_tokenizer *t, struct  } -int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail, int *verbose) { +int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail) {      const char *cs;      cs = s+strspn(s, whitespace); @@ -732,28 +726,18 @@ int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strb      if (*cs == '#' || !*cs)          return 0;      else if (*cs == '.') { -        static const char fail_meta[] = ".fail"; -        static const char nofail_meta[] = ".nofail"; -        static const char verbose_meta[] = ".verbose"; -        static const char noverbose_meta[] = ".noverbose"; - -        if (!strcmp(cs, verbose_meta)) -            *verbose = 1; -        else if (!strcmp(cs, noverbose_meta)) -            *verbose = 0; -        else if (!strcmp(cs, fail_meta)) +        if (!strcmp(cs, FAIL_META))              *fail = 1; -        else if (!strcmp(cs, nofail_meta)) +        else if (!strcmp(cs, NOFAIL_META))              *fail = 0;          else {              size_t l; -            static const char include_meta[] = ".include";              l = strcspn(cs, whitespace); -            if (l == sizeof(include_meta)-1 && !strncmp(cs, include_meta, l)) { +            if (l == sizeof(INCLUDE_META)-1 && !strncmp(cs, INCLUDE_META, l)) {                  const char *filename = cs+l+strspn(cs+l, whitespace); -                if (pa_cli_command_execute_file(c, filename, buf, fail, verbose) < 0) +                if (pa_cli_command_execute_file(c, filename, buf, fail) < 0)                      if (*fail) return -1;              } else {                  pa_strbuf_printf(buf, "Invalid meta command: %s\n", cs); @@ -772,7 +756,7 @@ int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strb                  int ret;                  struct pa_tokenizer *t = pa_tokenizer_new(cs, command->args);                  assert(t); -                ret = command->proc(c, t, buf, fail, verbose); +                ret = command->proc(c, t, buf, fail);                  pa_tokenizer_free(t);                  unknown = 0; @@ -792,7 +776,7 @@ int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strb      return 0;  } -int pa_cli_command_execute_file(struct pa_core *c, const char *fn, struct pa_strbuf *buf, int *fail, int *verbose) { +int pa_cli_command_execute_file(struct pa_core *c, const char *fn, struct pa_strbuf *buf, int *fail) {      char line[256];      FILE *f = NULL;      int ret = -1; @@ -805,20 +789,14 @@ int pa_cli_command_execute_file(struct pa_core *c, const char *fn, struct pa_str          goto fail;      } -    if (*verbose) -        pa_strbuf_printf(buf, "Executing file: '%s'\n", fn); -      while (fgets(line, sizeof(line), f)) {          char *e = line + strcspn(line, linebreak);          *e = 0; -        if (pa_cli_command_execute_line(c, line, buf, fail, verbose) < 0 && *fail) +        if (pa_cli_command_execute_line(c, line, buf, fail) < 0 && *fail)              goto fail;      } -    if (*verbose) -        pa_strbuf_printf(buf, "Executed file: '%s'\n", fn); -      ret = 0;  fail: @@ -828,16 +806,16 @@ fail:      return ret;  } -int pa_cli_command_execute(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail, int *verbose) { +int pa_cli_command_execute(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail) {      const char *p; -    assert(c && s && buf && fail && verbose); +    assert(c && s && buf && fail);      p = s;      while (*p) {          size_t l = strcspn(p, linebreak);          char *line = pa_xstrndup(p, l); -        if (pa_cli_command_execute_line(c, line, buf, fail, verbose) < 0&& *fail) { +        if (pa_cli_command_execute_line(c, line, buf, fail) < 0&& *fail) {              pa_xfree(line);              return -1;          } diff --git a/polyp/cli-command.h b/polyp/cli-command.h index 4887c55e..7af9d014 100644 --- a/polyp/cli-command.h +++ b/polyp/cli-command.h @@ -27,15 +27,14 @@  /* Execute a single CLI command. Write the results to the string   * buffer *buf. If *fail is non-zero the function will return -1 when - * one or more of the executed commands failed. If *verbose is - * non-zero the command is executed verbosely. Both *verbose and *fail + * one or more of the executed commands failed. *fail   * may be modified by the function call. */ -int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail, int *verbose); +int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail);  /* Execute a whole file of CLI commands */ -int pa_cli_command_execute_file(struct pa_core *c, const char *fn, struct pa_strbuf *buf, int *fail, int *verbose); +int pa_cli_command_execute_file(struct pa_core *c, const char *fn, struct pa_strbuf *buf, int *fail);  /* Split the specified string into lines and run pa_cli_command_execute_line() for each. */ -int pa_cli_command_execute(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail, int *verbose); +int pa_cli_command_execute(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail);  #endif diff --git a/polyp/cli.c b/polyp/cli.c index 7780d03d..04fbb7e0 100644 --- a/polyp/cli.c +++ b/polyp/cli.c @@ -55,7 +55,7 @@ struct pa_cli {      struct pa_client *client; -    int fail, verbose, kill_requested, defer_kill; +    int fail, kill_requested, defer_kill;  };  static void line_callback(struct pa_ioline *line, const char *s, void *userdata); @@ -85,7 +85,6 @@ struct pa_cli* pa_cli_new(struct pa_core *core, struct pa_iochannel *io, struct      pa_ioline_puts(c->line, "Welcome to polypaudio! Use \"help\" for usage information.\n"PROMPT);      c->fail = c->kill_requested = c->defer_kill = 0; -    c->verbose = 1;      return c;  } @@ -129,7 +128,7 @@ static void line_callback(struct pa_ioline *line, const char *s, void *userdata)      buf = pa_strbuf_new();      assert(buf);      c->defer_kill++; -    pa_cli_command_execute_line(c->core, s, buf, &c->fail, &c->verbose); +    pa_cli_command_execute_line(c->core, s, buf, &c->fail);      c->defer_kill--;      pa_ioline_puts(line, p = pa_strbuf_tostring_free(buf));      pa_xfree(p); diff --git a/polyp/client.c b/polyp/client.c index 22c7197a..40f5e385 100644 --- a/polyp/client.c +++ b/polyp/client.c @@ -50,7 +50,7 @@ struct pa_client *pa_client_new(struct pa_core *core, const char *protocol_name,      r = pa_idxset_put(core->clients, c, &c->index);      assert(c->index != PA_IDXSET_INVALID && r >= 0); -    pa_log(__FILE__": created %u \"%s\"\n", c->index, c->name); +    pa_log_info(__FILE__": created %u \"%s\"\n", c->index, c->name);      pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index);      pa_core_check_quit(core); @@ -65,7 +65,7 @@ void pa_client_free(struct pa_client *c) {      pa_core_check_quit(c->core); -    pa_log(__FILE__": freed %u \"%s\"\n", c->index, c->name); +    pa_log_info(__FILE__": freed %u \"%s\"\n", c->index, c->name);      pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);      pa_xfree(c->name);      pa_xfree(c->protocol_name); @@ -76,7 +76,7 @@ void pa_client_free(struct pa_client *c) {  void pa_client_kill(struct pa_client *c) {      assert(c);      if (!c->kill) { -        pa_log(__FILE__": kill() operation not implemented for client %u\n", c->index); +        pa_log_warn(__FILE__": kill() operation not implemented for client %u\n", c->index);          return;      } diff --git a/polyp/client.h b/polyp/client.h index 58c5ee31..324bb27c 100644 --- a/polyp/client.h +++ b/polyp/client.h @@ -35,7 +35,7 @@ struct pa_client {      struct pa_module *owner;      char *name;      struct pa_core *core; -    const char *protocol_name; +    char *protocol_name;      void (*kill)(struct pa_client *c);      void *userdata; diff --git a/polyp/cmdline.c b/polyp/cmdline.c index a39f6ca6..0951725a 100644 --- a/polyp/cmdline.c +++ b/polyp/cmdline.c @@ -43,7 +43,7 @@ enum {      ARG_DUMP_MODULES,      ARG_DAEMONIZE,      ARG_FAIL, -    ARG_VERBOSE, +    ARG_LOG_LEVEL,      ARG_HIGH_PRIORITY,      ARG_DISALLOW_MODULE_LOADING,      ARG_EXIT_IDLE_TIME, @@ -67,7 +67,8 @@ static struct option long_options[] = {      {"dump-modules",                0, 0, ARG_DUMP_MODULES},      {"daemonize",                   2, 0, ARG_DAEMONIZE},      {"fail",                        2, 0, ARG_FAIL}, -    {"verbose",                     2, 0, ARG_VERBOSE}, +    {"verbose",                     2, 0, ARG_LOG_LEVEL}, +    {"log-level",                   2, 0, ARG_LOG_LEVEL},      {"high-priority",               2, 0, ARG_HIGH_PRIORITY},      {"disallow-module-loading",     2, 0, ARG_DISALLOW_MODULE_LOADING},      {"exit-idle-time",              2, 0, ARG_EXIT_IDLE_TIME}, @@ -104,7 +105,6 @@ void pa_cmdline_help(const char *argv0) {             "OPTIONS:\n"             "  -D, --daemonize[=BOOL]                Daemonize after startup\n"             "      --fail[=BOOL]                     Quit when startup fails\n" -           "      --verbose[=BOOL]                  Be slightly more verbose\n"             "      --high-priority[=BOOL]            Try to set high process priority\n"             "                                        (only available as root)\n"             "      --disallow-module-loading[=BOOL]  Disallow module loading after startup\n" @@ -114,6 +114,8 @@ void pa_cmdline_help(const char *argv0) {             "                                        this time passed\n"             "      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"             "                                        this time passed\n" +           "      --log-level[=LEVEL]               Increase or set verbosity level\n" +           "  -v                                    Increase the verbosity level\n"              "      --log-target={auto,syslog,stderr} Specify the log target\n"             "  -p, --dl-search-path=PATH             Set the search path for dynamic shared\n"             "                                        objects (plugins)\n" @@ -143,7 +145,7 @@ int pa_cmdline_parse(struct pa_daemon_conf *conf, int argc, char *const argv [],      if (conf->script_commands)          pa_strbuf_puts(buf, conf->script_commands); -    while ((c = getopt_long(argc, argv, "L:F:ChDnp:k", long_options, NULL)) != -1) { +    while ((c = getopt_long(argc, argv, "L:F:ChDnp:kv", long_options, NULL)) != -1) {          switch (c) {              case ARG_HELP:              case 'h': @@ -200,11 +202,19 @@ int pa_cmdline_parse(struct pa_daemon_conf *conf, int argc, char *const argv [],                  }                  break; -            case ARG_VERBOSE: -                if ((conf->verbose = optarg ? pa_parse_boolean(optarg) : 1) < 0) { -                    pa_log(__FILE__": --verbose expects boolean argument\n"); -                    goto fail; +            case 'v': +            case ARG_LOG_LEVEL: + +                if (optarg) { +                    if (pa_daemon_conf_set_log_level(conf, optarg) < 0) { +                        pa_log(__FILE__": --log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error).\n"); +                        goto fail; +                    } +                } else { +                    if (conf->log_level < PA_LOG_LEVEL_MAX-1) +                        conf->log_level++;                  } +                                  break;              case ARG_HIGH_PRIORITY: diff --git a/polyp/conf-parser.c b/polyp/conf-parser.c index 35c4766e..b25508e2 100644 --- a/polyp/conf-parser.c +++ b/polyp/conf-parser.c @@ -135,17 +135,16 @@ finish:  }  int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { -    int *i = data, k; -    char *x = NULL; +    int *i = data; +    int32_t k;      assert(filename && lvalue && rvalue && data); -     -    k = strtol(rvalue, &x, 0);  -    if (!*rvalue || !x || *x) { + +    if (pa_atoi(rvalue, &k) < 0) {          pa_log(__FILE__": [%s:%u] Failed to parse numeric value: %s\n", filename, line, rvalue);          return -1;      } -    *i = k; +    *i = (int) k;      return 0;   } diff --git a/polyp/daemon-conf.c b/polyp/daemon-conf.c index 7753da6a..a6afd05a 100644 --- a/polyp/daemon-conf.c +++ b/polyp/daemon-conf.c @@ -53,7 +53,6 @@ static const struct pa_daemon_conf default_conf = {      .cmd = PA_CMD_DAEMON,      .daemonize = 0,      .fail = 1, -    .verbose = 0,      .high_priority = 0,      .disallow_module_loading = 0,      .exit_idle_time = -1, @@ -64,6 +63,7 @@ static const struct pa_daemon_conf default_conf = {      .dl_search_path = NULL,      .default_script_file = NULL,      .log_target = PA_LOG_SYSLOG, +    .log_level = PA_LOG_NOTICE,      .resample_method = PA_RESAMPLER_SRC_SINC_FASTEST,      .config_file = NULL,      .use_pid_file = 1 @@ -108,6 +108,31 @@ int pa_daemon_conf_set_log_target(struct pa_daemon_conf *c, const char *string)      return 0;  } +int pa_daemon_conf_set_log_level(struct pa_daemon_conf *c, const char *string) { +    uint32_t u; +    assert(c && string); + +    if (pa_atou(string, &u) >= 0) { +        if (u >= PA_LOG_LEVEL_MAX) +            return -1; + +        c->log_level = (enum pa_log_level) u; +    } else if (pa_startswith(string, "debug")) +        c->log_level = PA_LOG_DEBUG; +    else if (pa_startswith(string, "info")) +        c->log_level = PA_LOG_INFO; +    else if (pa_startswith(string, "notice")) +        c->log_level = PA_LOG_NOTICE; +    else if (pa_startswith(string, "warn")) +        c->log_level = PA_LOG_WARN; +    else if (pa_startswith(string, "err")) +        c->log_level = PA_LOG_ERROR; +    else +        return -1; + +    return 0; +} +  int pa_daemon_conf_set_resample_method(struct pa_daemon_conf *c, const char *string) {      int m;      assert(c && string); @@ -131,6 +156,18 @@ static int parse_log_target(const char *filename, unsigned line, const char *lva      return 0;  } +static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +    struct pa_daemon_conf *c = data; +    assert(filename && lvalue && rvalue && data); + +    if (pa_daemon_conf_set_log_level(c, rvalue) < 0) { +        pa_log(__FILE__": [%s:%u] Invalid log level '%s'.\n", filename, line, rvalue); +        return -1; +    } + +    return 0; +} +  static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {      struct pa_daemon_conf *c = data;      assert(filename && lvalue && rvalue && data); @@ -148,7 +185,6 @@ int pa_daemon_conf_load(struct pa_daemon_conf *c, const char *filename) {      FILE *f = NULL;      struct pa_config_item table[] = { -        { "verbose",                 pa_config_parse_bool,    NULL },          { "daemonize",               pa_config_parse_bool,    NULL },          { "fail",                    pa_config_parse_bool,    NULL },          { "high-priority",           pa_config_parse_bool,    NULL }, @@ -159,24 +195,27 @@ int pa_daemon_conf_load(struct pa_daemon_conf *c, const char *filename) {          { "dl-search-path",          pa_config_parse_string,  NULL },          { "default-script-file",     pa_config_parse_string,  NULL },          { "log-target",              parse_log_target,        NULL }, +        { "log-level",               parse_log_level,         NULL }, +        { "verbose",                 parse_log_level,         NULL },          { "resample-method",         parse_resample_method,   NULL },          { "use-pid-file",            pa_config_parse_bool,    NULL },          { NULL,                      NULL,                    NULL },      }; -    table[0].data = &c->verbose; -    table[1].data = &c->daemonize; -    table[2].data = &c->fail; -    table[3].data = &c->high_priority; -    table[4].data = &c->disallow_module_loading; -    table[5].data = &c->exit_idle_time; -    table[6].data = &c->module_idle_time; -    table[7].data = &c->scache_idle_time; -    table[8].data = &c->dl_search_path; -    table[9].data = &c->default_script_file; +    table[0].data = &c->daemonize; +    table[1].data = &c->fail; +    table[2].data = &c->high_priority; +    table[3].data = &c->disallow_module_loading; +    table[4].data = &c->exit_idle_time; +    table[5].data = &c->module_idle_time; +    table[6].data = &c->scache_idle_time; +    table[7].data = &c->dl_search_path; +    table[8].data = &c->default_script_file; +    table[9].data = c;      table[10].data = c;      table[11].data = c; -    table[12].data = &c->use_pid_file; +    table[12].data = c; +    table[13].data = &c->use_pid_file;      pa_xfree(c->config_file);      c->config_file = NULL; @@ -214,13 +253,22 @@ int pa_daemon_conf_env(struct pa_daemon_conf *c) {      return 0;  } +static const char* const log_level_to_string[] = { +    [PA_LOG_DEBUG] = "debug", +    [PA_LOG_INFO] = "info", +    [PA_LOG_NOTICE] = "notice", +    [PA_LOG_WARN] = "warning", +    [PA_LOG_ERROR] = "error" +}; +  char *pa_daemon_conf_dump(struct pa_daemon_conf *c) {      struct pa_strbuf *s = pa_strbuf_new();      if (c->config_file)          pa_strbuf_printf(s, "### Read from configuration file: %s ###\n", c->config_file); + +    assert(c->log_level <= PA_LOG_LEVEL_MAX); -    pa_strbuf_printf(s, "verbose = %i\n", !!c->verbose);      pa_strbuf_printf(s, "daemonize = %i\n", !!c->daemonize);      pa_strbuf_printf(s, "fail = %i\n", !!c->fail);      pa_strbuf_printf(s, "high-priority = %i\n", !!c->high_priority); @@ -231,6 +279,7 @@ char *pa_daemon_conf_dump(struct pa_daemon_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")); +    pa_strbuf_printf(s, "log-level = %s\n", log_level_to_string[c->log_level]);      pa_strbuf_printf(s, "resample-method = %s\n", pa_resample_method_to_string(c->resample_method));      pa_strbuf_printf(s, "use-pid-file = %i\n", c->use_pid_file); diff --git a/polyp/daemon-conf.h b/polyp/daemon-conf.h index f163400f..30137e8b 100644 --- a/polyp/daemon-conf.h +++ b/polyp/daemon-conf.h @@ -40,7 +40,6 @@ struct pa_daemon_conf {      enum pa_daemon_conf_cmd cmd;      int daemonize,          fail, -        verbose,          high_priority,          disallow_module_loading,          exit_idle_time, @@ -50,6 +49,7 @@ struct pa_daemon_conf {          use_pid_file;      char *script_commands, *dl_search_path, *default_script_file;      enum pa_log_target log_target; +    enum pa_log_level log_level;      int resample_method;      char *config_file;  }; @@ -74,6 +74,7 @@ int pa_daemon_conf_env(struct pa_daemon_conf *c);  /* Set these configuration variables in the structure by passing a string */  int pa_daemon_conf_set_log_target(struct pa_daemon_conf *c, const char *string); +int pa_daemon_conf_set_log_level(struct pa_daemon_conf *c, const char *string);  int pa_daemon_conf_set_resample_method(struct pa_daemon_conf *c, const char *string);  #endif diff --git a/polyp/dumpmodules.c b/polyp/dumpmodules.c index 1903fe00..1dc14edc 100644 --- a/polyp/dumpmodules.c +++ b/polyp/dumpmodules.c @@ -86,7 +86,7 @@ static int callback(const char *path, lt_ptr data) {          e = path;      if (strlen(e) > sizeof(PREFIX)-1 && !strncmp(e, PREFIX, sizeof(PREFIX)-1)) -        show_info(e, path, c->verbose ? long_info : short_info); +        show_info(e, path, c->log_level >= PA_LOG_INFO ? long_info : short_info);      return 0;  } diff --git a/polyp/log.c b/polyp/log.c index dc41dcd2..530fa691 100644 --- a/polyp/log.c +++ b/polyp/log.c @@ -34,7 +34,16 @@  static char *log_ident = NULL;  static enum pa_log_target log_target = PA_LOG_STDERR; -static void (*user_log_func)(const char *s) = NULL; +static void (*user_log_func)(enum pa_log_level l, const char *s) = NULL; +static enum pa_log_level maximal_level = PA_LOG_NOTICE; + +static const int level_to_syslog[] = { +    [PA_LOG_ERROR] = LOG_ERR, +    [PA_LOG_WARN] = LOG_WARNING, +    [PA_LOG_NOTICE] = LOG_NOTICE, +    [PA_LOG_INFO] = LOG_INFO, +    [PA_LOG_DEBUG] = LOG_DEBUG +};  void pa_log_set_ident(const char *p) {      if (log_ident) @@ -43,34 +52,85 @@ void pa_log_set_ident(const char *p) {      log_ident = pa_xstrdup(p);  } -void pa_log_set_target(enum pa_log_target t, void (*func)(const char*s)) { +void pa_log_set_maximal_level(enum pa_log_level l) { +    assert(l < PA_LOG_LEVEL_MAX); +    maximal_level = l; +} + +void pa_log_set_target(enum pa_log_target t, void (*func)(enum pa_log_level l, const char*s)) {      assert(t == PA_LOG_USER || !func);      log_target = t;      user_log_func = func;  } -void pa_log(const char *format, ...) { -    va_list ap; -    va_start(ap, format); +void pa_log_levelv(enum pa_log_level level, const char *format, va_list ap) { +    assert(level < PA_LOG_LEVEL_MAX); +    if (level > maximal_level) +        return; +          switch (log_target) {          case PA_LOG_STDERR:              vfprintf(stderr, format, ap);              break; +                      case PA_LOG_SYSLOG:              openlog(log_ident ? log_ident : "???", LOG_PID, LOG_USER); -            vsyslog(LOG_INFO, format, ap); +            vsyslog(level_to_syslog[level], format, ap);              closelog();              break; +                      case PA_LOG_USER: {              char *t = pa_vsprintf_malloc(format, ap);              assert(user_log_func); -            user_log_func(t); +            user_log_func(level, t);  	    pa_xfree(t);          } +                      case PA_LOG_NULL:              break;      } +} + +void pa_log_level(enum pa_log_level level, const char *format, ...) { +    va_list ap; +    va_start(ap, format); +    pa_log_levelv(level, format, ap); +    va_end(ap); +} + +void pa_log_debug(const char *format, ...) { +    va_list ap; +    va_start(ap, format); +    pa_log_levelv(PA_LOG_DEBUG, format, ap); +    va_end(ap); +} + +void pa_log_info(const char *format, ...) { +    va_list ap; +    va_start(ap, format); +    pa_log_levelv(PA_LOG_INFO, format, ap); +    va_end(ap); +} + +void pa_log_notice(const char *format, ...) { +    va_list ap; +    va_start(ap, format); +    pa_log_levelv(PA_LOG_INFO, format, ap); +    va_end(ap); +} + +void pa_log_warn(const char *format, ...) { +    va_list ap; +    va_start(ap, format); +    pa_log_levelv(PA_LOG_WARN, format, ap); +    va_end(ap); +} + +void pa_log_error(const char *format, ...) { +    va_list ap; +    va_start(ap, format); +    pa_log_levelv(PA_LOG_ERROR, format, ap);      va_end(ap);  } diff --git a/polyp/log.h b/polyp/log.h index cf55386c..fe2dad59 100644 --- a/polyp/log.h +++ b/polyp/log.h @@ -22,6 +22,7 @@    USA.  ***/ +#include <stdarg.h>  #include "gcc-printf.h"  /* A simple logging subsystem */ @@ -34,13 +35,35 @@ enum pa_log_target {      PA_LOG_NULL     /* to /dev/null */  }; +enum pa_log_level { +    PA_LOG_ERROR  = 0,    /* Error messages */ +    PA_LOG_WARN   = 1,    /* Warning messages */ +    PA_LOG_NOTICE = 2,    /* Notice messages */ +    PA_LOG_INFO   = 3,    /* Info messages */ +    PA_LOG_DEBUG  = 4,    /* debug message */ +    PA_LOG_LEVEL_MAX +}; +  /* Set an identifcation for the current daemon. Used when logging to syslog. */  void pa_log_set_ident(const char *p);  /* Set another log target. If t is PA_LOG_USER you may specify a function that is called every log string */ -void pa_log_set_target(enum pa_log_target t, void (*func)(const char*s)); +void pa_log_set_target(enum pa_log_target t, void (*func)(enum pa_log_level, const char*s)); + +/* Minimal log level */ +void pa_log_set_maximal_level(enum pa_log_level l);  /* Do a log line */ -void pa_log(const char *format, ...)  PA_GCC_PRINTF_ATTR(1,2); +void pa_log_debug(const char *format, ...)  PA_GCC_PRINTF_ATTR(1,2); +void pa_log_info(const char *format, ...)  PA_GCC_PRINTF_ATTR(1,2); +void pa_log_notice(const char *format, ...)  PA_GCC_PRINTF_ATTR(1,2); +void pa_log_warn(const char *format, ...)  PA_GCC_PRINTF_ATTR(1,2); +void pa_log_error(const char *format, ...)  PA_GCC_PRINTF_ATTR(1,2); + +void pa_log_level(enum pa_log_level level, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3); + +void pa_log_levelv(enum pa_log_level level, const char *format, va_list ap); + +#define pa_log pa_log_error  #endif diff --git a/polyp/main.c b/polyp/main.c index 0ba28e5a..f49232d4 100644 --- a/polyp/main.c +++ b/polyp/main.c @@ -64,7 +64,7 @@ int deny_severity = LOG_WARNING;  #endif  static void signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) { -    pa_log(__FILE__": Got signal %s.\n", pa_strsignal(sig)); +    pa_log_info(__FILE__": Got signal %s.\n", pa_strsignal(sig));      switch (sig) {          case SIGUSR1: @@ -108,7 +108,7 @@ static void signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e,                      default:                          return;                  } -                pa_log(c); +                pa_log_notice(c);                  pa_xfree(c);              } @@ -118,7 +118,7 @@ static void signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e,          case SIGINT:          case SIGTERM:          default: -            pa_log(__FILE__": Exiting.\n"); +            pa_log_info(__FILE__": Exiting.\n");              m->quit(m, 1);              return;      } @@ -150,7 +150,7 @@ int main(int argc, char *argv[]) {      suid_root = getuid() != 0 && geteuid() == 0;      if (suid_root && (pa_uid_in_group("realtime", &gid) <= 0 || gid >= 1000)) { -        pa_log(__FILE__": WARNING: called SUID root, but not in group 'realtime'.\n"); +        pa_log_warn(__FILE__": WARNING: called SUID root, but not in group 'realtime'.\n");          pa_drop_root();      } @@ -165,15 +165,16 @@ int main(int argc, char *argv[]) {      if (pa_daemon_conf_load(conf, NULL) < 0)          goto finish; -     +      if (pa_daemon_conf_env(conf) < 0)          goto finish; -     +      if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {          pa_log(__FILE__": failed to parse command line.\n");          goto finish;      } -     + +    pa_log_set_maximal_level(conf->log_level);      pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target, NULL);      if (conf->high_priority && conf->cmd == PA_CMD_DAEMON) @@ -215,11 +216,9 @@ int main(int argc, char *argv[]) {              pid_t pid;              if (pa_pid_file_check_running(&pid) < 0) { -                if (conf->verbose) -                    pa_log(__FILE__": daemon not running\n"); +                pa_log_info(__FILE__": daemon not running\n");              } else { -                if (conf->verbose) -                    pa_log(__FILE__": daemon running as PID %u\n", pid); +                pa_log_info(__FILE__": daemon running as PID %u\n", pid);                  retval = 0;              } @@ -268,8 +267,10 @@ int main(int argc, char *argv[]) {                  retval = 1;              } -            if (conf->verbose) -                pa_log(__FILE__": daemon startup %s.\n", retval ? "failed" : "succeeded"); +            if (retval) +                pa_log(__FILE__": daemon startup failed .\n"); +            else +                pa_log_info(__FILE__": daemon startup successful.\n");              goto finish;          } @@ -318,10 +319,10 @@ int main(int argc, char *argv[]) {      buf = pa_strbuf_new();      assert(buf);      if (conf->default_script_file) -        r = pa_cli_command_execute_file(c, conf->default_script_file, buf, &conf->fail, &conf->verbose); +        r = pa_cli_command_execute_file(c, conf->default_script_file, buf, &conf->fail);      if (r >= 0) -        r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail, &conf->verbose); +        r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);      pa_log(s = pa_strbuf_tostring_free(buf));      pa_xfree(s); @@ -345,10 +346,10 @@ int main(int argc, char *argv[]) {          c->scache_idle_time = conf->scache_idle_time;          c->resample_method = conf->resample_method; -        pa_log(__FILE__": Daemon startup complete.\n"); +        pa_log_info(__FILE__": Daemon startup complete.\n");          if (pa_mainloop_run(mainloop, &retval) < 0)              retval = 1; -        pa_log(__FILE__": Daemon shutdown initiated.\n"); +        pa_log_info(__FILE__": Daemon shutdown initiated.\n");      }      pa_core_free(c); @@ -357,7 +358,7 @@ int main(int argc, char *argv[]) {      pa_signal_done();      pa_mainloop_free(mainloop); -    pa_log(__FILE__": Daemon terminated.\n"); +    pa_log_info(__FILE__": Daemon terminated.\n");  finish: diff --git a/polyp/memblockq.c b/polyp/memblockq.c index 16c0da8e..3f2e4db1 100644 --- a/polyp/memblockq.c +++ b/polyp/memblockq.c @@ -58,7 +58,7 @@ struct pa_memblockq* pa_memblockq_new(size_t maxlength, size_t tlength, size_t b      bq->current_length = 0; -    /*pa_log(__FILE__": memblockq requested: maxlength=%u, tlength=%u, base=%u, prebuf=%u, minreq=%u\n", maxlength, tlength, base, prebuf, minreq);*/ +    pa_log_debug(__FILE__": memblockq requested: maxlength=%u, tlength=%u, base=%u, prebuf=%u, minreq=%u\n", maxlength, tlength, base, prebuf, minreq);      bq->base = base; @@ -83,7 +83,7 @@ struct pa_memblockq* pa_memblockq_new(size_t maxlength, size_t tlength, size_t b      bq->orig_prebuf = bq->prebuf; -    pa_log(__FILE__": memblockq sanitized: maxlength=%u, tlength=%u, base=%u, prebuf=%u, minreq=%u\n", bq->maxlength, bq->tlength, bq->base, bq->prebuf, bq->minreq); +    pa_log_debug(__FILE__": memblockq sanitized: maxlength=%u, tlength=%u, base=%u, prebuf=%u, minreq=%u\n", bq->maxlength, bq->tlength, bq->base, bq->prebuf, bq->minreq);      bq->mcalign = NULL; diff --git a/polyp/modargs.c b/polyp/modargs.c index 406f610f..9437d839 100644 --- a/polyp/modargs.c +++ b/polyp/modargs.c @@ -190,41 +190,27 @@ const char *pa_modargs_get_value(struct pa_modargs *ma, const char *key, const c  int pa_modargs_get_value_u32(struct pa_modargs *ma, const char *key, uint32_t *value) {      const char *v; -    char *e; -    unsigned long l;      assert(ma && key && value);      if (!(v = pa_modargs_get_value(ma, key, NULL)))          return 0; -    if (!*v) -        return -1; -     -    l = strtoul(v, &e, 0); -    if (*e) +    if (pa_atou(v, value) < 0)          return -1; -    *value = (uint32_t) l;      return 0;  }  int pa_modargs_get_value_s32(struct pa_modargs *ma, const char *key, int32_t *value) {      const char *v; -    char *e; -    signed long l;      assert(ma && key && value);      if (!(v = pa_modargs_get_value(ma, key, NULL)))          return 0; -    if (!*v) +    if (pa_atoi(v, value) < 0)          return -1; -     -    l = strtol(v, &e, 0); -    if (*e) -        return -1; - -    *value = (int32_t) l; +                  return 0;  } diff --git a/polyp/module-combine.c b/polyp/module-combine.c index 95bd958f..7b3c26dd 100644 --- a/polyp/module-combine.c +++ b/polyp/module-combine.c @@ -111,7 +111,7 @@ static void adjust_rates(struct userdata *u) {      target_latency = max_sink_latency > min_total_latency ? max_sink_latency : min_total_latency; -    pa_log(__FILE__": [%s] target latency is %0.0f usec.\n", u->sink->name, (float) target_latency); +    pa_log_info(__FILE__": [%s] target latency is %0.0f usec.\n", u->sink->name, (float) target_latency);      base_rate = u->sink->sample_spec.rate; @@ -124,9 +124,9 @@ static void adjust_rates(struct userdata *u) {              r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/ 1000000);          if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) -            pa_log(__FILE__": [%s] sample rates too different, not adjusting (%u vs. %u).\n", o->sink_input->name, base_rate, r); +            pa_log_warn(__FILE__": [%s] sample rates too different, not adjusting (%u vs. %u).\n", o->sink_input->name, base_rate, r);          else { -            pa_log(__FILE__": [%s] new rate is %u Hz; ratio is %0.3f; latency is %0.0f usec.\n", o->sink_input->name, r, (double) r / base_rate, (float) o->total_latency); +            pa_log_info(__FILE__": [%s] new rate is %u Hz; ratio is %0.3f; latency is %0.0f usec.\n", o->sink_input->name, r, (double) r / base_rate, (float) o->total_latency);              pa_sink_input_set_rate(o->sink_input, r);          }      } @@ -358,7 +358,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) {      }      if (u->n_outputs <= 1) -        pa_log(__FILE__": WARNING: no slave sinks specified.\n"); +        pa_log_warn(__FILE__": WARNING: no slave sinks specified.\n");      if (u->adjust_time > 0) {          gettimeofday(&tv, NULL); diff --git a/polyp/module-defs.h.m4 b/polyp/module-defs.h.m4 index 85eb64a2..2b9cdf9e 100644 --- a/polyp/module-defs.h.m4 +++ b/polyp/module-defs.h.m4 @@ -1,13 +1,16 @@  dnl $Id$  changecom(`/*', `*/')dnl -define(`module', patsubst(patsubst(fname, `-symdef.h$'), `[^0-9a-zA-Z]', `_'))dnl -define(`c_symbol', patsubst(module, `[^0-9a-zA-Z]', `_'))dnl -define(`c_macro', patsubst(module, `[^0-9a-zA-Z]', `'))dnl +define(`module_name', patsubst(patsubst(fname, `-symdef.h$'), `[^0-9a-zA-Z]', `_'))dnl +define(`c_symbol', patsubst(module_name, `[^0-9a-zA-Z]', `_'))dnl +define(`c_macro', patsubst(module_name, `[^0-9a-zA-Z]', `'))dnl  define(`incmacro', `foo'c_macro`symdeffoo')dnl -define(`gen_symbol', `#define $1 'module`_LTX_$1')dnl +define(`gen_symbol', `#define $1 'module_name`_LTX_$1')dnl  #ifndef incmacro  #define incmacro +#include "core.h" +#include "module.h" +  gen_symbol(pa__init)  gen_symbol(pa__done)  gen_symbol(pa__get_author) diff --git a/polyp/module-match.c b/polyp/module-match.c index 6f4fc38c..7fdc5f3e 100644 --- a/polyp/module-match.c +++ b/polyp/module-match.c @@ -88,8 +88,9 @@ static int load_rules(struct userdata *u, const char *filename) {      }      while (!feof(f)) { -        char *d, *v, *e = NULL; +        char *d, *v;          pa_volume_t volume; +        uint32_t k;          regex_t regex;          char ln[256];          struct rule *rule; @@ -114,14 +115,14 @@ static int load_rules(struct userdata *u, const char *filename) {          }          *d = 0; -         -        volume = (pa_volume_t) strtol(v, &e, 0); - -        if (!e || *e) { +        if (pa_atou(v, &k) < 0) {              pa_log(__FILE__": [%s:%u] failed to parse volume\n", filename, n);              goto finish;          } +        volume = (pa_volume_t) k; + +                  if (regcomp(®ex, ln, REG_EXTENDED|REG_NOSUB) != 0) {              pa_log(__FILE__": [%s:%u] invalid regular expression\n", filename, n);              goto finish; @@ -162,10 +163,8 @@ static void callback(struct pa_core *c, enum pa_subscription_event_type t, uint3      if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW))          return; -    if (!(si = pa_idxset_get_by_index(c->sink_inputs, index))) { -        pa_log(__FILE__": WARNING: failed to get sink input\n"); +    if (!(si = pa_idxset_get_by_index(c->sink_inputs, index)))          return; -    }      if (!si->name)          return; diff --git a/polyp/module-oss-mmap.c b/polyp/module-oss-mmap.c index 66daa77d..6fe4fa0c 100644 --- a/polyp/module-oss-mmap.c +++ b/polyp/module-oss-mmap.c @@ -289,7 +289,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) {              goto fail;          } -        pa_log(__FILE__": input -- %u fragments of size %u.\n", info.fragstotal, info.fragsize); +        pa_log_info(__FILE__": input -- %u fragments of size %u.\n", info.fragstotal, info.fragsize);          u->in_mmap_length = (u->in_fragment_size = info.fragsize) * (u->in_fragments = info.fragstotal);          if ((u->in_mmap = mmap(NULL, u->in_mmap_length, PROT_READ, MAP_SHARED, u->fd, 0)) == MAP_FAILED) { @@ -320,7 +320,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) {              goto fail;          } -        pa_log(__FILE__": output -- %u fragments of size %u.\n", info.fragstotal, info.fragsize); +        pa_log_info(__FILE__": output -- %u fragments of size %u.\n", info.fragstotal, info.fragsize);          u->out_mmap_length = (u->out_fragment_size = info.fragsize) * (u->out_fragments = info.fragstotal);          if ((u->out_mmap = mmap(NULL, u->out_mmap_length, PROT_WRITE, MAP_SHARED, u->fd, 0))  == MAP_FAILED) { diff --git a/polyp/module-oss.c b/polyp/module-oss.c index fe12b0bb..fa01876d 100644 --- a/polyp/module-oss.c +++ b/polyp/module-oss.c @@ -214,7 +214,7 @@ static pa_usec_t sink_get_latency_cb(struct pa_sink *s) {      assert(s && u && u->sink);      if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) { -        pa_log(__FILE__": device doesn't support SNDCTL_DSP_GETODELAY.\n"); +        pa_log_info(__FILE__": device doesn't support SNDCTL_DSP_GETODELAY.\n");          s->get_latency = NULL;          return 0;      } @@ -230,7 +230,7 @@ static pa_usec_t sink_get_latency_cb(struct pa_sink *s) {  static pa_usec_t source_get_latency_cb(struct pa_source *s) {      struct userdata *u = s->userdata;      audio_buf_info info; -    assert(s && u && u->sink); +    assert(s && u && u->source);      if (!u->use_getispace)          return 0; @@ -291,7 +291,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) {      if ((fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, NULL)) < 0)          goto fail; -    pa_log(__FILE__": device opened in %s mode.\n", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); +    pa_log_info(__FILE__": device opened in %s mode.\n", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR"));      if (nfrags >= 2 && frag_size >= 1) @@ -313,13 +313,13 @@ int pa__init(struct pa_core *c, struct pa_module*m) {      u->use_getospace = u->use_getispace = 0;      if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { -        pa_log(__FILE__": input -- %u fragments of size %u.\n", info.fragstotal, info.fragsize); +        pa_log_info(__FILE__": input -- %u fragments of size %u.\n", info.fragstotal, info.fragsize);          in_frag_size = info.fragsize;          u->use_getispace = 1;      }      if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) { -        pa_log(__FILE__": output -- %u fragments of size %u.\n", info.fragstotal, info.fragsize); +        pa_log_info(__FILE__": output -- %u fragments of size %u.\n", info.fragstotal, info.fragsize);          out_frag_size = info.fragsize;          u->use_getospace = 1;      } diff --git a/polyp/module-tunnel.c b/polyp/module-tunnel.c index 39aaab57..d165aab8 100644 --- a/polyp/module-tunnel.c +++ b/polyp/module-tunnel.c @@ -545,7 +545,7 @@ static int load_key(struct userdata *u, const char*fn) {      u->auth_cookie_in_property = 0;      if (!fn && pa_authkey_prop_get(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) { -        pa_log(__FILE__": using already loaded auth cookie.\n"); +        pa_log_debug(__FILE__": using already loaded auth cookie.\n");          pa_authkey_prop_ref(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME);          u->auth_cookie_in_property = 1;          return 0; @@ -557,7 +557,7 @@ static int load_key(struct userdata *u, const char*fn) {      if (pa_authkey_load_auto(fn, u->auth_cookie, sizeof(u->auth_cookie)) < 0)          return -1; -    pa_log(__FILE__": loading cookie from disk.\n"); +    pa_log_debug(__FILE__": loading cookie from disk.\n");      if (pa_authkey_prop_put(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0)          u->auth_cookie_in_property = 1; diff --git a/polyp/module-x11-bell.c b/polyp/module-x11-bell.c index c3987704..084f5d4b 100644 --- a/polyp/module-x11-bell.c +++ b/polyp/module-x11-bell.c @@ -69,7 +69,7 @@ static int ring_bell(struct userdata *u, int percent) {      assert(u);      if (!(s = pa_namereg_get(u->core, u->sink_name, PA_NAMEREG_SINK, 1))) { -        pa_log(__FILE__": Invalid sink\n"); +        pa_log(__FILE__": Invalid sink: %s\n", u->sink_name);          return -1;      } @@ -88,7 +88,7 @@ static int x11_event_callback(struct pa_x11_wrapper *w, XEvent *e, void *userdat      bne = (XkbBellNotifyEvent*) e;      if (ring_bell(u, bne->percent) < 0) { -        pa_log(__FILE__": Ringing bell failed, reverting to X11 device bell.\n"); +        pa_log_info(__FILE__": Ringing bell failed, reverting to X11 device bell.\n");          XkbForceDeviceBell(pa_x11_wrapper_get_display(w), bne->device, bne->bell_class, bne->bell_id, bne->percent);      } diff --git a/polyp/module-x11-publish.c b/polyp/module-x11-publish.c index 598fe5b5..a47a7606 100644 --- a/polyp/module-x11-publish.c +++ b/polyp/module-x11-publish.c @@ -77,7 +77,7 @@ static int load_key(struct userdata *u, const char*fn) {      u->auth_cookie_in_property = 0;      if (!fn && pa_authkey_prop_get(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) { -        pa_log(__FILE__": using already loaded auth cookie.\n"); +        pa_log_debug(__FILE__": using already loaded auth cookie.\n");          pa_authkey_prop_ref(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME);          u->auth_cookie_in_property = 1;          return 0; @@ -89,7 +89,7 @@ static int load_key(struct userdata *u, const char*fn) {      if (pa_authkey_load_auto(fn, u->auth_cookie, sizeof(u->auth_cookie)) < 0)          return -1; -    pa_log(__FILE__": loading cookie from disk.\n"); +    pa_log_debug(__FILE__": loading cookie from disk.\n");      if (pa_authkey_prop_put(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0)          u->auth_cookie_in_property = 1; diff --git a/polyp/module.c b/polyp/module.c index 67d7f44e..aedaae02 100644 --- a/polyp/module.c +++ b/polyp/module.c @@ -89,7 +89,7 @@ struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char      assert(m->init);      if (m->init(c, m) < 0) { -        pa_log(__FILE__": Failed to load  module \"%s\" (argument: \"%s\"): initialization failed.\n", name, argument ? argument : ""); +        pa_log_error(__FILE__": Failed to load  module \"%s\" (argument: \"%s\"): initialization failed.\n", name, argument ? argument : "");          goto fail;      } @@ -108,7 +108,7 @@ struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char      r = pa_idxset_put(c->modules, m, &m->index);      assert(r >= 0 && m->index != PA_IDXSET_INVALID); -    pa_log(__FILE__": Loaded \"%s\" (index: #%u; argument: \"%s\").\n", m->name, m->index, m->argument ? m->argument : ""); +    pa_log_info(__FILE__": Loaded \"%s\" (index: #%u; argument: \"%s\").\n", m->name, m->index, m->argument ? m->argument : "");       pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_NEW, m->index); @@ -135,13 +135,13 @@ static void pa_module_free(struct pa_module *m) {      if (m->core->disallow_module_loading)          return; -    pa_log(__FILE__": Unloading \"%s\" (index: #%u).\n", m->name, m->index); +    pa_log_info(__FILE__": Unloading \"%s\" (index: #%u).\n", m->name, m->index);       m->done(m->core, m);      lt_dlclose(m->dl); -    pa_log(__FILE__": Unloaded \"%s\" (index: #%u).\n", m->name, m->index); +    pa_log_info(__FILE__": Unloaded \"%s\" (index: #%u).\n", m->name, m->index);       pa_subscription_post(m->core, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_REMOVE, m->index); diff --git a/polyp/namereg.c b/polyp/namereg.c index dce8693f..04601442 100644 --- a/polyp/namereg.c +++ b/polyp/namereg.c @@ -35,6 +35,7 @@  #include "sink.h"  #include "xmalloc.h"  #include "subscribe.h" +#include "util.h"  struct namereg_entry {      enum pa_namereg_type type; @@ -112,8 +113,6 @@ void pa_namereg_unregister(struct pa_core *c, const char *name) {  void* pa_namereg_get(struct pa_core *c, const char *name, enum pa_namereg_type type, int autoload) {      struct namereg_entry *e;      uint32_t index; -    char *x = NULL; -    void *d = NULL;      assert(c);      if (!name) { @@ -130,9 +129,7 @@ void* pa_namereg_get(struct pa_core *c, const char *name, enum pa_namereg_type t          if (e->type == e->type)              return e->data; -    index = (uint32_t) strtol(name, &x, 0); - -    if (!x || *x != 0) { +    if (pa_atou(name, &index) < 0) {          if (autoload) {              pa_autoload_request(c, name, type); @@ -146,13 +143,13 @@ void* pa_namereg_get(struct pa_core *c, const char *name, enum pa_namereg_type t      }      if (type == PA_NAMEREG_SINK) -        d = pa_idxset_get_by_index(c->sinks, index); +        return pa_idxset_get_by_index(c->sinks, index);      else if (type == PA_NAMEREG_SOURCE) -        d = pa_idxset_get_by_index(c->sources, index); +        return pa_idxset_get_by_index(c->sources, index);      else if (type == PA_NAMEREG_SAMPLE && c->scache) -        d = pa_idxset_get_by_index(c->scache, index); -     -    return d; +        return pa_idxset_get_by_index(c->scache, index); + +    return NULL;  }  void pa_namereg_set_default(struct pa_core*c, const char *name, enum pa_namereg_type type) { diff --git a/polyp/pid.c b/polyp/pid.c index 32365136..2fac687e 100644 --- a/polyp/pid.c +++ b/polyp/pid.c @@ -43,8 +43,8 @@   * pid could be read, return 0, on failure (pid_t) -1 */  static pid_t read_pid(const char *fn, int fd) {      ssize_t r; -    char t[20], *e = NULL; -    long int pid; +    char t[20], *e; +    uint32_t pid;      assert(fn && fd >= 0); @@ -57,8 +57,10 @@ static pid_t read_pid(const char *fn, int fd) {          return (pid_t) 0;      t[r] = 0; +    if ((e = strchr(t, '\n'))) +        *e = 0; -    if (!t[0] || (pid = strtol(t, &e, 0)) == 0 || (*e != 0 && *e != '\n')) { +    if (pa_atou(t, &pid) < 0) {          pa_log(__FILE__": WARNING: failed to parse PID file '%s'\n", fn);          return (pid_t) -1;      } diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index 84d4efe8..94dc5e5f 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -2003,7 +2003,7 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo      assert(io && p);      if (pa_idxset_ncontents(p->connections)+1 > MAX_CONNECTIONS) { -        pa_log(__FILE__": Warning! Too many connections (%u), dropping incoming connection.\n", MAX_CONNECTIONS); +        pa_log_warn(__FILE__": Warning! Too many connections (%u), dropping incoming connection.\n", MAX_CONNECTIONS);          pa_iochannel_free(io);          return;      } @@ -2057,7 +2057,7 @@ static int load_key(struct pa_protocol_native*p, const char*fn) {      p->auth_cookie_in_property = 0;      if (!fn && pa_authkey_prop_get(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME, p->auth_cookie, sizeof(p->auth_cookie)) >= 0) { -        pa_log(__FILE__": using already loaded auth cookie.\n"); +        pa_log_info(__FILE__": using already loaded auth cookie.\n");          pa_authkey_prop_ref(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME);          p->auth_cookie_in_property = 1;          return 0; @@ -2069,7 +2069,7 @@ static int load_key(struct pa_protocol_native*p, const char*fn) {      if (pa_authkey_load_auto(fn, p->auth_cookie, sizeof(p->auth_cookie)) < 0)          return -1; -    pa_log(__FILE__": loading cookie from disk.\n"); +    pa_log_info(__FILE__": loading cookie from disk.\n");      if (pa_authkey_prop_put(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME, p->auth_cookie, sizeof(p->auth_cookie)) >= 0)          p->auth_cookie_in_property = 1; diff --git a/polyp/sample.c b/polyp/sample.c index 978a3d6a..b0723f70 100644 --- a/polyp/sample.c +++ b/polyp/sample.c @@ -84,7 +84,7 @@ int pa_sample_spec_equal(const struct pa_sample_spec*a, const struct pa_sample_s      return (a->format == b->format) && (a->rate == b->rate) && (a->channels == b->channels);  } -void pa_sample_spec_snprint(char *s, size_t l, const struct pa_sample_spec *spec) { +const char *pa_sample_format_to_string(enum pa_sample_format f) {      static const char* const table[]= {          [PA_SAMPLE_U8] = "U8",          [PA_SAMPLE_ALAW] = "ALAW", @@ -95,12 +95,21 @@ void pa_sample_spec_snprint(char *s, size_t l, const struct pa_sample_spec *spec          [PA_SAMPLE_FLOAT32BE] = "FLOAT32BE",      }; +    if (f >= PA_SAMPLE_MAX) +        return NULL; + +    return table[f]; +} + +void pa_sample_spec_snprint(char *s, size_t l, const struct pa_sample_spec *spec) { +    assert(s && l && spec); +          if (!pa_sample_spec_valid(spec)) {          snprintf(s, l, "Invalid");          return;      } -    snprintf(s, l, "%s %uch %uHz", table[spec->format], spec->channels, spec->rate); +    snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate);  }  pa_volume_t pa_volume_multiply(pa_volume_t a, pa_volume_t b) { diff --git a/polyp/sample.h b/polyp/sample.h index 93025a10..59226c46 100644 --- a/polyp/sample.h +++ b/polyp/sample.h @@ -86,6 +86,9 @@ int pa_sample_spec_valid(const struct pa_sample_spec *spec);  /** Return non-zero when the two sample type specifications match */  int pa_sample_spec_equal(const struct pa_sample_spec*a, const struct pa_sample_spec*b); +/* Return a descriptive string for the specified sample format. \since 0.7.1 */ +const char *pa_sample_format_to_string(enum pa_sample_format f); +  /** Maximum required string length for pa_sample_spec_snprint() */  #define PA_SAMPLE_SPEC_SNPRINT_MAX 32 @@ -126,7 +129,7 @@ pa_volume_t pa_volume_from_user(double v);  /** Pretty print a byte size value. (i.e. "2.5 MB") */  void pa_bytes_snprint(char *s, size_t l, unsigned v); -/** Parse a sample format text */ +/** Parse a sample format text. Inverse of pa_sample_format_to_string() */  enum pa_sample_format pa_parse_sample_format(const char *format);  PA_C_DECL_END diff --git a/polyp/sink-input.c b/polyp/sink-input.c index e66278ed..347b8f5c 100644 --- a/polyp/sink-input.c +++ b/polyp/sink-input.c @@ -85,7 +85,7 @@ struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, const char *name, con      assert(r == 0);      pa_sample_spec_snprint(st, sizeof(st), spec); -    pa_log(__FILE__": created %u \"%s\" on %u with sample spec \"%s\"\n", i->index, i->name, s->index, st); +    pa_log_info(__FILE__": created %u \"%s\" on %u with sample spec \"%s\"\n", i->index, i->name, s->index, st);      pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); @@ -115,6 +115,8 @@ static void sink_input_free(struct pa_sink_input* i) {      if (i->state != PA_SINK_INPUT_DISCONNECTED)          pa_sink_input_disconnect(i); +    pa_log_info(__FILE__": freed %u \"%s\"\n", i->index, i->name);  +          if (i->resampled_chunk.memblock)          pa_memblock_unref(i->resampled_chunk.memblock);      if (i->resampler) diff --git a/polyp/sink.c b/polyp/sink.c index 29aef6fb..3d20884b 100644 --- a/polyp/sink.c +++ b/polyp/sink.c @@ -81,7 +81,7 @@ struct pa_sink* pa_sink_new(struct pa_core *core, const char *name, int fail, co      assert(s->index != PA_IDXSET_INVALID && r >= 0);      pa_sample_spec_snprint(st, sizeof(st), spec); -    pa_log(__FILE__": created %u \"%s\" with sample spec \"%s\"\n", s->index, s->name, st); +    pa_log_info(__FILE__": created %u \"%s\" with sample spec \"%s\"\n", s->index, s->name, st);      pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); @@ -117,7 +117,7 @@ static void sink_free(struct pa_sink *s) {      if (s->state != PA_SINK_DISCONNECTED)          pa_sink_disconnect(s); -    pa_log(__FILE__": freed %u \"%s\"\n", s->index, s->name); +    pa_log_info(__FILE__": freed %u \"%s\"\n", s->index, s->name);       pa_source_unref(s->monitor_source);      s->monitor_source = NULL; diff --git a/polyp/source-output.c b/polyp/source-output.c index fb06ff8f..3568fd6f 100644 --- a/polyp/source-output.c +++ b/polyp/source-output.c @@ -37,6 +37,7 @@ struct pa_source_output* pa_source_output_new(struct pa_source *s, const char *n      struct pa_source_output *o;      struct pa_resampler *resampler = NULL;      int r; +    char st[256];      assert(s && spec);      if (pa_idxset_ncontents(s->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { @@ -73,6 +74,9 @@ struct pa_source_output* pa_source_output_new(struct pa_source *s, const char *n      r = pa_idxset_put(s->outputs, o, NULL);      assert(r == 0); +    pa_sample_spec_snprint(st, sizeof(st), spec); +    pa_log_info(__FILE__": created %u \"%s\" on %u with sample spec \"%s\"\n", o->index, o->name, s->index, st); +          pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index);      return o;     @@ -100,6 +104,8 @@ static void source_output_free(struct pa_source_output* o) {      if (o->state != PA_SOURCE_OUTPUT_DISCONNECTED)          pa_source_output_disconnect(o); +    pa_log_info(__FILE__": freed %u \"%s\"\n", o->index, o->name);  +          if (o->resampler)          pa_resampler_free(o->resampler); diff --git a/polyp/source.c b/polyp/source.c index 026ec7a8..7cdb9117 100644 --- a/polyp/source.c +++ b/polyp/source.c @@ -68,7 +68,7 @@ struct pa_source* pa_source_new(struct pa_core *core, const char *name, int fail      assert(s->index != PA_IDXSET_INVALID && r >= 0);      pa_sample_spec_snprint(st, sizeof(st), spec); -    pa_log(__FILE__": created %u \"%s\" with sample spec \"%s\"\n", s->index, s->name, st); +    pa_log_info(__FILE__": created %u \"%s\" with sample spec \"%s\"\n", s->index, s->name, st);       pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); @@ -101,7 +101,7 @@ static void source_free(struct pa_source *s) {      if (s->state != PA_SOURCE_DISCONNECTED)          pa_source_disconnect(s); -    pa_log(__FILE__": freed %u \"%s\"\n", s->index, s->name); +    pa_log_info(__FILE__": freed %u \"%s\"\n", s->index, s->name);       pa_idxset_free(s->outputs, NULL, NULL); diff --git a/polyp/util.c b/polyp/util.c index 970ebb93..ff1aebf3 100644 --- a/polyp/util.c +++ b/polyp/util.c @@ -381,9 +381,9 @@ supported.*/  void pa_raise_priority(void) {      if (setpriority(PRIO_PROCESS, 0, NICE_LEVEL) < 0) -        pa_log(__FILE__": setpriority() failed: %s\n", strerror(errno)); -/*     else */ -/*         pa_log(__FILE__": Successfully gained nice level %i.\n", NICE_LEVEL); */ +        pa_log_warn(__FILE__": setpriority() failed: %s\n", strerror(errno)); +    else  +        pa_log_info(__FILE__": Successfully gained nice level %i.\n", NICE_LEVEL);   #ifdef _POSIX_PRIORITY_SCHEDULING      { @@ -396,11 +396,11 @@ void pa_raise_priority(void) {          sp.sched_priority = 1;          if (sched_setscheduler(0, SCHED_FIFO, &sp) < 0) { -            pa_log(__FILE__": sched_setscheduler() failed: %s\n", strerror(errno)); +            pa_log_warn(__FILE__": sched_setscheduler() failed: %s\n", strerror(errno));              return;          } -/*         pa_log(__FILE__": Successfully enabled SCHED_FIFO scheduling.\n"); */ +        pa_log_info(__FILE__": Successfully enabled SCHED_FIFO scheduling.\n");       }  #endif  } @@ -698,17 +698,17 @@ int pa_unlock_lockfile(const char *fn, int fd) {      assert(fn && fd >= 0);      if (unlink(fn) < 0) { -        pa_log(__FILE__": WARNING: unable to remove lock file '%s': %s\n", fn, strerror(errno)); +        pa_log_warn(__FILE__": WARNING: unable to remove lock file '%s': %s\n", fn, strerror(errno));          r = -1;      }      if (pa_lock_fd(fd, 0) < 0) { -        pa_log(__FILE__": WARNING: failed to unlock file '%s'.\n", fn); +        pa_log_warn(__FILE__": WARNING: failed to unlock file '%s'.\n", fn);          r = -1;      }      if (close(fd) < 0) { -        pa_log(__FILE__": WARNING: failed to close lock file '%s': %s\n", fn, strerror(errno)); +        pa_log_warn(__FILE__": WARNING: failed to close lock file '%s': %s\n", fn, strerror(errno));          r = -1;      } @@ -862,6 +862,7 @@ char *pa_runtime_path(const char *fn, char *s, size_t l) {      return s;  } +/* Wait t milliseconds */  int pa_msleep(unsigned long t) {      struct timespec ts; @@ -870,3 +871,35 @@ int pa_msleep(unsigned long t) {      return nanosleep(&ts, NULL);  } + +/* Convert the string s to a signed integer in *ret_i */ +int pa_atoi(const char *s, int32_t *ret_i) { +    char *x = NULL; +    long l; +    assert(s && ret_i); + +    l = strtol(s, &x, 0); + +    if (x || *x) +        return -1; + +    *ret_i = (int32_t) l; +     +    return 0; +} + +/* Convert the string s to an unsigned integer in *ret_u */ +int pa_atou(const char *s, uint32_t *ret_u) { +    char *x = NULL; +    unsigned long l; +    assert(s && ret_u); + +    l = strtoul(s, &x, 0); + +    if (!x || *x) +        return -1; + +    *ret_u = (uint32_t) l; +     +    return 0; +} diff --git a/polyp/util.h b/polyp/util.h index 922aa49e..2cfc5f6e 100644 --- a/polyp/util.h +++ b/polyp/util.h @@ -90,4 +90,7 @@ char *pa_runtime_path(const char *fn, char *s, size_t l);  int pa_msleep(unsigned long t); +int pa_atoi(const char *s, int32_t *ret_i); +int pa_atou(const char *s, uint32_t *ret_u); +  #endif | 
