diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/config.c | 151 | ||||
| -rw-r--r-- | src/plugin.c | 3 |
2 files changed, 129 insertions, 25 deletions
diff --git a/src/config.c b/src/config.c index ef55387..fb3cb2b 100644 --- a/src/config.c +++ b/src/config.c @@ -5,12 +5,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -// -// . -// . -// warning: slices are not NULL-terminated, and should not be modified! -// strdup them if you need to make modifications. typedef struct slice { char* ref; size_t len; @@ -24,13 +19,109 @@ typedef struct pair { pair_t* global_arg_table = NULL; size_t args_count = 0; +void parse_config_file(const char* filename) { + FILE* file = fopen(filename, "r"); + if (!file) { + fprintf(stderr, "failed to open config file: %s\n", filename); + exit(1); + } + + char* line = NULL; + size_t len = 0; + ssize_t read; + size_t new_args_count = args_count; + + while ((read = getline(&line, &len, file)) != -1) { + if (read > 0 && line[0] != '#' && line[0] != '\n') { + new_args_count++; + } + } + rewind(file); + + if (new_args_count > args_count) { + pair_t* new_table = realloc(global_arg_table, new_args_count * sizeof(pair_t)); + if (!new_table) { + fprintf(stderr, "realloc failed for config file parsing\n"); + fclose(file); + free(line); + exit(1); + } + global_arg_table = new_table; + } + + while ((read = getline(&line, &len, file)) != -1) { + if (read <= 1 || line[0] == '#' || line[0] == '\n') continue; + + if (line[read - 1] == '\n') line[read - 1] = '\0'; + + char* current = line; + char* eq_sign = strchr(current, '='); + if (eq_sign == NULL) { + fprintf(stderr, "config file error: expected 'key=value' in '%s'\n", current); + continue; + } + + // key + size_t key_len = eq_sign - current; + size_t key_start = 0; + while (key_start < key_len && isspace(current[key_start])) { + key_start++; + key_len--; + } + while (key_len > 0 && isspace(current[key_start + key_len - 1])) { + key_len--; + } + + if (key_len == 0) { + fprintf(stderr, "config file error: empty key in '%s'\n", current); + continue; + } + + // value + size_t value_start = eq_sign - current + 1; + size_t value_len = strlen(current) - value_start; + while (value_start < strlen(current) && isspace(current[value_start])) { + value_start++; + value_len--; + } + while (value_len > 0 && isspace(current[value_start + value_len - 1])) { + value_len--; + } + + // store + char* key_str = strndup(current + key_start, key_len); + char* value_str = strndup(current + value_start, value_len); + if (!key_str || !value_str) { + fprintf(stderr, "strndup failed for config file parsing\n"); + free(key_str); + free(value_str); + fclose(file); + free(line); + exit(1); + } + + global_arg_table[args_count].key.ref = key_str; + global_arg_table[args_count].key.len = key_len; + global_arg_table[args_count].value.ref = value_str; + global_arg_table[args_count].value.len = value_len; + args_count++; + } + + fclose(file); + free(line); +} + void parse_arguments(int argc, char** argv) { if (argc <= 1) return; global_arg_table = calloc(argc - 1, sizeof(pair_t)); + if (!global_arg_table) { + fprintf(stderr, "calloc failed for argument parsing\n"); + exit(1); + } for (int i = 1; i < argc; i++) { - char* current = argv[ i ]; + char* current = argv[i]; char* eq_sign = strchr(current, '='); if (eq_sign == NULL) { printf( @@ -41,14 +132,14 @@ void parse_arguments(int argc, char** argv) { exit(1); } - // key - size_t key_len = eq_sign - current; + // Key + size_t key_len = eq_sign - current; size_t key_start = 0; - while (key_start < key_len && isspace(current[ key_start ])) { // trim start + while (key_start < key_len && isspace(current[key_start])) { key_start++; key_len--; } - while (key_len > 0 && isspace(current[ key_start + key_len - 1 ])) { // trim end + while (key_len > 0 && isspace(current[key_start + key_len - 1])) { key_len--; } @@ -62,38 +153,50 @@ void parse_arguments(int argc, char** argv) { // value size_t value_start = eq_sign - current + 1; - size_t value_len = strlen(current) - value_start; - while (value_start < strlen(current) && isspace(current[ value_start ])) { // trim start + size_t value_len = strlen(current) - value_start; + while (value_start < strlen(current) && isspace(current[value_start])) { value_start++; value_len--; } - while (value_len > 0 && isspace(current[ value_start + value_len - 1 ])) { // trim end + while (value_len > 0 && isspace(current[value_start + value_len - 1])) { value_len--; } + // config file + if (key_len == 6 && strncmp(current + key_start, "config", 6) == 0) { + char* config_file = strndup(current + value_start, value_len); + if (!config_file) { + fprintf(stderr, "strndup failed for config file path\n"); + exit(1); + } + parse_config_file(config_file); + free(config_file); + continue; + } + // store - global_arg_table[ args_count ].key.ref = current + key_start; - global_arg_table[ args_count ].key.len = key_len; - global_arg_table[ args_count ].value.ref = current + value_start; - global_arg_table[ args_count ].value.len = value_len; + global_arg_table[args_count].key.ref = current + key_start; + global_arg_table[args_count].key.len = key_len; + global_arg_table[args_count].value.ref = current + value_start; + global_arg_table[args_count].value.len = value_len; args_count++; } } -// get a config option's value from argv. -// if mandatory == true -> program errors char* get_config(char* key, bool mandatory) { size_t len = strlen(key); for (int i = 0; i < args_count; i++) { - if (global_arg_table[ i ].key.len != len) continue; - if (strncmp(key, global_arg_table[ i ].key.ref, len) != 0) continue; - char* new_str = malloc(global_arg_table[ i ].value.len); - memcpy(new_str, global_arg_table[ i ].value.ref, global_arg_table[ i ].value.len); + if (global_arg_table[i].key.len != len) continue; + if (strncmp(key, global_arg_table[i].key.ref, len) != 0) continue; + char* new_str = strndup(global_arg_table[i].value.ref, global_arg_table[i].value.len); + if (!new_str && mandatory) { + fprintf(stderr, "strndup failed for config value\n"); + exit(1); + } return new_str; // free me! } if (!mandatory) return NULL; fprintf(stderr, "program expected argument %s but did not receive it.\n", key); - // __builtin_unreachable(); return NULL; }
\ No newline at end of file diff --git a/src/plugin.c b/src/plugin.c index cfee5d4..514db04 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -117,6 +117,8 @@ void load_plugins(const char *plugin_path) { return; } + init_plugin_func = dlsym(plugin_handle, "MP_init_plugin"); + if (init_plugin_func) { init_plugin_func(); log(_info, "loaded %s\n", plugin_path); @@ -128,7 +130,6 @@ void load_plugins(const char *plugin_path) { return; } - init_plugin_func = dlsym(plugin_handle, "MP_init_plugin"); modify_server_stats_func = dlsym(plugin_handle, "MP_modify_server_stats"); decide_neighbor_registry_func = dlsym(plugin_handle, "MP_decide_neighbor_registry"); decide_packet_propogation_func = dlsym(plugin_handle, "MP_decide_packet_propogation"); |
