From e179213be05ba5c268b09354bf56e95277b7b354 Mon Sep 17 00:00:00 2001
From: frtabu <francois.taburet@nokia-bell-labs.com>
Date: Mon, 14 Jan 2019 19:13:12 +0100
Subject: [PATCH] exit softmodem when a command line option requiring an
 argument is specified without an option value. Previous behavior was to print
 a message and ignore the option

---
 common/config/config_cmdline.c             |  12 +-
 common/config/config_userapi.c             |   6 +
 common/config/config_userapi.h             |   5 +-
 common/config/libconfig/config_libconfig.c | 489 +++++++++++----------
 targets/RT/USER/lte-softmodem.c            |   4 +-
 targets/RT/USER/lte-uesoftmodem.c          |   2 +-
 6 files changed, 282 insertions(+), 236 deletions(-)

diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c
index 7fca12540d..635287afb4 100644
--- a/common/config/config_cmdline.c
+++ b/common/config/config_cmdline.c
@@ -75,6 +75,7 @@ int processoption(paramdef_t *cfgoptions, char *value) {
   if ( value == NULL) {
     if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */
       fprintf(stderr,"[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname);
+      exit_fun("[CONFIG] command line parsing fatal error");
       return 0;
     } else {        /* boolean value option without argument, set value to true*/
       tmpval = defbool;
@@ -143,7 +144,10 @@ int processoption(paramdef_t *cfgoptions, char *value) {
   return optisset;
 }
 
-int config_check_cmdlineopt(char *prefix) {
+/*--------------------------------------------------------------------*/
+/*  check unknown options in the command line
+*/
+int config_check_unknown_cmdlineopt(char *prefix) {
   int unknowndetected=0;
   char testprefix[CONFIG_MAXOPTLENGTH]="";
   int finalcheck = 0;
@@ -161,6 +165,8 @@ int config_check_cmdlineopt(char *prefix) {
 
     if ( !finalcheck && testprefix[0]==0 && index(config_get_if()->argv[i],'.') != NULL) continue;
 
+    if ( !finalcheck && isdigit(config_get_if()->argv[i][0])) continue;
+
     if ( !finalcheck && config_get_if()->argv[i][0] == '-' && isdigit(config_get_if()->argv[i][1])) continue;
 
     if ( (config_get_if()->argv_info[i] & CONFIG_CMDLINEOPT_PROCESSED) == 0 ) {
@@ -173,7 +179,7 @@ int config_check_cmdlineopt(char *prefix) {
   printf_cmdl("[CONFIG] %i unknown option(s) in command line starting with %s (section %s)\n",
               unknowndetected,testprefix,((prefix==NULL)?"":prefix));
   return unknowndetected;
-}  /* parse_cmdline*/
+}  /* config_check_unknown_cmdlineopt */
 
 int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) {
   int c = config_get_if()->argc;
@@ -269,7 +275,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
   printf_cmdl("[CONFIG] %s %i options set from command line\n",((prefix == NULL) ? "(root)":prefix),j);
 
   if ( !(CONFIG_ISFLAGSET( CONFIG_NOCHECKUNKOPT )) ) {
-    i=config_check_cmdlineopt(prefix);
+    i=config_check_unknown_cmdlineopt(prefix);
 
     if (i > 0) {
       fprintf(stderr,"[CONFIG] %i unknown options for section %s detected in command line\n",
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index afbe1ae887..b149bfd636 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -370,6 +370,12 @@ int config_checkstr_assign_integer(paramdef_t *param) {
   return -1;
 }
 
+void config_set_checkfunctions(paramdef_t *params, checkedparam_t *checkfunctions, int numparams) {
+  for (int i=0; i< numparams ; i++ ) {
+    params[i].chkPptr = &(checkfunctions[i]);
+  }
+}
+
 int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) {
   int status = 0;
 
diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h
index 5542148343..d0508ffbeb 100644
--- a/common/config/config_userapi.h
+++ b/common/config/config_userapi.h
@@ -57,10 +57,13 @@ extern int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr);
 
 /* apis to get/check parameters, to be used by oai modules, at configuration time */
 #define CONFIG_CHECKALLSECTIONS "ALLSECTIONS"
-extern int config_check_cmdlineopt(char *prefix);
+extern int config_check_unknown_cmdlineopt(char *prefix);
 extern int config_get(paramdef_t *params,int numparams, char *prefix);
 extern int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix);
 
+/* apis to set some of the paramdef_t fields before using the get/getlist api's */
+extern void config_set_checkfunctions(paramdef_t *params, checkedparam_t *checkfunctions, int numparams);
+
 /* apis to retrieve parameters info after calling get or getlist functions */
 extern int config_isparamset(paramdef_t *params,int paramidx);
 extern int config_get_processedint(paramdef_t *cfgoption);
diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c
index cb6fa46293..2d861f2dc3 100644
--- a/common/config/libconfig/config_libconfig.c
+++ b/common/config/libconfig/config_libconfig.c
@@ -42,60 +42,60 @@
 #include "errno.h"
 
 #if ( LIBCONFIG_VER_MAJOR == 1 && LIBCONFIG_VER_MINOR < 5)
-#define config_setting_lookup config_lookup_from
+  #define config_setting_lookup config_lookup_from
 #endif
 
 void config_libconfig_end(void );
 
-int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath)
-{
-const char *str;
-int st;
-int numelt;
-
-   numelt=config_setting_length(setting);
-   config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt);
-   st=0;
-   for (int i=0; i< numelt ; i++) {
-       str=config_setting_get_string_elem(setting,i);
-       if (str==NULL) {
-          printf("[LIBCONFIG] %s%i  not found in config file\n", cfgoptions->optname,i);
-       } else {
-            config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1);
-            sprintf(cfgoptions->strlistptr[i],"%s",str);
-	    st++;
-            printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]);
-       }
-   }
-   cfgoptions->numelt=numelt;
-   return st;
+int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath) {
+  const char *str;
+  int st;
+  int numelt;
+  numelt=config_setting_length(setting);
+  config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt);
+  st=0;
+
+  for (int i=0; i< numelt ; i++) {
+    str=config_setting_get_string_elem(setting,i);
+
+    if (str==NULL) {
+      printf("[LIBCONFIG] %s%i  not found in config file\n", cfgoptions->optname,i);
+    } else {
+      config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1);
+      sprintf(cfgoptions->strlistptr[i],"%s",str);
+      st++;
+      printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]);
+    }
+  }
+
+  cfgoptions->numelt=numelt;
+  return st;
 }
 
-int read_intarray(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath)
-{
-
-   cfgoptions->numelt=config_setting_length(setting);
-   
-   if (cfgoptions->numelt > 0) {
-       cfgoptions->iptr=malloc(sizeof(int) * (cfgoptions->numelt));
-       for (int i=0; i< cfgoptions->numelt && cfgoptions->iptr != NULL; i++) {
-            cfgoptions->iptr[i]=config_setting_get_int_elem(setting,i);
-            printf_params("[LIBCONFIG] %s[%i]: %i\n", cfgpath,i,cfgoptions->iptr[i]);
-       } /* for loop on array element... */
-   }
-   return cfgoptions->numelt;
+int read_intarray(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath) {
+  cfgoptions->numelt=config_setting_length(setting);
+
+  if (cfgoptions->numelt > 0) {
+    cfgoptions->iptr=malloc(sizeof(int) * (cfgoptions->numelt));
+
+    for (int i=0; i< cfgoptions->numelt && cfgoptions->iptr != NULL; i++) {
+      cfgoptions->iptr[i]=config_setting_get_int_elem(setting,i);
+      printf_params("[LIBCONFIG] %s[%i]: %i\n", cfgpath,i,cfgoptions->iptr[i]);
+    } /* for loop on array element... */
+  }
+
+  return cfgoptions->numelt;
 }
 
 
 
 
-int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
-{
+int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
   config_setting_t *setting;
   char *str;
   int i,u;
   long long int llu;
-  double dbl; 
+  double dbl;
   int rst;
   int status=0;
   int notfound;
@@ -104,211 +104,244 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
   int numdefvals=0;
   char cfgpath[512];  /* 512 should be enough for the sprintf below */
 
-  for(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("[LIBCONFIG] %s.%s ignored\n", cfgpath,cfgoptions[i].optname );
-         continue;
-     }
-     notfound=0;
-     defval=0;
-     switch(cfgoptions[i].type)
-       {
-       	case TYPE_STRING:
-           if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
-              if ( cfgoptions[i].numelt > 0  && str != NULL && strlen(str) >= cfgoptions[i].numelt ) {
-                  fprintf(stderr,"[LIBCONFIG] %s:  %s exceeds maximum length of %i bytes, value truncated\n",
-                           cfgpath,str,cfgoptions[i].numelt); 
-                  str[strlen(str)-1] = 0;
-              }
-              if (cfgoptions[i].numelt == 0 ) {
-        //          config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
-                  config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
-                  sprintf( *(cfgoptions[i].strptr) , "%s", str);
-                  printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) );
-              } else {
-                 sprintf( (char *)(cfgoptions[i].strptr) , "%s", str);
-                 printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr );
-              }
-           } else {
-              defval=config_setdefault_string(&(cfgoptions[i]),prefix); 
-	   }
-       break;
-       	case TYPE_STRINGLIST:
-	   setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath );
-           if ( setting != NULL) {
-              read_strlist(&cfgoptions[i],setting,cfgpath);
-           } else {
-              defval=config_setdefault_stringlist(&(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(&(cfgoptions[i]), (char **)(&(cfgoptions[i].iptr)),sizeof(int32_t));
-	      config_assign_int(&(cfgoptions[i]),cfgpath,u);
-           } else {
-              defval=config_setdefault_int(&(cfgoptions[i]),prefix);
-	   }	      
+  for(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("[LIBCONFIG] %s.%s ignored\n", cfgpath,cfgoptions[i].optname );
+      continue;
+    }
+
+    notfound=0;
+    defval=0;
+
+    switch(cfgoptions[i].type) {
+      case TYPE_STRING:
+        if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
+          if ( cfgoptions[i].numelt > 0  && str != NULL && strlen(str) >= cfgoptions[i].numelt ) {
+            fprintf(stderr,"[LIBCONFIG] %s:  %s exceeds maximum length of %i bytes, value truncated\n",
+                    cfgpath,str,cfgoptions[i].numelt);
+            str[strlen(str)-1] = 0;
+          }
+
+          if (cfgoptions[i].numelt == 0 ) {
+            //          config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
+            config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
+            sprintf( *(cfgoptions[i].strptr) , "%s", str);
+            printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) );
+          } else {
+            sprintf( (char *)(cfgoptions[i].strptr) , "%s", str);
+            printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr );
+          }
+        } else {
+          defval=config_setdefault_string(&(cfgoptions[i]),prefix);
+        }
+
         break;
-       	case TYPE_UINT64:
-       	case TYPE_INT64:
-           if ( config_lookup_int64(&(libconfig_privdata.cfg),cfgpath, &llu)) {
-              config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].i64ptr),sizeof(long long));
-              if(cfgoptions[i].type==TYPE_UINT64) {
-                 *(cfgoptions[i].u64ptr) = (uint64_t)llu;
-                 printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].u64ptr)) );
-              } else {
-                 *(cfgoptions[i].iptr) = llu;
-                 printf_params("[LIBCONFIG] %s: %lli\n", cfgpath,(long long unsigned)(*(cfgoptions[i].i64ptr)) ); 
-              }
-           } else {
-              defval=config_setdefault_int64(&(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(&cfgoptions[i],setting,cfgpath);
-           } else {
-              defval=config_setdefault_intlist(&(cfgoptions[i]),prefix);
-	   }    
+
+      case TYPE_STRINGLIST:
+        setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath );
+
+        if ( setting != NULL) {
+          read_strlist(&cfgoptions[i],setting,cfgpath);
+        } else {
+          defval=config_setdefault_stringlist(&(cfgoptions[i]),prefix);
+        }
+
         break;
-       	case TYPE_DOUBLE:
-           if ( config_lookup_float(&(libconfig_privdata.cfg),cfgpath, &dbl)) {
-                 config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].dblptr),sizeof(double));
-                 *(cfgoptions[i].dblptr) = dbl;
-                 printf_params("[LIBCONFIG] %s: %lf\n", cfgpath,*(cfgoptions[i].dblptr) );
-           } else {
-              defval=config_setdefault_double(&(cfgoptions[i]),prefix);
-	   }	      
-        break;  
-       	case TYPE_IPV4ADDR:
-           if ( !config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
-              defval=config_setdefault_ipv4addr(&(cfgoptions[i]),prefix);
-	   } else {
-              rst=config_assign_ipv4addr(cfgoptions, str);
-	      if (rst < 0) {
-		 fprintf(stderr,"[LIBCONFIG] %s not valid for %s \n", str, cfgpath);
-                 fatalerror=1;
-              }
-           }  
+
+      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(&(cfgoptions[i]), (char **)(&(cfgoptions[i].iptr)),sizeof(int32_t));
+          config_assign_int(&(cfgoptions[i]),cfgpath,u);
+        } else {
+          defval=config_setdefault_int(&(cfgoptions[i]),prefix);
+        }
+
         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) {
-        printf("[LIBCONFIG] %s not found in %s ", cfgpath,libconfig_privdata.configfile );
-        if ( (cfgoptions[i].paramflags & PARAMFLAG_MANDATORY) != 0) {
+
+      case TYPE_UINT64:
+      case TYPE_INT64:
+        if ( config_lookup_int64(&(libconfig_privdata.cfg),cfgpath, &llu)) {
+          config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].i64ptr),sizeof(long long));
+
+          if(cfgoptions[i].type==TYPE_UINT64) {
+            *(cfgoptions[i].u64ptr) = (uint64_t)llu;
+            printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].u64ptr)) );
+          } else {
+            *(cfgoptions[i].iptr) = llu;
+            printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].i64ptr)) );
+          }
+        } else {
+          defval=config_setdefault_int64(&(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(&cfgoptions[i],setting,cfgpath);
+        } else {
+          defval=config_setdefault_intlist(&(cfgoptions[i]),prefix);
+        }
+
+        break;
+
+      case TYPE_DOUBLE:
+        if ( config_lookup_float(&(libconfig_privdata.cfg),cfgpath, &dbl)) {
+          config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].dblptr),sizeof(double));
+          *(cfgoptions[i].dblptr) = dbl;
+          printf_params("[LIBCONFIG] %s: %lf\n", cfgpath,*(cfgoptions[i].dblptr) );
+        } else {
+          defval=config_setdefault_double(&(cfgoptions[i]),prefix);
+        }
+
+        break;
+
+      case TYPE_IPV4ADDR:
+        if ( !config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
+          defval=config_setdefault_ipv4addr(&(cfgoptions[i]),prefix);
+        } else {
+          rst=config_assign_ipv4addr(cfgoptions, str);
+
+          if (rst < 0) {
+            fprintf(stderr,"[LIBCONFIG] %s not valid for %s \n", str, cfgpath);
             fatalerror=1;
-            printf("  mandatory parameter missing\n");
+          }
+        }
+
+        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 {
-           printf("\n");
+          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) {
+      printf("[LIBCONFIG] %s not found in %s ", cfgpath,libconfig_privdata.configfile );
+
+      if ( (cfgoptions[i].paramflags & PARAMFLAG_MANDATORY) != 0) {
+        fatalerror=1;
+        printf("  mandatory parameter missing\n");
+      } else {
+        printf("\n");
+      }
     } else {
       if (defval == 1) {
-          numdefvals++;
-	  cfgoptions[i].paramflags = cfgoptions[i].paramflags |  PARAMFLAG_PARAMSETDEF;
+        numdefvals++;
+        cfgoptions[i].paramflags = cfgoptions[i].paramflags |  PARAMFLAG_PARAMSETDEF;
       } else {
-          cfgoptions[i].paramflags = cfgoptions[i].paramflags |  PARAMFLAG_PARAMSET;
+        cfgoptions[i].paramflags = cfgoptions[i].paramflags |  PARAMFLAG_PARAMSET;
       }
+
       status++;
     }
   } /* for loop on options */
+
   printf("[LIBCONFIG] %s: %i/%i parameters successfully set, (%i to default value)\n",
-         ((prefix == NULL)?"(root)":prefix), 
+         ((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();
-      end_configmodule();
+    fprintf(stderr,"[LIBCONFIG] fatal errors found when processing  %s \n", libconfig_privdata.configfile );
+    config_libconfig_end();
+    end_configmodule();
   }
+
   return status;
 }
 
-int config_libconfig_getlist(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("[LIBCONFIG] %i %s in config file %s \n", 
-               ParamList->numelt,listpath,libconfig_privdata.configfile );
+int config_libconfig_getlist(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("[LIBCONFIG] %i %s in config file %s \n",
+                  ParamList->numelt,listpath,libconfig_privdata.configfile );
+  } else {
+    printf("[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 = malloc(ParamList->numelt * sizeof(paramdef_t *));
+
+    if ( ParamList->paramarray != NULL) {
+      config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray);
+      config_get_if()->numptrs++;
     } else {
-        printf("[LIBCONFIG] list %s not found in config file %s \n", 
-               listpath,libconfig_privdata.configfile );
-        ParamList->numelt= 0;
-        status = -1;
+      fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__);
+      exit(-1);
     }
-    if (ParamList->numelt > 0 && params != NULL) {
-        ParamList->paramarray = malloc(ParamList->numelt * sizeof(paramdef_t *));
-        if ( ParamList->paramarray != NULL) {
-             config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray); 
-             config_get_if()->numptrs++;
-        } else {
-             fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__);
-             exit(-1);
-        }
-        for (i=0 ; i < ParamList->numelt ; i++) {
-            ParamList->paramarray[i] = malloc(numparams * sizeof(paramdef_t));
-            if ( ParamList->paramarray[i] != NULL) {
-                 config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray[i]); 
-                 config_get_if()->numptrs++;
-            } else {
-                 fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__);
-                 exit(-1);
-            }
-            
-            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(ParamList->paramarray[i], numparams, cfgpath );
-        } /* for i... */
-    } /* ParamList->numelt > 0 && params != NULL */
-    if (listpath != NULL)
-        free(listpath);
-    return status;
+
+    for (i=0 ; i < ParamList->numelt ; i++) {
+      ParamList->paramarray[i] = malloc(numparams * sizeof(paramdef_t));
+
+      if ( ParamList->paramarray[i] != NULL) {
+        config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray[i]);
+        config_get_if()->numptrs++;
+      } else {
+        fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__);
+        exit(-1);
+      }
+
+      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(ParamList->paramarray[i], numparams, cfgpath );
+    } /* for i... */
+  } /* ParamList->numelt > 0 && params != NULL */
+
+  if (listpath != NULL)
+    free(listpath);
+
+  return status;
 }
 
-int config_libconfig_init(char *cfgP[], int numP)
-{
+int config_libconfig_init(char *cfgP[], int numP) {
   config_init(&(libconfig_privdata.cfg));
   libconfig_privdata.configfile = strdup((char *)cfgP[0]);
   config_get_if()->numptrs=0;
@@ -317,24 +350,22 @@ int config_libconfig_init(char *cfgP[], int numP)
   /* Read the file. If there is an error, report it and exit. */
   if(! config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile)) {
     fprintf(stderr,"[LIBCONFIG] %s %d file %s - %d - %s\n",__FILE__, __LINE__,
-                   libconfig_privdata.configfile, config_error_line(&(libconfig_privdata.cfg)),
-                   config_error_text(&(libconfig_privdata.cfg)));
+            libconfig_privdata.configfile, config_error_line(&(libconfig_privdata.cfg)),
+            config_error_text(&(libconfig_privdata.cfg)));
     config_destroy(&(libconfig_privdata.cfg));
     printf( "\n");
     return -1;
   }
-  
 
   return 0;
 }
 
 
-void config_libconfig_end(void )
-{
+void config_libconfig_end(void ) {
   config_destroy(&(libconfig_privdata.cfg));
+
   if ( libconfig_privdata.configfile != NULL ) {
-     free(libconfig_privdata.configfile);
-     libconfig_privdata.configfile=NULL;
-  } 
-  
+    free(libconfig_privdata.configfile);
+    libconfig_privdata.configfile=NULL;
+  }
 }
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 5dde1034a4..2ded10d3b0 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -689,7 +689,7 @@ int main( int argc, char **argv ) {
 #if T_TRACER
   T_Config_Init();
 #endif
-  ret=config_check_cmdlineopt(NULL);
+  ret=config_check_unknown_cmdlineopt(NULL);
 
   if (ret != 0) {
     LOG_E(ENB_APP, "%i unknown options in command line\n",ret);
@@ -938,7 +938,7 @@ int main( int argc, char **argv ) {
   sync_var=0;
   pthread_cond_broadcast(&sync_cond);
   pthread_mutex_unlock(&sync_mutex);
-  ret=config_check_cmdlineopt(CONFIG_CHECKALLSECTIONS);
+  ret=config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
 
   if (ret != 0) {
     LOG_E(ENB_APP, "%i unknown options in command line (invalid section name)\n",ret);
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index 1cd0b24f81..38937226e5 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -1010,7 +1010,7 @@ int main( int argc, char **argv ) {
   }
 
 #endif
-  ret=config_check_cmdlineopt(CONFIG_CHECKALLSECTIONS);
+  ret=config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
 
   if (ret != 0) {
     LOG_E(ENB_APP, "%i unknown options in command line (invalid section name)\n",ret);
-- 
2.26.2