From d1da1e3abaa2c7751f67d67fb41a4ed0c551a3ab Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Sat, 2 May 2020 10:41:46 +0200
Subject: [PATCH] Some small bug fixes and documentation update. New command
 with lktadm

---
 README.md                      | 48 ++++++++++++++++++----------------
 doc/lktadm.1                   |  4 +++
 inc/common/common.h            |  4 ++-
 inc/common/define.h            |  9 -------
 inc/common/macro.h             |  9 +++++++
 inc/lektor/common.h            |  3 +--
 inc/lektor/config.h            |  2 +-
 inc/mthread/mthread_internal.h |  2 --
 meson.build                    |  1 -
 scripts/install.sh             |  1 +
 src/cmd.c                      |  6 ++---
 src/common.c                   | 12 +++++++++
 src/config.c                   | 18 +++++++++----
 src/main/lktadm.c              | 43 ++++++++++++++++++++++++++++++
 src/mthread/mthread_debug.c    | 13 ---------
 src/net/listen.c               | 19 +++++++-------
 16 files changed, 126 insertions(+), 68 deletions(-)
 delete mode 100644 inc/common/define.h
 delete mode 100644 src/mthread/mthread_debug.c

diff --git a/README.md b/README.md
index a49bf413..749c74c1 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,6 @@ Prerequisites:
 
 - [meson](https://mesonbuild.com/)
 - a C compiler with C18 support (e.g. `gcc>8.1`, `clang>7.0`)
-- the [libpcre](http://www.pcre.org/) development library
 - the [sqlite3](https://www.sqlite.org/) development library, version 3.31.0 or
   newer for [generated columns](https://www.sqlite.org/gencol.html) support
 - the [json-c](https://github.com/json-c/json-c) development library
@@ -25,16 +24,19 @@ configuration file:
 
 - mkvpropedit from [mkvtoolnix](https://gitlab.com/mbunkus/mkvtoolnix)
 - the bourn shell again: [bash](https://git.savannah.gnu.org/cgit/bash.git)
-- the command line tool [sqlite](https://www.sqlite.org/)
+- the command line tool xxd, is distributed in the
+  [vim](https://www.archlinux.org/packages/extra/x86_64/vim/) and
+  [gvim](https://www.archlinux.org/packages/extra/x86_64/gvim/) packages on
+  archlinux, seems to be distributed in its own package on debian:
+  [xxd](https://packages.debian.org/sid/xxd)
 
 The manual way of installing and setting up lektor:
 
 ```sh
-meson build
-ninja -C build
-./build/lktadm init database            # Create the database
-./build/lktadm init metadata            # Modify mkv, if the metadata ar already set do not do this
-./build/lktadm init populate            # Papulate the database with karas on the filesystem
+sudo mkdir /home/kara && sudo chown USER:USER /home/kara
+meson build && cd build
+ninja && ninja install
+sudo chown USER:USER /home/kara/kara.db
 ```
 
 You may need to put the `lib_window_x11.so` in the right directory to have the
@@ -52,20 +54,14 @@ lektor can store it in its database. This information is to be directly
 written in the `.mkv` file.
 
 For that purpose, run the `karadata` from the command-line, with your kara as an
-argument, like:
+argument. For that, karas must be placed in a folder hierarchy like the following:
 
 ```
-./lktadm --file /path/to/my/kara.mkv
+/some/directory/$CAT/$LANG/$AUTH/$SOURCE - $TYPE$NUM - $TITLE.mkv
 ```
 
-or
-
-```
-./lktadm --prompt-file /path/to/my/kara.mkv
-```
-
-A karamaker may use the `scripts/karafont.py` to set the right MIME type for
-fonts (stored as attachments in the mkv).
+The ideal way of populating lektor is using *Kurisu*. The *update* and *rescan*
+commands are here for that.
 
 ## How to launch lektor
 
@@ -78,6 +74,8 @@ card with optimus (in almose every laptop), please use `optirun` or `primusrun`:
 optirun ./lektord
 ```
 
+The `x11` module may have some issues with `optirun` and `primusrun`.
+
 ## How to use lektor
 
 Lektor is compatible with mpd, which means that you can use any client (only mpc is
@@ -94,7 +92,7 @@ done by the same INI file using diferent sections.
 Lektor searches for the configuration file in that order:
 
 - `$(pwd)/lektor.ini`
-- if XDG_CONFIG_HOME defined then `$XDG_CONFIG_HOME/lektor/lektor.ini` else
+- if `XDG_CONFIG_HOME` defined then `$XDG_CONFIG_HOME/lektor/lektor.ini` else
   `$HOME/.config/lektor/lektor.ini`
 - `/opt/lektor/lektor.ini`
 - `/usr/local/etc/lektor.ini`
@@ -103,7 +101,11 @@ Lektor searches for the configuration file in that order:
 The first one to be found is picked up by lektor. Note that if the environment
 variable `XDG_CONFIG_HOME` is not defined, it is replaced by `HOME/.config`.
 
-To get the default config file, you can use the `lktadm` command.
+To get the default config file, you can use the `lktadm` command. To see what
+are the settings used by lektor, you can also use the `lktadm` command.
+
+Be aware that if the home directory or the `XDG_CONFIG_HOME` are too long
+they will be ignored.
 
 ## Modules
 
@@ -114,12 +116,14 @@ function named `module_set_function` which takes a `void *` and a
 The name of this function can be defined in the INI file.
 
 Module can be configured with the ini configuration file in a section named
-`module_${name}`.
+`module_${name}`, this a convention but it can be anything as long as it
+don't make collision with sections used by lektor (may be fine, but don't to
+this!).
 
 Like in the *player*, modules are loaded into slots and **must be** refered by
 their section name. The function used to load the `.so` file will be determied
-depending on the context in which the module is configured and will pass the
-option corresponding on the section's name.
+by the `load_function` property. The path to the `.so` file is determined by
+the `path` property.
 
 ## MPD
 
diff --git a/doc/lktadm.1 b/doc/lktadm.1
index f7309e8b..50bac19f 100644
--- a/doc/lktadm.1
+++ b/doc/lktadm.1
@@ -36,6 +36,10 @@ Display the metadata of a kara specified by the its path
 .TP
 \fBconf\fP
 Prints the default configuration file to stdout
+.TP
+\fBsource\fP
+Prints the configuration that is red by lektor, this is the configuration that
+will use \fBlektord\fP when launched. Usefull when debuging
 
 .PP
 \fIINITIALISATION-COMMANDS\fP
diff --git a/inc/common/common.h b/inc/common/common.h
index 010317a5..47ec6651 100644
--- a/inc/common/common.h
+++ b/inc/common/common.h
@@ -1,7 +1,7 @@
 #pragma once
 
-#include <common/define.h>
 #include <common/macro.h>
+#include <unistd.h>
 
 #define not_implemented() __not_implemented(__func__,__FILE__,__LINE__)
 extern void __not_implemented(const char *func, char *file, int line);
@@ -10,3 +10,5 @@ extern void __not_implemented(const char *func, char *file, int line);
 void __unused(void *, ...);
 
 long get_mtime(const char *path);
+
+void *safe_malloc(size_t size);
diff --git a/inc/common/define.h b/inc/common/define.h
deleted file mode 100644
index 3fd65003..00000000
--- a/inc/common/define.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-/* Max value for any buffer, to not squash the stack. */
-#define BUFFER_MAX 4096
-
-#ifndef __GNUC__
-#define inline
-#endif
-
diff --git a/inc/common/macro.h b/inc/common/macro.h
index b2b33400..be074b7b 100644
--- a/inc/common/macro.h
+++ b/inc/common/macro.h
@@ -1,5 +1,14 @@
 #pragma once
 
+/* Max value for any buffer, to not squash the stack. */
+#define BUFFER_MAX 4096
+
+#ifndef __GNUC__
+#define inline
+#endif
+
+/* Macros */
+
 #define BRACKETS_THAT(that) (that)
 
 #ifndef MAX
diff --git a/inc/lektor/common.h b/inc/lektor/common.h
index 75f81aba..7b0839cb 100644
--- a/inc/lektor/common.h
+++ b/inc/lektor/common.h
@@ -1,7 +1,6 @@
 #pragma once
 
-#include <common/macro.h>
-#include <common/define.h>
+#include <common/common.h>
 #include <stdint.h>
 #include <stdlib.h>
 
diff --git a/inc/lektor/config.h b/inc/lektor/config.h
index 323e900b..f9e91358 100644
--- a/inc/lektor/config.h
+++ b/inc/lektor/config.h
@@ -30,7 +30,7 @@ static const char *const lkt_default_config_file =
     "; can be seen.\n"
     "[player]\n"
     "autoclear = true            ; Clear the queue when starting\n"
-    "module = module_winx11      ; Default module for the window\n"
+    "module = module_x11         ; Default module for the window\n"
     "def_random = false          ; Play at random per default\n"
     "def_consume = false         ; Consume per default\n"
     "def_single = false          ; Single per default\n"
diff --git a/inc/mthread/mthread_internal.h b/inc/mthread/mthread_internal.h
index 0462d0cf..285f337e 100644
--- a/inc/mthread/mthread_internal.h
+++ b/inc/mthread/mthread_internal.h
@@ -60,8 +60,6 @@ void mthread_spinlock_lock  (mthread_tst_t *atomic);
 void mthread_spinlock_unlock(mthread_tst_t *atomic);
 int  mthread_get_vp_rank();
 
-void *safe_malloc(size_t size);
-
 void mthread_insert_first(struct mthread_s *item, mthread_list_t *list);
 void mthread_insert_last (struct mthread_s *item, mthread_list_t *list);
 int  mthread_list_test   (struct mthread_s *item, mthread_list_t *list);
diff --git a/meson.build b/meson.build
index 5d3d4429..b84a924c 100644
--- a/meson.build
+++ b/meson.build
@@ -31,7 +31,6 @@ add_global_arguments('-D_REENTRANT', language: 'c')
 ## Sources for mthread
 mthread_sources = [ 'src/mthread/mthread.c'
                   , 'src/mthread/mthread_cond.c'
-                  , 'src/mthread/mthread_debug.c'
                   , 'src/mthread/mthread_key.c'
                   , 'src/mthread/mthread_mutex.c'
                   , 'src/mthread/mthread_once.c'
diff --git a/scripts/install.sh b/scripts/install.sh
index 213e4d29..71fac2d1 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -15,4 +15,5 @@ type $LKTADM &>/dev/null
 $LKTADM conf > $LKT_INI                             || die
 sed "s+LKT_PREFIX+$MESON_INSTALL_PREFIX+g" $LKT_INI || die
 mkdir /home/kara >&/dev/null                        || echo '/home/kara already exists'
+$LKTADM source                                      || die
 $LKTADM init database                               || die
diff --git a/src/cmd.c b/src/cmd.c
index 4a38bddc..9cd2b012 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -17,7 +17,7 @@ help__()
 {
     if (!executable_name)
         exit(EXIT_FAILURE);
-    const char *const args[] = { man_executable_path, executable_name };
+    const char *const args[] = { man_executable_path, executable_name, NULL };
     execv(args[0], (char *const *) args);
     exit(EXIT_FAILURE);
 }
@@ -29,8 +29,8 @@ lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **argv)
     struct lkt_cmd_opt *it = opts;
     lkt_cmd_callback call[2] = { NULL, NULL };
 
-    if (argc == 0 || *argv == NULL || strcasecmp(argv[0], "help") ||
-        strcasecmp(argv[0], "--help") || strcasecmp(argv[0], "-help"))
+    if (argc == 0 || *argv == NULL || ! strcasecmp(argv[0], "help") ||
+        ! strcasecmp(argv[0], "--help") || ! strcasecmp(argv[0], "-help"))
         goto help;
 
     /* Find the command */
diff --git a/src/common.c b/src/common.c
index 6b906e78..df21628d 100644
--- a/src/common.c
+++ b/src/common.c
@@ -135,3 +135,15 @@ get_mtime(const char *path)
     struct stat statbuf;
     return (stat(path, &statbuf) == -1) ? 0 : statbuf.st_mtime;
 }
+
+void *
+safe_malloc(size_t size)
+{
+    void *tmp;
+    tmp = malloc(size);
+    if (!tmp) {
+        LOG_ERROR_SCT("GENERAL", "Out of memory, can't alloc '%ld' Bytes", size);
+        exit(1);
+    }
+    return tmp;
+}
diff --git a/src/config.c b/src/config.c
index e36fcf6b..e5a7a688 100644
--- a/src/config.c
+++ b/src/config.c
@@ -82,7 +82,7 @@ ini_parse(const char *path, ini_handler handle, volatile sqlite3 *db)
                 value  = &end[1];
 
                 /* Find a comment */
-                end = &value[strcspn(value, ":=")];
+                end = &value[strcspn(value, ";#")];
                 if (end[0])
                     end[0] = '\0';
 
@@ -169,15 +169,16 @@ validate_conf(volatile sqlite3 *db)
     CHK_OPTION("server", "port");
     CHK_OPTION("server", "max_clients");
 
-    CHK_OPTION("player", "module");
+    CHK_OPTION("database", "kara_dir");
+    CHK_OPTION("database", "db_path");
+
     CHK_OPTION("player", "autoclear");
     CHK_OPTION("player", "def_random");
     CHK_OPTION("player", "def_consume");
     CHK_OPTION("player", "def_single");
     CHK_OPTION("player", "def_repeat");
-
-    CHK_OPTION("database", "kara_dir");
-    CHK_OPTION("database", "db_path");
+    CHK_OPTION("player", "module");
+#undef CHK_OPTION
 
     return 0;
 }
@@ -212,6 +213,12 @@ config_detect_file(char *conf, size_t conf_len)
 
     /* Try the config file from the config directory. */
     home = getenv("XDG_CONFIG_HOME");
+    if (home && strlen(home) < conf_len) {
+        /* Skip the strncat to not append the '.config/' to
+           the XDG_CONFIG_HOME which must already have this directory in it */
+        strncat(conf, "/lektor/lektor.ini", conf_len - 1);
+        goto skip_this_strcat;
+    }
     if (!home || (strlen(home) >= conf_len))
         home = getenv("HOME");
     if (!home || (strlen(home) >= conf_len))
@@ -220,6 +227,7 @@ config_detect_file(char *conf, size_t conf_len)
         goto no_config_directory;
     memcpy(conf, home, (strlen(home) + 1) * sizeof(char));
     strncat(conf, "/.config/lektor/lektor.ini", conf_len - 1);
+skip_this_strcat:
     LOG_INFO("Trying %s", conf);
     if (!access(conf, R_OK | F_OK))
         goto found;
diff --git a/src/main/lktadm.c b/src/main/lktadm.c
index df2846b6..a67d8d28 100644
--- a/src/main/lktadm.c
+++ b/src/main/lktadm.c
@@ -228,6 +228,48 @@ download__(struct lkt_cmd_args *args)
     exit(EXIT_SUCCESS);
 }
 
+noreturn void
+source__(struct lkt_cmd_args *args)
+{
+    if (args->argc != 0)
+        fail("The source command takes no arguments");
+    char value[INI_MAX_LINE_LEN];
+    char player_mod[INI_MAX_LINE_LEN];
+    open_db();
+    if (!database_open(db, db_path))
+        fail("Failed to open database");
+
+#define CHK_OPTION(section, name)                                                   \
+    if (!database_config_get_text(db, section, name, value, INI_MAX_LINE_LEN)) {    \
+        LOG_ERROR("Failed to get value for option '[%s] %s'", section, name);       \
+        exit(EXIT_FAILURE);                                                         \
+    }                                                                               \
+    printf("[%s]\t%s -> %s\n", section, name, value);
+
+    CHK_OPTION("externals", "mkvpropedit");
+
+    CHK_OPTION("server", "host");
+    CHK_OPTION("server", "port");
+    CHK_OPTION("server", "max_clients");
+
+    CHK_OPTION("player", "module");
+    memcpy(player_mod, value, INI_MAX_LINE_LEN);
+    CHK_OPTION("player", "autoclear");
+    CHK_OPTION("player", "def_random");
+    CHK_OPTION("player", "def_consume");
+    CHK_OPTION("player", "def_single");
+    CHK_OPTION("player", "def_repeat");
+
+    CHK_OPTION("database", "kara_dir");
+    CHK_OPTION("database", "db_path");
+
+    CHK_OPTION(player_mod, "path");
+    CHK_OPTION(player_mod, "load_function");
+#undef CHK_OPTION
+
+    exit(EXIT_SUCCESS);
+}
+
 static struct lkt_cmd_opt options_init[] = {
     { .name = "database",   .call = init_database__  },
     { .name = "populate",   .call = init_populate__  },
@@ -248,6 +290,7 @@ static struct lkt_cmd_opt options[] = {
     { .name = "download",   .call = download__ },
     { .name = "cat",        .call = cat__      },
     { .name = "conf",       .call = conf__     },
+    { .name = "source",     .call = source__   },
     LKT_OPT_NULL,
 };
 
diff --git a/src/mthread/mthread_debug.c b/src/mthread/mthread_debug.c
deleted file mode 100644
index 3230f816..00000000
--- a/src/mthread/mthread_debug.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include <mthread/mthread_internal.h>
-#include <assert.h>
-
-void *
-safe_malloc(size_t size)
-{
-    void *tmp;
-    tmp = malloc(size);
-    assert(tmp != NULL);
-    return tmp;
-}
diff --git a/src/net/listen.c b/src/net/listen.c
index e7211030..489c5e79 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -1,5 +1,6 @@
 #define _POSIX_C_SOURCE 200809L
 
+#include <common/common.h>
 #include <lektor/commands.h>
 #include <lektor/common.h>
 #include <lektor/database.h>
@@ -687,7 +688,7 @@ lkt_client_auth(struct lkt_state *srv, size_t c, bool set)
 int
 lkt_listen(void)
 {
-    char *memory = (char *) calloc(2 * PATH_MAX + HOST_NAME_MAX + 3, sizeof(char));
+    char *memory = (char *) safe_malloc((2 * PATH_MAX + HOST_NAME_MAX + 3) * sizeof(char));
     RETURN_UNLESS(memory, "Out of memory", 5);
 
     struct lkt_state srv;
@@ -701,13 +702,13 @@ lkt_listen(void)
     memset(&srv, 0, sizeof(struct lkt_state));
 
     /* Initialize the system. */
-    RETURN_UNLESS(database_new(&srv.db), "Failed to initialize the memory database", 1);
-    RETURN_IF(config_detect_file(conf_file, PATH_MAX), "Failed to find a config file", 1);
-    RETURN_IF(config_new(srv.db, conf_file), "Failed to read configuration file", 1);
+    RETURN_UNLESS(database_new(&srv.db),                   "Failed to initialize the memory database", 1);
+    RETURN_IF    (config_detect_file(conf_file, PATH_MAX), "Failed to find a config file",             1);
+    RETURN_IF    (config_new(srv.db, conf_file),           "Failed to read configuration file",        1);
 
     /* Finish to initialize. */
-    RETURN_UNLESS(database_config_get_text(srv.db, "database", "db_path", db_path, PATH_MAX), "Cfg error", 2);
-    RETURN_UNLESS(database_open(srv.db, db_path), "Can't open database", 1);
+    RETURN_UNLESS(database_config_get_text(srv.db, "database", "db_path", db_path, PATH_MAX), "Cfg error",           2);
+    RETURN_UNLESS(database_open(srv.db, db_path),                                             "Can't open database", 1);
 
     /* Read the configuration. */
     RETURN_UNLESS(database_config_get_int (srv.db, "player",   "autoclear", &autoclear),                   "Cfg error", 2);
@@ -736,10 +737,10 @@ lkt_listen(void)
     if (autoclear)
         database_queue_clear(srv.db);
 
-    RETURN_UNLESS(load_module_by_name(srv.db, player_mod, &srv.win), "Can't load module", 3);
-    RETURN_UNLESS(srv.win.new(&srv.win), "Can't create window", 3);
+    RETURN_IF    (repo_new(&srv.repo, "kurisu", "https://kurisu.iiens.net", srv.db), "Failed to create repo", 4);
+    RETURN_UNLESS(load_module_by_name(srv.db, player_mod, &srv.win),                 "Can't load module",     3);
+    RETURN_UNLESS(srv.win.new(&srv.win),                                             "Can't create window",   3);
     srv.win.attach(&srv.win, &srv);
-    RETURN_IF(repo_new(&srv.repo, "kurisu", "https://kurisu.iiens.net", srv.db), "Failed to create repo", 4);
 
     for (;;) {
         if (handle_network_events(&srv) < 0)
-- 
GitLab