diff --git a/inc/lektor/config.h b/inc/lektor/config.h index 074fb50b3a1ce06d972ba11945e1a302d5b50399..4515f0e352df48e9bc35978cedd42993206534ce 100644 --- a/inc/lektor/config.h +++ b/inc/lektor/config.h @@ -37,6 +37,9 @@ int config_new(volatile sqlite3 *db, const char *conf); /* 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 711df535078bacb3d1b7f57912e94c5f5ff3cb8a..4d5d7d50564dfdbe22a04befaa19cef117c30d8f 100644 --- a/src/base/config.c +++ b/src/base/config.c @@ -164,6 +164,25 @@ ini_parse(const char *path, volatile sqlite3 *db) return error; } +void +config_default_file(char *dest, size_t len) +{ + /* TODO: Use ~/.config/baka and not ~/.config/lektor. */ + /* First try the XDG_CONFIG_HOME variable, else the default location HOME/.config. */ + memset(dest, 0, len * sizeof(char)); + char *home = getenv("XDG_CONFIG_HOME"); + if (NULL == home || strlen(home) >= len) { + home = getenv("HOME"); + if (NULL == home) { + LOG_ERROR("FATAL", "Failed to get home folder for user, will now exit"); + exit(EXIT_FAILURE); + } + strncat(dest, "/.config/lektor/lektor.ini", len - 1); + } else { + strncat(dest, "/lektor/lektor.ini", len - 1); + } +} + int config_detect_file(char *conf, size_t conf_len) { diff --git a/src/main/server.c b/src/main/server.c index fb1c4cba36eb85672f9372d02559d9d71694f429..12515efe639f8f5b5462eaadf6b2423ec12fdb35 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -16,12 +16,36 @@ #include <string.h> #include <strings.h> #include <pthread.h> +#include <sys/stat.h> #if defined (LKT_STATIC_MODULE) - REG_DECLARE(sdl2_reg) - REG_DECLARE(repo_reg) +REG_DECLARE(sdl2_reg) +REG_DECLARE(repo_reg) #endif +/* Recursive mkdir, where the last word of the string is a file, not a folder. */ +static inline 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[]) { @@ -62,9 +86,7 @@ main(int argc, char *argv[]) /* Init the server */ char *db_path = safe_malloc(PATH_MAX * sizeof(char)); char *kara_dir = safe_malloc(PATH_MAX * sizeof(char)); - struct lkt_state srv = { - .kara_prefix = kara_dir, - }; + struct lkt_state srv = { .kara_prefix = kara_dir }; if (lkt_queue_new(&srv.queue)) { LOG_ERROR("INIT", "Faield to create server queue"); exit(EXIT_FAILURE); @@ -76,9 +98,28 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } + /* 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)) { - LOG_ERROR("INIT", "Failed to find a config file"); - exit(EXIT_FAILURE); + if (retry_config_once) { + LOG_ERROR("INIT", "Failed to find a config file"); + exit(EXIT_FAILURE); + } else { + 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+"); + if (NULL == file_desc) { + LOG_ERROR("FATAL", "Failed to open default config fiel for initializing it"); + exit(EXIT_FAILURE); + } + 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; + } } if (config_new(srv.db, conf_file)) {