LCOV - code coverage report
Current view: top level - ini - ini_get_valueobj.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 204 243 84.0 %
Date: 2014-04-01 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /*
       2             :     INI LIBRARY
       3             : 
       4             :     Value interpretation functions for single values
       5             :     and corresponding memory cleanup functions.
       6             : 
       7             :     Copyright (C) Dmitri Pal <dpal@redhat.com> 2012
       8             : 
       9             :     INI Library is free software: you can redistribute it and/or modify
      10             :     it under the terms of the GNU Lesser General Public License as published by
      11             :     the Free Software Foundation, either version 3 of the License, or
      12             :     (at your option) any later version.
      13             : 
      14             :     INI Library is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :     GNU Lesser General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU Lesser General Public License
      20             :     along with INI Library.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "config.h"
      24             : #include <stdio.h>
      25             : #include <errno.h>
      26             : #include <string.h>
      27             : #include <stdlib.h>
      28             : #include <ctype.h>
      29             : #include "trace.h"
      30             : #include "collection.h"
      31             : #include "collection_tools.h"
      32             : #include "ini_defines.h"
      33             : #include "ini_config_priv.h"
      34             : #include "ini_configobj.h"
      35             : #include "ini_valueobj.h"
      36             : 
      37             : /* Macro co convert to HEX value */
      38             : #define HEXVAL(c) (isdigit(c) ? (c - '0') : (tolower(c) - 'a') + 10)
      39             : 
      40          59 : static int is_same_section(struct ini_cfgobj *ini_config,
      41             :                            const char *section)
      42             : {
      43          59 :     int len = 0;
      44             : 
      45             :     TRACE_FLOW_ENTRY();
      46             : 
      47             :     /* If section is not defined it is different */
      48          59 :     if (ini_config->section == NULL) {
      49             :         TRACE_FLOW_RETURN(0);
      50             :         return 0;
      51             :     }
      52             : 
      53          23 :     len = strlen(section);
      54             : 
      55             :     /* If values are same this is the same section */
      56          23 :     if ((strncasecmp(ini_config->section, section, ini_config->section_len) == 0) &&
      57             :         (ini_config->section_len == len)) {
      58             :         TRACE_FLOW_RETURN(1);
      59             :         return 1;
      60             :     }
      61             : 
      62             :     /* Otherwise the values are different */
      63             :     TRACE_FLOW_RETURN(0);
      64             :     return 0;
      65             : }
      66             : 
      67         111 : static int is_same_name(struct ini_cfgobj *ini_config,
      68             :                         const char *name,
      69             :                         int name_len)
      70             : {
      71             :     TRACE_FLOW_ENTRY();
      72             : 
      73             :     /* If name is not defined it is different */
      74         111 :     if (ini_config->name == NULL) {
      75             :         TRACE_FLOW_RETURN(0);
      76             :         return 0;
      77             :     }
      78             : 
      79             :     /* If values are same this is the same value */
      80          35 :     if ((strncasecmp(ini_config->name, name, ini_config->name_len) == 0) &&
      81             :         (ini_config->name_len == name_len)) {
      82             :         TRACE_FLOW_RETURN(1);
      83             :         return 1;
      84             :     }
      85             : 
      86             :     /* Otherwise the values are different */
      87             :     TRACE_FLOW_RETURN(0);
      88             :     return 0;
      89             : }
      90             : 
      91             : 
      92             : /* Function to get value object from the configuration handle */
      93          59 : int ini_get_config_valueobj(const char *section,
      94             :                             const char *name,
      95         170 :                             struct ini_cfgobj *ini_config,
      96             :                             int mode,
      97             :                             struct value_obj **vo)
      98             : {
      99          59 :     int error = EOK;
     100          59 :     struct collection_item *section_handle = NULL;
     101          59 :     struct collection_item *item = NULL;
     102          59 :     struct collection_item *last_found = NULL;
     103             :     const char *to_find;
     104          59 :     char default_section[] = INI_DEFAULT_SECTION;
     105          59 :     uint64_t hash = 0;
     106          59 :     int len = 0, name_len = 0;
     107             : 
     108             :     TRACE_FLOW_ENTRY();
     109             : 
     110             :     /* Do we have the accepting memory ? */
     111          59 :     if (vo == NULL) {
     112             :         TRACE_ERROR_NUMBER("Invalid argument vo.", EINVAL);
     113             :         return EINVAL;
     114             :     }
     115             : 
     116          59 :     *vo = NULL;
     117             : 
     118          59 :     if (ini_config == NULL) {
     119             :         TRACE_ERROR_NUMBER("Invalid argument ini_config.", EINVAL);
     120             :         return EINVAL;
     121             :     }
     122             : 
     123          59 :     if ((mode < INI_GET_FIRST_VALUE) ||
     124             :         (mode > INI_GET_LAST_VALUE)) {
     125             :         TRACE_ERROR_NUMBER("Invalid argument mode:", mode);
     126             :         return EINVAL;
     127             :     }
     128             : 
     129             :     /* Do we have a name ? */
     130          59 :     if (name == NULL) {
     131             :         TRACE_ERROR_NUMBER("Name is NULL it will not be found.", EINVAL);
     132             :         return EINVAL;
     133             :     }
     134             : 
     135             :     /* Empty section means look for the default one */
     136          59 :     if (section == NULL) to_find = default_section;
     137          59 :     else to_find = section;
     138             : 
     139             :     TRACE_INFO_STRING("Getting Name:", name);
     140             :     TRACE_INFO_STRING("In Section:", to_find);
     141             : 
     142             :     /* Make sure we start over if this is the first value */
     143          59 :     if (mode == INI_GET_FIRST_VALUE) ini_config_clean_state(ini_config);
     144             : 
     145             :     /* Are we looking in the same section ? */
     146          59 :     if (!is_same_section(ini_config, to_find)) {
     147             : 
     148             :         /* This is a different section */
     149          38 :         ini_config_clean_state(ini_config);
     150             : 
     151             :         /* Get Subcollection */
     152          38 :         error = col_get_collection_reference(ini_config->cfg, &section_handle, to_find);
     153             :         /* Check error */
     154          38 :         if (error && (error != ENOENT)) {
     155             :             TRACE_ERROR_NUMBER("Failed to get section", error);
     156             :             return error;
     157             :         }
     158             : 
     159             :         /* Did we find a section */
     160          38 :         if ((error == ENOENT) || (section_handle == NULL)) {
     161             :             /* We have not found section - return success */
     162             :                 TRACE_FLOW_EXIT();
     163             :             return EOK;
     164             :         }
     165             : 
     166             :         /* Create an iterator */
     167          37 :         error = col_bind_iterator(&(ini_config->iterator),
     168             :                                   section_handle,
     169             :                                   COL_TRAVERSE_ONELEVEL);
     170             :         /* Make sure we free the section we found */
     171          37 :         col_destroy_collection(section_handle);
     172             :         /* Check error */
     173          37 :         if (error) {
     174             :             TRACE_ERROR_NUMBER("Failed to bind to section", error);
     175             :             return error;
     176             :         }
     177             : 
     178             :         /* Save section */
     179          37 :         ini_config->section_len = strlen(to_find);
     180          37 :         ini_config->section = strndup(to_find, ini_config->section_len);
     181             :         /* Check error */
     182          37 :         if (ini_config->section == NULL) {
     183             :             TRACE_ERROR_NUMBER("Failed to save section name ", ENOMEM);
     184           0 :             ini_config_clean_state(ini_config);
     185           0 :             return ENOMEM;
     186             :         }
     187             :     }
     188             : 
     189          58 :     hash = col_make_hash(name, 0, &name_len);
     190             : 
     191             :     /* Check if this is the same name */
     192         116 :     if (!is_same_name(ini_config, name, name_len)) {
     193             :         TRACE_INFO_STRING("Saved name:", ini_config->name);
     194             :         TRACE_INFO_STRING("Passed name:", name);
     195             :         TRACE_INFO_NUMBER("Length of the saved name", ini_config->name_len);
     196             :         TRACE_INFO_NUMBER("Length of the passed name", name_len);
     197          40 :         col_rewind_iterator(ini_config->iterator);
     198          40 :         free(ini_config->name);
     199          40 :         ini_config->name = NULL;
     200          40 :         ini_config->name_len = 0;
     201             :     }
     202             : 
     203             :     /* Iterate through the section */
     204             :     do {
     205             : 
     206             :         /* Loop through a collection */
     207         382 :         error = col_iterate_collection(ini_config->iterator, &item);
     208         382 :         if (error) {
     209             :             TRACE_ERROR_NUMBER("Failed to iterate", error);
     210           0 :             ini_config_clean_state(ini_config);
     211           0 :             return error;
     212             :         }
     213             : 
     214             :         /* Are we done ? */
     215         382 :         if (item == NULL) {
     216             :             /* We looped to the end and found last value */
     217           6 :             if ((mode == INI_GET_LAST_VALUE) && (last_found)) {
     218           1 :                 item = last_found;
     219           1 :                 break;
     220             :             }
     221             :             /* There is nothing left to look for */
     222           5 :             ini_config_clean_state(ini_config);
     223             :             TRACE_FLOW_EXIT();
     224           5 :             return EOK;
     225             :         }
     226             : 
     227         432 :         if ((hash == col_get_item_hash(item)) &&
     228         112 :             (strncasecmp(col_get_item_property(item, &len), name, name_len) == 0) &&
     229          56 :             (len == name_len)) {
     230             :                 TRACE_INFO_STRING("Item is found", name);
     231          56 :                 last_found = item;
     232          56 :                 if (mode == INI_GET_LAST_VALUE) continue;
     233             :                 break;
     234             :         }
     235             :     }
     236             :     while(1);
     237             : 
     238         106 :     if (!is_same_name(ini_config, name, name_len)) {
     239             :         /* Save name */
     240          39 :         ini_config->name_len = name_len;
     241          39 :         ini_config->name = strndup(name, name_len);
     242             :         /* Check error */
     243          39 :         if (ini_config->name == NULL) {
     244             :             TRACE_ERROR_NUMBER("Failed to save key name ", ENOMEM);
     245           0 :             ini_config_clean_state(ini_config);
     246           0 :             return ENOMEM;
     247             :         }
     248             :     }
     249             : 
     250          53 :     *vo = *((struct value_obj **)(col_get_item_data(item)));
     251             : 
     252             :     TRACE_FLOW_EXIT();
     253          53 :     return error;
     254             : }
     255             : 
     256             : /* Get long long value from config value object */
     257           6 : static long long ini_get_llong_config_value(struct value_obj *vo,
     258             :                                             int strict,
     259             :                                             long long def,
     260             :                                             int *error)
     261             : {
     262             :     int err;
     263             :     const char *str;
     264             :     char *endptr;
     265           6 :     long long val = 0;
     266             : 
     267             :     TRACE_FLOW_ENTRY();
     268             : 
     269             :     /* Do we have the vo ? */
     270           6 :     if (vo == NULL) {
     271             :         TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
     272           0 :         if (error) *error = EINVAL;
     273           0 :         return def;
     274             :     }
     275             : 
     276           6 :     if (error) *error = EOK;
     277             : 
     278             :     /* Get value - no error checking as we checked it above
     279             :      * and there is no other reson the function could fail.
     280             :      */
     281           6 :     value_get_concatenated(vo, &str);
     282             : 
     283             :     /* Try to parse the value */
     284           6 :     errno = 0;
     285           6 :     val = strtoll(str, &endptr, 10);
     286           6 :     err = errno;
     287             : 
     288             :     /* Check for various possible errors */
     289           6 :     if (err != 0) {
     290             :         TRACE_ERROR_NUMBER("Conversion failed", err);
     291           0 :         if (error) *error = err;
     292           0 :         return def;
     293             :     }
     294             : 
     295             :     /* Other error cases */
     296           6 :     if ((endptr == str) || (strict && (*endptr != '\0'))) {
     297             :         TRACE_ERROR_NUMBER("More characters or nothing processed", EIO);
     298           1 :         if (error) *error = EIO;
     299           1 :         return def;
     300             :     }
     301             : 
     302             :     TRACE_FLOW_NUMBER("ini_get_llong_config_value returning", (long)val);
     303             :     return val;
     304             : }
     305             : 
     306             : /* Get unsigned long long value from config value object */
     307           4 : static unsigned long long ini_get_ullong_config_value(struct value_obj *vo,
     308             :                                                       int strict,
     309             :                                                       unsigned long long def,
     310             :                                                       int *error)
     311             : {
     312             :     int err;
     313             :     const char *str;
     314             :     char *endptr;
     315           4 :     unsigned long long val = 0;
     316             : 
     317             :     TRACE_FLOW_ENTRY();
     318             : 
     319             :     /* Do we have the vo ? */
     320           4 :     if (vo == NULL) {
     321             :         TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
     322           0 :         if (error) *error = EINVAL;
     323           0 :         return def;
     324             :     }
     325             : 
     326           4 :     if (error) *error = EOK;
     327             : 
     328             :     /* Get value - no error checking as we checked it above
     329             :      * and there is no other reson the function could fail.
     330             :      */
     331           4 :     value_get_concatenated(vo, &str);
     332             : 
     333           4 :     errno = 0;
     334           4 :     val = strtoull(str, &endptr, 10);
     335           4 :     err = errno;
     336             : 
     337             :     /* Check for various possible errors */
     338           4 :     if (err != 0) {
     339             :         TRACE_ERROR_NUMBER("Conversion failed", err);
     340           0 :         if (error) *error = err;
     341           0 :         return def;
     342             :     }
     343             : 
     344             :     /* Other error cases */
     345           4 :     if ((endptr == str) || (strict && (*endptr != '\0'))) {
     346             :         TRACE_ERROR_NUMBER("More characters or nothing processed", EIO);
     347           0 :         if (error) *error = EIO;
     348           0 :         return def;
     349             :     }
     350             : 
     351             :     TRACE_FLOW_NUMBER("ini_get_ullong_config_value returning", val);
     352             :     return val;
     353             : }
     354             : 
     355             : 
     356             : /* Get integer value from config value */
     357           3 : int ini_get_int_config_value(struct value_obj *vo,
     358             :                              int strict,
     359             :                              int def,
     360             :                              int *error)
     361             : {
     362           3 :     long long val = 0;
     363           3 :     int err = 0;
     364             : 
     365             :     TRACE_FLOW_ENTRY();
     366             : 
     367           3 :     val = ini_get_llong_config_value(vo, strict, def, &err);
     368           3 :     if (err == 0) {
     369           2 :         if ((val > INT_MAX) || (val < INT_MIN)) {
     370             :             TRACE_ERROR_NUMBER("Value is out of range", ERANGE);
     371           0 :             val = def;
     372           0 :             err = ERANGE;
     373             :         }
     374             :     }
     375             : 
     376           3 :     if (error) *error = err;
     377             : 
     378             :     TRACE_FLOW_NUMBER("ini_get_int_config_value returning", (int)val);
     379           3 :     return (int)val;
     380             : }
     381             : 
     382             : /* Get unsigned integer value from config value object */
     383           1 : unsigned ini_get_unsigned_config_value(struct value_obj *vo,
     384             :                                        int strict,
     385             :                                        unsigned def,
     386             :                                        int *error)
     387             : {
     388           1 :     unsigned long long val = 0;
     389           1 :     int err = 0;
     390             : 
     391             :     TRACE_FLOW_ENTRY();
     392             : 
     393           1 :     val = ini_get_ullong_config_value(vo, strict, def, &err);
     394           1 :     if (err == 0) {
     395           1 :         if (val > UINT_MAX) {
     396             :             TRACE_ERROR_NUMBER("Value is out of range", ERANGE);
     397           0 :             val = def;
     398           0 :             err = ERANGE;
     399             :         }
     400             :     }
     401             : 
     402           1 :     if (error) *error = err;
     403             : 
     404             :     TRACE_FLOW_NUMBER("ini_get_unsigned_config_value returning",
     405             :                       (unsigned)val);
     406           1 :     return (unsigned)val;
     407             : }
     408             : 
     409             : /* Get long value from config value object */
     410           1 : long ini_get_long_config_value(struct value_obj *vo,
     411             :                                int strict,
     412             :                                long def,
     413             :                                int *error)
     414             : {
     415           1 :     long long val = 0;
     416           1 :     int err = 0;
     417             : 
     418             :     TRACE_FLOW_ENTRY();
     419             : 
     420           1 :     val = ini_get_llong_config_value(vo, strict, def, &err);
     421             :     if (err == 0) {
     422             :         if ((val > LONG_MAX) || (val < LONG_MIN)) {
     423             :             TRACE_ERROR_NUMBER("Value is out of range", ERANGE);
     424             :             val = def;
     425             :             err = ERANGE;
     426             :         }
     427             :     }
     428             : 
     429           1 :     if (error) *error = err;
     430             : 
     431             :     TRACE_FLOW_NUMBER("ini_get_long_config_value returning",
     432             :                       (long)val);
     433           1 :     return (long)val;
     434             : }
     435             : 
     436             : /* Get unsigned long value from config value object */
     437           1 : unsigned long ini_get_ulong_config_value(struct value_obj *vo,
     438             :                                          int strict,
     439             :                                          unsigned long def,
     440             :                                          int *error)
     441             : {
     442           1 :     unsigned long long val = 0;
     443           1 :     int err = 0;
     444             : 
     445             :     TRACE_FLOW_ENTRY();
     446             : 
     447           1 :     val = ini_get_ullong_config_value(vo, strict, def, &err);
     448             :     if (err == 0) {
     449             :         if (val > ULONG_MAX) {
     450             :             TRACE_ERROR_NUMBER("Value is out of range", ERANGE);
     451             :             val = def;
     452             :             err = ERANGE;
     453             :         }
     454             :     }
     455             : 
     456           1 :     if (error) *error = err;
     457             : 
     458             :     TRACE_FLOW_NUMBER("ini_get_ulong_config_value returning",
     459             :                       (unsigned long)val);
     460           1 :     return (unsigned long)val;
     461             : }
     462             : 
     463             : /* Get int32_t value from config value object */
     464           1 : int32_t ini_get_int32_config_value(struct value_obj *vo,
     465             :                                    int strict,
     466             :                                    int32_t def,
     467             :                                    int *error)
     468             : {
     469           1 :     long long val = 0;
     470           1 :     int err = 0;
     471             : 
     472             :     TRACE_FLOW_ENTRY();
     473             : 
     474           1 :     val = ini_get_llong_config_value(vo, strict, def, &err);
     475           1 :     if (err == 0) {
     476           1 :         if ((val > INT32_MAX) || (val < INT32_MIN)) {
     477             :             TRACE_ERROR_NUMBER("Value is out of range", ERANGE);
     478           0 :             val = def;
     479           0 :             err = ERANGE;
     480             :         }
     481             :     }
     482             : 
     483           1 :     if (error) *error = err;
     484             : 
     485             :     TRACE_FLOW_NUMBER("ini_get_int32_config_value returning",
     486             :                       (int32_t)val);
     487           1 :     return (int32_t)val;
     488             : }
     489             : 
     490             : /* Get uint32_t value from config value object */
     491           1 : uint32_t ini_get_uint32_config_value(struct value_obj *vo,
     492             :                                      int strict,
     493             :                                      uint32_t def,
     494             :                                      int *error)
     495             : {
     496           1 :     unsigned long long val = 0;
     497           1 :     int err = 0;
     498             : 
     499             :     TRACE_FLOW_ENTRY();
     500             : 
     501           1 :     val = ini_get_ullong_config_value(vo, strict, def, &err);
     502           1 :     if (err == 0) {
     503           1 :         if (val > UINT32_MAX) {
     504             :             TRACE_ERROR_NUMBER("Value is out of range", ERANGE);
     505           0 :             val = def;
     506           0 :             err = ERANGE;
     507             :         }
     508             :     }
     509             : 
     510           1 :     if (error) *error = err;
     511             : 
     512             :     TRACE_FLOW_NUMBER("ini_get_uint32_config_value returning",
     513             :                       (uint32_t)val);
     514           1 :     return (uint32_t)val;
     515             : }
     516             : 
     517             : /* Get int64_t value from config value ovject */
     518           1 : int64_t ini_get_int64_config_value(struct value_obj *vo,
     519             :                                    int strict,
     520             :                                    int64_t def,
     521             :                                    int *error)
     522             : {
     523           1 :     long long val = 0;
     524           1 :     int err = 0;
     525             : 
     526             :     TRACE_FLOW_ENTRY();
     527             : 
     528           1 :     val = ini_get_llong_config_value(vo, strict, def, &err);
     529             :     if (err == 0) {
     530             :         if ((val > INT64_MAX) || (val < INT64_MIN)) {
     531             :             TRACE_ERROR_NUMBER("Value is out of range", ERANGE);
     532             :             val = def;
     533             :             err = ERANGE;
     534             :         }
     535             :     }
     536             : 
     537           1 :     if (error) *error = err;
     538             : 
     539             :     TRACE_FLOW_NUMBER("ini_get_int64_config_value returning",
     540             :                       (int64_t)val);
     541           1 :     return (int64_t)val;
     542             : }
     543             : 
     544             : /* Get uint64_t value from config value object */
     545           1 : uint64_t ini_get_uint64_config_value(struct value_obj *vo,
     546             :                                      int strict,
     547             :                                      uint64_t def,
     548             :                                      int *error)
     549             : {
     550           1 :     unsigned long long val = 0;
     551           1 :     int err = 0;
     552             : 
     553             :     TRACE_FLOW_ENTRY();
     554             : 
     555           1 :     val = ini_get_ullong_config_value(vo, strict, def, &err);
     556             :     if (err == 0) {
     557             :         if (val > UINT64_MAX) {
     558             :             TRACE_ERROR_NUMBER("Value is out of range", ERANGE);
     559             :             val = def;
     560             :             err = ERANGE;
     561             :         }
     562             :     }
     563             : 
     564           1 :     if (error) *error = err;
     565             : 
     566             :     TRACE_FLOW_NUMBER("ini_get_uint64_config_value returning",
     567             :                       (uint64_t)val);
     568           1 :     return (uint64_t)val;
     569             : }
     570             : 
     571             : /* Get double value */
     572           1 : double ini_get_double_config_value(struct value_obj *vo,
     573             :                                    int strict, double def, int *error)
     574             : {
     575             :     const char *str;
     576             :     char *endptr;
     577           1 :     double val = 0;
     578             : 
     579             :     TRACE_FLOW_ENTRY();
     580             : 
     581             :     /* Do we have the vo ? */
     582           1 :     if (vo == NULL) {
     583             :         TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
     584           0 :         if (error) *error = EINVAL;
     585           0 :         return def;
     586             :     }
     587             : 
     588           1 :     if (error) *error = EOK;
     589             : 
     590             :     /* Get value - no error checking as we checked it above
     591             :      * and there is no other reason the function could fail.
     592             :      */
     593           1 :     value_get_concatenated(vo, &str);
     594             : 
     595           1 :     errno = 0;
     596           1 :     val = strtod(str, &endptr);
     597             : 
     598             :     /* Check for various possible errors */
     599           1 :     if ((errno == ERANGE) ||
     600           1 :         ((errno != 0) && (val == 0)) ||
     601           1 :         (endptr == str)) {
     602             :         TRACE_ERROR_NUMBER("Conversion failed", EIO);
     603           0 :         if (error) *error = EIO;
     604           0 :         return def;
     605             :     }
     606             : 
     607           1 :     if (strict && (*endptr != '\0')) {
     608             :         TRACE_ERROR_NUMBER("More characters than expected", EIO);
     609           0 :         if (error) *error = EIO;
     610           0 :         val = def;
     611             :     }
     612             : 
     613             :     TRACE_FLOW_DOUBLE("ini_get_double_config_value returning", val);
     614           1 :     return val;
     615             : }
     616             : 
     617             : /* Get boolean value */
     618           2 : unsigned char ini_get_bool_config_value(struct value_obj *vo,
     619             :                                         unsigned char def, int *error)
     620             : {
     621             :     const char *str;
     622           2 :     uint32_t len = 0;
     623             : 
     624             :     TRACE_FLOW_ENTRY();
     625             : 
     626             :     /* Do we have the vo ? */
     627           2 :     if (vo == NULL) {
     628             :         TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
     629           0 :         if (error) *error = EINVAL;
     630           0 :         return def;
     631             :     }
     632             : 
     633           2 :     if (error) *error = EOK;
     634             : 
     635             :     /* Get value - no error checking as we checked it above
     636             :      * and there is no other reson the function could fail.
     637             :      */
     638           2 :     value_get_concatenated(vo, &str);
     639           2 :     value_get_concatenated_len(vo, &len);
     640             : 
     641             :     /* Try to parse the value */
     642           4 :     if ((strncasecmp(str, "true", len) == 0) ||
     643           2 :         (strncasecmp(str, "yes", len) == 0)) {
     644             :         TRACE_FLOW_STRING("Returning", "true");
     645             :         return '\1';
     646             :     }
     647           3 :     else if ((strncasecmp(str, "false", len) == 0) ||
     648           1 :              (strncasecmp(str, "no", len) == 0)) {
     649             :         TRACE_FLOW_STRING("Returning", "false");
     650             :         return '\0';
     651             :     }
     652             : 
     653             :     TRACE_ERROR_STRING("Returning", "error");
     654           1 :     if (error) *error = EIO;
     655           1 :     return def;
     656             : }
     657             : 
     658             : /* Return a string out of the value */
     659           1 : char *ini_get_string_config_value(struct value_obj *vo,
     660             :                               int *error)
     661             : {
     662           1 :     const char *str = NULL;
     663           1 :     char *ret_str = NULL;
     664             : 
     665             :     TRACE_FLOW_ENTRY();
     666             : 
     667             :     /* Do we have the vo ? */
     668           1 :     if (vo == NULL) {
     669             :         TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
     670           0 :         if (error) *error = EINVAL;
     671             :         return NULL;
     672             :     }
     673             : 
     674             :     /* Get value - no error checking as we checked it above
     675             :      * and there is no other reson the function could fail.
     676             :      */
     677           1 :     value_get_concatenated(vo, &str);
     678             : 
     679           1 :     ret_str = strdup(str);
     680           1 :     if (ret_str == NULL) {
     681             :         TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
     682           0 :         if (error) *error = ENOMEM;
     683             :         return NULL;
     684             :     }
     685             : 
     686           1 :     if (error) *error = EOK;
     687             : 
     688             :     TRACE_FLOW_STRING("ini_get_string_config_value returning", str);
     689           1 :     return ret_str;
     690             : }
     691             : 
     692             : /* Get string from the value object */
     693           3 : const char *ini_get_const_string_config_value(struct value_obj *vo,
     694             :                                               int *error)
     695             : {
     696             :     const char *str;
     697             : 
     698             :     TRACE_FLOW_ENTRY();
     699             : 
     700             :     /* Do we have the vo ? */
     701           3 :     if (vo == NULL) {
     702             :         TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
     703           1 :         if (error) *error = EINVAL;
     704             :         return NULL;
     705             :     }
     706             : 
     707             :     /* Get value - no error checking as we checked it above
     708             :      * and there is no other reson the function could fail.
     709             :      */
     710           2 :     value_get_concatenated(vo, &str);
     711             : 
     712           2 :     if (error) *error = EOK;
     713             : 
     714             :     TRACE_FLOW_STRING("ini_get_const_string_config_value returning", str);
     715           2 :     return str;
     716             : }
     717             : 
     718             : /* A special hex format is assumed.
     719             :  * The string should be taken in single quotes
     720             :  * and consist of hex encoded value two hex digits per byte.
     721             :  * Example: '0A2BFECC'
     722             :  * Case does not matter.
     723             :  */
     724           2 : char *ini_get_bin_config_value(struct value_obj *vo,
     725             :                                int *length, int *error)
     726             : {
     727             :     int i;
     728           2 :     char *value = NULL;
     729             :     const char *buff;
     730           2 :     int size = 0;
     731           2 :     uint32_t len = 0;
     732             :     const char *str;
     733             : 
     734             :     TRACE_FLOW_ENTRY();
     735             : 
     736             :     /* Do we have the vo ? */
     737           2 :     if (vo == NULL) {
     738             :         TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
     739           0 :         if (error) *error = EINVAL;
     740             :         return NULL;
     741             :     }
     742             : 
     743           2 :     if (error) *error = EOK;
     744             : 
     745             :     /* Get value - no error checking as we checked it above
     746             :      * and there is no other reson the function could fail.
     747             :      */
     748           2 :     value_get_concatenated(vo, &str);
     749             : 
     750             :     /* Check the length */
     751           2 :     value_get_concatenated_len(vo, &len);
     752           2 :     if ((len%2) != 0) {
     753             :         TRACE_ERROR_STRING("Invalid length for binary data", "");
     754           0 :         if (error) *error = EINVAL;
     755             :         return NULL;
     756             :     }
     757             : 
     758             :     /* Is the format correct ? */
     759           4 :     if ((*str != '\'') ||
     760           2 :         (str[len -1] != '\'')) {
     761             :         TRACE_ERROR_STRING("String is not escaped","");
     762           0 :         if (error) *error = EIO;
     763             :         return NULL;
     764             :     }
     765             : 
     766             :     /* Check that all the symbols are ok */
     767           2 :     buff = str + 1;
     768           2 :     len -= 2;
     769          14 :     for (i = 0; i < len; i++) {
     770          12 :         if (!isxdigit(buff[i])) {
     771             :             TRACE_ERROR_STRING("Invalid encoding for binary data", buff);
     772           0 :             if (error) *error = EIO;
     773             :             return NULL;
     774             :         }
     775             :     }
     776             : 
     777             :     /* The value is good so we can allocate memory for it */
     778           2 :     value = malloc(len / 2);
     779           2 :     if (value == NULL) {
     780             :         TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
     781           0 :         if (error) *error = ENOMEM;
     782             :         return NULL;
     783             :     }
     784             : 
     785             :     /* Convert the value */
     786           6 :     for (i = 0; i < len; i += 2) {
     787           6 :         value[size] = (char)(16 * HEXVAL(buff[i]) + HEXVAL(buff[i+1]));
     788           6 :         size++;
     789             :     }
     790             : 
     791           2 :     if (error) *error = EOK;
     792           2 :     if (length) *length = size;
     793             :     TRACE_FLOW_STRING("ini_get_bin_config_value", "Exit");
     794           2 :     return value;
     795             : }
     796             : 
     797             : /* Function to free binary configuration value */
     798           2 : void ini_free_bin_config_value(char *value)
     799             : {
     800           2 :     free(value);
     801           2 : }

Generated by: LCOV version 1.10