diff --git a/doc/lkt.1 b/doc/lkt.1 index 710934f4410a6e85310fa67bde1bac34eed7f513..54cdef401d7d38579de35205b1a3abbbac34b3b9 100644 --- a/doc/lkt.1 +++ b/doc/lkt.1 @@ -180,6 +180,9 @@ to bootstrap the database from a filesystem \fBadmin update\fP Update the base from the \fIKurisu\fP repo. Don't scan for new files in the filesystem +.TP +\fBadmin config\fP +Prints to \fIstdout\fP the default configuration file .PP .SH "OPTIONS" diff --git a/inc/lektor/config.h b/inc/lektor/config.h index 7a2bf0fbf92181e3cbe6c47dff566239def8b205..22c200b1ef6d88e7d6794ce6c179b2c5eb722746 100644 --- a/inc/lektor/config.h +++ b/inc/lektor/config.h @@ -13,7 +13,7 @@ struct lkt_state; #define value_opt(key, val) value(key, val) static const char *const lkt_default_config_file = #include <lektor/config.inc> -; + ; #undef value #undef value_opt #undef section @@ -33,10 +33,5 @@ int config_detect_file(char *conf, size_t conf_len); Return 0 if the read operation was a success, a non zero value otherwise. */ int config_new(volatile sqlite3 *db, const char *conf); -/* Load a module by its name. Also initialize the mod pointer. No check on data - type is done, it is up to the user to check if the structure passed as a - `void*` is the right structure. */ -int load_module_by_name(struct lkt_state *srv, const char *name, void *mod); - /* Prints the default config file. */ void config_default(FILE *output); diff --git a/inc/lektor/database.h b/inc/lektor/database.h index b0383152b10acc95f9d82f029f2a74fafa7e6b47..574625404379ae74bd210dcc9cc919dd44435fc6 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -120,6 +120,7 @@ bool database_queue_prev(volatile sqlite3 *db, char filepath[PATH_MAX]); bool database_queue_skip_current(volatile sqlite3 *db, char filepath[PATH_MAX]); /* Set a value in the config table */ +bool database_validate_conf (volatile sqlite3 *db); bool database_config_set (volatile sqlite3 *db, const char *section, const char *key, const char *value); bool database_config_get_text(volatile sqlite3 *db, const char *section, const char *key, char *value, size_t len); bool database_config_get_int (volatile sqlite3 *db, const char *section, const char *key, int *value); diff --git a/inc/lektor/reg.h b/inc/lektor/reg.h index 970fc1b2e582c61c721d3654a17ea9c4f6ddd708..d156b68b67261a28e7fe0361bada4720f1668f26 100644 --- a/inc/lektor/reg.h +++ b/inc/lektor/reg.h @@ -22,3 +22,8 @@ void *reg_pick(const char *file, void **handle, const char *symbol); /* Set the ref for this .a / .so file */ void reg_set(struct module_reg *); + +/* Load a module by its name. Also initialize the mod pointer. No check on data + type is done, it is up to the user to check if the structure passed as a + `void*` is the right structure. */ +int load_module_by_name(struct lkt_state *srv, const char *name, void *mod); diff --git a/src/config.c b/src/config.c index 4a59d05c405d83f8219caf8af707a10ba01447ef..3f2f016aa4d2432f5a6ca066fce2b23f25791ac3 100644 --- a/src/config.c +++ b/src/config.c @@ -18,8 +18,6 @@ #include <limits.h> #include <ctype.h> -typedef int (*ini_handler)(volatile sqlite3 *db, const char *section, const char *name, const char *value); - static inline char * strip(char *s) { @@ -37,8 +35,16 @@ skip(char *s) return s; } +static int +handler(volatile sqlite3 *user, const char *section, const char *name, const char *value) +{ + RETURN_UNLESS(section && name && value, "I can't complete the database with incomplete lines", 1); + RETURN_UNLESS(database_config_set(user, section, name, value), "Failed to update the database", 1); + return 0; +} + static inline int -ini_parse(const char *path, ini_handler handle, volatile sqlite3 *db) +ini_parse(const char *path, volatile sqlite3 *db) { char *start, *end, *name, *value; char section[INI_MAX_SECTION_LEN], line[INI_MAX_LINE_LEN]; @@ -93,7 +99,7 @@ ini_parse(const char *path, ini_handler handle, volatile sqlite3 *db) strip(value); /* Handle the SECTION, NAME[:=]VALUE */ - if (handle(db, section, name, value)) { + if (handler(db, section, name, value)) { error = 1; LOG_ERROR_SCT("PARSER", "Failed to '[handle] %s, %s{:,=}%s' at line '%d'", section, name, value, linenum); @@ -114,73 +120,6 @@ ini_parse(const char *path, ini_handler handle, volatile sqlite3 *db) return error; } -int -load_so(const char *const mod_path, const char *const mod_init, void *mod, struct lkt_state *srv) -{ - /* An init function takes two arguments: the module pointer and a void* - which is the handler for the .so file. It the role of the module to - store the handle pointer. - Uppon successfull completion, the function shall return 0, and return - a non zero value if something bad happened. */ - int (*module_set_function)(void *const, struct lkt_state *, void *const); - void *handle = NULL; - *(void **) (&module_set_function) = reg_pick(mod_path, &handle, mod_init); - - if (module_set_function) - return module_set_function(mod, srv, handle); - else { - LOG_ERROR_SCT("LOAD", "Failed to find init symbol %s in file %s", mod_init, mod_path); - return 1; - } -} - -int -load_module_by_name(struct lkt_state *srv, const char *name, void *mod) -{ - char mod_path[PATH_MAX], mod_load[INI_MAX_LINE_LEN]; - - /* When, don't mind if its not here */ - if (!database_config_get_text(srv->db, name, "path", mod_path, PATH_MAX)) { - LOG_WARN_SCT("CONFIG", "No setting 'path' in section '%s'", name); - mod_path[0] = '\0'; - } - - if (!database_config_get_text(srv->db, name, "load_function", mod_load, INI_MAX_LINE_LEN)) { - LOG_ERROR_SCT("CONFIG", "Module named %s is incomplete or is not defined in config file", name); - return 1; - } - - return load_so(mod_path, mod_load, mod, srv); -} - -inline static int -validate_conf(volatile sqlite3 *db) -{ - const char *section; -#define section(_sct) section = _sct; -#define value_opt(name, value) -#define value(name, value) \ - if (!database_config_exists(db, section, name)) { \ - LOG_ERROR_SCT("CONFIG", "Missing option \""name"\" in section \"%s\"", \ - section); \ - return 1; \ - } -#include <lektor/config.inc> -#undef section -#undef value -#undef value_opt - - return 0; -} - -static int -handler(volatile sqlite3 *user, const char *section, const char *name, const char *value) -{ - RETURN_UNLESS(section && name && value, "I can't complete the database with incomplete lines", 1); - RETURN_UNLESS(database_config_set(user, section, name, value), "Failed to update the database", 1); - return 0; -} - int config_detect_file(char *conf, size_t conf_len) { @@ -254,12 +193,12 @@ found: int config_new(volatile sqlite3 *db, const char *conf) { - if (ini_parse(conf, handler, db)) { + if (ini_parse(conf, db)) { LOG_ERROR_SCT("CONFIG", "Failed to parse file %s", conf); goto error; } - if (validate_conf(db)) { + if (!database_validate_conf(db)) { LOG_ERROR_SCT("CONFIG", "Configuration file %s is incomplete", conf); goto error; } diff --git a/src/database/config.c b/src/database/config.c index f4de2a20c6891cf94b65f44f3c53b45f1cfd48b8..07241a78e0a1922202b1b61a102495af9fb22667 100644 --- a/src/database/config.c +++ b/src/database/config.c @@ -151,3 +151,22 @@ error: sqlite3_finalize(stmt); return ret; } + +bool +database_validate_conf(volatile sqlite3 *db) +{ + const char *section; +#define section(_sct) section = _sct; +#define value_opt(name, value) +#define value(name, value) \ + if (!database_config_exists(db, section, name)) { \ + LOG_ERROR_SCT("CONFIG", "Missing option \""name"\" in section \"%s\"", \ + section); \ + return false; \ + } +#include <lektor/config.inc> +#undef section +#undef value +#undef value_opt + return true; +} diff --git a/src/main/lkt.c b/src/main/lkt.c index 170e0f0a4ebbe7c2e33bc6d3477e5fc67c2db673..06349601d63e7ebbea8e53ea7348292d86b8b063 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -3,6 +3,7 @@ #include <common/common.h> #include <lektor/net.h> #include <lektor/cmd.h> +#include <lektor/config.h> #include <arpa/inet.h> #include <sys/types.h> @@ -275,11 +276,21 @@ populate__(struct lkt_cmd_args *args) rescan_or_update__(args, "__rescan"); } +noreturn void +config__(struct lkt_cmd_args *args) +{ + int ret = EXIT_SUCCESS; + if (args->argc == 0) + fwrite(lkt_default_config_file, sizeof(char), + strlen(lkt_default_config_file), stdout); + exit(ret); +} + noreturn void play__(struct lkt_cmd_args *args) { if (args->argc > 1) - fail("Invalid argument, the play command takes no arguments or only one"); + fail("Invalid argument"); int pos = 0; if (args->argc != 0) @@ -839,6 +850,7 @@ static struct lkt_cmd_opt options_admin[] = { { .name = "rescan", .call = rescan__ }, { .name = "update", .call = update__ }, { .name = "populate", .call = populate__ }, + { .name = "config", .call = config__ }, LKT_OPT_NULL, }; diff --git a/src/net/listen.c b/src/net/listen.c index 3fab03bbf24716fdb3966c8f43501e8552eca28b..e5d6af49404a0eba5fbeff13f74e3db216849ea2 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -4,6 +4,7 @@ #include <lektor/commands.h> #include <lektor/database.h> #include <lektor/net.h> +#include <lektor/reg.h> #include <sqlite3.h> diff --git a/src/reg.c b/src/reg.c index 3a4546fd08944cd9cc3b9055392a12c906181f19..bdb7e6caef6fdf489143cd6f19b07608872d6a7f 100644 --- a/src/reg.c +++ b/src/reg.c @@ -2,6 +2,9 @@ #include <common/common.h> #include <lektor/reg.h> +#include <lektor/database.h> +#include <lektor/config.h> +#include <lektor/net.h> #include <dlfcn.h> #include <stdio.h> #include <strings.h> @@ -44,7 +47,7 @@ reg_pick(const char *file, void **handle, const char *symbol) use_reg: LOG_INFO_SCT("REG", "Using the reg structure to find %s", symbol); for (i = 0; reg[i].name && reg[i].func; ++i) - if(STR_MATCH(reg[i].name, symbol)) + if (STR_MATCH(reg[i].name, symbol)) return (void *) reg[i].func; return NULL; @@ -55,3 +58,43 @@ reg_set(struct module_reg *_reg) { reg = _reg; } + +int +load_so(const char *const mod_path, const char *const mod_init, void *mod, struct lkt_state *srv) +{ + /* An init function takes two arguments: the module pointer and a void* + which is the handler for the .so file. It the role of the module to + store the handle pointer. + Uppon successfull completion, the function shall return 0, and return + a non zero value if something bad happened. */ + int (*module_set_function)(void *const, struct lkt_state *, void *const); + void *handle = NULL; + *(void **) (&module_set_function) = reg_pick(mod_path, &handle, mod_init); + + if (module_set_function) + return module_set_function(mod, srv, handle); + else { + LOG_ERROR_SCT("LOAD", "Failed to find init symbol %s in file %s", mod_init, mod_path); + return 1; + } +} + +int +load_module_by_name(struct lkt_state *srv, const char *name, void *mod) +{ + char mod_path[PATH_MAX], mod_load[INI_MAX_LINE_LEN]; + + /* When, don't mind if its not here */ + if (!database_config_get_text(srv->db, name, "path", mod_path, PATH_MAX)) { + LOG_WARN_SCT("CONFIG", "No setting 'path' in section '%s'", name); + mod_path[0] = '\0'; + } + + if (!database_config_get_text(srv->db, name, "load_function", mod_load, INI_MAX_LINE_LEN)) { + LOG_ERROR_SCT("CONFIG", "Module named %s is incomplete or is not defined in config file", name); + return 1; + } + + return load_so(mod_path, mod_load, mod, srv); +} +