diff --git a/inc/lektor/common.h b/inc/lektor/common.h index 36e007e73b248adead994bcba72b54fa9017454b..82a58096dcf26cffa1c00b49074947378f09fdd6 100644 --- a/inc/lektor/common.h +++ b/inc/lektor/common.h @@ -111,6 +111,7 @@ void ___lkt_log(LOG_LEVEL, const char *sec, const char *func, const char *file, LOG_ERROR("FATAL", __VA_ARGS__); \ exit(1); \ } +#define LOG_UNREACHABLE LOG_FATAL("Ureachable!"); void ___lkt_print(const char *section, const char *format, ...); #define LKT_OUTPUT(section, ...) ___lkt_print(section, __VA_ARGS__) diff --git a/src/net/listen.c b/src/net/listen.c index b578fb81dfc70098ca82aa5510dfcb84b99337fa..d32a2019ae11961c0ad4508aed23033dfaa7bba8 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -185,23 +185,25 @@ ___cmd_trie_init(void) cmd_trie_insert(cmd_trie_root, "currentsong", FUNCTION_POINTER(command_currentsong), LKT_COMMAND_SIMPLE); cmd_trie_insert(cmd_trie_root, "status", FUNCTION_POINTER(command_status), LKT_COMMAND_SIMPLE); cmd_trie_insert(cmd_trie_root, "stats", FUNCTION_POINTER(command_stats), LKT_COMMAND_SIMPLE); + cmd_trie_insert(cmd_trie_root, "help", FUNCTION_POINTER(command_help), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "next", FUNCTION_POINTER(command_next), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "previous", FUNCTION_POINTER(command_previous), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "pause", FUNCTION_POINTER(command_pause), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "play", FUNCTION_POINTER(command_next), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "playid", FUNCTION_POINTER(command_next), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "stop", FUNCTION_POINTER(command_next), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "seek", FUNCTION_POINTER(command_seek), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "seekid", FUNCTION_POINTER(command_seekid), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "seekcur", FUNCTION_POINTER(command_seekcur), LKT_COMMAND_SIMPLE); + cmd_trie_insert(cmd_trie_root, "next", FUNCTION_POINTER(command_next), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "previous", FUNCTION_POINTER(command_previous), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "pause", FUNCTION_POINTER(command_pause), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "play", FUNCTION_POINTER(command_next), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "playid", FUNCTION_POINTER(command_next), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "stop", FUNCTION_POINTER(command_next), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "seek", FUNCTION_POINTER(command_seek), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "seekid", FUNCTION_POINTER(command_seekid), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "seekcur", FUNCTION_POINTER(command_seekcur), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "__insert", FUNCTION_POINTER(command_add_5), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "add", FUNCTION_POINTER(command_add_1), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "searchadd", FUNCTION_POINTER(command_add_1), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "findadd", FUNCTION_POINTER(command_add_1), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "addid", FUNCTION_POINTER(command_addid), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "del", FUNCTION_POINTER(command_del), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "delid", FUNCTION_POINTER(command_delid), LKT_COMMAND_ANON); - cmd_trie_insert(cmd_trie_root, "clear", FUNCTION_POINTER(command_clear), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "crop", FUNCTION_POINTER(command_crop), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "move", FUNCTION_POINTER(command_move), LKT_COMMAND_ANON); @@ -220,13 +222,13 @@ ___cmd_trie_init(void) cmd_trie_insert(cmd_trie_root, "rm", FUNCTION_POINTER(command_plt_remove), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "playlistadd", FUNCTION_POINTER(command_plt_add), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "save", FUNCTION_POINTER(command_plt_export), LKT_COMMAND_ANON); - cmd_trie_insert(cmd_trie_root, "__import", FUNCTION_POINTER(command_plt_import), LKT_COMMAND_ANON); + cmd_trie_insert(cmd_trie_root, "__plt_import", FUNCTION_POINTER(command_plt_import), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "__dump", FUNCTION_POINTER(command_dump), LKT_COMMAND_ANON); cmd_trie_insert(cmd_trie_root, "listplaylists", FUNCTION_POINTER(command_plt_list), LKT_COMMAND_INTEGER); cmd_trie_insert(cmd_trie_root, "listplaylist", FUNCTION_POINTER(command_plt_ctx), LKT_COMMAND_INTEGER); + cmd_trie_insert(cmd_trie_root, "sticker", FUNCTION_POINTER(command_sticker_handle), LKT_COMMAND_SIMPLE); - cmd_trie_insert(cmd_trie_root, "help", FUNCTION_POINTER(command_help), LKT_COMMAND_SIMPLE); - + /* Commands that requires authentification. */ cmd_trie_insert(cmd_trie_root, "password", FUNCTION_POINTER(command_password), LKT_COMMAND_SIMPLE); cmd_trie_insert(cmd_trie_root, "__adduser", FUNCTION_POINTER(command_user_add), LKT_COMMAND_SIMPLE); cmd_trie_insert(cmd_trie_root, "__restart", FUNCTION_POINTER(command_restart), LKT_COMMAND_SIMPLE); @@ -236,8 +238,6 @@ ___cmd_trie_init(void) cmd_trie_insert(cmd_trie_root, "update", FUNCTION_POINTER(command_update), LKT_COMMAND_SIMPLE); cmd_trie_insert(cmd_trie_root, "rescan", FUNCTION_POINTER(command_rescan_false), LKT_COMMAND_SIMPLE); cmd_trie_insert(cmd_trie_root, "config", FUNCTION_POINTER(command_config), LKT_COMMAND_SIMPLE); - - cmd_trie_insert(cmd_trie_root, "sticker", FUNCTION_POINTER(command_sticker_handle), LKT_COMMAND_SIMPLE); // clang-format on cmd_trie_print(cmd_trie_root); @@ -365,121 +365,55 @@ command_list_begin(struct lkt_state *srv, size_t c, int list_ok) static int handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd) { - int err = 0, continuation = 0; + int err = 0; + int continuation = 0; + struct cmd_trie_node *cmd_node = NULL; + union { + bool (*anon)(struct lkt_state *, char *[LKT_MESSAGE_ARGS_MAX]); + bool (*simple)(struct lkt_state *, size_t, char *[LKT_MESSAGE_ARGS_MAX]); + bool (*integer)(struct lkt_state *, size_t, char *[LKT_MESSAGE_ARGS_MAX], int); + void (*base_pointer)(void); + } handle_function; switch (lkt_client_get_mask(srv, c)) { case MPD_IDLE_NONE: - /* Commands that requires authentification. */ - if (STR_MATCH(cmd.name, "__adduser")) - err = !command_user_add(srv, c, cmd.args); - else if (STR_MATCH(cmd.name, "__restart")) - err = !command_restart(srv, c, NULL); - else if (STR_MATCH(cmd.name, "kill")) - err = !command_kill(srv, c, NULL); - else if (STR_MATCH(cmd.name, "update")) - err = !command_update(srv, c, cmd.args); - else if (STR_MATCH(cmd.name, "rescan")) - err = !command_rescan(srv, c, cmd.args, false); - else if (STR_MATCH(cmd.name, "__import")) - err = !command_import(srv, c, cmd.args); - else if (STR_MATCH(cmd.name, "__rescan")) - err = !command_rescan(srv, c, cmd.args, true); - else if (STR_MATCH(cmd.name, "config")) - err = !command_config(srv, c, NULL); - - /* Commands that are available if not in idle mode */ - else if (STR_MATCH(cmd.name, "currentsong")) - err = !command_currentsong(srv, c, NULL); - else if (STR_MATCH(cmd.name, "status")) - err = !command_status(srv, c, NULL); - else if (STR_MATCH(cmd.name, "stats")) - err = !command_stats(srv, c, NULL); + /* First try the 'fast' search with the trie structure */ + cmd_node = cmd_trie_find(cmd_trie_root, cmd.name); + if (cmd_node != NULL) { + handle_function.base_pointer = cmd_node->cmd_ptr; + + switch (cmd_node->type) { + /* Basic command */ + case LKT_COMMAND_SIMPLE: + err = ! handle_function.simple(srv, c, cmd.args); + break; + /* Anonymous client command */ + case LKT_COMMAND_ANON: + err = ! handle_function.anon(srv, cmd.args); + break; + + /* Need the continuation */ + case LKT_COMMAND_INTEGER: + err = ! handle_function.integer(srv, c, cmd.args, cmd.cont); + break; + + /* Unreachable */ + case LKT_COMMAND_NULL: + default: + LOG_UNREACHABLE; + } + } + + /* Some commands are not in the structure because they have a unique + * way to handle arguments. */ else if (STR_MATCH(cmd.name, "close")) err = !lkt_close_client(srv, c); else if (STR_MATCH(cmd.name, "ping")) err = 0; - else if (STR_MATCH(cmd.name, "next")) - err = !command_next(srv, NULL); - else if (STR_MATCH(cmd.name, "pause")) - err = !command_pause(srv, cmd.args); - else if (STR_MATCH(cmd.name, "previous")) - err = !command_previous(srv, NULL); - else if (STR_MATCH(cmd.name, "play")) - err = !command_play(srv, cmd.args); - else if (STR_MATCH(cmd.name, "playid")) - err = !command_playid(srv, cmd.args); - else if (STR_MATCH(cmd.name, "stop")) - err = !command_stop(srv, NULL); - else if (STR_MATCH(cmd.name, "clear")) - err = !command_clear(srv, NULL); - else if (STR_MATCH(cmd.name, "crop")) - err = !command_crop(srv, NULL); - else if (STR_MATCH(cmd.name, "move")) - err = !command_move(srv, cmd.args); - else if (STR_MATCH(cmd.name, "shuffle")) - err = !command_shuffle(srv, NULL); - else if (STR_MATCH(cmd.name, "swap")) - err = !command_swap(srv, cmd.args); - else if (STR_MATCH(cmd.name, "swapid")) - err = !command_swapid(srv, cmd.args); - else if (STR_MATCH(cmd.name, "__flat")) - err = !command_flat(srv, cmd.args); - - else if (STR_MATCH(cmd.name, "seek")) - err = !command_seek(srv, cmd.args); - else if (STR_MATCH(cmd.name, "seekid")) - err = !command_seekid(srv, cmd.args); - else if (STR_MATCH(cmd.name, "seekcur")) - err = !command_seekcur(srv, cmd.args); - - else if (STR_MATCH(cmd.name, "playlistid")) - err = !command_queue_listid(srv, c, cmd.args); - else if (STR_MATCH(cmd.name, "playlist") || STR_MATCH(cmd.name, "playlistinfo")) - err = !command_queue_list(srv, c, cmd.args); - else if (STR_MATCH(cmd.name, "playlistfind") || STR_MATCH(cmd.name, "playlistsearch")) - err = !command_find(srv, c, cmd.args, cmd.cont, database_search_queue_init); - - else if (STR_MATCH(cmd.name, "sticker") && cmd.args[0]) - err = !command_sticker_handle(srv, c, cmd.args); - - else if (STR_MATCH(cmd.name, "help")) - err = !command_help(srv, c, NULL); - - else if (STR_MATCH(cmd.name, "__insert")) - err = !command_add(srv, cmd.args, 5); - else if (STR_MATCH(cmd.name, "searchadd") || STR_MATCH(cmd.name, "findadd") || STR_MATCH(cmd.name, "add")) - err = !command_add(srv, cmd.args, 1); - else if (STR_MATCH(cmd.name, "addid")) - err = !command_addid(srv, cmd.args); - else if (STR_MATCH(cmd.name, "deleteid")) - err = !command_delid(srv, cmd.args); - else if (STR_MATCH(cmd.name, "delete")) - err = !command_del(srv, cmd.args); - - else if (STR_MATCH(cmd.name, "playlistclear")) - err = !command_plt_clear(srv, cmd.args); - else if (STR_MATCH(cmd.name, "rename")) - err = !command_plt_rename(srv, cmd.args); - else if (STR_MATCH(cmd.name, "playlistdelete")) - err = !command_plt_remove(srv, cmd.args); - else if (STR_MATCH(cmd.name, "playlistadd")) - err = !command_plt_add(srv, cmd.args); - else if (STR_MATCH(cmd.name, "rm") && cmd.args[0] != NULL && cmd.args[1] == NULL) - err = !command_plt_remove(srv, cmd.args); - else if (STR_MATCH(cmd.name, "save")) - err = !command_plt_export(srv, cmd.args); - else if (STR_MATCH(cmd.name, "__import")) - err = !command_plt_import(srv, cmd.args); - else if (STR_MATCH(cmd.name, "__dump")) - err = !command_dump(srv, cmd.args); else if (STR_MATCH(cmd.name, "listplaylistinfo")) err = !command_find(srv, c, cmd.args, cmd.cont, database_search_playlist_init); - else if (STR_MATCH(cmd.name, "listplaylists")) - err = !command_plt_list(srv, c, NULL, cmd.cont); - else if (STR_MATCH(cmd.name, "listplaylist")) - err = !command_plt_ctx(srv, c, cmd.args, cmd.cont); else if (STR_MATCH(cmd.name, "random")) err = !command_set_playback_option(srv, c, LKT_PLAYBACK_OPTION_RANDOM, cmd.args); @@ -492,9 +426,6 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd) else if (STR_MATCH(cmd.name, "consume")) err = !command_set_playback_option(srv, c, LKT_PLAYBACK_OPTION_CONSUME, cmd.args); - else if (STR_MATCH(cmd.name, "password")) - err = !command_password(srv, c, cmd.args); - else if (STR_MATCH(cmd.name, "idle")) { err = !command_idle(srv, c, cmd.args); goto end_no_send_status;