config.c (2208B)
1 #include "infrastructure/config.h" 2 3 #include <stdlib.h> 4 #include <string.h> 5 6 #include "benhoyt/inih.h" 7 #include "common/resp.h" 8 #include "domain/config.h" 9 #include "rxi/log.h" 10 11 resp_object *pending_cfg = NULL; 12 13 static const char *stored_config_path = NULL; 14 15 static int config_handler(void *user, const char *section, const char *name, const char *value, int lineno) { 16 (void)lineno; 17 resp_object *cfg = (resp_object *)user; 18 resp_object *sec = resp_map_get(cfg, section); 19 if (!sec || sec->type != RESPT_ARRAY) { 20 sec = resp_array_init(); 21 resp_map_set(cfg, section, sec); 22 sec = resp_map_get(cfg, section); 23 } 24 25 if (strcmp(name, "cluster") == 0 || strcmp(name, "listen") == 0) { 26 resp_object *arr = resp_map_get(sec, name); 27 if (!arr) { 28 arr = resp_array_init(); 29 resp_map_set(sec, name, arr); 30 arr = resp_map_get(sec, name); 31 } 32 if (!arr || arr->type != RESPT_ARRAY) { 33 log_error("config: '%s' key already exists as non-array", name); 34 return 0; 35 } 36 resp_array_append_bulk(arr, value); 37 } else { 38 resp_array_append_bulk(sec, name); 39 resp_array_append_bulk(sec, value); 40 } 41 return 1; 42 } 43 44 void config_init(void) { 45 if (pending_cfg) resp_free(pending_cfg); 46 pending_cfg = resp_array_init(); 47 config_load(NULL, config_get_path()); 48 resp_object *old = domain_cfg; 49 domain_cfg = pending_cfg; 50 pending_cfg = NULL; 51 if (old) resp_free(old); 52 } 53 54 int config_load(resp_object *cfg, const char *path) { 55 resp_object *load_cfg = cfg; 56 if (!load_cfg) { 57 load_cfg = pending_cfg; 58 } 59 return ini_parse(path, config_handler, load_cfg); 60 } 61 62 void config_pending_init(void) { 63 if (pending_cfg) resp_free(pending_cfg); 64 pending_cfg = resp_array_init(); 65 } 66 67 int config_reload(void) { 68 config_pending_init(); 69 int r = config_load(NULL, config_get_path()); 70 if (r < 0) return -1; 71 resp_object *old = domain_cfg; 72 domain_cfg = pending_cfg; 73 pending_cfg = NULL; 74 if (old) resp_free(old); 75 return 0; 76 } 77 78 void config_set_path(const char *path) { 79 if (stored_config_path) free((void *)stored_config_path); 80 stored_config_path = path ? strdup(path) : NULL; 81 } 82 83 const char *config_get_path(void) { 84 return stored_config_path; 85 }