X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/07bc035e2ec3e4fb109fb36ad5f1fd751a960e70..1cf4ef2f03a2dd2cd0ae7bcd23f3670becbcdd17:/lib/configuration.c diff --git a/lib/configuration.c b/lib/configuration.c index 95720a3..3cf276e 100644 --- a/lib/configuration.c +++ b/lib/configuration.c @@ -54,6 +54,7 @@ #include "regsub.h" #include "signame.h" #include "authhash.h" +#include "vector.h" /** @brief Path to config file * @@ -679,12 +680,6 @@ static int validate_isreg(const struct config_state *cs, return 0; } -static int validate_ischr(const struct config_state *cs, - int nvec, char **vec) { - VALIDATE_FILE(S_ISCHR, "character device"); - return 0; -} - static int validate_player(const struct config_state *cs, int nvec, char attribute((unused)) **vec) { @@ -781,16 +776,6 @@ static int validate_sample_format(const struct config_state *cs, return parse_sample_format(cs, 0, nvec, vec); } -static int validate_channel(const struct config_state *cs, - int attribute((unused)) nvec, - char **vec) { - if(mixer_channel(vec[0]) == -1) { - error(0, "%s:%d: invalid channel '%s'", cs->path, cs->line, vec[0]); - return -1; - } - return 0; -} - static int validate_any(const struct config_state attribute((unused)) *cs, int attribute((unused)) nvec, char attribute((unused)) **vec) { @@ -937,10 +922,11 @@ static int validate_algo(const struct config_state attribute((unused)) *cs, static const struct conf conf[] = { { C(alias), &type_string, validate_alias }, { C(allow), &type_stringlist_accum, validate_allow }, + { C(api), &type_backend, validate_any }, { C(authorization_algorithm), &type_string, validate_algo }, { C(broadcast), &type_stringlist, validate_addrport }, { C(broadcast_from), &type_stringlist, validate_addrport }, - { C(channel), &type_string, validate_channel }, + { C(channel), &type_string, validate_any }, { C(checkpoint_kbyte), &type_integer, validate_non_negative }, { C(checkpoint_min), &type_integer, validate_non_negative }, { C(collection), &type_collections, validate_any }, @@ -956,7 +942,7 @@ static const struct conf conf[] = { { C(listen), &type_stringlist, validate_port }, { C(lock), &type_boolean, validate_any }, { C(mail_sender), &type_string, validate_any }, - { C(mixer), &type_string, validate_ischr }, + { C(mixer), &type_string, validate_any }, { C(multicast_loop), &type_boolean, validate_any }, { C(multicast_ttl), &type_integer, validate_non_negative }, { C(namepart), &type_namepart, validate_any }, @@ -978,7 +964,7 @@ static const struct conf conf[] = { { C(signal), &type_signal, validate_any }, { C(smtp_server), &type_string, validate_any }, { C(sox_generation), &type_integer, validate_non_negative }, - { C(speaker_backend), &type_backend, validate_any }, + { C2(speaker_backend, api), &type_backend, validate_any }, { C(speaker_command), &type_string, validate_any }, { C(stopword), &type_string_accum, validate_any }, { C(templates), &type_string_accum, validate_isdir }, @@ -1014,6 +1000,22 @@ static int config_set(const struct config_state *cs, || which->type->set(cs, which, nvec - 1, vec + 1)); } +static int config_set_args(const struct config_state *cs, + const char *which, ...) { + va_list ap; + struct vector v[1]; + char *s; + + vector_init(v); + vector_append(v, (char *)which); + va_start(ap, which); + while((s = va_arg(ap, char *))) + vector_append(v, s); + va_end(ap); + vector_terminate(v); + return config_set(cs, v->nvec, v->vec); +} + /** @brief Error callback used by config_include() */ static void config_error(const char *msg, void *u) { const struct config_state *cs = u; @@ -1134,12 +1136,21 @@ static const char *const default_stopwords[] = { }; #define NDEFAULT_STOPWORDS (sizeof default_stopwords / sizeof *default_stopwords) +static const char *const default_players[] = { + "*.ogg", + "*.flac", + "*.mp3", + "*.wav", +}; +#define NDEFAULT_PLAYERS (sizeof default_players / sizeof *default_players) + /** @brief Make a new default configuration */ static struct config *config_default(void) { struct config *c = xmalloc(sizeof *c); const char *logname; struct passwd *pw; struct config_state cs; + size_t n; cs.path = ""; cs.line = 0; @@ -1165,20 +1176,30 @@ static struct config *config_default(void) { c->sample_format.channels = 2; c->sample_format.endian = ENDIAN_NATIVE; c->queue_pad = 10; - c->speaker_backend = -1; + c->api = -1; c->multicast_ttl = 1; c->multicast_loop = 1; c->authorization_algorithm = xstrdup("sha1"); c->noticed_history = 31; c->short_display = 32; - c->mixer = xstrdup("/dev/mixer"); - c->channel = xstrdup("pcm"); + c->mixer = 0; + c->channel = 0; c->dbversion = 2; c->cookie_login_lifetime = 86400; c->cookie_key_lifetime = 86400 * 7; c->smtp_server = xstrdup("127.0.0.1"); + /* Default stopwords */ if(config_set(&cs, (int)NDEFAULT_STOPWORDS, (char **)default_stopwords)) exit(1); + /* Default player configuration */ + for(n = 0; n < NDEFAULT_PLAYERS; ++n) { + if(config_set_args(&cs, "player", + default_players[n], "execraw", "disorder-decode", (char *)0)) + exit(1); + if(config_set_args(&cs, "tracklength", + default_players[n], "disorder-tracklength", (char *)0)) + exit(1); + } return c; } @@ -1247,31 +1268,31 @@ static void config_postdefaults(struct config *c, for(n = 0; n < NTRANSFORM; ++n) set_transform(&cs, whoami, 5, (char **)transform[n]); } - if(c->speaker_backend == -1) { + if(c->api == -1) { if(c->speaker_command) - c->speaker_backend = BACKEND_COMMAND; + c->api = BACKEND_COMMAND; else if(c->broadcast.n) - c->speaker_backend = BACKEND_NETWORK; + c->api = BACKEND_NETWORK; else { #if HAVE_ALSA_ASOUNDLIB_H - c->speaker_backend = BACKEND_ALSA; + c->api = BACKEND_ALSA; #elif HAVE_SYS_SOUNDCARD_H - c->speaker_backend = BACKEND_OSS; + c->api = BACKEND_OSS; #elif HAVE_COREAUDIO_AUDIOHARDWARE_H - c->speaker_backend = BACKEND_COREAUDIO; + c->api = BACKEND_COREAUDIO; #else - c->speaker_backend = BACKEND_COMMAND; + c->api = BACKEND_COMMAND; #endif } } if(server) { - if(c->speaker_backend == BACKEND_COMMAND && !c->speaker_command) - fatal(0, "speaker_backend is command but speaker_command is not set"); - if(c->speaker_backend == BACKEND_NETWORK && !c->broadcast.n) - fatal(0, "speaker_backend is network but broadcast is not set"); + if(c->api == BACKEND_COMMAND && !c->speaker_command) + fatal(0, "'api command' but speaker_command is not set"); + if(c->api == BACKEND_NETWORK && !c->broadcast.n) + fatal(0, "'api network' but broadcast is not set"); } /* Override sample format */ - switch(c->speaker_backend) { + switch(c->api) { case BACKEND_NETWORK: c->sample_format.rate = 44100; c->sample_format.channels = 2;