Module: sip-router Branch: master Commit: ca88d95652abd911f7b8d2525c43b560eb571608 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ca88d956...
Author: Miklos Tirpak miklos@iptel.org Committer: Miklos Tirpak miklos@iptel.org Date: Tue Jan 4 15:47:14 2011 +0100
cfg framework: cfg_set_* works with dynamic group even before forking
Added support for the cfg_set_* functions for dynamic groups (i.e. variables declared from the script) before forking.
---
cfg/cfg_ctx.c | 26 ++++++++++++----- cfg/cfg_ctx.h | 6 +++- cfg/cfg_script.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ cfg/cfg_script.h | 9 ++++++ 4 files changed, 111 insertions(+), 9 deletions(-)
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c index 5fe2dc6..53d881a 100644 --- a/cfg/cfg_ctx.c +++ b/cfg/cfg_ctx.c @@ -30,6 +30,7 @@
#include "../ut.h" #include "cfg_struct.h" +#include "cfg_script.h" #include "cfg_ctx.h"
@@ -231,13 +232,13 @@ error: return -1; }
-#define convert_val_cleanup() \ - do { \ - if (temp_string) { \ - pkg_free(temp_string); \ - temp_string = NULL; \ - } \ - } while(0) +void convert_val_cleanup(void) +{ + if (temp_string) { + pkg_free(temp_string); + temp_string = NULL; + } +}
/* returns the size of the variable */ static int cfg_var_size(cfg_mapping_t *var) @@ -339,8 +340,17 @@ int cfg_set_now(cfg_ctx_t *ctx, str *group_name, unsigned int *group_id, str *va }
/* look-up the group and the variable */ - if (cfg_lookup_var(group_name, var_name, &group, &var)) + if (cfg_lookup_var(group_name, var_name, &group, &var)) { + if (!cfg_shmized) { + /* The group may be dynamic which is not yet ready + * before forking */ + if ((group = cfg_lookup_group(group_name->s, group_name->len)) + && (group->dynamic == CFG_GROUP_DYNAMIC) + ) + return cfg_set_script_var(group, var_name, val, val_type); + } return 1; + } /* check whether the variable is read-only */ if (var->def->type & CFG_READONLY) { diff --git a/cfg/cfg_ctx.h b/cfg/cfg_ctx.h index 481c7ff..359f590 100644 --- a/cfg/cfg_ctx.h +++ b/cfg/cfg_ctx.h @@ -122,10 +122,14 @@ int cfg_help(cfg_ctx_t *ctx, str *group_name, str *var_name, /*! \brief notify the drivers about the new config definition */ void cfg_notify_drivers(char *group_name, int group_name_len, cfg_def_t *def);
-/*! \brief convert the value to the requested type */ +/*! \brief convert the value to the requested type. + * Do not forget the call convert_val_cleaup afterwards. */ int convert_val(unsigned int val_type, void *val, unsigned int var_type, void **new_val);
+/*! \brief cleanup function for convert_val() */ +void convert_val_cleanup(void); + /*! \brief initialize the handle for cfg_get_group_next() */ #define cfg_get_group_init(handle) \ (*(handle)) = (void *)cfg_group diff --git a/cfg/cfg_script.c b/cfg/cfg_script.c index 58b6cd9..5106dd9 100644 --- a/cfg/cfg_script.c +++ b/cfg/cfg_script.c @@ -31,6 +31,7 @@ #include "../ut.h" #include "cfg_struct.h" #include "cfg.h" +#include "cfg_ctx.h" #include "cfg_script.h"
/* allocates memory for a new config script variable @@ -145,6 +146,84 @@ error: return NULL; }
+/* Rewrite the value of an already declared script variable before forking. + * Return value: + * 0: success + * -1: error + * 1: variable not found + */ +int cfg_set_script_var(cfg_group_t *group, str *var_name, + void *val, unsigned int val_type) +{ + cfg_script_var_t *var; + void *v; + str s; + + if (cfg_shmized || (group->dynamic != CFG_GROUP_DYNAMIC)) { + LOG(L_ERR, "BUG: cfg_set_script_var(): Not a dynamic group before forking\n"); + return -1; + } + + for ( var = (cfg_script_var_t *)(void *)group->vars; + var; + var = var->next + ) { + if ((var->name_len == var_name->len) + && (memcmp(var->name, var_name->s, var_name->len) == 0) + ) { + switch (var->type) { + case CFG_VAR_INT: + if (convert_val(val_type, val, CFG_INPUT_INT, &v)) + goto error; + if ((var->min || var->max) + && ((var->min > (int)(long)v) || (var->max < (int)(long)v)) + ) { + LOG(L_ERR, "ERROR: cfg_set_script_var(): integer value is out of range\n"); + goto error; + } + var->val.i = (int)(long)v; + break; + + case CFG_VAR_STR: + if (convert_val(val_type, val, CFG_INPUT_STR, &v)) + goto error; + if (((str *)v)->s) { + s.len = ((str *)v)->len; + s.s = pkg_malloc(sizeof(char) * (s.len + 1)); + if (!s.s) { + LOG(L_ERR, "ERROR: cfg_set_script_var(): not enough memory\n"); + goto error; + } + memcpy(s.s, ((str *)v)->s, s.len); + s.s[s.len] = '\0'; + } else { + s.s = NULL; + s.len = 0; + } + if (var->val.s.s) + pkg_free(var->val.s.s); + var->val.s = s; + break; + + default: + LOG(L_ERR, "ERROR: cfg_set_script_var(): unsupported variable type\n"); + goto error; + } + + convert_val_cleanup(); + return 0; + } + } + + return 1; + +error: + LOG(L_ERR, "ERROR: cfg_set_script_var(): failed to set the script variable: %.*s.%.*s\n", + group->name_len, group->name, + var_name->len, var_name->s); + return -1; +} + /* fix-up the dynamically declared group: * - allocate memory for the arrays * - set the values within the memory block diff --git a/cfg/cfg_script.h b/cfg/cfg_script.h index 1c22bdb..8f4aeaa 100644 --- a/cfg/cfg_script.h +++ b/cfg/cfg_script.h @@ -53,6 +53,15 @@ typedef struct _cfg_script_var { cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type, char *descr);
+/* Rewrite the value of an already declared script variable before forking. + * Return value: + * 0: success + * -1: error + * 1: variable not found + */ +int cfg_set_script_var(cfg_group_t *group, str *var_name, + void *val, unsigned int val_type); + /* fix-up the dynamically declared group */ int cfg_script_fixup(cfg_group_t *group, unsigned char *block);