From 9391e5c2ae806d409a2c757c6dca32603dcef3e4 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Fri, 17 Apr 2020 18:01:33 +0200
Subject: [PATCH] Init the empty database

---
 src/main/lktadm.c | 80 +++++++++++++++++++++++++++++++++++++++--------
 src/net/listen.c  |  3 +-
 2 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/src/main/lktadm.c b/src/main/lktadm.c
index 2cc95f68..e263bdfd 100644
--- a/src/main/lktadm.c
+++ b/src/main/lktadm.c
@@ -10,12 +10,21 @@
 #include <lektor/repo.h>
 #include <lektor/utils.h>
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/wait.h>
+
 /* ----------------- *
  * The main function *
  * ----------------- */
 
 static sqlite3 *db = NULL;
-static char kara_dir[PATH_MAX], db_path[PATH_MAX], mkvpropedit[PATH_MAX], buf[100];
+static char kara_dir[PATH_MAX], db_path[PATH_MAX], mkvpropedit[PATH_MAX], sqlite3_bin[PATH_MAX], init_script[PATH_MAX], buf[100];
 
 void
 open_db(void)
@@ -30,21 +39,20 @@ open_db(void)
         exit(EXIT_FAILURE);
     }
 
-    if (!database_config_get_text(db, "externals", "mkvpropedit", mkvpropedit, PATH_MAX)) {
-        fprintf(stderr, " ! could not get the 'mkvpropedit property from the externals section\n'");
+    if (!database_config_get_text(db, "externals", "mkvpropedit", mkvpropedit, PATH_MAX))
         exit(EXIT_FAILURE);
-    }
 
-    if (!database_config_get_text(db, "database", "db_path", db_path, PATH_MAX)) {
-        fprintf(stderr, " ! Failed to get database path\n");
+    if (!database_config_get_text(db, "externals", "sqlite3", sqlite3_bin, PATH_MAX))
         exit(EXIT_FAILURE);
-    }
 
-    if (!database_config_get_text(db, "database", "kara_dir", kara_dir, PATH_MAX)) {
-        fprintf(stderr, " ! Failed to get kara directory\n");
+    if (!database_config_get_text(db, "database", "db_path", db_path, PATH_MAX))
+        exit(EXIT_FAILURE);
+
+    if (!database_config_get_text(db, "database", "kara_dir", kara_dir, PATH_MAX))
         exit(EXIT_FAILURE);
-    }
 
+    if (!database_config_get_text(db, "database", "init_script", init_script, PATH_MAX))
+        exit(EXIT_FAILURE);
 }
 
 noreturn void
@@ -204,6 +212,52 @@ get__(struct lkt_cmd_args *args)
     exit(EXIT_SUCCESS);
 }
 
+noreturn void
+init_database__(struct lkt_cmd_args *args)
+{
+    (void) args;
+    pid_t pid;
+    int wstatus, status, fd;
+    char * sqlite_args[] = { sqlite3_bin, db_path };
+
+    if ((pid = fork()) == 0) {
+        if ((fd = open(init_script, O_RDONLY)) < 0) {
+            fprintf(stderr, " ! init_database__: can't to open %s in O_RDONLY\n", init_script);
+            exit(EXIT_FAILURE);
+        }
+
+        if (dup2(fd, 0) < 0) {
+            fprintf(stderr, " ! init_database__: failed to duplicate %s to stdint\n", init_script);
+            exit(EXIT_FAILURE);
+        }
+
+        execv(sqlite3_bin, sqlite_args);
+        exit(EXIT_FAILURE);
+    }
+
+    else if (pid < 0) {
+        fprintf(stderr, " ! init_database__: failed to fork: %s\n", strerror(errno));
+        exit(EXIT_FAILURE);
+    }
+
+    else {
+        do {
+            if (waitpid(pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
+                fprintf(stderr, " ! init_database__: Failed to wait children: %s\n",
+                        strerror(errno));
+                exit(EXIT_FAILURE);
+            }
+        } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
+
+        if ((status = WEXITSTATUS(wstatus))) {
+            fprintf(stderr, " ! init_database__: children failed with status %d", status);
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    exit(EXIT_SUCCESS);
+}
+
 noreturn void
 download__(struct lkt_cmd_args *args)
 {
@@ -237,7 +291,7 @@ download__(struct lkt_cmd_args *args)
 }
 
 static struct lkt_cmd_opt options_init[] = {
-//    { .name = "database",   .call = init_database__ },
+    { .name = "database",   .call = init_database__ },
     { .name = "populate",   .call = init_populate__ },
     { .name = "metadata",   .call = init_metadata__ },
     LKT_OPT_NULL,
@@ -259,8 +313,8 @@ static struct lkt_cmd_opt options[] = {
 };
 
 int
-main(int argc, char *argv[])
+main(int argc, const char **argv)
 {
-    lkt_cmd_parse(options, argc, (const char **) argv, help);
+    lkt_cmd_parse(options, argc, argv, help);
 }
 
diff --git a/src/net/listen.c b/src/net/listen.c
index dbb96795..5727ada3 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -361,7 +361,6 @@ handle_incoming_data(struct lkt_state *srv, size_t i)
 
     for (;;) {
         /* Recieve some data. */
-recv:
         n = recv(srv->fds[i].fd, cli->buffer_in + cli->buffer_in_len,
                  LKT_MESSAGE_MAX - cli->buffer_in_len, 0);
         if (n < 0) {
@@ -378,7 +377,7 @@ recv:
         for (;;) {
             size_t line_len = strcspn(buf, "\n");
             if (line_len >= cli->buffer_in_len)
-                goto recv;
+                break;
             buf[line_len] = 0;
 
             struct lkt_command cmd = lkt_command_parse(buf);
-- 
GitLab