Module: sip-router
Branch: master
Commit: ca88d95652abd911f7b8d2525c43b560eb571608
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ca88d95652abd911f7b8d2525c43b560eb571608

Author: Miklos Tirpak <[email protected]>
Committer: Miklos Tirpak <[email protected]>
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);
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to