[sr-dev] git:master: cfg framework: cfg_set_* works with dynamic group even before forking

Miklos Tirpak miklos at iptel.org
Wed Jan 5 15:13:58 CET 2011


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 <miklos at iptel.org>
Committer: Miklos Tirpak <miklos at 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);
 




More information about the sr-dev mailing list