643 lines
23 KiB
C
643 lines
23 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
/*! \file common/config/libconfig/config_libconfig.c
|
|
* \brief: implementation libconfig configuration library
|
|
* \author Francois TABURET
|
|
* \date 2017
|
|
* \version 0.1
|
|
* \company NOKIA BellLabs France
|
|
* \email: francois.taburet@nokia-bell-labs.com
|
|
* \note
|
|
* \warning
|
|
*/
|
|
#define _GNU_SOURCE
|
|
#include <pthread.h>
|
|
#include <libconfig.h>
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
#include <libgen.h>
|
|
#include <sys/types.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
|
|
#include "config_libconfig.h"
|
|
#include "config_libconfig_private.h"
|
|
#define NOT_uniqCfg
|
|
#include "../config_common.h"
|
|
#include "../config_userapi.h"
|
|
#include "errno.h"
|
|
#include "assertions.h"
|
|
|
|
#if ( LIBCONFIG_VER_MAJOR == 1 && LIBCONFIG_VER_MINOR < 5)
|
|
#define config_setting_lookup config_lookup_from
|
|
#endif
|
|
|
|
void config_libconfig_end(configmodule_interface_t *cfg);
|
|
|
|
int read_strlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, config_setting_t *setting, char *cfgpath)
|
|
{
|
|
const char *str;
|
|
int st;
|
|
int numelt;
|
|
numelt=config_setting_length(setting);
|
|
config_check_valptr(cfg, cfgoptions, sizeof(char *), numelt);
|
|
st=0;
|
|
AssertFatal(MAX_LIST_SIZE > numelt,
|
|
"This piece of code use fixed size arry of constant #define MAX_LIST_SIZE %d\n",
|
|
MAX_LIST_SIZE );
|
|
for (int i=0; i< numelt ; i++) {
|
|
str=config_setting_get_string_elem(setting,i);
|
|
|
|
if (str==NULL) {
|
|
printf_params(cfg, "[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i);
|
|
} else {
|
|
snprintf(cfgoptions->strlistptr[i], DEFAULT_EXTRA_SZ, "%s",str);
|
|
st++;
|
|
printf_params(cfg, "[LIBCONFIG] %s%i: %s\n", cfgpath, i, cfgoptions->strlistptr[i]);
|
|
}
|
|
}
|
|
|
|
cfgoptions->numelt=numelt;
|
|
return st;
|
|
}
|
|
|
|
static int read_intarray(configmodule_interface_t *cfg, paramdef_t *cfgoptions, config_setting_t *setting, char *cfgpath)
|
|
{
|
|
cfgoptions->numelt=config_setting_length(setting);
|
|
|
|
if (cfgoptions->numelt > 0) {
|
|
cfgoptions->iptr =
|
|
config_allocate_new(cfg, cfgoptions->numelt * sizeof(*cfgoptions->iptr), !(cfgoptions->paramflags & PARAMFLAG_NOFREE));
|
|
|
|
for (int i=0; i< cfgoptions->numelt && cfgoptions->iptr != NULL; i++) {
|
|
cfgoptions->iptr[i]=config_setting_get_int_elem(setting,i);
|
|
printf_params(cfg, "[LIBCONFIG] %s[%i]: %i\n", cfgpath, i, cfgoptions->iptr[i]);
|
|
} /* for loop on array element... */
|
|
}
|
|
|
|
return cfgoptions->numelt;
|
|
}
|
|
int config_libconfig_setparams(configmodule_interface_t *cfg,
|
|
paramdef_t *cfgoptions,
|
|
int numoptions,
|
|
config_setting_t *asetting,
|
|
char *prefix)
|
|
{
|
|
int status;
|
|
int errors = 0;
|
|
int notused = 0;
|
|
int emptyla = 0;
|
|
#define LIBCONFIG_NOTUSED_PARAMS "Not used? (NULL value ptr)"
|
|
char *secprefix = (prefix == NULL) ? "" : prefix;
|
|
|
|
for (int i = 0; i < numoptions; i++) {
|
|
if (cfgoptions[i].paramflags & PARAMFLAG_CMDLINEONLY) {
|
|
continue;
|
|
printf_params(cfg, "[LIBCONFIG] setting %s.%s skipped (command line only) \n", secprefix, cfgoptions[i].optname);
|
|
}
|
|
status = CONFIG_FALSE;
|
|
config_setting_t *psetting;
|
|
char *spath = malloc(((prefix == NULL) ? 0 : strlen(prefix)) + strlen(cfgoptions[i].optname) + 10);
|
|
sprintf(spath, "%s%s%s", secprefix, (prefix == NULL) ? "" : ".", cfgoptions[i].optname);
|
|
psetting = config_lookup(&(libconfig_privdata.runtcfg), spath);
|
|
free(spath);
|
|
if (psetting != NULL) {
|
|
printf_params(cfg, "[LIBCONFIG] setting %s.%s already created \n", secprefix, cfgoptions[i].optname);
|
|
continue;
|
|
}
|
|
switch (cfgoptions[i].type) {
|
|
case TYPE_STRING:
|
|
psetting = config_setting_add(asetting, cfgoptions[i].optname, CONFIG_TYPE_STRING);
|
|
if (psetting != NULL) {
|
|
char *value;
|
|
if (cfgoptions[i].strptr == NULL) {
|
|
notused++;
|
|
value = LIBCONFIG_NOTUSED_PARAMS;
|
|
} else {
|
|
value = *(cfgoptions[i].strptr);
|
|
}
|
|
status = config_setting_set_string(psetting, value);
|
|
}
|
|
break;
|
|
case TYPE_STRINGLIST:
|
|
psetting = config_setting_add(asetting, cfgoptions[i].optname, CONFIG_TYPE_LIST);
|
|
if (psetting != NULL) {
|
|
if (cfgoptions[i].numelt <= 0) {
|
|
emptyla++;
|
|
printf_params(cfg, "[LIBCONFIG], no element in list %s\n", cfgoptions[i].optname);
|
|
status = CONFIG_TRUE;
|
|
}
|
|
for (int j = 0; j < cfgoptions[i].numelt; j++) {
|
|
config_setting_t *elemsetting = config_setting_set_string_elem(psetting, -1, cfgoptions[i].strptr[j]);
|
|
if (elemsetting == NULL) {
|
|
fprintf(stderr, "[LIBCONFIG] Error: Creating list %s element %i value %s\n", cfgoptions[i].optname, j, cfgoptions[i].strptr[j]);
|
|
break;
|
|
} else
|
|
status = CONFIG_TRUE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TYPE_UINT8:
|
|
case TYPE_INT8:
|
|
case TYPE_UINT16:
|
|
case TYPE_INT16:
|
|
case TYPE_UINT32:
|
|
case TYPE_INT32:
|
|
case TYPE_MASK:
|
|
psetting = config_setting_add(asetting, cfgoptions[i].optname, CONFIG_TYPE_INT);
|
|
if (psetting != NULL)
|
|
status = config_setting_set_int(psetting, (int)*(cfgoptions[i].iptr));
|
|
break;
|
|
|
|
case TYPE_UINT64:
|
|
case TYPE_INT64:
|
|
psetting = config_setting_add(asetting, cfgoptions[i].optname, CONFIG_TYPE_INT64);
|
|
if (psetting != NULL)
|
|
status = config_setting_set_int64(psetting, (int64_t) * (cfgoptions[i].i64ptr));
|
|
break;
|
|
|
|
case TYPE_UINTARRAY:
|
|
case TYPE_INTARRAY:
|
|
psetting = config_setting_add(asetting, cfgoptions[i].optname, CONFIG_TYPE_ARRAY);
|
|
if (psetting != NULL) {
|
|
if (cfgoptions[i].numelt <= 0) {
|
|
emptyla++;
|
|
printf_params(cfg, "[LIBCONFIG], no element in array %s.%s\n", secprefix, cfgoptions[i].optname);
|
|
status = CONFIG_TRUE;
|
|
}
|
|
for (int j = 0; j < cfgoptions[i].numelt; j++) {
|
|
config_setting_t *elemsetting = config_setting_set_int_elem(psetting, -1, (int)(cfgoptions[i].iptr[j]));
|
|
if (elemsetting == NULL) {
|
|
fprintf(stderr, "[LIBCONFIG] Error: Creating array %s.%s, at index %i value %i\n", secprefix, cfgoptions[i].optname, j, (int)(cfgoptions[i].iptr[j]));
|
|
break;
|
|
} else
|
|
status = CONFIG_TRUE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TYPE_DOUBLE:
|
|
psetting = config_setting_add(asetting, cfgoptions[i].optname, CONFIG_TYPE_FLOAT);
|
|
if (psetting != NULL)
|
|
status = config_setting_set_float(psetting, (double)*(cfgoptions[i].dblptr));
|
|
break;
|
|
|
|
case TYPE_IPV4ADDR:
|
|
psetting = config_setting_add(asetting, cfgoptions[i].optname, CONFIG_TYPE_STRING);
|
|
if (psetting != NULL) {
|
|
char ipstr[INET_ADDRSTRLEN];
|
|
if (inet_ntop(AF_INET, cfgoptions[i].uptr, ipstr, INET_ADDRSTRLEN) == NULL) {
|
|
notused++;
|
|
sprintf(ipstr, "undef");
|
|
} else {
|
|
status = config_setting_set_string(psetting, ipstr);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TYPE_LIST:
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "[LIBCONFIG] %s.%s type %i not supported\n", secprefix, cfgoptions[i].optname, cfgoptions[i].type);
|
|
status = CONFIG_FALSE;
|
|
break;
|
|
} /* switch on param type */
|
|
if (status != CONFIG_TRUE) {
|
|
errors++;
|
|
fprintf(stderr, "[LIBCONFIG] Error creating setting %i: %s.%s type %i\n", i, secprefix, cfgoptions[i].optname, cfgoptions[i].type);
|
|
}
|
|
}
|
|
printf_params(cfg, "[LIBCONFIG], in group \"%s\" %i settings \n", secprefix, numoptions);
|
|
if (notused > 0)
|
|
printf_params(cfg, "[LIBCONFIG], ..... %i settings with NULL value pointer\n", notused);
|
|
if (errors > 0)
|
|
fprintf(stderr, "[LIBCONFIG] .....%i settings creation errors \n", errors);
|
|
if (emptyla > 0)
|
|
fprintf(stderr, "[LIBCONFIG] .....%i empty lists or arrays settings \n", emptyla);
|
|
|
|
if (cfg->status) {
|
|
cfg->status->num_err_nullvalue += notused;
|
|
cfg->status->num_err_write += errors;
|
|
cfg->status->num_write += numoptions;
|
|
cfg->status->emptyla += emptyla;
|
|
}
|
|
return errors;
|
|
}
|
|
|
|
int config_libconfig_set(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix)
|
|
{
|
|
char *tokctx1 = NULL;
|
|
int listidx = -1;
|
|
char *prefixbck = NULL;
|
|
char *prefix_elem1 = NULL;
|
|
config_setting_t *asetting = config_root_setting(&(libconfig_privdata.runtcfg));
|
|
if (prefix != NULL) {
|
|
prefixbck = strdup(prefix);
|
|
prefix_elem1 = strtok_r(prefixbck, ".", &tokctx1);
|
|
}
|
|
printf_params(cfg, "[LIBCONFIG], processing prefix %s\n", (prefix == NULL) ? "NULL" : prefix);
|
|
|
|
/* parse the prefix , possibly creating groups, lists and list elements */
|
|
while (prefix_elem1 != NULL) {
|
|
int n1 = strlen(prefix_elem1);
|
|
char *prefix_elem2 = prefix_elem1 + n1 + 1;
|
|
printf_params(cfg, "[LIBCONFIG], processing elem1 %s elem2 %s\n", prefix_elem1, prefix_elem2);
|
|
/* prefix (the path to the parameter name) may contain groups and elements from a list, which are specified with [] */
|
|
if (prefix_elem2[0] != '[') { // not a list
|
|
|
|
config_setting_t *tmpset = config_setting_lookup(asetting, prefix_elem1);
|
|
if (tmpset == NULL)
|
|
asetting = config_setting_add(asetting, prefix_elem1, CONFIG_TYPE_GROUP);
|
|
else
|
|
asetting = tmpset;
|
|
printf_params(cfg, "[LIBCONFIG], creating or looking for group %s: %s\n", prefix_elem1, (asetting == NULL) ? "NOK" : "OK");
|
|
} else { // a list
|
|
listidx = (int)strtol(prefix_elem2 + 1, NULL, 10);
|
|
if (errno == EINVAL || errno == ERANGE) {
|
|
printf_params(cfg, "[LIBCONFIG], Error %s looking for list index in %s \n", strerror(errno), prefix_elem2);
|
|
break;
|
|
}
|
|
config_setting_t *tmpset = config_setting_lookup(asetting, prefix_elem1);
|
|
if (tmpset == NULL)
|
|
asetting = config_setting_add(asetting, prefix_elem1, CONFIG_TYPE_LIST);
|
|
else
|
|
asetting = tmpset;
|
|
printf_params(cfg, "[LIBCONFIG], creating or looking for list %s: %s\n", prefix_elem1, (asetting == NULL) ? "NOK" : "OK");
|
|
if (asetting != NULL) {
|
|
tmpset = config_setting_get_elem(asetting, listidx);
|
|
if (tmpset == NULL)
|
|
asetting = config_setting_add(asetting, NULL, CONFIG_TYPE_GROUP);
|
|
else
|
|
asetting = tmpset;
|
|
printf_params(cfg,
|
|
"[LIBCONFIG], creating or looking for list element %i: %s\n",
|
|
listidx,
|
|
(asetting == NULL) ? "NOK" : "OK");
|
|
}
|
|
prefix_elem1 = strtok_r(NULL, ".", &tokctx1); // skip the [x] elements we already took care of it
|
|
if (prefix_elem1 == NULL) {
|
|
fprintf(stderr, "[LICONFIG] End of parsing %s \n", prefix);
|
|
break;
|
|
}
|
|
}
|
|
if (asetting == NULL) {
|
|
fprintf(stderr, "[LIBCONFIG] Error creating setting %s %s %i\n", prefix_elem1, prefix_elem2, listidx);
|
|
}
|
|
prefix_elem1 = strtok_r(NULL, ".", &tokctx1);
|
|
}
|
|
free(prefixbck);
|
|
if (asetting != NULL) {
|
|
config_libconfig_setparams(cfg, cfgoptions, numoptions, asetting, prefix);
|
|
printf_params(cfg, "[LIBCONFIG] %i settings added in group %s\n", numoptions, (prefix == NULL) ? "" : prefix);
|
|
return 0;
|
|
} else {
|
|
fprintf(stderr, "[LIBCONFIG] Error parsing %s params, skipped...\n", (prefix == NULL) ? "" : prefix);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int config_libconfig_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix)
|
|
{
|
|
config_setting_t *setting;
|
|
char *str = NULL;
|
|
int u = 0;
|
|
long long int llu = 0;
|
|
double dbl = 0.0f;
|
|
int status = 0;
|
|
int fatalerror = 0;
|
|
int numdefvals = 0;
|
|
char cfgpath[512]; /* 512 should be enough for the sprintf below */
|
|
|
|
for(int i=0; i<numoptions; i++) {
|
|
if (prefix != NULL) {
|
|
sprintf(cfgpath,"%s.%s",prefix,cfgoptions[i].optname);
|
|
} else {
|
|
sprintf(cfgpath,"%s",cfgoptions[i].optname);
|
|
}
|
|
|
|
if( (cfgoptions->paramflags & PARAMFLAG_DONOTREAD) != 0) {
|
|
printf_params(cfg, "[LIBCONFIG] %s.%s ignored\n", cfgpath, cfgoptions[i].optname);
|
|
continue;
|
|
}
|
|
|
|
int notfound = 0;
|
|
int defval = 0;
|
|
|
|
switch(cfgoptions[i].type) {
|
|
case TYPE_STRING:
|
|
if ( config_lookup_string(&(libconfig_privdata.cfg), cfgpath, (const char**)&str)) {
|
|
config_check_valptr(cfg, &cfgoptions[i], 1, strlen(str) + 1);
|
|
if ( strlen(str)+1 > cfgoptions[i].numelt )
|
|
fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n",
|
|
cfgpath,str,cfgoptions[i].numelt);
|
|
snprintf( *cfgoptions[i].strptr , cfgoptions[i].numelt, "%s", str);
|
|
printf_params(cfg, "[LIBCONFIG] %s: \"%s\"\n", cfgpath, *cfgoptions[i].strptr);
|
|
} else {
|
|
defval = config_common_getdefault(cfg, &cfgoptions[i], prefix);
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPE_STRINGLIST:
|
|
setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath );
|
|
|
|
if ( setting != NULL) {
|
|
read_strlist(cfg, &cfgoptions[i], setting, cfgpath);
|
|
} else {
|
|
defval = config_common_getdefault(cfg, &(cfgoptions[i]), prefix);
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPE_UINT8:
|
|
case TYPE_INT8:
|
|
case TYPE_UINT16:
|
|
case TYPE_INT16:
|
|
case TYPE_UINT32:
|
|
case TYPE_INT32:
|
|
case TYPE_MASK:
|
|
if ( config_lookup_int(&(libconfig_privdata.cfg),cfgpath, &u)) {
|
|
config_check_valptr(cfg, &(cfgoptions[i]), sizeof(*cfgoptions[i].iptr), 1);
|
|
config_assign_int(cfg, &(cfgoptions[i]), cfgpath, u);
|
|
} else {
|
|
defval = config_common_getdefault(cfg, &(cfgoptions[i]), prefix);
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPE_UINT64:
|
|
case TYPE_INT64:
|
|
if ( config_lookup_int64(&(libconfig_privdata.cfg),cfgpath, &llu)) {
|
|
config_check_valptr(cfg, &cfgoptions[i], sizeof(*cfgoptions[i].i64ptr), 1);
|
|
|
|
if(cfgoptions[i].type==TYPE_UINT64) {
|
|
*(cfgoptions[i].u64ptr) = (uint64_t)llu;
|
|
printf_params(cfg, "[LIBCONFIG] %s: %lu\n", cfgpath, *cfgoptions[i].u64ptr);
|
|
} else {
|
|
*(cfgoptions[i].i64ptr) = llu;
|
|
printf_params(cfg, "[LIBCONFIG] %s: %ld\n", cfgpath, *cfgoptions[i].i64ptr);
|
|
}
|
|
} else {
|
|
defval = config_common_getdefault(cfg, &(cfgoptions[i]), prefix);
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPE_UINTARRAY:
|
|
case TYPE_INTARRAY:
|
|
setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath );
|
|
|
|
if ( setting != NULL) {
|
|
read_intarray(cfg, &cfgoptions[i], setting, cfgpath);
|
|
} else {
|
|
defval = config_common_getdefault(cfg, &(cfgoptions[i]), prefix);
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPE_DOUBLE:
|
|
if ( config_lookup_float(&(libconfig_privdata.cfg),cfgpath, &dbl)) {
|
|
config_check_valptr(cfg, &cfgoptions[i], sizeof(*cfgoptions[i].dblptr), 1);
|
|
*cfgoptions[i].dblptr = dbl;
|
|
printf_params(cfg, "[LIBCONFIG] %s: %lf\n", cfgpath, *(cfgoptions[i].dblptr));
|
|
} else {
|
|
defval = config_common_getdefault(cfg, &(cfgoptions[i]), prefix);
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPE_IPV4ADDR:
|
|
if ( !config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
|
|
defval = config_common_getdefault(cfg, &(cfgoptions[i]), prefix);
|
|
} else {
|
|
int rst = config_assign_ipv4addr(cfg, cfgoptions, str);
|
|
|
|
if (rst < 0) {
|
|
fprintf(stderr,"[LIBCONFIG] %s not valid for %s \n", str, cfgpath);
|
|
fatalerror=1;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPE_LIST:
|
|
setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath );
|
|
|
|
if ( setting) {
|
|
cfgoptions[i].numelt=config_setting_length(setting);
|
|
} else {
|
|
notfound=1;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr,"[LIBCONFIG] %s type %i not supported\n", cfgpath,cfgoptions[i].type);
|
|
fatalerror=1;
|
|
break;
|
|
} /* switch on param type */
|
|
|
|
if( notfound == 1) {
|
|
fprintf(stderr, "[LIBCONFIG] %s not found in %s ", cfgpath, libconfig_privdata.configfile);
|
|
|
|
if ( (cfgoptions[i].paramflags & PARAMFLAG_MANDATORY) != 0) {
|
|
fatalerror=1;
|
|
fprintf(stderr, " mandatory parameter missing\n");
|
|
}
|
|
} else {
|
|
if (defval == 1) {
|
|
numdefvals++;
|
|
cfgoptions[i].paramflags = cfgoptions[i].paramflags | PARAMFLAG_PARAMSETDEF;
|
|
} else {
|
|
cfgoptions[i].paramflags = cfgoptions[i].paramflags | PARAMFLAG_PARAMSET;
|
|
}
|
|
|
|
status++;
|
|
}
|
|
} /* for loop on options */
|
|
|
|
printf_params(cfg,
|
|
"[LIBCONFIG] %s: %i/%i parameters successfully set, (%i to default value)\n",
|
|
prefix == NULL ? "(root)" : prefix,
|
|
status,
|
|
numoptions,
|
|
numdefvals);
|
|
|
|
if (fatalerror == 1) {
|
|
fprintf(stderr,"[LIBCONFIG] fatal errors found when processing %s \n", libconfig_privdata.configfile );
|
|
config_libconfig_end(cfg);
|
|
end_configmodule(cfg);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
int config_libconfig_getlist(configmodule_interface_t *cfg,
|
|
paramlist_def_t *ParamList,
|
|
paramdef_t *params,
|
|
int numparams,
|
|
char *prefix)
|
|
{
|
|
config_setting_t *setting;
|
|
int i,j,status;
|
|
char *listpath=NULL;
|
|
char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */
|
|
|
|
if (prefix != NULL) {
|
|
i=asprintf(&listpath ,"%s.%s",prefix,ParamList->listname);
|
|
} else {
|
|
i=asprintf(&listpath ,"%s",ParamList->listname);
|
|
}
|
|
|
|
setting = config_lookup(&(libconfig_privdata.cfg), listpath);
|
|
|
|
if ( setting) {
|
|
status = ParamList->numelt = config_setting_length(setting);
|
|
printf_params(cfg, "[LIBCONFIG] %i %s in config file %s \n", ParamList->numelt, listpath, libconfig_privdata.configfile);
|
|
} else {
|
|
printf_params(cfg, "[LIBCONFIG] list %s not found in config file %s \n", listpath, libconfig_privdata.configfile);
|
|
ParamList->numelt= 0;
|
|
status = -1;
|
|
}
|
|
|
|
if (ParamList->numelt > 0 && params != NULL) {
|
|
ParamList->paramarray = config_allocate_new(cfg, ParamList->numelt * sizeof(paramdef_t *), true);
|
|
|
|
for (i=0 ; i < ParamList->numelt ; i++) {
|
|
ParamList->paramarray[i] = config_allocate_new(cfg, numparams * sizeof(paramdef_t), true);
|
|
memcpy(ParamList->paramarray[i], params, sizeof(paramdef_t)*numparams);
|
|
|
|
for (j=0; j<numparams; j++) {
|
|
ParamList->paramarray[i][j].strptr = NULL ;
|
|
}
|
|
|
|
sprintf(cfgpath,"%s.[%i]",listpath,i);
|
|
config_libconfig_get(cfg, ParamList->paramarray[i], numparams, cfgpath);
|
|
} /* for i... */
|
|
} /* ParamList->numelt > 0 && params != NULL */
|
|
|
|
if (listpath != NULL)
|
|
free(listpath);
|
|
|
|
return status;
|
|
}
|
|
|
|
int config_libconfig_init(configmodule_interface_t *cfg)
|
|
{
|
|
char **cfgP = cfg->cfgP;
|
|
int numP = cfg->num_cfgP;
|
|
config_init(&(libconfig_privdata.cfg));
|
|
libconfig_privdata.configfile = strdup((char *)cfgP[0]);
|
|
cfg->numptrs = 0;
|
|
pthread_mutex_init(&cfg->memBlocks_mutex, NULL);
|
|
memset(cfg->oneBlock, 0, sizeof(cfg->oneBlock));
|
|
/* search for include path parameter and set config file include path accordingly */
|
|
for (int i=0; i<numP; i++) {
|
|
if (strncmp(cfgP[i],"incp",4) == 0) {
|
|
config_set_include_dir (&(libconfig_privdata.cfg),cfgP[i]+4);
|
|
break;
|
|
}
|
|
}
|
|
/* dirname may modify the input path and returned ptr may points to part of input path */
|
|
char *tmppath = strdup(libconfig_privdata.configfile);
|
|
if ( config_get_include_dir (&(libconfig_privdata.cfg)) == NULL) {
|
|
config_set_include_dir (&(libconfig_privdata.cfg),dirname( tmppath ));
|
|
}
|
|
|
|
const char *incp = config_get_include_dir (&(libconfig_privdata.cfg)) ;
|
|
|
|
printf_params(cfg, "[LIBCONFIG] Path for include directive set to: %s\n", (incp != NULL) ? incp : "libconfig defaults");
|
|
/* set convertion option to allow integer to float conversion*/
|
|
config_set_auto_convert (&(libconfig_privdata.cfg), CONFIG_TRUE);
|
|
/* Read the file. If there is an error, report it and exit. */
|
|
if( config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile) == CONFIG_FALSE) {
|
|
fprintf(stderr,
|
|
"[LIBCONFIG] file %s - line %d: %s\n",
|
|
libconfig_privdata.configfile,
|
|
config_error_line(&(libconfig_privdata.cfg)),
|
|
config_error_text(&(libconfig_privdata.cfg)));
|
|
config_destroy(&(libconfig_privdata.cfg));
|
|
fprintf(stderr, "\n");
|
|
free(tmppath);
|
|
return -1;
|
|
}
|
|
|
|
/* possibly init a libconfig struct for saving really used params */
|
|
if (cfg->rtflags & CONFIG_SAVERUNCFG) {
|
|
config_init(&(libconfig_privdata.runtcfg));
|
|
// config_set_options (&(libconfig_privdata.runtcfg), CONFIG_OPTION_ALLOW_OVERRIDES, CONFIG_TRUE);
|
|
}
|
|
free(tmppath);
|
|
return 0;
|
|
}
|
|
|
|
void config_libconfig_write_parsedcfg(configmodule_interface_t *cfg)
|
|
{
|
|
if (cfg->rtflags & CONFIG_SAVERUNCFG) {
|
|
char *fname = strdup(libconfig_privdata.configfile);
|
|
int newcfgflen = strlen(libconfig_privdata.configfile) + strlen(cfg->tmpdir) + 20;
|
|
cfg->status->debug_cfgname = realloc(cfg->status->debug_cfgname, newcfgflen);
|
|
time_t t = time(NULL);
|
|
struct tm tm = *localtime(&t);
|
|
snprintf(cfg->status->debug_cfgname,
|
|
newcfgflen,
|
|
"%s/%s-run%d_%02d_%02d_%02d%02d",
|
|
cfg->tmpdir,
|
|
basename(fname),
|
|
tm.tm_year + 1900,
|
|
tm.tm_mon + 1,
|
|
tm.tm_mday,
|
|
tm.tm_hour,
|
|
tm.tm_min);
|
|
if (config_write_file(&(libconfig_privdata.runtcfg), cfg->status->debug_cfgname) != CONFIG_TRUE) {
|
|
fprintf(stderr,
|
|
"[LIBCONFIG] %s %d file %s - line %d: %s\n",
|
|
__FILE__,
|
|
__LINE__,
|
|
cfg->status->debug_cfgname,
|
|
config_error_line(&(libconfig_privdata.runtcfg)),
|
|
config_error_text(&(libconfig_privdata.runtcfg)));
|
|
} else {
|
|
printf_params(cfg, "[LIBCONFIG] file %s created successfully\n", cfg->status->debug_cfgname);
|
|
}
|
|
free(fname);
|
|
} else {
|
|
printf_params(cfg, "[LIBCONFIG] Cannot create config file after parsing: CONFIG_SAVERUNCFG flag not specified\n");
|
|
}
|
|
}
|
|
|
|
void config_libconfig_end(configmodule_interface_t *cfg)
|
|
{
|
|
config_destroy(&(libconfig_privdata.cfg));
|
|
if (cfg->rtflags & CONFIG_SAVERUNCFG) {
|
|
config_destroy(&(libconfig_privdata.runtcfg));
|
|
}
|
|
if ( libconfig_privdata.configfile != NULL ) {
|
|
free(libconfig_privdata.configfile);
|
|
libconfig_privdata.configfile=NULL;
|
|
}
|
|
}
|