From: Andre Noll Date: Mon, 25 Nov 2024 20:55:43 +0000 (+0100) Subject: com_select(): Support '-' to reactivate the previous mood/playlist. X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=d09ca1da67f3f71b54ddd5f7d56d8d7cacf9d12c;p=paraslash.git com_select(): Support '-' to reactivate the previous mood/playlist. This adds two global variables to keep track of the previously active mood or playlist. The select subcommand makes use of this information if the argument is the special string '-'. The subcommand then follows common Unix conventions and reactivates the previous mood or playlist. --- diff --git a/afs.c b/afs.c index 445d5871..ad1ececf 100644 --- a/afs.c +++ b/afs.c @@ -69,8 +69,8 @@ static int server_socket; static struct command_task command_task_struct; static struct signal_task *signal_task; -static enum play_mode current_play_mode; -static char *current_mop; /* mode or playlist specifier. NULL means dummy mood */ +static enum play_mode current_play_mode, previous_play_mode; +static char *current_mop, *previous_mop; /* NULL means dummy mood */ extern uint32_t afs_socket_cookie; @@ -435,41 +435,56 @@ static int activate_mood_or_playlist(const char *arg, struct para_buffer *pb) { enum play_mode mode; int ret; - char *msg; + char *errmsg; if (!arg) { /* load dummy mood */ - ret = mood_load(NULL, NULL, &msg); + ret = mood_load(NULL, NULL, &errmsg); mode = PLAY_MODE_MOOD; + } else if (!strcmp(arg, "-")) { /* load previous mop */ + char *mop = previous_mop? previous_mop + 2 : NULL; + if (previous_play_mode == PLAY_MODE_MOOD) + ret = mood_load(mop, NULL, &errmsg); + else + ret = playlist_load(mop, NULL, &errmsg); + mode = previous_play_mode; } else if (!strncmp(arg, "p/", 2)) { - ret = playlist_load(arg + 2, NULL, &msg); + ret = playlist_load(arg + 2, NULL, &errmsg); mode = PLAY_MODE_PLAYLIST; } else if (!strncmp(arg, "m/", 2)) { - ret = mood_load(arg + 2, NULL, &msg); + ret = mood_load(arg + 2, NULL, &errmsg); mode = PLAY_MODE_MOOD; } else { ret = -ERRNO_TO_PARA_ERROR(EINVAL); - msg = make_message("%s: parse error\n", arg); + errmsg = make_message("%s: parse error\n", arg); } if (pb) - para_printf(pb, "%s", msg); - free(msg); + para_printf(pb, "%s", errmsg); + free(errmsg); if (ret < 0) return ret; - current_play_mode = mode; /* * We get called with arg == current_mop from the signal dispatcher * after SIGHUP and from the error path of the select command to - * re-select the current mood or playlist. In this case the assignment - * to current_mop below would result in a use-after-free condition. + * re-select the current mood or playlist. Don't update the four global + * mop variables in these cases. */ if (arg != current_mop) { - free(current_mop); - current_mop = arg? para_strdup(arg) : NULL; + previous_play_mode = current_play_mode; + current_play_mode = mode; + if (arg && !strcmp(arg, "-")) { + char *tmp = current_mop; + current_mop = previous_mop; + previous_mop = tmp; + } else { + free(previous_mop); + previous_mop = current_mop; + current_mop = arg? para_strdup(arg) : NULL; + } } /* Notify the server about the mood/playlist change. */ mutex_lock(mmd_mutex); - strncpy(mmd->afs_mode_string, arg? arg: "dummy", - sizeof(mmd->afs_mode_string)); + snprintf(mmd->afs_mode_string, sizeof(mmd->afs_mode_string) - 1, + "%s", current_mop? current_mop : "dummy"); mmd->afs_mode_string[sizeof(mmd->afs_mode_string) - 1] = '\0'; mmd->events++; mutex_unlock(mmd_mutex); @@ -959,6 +974,7 @@ out: signal_shutdown(signal_task); free_status_items(); free(current_mop); + free(previous_mop); free_lpr(); if (ret < 0) PARA_EMERG_LOG("%s\n", para_strerror(-ret)); diff --git a/m4/lls/server_cmd.suite.m4 b/m4/lls/server_cmd.suite.m4 index d694082b..f700339e 100644 --- a/m4/lls/server_cmd.suite.m4 +++ b/m4/lls/server_cmd.suite.m4 @@ -418,11 +418,13 @@ m4_include(`com_ll.m4') [subcommand select] purpose = activate a mood or a playlist - non-opts-name = specifier/name + non-opts-name = mop aux_info = AFS_READ | AFS_WRITE [description] - The specifier is either 'm' or 'p' to indicate whether a playlist or - a mood should be activated. Example: + The argument is either the special string '-' to load the previous + mood or playlist, or of the form specifier/name. In the latter case + the specifier part of the argument is either 'm' or 'p' to indicate + whether a playlist or a mood should be activated. Example: select m/foo