Browse code

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 authored on 24/11/2008 13:16:52
Showing 7 changed files
... ...
@@ -46,6 +46,7 @@
46 46
  *              (andrei)
47 47
  *  2007-06-14  run_actions & do_action need a ctx or handle now, no more 
48 48
  *               static vars (andrei)
49
+ *  2008-11-18  support for variable parameter module functions (andrei)
49 50
  */
50 51
 
51 52
 
... ...
@@ -101,6 +102,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
101 102
 	struct dest_info dst;
102 103
 	char* tmp;
103 104
 	char *new_uri, *end, *crt;
105
+	void* f;
104 106
 	int len;
105 107
 	int user;
106 108
 	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)
717 719
 			break;
718 720
 		case MODULE_T:
719 721
 			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
720
-					((union cmd_export_u*)a->val[0].u.data)->c.function){
721
-				ret=((union cmd_export_u*)a->val[0].u.data)->c.function(msg,
722
-					(char*)a->val[2].u.data,
723
-					(char*)a->val[3].u.data
724
-				);
722
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
723
+				ret=((cmd_function)f)(msg,
724
+										(char*)a->val[2].u.data,
725
+										(char*)a->val[3].u.data
726
+									);
727
+				if (ret==0) h->run_flags|=EXIT_R_F;
728
+				h->last_retcode=ret;
729
+			} else {
730
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
731
+			}
732
+			break;
733
+		/* instead of using the parameter number, we use different names
734
+		 * for calls to functions with 3, 4, 5, 6 or variable number of
735
+		 * parameters due to performance reasons */
736
+		case MODULE3_T:
737
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
738
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
739
+				ret=((cmd_function3)f)(msg,
740
+										(char*)a->val[2].u.data,
741
+										(char*)a->val[3].u.data,
742
+										(char*)a->val[4].u.data
743
+									);
744
+				if (ret==0) h->run_flags|=EXIT_R_F;
745
+				h->last_retcode=ret;
746
+			} else {
747
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
748
+			}
749
+			break;
750
+		case MODULE4_T:
751
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
752
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
753
+				ret=((cmd_function4)f)(msg,
754
+										(char*)a->val[2].u.data,
755
+										(char*)a->val[3].u.data,
756
+										(char*)a->val[4].u.data,
757
+										(char*)a->val[5].u.data
758
+									);
759
+				if (ret==0) h->run_flags|=EXIT_R_F;
760
+				h->last_retcode=ret;
761
+			} else {
762
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
763
+			}
764
+			break;
765
+		case MODULE5_T:
766
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
767
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
768
+				ret=((cmd_function5)f)(msg,
769
+										(char*)a->val[2].u.data,
770
+										(char*)a->val[3].u.data,
771
+										(char*)a->val[4].u.data,
772
+										(char*)a->val[5].u.data,
773
+										(char*)a->val[6].u.data
774
+									);
775
+				if (ret==0) h->run_flags|=EXIT_R_F;
776
+				h->last_retcode=ret;
777
+			} else {
778
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
779
+			}
780
+			break;
781
+		case MODULE6_T:
782
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
783
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
784
+				ret=((cmd_function6)f)(msg,
785
+										(char*)a->val[2].u.data,
786
+										(char*)a->val[3].u.data,
787
+										(char*)a->val[4].u.data,
788
+										(char*)a->val[5].u.data,
789
+										(char*)a->val[6].u.data,
790
+										(char*)a->val[7].u.data
791
+									);
792
+				if (ret==0) h->run_flags|=EXIT_R_F;
793
+				h->last_retcode=ret;
794
+			} else {
795
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
796
+			}
797
+			break;
798
+		case MODULEX_T:
799
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
800
+					(f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
801
+				ret=((cmd_function_var)f)(msg,
802
+											a->val[1].u.number,
803
+											&a->val[2]
804
+										);
725 805
 				if (ret==0) h->run_flags|=EXIT_R_F;
726 806
 				h->last_retcode=ret;
727 807
 			} else {
... ...
@@ -88,6 +88,7 @@
88 88
  * 2007-11-28  added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
89 89
  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
90 90
  * 2008-01-24  added cfg_var definition (Miklos)
91
+ * 2008-11-18  support for variable parameter module functions (andrei)
91 92
 */
92 93
 
93 94
 %{
... ...
@@ -2359,7 +2360,8 @@ cmd:
2359 2360
 		$$=0; yyerror("bad argument, [proto:]host[:port] expected");
2360 2361
 	}
2361 2362
 	| FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
2362
-	| ID {mod_func_action = mk_action(MODULE_T, 2, MODEXP_ST, NULL, NUMBER_ST, 0); } LPAREN func_params RPAREN	{
2363
+	| ID {mod_func_action = mk_action(MODULE_T, 2, MODEXP_ST, NULL, NUMBER_ST,
2364
+			0); } LPAREN func_params RPAREN	{
2363 2365
 		mod_func_action->val[0].u.data = 
2364 2366
 			find_export_record($1, mod_func_action->val[1].u.number, rt,
2365 2367
 								&u_tmp);
... ...
@@ -2372,6 +2374,33 @@ cmd:
2372 2374
 			}
2373 2375
 			pkg_free(mod_func_action);
2374 2376
 			mod_func_action=0;
2377
+		}else{
2378
+			switch( ((union cmd_export_u*)
2379
+						mod_func_action->val[0].u.data)->c.param_no){
2380
+				case 0:
2381
+				case 1:
2382
+				case 2:
2383
+					/* MODULE_T used for 0-2 params */
2384
+					break;
2385
+				case 3:
2386
+					mod_func_action->type=MODULE3_T;
2387
+					break;
2388
+				case 4:
2389
+					mod_func_action->type=MODULE4_T;
2390
+					break;
2391
+				case 5:
2392
+					mod_func_action->type=MODULE5_T;
2393
+					break;
2394
+				case 6:
2395
+					mod_func_action->type=MODULE6_T;
2396
+					break;
2397
+				case VAR_PARAM_NO:
2398
+					mod_func_action->type=MODULEX_T;
2399
+					break;
2400
+				default:
2401
+					yyerror("too many parameters for function\n");
2402
+					break;
2403
+			}
2375 2404
 		}
2376 2405
 		$$ = mod_func_action;
2377 2406
 	}
... ...
@@ -2385,8 +2414,10 @@ func_params:
2385 2414
 func_param:
2386 2415
         NUMBER {
2387 2416
 		if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
2388
-			mod_func_action->val[mod_func_action->val[1].u.number+2].type = NUMBER_ST;
2389
-			mod_func_action->val[mod_func_action->val[1].u.number+2].u.number = $1;
2417
+			mod_func_action->val[mod_func_action->val[1].u.number+2].type =
2418
+				NUMBER_ST;
2419
+			mod_func_action->val[mod_func_action->val[1].u.number+2].u.number =
2420
+				$1;
2390 2421
 			mod_func_action->val[1].u.number++;
2391 2422
 		} else {
2392 2423
 			yyerror("Too many arguments\n");
... ...
@@ -503,6 +503,11 @@ static int fix_actions(struct action* a)
503 503
 				break;
504 504
 
505 505
 			case MODULE_T:
506
+			case MODULE3_T:
507
+			case MODULE4_T:
508
+			case MODULE5_T:
509
+			case MODULE6_T:
510
+			case MODULEX_T:
506 511
 				cmd = t->val[0].u.data;
507 512
 				if (cmd && cmd->c.fixup) {
508 513
 					int i;
... ...
@@ -350,6 +350,11 @@ void print_action(struct action* t)
350 350
 			DBG("if (");
351 351
 			break;
352 352
 		case MODULE_T:
353
+		case MODULE3_T:
354
+		case MODULE4_T:
355
+		case MODULE5_T:
356
+		case MODULE6_T:
357
+		case MODULEX_T:
353 358
 			DBG(" external_module_call(");
354 359
 			break;
355 360
 		case FORCE_RPORT_T:
... ...
@@ -70,7 +70,7 @@ enum { METHOD_O=1, URI_O, FROM_URI_O, TO_URI_O, SRCIP_O, SRCPORT_O,
70 70
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
71 71
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T,
72 72
 		SET_PORT_T, SET_URI_T, SET_HOSTPORTTRANS_T,
73
-		IF_T, MODULE_T,
73
+		IF_T, MODULE_T, MODULE3_T, MODULE4_T, MODULE5_T, MODULE6_T, MODULEX_T,
74 74
 		SETFLAG_T, RESETFLAG_T, ISFLAGSET_T ,
75 75
 		AVPFLAG_OPER_T,
76 76
 		LEN_GT_T, PREFIX_T, STRIP_T,STRIP_TAIL_T,
... ...
@@ -133,13 +133,17 @@ typedef struct {
133 133
 	} u;
134 134
 } action_u_t;
135 135
 
136
-#define MAX_ACTIONS 4
136
+/* maximum internal array/params
137
+ * for module function calls val[0] and val[1] store a pointer to the
138
+ * function and the number of params, the rest are the function params 
139
+ */
140
+#define MAX_ACTIONS (2+6)
137 141
 
138 142
 struct action{
139 143
 	int type;  /* forward, drop, log, send ...*/
140 144
 	int count;
141
-	action_u_t val[MAX_ACTIONS];
142 145
 	struct action* next;
146
+	action_u_t val[MAX_ACTIONS];
143 147
 };
144 148
 
145 149
 struct expr* mk_exp(int op, struct expr* left, struct expr* right);
... ...
@@ -353,7 +353,8 @@ union cmd_export_u* find_mod_export_record(char* mod, char* name,
353 353
 			for(i=0, cmd=(void*)&t->exports->VER.cmds[0]; cmd->VER.name; \
354 354
 					i++, cmd=(void*)&t->exports->VER.cmds[i]){\
355 355
 				if((strcmp(name, cmd->VER.name)==0)&& \
356
-					(cmd->VER.param_no==param_no) &&  \
356
+					((cmd->VER.param_no==param_no) || \
357
+					 (cmd->VER.param_no==VAR_PARAM_NO)) && \
357 358
 					((cmd->VER.flags & flags) == flags) \
358 359
 				){ \
359 360
 					DBG("find_export_record: found <%s> in module %s [%s]\n", \
... ...
@@ -44,6 +44,8 @@
44 44
  *  2008-11-17  sip-router version: includes some of the openser/kamailio
45 45
  *               changes: f(void) instead of f(), free_fixup_function()
46 46
  *              dual module interface support: ser & kamailio (andrei)
47
+ *  2008-11-18  prototypes for various fixed parameters numbers module
48
+ *               functions (3, 4, 5 & 6) and variable parameters (andrei)
47 49
  */
48 50
 
49 51
 /*!
... ...
@@ -89,6 +91,15 @@
89 91
 
90 92
 typedef  struct module_exports* (*module_register)(void);
91 93
 typedef  int (*cmd_function)(struct sip_msg*, char*, char*);
94
+typedef  int (*cmd_function3)(struct sip_msg*, char*, char*, char*);
95
+typedef  int (*cmd_function4)(struct sip_msg*, char*, char*, char*, char*);
96
+typedef  int (*cmd_function5)(struct sip_msg*,  char*, char*, char*,
97
+												char*, char*);
98
+typedef  int (*cmd_function6)(struct sip_msg*,  char*, char*, char*,
99
+												char*, char*, char*);
100
+/* variable number of param module function, takes as param the sip_msg,
101
+   extra paremeters number and a pointer to an array of parameters */
102
+typedef  int (*cmd_function_var)(struct sip_msg*, int no, action_u_t* vals );
92 103
 typedef  int (*fixup_function)(void** param, int param_no);
93 104
 typedef  int (*free_fixup_function)(void** param, int param_no);
94 105
 typedef  int (*response_function)(struct sip_msg*);
... ...
@@ -114,6 +125,13 @@ typedef unsigned int modparam_t;
114 125
 
115 126
 typedef int (*param_func_t)( modparam_t type, void* val);
116 127
 
128
+/* magic parameter number values */
129
+
130
+#define NO_SCRIPT     -1    /* export not usable from scripts */
131
+#define VAR_PARAM_NO  -128  /* function has variable number of parameters
132
+							   (see cmd_function_var for the prototype) */
133
+
134
+/* functions flags */
117 135
 #define REQUEST_ROUTE 1  /* Function can be used in request route blocks */
118 136
 #define FAILURE_ROUTE 2  /* Function can be used in reply route blocks */
119 137
 #define ONREPLY_ROUTE 4  /* Function can be used in on_reply */