+ const struct lls_command *cmd = SERVER_CMD_CMD_PTR(SELECT);
+ const char *arg;
+ int ret;
+ struct para_buffer *pbout;
+
+ ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr);
+ assert(ret >= 0);
+ arg = lls_input(0, aca->lpr);
+ pbout = SERVER_CMD_OPT_GIVEN(SELECT, VERBOSE, aca->lpr)?
+ &aca->pbout : NULL;
+ score_clear();
+ if (current_play_mode == PLAY_MODE_MOOD)
+ mood_unload(NULL);
+ else
+ playlist_unload(NULL);
+ ret = activate_mood_or_playlist(arg, pbout);
+ if (ret >= 0)
+ goto free_lpr;
+ /* ignore subsequent errors (but log them) */
+ if (current_mop && strcmp(current_mop, arg) != 0) {
+ int ret2;
+ afs_error(aca, "switching back to %s\n", current_mop);
+ ret2 = activate_mood_or_playlist(current_mop, pbout);
+ if (ret2 >= 0)
+ goto free_lpr;
+ afs_error(aca, "could not reactivate %s: %s\n", current_mop,
+ para_strerror(-ret2));
+ }
+ activate_mood_or_playlist(NULL, pbout);
+free_lpr:
+ lls_free_parse_result(aca->lpr, cmd);
+ return ret;
+}
+
+static int com_select(struct command_context *cc, struct lls_parse_result *lpr)
+{
+ const struct lls_command *cmd = SERVER_CMD_CMD_PTR(SELECT);
+ char *errctx;
+ int ret = lls(lls_check_arg_count(lpr, 1, 1, &errctx));
+
+ if (ret < 0) {
+ send_errctx(cc, errctx);
+ return ret;
+ }
+ ret = send_lls_callback_request(com_select_callback, cmd, lpr, cc);
+ return ret == osl(-E_OSL_RB_KEY_NOT_FOUND)? -E_BAD_MOP : ret;
+}
+EXPORT_SERVER_CMD_HANDLER(select);
+
+static int com_init_callback(struct afs_callback_arg *aca)
+{
+ uint32_t table_mask = *(uint32_t *)aca->query.data;