X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/2257512d31e410938ae2f7f7f511830989c58f7f..40dcd866894885d9d1965be248b7e04af0f853f0:/server/actions.c diff --git a/server/actions.c b/server/actions.c index 1a6f7c9..a504ed5 100644 --- a/server/actions.c +++ b/server/actions.c @@ -119,6 +119,37 @@ static void act_random_enable(void) { redirect(0); } +static void act_remove(void) { + const char *id; + struct queue_entry *q; + + if(dcgi_client) { + if(!(id = cgi_get("id"))) + error(0, "missing 'id' argument"); + else if(!(q = dcgi_findtrack(id))) + error(0, "unknown queue id %s", id); + else switch(q->state) { + case playing_isscratch: + case playing_failed: + case playing_no_player: + case playing_ok: + case playing_quitting: + case playing_scratched: + error(0, "does not make sense to scratch %s", id); + break; + case playing_paused: /* started but paused */ + case playing_started: /* started to play */ + disorder_scratch(dcgi_client, id); + break; + case playing_random: /* unplayed randomly chosen track */ + case playing_unplayed: /* haven't played this track yet */ + disorder_remove(dcgi_client, id); + break; + } + } + redirect(0); +} + /** @brief Table of actions */ static const struct action { /** @brief Action name */ @@ -130,23 +161,48 @@ static const struct action { { "enable", act_enable }, { "manage", act_playing }, { "playing", act_playing }, - { "random-disable", act_random_disable }, - { "random-enable", act_random_enable }, + { "randomdisable", act_random_disable }, + { "randomenable", act_random_enable }, + { "remove", act_remove }, }; +/** @brief Check that an action name is valid + * @param name Action + * @return 1 if valid, 0 if not + */ +static int dcgi_valid_action(const char *name) { + int c; + + /* First character must be letter or digit (this also requires there to _be_ + * a first character) */ + if(!isalnum((unsigned char)*name)) + return 0; + /* Only letters, digits, '.' and '-' allowed */ + while((c = (unsigned char)*name++)) { + if(!(isalnum(c) + || c == '.' + || c == '_')) + return 0; + } + return 1; +} + /** @brief Expand a template * @param name Base name of template, or NULL to consult CGI args */ void dcgi_expand(const char *name) { - const char *p; - + const char *p, *found; + + /* Parse macros first */ + if((found = mx_find("macros.tmpl"))) + mx_expand_file(found, sink_discard(), 0); /* For unknown actions check that they aren't evil */ - for(p = name; *p && isalnum((unsigned char)*p); ++p) - ; - if(*p) + if(!dcgi_valid_action(name)) fatal(0, "invalid action name '%s'", name); byte_xasprintf((char **)&p, "%s.tmpl", name); - if(mx_expand_file(p, sink_stdio("stdout", stdout), 0) == -1 + if(!(found = mx_find(p))) + fatal(errno, "cannot find %s", p); + if(mx_expand_file(found, sink_stdio("stdout", stdout), 0) == -1 || fflush(stdout) < 0) fatal(errno, "error writing to stdout"); } @@ -188,12 +244,8 @@ void dcgi_action(const char *action) { } /** @brief Generate an error page */ -void dcgi_error(const char *msg, ...) { - va_list ap; - - va_start(ap, msg); - byte_xvasprintf(&dcgi_error_string, msg, ap); - va_end(ap); +void dcgi_error(const char *key) { + dcgi_error_string = xstrdup(key); dcgi_expand("error"); }