static struct command_task command_task_struct;
static struct signal_task signal_task_struct;
+static enum play_mode current_play_mode;
/**
* A random number used to "authenticate" the connection.
* \param result Callback result will be stored here.
*
* This function creates a shared memory area, copies the buffer pointed to by
- * \a buf to that area and notifies the afs process that \a f should be
+ * query to that area and notifies the afs process that \a f should be
* called ASAP.
*
* \return Negative, on errors, the return value of the callback function
return ret;
}
-static enum play_mode init_admissible_files(void)
+static char *current_mop; /* mode or playlist specifier. NULL means dummy mooe */
+
+/* Never fails if arg == NULL */
+static int activate_mood_or_playlist(char *arg, int *num_admissible)
{
- int ret = 0;
- char *arg = conf.afs_initial_mode_arg;
+ enum play_mode mode;
+ int ret;
- if (conf.afs_initial_mode_given) {
+ if (!arg) {
+ ret = change_current_mood(NULL); /* always successful */
+ mode = PLAY_MODE_MOOD;
+ } else {
if (!strncmp(arg, "p:", 2)) {
ret = playlist_open(arg + 2);
- if (ret >= 0)
- return PLAY_MODE_PLAYLIST;
- goto dummy;
- }
- if (!strncmp(arg, "m:", 2)) {
+ mode = PLAY_MODE_PLAYLIST;
+ } else if (!strncmp(arg, "m:", 2)) {
ret = change_current_mood(arg + 2);
- if (ret >= 0)
- return PLAY_MODE_MOOD;
- goto dummy;
- }
- PARA_ERROR_LOG("bad afs initial mode arg: %s\n", arg);
+ mode = PLAY_MODE_MOOD;
+ } else
+ ret = -E_AFS_SYNTAX;
+ if (ret < 0)
+ return ret;
+ }
+ if (num_admissible)
+ *num_admissible = ret;
+ current_play_mode = mode;
+ if (arg != current_mop) {
+ free(current_mop);
+ if (arg)
+ current_mop = para_strdup(arg);
+ else
+ current_mop = NULL;
}
-dummy:
+ return 1;
+}
+
+static int com_select_callback(const struct osl_object *query,
+ struct osl_object *result)
+{
+ struct para_buffer pb = {.buf = NULL};
+ char *arg = query->data;
+ int num_admissible, ret;
+
+ ret = clear_score_table();
if (ret < 0)
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ return ret;
+ if (current_play_mode == PLAY_MODE_MOOD)
+ close_current_mood();
+ else
+ playlist_close();
+ ret = activate_mood_or_playlist(arg, &num_admissible);
+ if (ret < 0) {
+ para_printf(&pb, "%s\n", PARA_STRERROR(-ret));
+ para_printf(&pb, "switching back to %s\n", current_mop?
+ current_mop : "dummy");
+ ret = activate_mood_or_playlist(current_mop, &num_admissible);
+ if (ret < 0) {
+ para_printf(&pb, "failed, switching to dummy\n");
+ change_current_mood(NULL); /* always successful */
+ }
+ }
+ para_printf(&pb, "activated %s (%d admissible files)\n", current_mop?
+ current_mop : "dummy mood", num_admissible);
+ result->data = pb.buf;
+ result->size = pb.size;
+ return 1;
+}
+
+int com_select(int fd, int argc, char * const * const argv)
+{
+ int ret;
+ struct osl_object query, result;
+
+ if (argc != 2)
+ return -E_AFS_SYNTAX;
+ query.data = argv[1];
+ query.size = strlen(argv[1]) + 1;
+ ret = send_callback_request(com_select_callback, &query,
+ &result);
+ if (ret > 0 && result.data && result.size) {
+ ret = send_va_buffer(fd, "%s", (char *)result.data);
+ free(result.data);
+ }
+ return ret;
+}
+
+static void init_admissible_files(void)
+{
+ int ret = 0;
+ char *arg = conf.afs_initial_mode_arg;
+ ret = activate_mood_or_playlist(arg, NULL);
+ if (ret >= 0)
+ return;
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
PARA_NOTICE_LOG("defaulting to dummy mood\n");
- change_current_mood(NULL); /* always successful */
- return PLAY_MODE_MOOD;
+ activate_mood_or_playlist(NULL, NULL); /* always successful */
}
static int setup_command_socket_or_die(void)
*/
__noreturn void afs_init(uint32_t cookie, int socket_fd)
{
- enum play_mode current_play_mode;
struct sched s;
int i, ret;
exit(EXIT_FAILURE);
PARA_INFO_LOG("server_socket: %d, afs_socket_cookie: %u\n",
server_socket, (unsigned) cookie);
- current_play_mode = init_admissible_files();
+ init_admissible_files();
register_tasks(cookie);
s.default_timeout.tv_sec = 0;
s.default_timeout.tv_usec = 99 * 1000;
(long long unsigned)int_sqrt(statistics.num_played_qd / n));
}
+/**
+ * Close the current mood.
+ *
+ * Free all resources of the current mood which were allocated during
+ * mood_open().
+ */
+void close_current_mood(void)
+{
+ destroy_mood(current_mood);
+ current_mood = NULL;
+ memset(&statistics, 0, sizeof(statistics));
+}
+
+
/**
* Change the current mood.
*
ret = load_mood(row, &m);
if (ret < 0)
return ret;
- destroy_mood(current_mood);
+ close_current_mood();
current_mood = m;
} else {
- destroy_mood(current_mood);
+ close_current_mood();
current_mood = alloc_new_mood("dummy");
}
aa.m = current_mood;
goto out;
}
PARA_NOTICE_LOG("score add complete\n");
- ret = 1;
+ ret = statistics.num;
out:
free(aa.array);
return ret;
}
-
-/**
- * Close the current mood.
- *
- * Free all resources of the current mood which were allocated during
- * mood_open().
- */
-static void close_current_mood(void)
-{
- destroy_mood(current_mood);
- current_mood = NULL;
- memset(&statistics, 0, sizeof(statistics));
-}
-
/**
* Close and re-open the current mood.
*
if (current_mood->name)
mood_name = para_strdup(current_mood->name);
close_current_mood();
- ret = clear_score_table();
- if (ret < 0)
- return ret;
ret = change_current_mood(mood_name);
free(mood_name);
return ret;