Fix config handling

This commit is contained in:
Tobias Reisinger 2020-11-12 21:58:01 +01:00
parent fad3d80f39
commit fca35ade9e
18 changed files with 125 additions and 139 deletions

1
.gitignore vendored
View file

@ -6,3 +6,4 @@ tests/testing/
include/sql/*.h
emgauwa-core.sqlite
vgcore.*

View file

@ -39,7 +39,7 @@ add_custom_target(sql
)
add_custom_target(run
COMMAND ${CMAKE_BINARY_DIR}/core start
COMMAND ${CMAKE_BINARY_DIR}/core
DEPENDS core
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
@ -56,24 +56,24 @@ add_custom_target(docs
)
IF(CMAKE_BUILD_TYPE MATCHES Debug)
message("debug mode")
message(STATUS "loading debug targets")
add_custom_target(debug
COMMAND gdb ${CMAKE_BINARY_DIR}/core
DEPENDS core
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
add_custom_target(valgrind
COMMAND valgrind -s ${CMAKE_BINARY_DIR}/core start
COMMAND valgrind -s ${CMAKE_BINARY_DIR}/core
DEPENDS core
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
add_custom_target(valgrind-leak
COMMAND valgrind --leak-check=full --show-leak-kinds=all ${CMAKE_BINARY_DIR}/core start
COMMAND valgrind --leak-check=full --show-leak-kinds=all ${CMAKE_BINARY_DIR}/core
DEPENDS core
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
add_custom_target(valgrind-callgrind
COMMAND valgrind --tool=callgrind ${CMAKE_BINARY_DIR}/core start
COMMAND valgrind --tool=callgrind ${CMAKE_BINARY_DIR}/core
DEPENDS core
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)

View file

@ -1,6 +1,6 @@
[core]
server-port = 5000
database = core.sqlite
database = emgauwa-core.sqlite
content-dir = /usr/share/webapps/emgauwa
not-found-file = 404.html
not-found-file-mime = text/html

13
include/cli.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef CORE_CLI_H
#define CORE_CLI_H
typedef struct cli
{
char *config_path;
} cli_t;
void
cli_parse(int argc, const char **argv, config_t *config);
#endif /* CORE_CLI_H */

View file

@ -6,12 +6,6 @@
#include <mongoose.h>
#include <confini.h>
typedef enum
{
RUN_TYPE_START,
RUN_TYPE_INVALID,
} run_type_t;
typedef struct
{
char *file;
@ -21,7 +15,6 @@ typedef struct
char *group;
int log_level;
FILE *log_file;
run_type_t run_type;
uint16_t server_port;
uint16_t discovery_port;
uint16_t mqtt_port;
@ -33,7 +26,7 @@ typedef struct
struct mg_serve_http_opts http_server_opts;
} config_t;
extern config_t global_config;
extern config_t *global_config;
void
config_init();
@ -42,7 +35,7 @@ void
config_free();
void
config_try_ini_files(config_t *config);
config_load_string(char **holder, const char *value);
int
config_load(IniDispatch *disp, void *config_void);

View file

@ -14,13 +14,6 @@
*/
#define MAX_NAME_LENGTH 128
/**
* @brief Maximum number of dbs for the databases for the MDB_env
*
* Used when calling mdb_env_set_maxdbs() in database_setup()
*/
#define MDB_MAXDBS 8
/**
* @brief How many milli seconds to wait until poll timeout in main loop
*/
@ -28,4 +21,6 @@
#define PIFACE_GPIO_BASE 200
#define DEFAULT_CONFIG_PATH "emgauwa-core.ini"
#endif /* CORE_CONTANTS_H */

View file

@ -3,14 +3,10 @@
#include <time.h>
#include <config.h>
#include <confini.h>
int
helper_connect_tcp_server(char* host, uint16_t port);
void
helper_parse_cli(int argc, const char **argv, config_t *config);
int
helper_get_weekday(const struct tm *time_struct);

View file

@ -10,20 +10,20 @@
#include <version.h>
static const char *const usage[] = {
"core [options] [[--] args]",
"core [options]",
NULL,
};
void
helper_parse_cli(int argc, const char **argv, config_t *config)
cli_parse(int argc, const char **argv, config_t *config)
{
const char *config_file = NULL;
int version = 0;
struct argparse_option options[] =
{
OPT_HELP(),
OPT_GROUP("Basic options"),
OPT_STRING('c', "config", &config->file, "path to config file", NULL, 0, OPT_NONEG),
OPT_STRING('c', "config", &config_file, "path to config file", NULL, 0, OPT_NONEG),
OPT_BOOLEAN('v', "version", &version, "print version", NULL, 0, OPT_NONEG),
OPT_END(),
};
@ -37,27 +37,15 @@ helper_parse_cli(int argc, const char **argv, config_t *config)
);
argc = argparse_parse(&argparse, argc, argv);
if(config_file)
{
config_load_string(&config->file, config_file);
}
if(version)
{
printf("%s\n", EMGAUWA_CORE_VERSION);
exit(0);
}
if(argc == 1)
{
config->run_type = RUN_TYPE_INVALID;
if(strcmp(argv[0], "start") == 0)
{
config->run_type = RUN_TYPE_START;
return;
}
LOGGER_CRIT("bad action '%s' given ('start')\n", argv[0]);
exit(1);
}
else
{
LOGGER_CRIT("no action given ('start')\n");
exit(1);
}
return;
}

View file

@ -1,10 +1,11 @@
#include <stdlib.h>
#include <string.h>
#include <logger.h>
#include <config.h>
#include <constants.h>
#include <logger.h>
config_t global_config;
config_t *global_config;
#define CONFINI_IS_KEY(SECTION, KEY) \
@ -57,6 +58,7 @@ config_load_log_level(IniDispatch *disp, config_t *config)
return 0;
}
LOGGER_WARNING("invalid log-level '%s'\n", disp->value);
return 0;
}
@ -77,8 +79,49 @@ config_load_log_file(IniDispatch *disp, config_t *config)
return 0;
}
static void
config_load_string(char **holder, char *value)
void
config_init()
{
global_config = calloc(1, sizeof(config_t));
config_load_string(&global_config->file, DEFAULT_CONFIG_PATH);
global_config->discovery_port = 4421;
global_config->mqtt_port = 1885;
global_config->server_port = 5000;
global_config->log_level = LOG_DEBUG;
global_config->log_file = stdout;
global_config->user = NULL;
global_config->group = NULL;
config_load_string(&global_config->content_dir, ".");
config_load_string(&global_config->not_found_file, "404.html");
config_load_string(&global_config->not_found_file_type, "text/html");
config_load_string(&global_config->not_found_content, "404 - NOT FOUND");
config_load_string(&global_config->not_found_content_type, "text/plain");
}
void
config_free()
{
free(global_config->file);
free(global_config->include);
free(global_config->database);
free(global_config->user);
free(global_config->group);
free(global_config->content_dir);
free(global_config->not_found_file);
free(global_config->not_found_file_type);
free(global_config->not_found_content);
free(global_config->not_found_content_type);
free(global_config);
}
void
config_load_string(char **holder, const char *value)
{
if(*holder)
{
@ -93,50 +136,6 @@ config_load_string(char **holder, char *value)
*holder = new_holder;
}
void
config_init()
{
memset(&global_config, 0, sizeof(config_t));
global_config.discovery_port = 4421;
global_config.mqtt_port = 1885;
global_config.server_port = 5000;
global_config.log_level = LOG_INFO;
global_config.log_file = stdout;
global_config.user = NULL;
global_config.group = NULL;
config_load_string(&global_config.content_dir, ".");
config_load_string(&global_config.not_found_file, "404.html");
config_load_string(&global_config.not_found_file_type, "text/html");
config_load_string(&global_config.not_found_content, "404 - NOT FOUND");
config_load_string(&global_config.not_found_content_type, "text/plain");
}
void
config_free()
{
free(global_config.file);
free(global_config.include);
free(global_config.database);
free(global_config.user);
free(global_config.group);
free(global_config.content_dir);
free(global_config.not_found_file);
free(global_config.not_found_file_type);
free(global_config.not_found_content);
free(global_config.not_found_content_type);
}
void
config_try_ini_files(config_t *config)
{
(void)config;
}
int
config_load(IniDispatch *disp, void *config_void)
{

View file

@ -13,7 +13,7 @@ static database_transaction_lock *transaction_lock;
void
database_init()
{
int rc = sqlite3_open(global_config.database, &global_database);
int rc = sqlite3_open(global_config->database, &global_database);
if(rc)
{
@ -21,6 +21,8 @@ database_init()
exit(1);
}
LOGGER_DEBUG("Opened database %s\n", global_config->database);
database_migrate();
sqlite3_exec(global_database, "PRAGMA foreign_keys = ON", 0, 0, 0);

View file

@ -14,7 +14,7 @@ endpoint_func_index(struct mg_connection *nc, struct http_message *hm, endpoint_
response->status_code = 0;
mg_serve_http(nc, hm, global_config.http_server_opts);
mg_serve_http(nc, hm, global_config->http_server_opts);
}
void
@ -24,19 +24,19 @@ endpoint_func_not_found(struct mg_connection *nc, struct http_message *hm, endpo
(void)hm;
(void)nc;
if(access(global_config.not_found_file, R_OK) != -1)
if(access(global_config->not_found_file, R_OK) != -1)
{
struct mg_str mime_type = mg_mk_str(global_config.not_found_file_type);
struct mg_str mime_type = mg_mk_str(global_config->not_found_file_type);
response->status_code = 0;
mg_http_serve_file(nc, hm, global_config.not_found_file, mime_type, mg_mk_str(""));
mg_http_serve_file(nc, hm, global_config->not_found_file, mime_type, mg_mk_str(""));
}
else
{
LOGGER_DEBUG("404 file not found\n");
response->status_code = 404;
response->content_type = global_config.not_found_content_type;
response->content_length = strlen(global_config.not_found_content);
response->content = global_config.not_found_content;
response->content_type = global_config->not_found_content_type;
response->content_length = strlen(global_config->not_found_content);
response->content = global_config->not_found_content;
response->alloced_content = false;
}

View file

@ -122,7 +122,7 @@ api_v1_controllers_discover_PUT(struct mg_connection *nc, struct http_message *h
payload[0] = discover_server_port;
LOGGER_DEBUG("sending udp broadcast\n");
if(send_udp_broadcast("255.255.255.255", global_config.discovery_port, payload, sizeof(payload)) < 0)
if(send_udp_broadcast("255.255.255.255", global_config->discovery_port, payload, sizeof(payload)) < 0)
{
M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to send discovery broadcast");
return;

View file

@ -23,6 +23,8 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin
cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name");
if(!cJSON_IsString(json_name) || (json_name->valuestring == NULL))
{
cJSON_Delete(json);
M_RESPONSE_400_NO_NAME(response);
return;
}

View file

@ -17,16 +17,16 @@ static char*
add_extra_headers(char *extra_headers)
{
char *result;
size_t std_headers_len = strlen(global_config.http_server_opts.extra_headers);
size_t std_headers_len = strlen(global_config->http_server_opts.extra_headers);
if(extra_headers == NULL)
{
result = malloc(sizeof(char) * (std_headers_len + 1));
strcpy(result, global_config.http_server_opts.extra_headers);
strcpy(result, global_config->http_server_opts.extra_headers);
return result;
}
result = malloc(sizeof(char) * (std_headers_len + strlen(extra_headers) + 3));
sprintf(result, "%s\r\n%s", global_config.http_server_opts.extra_headers, extra_headers);
sprintf(result, "%s\r\n%s", global_config->http_server_opts.extra_headers, extra_headers);
return result;
}
@ -89,7 +89,7 @@ handle_http_request(struct mg_connection *nc, struct http_message *hm)
{
/* Normalize path - resolve "." and ".." (in-place). */
if (!mg_normalize_uri_path(&hm->uri, &hm->uri)) {
mg_http_send_error(nc, 400, global_config.http_server_opts.extra_headers);
mg_http_send_error(nc, 400, global_config->http_server_opts.extra_headers);
LOGGER_DEBUG("failed to normalize uri %.*s\n", hm->uri.len, hm->uri.p);
return;
}
@ -105,15 +105,15 @@ handle_http_request(struct mg_connection *nc, struct http_message *hm)
++request_file;
}
char *request_file_path = malloc(sizeof(char) * (strlen(request_file) + strlen(global_config.content_dir) + 2));
sprintf(request_file_path, "%s/%s", global_config.content_dir, request_file);
char *request_file_path = malloc(sizeof(char) * (strlen(request_file) + strlen(global_config->content_dir) + 2));
sprintf(request_file_path, "%s/%s", global_config->content_dir, request_file);
int access_result = access(request_file_path, R_OK);
free(request_file_path);
free(request_file_org);
if(access_result != -1)
{
response.status_code = 0;
mg_serve_http(nc, hm, global_config.http_server_opts);
mg_serve_http(nc, hm, global_config->http_server_opts);
LOGGER_DEBUG("serving %.*s\n", hm->uri.len, hm->uri.p);
return;
}

View file

@ -59,8 +59,8 @@ get_gid_for_group(char *group)
int
helper_drop_privileges()
{
uid_t uid = get_uid_for_user(global_config.user);
gid_t gid = get_gid_for_group(global_config.group);
uid_t uid = get_uid_for_user(global_config->user);
gid_t gid = get_gid_for_group(global_config->group);
LOGGER_DEBUG("drop privileges to %lu:%lu\n", uid, gid);

View file

@ -17,7 +17,7 @@ const char *COLOR_EMERG = COLOR_MAGENTA;
void
logger_log(int level, const char *filename, int line, const char *func, const char *msg, ...)
{
if(global_config.log_level < level || level == LOG_NONE )
if(global_config->log_level < level || level == LOG_NONE )
{
return;
}
@ -76,8 +76,8 @@ logger_log(int level, const char *filename, int line, const char *func, const ch
char *buffer_timed = malloc(sizeof(char) * (strlen(timestamp_str) + strlen(buffer) + 2));
sprintf(buffer_timed, "%s %s", timestamp_str, buffer);
va_start(args, msg);
vfprintf(global_config.log_file, buffer_timed, args);
fflush(global_config.log_file);
vfprintf(global_config->log_file, buffer_timed, args);
fflush(global_config->log_file);
va_end(args);
free(buffer);

View file

@ -7,6 +7,7 @@
#include <confini.h>
#include <cache.h>
#include <cli.h>
#include <router.h>
#include <logger.h>
#include <config.h>
@ -52,22 +53,22 @@ main(int argc, const char** argv)
signal(SIGABRT, terminate);
signal(SIGTERM, terminate);
setlogmask(LOG_UPTO(LOG_INFO));
openlog("emgauwa-core", 0, LOG_USER);
setlogmask(LOG_UPTO(LOG_DEBUG));
/******************** LOAD CONFIG ********************/
config_init();
helper_parse_cli(argc, argv, &global_config);
cli_parse(argc, argv, global_config);
FILE * const ini_file = fopen(global_config.file, "rb");
FILE * const ini_file = fopen(global_config->file, "rb");
if(ini_file == NULL)
{
LOGGER_CRIT("config file '%s' was not found\n", global_config.file);
LOGGER_CRIT("config file '%s' was not found\n", global_config->file);
exit(1);
}
if(load_ini_file(ini_file, INI_DEFAULT_FORMAT, NULL, config_load, &global_config))
if(load_ini_file(ini_file, INI_DEFAULT_FORMAT, NULL, config_load, global_config))
{
LOGGER_CRIT("unable to parse ini file\n");
exit(1);
@ -75,16 +76,12 @@ main(int argc, const char** argv)
fclose(ini_file);
memset(&global_config.http_server_opts, 0, sizeof(global_config.http_server_opts));
global_config.http_server_opts.document_root = global_config.content_dir;
global_config.http_server_opts.enable_directory_listing = "no";
global_config.http_server_opts.extra_headers = "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: *\r\nAccess-Control-Allow-Methods: *";
if(global_config.log_file == NULL)
if(global_config->log_file == NULL)
{
global_config.log_file = stdout;
global_config->log_file = stdout;
}
openlog("emgauwa-core", 0, LOG_USER);
LOGGER_DEBUG("Loaded config from %s\n", global_config->file);
/******************** SETUP CONNECTION ********************/
@ -94,20 +91,20 @@ main(int argc, const char** argv)
mg_mgr_init(&mgr, NULL);
char address[100];
sprintf(address, "tcp://0.0.0.0:%u", global_config.server_port);
sprintf(address, "tcp://0.0.0.0:%u", global_config->server_port);
struct mg_connection *c_http = mg_bind(&mgr, address, handler_http);
if(c_http == NULL)
{
LOGGER_CRIT("failed to bind http server to port %u\n", global_config.server_port);
LOGGER_CRIT("failed to bind http server to port %u\n", global_config->server_port);
exit(1);
}
mg_set_protocol_http_websocket(c_http);
sprintf(address, "tcp://0.0.0.0:%u", global_config.mqtt_port);
sprintf(address, "tcp://0.0.0.0:%u", global_config->mqtt_port);
struct mg_connection *c_mqtt = mg_bind(&mgr, address, handler_mqtt);
if(c_mqtt == NULL)
{
LOGGER_CRIT("failed to bind mqtt server to port %u\n", global_config.mqtt_port);
LOGGER_CRIT("failed to bind mqtt server to port %u\n", global_config->mqtt_port);
exit(1);
}
mg_mqtt_broker_init(&brk, NULL);
@ -116,6 +113,11 @@ main(int argc, const char** argv)
helper_drop_privileges();
memset(&global_config->http_server_opts, 0, sizeof(global_config->http_server_opts));
global_config->http_server_opts.document_root = global_config->content_dir;
global_config->http_server_opts.enable_directory_listing = "no";
global_config->http_server_opts.extra_headers = "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: *\r\nAccess-Control-Allow-Methods: *";
/******************** INIT COMPONENTS ********************/

View file

@ -41,12 +41,7 @@ touch $working_dir/index.html
cp $1 $working_dir/core
echo "=== invalids start (must exit) ===" >$working_dir/core.log
$working_dir/core -c $source_dir/emgauwa-core-testing-ini >>$working_dir/core.log 2>&1
$working_dir/core -c $source_dir/emgauwa-core-testing-ini INVALID_ACTION >>$working_dir/core.log 2>&1
echo "=== valid start ===" >>$working_dir/core.log
valgrind_emgauwa $working_dir/core -c $source_dir/emgauwa-core-testing.ini start >>$working_dir/core.log 2>&1 &
valgrind_emgauwa $working_dir/core -c $source_dir/emgauwa-core-testing.ini >>$working_dir/core.log 2>&1 &
core_id=$!