From 04175995f76b73f7456143f11d9a39934009736f Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Wed, 30 Dec 2020 18:07:20 +0100
Subject: [PATCH] LKT: The new function to get the queries should be used
 everywhere [to be tested]

---
 man/lektor.template |   1 +
 src/main/lkt.c      | 160 ++++++++++++++++----------------------------
 2 files changed, 60 insertions(+), 101 deletions(-)

diff --git a/man/lektor.template b/man/lektor.template
index 53ed13d2..49766112 100644
--- a/man/lektor.template
+++ b/man/lektor.template
@@ -38,6 +38,7 @@ Lektord can be piloted over the network with \fBlkt\fP.
 \fBPlaylists and stickers\fP
 Reading and searching through the base can be facilitated by creating
 \fIplaylist\fP and using \fIstickers\fP (\fIMPD\fP version of tags).
+
 .SH "INSTALLATION"
 You may install lektor from source like this:
 .sp
diff --git a/src/main/lkt.c b/src/main/lkt.c
index 2ebe7a81..9a3eba1d 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -55,29 +55,6 @@ static const char *LKT_QUEUE_DEFAULT[] = { "10" };
 
 /* Communication functions and fonction that interact with lektor stuff. */
 
-static int
-lkt_valid_type(const char *type)
-{
-    return (STR_MATCH(type, "query")    ||
-            STR_MATCH(type, "category") ||
-            STR_MATCH(type, "author")   ||
-            STR_MATCH(type, "lang")     ||
-            STR_MATCH(type, "id")       ||
-            STR_MATCH(type, "type")     ||
-            STR_MATCH(type, "playlist"));
-}
-
-enum lkt_query_type {
-    LKT_QUERY_TYPE_ERROR = 0,
-    LKT_QUERY_TYPE_ID,
-    LKT_QUERY_TYPE_LANG,
-    LKT_QUERY_TYPE_AUTHOR,
-    LKT_QUERY_TYPE_CAT,
-    LKT_QUERY_TYPE_TYPE,
-    LKT_QUERY_TYPE_PLAYLIST,
-    LKT_QUERY_TYPE_QUERY,
-};
-
 static inline int
 __string_is_lower(const char *str)
 {
@@ -109,13 +86,11 @@ __concat_strings(char *const res, size_t len, const char **tab, size_t count)
     strncat(res, tab[i], len - 1);
 }
 
-__attribute__((unused)) static int
-lkt_get_query_type(struct cmd_args *args, enum lkt_query_type *type,
-                   char *const regex, size_t regex_len)
+static int
+lkt_get_query_type(struct cmd_args *args, char *const regex, size_t regex_len)
 {
     if (args->argc == 0) {
         LOG_ERROR("LKT", "Invalid empty query");
-        *type = LKT_QUERY_TYPE_ERROR;
         return 1;
     }
 
@@ -126,8 +101,7 @@ lkt_get_query_type(struct cmd_args *args, enum lkt_query_type *type,
         errno = 0;
         id = strtol(args->argv[0], NULL, 10);
         if (id != 0 && errno == 0) {
-            *type = LKT_QUERY_TYPE_ID;
-            safe_snprintf(regex, regex_len, "%ld", id);
+            safe_snprintf(regex, regex_len, "id://%ld", id);
             return 0;
         }
 
@@ -135,11 +109,10 @@ lkt_get_query_type(struct cmd_args *args, enum lkt_query_type *type,
         else if (__string_is_upper(args->argv[0])) {
 #define kara_category(unused)
 #define kara_language(unused)
-#define kara_type(tp)                                       \
-if (STR_MATCH(tp, args->argv[0])) {                         \
-    *type = LKT_QUERY_TYPE_TYPE;                            \
-    safe_snprintf(regex, regex_len, "%s", args->argv[0]);   \
-    return 0;                                               \
+#define kara_type(tp)                                               \
+if (STR_MATCH(tp, args->argv[0])) {                                 \
+    safe_snprintf(regex, regex_len, "type://%s", args->argv[0]);    \
+    return 0;                                                       \
 }
 #include <lektor/database.def>
 #undef kara_category
@@ -150,17 +123,15 @@ if (STR_MATCH(tp, args->argv[0])) {                         \
         /* Type ?== category OR Type ?== lang */
         else if (__string_is_lower(args->argv[0])) {
 #define kara_type(unused)
-#define kara_category(ct)                                   \
-if (STR_MATCH(ct, args->argv[0])) {                         \
-    *type = LKT_QUERY_TYPE_CAT;                             \
-    safe_snprintf(regex, regex_len, "%s", args->argv[0]);   \
-    return 0;                                               \
+#define kara_category(ct)                                               \
+if (STR_MATCH(ct, args->argv[0])) {                                     \
+    safe_snprintf(regex, regex_len, "category://%s", args->argv[0]);    \
+    return 0;                                                           \
 }
-#define kara_language(lg)                                   \
-if (STR_MATCH(lg, args->argv[0])) {                         \
-    *type = LKT_QUERY_TYPE_LANG;                            \
-    safe_snprintf(regex, regex_len, "%s", args->argv[0]);   \
-    return 0;                                               \
+#define kara_language(lg)                                           \
+if (STR_MATCH(lg, args->argv[0])) {                                 \
+    safe_snprintf(regex, regex_len, "lang://%s", args->argv[0]);    \
+    return 0;                                                       \
 }
 #include <lektor/database.def>
 #undef kara_category
@@ -175,14 +146,14 @@ if (STR_MATCH(lg, args->argv[0])) {                         \
     if (args->argc >= 2) {
         /* Type ?== author */
         if (STR_MATCH("author", args->argv[0])) {
-            *type = LKT_QUERY_TYPE_AUTHOR;
+            strncat(regex, "author://", regex_len - 1);
             __concat_strings(regex, regex_len, args->argv + 1, args->argc - 1);
             return 0;
         }
 
         /* Type ?== playlist */
         else if (STR_MATCH("plt", args->argv[0]) || STR_MATCH("playlist", args->argv[0])) {
-            *type = LKT_QUERY_TYPE_PLAYLIST;
+            strncat(regex, "playlist://", regex_len - 1);
             __concat_strings(regex, regex_len, args->argv + 1, args->argc - 1);
             return 0;
         }
@@ -191,32 +162,29 @@ if (STR_MATCH(lg, args->argv[0])) {                         \
 
         /* Type ?== category */
         else if (STR_MATCH("cat", args->argv[0]) || STR_MATCH("category", args->argv[0])) {
-            *type = LKT_QUERY_TYPE_CAT;
-            safe_snprintf(regex, regex_len, "%s", args->argv[0]);
+            strncat(regex, "category://", regex_len - 1);
+            safe_snprintf(regex, regex_len, "category://%s", args->argv[0]);
             return 0;
         }
 
         /* Type ?== lang */
         else if (STR_MATCH("lang", args->argv[0]) || STR_MATCH("language", args->argv[0])) {
-            *type = LKT_QUERY_TYPE_LANG;
-            safe_snprintf(regex, regex_len, "%s", args->argv[0]);
+            safe_snprintf(regex, regex_len, "lang://%s", args->argv[0]);
             return 0;
         }
 
         /* Type ?== type */
         if (STR_MATCH("type", args->argv[0])) {
-            *type = LKT_QUERY_TYPE_TYPE;
-            safe_snprintf(regex, regex_len, "%s", args->argv[0]);
+            safe_snprintf(regex, regex_len, "type://%s", args->argv[0]);
             return 0;
         }
     }
 
     /* If 'query' is specified, skip it */
     int index = STR_MATCH("query", args->argv[0]) ? 1 : 0;
-    strncat(regex, "%", regex_len - 1);
+    strncat(regex, "query://%", regex_len - 1);
     __concat_strings(regex, regex_len, args->argv + index, args->argc - index);
     strncat(regex, "%", regex_len - 1);
-    *type = LKT_QUERY_TYPE_QUERY;
     return 0;
 }
 
@@ -310,15 +278,14 @@ lkt_skip_key(char *buffer)
 static inline void
 send_cmd_with_uri(FILE *sock, char *cmd, int argc, const char **argv)
 {
-    int i;
-    char buf[LKT_MESSAGE_MAX] = {0};
-    for (i = 1; i < argc - 1; ++i) {
-        strncat(buf, argv[i], LKT_MESSAGE_MAX - 1);
-        strncat(buf, " ", LKT_MESSAGE_MAX - 1);
-    }
-    strncat(buf, argv[i], LKT_MESSAGE_MAX - 1);
-    strncat(buf, "\n", LKT_MESSAGE_MAX - 1);
-    write_socket(sock, "%s %s://%s", cmd, argv[0], buf);
+    char buf[LKT_MESSAGE_MAX];
+    struct cmd_args args = {
+        .argc = argc,
+        .argv = argv,
+    };
+    memset(buf, 0, LKT_MESSAGE_MAX * sizeof(char));
+    fail_if(lkt_get_query_type(&args, buf, LKT_MESSAGE_MAX), "Query is invalid");
+    write_socket(sock, "%s %s\n", cmd, buf);
 }
 
 /* Functions implementing options. */
@@ -386,8 +353,6 @@ rescan_or_update__(struct cmd_args *args, const char *cmd)
     if (!password)
         fail("Password not provided");
     FILE *sock = lkt_connect();
-    char buff[LKT_MESSAGE_MAX];
-    int i;
 
     /* All the db */
     if (args->argc == 0) {
@@ -399,9 +364,9 @@ rescan_or_update__(struct cmd_args *args, const char *cmd)
 
     /* With a query */
     else {
+        char buff[LKT_MESSAGE_MAX];
         memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char));
-        for (i = 0; i < args->argc; ++i)
-            strncat(buff, args->argv[i], LKT_MESSAGE_MAX - 1);
+        fail_if(lkt_get_query_type(args, buff, LKT_MESSAGE_MAX), "Query is not valid");
         write_socket(sock, "command_list_begin\n");
         write_socket(sock, "password %s\n", password);
         write_socket(sock, "%s %s\n", cmd, buff);
@@ -764,7 +729,6 @@ queue_add__(struct cmd_args *args)
 {
     char buff[3];
     fail_if(args->argc < 1, "Invalid arguments");
-    fail_if(!lkt_valid_type(args->argv[0]), "Invalid query type");
     FILE *sock = lkt_connect();
     send_cmd_with_uri(sock, "add", args->argc, args->argv);
     exit_with_status(sock, buff);
@@ -775,7 +739,6 @@ queue_insert__(struct cmd_args *args)
 {
     char buff[3];
     fail_if(args->argc < 1, "Invalid arguments");
-    fail_if(!lkt_valid_type(args->argv[0]), "Invalid query type");
     FILE *sock = lkt_connect();
     send_cmd_with_uri(sock, "__insert", args->argc, args->argv);
     exit_with_status(sock, buff);
@@ -913,21 +876,18 @@ noreturn void
 plt_add__(struct cmd_args *args)
 {
     char buff[2];
-    FILE *sock = lkt_connect();
-    fail_if(args->argc < 3,
+    fail_if(args->argc < 2,
             "Invalid argument, need at least three arguments: plt add <plt> <query>");
-    fail_if(!lkt_valid_type(args->argv[1]), "Invalid argument, type for the query is invalid");
 
-    int i;
-    char buf[LKT_MESSAGE_MAX] = {0};
-    for (i = 2; i < args->argc - 1; ++i) {
-        strncat(buf, args->argv[i], LKT_MESSAGE_MAX - 1);
-        strncat(buf, " ", LKT_MESSAGE_MAX - 1);
-    }
-    strncat(buf, args->argv[i], LKT_MESSAGE_MAX - 1);
-    strncat(buf, "\n", LKT_MESSAGE_MAX - 1);
-    write_socket(sock, "playlistadd %s %s://%s", args->argv[0], args->argv[1], buf);
+    char regex[LKT_MESSAGE_MAX];
+    struct cmd_args args_regex = {
+        .argc = args->argc - 1,
+        .argv = args->argv + 1,
+    };
 
+    fail_if(lkt_get_query_type(&args_regex, regex, LKT_MESSAGE_MAX), "Query is invalid");
+    FILE *sock = lkt_connect();
+    write_socket(sock, "playlistadd %s %s\n", args->argv[0], regex);
     exit_with_status(sock, buff);
 }
 
@@ -1052,19 +1012,16 @@ list_plt_content__(struct cmd_args *args)
 noreturn void
 search_with_cmd__(struct cmd_args *args, const char *cmd)
 {
-    fail_if(args->argc < 2,                 "Invalid number of arguments");
-    fail_if(!lkt_valid_type(args->argv[0]), "Invalid type for the query");
-
     char buff[LKT_MESSAGE_MAX];
-    int continuation = 0, i;
+    char regex[LKT_MESSAGE_MAX];
+    int continuation = 0;
     FILE *sock = NULL;
+
+    fail_if(lkt_get_query_type(args, regex, LKT_MESSAGE_MAX), "Query is invalid");
+
 redo:
     sock = lkt_connect();
-
-    write_socket(sock, "%d %s %s://", continuation, cmd, args->argv[0]);
-    for (i = 1; i < args->argc - 1; ++i)
-        write_socket(sock, "%s ", args->argv[i]);
-    write_socket(sock, "%s\n", args->argv[i]);
+    write_socket(sock, "%d %s %s\n", continuation, cmd, regex);
 
     for (;;) {
         memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char));
@@ -1113,19 +1070,20 @@ search_plt__(struct cmd_args *args)
     if (args->argc == 1)
         list_plt_content__(args);
 
-    fail_if(args->argc < 3, "Invalid number of arguments");
-    fail_if(!lkt_valid_type(args->argv[1]), "Invalid type for query");
     char buff[LKT_MESSAGE_MAX];
-    int continuation = 0, i;
+    char regex[LKT_MESSAGE_MAX];
+    int continuation = 0;
     FILE *sock = NULL;
+    struct cmd_args args_regex = {
+        .argc = args->argc - 1,
+        .argv = args->argv + 1,
+    };
+
+    fail_if(args->argc < 2, "Invalid number of arguments");
+    fail_if(lkt_get_query_type(&args_regex, regex, LKT_MESSAGE_MAX), "Query is invalid");
 redo:
     sock = lkt_connect();
-
-    write_socket(sock, "%d listplaylistinfo %s %s://", continuation,
-                 args->argv[0], args->argv[1]);
-    for (i = 2; i < args->argc - 1; ++i)
-        write_socket(sock, "%s ", args->argv[i]);
-    write_socket(sock, "%s\n", args->argv[i]);
+    write_socket(sock, "%d listplaylistinfo %s %s\n", continuation, args->argv[0], regex);
 
     for (;;) {
         memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char));
@@ -1260,7 +1218,7 @@ parse_args(args_t *args, int argc, const char **argv)
     size_t len;
 
     for (i = 1; i < argc && i < 3; ++i) {
-        len = strcspn(argv[i], "=");
+        len = strcspn(argv[i], "=:");
 
         if (STR_NMATCH("host", argv[i], len)) {
             args->host = (argv[i] + len + 1);
@@ -1289,7 +1247,7 @@ main(int argc, const char **argv)
     executable_name = "lkt";
     assert(NULL != setlocale(LC_ALL, "en_US.UTF-8")); /* BECAUSE! */
     if (signal(SIGPIPE, sigpipe__))
-        LOG_ERROR("SYS", "Failed to install handler for SIGPIPE signal");
+        LOG_ERROR("SYS", "Failed to install handler for SIGPIPE signal (you may be using php...)");
 
     args_t args = {
         .host = "localhost",
-- 
GitLab