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: https://git.tuebingen.mpg.de/?a=commitdiff_plain;h=4f4ad5e5ec04deda44d6d7953842d4bfa4969a12;p=paraslash.git com_select(): Support '-' to reactivate the previous mood/playlist. This adds two static global variables to afs.c which track the previously active mood or playlist. The select subcommand now 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..4951af75 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; @@ -440,6 +440,13 @@ static int activate_mood_or_playlist(const char *arg, struct para_buffer *pb) if (!arg) { /* load dummy mood */ ret = mood_load(NULL, NULL, &msg); 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, &msg); + else + ret = playlist_load(mop, NULL, &msg); + mode = previous_play_mode; } else if (!strncmp(arg, "p/", 2)) { ret = playlist_load(arg + 2, NULL, &msg); mode = PLAY_MODE_PLAYLIST; @@ -455,21 +462,29 @@ static int activate_mood_or_playlist(const char *arg, struct para_buffer *pb) free(msg); 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