X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=afs.c;h=0c7526c74110fb59da4cc20b815972421090cc12;hb=d894e0cc7ce94d09847a8a35f47127968d4268f1;hp=becff09dde80d70564dd9a856acd7df1b896f34d;hpb=8d45d703078c89bb89804dacb6706f0c563ac4c6;p=paraslash.git diff --git a/afs.c b/afs.c index becff09d..0c7526c7 100644 --- a/afs.c +++ b/afs.c @@ -79,6 +79,7 @@ static int server_socket; 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. @@ -143,7 +144,7 @@ struct callback_result { * \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 @@ -507,32 +508,102 @@ destroy: 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) @@ -861,7 +932,6 @@ static void register_tasks(uint32_t cookie) */ __noreturn void afs_init(uint32_t cookie, int socket_fd) { - enum play_mode current_play_mode; struct sched s; int i, ret; @@ -880,7 +950,7 @@ __noreturn void afs_init(uint32_t cookie, int socket_fd) 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;