Browse Source

Merge commit 'origin/andrei/mod_f_params'

* commit 'origin/andrei/mod_f_params':
  script: variable number of params for functions
  mod if: more prototypes and defines
Andrei Pelinescu-Onciul 17 years ago
parent
commit
bc8bd3d7db
7 changed files with 156 additions and 12 deletions
  1. 85 5
      action.c
  2. 34 3
      cfg.y
  3. 5 0
      route.c
  4. 5 0
      route_struct.c
  5. 7 3
      route_struct.h
  6. 2 1
      sr_module.c
  7. 18 0
      sr_module.h

+ 85 - 5
action.c

@@ -46,6 +46,7 @@
  *              (andrei)
  *              (andrei)
  *  2007-06-14  run_actions & do_action need a ctx or handle now, no more 
  *  2007-06-14  run_actions & do_action need a ctx or handle now, no more 
  *               static vars (andrei)
  *               static vars (andrei)
+ *  2008-11-18  support for variable parameter module functions (andrei)
  */
  */
 
 
 
 
@@ -101,6 +102,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 	struct dest_info dst;
 	struct dest_info dst;
 	char* tmp;
 	char* tmp;
 	char *new_uri, *end, *crt;
 	char *new_uri, *end, *crt;
+	void* f;
 	int len;
 	int len;
 	int user;
 	int user;
 	struct sip_uri uri, next_hop;
 	struct sip_uri uri, next_hop;
@@ -717,11 +719,89 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 			break;
 			break;
 		case MODULE_T:
 		case MODULE_T:
 			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
 			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
-					((union cmd_export_u*)a->val[0].u.data)->c.function){
-				ret=((union cmd_export_u*)a->val[0].u.data)->c.function(msg,
-					(char*)a->val[2].u.data,
-					(char*)a->val[3].u.data
-				);
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
+				ret=((cmd_function)f)(msg,
+										(char*)a->val[2].u.data,
+										(char*)a->val[3].u.data
+									);
+				if (ret==0) h->run_flags|=EXIT_R_F;
+				h->last_retcode=ret;
+			} else {
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
+			}
+			break;
+		/* instead of using the parameter number, we use different names
+		 * for calls to functions with 3, 4, 5, 6 or variable number of
+		 * parameters due to performance reasons */
+		case MODULE3_T:
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
+				ret=((cmd_function3)f)(msg,
+										(char*)a->val[2].u.data,
+										(char*)a->val[3].u.data,
+										(char*)a->val[4].u.data
+									);
+				if (ret==0) h->run_flags|=EXIT_R_F;
+				h->last_retcode=ret;
+			} else {
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
+			}
+			break;
+		case MODULE4_T:
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
+				ret=((cmd_function4)f)(msg,
+										(char*)a->val[2].u.data,
+										(char*)a->val[3].u.data,
+										(char*)a->val[4].u.data,
+										(char*)a->val[5].u.data
+									);
+				if (ret==0) h->run_flags|=EXIT_R_F;
+				h->last_retcode=ret;
+			} else {
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
+			}
+			break;
+		case MODULE5_T:
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
+				ret=((cmd_function5)f)(msg,
+										(char*)a->val[2].u.data,
+										(char*)a->val[3].u.data,
+										(char*)a->val[4].u.data,
+										(char*)a->val[5].u.data,
+										(char*)a->val[6].u.data
+									);
+				if (ret==0) h->run_flags|=EXIT_R_F;
+				h->last_retcode=ret;
+			} else {
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
+			}
+			break;
+		case MODULE6_T:
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
+				ret=((cmd_function6)f)(msg,
+										(char*)a->val[2].u.data,
+										(char*)a->val[3].u.data,
+										(char*)a->val[4].u.data,
+										(char*)a->val[5].u.data,
+										(char*)a->val[6].u.data,
+										(char*)a->val[7].u.data
+									);
+				if (ret==0) h->run_flags|=EXIT_R_F;
+				h->last_retcode=ret;
+			} else {
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
+			}
+			break;
+		case MODULEX_T:
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
+				ret=((cmd_function_var)f)(msg,
+											a->val[1].u.number,
+											&a->val[2]
+										);
 				if (ret==0) h->run_flags|=EXIT_R_F;
 				if (ret==0) h->run_flags|=EXIT_R_F;
 				h->last_retcode=ret;
 				h->last_retcode=ret;
 			} else {
 			} else {

+ 34 - 3
cfg.y

@@ -88,6 +88,7 @@
  * 2007-11-28  added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
  * 2007-11-28  added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
  * 2008-01-24  added cfg_var definition (Miklos)
  * 2008-01-24  added cfg_var definition (Miklos)
+ * 2008-11-18  support for variable parameter module functions (andrei)
 */
 */
 
 
 %{
 %{
@@ -2359,7 +2360,8 @@ cmd:
 		$$=0; yyerror("bad argument, [proto:]host[:port] expected");
 		$$=0; yyerror("bad argument, [proto:]host[:port] expected");
 	}
 	}
 	| FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
 	| FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
-	| ID {mod_func_action = mk_action(MODULE_T, 2, MODEXP_ST, NULL, NUMBER_ST, 0); } LPAREN func_params RPAREN	{
+	| ID {mod_func_action = mk_action(MODULE_T, 2, MODEXP_ST, NULL, NUMBER_ST,
+			0); } LPAREN func_params RPAREN	{
 		mod_func_action->val[0].u.data = 
 		mod_func_action->val[0].u.data = 
 			find_export_record($1, mod_func_action->val[1].u.number, rt,
 			find_export_record($1, mod_func_action->val[1].u.number, rt,
 								&u_tmp);
 								&u_tmp);
@@ -2372,6 +2374,33 @@ cmd:
 			}
 			}
 			pkg_free(mod_func_action);
 			pkg_free(mod_func_action);
 			mod_func_action=0;
 			mod_func_action=0;
+		}else{
+			switch( ((union cmd_export_u*)
+						mod_func_action->val[0].u.data)->c.param_no){
+				case 0:
+				case 1:
+				case 2:
+					/* MODULE_T used for 0-2 params */
+					break;
+				case 3:
+					mod_func_action->type=MODULE3_T;
+					break;
+				case 4:
+					mod_func_action->type=MODULE4_T;
+					break;
+				case 5:
+					mod_func_action->type=MODULE5_T;
+					break;
+				case 6:
+					mod_func_action->type=MODULE6_T;
+					break;
+				case VAR_PARAM_NO:
+					mod_func_action->type=MODULEX_T;
+					break;
+				default:
+					yyerror("too many parameters for function\n");
+					break;
+			}
 		}
 		}
 		$$ = mod_func_action;
 		$$ = mod_func_action;
 	}
 	}
@@ -2385,8 +2414,10 @@ func_params:
 func_param:
 func_param:
         NUMBER {
         NUMBER {
 		if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
 		if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
-			mod_func_action->val[mod_func_action->val[1].u.number+2].type = NUMBER_ST;
-			mod_func_action->val[mod_func_action->val[1].u.number+2].u.number = $1;
+			mod_func_action->val[mod_func_action->val[1].u.number+2].type =
+				NUMBER_ST;
+			mod_func_action->val[mod_func_action->val[1].u.number+2].u.number =
+				$1;
 			mod_func_action->val[1].u.number++;
 			mod_func_action->val[1].u.number++;
 		} else {
 		} else {
 			yyerror("Too many arguments\n");
 			yyerror("Too many arguments\n");

+ 5 - 0
route.c

@@ -503,6 +503,11 @@ static int fix_actions(struct action* a)
 				break;
 				break;
 
 
 			case MODULE_T:
 			case MODULE_T:
+			case MODULE3_T:
+			case MODULE4_T:
+			case MODULE5_T:
+			case MODULE6_T:
+			case MODULEX_T:
 				cmd = t->val[0].u.data;
 				cmd = t->val[0].u.data;
 				if (cmd && cmd->c.fixup) {
 				if (cmd && cmd->c.fixup) {
 					int i;
 					int i;

+ 5 - 0
route_struct.c

@@ -350,6 +350,11 @@ void print_action(struct action* t)
 			DBG("if (");
 			DBG("if (");
 			break;
 			break;
 		case MODULE_T:
 		case MODULE_T:
+		case MODULE3_T:
+		case MODULE4_T:
+		case MODULE5_T:
+		case MODULE6_T:
+		case MODULEX_T:
 			DBG(" external_module_call(");
 			DBG(" external_module_call(");
 			break;
 			break;
 		case FORCE_RPORT_T:
 		case FORCE_RPORT_T:

+ 7 - 3
route_struct.h

@@ -70,7 +70,7 @@ enum { METHOD_O=1, URI_O, FROM_URI_O, TO_URI_O, SRCIP_O, SRCPORT_O,
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T,
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T,
 		SET_PORT_T, SET_URI_T, SET_HOSTPORTTRANS_T,
 		SET_PORT_T, SET_URI_T, SET_HOSTPORTTRANS_T,
-		IF_T, MODULE_T,
+		IF_T, MODULE_T, MODULE3_T, MODULE4_T, MODULE5_T, MODULE6_T, MODULEX_T,
 		SETFLAG_T, RESETFLAG_T, ISFLAGSET_T ,
 		SETFLAG_T, RESETFLAG_T, ISFLAGSET_T ,
 		AVPFLAG_OPER_T,
 		AVPFLAG_OPER_T,
 		LEN_GT_T, PREFIX_T, STRIP_T,STRIP_TAIL_T,
 		LEN_GT_T, PREFIX_T, STRIP_T,STRIP_TAIL_T,
@@ -133,13 +133,17 @@ typedef struct {
 	} u;
 	} u;
 } action_u_t;
 } action_u_t;
 
 
-#define MAX_ACTIONS 4
+/* maximum internal array/params
+ * for module function calls val[0] and val[1] store a pointer to the
+ * function and the number of params, the rest are the function params 
+ */
+#define MAX_ACTIONS (2+6)
 
 
 struct action{
 struct action{
 	int type;  /* forward, drop, log, send ...*/
 	int type;  /* forward, drop, log, send ...*/
 	int count;
 	int count;
-	action_u_t val[MAX_ACTIONS];
 	struct action* next;
 	struct action* next;
+	action_u_t val[MAX_ACTIONS];
 };
 };
 
 
 struct expr* mk_exp(int op, struct expr* left, struct expr* right);
 struct expr* mk_exp(int op, struct expr* left, struct expr* right);

+ 2 - 1
sr_module.c

@@ -353,7 +353,8 @@ union cmd_export_u* find_mod_export_record(char* mod, char* name,
 			for(i=0, cmd=(void*)&t->exports->VER.cmds[0]; cmd->VER.name; \
 			for(i=0, cmd=(void*)&t->exports->VER.cmds[0]; cmd->VER.name; \
 					i++, cmd=(void*)&t->exports->VER.cmds[i]){\
 					i++, cmd=(void*)&t->exports->VER.cmds[i]){\
 				if((strcmp(name, cmd->VER.name)==0)&& \
 				if((strcmp(name, cmd->VER.name)==0)&& \
-					(cmd->VER.param_no==param_no) &&  \
+					((cmd->VER.param_no==param_no) || \
+					 (cmd->VER.param_no==VAR_PARAM_NO)) && \
 					((cmd->VER.flags & flags) == flags) \
 					((cmd->VER.flags & flags) == flags) \
 				){ \
 				){ \
 					DBG("find_export_record: found <%s> in module %s [%s]\n", \
 					DBG("find_export_record: found <%s> in module %s [%s]\n", \

+ 18 - 0
sr_module.h

@@ -44,6 +44,8 @@
  *  2008-11-17  sip-router version: includes some of the openser/kamailio
  *  2008-11-17  sip-router version: includes some of the openser/kamailio
  *               changes: f(void) instead of f(), free_fixup_function()
  *               changes: f(void) instead of f(), free_fixup_function()
  *              dual module interface support: ser & kamailio (andrei)
  *              dual module interface support: ser & kamailio (andrei)
+ *  2008-11-18  prototypes for various fixed parameters numbers module
+ *               functions (3, 4, 5 & 6) and variable parameters (andrei)
  */
  */
 
 
 /*!
 /*!
@@ -89,6 +91,15 @@
 
 
 typedef  struct module_exports* (*module_register)(void);
 typedef  struct module_exports* (*module_register)(void);
 typedef  int (*cmd_function)(struct sip_msg*, char*, char*);
 typedef  int (*cmd_function)(struct sip_msg*, char*, char*);
+typedef  int (*cmd_function3)(struct sip_msg*, char*, char*, char*);
+typedef  int (*cmd_function4)(struct sip_msg*, char*, char*, char*, char*);
+typedef  int (*cmd_function5)(struct sip_msg*,  char*, char*, char*,
+												char*, char*);
+typedef  int (*cmd_function6)(struct sip_msg*,  char*, char*, char*,
+												char*, char*, char*);
+/* variable number of param module function, takes as param the sip_msg,
+   extra paremeters number and a pointer to an array of parameters */
+typedef  int (*cmd_function_var)(struct sip_msg*, int no, action_u_t* vals );
 typedef  int (*fixup_function)(void** param, int param_no);
 typedef  int (*fixup_function)(void** param, int param_no);
 typedef  int (*free_fixup_function)(void** param, int param_no);
 typedef  int (*free_fixup_function)(void** param, int param_no);
 typedef  int (*response_function)(struct sip_msg*);
 typedef  int (*response_function)(struct sip_msg*);
@@ -114,6 +125,13 @@ typedef unsigned int modparam_t;
 
 
 typedef int (*param_func_t)( modparam_t type, void* val);
 typedef int (*param_func_t)( modparam_t type, void* val);
 
 
+/* magic parameter number values */
+
+#define NO_SCRIPT     -1    /* export not usable from scripts */
+#define VAR_PARAM_NO  -128  /* function has variable number of parameters
+							   (see cmd_function_var for the prototype) */
+
+/* functions flags */
 #define REQUEST_ROUTE 1  /* Function can be used in request route blocks */
 #define REQUEST_ROUTE 1  /* Function can be used in request route blocks */
 #define FAILURE_ROUTE 2  /* Function can be used in reply route blocks */
 #define FAILURE_ROUTE 2  /* Function can be used in reply route blocks */
 #define ONREPLY_ROUTE 4  /* Function can be used in on_reply */
 #define ONREPLY_ROUTE 4  /* Function can be used in on_reply */