Module: sip-router
Branch: master
Commit: ca88d95652abd911f7b8d2525c43b560eb571608
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ca88d95…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)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);