Browse code

- added support for maximum 2 parameters per cmd call - added parameters no. for every function (can be 0, 1 or 2). - new example module (textops)

Andrei Pelinescu-Onciul authored on 26/10/2001 00:39:42
Showing 11 changed files
... ...
@@ -6,10 +6,12 @@
6 6
 #  Arch supported: Linux, FreeBSD, SunOS (tested on Solaris 6), WinNT
7 7
 
8 8
 auto_gen=lex.yy.c cfg.tab.c   #lexx, yacc etc
9
+exclude_modules=CVS
9 10
 sources=$(filter-out $(auto_gen), $(wildcard *.c)) $(auto_gen) 
10 11
 objs=$(sources:.c=.o)
11 12
 depends=$(sources:.c=.d)
12
-modules=$(wildcard modules/*)
13
+modules=$(filter-out $(addprefix modules/, $(exclude_modules)), \
14
+						$(wildcard modules/*))
13 15
 
14 16
 NAME=ser
15 17
 
... ...
@@ -278,7 +278,8 @@ int do_action(struct action* a, struct sip_msg* msg)
278 278
 		case MODULE_T:
279 279
 			if ( ((a->p1_type==CMDF_ST)&&a->p1.data)&&
280 280
 					((a->p2_type==STRING_ST)&&a->p2.data) ){
281
-				ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data);
281
+				ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data,
282
+													  (char*)a->p3.data);
282 283
 			}else{
283 284
 				LOG(L_CRIT,"BUG: do_action: bad module call\n");
284 285
 			}
... ...
@@ -197,6 +197,10 @@ EAT_ABLE	[\ \t\b\r]
197 197
 
198 198
 <STRING1>\\n		{ count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
199 199
 						yyleng--; addstr(yytext, &str); }
200
+<STRING1>\\r		{ count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
201
+						yyleng--; addstr(yytext, &str); }
202
+<STRING1>\\g		{ count(); yytext[yyleng-2]='\g';yytext[yyleng-1]=0; 
203
+						yyleng--; addstr(yytext, &str); }
200 204
 <STRING1>\\t		{ count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
201 205
 						yyleng--; addstr(yytext, &str); }
202 206
 <STRING1>\\\\		{ count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 
... ...
@@ -554,7 +554,21 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
554 554
 		| SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
555 555
 		| SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, "
556 556
 										"string expected"); }
557
-		| ID LPAREN STRING RPAREN { f_tmp=find_export($1);
557
+		| ID LPAREN RPAREN			{ f_tmp=find_export($1, 0);
558
+									   if (f_tmp==0){
559
+										yyerror("unknown command %s, missing"
560
+										" loadmodule?\n");
561
+										$$=0;
562
+									   }else{
563
+										$$=mk_action(	MODULE_T,
564
+														CMDF_ST,
565
+														0,
566
+														f_tmp,
567
+														0
568
+													);
569
+									   }
570
+									}
571
+		| ID LPAREN STRING RPAREN { f_tmp=find_export($1, 1);
558 572
 									if (f_tmp==0){
559 573
 										yyerror("unknown command %s, missing"
560 574
 										" loadmodule?\n");
... ...
@@ -568,6 +582,23 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
568 568
 													);
569 569
 									}
570 570
 								  }
571
+		| ID LPAREN STRING  COMMA STRING RPAREN 
572
+								  { f_tmp=find_export($1, 2);
573
+									if (f_tmp==0){
574
+										yyerror("unknown command %s, missing"
575
+										" loadmodule?\n");
576
+										$$=0;
577
+									}else{
578
+										$$=mk_action3(	MODULE_T,
579
+														CMDF_ST,
580
+														STRING_ST,
581
+														STRING_ST,
582
+														f_tmp,
583
+														$3,
584
+														$5
585
+													);
586
+									}
587
+								  }
571 588
 		| ID LPAREN error RPAREN { $$=0; yyerror("bad arguments"); }
572 589
 		| if_cmd		{ $$=$1; }
573 590
 	;
... ...
@@ -138,9 +138,12 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
138 138
 	}
139 139
 	
140 140
 	
141
-	/* compute new msg len*/
141
+	/* compute new msg len and fix overlapping zones*/
142 142
 	new_len=len;
143
+	s_offset=0;
143 144
 	for(t=msg->add_rm;t;t=t->next){
145
+		DBG("t=%x, op=%d, offset=%x, len=%d, s_offset=%x\n",
146
+				t, t->op, t->u.offset, t->len, s_offset);
144 147
 		for(r=t->before;r;r=r->before){
145 148
 			switch(r->op){
146 149
 				case LUMP_ADD:
... ...
@@ -157,9 +160,28 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
157 157
 				new_len+=t->len;
158 158
 				break;
159 159
 			case LUMP_DEL:
160
+				/* fix overlapping deleted zones */
161
+				if (t->u.offset < s_offset){
162
+					DBG( "overlapping DEL offsets (%d,%d(%d)), fixing...\n",
163
+						 s_offset, t->u.offset, t->len);
164
+					/* change len */
165
+					if (t->len>s_offset-t->u.offset) 
166
+							t->len-=s_offset-t->u.offset;
167
+					else t->len=0;
168
+					t->u.offset=s_offset;
169
+					DBG("fixed to %d(%d)\n", t->u.offset, t->len);
170
+				}
171
+				s_offset=t->u.offset+t->len;
160 172
 				new_len-=t->len;
161 173
 				break;
162 174
 			case LUMP_NOP:
175
+				/* fix offset if overlapping on a deleted zone */
176
+				if (t->u.offset < s_offset){
177
+					DBG("overlapping zones (%d,%d)\n", s_offset, t->u.offset);
178
+					t->u.offset=s_offset;
179
+					DBG("fixed to %d\n", t->u.offset);
180
+				}else
181
+					s_offset=t->u.offset;
163 182
 				/* do nothing */
164 183
 				break;
165 184
 			debug:
... ...
@@ -204,19 +226,53 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
204 204
 	}
205 205
 /* copy msg adding/removing lumps */
206 206
 	for (t=msg->add_rm;t;t=t->next){
207
+		DBG(" t=%x, op=%d, offset=%x, len=%d, s_offset=%x\n",
208
+				t, t->op, t->u.offset, t->len, s_offset);
207 209
 		switch(t->op){
208 210
 			case LUMP_ADD:
209 211
 				/* just add it here! */
212
+				/* process before  */
213
+				for(r=t->before;r;r=r->before){
214
+					switch (r->op){
215
+						case LUMP_ADD:
216
+							/*just add it here*/
217
+							memcpy(new_buf+offset, r->u.value, r->len);
218
+							offset+=r->len;
219
+							break;
220
+						default:
221
+							/* only ADD allowed for before/after */
222
+							LOG(L_CRIT, "BUG:forward_request: invalid op for"
223
+									" data lump (%x)\n", r->op);
224
+								
225
+					}
226
+				}
227
+				/* copy "main" part */
210 228
 				memcpy(new_buf+offset, t->u.value, t->len);
211 229
 				offset+=t->len;
230
+				/* process after */
231
+				for(r=t->after;r;r=r->after){
232
+					switch (r->op){
233
+						case LUMP_ADD:
234
+							/*just add it here*/
235
+							memcpy(new_buf+offset, r->u.value, r->len);
236
+							offset+=r->len;
237
+							break;
238
+						default:
239
+							/* only ADD allowed for before/after */
240
+							LOG(L_CRIT, "BUG:forward_request: invalid op for"
241
+									" data lump (%x)\n", r->op);
242
+					}
243
+				}
212 244
 				break;
213 245
 			case LUMP_NOP:
214 246
 			case LUMP_DEL:
215 247
 				/* copy till offset */
216 248
 				if (s_offset>t->u.offset){
217
-					LOG(L_CRIT, "BUG: invalid offset in lump (%d)\n",
218
-								t->u.offset);
219
-					goto error;
249
+					DBG("Warning: (%d) overlapped lumps offsets,"
250
+						" ignoring(%x, %x)\n", t->op, s_offset,t->u.offset);
251
+					/* this should've been fixed above (when computing len) */
252
+					/* just ignore it*/
253
+					break;
220 254
 				}
221 255
 				size=t->u.offset-s_offset;
222 256
 				if (size){
... ...
@@ -232,7 +288,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
232 232
 							memcpy(new_buf+offset, r->u.value, r->len);
233 233
 							offset+=r->len;
234 234
 							break;
235
-						defaut:
235
+						default:
236 236
 							/* only ADD allowed for before/after */
237 237
 							LOG(L_CRIT, "BUG:forward_request: invalid op for"
238 238
 									" data lump (%x)\n", r->op);
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 
32 32
 static char id[]="@(#) $Id$";
33
-static char version[]="ser 0.8.1-plugins";
33
+static char version[]="ser 0.8.2";
34 34
 static char flags[]="NOCR:"
35 35
 #ifdef NOCR
36 36
 "On"
... ...
@@ -26,12 +26,13 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
26 26
 	msg.len=len;
27 27
 	msg.src_ip=src_ip;
28 28
 	/* make a copy of the message */
29
-	msg.orig=(char*) malloc(len);
29
+	msg.orig=(char*) malloc(len+1);
30 30
 	if (msg.orig==0){
31 31
 		LOG(L_ERR, "ERROR:receive_msg: memory allocation failure\n");
32 32
 		goto error1;
33 33
 	}
34 34
 	memcpy(msg.orig, buf, len);
35
+	msg.orig[len]=0; /* null terminate it,good for using str* functions on it*/
35 36
 	
36 37
 	if (parse_msg(buf,len, &msg)!=0){
37 38
 		goto error;
... ...
@@ -19,6 +19,7 @@
19 19
 #include "dprint.h"
20 20
 #include "proxy.h"
21 21
 #include "action.h"
22
+#include "sr_module.h"
22 23
 
23 24
 #ifdef DEBUG_DMALLOC
24 25
 #include <dmalloc.h>
... ...
@@ -104,7 +105,8 @@ static int fix_actions(struct action* a)
104 104
 	struct action *t;
105 105
 	struct proxy_l* p;
106 106
 	char *tmp;
107
-	int ret;
107
+	int ret,r;
108
+	struct sr_module* mod;
108 109
 	
109 110
 	if (a==0){
110 111
 		LOG(L_CRIT,"BUG: fix_actions: null pointer\n");
... ...
@@ -140,7 +142,7 @@ static int fix_actions(struct action* a)
140 140
 							return E_BUG;
141 141
 					}
142 142
 					break;
143
-		case IF_T:
143
+			case IF_T:
144 144
 				if (t->p1_type!=EXPR_ST){
145 145
 					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
146 146
 								"%d for if (should be expr)\n",
... ...
@@ -170,6 +172,22 @@ static int fix_actions(struct action* a)
170 170
 						return ret;
171 171
 				}
172 172
 				break;
173
+			case MODULE_T:
174
+				if ((mod=find_module(t->p1.data, &r))!=0){
175
+					DBG("fixing %s %s\n", mod->path,
176
+							mod->exports->cmd_names[r]);
177
+					if (mod->exports->fixup_pointers[r]){
178
+						if (mod->exports->param_no[r]>0){
179
+							ret=mod->exports->fixup_pointers[r](&t->p2.data,1);
180
+							if (ret<0) return ret;
181
+						}
182
+						if (mod->exports->param_no[r]>1){
183
+							ret=mod->exports->fixup_pointers[r](&t->p3.data,2);
184
+							if (ret<0) return ret;
185
+						}
186
+					}
187
+				}
188
+			
173 189
 		}
174 190
 	}
175 191
 	return 0;
... ...
@@ -72,14 +72,15 @@ skip:
72 72
 
73 73
 /* searches the module list and returns a pointer to the "name" function or
74 74
  * 0 if not found */
75
-cmd_function find_export(char* name)
75
+cmd_function find_export(char* name, int param_no)
76 76
 {
77 77
 	struct sr_module* t;
78 78
 	int r;
79 79
 
80 80
 	for(t=modules;t;t=t->next){
81 81
 		for(r=0;r<t->exports->cmd_no;r++){
82
-			if(strcmp(name, t->exports->cmd_names[r])==0){
82
+			if((strcmp(name, t->exports->cmd_names[r])==0)&&
83
+				(t->exports->param_no[r]==param_no) ){
83 84
 				DBG("find_export: found <%s> in module %s [%s]\n",
84 85
 						name, t->exports->name, t->path);
85 86
 				return t->exports->cmd_pointers[r];
... ...
@@ -90,4 +91,20 @@ cmd_function find_export(char* name)
90 90
 	return 0;
91 91
 }
92 92
 
93
-	
93
+
94
+
95
+/* finds a module, given a pointer to a module function *
96
+ * returns pointer to module, & if i i!=0, *i=the function index */
97
+struct sr_module* find_module(void* f, int *i)
98
+{
99
+	struct sr_module* t;
100
+	int r;
101
+	for (t=modules;t;t=t->next){
102
+		for(r=0;r<t->exports->cmd_no;r++) 
103
+			if (f==t->exports->cmd_pointers[r]) {
104
+				if (i) *i=r;
105
+				return t;
106
+			}
107
+	}
108
+	return 0;
109
+}
... ...
@@ -8,13 +8,17 @@
8 8
 
9 9
 #include "msg_parser.h" /* for sip_msg */
10 10
 
11
-typedef  int (*cmd_function)(struct sip_msg*, char*);
11
+typedef  int (*cmd_function)(struct sip_msg*, char*, char*);
12
+typedef  int (*fixup_function)(void** param, int param_no);
12 13
 typedef  int (*response_function)(struct sip_msg*);
13 14
 
14 15
 struct module_exports{
15 16
 	char* name; /* null terminated module name */
16
-	char** cmd_names;
17
-	cmd_function* cmd_pointers;
17
+	char** cmd_names; /* cmd names registered by this modules */
18
+	cmd_function* cmd_pointers; /* pointers to the corresponding functions */
19
+	int* param_no; /* number of parameters used by the function */
20
+	fixup_function* fixup_pointers; /* pointers to functions called to "fix"
21
+										the params, e.g: precompile a re */
18 22
 	int cmd_no; /* number of registered commands 
19 23
 				   (size of cmd_{names,pointers}*/
20 24
 	response_function response_f; /* function used for responses,
... ...
@@ -30,7 +34,9 @@ struct sr_module{
30 30
 
31 31
 
32 32
 int load_module(char* path);
33
-cmd_function find_export(char* name);
33
+cmd_function find_export(char* name, int param_no);
34
+struct sr_module* find_module(void *f, int* r);
35
+
34 36
 
35 37
 /* modules function prototypes:
36 38
  * struct module_exports* mod_register();
... ...
@@ -8,9 +8,13 @@ log_stderror=yes # (cmd line: -E)
8 8
 
9 9
 #modules
10 10
 loadmodule "modules/print/print.so"
11
+loadmodule "modules/textops/textops.so"
11 12
 
12 13
 route{
13
-	print("before forward");
14
+	print("before insert");
15
+	replace('^User-Agent:.*$', "User-Agent: ser 0.8.x");
16
+	print("after insert");
17
+	search_append('To:.*$', "Foo Bar");
14 18
 	forward(127.0.0.1,5061);
15 19
 	print("after forward");
16 20
 }