diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h index 194881edac4efdc019d519a7ebbf1dc309e3c5cc..5e0a17b6be084c4f42423c76cff622486e4600d9 100644 --- a/inc/lektor/cmd.h +++ b/inc/lektor/cmd.h @@ -4,7 +4,8 @@ #include <stdnoreturn.h> #include <stddef.h> -#define LKT_OPT_NULL { .name = NULL, .call = NULL, .name_len = 0 } +#define LKT_OPT_NULL { .name = NULL, .call = NULL } +#define LKT_OPT_DEFAULT(func) { .name = NULL, .call = func } struct lkt_cmd_args { int argc; /* The number of arguments passed. */ @@ -15,7 +16,6 @@ typedef void (*lkt_cmd_callback)(struct lkt_cmd_args *); struct lkt_cmd_opt { const char *name; - size_t name_len; lkt_cmd_callback call; }; diff --git a/src/cmd.c b/src/cmd.c index f1983fb2882eb159a92dd57803090fa1c741bb7a..6cc748e8c97000744268845946a7e336905dcad2 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -24,6 +24,16 @@ lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **argv, void (*help it = opts + (++offset); } + /* The default function */ + if (!it->name && it->call) { + struct lkt_cmd_args arguments = { + .argc = argc, + .argv = (const char **) argv, + }; + it->call(&arguments); + } + + /* Now search for a unique match */ if (count > 1) goto not_exclusive; diff --git a/src/main/lkt.c b/src/main/lkt.c index cc38dbe34161e22117bfcf6ab9139c0b6ce841e7..1d1adf83400c1ae201ccb011b33b80ac07438c33 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -1,5 +1,6 @@ #define _POSIX_C_SOURCE 200809L +#include <lektor/macro.h> #include <lektor/defines.h> #include <lektor/net.h> #include <lektor/cmd.h> @@ -67,14 +68,12 @@ help(void) " crop crop the queue.\n" "\n" " PLAYLIST COMMANDS:\n" - " help display this help message.\n" " create <plt> creates a playlist after the argument.\n" " destroy <plt> delete a playlist after the argument.\n" " add <plt> <type> <query> add something to a playlist from the database.\n" " delete <plt> <id> delete domething from a playlist.\n" "\n" " SEARCH COMMANDS:\n" - " help display this help message.\n" " get <query> prints the results of the query.\n" " add <query> add to the queue and prints the results of the query.\n" " insert <query> insert on top of the aueue and prints the results of the query.\n" @@ -642,6 +641,78 @@ queue_seek__(struct lkt_cmd_args *args) exit(!strncmp(buf, "OK", 2)); } +noreturn void +queue_list__(struct lkt_cmd_args *args) +{ + char buff[LKT_MESSAGE_MAX], *endptr; + FILE *sock = NULL; + long continuation = 0, up = 0, song_index = 1; + + /* Arguments stuff. */ + + if (args->argc == 0) + args->argv = LKT_QUEUE_DEFAULT; + else if (args->argc != 1) + fail("Invalid argument"); + + continuation = strtol(args->argv[0], &endptr, 0); + if ((errno == ERANGE && (continuation == LONG_MAX || continuation == LONG_MIN)) || (errno != 0 + && continuation == 0) || (endptr == args->argv[0])) + fail("Invalid argument, not an integer"); + + if (*endptr != '\0') + fail("Invalid argument"); + + /* Get the current pos to get limits for the playlist command. */ + sock = lkt_connect(); + if (write_socket(sock, "status\n", sizeof("status\n"))) + fail("Communication error"); + +#define assign_int(str, var) if (! strncmp(buff, str, len)) { var = (atoi(lkt_skip_key(buff))); continue; } + + for (;;) { + memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); + if (read_socket(sock, buff, LKT_MESSAGE_MAX - 1) <= 0) + fail("Connextion error"); + + size_t len = strcspn(buff, LKT_KEY_VALUE_SEP); + assign_int("song", song_index); + + /* At this point every key has been parsed. */ + if (! strncmp(buff, "OK", 2)) + break; + else if (! strncmp(buff, "ACK", 3)) + exit(EXIT_FAILURE); + } + + /* Get the content of the queue. */ + song_index = MAX(song_index, 1); + fclose(sock); +redo: + sock = lkt_connect(); + write_socket_format(sock, "playlist %d:%d\n", continuation, up); + + for (;;) { + memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); + assert(read_socket(sock, buff, LKT_MESSAGE_MAX - 1) > 0); + + if (! strncmp(buff, "continue:", strlen("continue:"))) { + continuation = atoi(lkt_skip_key(buff)); + if (continuation > 0) { + fclose(sock); + goto redo; + } + } + + if (! strncmp(buff, "OK", 2)) + exit(EXIT_SUCCESS); + else if (! strncmp(buff, "ACK", 3)) + exit(EXIT_FAILURE); + + fprintf(stdout, "%s", buff); + } +} + noreturn void queue_pos__(struct lkt_cmd_args *args) { @@ -891,7 +962,7 @@ static struct lkt_cmd_opt options_queue[] = { { .name = "delete", .call = queue_delete__ }, { .name = "clear", .call = queue_clear__ }, { .name = "crop", .call = queue_crop__ }, - LKT_OPT_NULL, + LKT_OPT_DEFAULT(queue_list__), }; static struct lkt_cmd_opt options_plt[] = { @@ -918,7 +989,7 @@ noreturn void queue__(struct lkt_cmd_args *args) { if (args->argc == 0) - fail("Invalid argument, you must specify a sub command for the queue command"); + queue_list__(args); lkt_cmd_parse(options_queue, args->argc, args->argv, help); }