static const char *test_libconfig_setting_types(void) { struct config_t config; struct config_setting_t *t; const char *input = "/* Test File */\n" "Setting_Int: 1;\n" "Setting_Int64: 1L;\n" "Setting_Float: 1.0;\n" "Setting_Bool: true;\n" "Setting_String: \"1\";\n" "Setting_Array: [ ];\n" "Setting_Group: { };\n" "Setting_List: ( );\n" "/* End test file */\n"; if (libconfig->read_string(&config, input) == CONFIG_FALSE) { libconfig->destroy(&config); return "Unable to parse configuration."; } if (config_setting_type(config.root) != CONFIG_TYPE_GROUP) { libconfig->destroy(&config); return "CONFIG_TYPE_GROUP failed."; } if ((t = libconfig->lookup(&config, "Setting_Int")) == NULL || config_setting_type(t) != CONFIG_TYPE_INT || config_setting_is_group(t) || config_setting_is_array(t) || config_setting_is_list(t) || config_setting_is_aggregate(t) || !config_setting_is_scalar(t) || !config_setting_is_number(t) ) { libconfig->destroy(&config); return "CONFIG_TYPE_INT failed."; } if ((t = libconfig->lookup(&config, "Setting_Int64")) == NULL || config_setting_type(t) != CONFIG_TYPE_INT64 || config_setting_is_group(t) || config_setting_is_array(t) || config_setting_is_list(t) || config_setting_is_aggregate(t) || !config_setting_is_scalar(t) || !config_setting_is_number(t) ) { libconfig->destroy(&config); return "CONFIG_TYPE_INT64 failed."; } if ((t = libconfig->lookup(&config, "Setting_Float")) == NULL || config_setting_type(t) != CONFIG_TYPE_FLOAT || config_setting_is_group(t) || config_setting_is_array(t) || config_setting_is_list(t) || config_setting_is_aggregate(t) || !config_setting_is_scalar(t) || !config_setting_is_number(t) ) { libconfig->destroy(&config); return "CONFIG_TYPE_FLOAT failed."; } if ((t = libconfig->lookup(&config, "Setting_Bool")) == NULL || config_setting_type(t) != CONFIG_TYPE_BOOL || config_setting_is_group(t) || config_setting_is_array(t) || config_setting_is_list(t) || config_setting_is_aggregate(t) || !config_setting_is_scalar(t) || config_setting_is_number(t) ) { libconfig->destroy(&config); return "CONFIG_TYPE_BOOL failed."; } if ((t = libconfig->lookup(&config, "Setting_String")) == NULL || config_setting_type(t) != CONFIG_TYPE_STRING || config_setting_is_group(t) || config_setting_is_array(t) || config_setting_is_list(t) || config_setting_is_aggregate(t) || !config_setting_is_scalar(t) || config_setting_is_number(t) ) { libconfig->destroy(&config); return "CONFIG_TYPE_STRING failed."; } if ((t = libconfig->lookup(&config, "Setting_Array")) == NULL || config_setting_type(t) != CONFIG_TYPE_ARRAY || config_setting_is_group(t) || !config_setting_is_array(t) || config_setting_is_list(t) || !config_setting_is_aggregate(t) || config_setting_is_scalar(t) || config_setting_is_number(t) ) { libconfig->destroy(&config); return "CONFIG_TYPE_ARRAY failed."; } if ((t = libconfig->lookup(&config, "Setting_Group")) == NULL || config_setting_type(t) != CONFIG_TYPE_GROUP || !config_setting_is_group(t) || config_setting_is_array(t) || config_setting_is_list(t) || !config_setting_is_aggregate(t) || config_setting_is_scalar(t) || config_setting_is_number(t) ) { libconfig->destroy(&config); return "CONFIG_TYPE_GROUP failed."; } if ((t = libconfig->lookup(&config, "Setting_List")) == NULL || config_setting_type(t) != CONFIG_TYPE_LIST || config_setting_is_group(t) || config_setting_is_array(t) || !config_setting_is_list(t) || !config_setting_is_aggregate(t) || config_setting_is_scalar(t) || config_setting_is_number(t) ) { libconfig->destroy(&config); return "CONFIG_TYPE_LIST failed."; } libconfig->destroy(&config); return NULL; }
void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_ports, int *tcp_relay_port_count) { const char *NAME_TCP_RELAY_PORTS = "tcp_relay_ports"; *tcp_relay_port_count = 0; config_setting_t *ports_array = config_lookup(cfg, NAME_TCP_RELAY_PORTS); if (ports_array == NULL) { syslog(LOG_WARNING, "No '%s' setting in the configuration file.\n", NAME_TCP_RELAY_PORTS); syslog(LOG_WARNING, "Using default '%s':\n", NAME_TCP_RELAY_PORTS); uint16_t default_ports[DEFAULT_TCP_RELAY_PORTS_COUNT] = {DEFAULT_TCP_RELAY_PORTS}; int i; for (i = 0; i < DEFAULT_TCP_RELAY_PORTS_COUNT; i ++) { syslog(LOG_WARNING, "Port #%d: %u\n", i, default_ports[i]); } // similar procedure to the one of reading config file below *tcp_relay_ports = malloc(DEFAULT_TCP_RELAY_PORTS_COUNT * sizeof(uint16_t)); for (i = 0; i < DEFAULT_TCP_RELAY_PORTS_COUNT; i ++) { (*tcp_relay_ports)[*tcp_relay_port_count] = default_ports[i]; if ((*tcp_relay_ports)[*tcp_relay_port_count] < MIN_ALLOWED_PORT || (*tcp_relay_ports)[*tcp_relay_port_count] > MAX_ALLOWED_PORT) { syslog(LOG_WARNING, "Port #%d: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i, (*tcp_relay_ports)[*tcp_relay_port_count], MIN_ALLOWED_PORT, MAX_ALLOWED_PORT); continue; } (*tcp_relay_port_count) ++; } // the loop above skips invalid ports, so we adjust the allocated memory size if ((*tcp_relay_port_count) > 0) { *tcp_relay_ports = realloc(*tcp_relay_ports, (*tcp_relay_port_count) * sizeof(uint16_t)); } else { free(*tcp_relay_ports); *tcp_relay_ports = NULL; } return; } if (config_setting_is_array(ports_array) == CONFIG_FALSE) { syslog(LOG_WARNING, "'%s' setting should be an array. Array syntax: 'setting = [value1, value2, ...]'.\n", NAME_TCP_RELAY_PORTS); return; } int config_port_count = config_setting_length(ports_array); if (config_port_count == 0) { syslog(LOG_WARNING, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS); return; } *tcp_relay_ports = malloc(config_port_count * sizeof(uint16_t)); int i; for (i = 0; i < config_port_count; i ++) { config_setting_t *elem = config_setting_get_elem(ports_array, i); if (elem == NULL) { // it's NULL if `ports_array` is not an array (we have that check earlier) or if `i` is out of range, which should not be syslog(LOG_WARNING, "Port #%d: Something went wrong while parsing the port. Stopping reading ports.\n", i); break; } if (config_setting_is_number(elem) == CONFIG_FALSE) { syslog(LOG_WARNING, "Port #%d: Not a number. Skipping.\n", i); continue; } (*tcp_relay_ports)[*tcp_relay_port_count] = config_setting_get_int(elem); if ((*tcp_relay_ports)[*tcp_relay_port_count] < MIN_ALLOWED_PORT || (*tcp_relay_ports)[*tcp_relay_port_count] > MAX_ALLOWED_PORT) { syslog(LOG_WARNING, "Port #%d: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i, (*tcp_relay_ports)[*tcp_relay_port_count], MIN_ALLOWED_PORT, MAX_ALLOWED_PORT); continue; } (*tcp_relay_port_count) ++; } // the loop above skips invalid ports, so we adjust the allocated memory size if ((*tcp_relay_port_count) > 0) { *tcp_relay_ports = realloc(*tcp_relay_ports, (*tcp_relay_port_count) * sizeof(uint16_t)); } else { free(*tcp_relay_ports); *tcp_relay_ports = NULL; } }