From dc5a269097c9314fbc2cd99ec0eb1166b01c3eff Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Sat, 30 Oct 2021 11:40:39 +0200
Subject: [PATCH] CONF: Clean up a bit the config API

---
 inc/lektor/config.h | 22 ++++-----------
 src/base/config.c   | 68 +++++++++++++++++++++++++++++++++++++++------
 src/main/luka.c     |  4 +--
 src/main/server.c   | 49 +-------------------------------
 src/net/listen.c    | 12 ++++----
 5 files changed, 73 insertions(+), 82 deletions(-)

diff --git a/inc/lektor/config.h b/inc/lektor/config.h
index 1a5a399d..ad0a4522 100644
--- a/inc/lektor/config.h
+++ b/inc/lektor/config.h
@@ -24,27 +24,15 @@ static const char *const lkt_default_config_file =
 #undef value_opt
 #undef section
 
-/* It is just an alias to the consecutive use of config_detect_file and
-   config_new function, with the return an '&&' between the two returns of the
-   two other functions. */
-int config_open(lkt_db *db);
-
-/* Get the path to the config file that may be red, taking into account the
-   priority between existing files. The returned path is a path to an existing
-   file. If no file is found, returns a non zero value. Returns 1 otherwise. */
-int config_detect_file(char *conf, size_t conf_len);
-
-/* Create and read the configuration in the conf file and write it into
-   lkt_conf. The type is opaque because it's a C++ class.
-   Return 0 if the read operation was a success, a non zero value otherwise. */
-int config_new(lkt_db *db, const char *conf);
+/* Try to open the config file `maybe_conf` or find the one to use (see conf
+ * file priorities). If no config file is found, one is created at the user
+ * level. Returns 0 on success, 1 on failure. Note that the `maybe_conf` buffer
+ * of length `maybe_conf_len` will be used to store the used config file path. */
+int config_open(lkt_db *db, char *maybe_conf, size_t maybe_conf_len);
 
 /* Prints the default config file. */
 void config_default(FILE *output);
 
-/* Get the default user config file, the ~/.config/lektor/lektor.ini file. */
-void config_default_file(char *dest, size_t len);
-
 /* Manipulate Environment Variables */
 #define env_set(var, val) setenv(var, val, 1)
 #define env_get           getenv
diff --git a/src/base/config.c b/src/base/config.c
index 41d567be..de0cdb2d 100644
--- a/src/base/config.c
+++ b/src/base/config.c
@@ -7,6 +7,19 @@
 #include <dlfcn.h>
 #include <pwd.h>
 
+/* Get the path to the config file that may be red, taking into account the
+   priority between existing files. The returned path is a path to an existing
+   file. If no file is found, returns a non zero value. Returns 1 otherwise. */
+PRIVATE_FUNCTION int config_detect_file(char *conf, size_t conf_len);
+
+/* Create and read the configuration in the conf file and write it into
+   lkt_conf. The type is opaque because it's a C++ class.
+   Return 0 if the read operation was a success, a non zero value otherwise. */
+PRIVATE_FUNCTION int config_new(lkt_db *db, const char *conf);
+
+/* Get the default user config file, the ~/.config/lektor/lektor.ini file. */
+PRIVATE_FUNCTION void config_default_file(char *dest, size_t len);
+
 static inline char *
 strip(char *s)
 {
@@ -171,7 +184,7 @@ ini_parse(const char *path, lkt_db *db)
     return error;
 }
 
-void
+PRIVATE_FUNCTION void
 config_default_file(char *dest, size_t len)
 {
     /* First try the XDG_CONFIG_HOME variable, else the default location HOME/.config. */
@@ -189,7 +202,7 @@ config_default_file(char *dest, size_t len)
         strncat(dest, "/lektor/lektor.ini", len - 1);
 }
 
-int
+PRIVATE_FUNCTION int
 config_detect_file(char *conf, size_t conf_len)
 {
     bool is_malloc    = false;
@@ -260,7 +273,7 @@ found:
     return 0;
 }
 
-int
+PRIVATE_FUNCTION int
 config_new(lkt_db *db, const char *conf)
 {
     if (ini_parse(conf, db)) {
@@ -290,13 +303,52 @@ config_default(FILE *output)
     fwrite(lkt_default_config_file, sizeof(char), strlen(lkt_default_config_file), output);
 }
 
+/* Recursive mkdir, where the last word of the string is a file, not a folder. */
+PRIVATE_FUNCTION void
+__mkdir(const char *dir)
+{
+    char tmp[PATH_MAX];
+    char *p = NULL;
+    safe_snprintf(tmp, sizeof(tmp), "%s", dir);
+    size_t len = strlen(tmp);
+    /* In our case, the final word is always a file, not a folder. */
+    if (tmp[len - 1] == '/')
+        tmp[len - 1] = 0;
+    for (p = tmp + 1; *p; p++) {
+        if (*p == '/') {
+            *p = 0;
+            mkdir(tmp, 00700);
+            *p = '/';
+        }
+    }
+    /* Don't do final mkdir here, because in our case the final word in the string
+     * is a file, not a folder.
+     * mkdir(tmp, S_IRWXU); */
+}
+
 int
-config_open(lkt_db *db)
+config_open(lkt_db *db, char *conf_file, size_t conf_len)
 {
-    char conf_file[PATH_MAX];
-    RETURN_IF(config_detect_file(conf_file, PATH_MAX), "Error while searching for a config file",
-              1);
-    RETURN_IF(config_new(db, conf_file), "Failed to read configuration file", 1);
+    int retry_config_once = 0;
+retry_config:
+    if (conf_file[0] == '\0' && config_detect_file(conf_file, conf_len)) {
+        RETURN_IF(retry_config_once, "Failed to find a config file", 1);
+
+        LOG_INFO("INIT", "Creating default config file");
+        config_default_file(conf_file, conf_len);
+        __mkdir(conf_file); /* Create the folder for the file. */
+
+        FILE *file_desc = fopen(conf_file, "w+");
+        RETURN_UNLESS(file_desc, "Failed to open default config file to initialize it", 1);
+        config_default(file_desc);
+        fclose(file_desc);
+
+        LOG_INFO("INIT", "Default configuration file has been writen to %s", conf_file);
+        retry_config_once = 1;
+        goto retry_config;
+    }
+
+    RETURN_IF(config_new(db, conf_file), "Failed to read the config", 1);
     return 0;
 }
 
diff --git a/src/main/luka.c b/src/main/luka.c
index f0fbd5df..c49d87aa 100644
--- a/src/main/luka.c
+++ b/src/main/luka.c
@@ -61,9 +61,7 @@ ___setup(void)
     reg_export(luka_reg);
 
     FAIL_UNLESS(database_new((lkt_db **)&__db), "Can't init sqlite database");
-    FAIL_IF(config_detect_file(path, PATH_MAX),
-            "Can't find a config file, did you run lektord at least once?");
-    FAIL_IF(config_new(__db, path), "Failed to read the config");
+    FAIL_IF(config_open(__db, path, PATH_MAX), "Failed to read the config");
 
     database_config_get_text(__db, "database", "db_path", path, PATH_MAX);
     FAIL_UNLESS(database_open(__db, path, true), "Can't open database %s", path);
diff --git a/src/main/server.c b/src/main/server.c
index 804b0e78..1808cd00 100644
--- a/src/main/server.c
+++ b/src/main/server.c
@@ -52,29 +52,6 @@ ___tty_enable_echo(void)
     RETURN_IF(fflush(stdin) != 0, "Failed to flush stdin", NOTHING);
 }
 
-/* Recursive mkdir, where the last word of the string is a file, not a folder. */
-PRIVATE_FUNCTION void
-__mkdir(const char *dir)
-{
-    char tmp[PATH_MAX];
-    char *p = NULL;
-    safe_snprintf(tmp, sizeof(tmp), "%s", dir);
-    size_t len = strlen(tmp);
-    /* In our case, the final word is always a file, not a folder. */
-    if (tmp[len - 1] == '/')
-        tmp[len - 1] = 0;
-    for (p = tmp + 1; *p; p++) {
-        if (*p == '/') {
-            *p = 0;
-            mkdir(tmp, 00700);
-            *p = '/';
-        }
-    }
-    /* Don't do final mkdir here, because in our case the final word in the string
-     * is a file, not a folder.
-     * mkdir(tmp, S_IRWXU); */
-}
-
 int
 main(int argc, char *argv[])
 {
@@ -131,31 +108,7 @@ main(int argc, char *argv[])
 
     FAIL_IF(lkt_queue_new(&srv.queue), "Failed to create server queue");
     FAIL_UNLESS(database_new(&srv.db), "Failed to init memory database");
-
-    /* Read or create default config file. */
-    {
-        int retry_config_once = 0;
-    retry_config:
-        if (conf_file[0] == '\0' && config_detect_file(conf_file, PATH_MAX)) {
-            FAIL_IF(retry_config_once, "Failed to find a config file");
-
-            LOG_INFO("INIT", "Creating default config file");
-            config_default_file(conf_file, PATH_MAX);
-            __mkdir(conf_file); /* Create the folder for the file. */
-
-            FILE *file_desc = fopen(conf_file, "w+");
-            FAIL_UNLESS(file_desc, "Failed to open default config file '%s' to initialize it",
-                        conf_file);
-            config_default(file_desc);
-            fclose(file_desc);
-
-            LOG_INFO("INIT", "Default configuration file has been writen to %s", conf_file);
-            retry_config_once = 1;
-            goto retry_config;
-        }
-    }
-
-    FAIL_IF(config_new(srv.db, conf_file), "Failed to read the config");
+    FAIL_IF(config_open(srv.db, conf_file, PATH_MAX), "Failed to open or create the config file");
 
     /* Dump and abort here, if we are dumping informations about the server */
     if (dump_and_abort) {
diff --git a/src/net/listen.c b/src/net/listen.c
index 0d058459..79e4f01a 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -1083,10 +1083,10 @@ static int ___lkt_signal_USR2 = 0; /* SIGUSR2 => not used         */
 PRIVATE_FUNCTION void
 ___signal_handler(int sig)
 {
-#define ___HANDLE(signal)                              \
+#define ___HANDLE(signal)                             \
     case SIG##signal:                                 \
         LOG_INFO("SIGNAL", "Got signal SIG" #signal); \
-        ___lkt_signal_##signal = 1;                    \
+        ___lkt_signal_##signal = 1;                   \
         break;
 
     switch (sig) {
@@ -1139,11 +1139,11 @@ ___lkt_handle_USR2(struct lkt_state UNUSED *srv)
 static inline void
 handle_signals(struct lkt_state *srv)
 {
-#define ___HANDLE(srv, signal)                                                  \
-    if (___lkt_signal_##signal) {                                               \
+#define ___HANDLE(srv, signal)                                                 \
+    if (___lkt_signal_##signal) {                                              \
         LOG_INFO("SIGNAL", "Server in handle phase for signal SIG" #signal);   \
-        if (srv->___signal_##signal)                                            \
-            srv->___signal_##signal(srv);                                       \
+        if (srv->___signal_##signal)                                           \
+            srv->___signal_##signal(srv);                                      \
         else                                                                   \
             LOG_WARN("SIGNAL", "No signal handler in server for SIG" #signal); \
     }                                                                          \
-- 
GitLab