Ver Fonte

core: new core directive modparamx(mod, param, val)

- alternative to modparam() where all its parameters are evaluated for
config script variables
- note that only variables that do not depend on SIP message processing
should be used at this stage
- example - set a module parameter using the value of an evironment
variable:
  modparamx("dispatcher", "db_url", "$env(DBURL)")
Daniel-Constantin Mierla há 4 anos atrás
pai
commit
dd717b80be
5 ficheiros alterados com 131 adições e 2 exclusões
  1. 2 0
      src/core/cfg.lex
  2. 29 0
      src/core/cfg.y
  3. 96 0
      src/core/modparam.c
  4. 3 2
      src/core/modparam.h
  5. 1 0
      src/core/sr_module.h

+ 2 - 0
src/core/cfg.lex

@@ -490,6 +490,7 @@ CFG_DESCRIPTION		"description"|"descr"|"desc"
 LOADMODULE	loadmodule
 LOADPATH	"loadpath"|"mpath"
 MODPARAM        modparam
+MODPARAMX        modparamx
 
 CFGENGINE	"cfgengine"
 
@@ -1003,6 +1004,7 @@ IMPORTFILE      "import_file"
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
 <INITIAL>{LOADPATH}		{ count(); yylval.strval=yytext; return LOADPATH; }
 <INITIAL>{MODPARAM}     { count(); yylval.strval=yytext; return MODPARAM; }
+<INITIAL>{MODPARAMX}     { count(); yylval.strval=yytext; return MODPARAMX; }
 <INITIAL>{CFGENGINE}	{ count(); yylval.strval=yytext; return CFGENGINE; }
 <INITIAL>{URI_HOST_EXTRA_CHARS}	{ yylval.strval=yytext; return URI_HOST_EXTRA_CHARS; }
 <INITIAL>{HDR_NAME_EXTRA_CHARS}	{ yylval.strval=yytext; return HDR_NAME_EXTRA_CHARS; }

+ 29 - 0
src/core/cfg.y

@@ -403,6 +403,7 @@ extern char *default_routename;
 %token LOADMODULE
 %token LOADPATH
 %token MODPARAM
+%token MODPARAMX
 %token CFGENGINE
 %token MAXBUFFER
 %token SQL_BUFFER_SIZE
@@ -1890,6 +1891,34 @@ module_stm:
 		}
 	}
 	| MODPARAM error { yyerror("Invalid arguments"); }
+	| MODPARAMX LPAREN STRING COMMA STRING COMMA STRING RPAREN {
+		if (!shm_initialized() && init_shm()<0) {
+			yyerror("Can't initialize shared memory");
+			YYABORT;
+		}
+		if (modparamx_set($3, $5, PARAM_STRING, $7) != 0) {
+			 yyerror("Can't set module parameter");
+		}
+	}
+	| MODPARAMX LPAREN STRING COMMA STRING COMMA intno RPAREN {
+		if (!shm_initialized() && init_shm()<0) {
+			yyerror("Can't initialize shared memory");
+			YYABORT;
+		}
+		if (modparamx_set($3, $5, PARAM_INT, (void*)$7) != 0) {
+			 yyerror("Can't set module parameter");
+		}
+	}
+	| MODPARAMX LPAREN STRING COMMA STRING COMMA PVAR RPAREN {
+		if (!shm_initialized() && init_shm()<0) {
+			yyerror("Can't initialize shared memory");
+			YYABORT;
+		}
+		if (modparamx_set($3, $5, PARAM_VAR, (void*)$7) != 0) {
+			 yyerror("Can't set module parameter");
+		}
+	}
+	| MODPARAMX error { yyerror("Invalid arguments"); }
 	| CFGENGINE STRING {
 		if(sr_kemi_eng_setz($2, NULL)) {
 			yyerror("Can't set config routing engine");

+ 96 - 0
src/core/modparam.c

@@ -29,6 +29,8 @@
 
 #include "modparam.h"
 #include "dprint.h"
+#include "fmsg.h"
+#include "pvar.h"
 #include "mem/mem.h"
 #include <sys/types.h>
 #include <regex.h>
@@ -179,6 +181,100 @@ int set_mod_param_regex(char* regex, char* name, modparam_t type, void* val)
 	return 0;
 }
 
+int modparamx_set(char* mname, char* pname, modparam_t ptype, void* pval)
+{
+	str seval;
+	str sfmt;
+	sip_msg_t *fmsg;
+	char* emname;
+	char* epname;
+	pv_spec_t *pvs;
+	pv_value_t pvv;
+
+	emname = mname;
+	if(strchr(mname, '$') != NULL) {
+		fmsg = faked_msg_get_next();
+		sfmt.s = mname;
+		sfmt.len = strlen(sfmt.s);
+		if(pv_eval_str(fmsg, &seval, &sfmt)>=0) {
+			emname = seval.s;
+		}
+	}
+
+	epname = pname;
+	if(strchr(pname, '$') != NULL) {
+		fmsg = faked_msg_get_next();
+		sfmt.s = pname;
+		sfmt.len = strlen(sfmt.s);
+		if(pv_eval_str(fmsg, &seval, &sfmt)>=0) {
+			epname = seval.s;
+		}
+	}
+
+	switch(ptype) {
+		case PARAM_STRING:
+			if(strchr((char*)pval, '$') != NULL) {
+				fmsg = faked_msg_get_next();
+				sfmt.s = (char*)pval;
+				sfmt.len = strlen(sfmt.s);
+				if(pv_eval_str(fmsg, &seval, &sfmt)>=0) {
+					return set_mod_param_regex(emname, epname, PARAM_STRING,
+							(void*)seval.s);
+				} else {
+					LM_ERR("failed to evaluate parameter [%s]\n", (char*)pval);
+					return -1;
+				}
+			} else {
+				return set_mod_param_regex(emname, epname, PARAM_STRING, pval);
+			}
+		case PARAM_INT:
+			return set_mod_param_regex(emname, epname, PARAM_INT, pval);
+		case PARAM_VAR:
+			sfmt.s = (char*)pval;
+			sfmt.len = strlen(sfmt.s);
+			seval.len = pv_locate_name(&sfmt);
+			if(seval.len != sfmt.len) {
+				LM_ERR("invalid pv [%.*s] (%d/%d)\n", sfmt.len, sfmt.s,
+						seval.len, sfmt.len);
+				return -1;
+			}
+			pvs = pv_cache_get(&sfmt);
+			if(pvs==NULL) {
+				LM_ERR("cannot get pv spec for [%.*s]\n", sfmt.len, sfmt.s);
+				return -1;
+			}
+
+			fmsg = faked_msg_get_next();
+			memset(&pvv, 0, sizeof(pv_value_t));
+			if(pv_get_spec_value(fmsg, pvs, &pvv) != 0) {
+				LM_ERR("unable to get pv value for [%.*s]\n", sfmt.len, sfmt.s);
+				return -1;
+			}
+			if(pvv.flags&PV_VAL_NULL) {
+				LM_ERR("unable to get pv value for [%.*s]\n", sfmt.len, sfmt.s);
+				return -1;
+			}
+			if(pvv.flags&PV_TYPE_INT) {
+				return set_mod_param_regex(emname, epname, PARAM_INT,
+						(void*)(long)pvv.ri);
+			}
+			if(pvv.rs.len<0) {
+				LM_ERR("invalid pv string value for [%.*s]\n", sfmt.len, sfmt.s);
+				return -1;
+			}
+			if(pvv.rs.s[pvv.rs.len] != '\0') {
+				LM_ERR("non 0-terminated pv string value for [%.*s]\n",
+						sfmt.len, sfmt.s);
+				return -1;
+			}
+			return set_mod_param_regex(emname, epname, PARAM_STRING,
+							(void*)pvv.rs.s);
+		default:
+			LM_ERR("invalid parameter type: %d\n", ptype);
+			return -1;
+	}
+}
+
 int set_mod_param_serialized(char* mval)
 {
 #define MPARAM_MBUF_SIZE 256

+ 3 - 2
src/core/modparam.h

@@ -13,8 +13,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 /*!
@@ -33,6 +33,7 @@
 int set_mod_param(char* _mod, char* _name, modparam_t _type, void* _val);
 
 int set_mod_param_regex(char* regex, char* name, modparam_t type, void* val);
+int modparamx_set(char* regex, char* name, modparam_t type, void* val);
 
 int set_mod_param_serialized(char* mval);
 

+ 1 - 0
src/core/sr_module.h

@@ -109,6 +109,7 @@ typedef int (*child_init_function)(int rank);
 #define PARAM_STRING     (1U<<0)  /**< String (char *) parameter type */
 #define PARAM_INT        (1U<<1)  /**< Integer parameter type */
 #define PARAM_STR        (1U<<2)  /**< struct str parameter type */
+#define PARAM_VAR        (1U<<3)  /**< var parameter type - mdoparamx */
 #define PARAM_USE_FUNC   (1U<<(8*sizeof(int)-1))
 #define PARAM_TYPE_MASK(_x)   ((_x)&(~PARAM_USE_FUNC))