| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #ifndef LIBNETDATA_INICFG_INTERNALS_H |
| 4 | #define LIBNETDATA_INICFG_INTERNALS_H |
| 5 | |
| 6 | #include "inicfg.h" |
| 7 | |
| 8 | typedef enum __attribute__((packed)) { |
| 9 | CONFIG_VALUE_TYPE_UNKNOWN = 0, |
| 10 | CONFIG_VALUE_TYPE_TEXT, |
| 11 | CONFIG_VALUE_TYPE_HOSTNAME, |
| 12 | CONFIG_VALUE_TYPE_USERNAME, |
| 13 | CONFIG_VALUE_TYPE_FILENAME, |
| 14 | CONFIG_VALUE_TYPE_PATH, |
| 15 | CONFIG_VALUE_TYPE_SIMPLE_PATTERN, |
| 16 | CONFIG_VALUE_TYPE_URL, |
| 17 | CONFIG_VALUE_TYPE_ENUM, |
| 18 | CONFIG_VALUE_TYPE_BITMAP, |
| 19 | CONFIG_VALUE_TYPE_INTEGER, |
| 20 | CONFIG_VALUE_TYPE_DOUBLE, |
| 21 | CONFIG_VALUE_TYPE_BOOLEAN, |
| 22 | CONFIG_VALUE_TYPE_BOOLEAN_ONDEMAND, |
| 23 | CONFIG_VALUE_TYPE_DURATION_IN_SECS, |
| 24 | CONFIG_VALUE_TYPE_DURATION_IN_MS, |
| 25 | CONFIG_VALUE_TYPE_DURATION_IN_DAYS_TO_SECONDS, |
| 26 | CONFIG_VALUE_TYPE_SIZE_IN_BYTES, |
| 27 | CONFIG_VALUE_TYPE_SIZE_IN_MB, |
| 28 | } CONFIG_VALUE_TYPES; |
| 29 | |
| 30 | typedef enum __attribute__((packed)) { |
| 31 | CONFIG_VALUE_LOADED = (1 << 0), // has been loaded from the config |
| 32 | CONFIG_VALUE_USED = (1 << 1), // has been accessed from the program |
| 33 | CONFIG_VALUE_CHANGED = (1 << 2), // has been changed from the loaded value or the internal default value |
| 34 | CONFIG_VALUE_CHECKED = (1 << 3), // has been checked if the value is different from the default |
| 35 | CONFIG_VALUE_MIGRATED = (1 << 4), // has been migrated from an old config |
| 36 | CONFIG_VALUE_REFORMATTED = (1 << 5), // has been reformatted with the official formatting |
| 37 | CONFIG_VALUE_DEFAULT_SET = (1 << 6), // the default value has been set |
| 38 | } CONFIG_VALUE_FLAGS; |
| 39 | |
| 40 | struct config_option { |
| 41 | avl_t avl_node; // the index entry of this entry - this has to be first! |
| 42 | |
| 43 | CONFIG_VALUE_TYPES type; |
| 44 | CONFIG_VALUE_FLAGS flags; |
| 45 | |
| 46 | STRING *name; |
| 47 | STRING *value; |
| 48 | |
| 49 | STRING *value_original; // the original value of this option (the first value it got, independently on how it got it) |
| 50 | STRING *value_default; // the internal default value of this option (the first value it got, from inicfg_get_XXX()) |
| 51 | |
| 52 | // when we move options around, this is where we keep the original |
| 53 | // section and name (of the first migration) |
| 54 | struct { |
| 55 | STRING *section; |
| 56 | STRING *name; |
| 57 | } migrated; |
| 58 | |
| 59 | struct config_option *prev, *next; // config->mutex protects just this |
| 60 | }; |
| 61 | |
| 62 | struct config_section { |
| 63 | avl_t avl_node; // the index entry of this section - this has to be first! |
| 64 | |
| 65 | STRING *name; |
| 66 | |
| 67 | struct config_option *values; |
| 68 | avl_tree_lock values_index; |
| 69 | |
| 70 | SPINLOCK spinlock; |
| 71 | struct config_section *prev, *next; // global config_mutex protects just this |
| 72 | }; |
| 73 | |
| 74 | // ---------------------------------------------------------------------------- |
| 75 | // locking |
| 76 | |
| 77 | #define APPCONFIG_LOCK(root) spinlock_lock(&((root)->spinlock)) |
| 78 | #define APPCONFIG_UNLOCK(root) spinlock_unlock(&((root)->spinlock)) |
| 79 | #define SECTION_LOCK(sect) spinlock_lock(&((sect)->spinlock)) |
| 80 | #define SECTION_UNLOCK(sect) spinlock_unlock(&((sect)->spinlock)); |
| 81 | |
| 82 | // config sections |
| 83 | void inicfg_section_free(struct config_section *sect); |
| 84 | void inicfg_section_remove_and_delete(struct config *root, struct config_section *sect, bool have_root_lock, bool have_sect_lock); |
| 85 | #define inicfg_section_add(root, cfg) (struct config_section *)avl_insert_lock(&(root)->index, (avl_t *)(cfg)) |
| 86 | #define inicfg_section_del(root, cfg) (struct config_section *)avl_remove_lock(&(root)->index, (avl_t *)(cfg)) |
| 87 | struct config_section *inicfg_section_find(struct config *root, const char *name); |
| 88 | struct config_section *inicfg_section_create(struct config *root, const char *section); |
| 89 | |
| 90 | // config options |
| 91 | void inicfg_option_cleanup(struct config_option *opt); |
| 92 | void inicfg_option_free(struct config_option *opt); |
| 93 | void inicfg_option_remove_and_delete(struct config_section *sect, struct config_option *opt, bool have_sect_lock); |
| 94 | void inicfg_option_remove_and_delete_all(struct config_section *sect, bool have_sect_lock); |
| 95 | int inicfg_option_compare(void *a, void *b); |
| 96 | #define inicfg_option_add(co, cv) (struct config_option *)avl_insert_lock(&((co)->values_index), (avl_t *)(cv)) |
| 97 | #define inicfg_option_del(co, cv) (struct config_option *)avl_remove_lock(&((co)->values_index), (avl_t *)(cv)) |
| 98 | struct config_option *inicfg_option_find(struct config_section *sect, const char *name); |
| 99 | struct config_option *inicfg_option_create(struct config_section *sect, const char *name, const char *value); |
| 100 | |
| 101 | // lookup |
| 102 | int inicfg_get_boolean_by_section(struct config_section *sect, const char *name, int value); |
| 103 | |
| 104 | typedef STRING *(*reformat_t)(STRING *value); |
| 105 | struct config_option *inicfg_get_raw_value_of_option_in_section(struct config_section *sect, const char *option, const char *default_value, CONFIG_VALUE_TYPES type, reformat_t cb); |
| 106 | struct config_option *inicfg_get_raw_value(struct config *root, const char *section, const char *option, const char *default_value, CONFIG_VALUE_TYPES type, reformat_t cb); |
| 107 | |
| 108 | void inicfg_set_raw_value_of_option(struct config_option *opt, const char *value, CONFIG_VALUE_TYPES type); |
| 109 | struct config_option *inicfg_set_raw_value_of_option_in_section(struct config_section *sect, const char *option, const char *value, CONFIG_VALUE_TYPES type); |
| 110 | struct config_option *inicfg_set_raw_value(struct config *root, const char *section, const char *option, const char *value, CONFIG_VALUE_TYPES type); |
| 111 | |
| 112 | // cleanup |
| 113 | void inicfg_section_destroy_non_loaded(struct config *root, const char *section); |
| 114 | void inicfg_section_option_destroy_non_loaded(struct config *root, const char *section, const char *name); |
| 115 | |
| 116 | // exporters |
| 117 | _CONNECTOR_INSTANCE *add_connector_instance(struct config_section *connector, struct config_section *instance); |
| 118 | int is_valid_connector(char *type, int check_reserved); |
| 119 | |
| 120 | #endif /* LIBNETDATA_INICFG_INTERNALS_H */ |