/src/opensips/route_struct.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * route structures helping functions |
3 | | * |
4 | | * Copyright (C) 2001-2003 FhG Fokus |
5 | | * |
6 | | * This file is part of opensips, a free SIP server. |
7 | | * |
8 | | * opensips is free software; you can redistribute it and/or modify |
9 | | * it under the terms of the GNU General Public License as published by |
10 | | * the Free Software Foundation; either version 2 of the License, or |
11 | | * (at your option) any later version |
12 | | * |
13 | | * opensips is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | | * |
22 | | * History: |
23 | | * -------- |
24 | | * 2003-01-29 src_port introduced (jiri) |
25 | | * 2003-03-19 replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei) |
26 | | * 2003-04-12 FORCE_RPORT_T added (andrei) |
27 | | * 2003-10-02 added SET_ADV_ADDRESS & SET_ADV_PORT (andrei) |
28 | | * 2006-03-02 mk_action -> mk_action_2p and mk_action3 -> mk_action_3p; |
29 | | * both functions take as extra param the cfg line (bogdan) |
30 | | * 2006-12-22 support for script and branch flags added (bogdan) |
31 | | */ |
32 | | |
33 | | /*! |
34 | | * \file |
35 | | * \brief SIP routing engine - structure helping functions |
36 | | */ |
37 | | |
38 | | #include "route_struct.h" |
39 | | |
40 | | #include <stdio.h> |
41 | | #include <stdlib.h> |
42 | | #include <string.h> |
43 | | |
44 | | #include "sr_module.h" |
45 | | #include "dprint.h" |
46 | | #include "ip_addr.h" |
47 | | #include "mem/mem.h" |
48 | | #include "ut.h" /* ZSW() */ |
49 | | |
50 | | struct expr* mk_exp(int op, struct expr* left, struct expr* right) |
51 | 0 | { |
52 | 0 | struct expr * e; |
53 | 0 | e=(struct expr*)pkg_malloc(sizeof (struct expr)); |
54 | 0 | if (e==0) goto error; |
55 | 0 | e->type=EXP_T; |
56 | 0 | e->op=op; |
57 | 0 | e->left.v.expr=left; |
58 | 0 | e->right.v.expr=right; |
59 | 0 | return e; |
60 | 0 | error: |
61 | 0 | LM_CRIT("pkg memory allocation failure\n"); |
62 | 0 | return 0; |
63 | 0 | } |
64 | | |
65 | | |
66 | | struct expr* mk_elem(int op, int leftt, void *leftd, int rightt, void *rightd) |
67 | 0 | { |
68 | 0 | struct expr * e; |
69 | 0 | e=(struct expr*)pkg_malloc(sizeof (struct expr)); |
70 | 0 | if (e==0) goto error; |
71 | 0 | memset(e, 0, sizeof(struct expr)); |
72 | 0 | e->type=ELEM_T; |
73 | 0 | e->op=op; |
74 | 0 | e->left.type = leftt; |
75 | 0 | e->left.v.data = leftd; |
76 | 0 | if((e->left.type==STR_ST || e->left.type==STRINGV_O) |
77 | 0 | && e->left.v.s.s!=NULL) |
78 | 0 | e->left.v.s.len = strlen(e->left.v.s.s); |
79 | 0 | e->right.type = rightt; |
80 | 0 | e->right.v.data = rightd; |
81 | 0 | if((e->right.type==STR_ST || e->right.type==STRINGV_O) |
82 | 0 | && e->right.v.s.s!=0) |
83 | 0 | e->right.v.s.len = strlen(e->right.v.s.s); |
84 | 0 | return e; |
85 | 0 | error: |
86 | 0 | LM_CRIT("pkg memory allocation failure\n"); |
87 | 0 | return 0; |
88 | 0 | } |
89 | | |
90 | | |
91 | | |
92 | | struct action* mk_action(int type, int n, action_elem_t *elem, |
93 | | int line, char *file) |
94 | 0 | { |
95 | 0 | int i; |
96 | 0 | struct action* a; |
97 | |
|
98 | 0 | if(n>MAX_ACTION_ELEMS) |
99 | 0 | { |
100 | 0 | LM_ERR("too many action elements at %s:%d for %d", |
101 | 0 | file, line, type); |
102 | 0 | return 0; |
103 | 0 | } |
104 | | |
105 | 0 | a=(struct action*)pkg_malloc(sizeof(struct action)); |
106 | 0 | if (a==0) goto error; |
107 | 0 | memset(a,0,sizeof(struct action)); |
108 | 0 | a->type=type; |
109 | |
|
110 | 0 | for(i=0; i<n; i++) |
111 | 0 | { |
112 | 0 | a->elem[i].type = elem[i].type; |
113 | 0 | a->elem[i].u.data = elem[i].u.data; |
114 | 0 | if(a->elem[i].type==STR_ST && a->elem[i].u.s.s!=NULL) |
115 | 0 | a->elem[i].u.s.len = strlen(a->elem[i].u.s.s); |
116 | 0 | } |
117 | |
|
118 | 0 | a->line = line; |
119 | 0 | a->file = file; |
120 | 0 | a->next=0; |
121 | 0 | return a; |
122 | | |
123 | 0 | error: |
124 | 0 | LM_CRIT("pkg memory allocation failure\n"); |
125 | 0 | return 0; |
126 | |
|
127 | 0 | } |
128 | | |
129 | | |
130 | | struct action* append_action(struct action* a, struct action* b) |
131 | 0 | { |
132 | 0 | struct action *t; |
133 | 0 | if (b==0) return a; |
134 | 0 | if (a==0) return b; |
135 | | |
136 | 0 | for(t=a;t->next;t=t->next); |
137 | 0 | t->next=b; |
138 | 0 | return a; |
139 | 0 | } |
140 | | |
141 | | |
142 | | static void free_expr( struct expr *e) |
143 | 0 | { |
144 | 0 | if (e==NULL) |
145 | 0 | return; |
146 | | |
147 | 0 | if (e->type==ELEM_T) { |
148 | | |
149 | | /* left ... */ |
150 | 0 | switch (e->left.type) { |
151 | 0 | case EXPR_O: |
152 | 0 | free_expr( e->left.v.expr ); break; |
153 | 0 | case ACTION_O: |
154 | 0 | free_action_list( (struct action*)e->left.v.data ); break; |
155 | 0 | case SCRIPTVAR_O: |
156 | 0 | pkg_free( e->left.v.data ); break; |
157 | 0 | } |
158 | | /* ... and right */ |
159 | 0 | switch (e->right.type) { |
160 | 0 | case EXPR_ST: |
161 | 0 | free_expr( e->right.v.expr ); break; |
162 | 0 | case ACTIONS_ST: |
163 | 0 | free_action_list( (struct action*)e->right.v.data ); break; |
164 | 0 | case SCRIPTVAR_ST: |
165 | 0 | pkg_free( e->right.v.data ); break; |
166 | 0 | } |
167 | |
|
168 | 0 | } else if (e->type==EXP_T) { |
169 | | |
170 | | /* left ... */ |
171 | 0 | if (e->left.v.expr) |
172 | 0 | free_expr( e->left.v.expr ); |
173 | | /* ... and right */ |
174 | 0 | if (e->right.v.expr) |
175 | 0 | free_expr( e->right.v.expr ); |
176 | |
|
177 | 0 | } |
178 | | |
179 | 0 | pkg_free( e ); |
180 | 0 | } |
181 | | |
182 | | |
183 | | static void free_action_elem( action_elem_t *e ) |
184 | 0 | { |
185 | 0 | if (e->type==EXPR_ST) |
186 | 0 | free_expr( (struct expr*)e->u.data ); |
187 | 0 | else if (e->type==ACTIONS_ST) |
188 | 0 | free_action_list( (struct action*)e->u.data ); |
189 | 0 | else if (e->type==SCRIPTVAR_ST) |
190 | 0 | pkg_free(e->u.data); |
191 | 0 | else if (e->type==SCRIPTVAR_ELEM_ST) |
192 | 0 | pv_elem_free_all(e->u.data); |
193 | 0 | } |
194 | | |
195 | | |
196 | | void free_action_list( struct action *a) |
197 | 0 | { |
198 | 0 | int i; |
199 | |
|
200 | 0 | if (a==NULL) |
201 | 0 | return; |
202 | | |
203 | 0 | if (a->type==ASYNC_T || a->type==LAUNCH_T) |
204 | | /* unref the resume route */ |
205 | 0 | unref_script_route |
206 | 0 | ( (struct script_route_ref*)(a->elem[1].u.data) ); |
207 | |
|
208 | 0 | for( i=0 ; i<MAX_ACTION_ELEMS ; i++) { |
209 | 0 | if (a->elem[i].type) |
210 | 0 | free_action_elem( &a->elem[i] ); |
211 | 0 | } |
212 | |
|
213 | 0 | if (a->next) |
214 | 0 | free_action_list(a->next); |
215 | |
|
216 | 0 | pkg_free(a); |
217 | 0 | } |
218 | | |
219 | | |
220 | | |
221 | | void print_expr(struct expr* exp) |
222 | 0 | { |
223 | 0 | if (exp==0){ |
224 | 0 | LM_CRIT("null expression!\n"); |
225 | 0 | return; |
226 | 0 | } |
227 | 0 | if (exp->type==ELEM_T){ |
228 | 0 | switch(exp->left.type){ |
229 | 0 | case SCRIPTVAR_O: |
230 | 0 | LM_GEN1(L_DBG, "scriptvar[%d]", |
231 | 0 | (exp->left.v.spec)?exp->left.v.spec->type:0); |
232 | 0 | break; |
233 | 0 | case NUMBER_O: |
234 | 0 | case NUMBERV_O: |
235 | 0 | LM_GEN1(L_DBG, "%d",exp->left.v.n); |
236 | 0 | break; |
237 | 0 | case STRINGV_O: |
238 | 0 | LM_GEN1(L_DBG, "\"%s\"", ZSW((char*)exp->left.v.data)); |
239 | 0 | break; |
240 | 0 | case ACTION_O: |
241 | 0 | break; |
242 | 0 | case EXPR_O: |
243 | 0 | print_expr((struct expr*)exp->left.v.data); |
244 | 0 | break; |
245 | 0 | default: |
246 | 0 | LM_GEN1(L_DBG, "UNKNOWN[%d]", exp->left.type); |
247 | 0 | } |
248 | 0 | switch(exp->op){ |
249 | 0 | case EQUAL_OP: |
250 | 0 | LM_GEN1(L_DBG, "=="); |
251 | 0 | break; |
252 | 0 | case MATCHD_OP: |
253 | 0 | case MATCH_OP: |
254 | 0 | LM_GEN1(L_DBG, "=~"); |
255 | 0 | break; |
256 | 0 | case NOTMATCHD_OP: |
257 | 0 | case NOTMATCH_OP: |
258 | 0 | LM_GEN1(L_DBG, "!~"); |
259 | 0 | break; |
260 | 0 | case GT_OP: |
261 | 0 | LM_GEN1(L_DBG, ">"); |
262 | 0 | break; |
263 | 0 | case GTE_OP: |
264 | 0 | LM_GEN1(L_DBG, ">="); |
265 | 0 | break; |
266 | 0 | case LT_OP: |
267 | 0 | LM_GEN1(L_DBG, "<"); |
268 | 0 | break; |
269 | 0 | case LTE_OP: |
270 | 0 | LM_GEN1(L_DBG, "<="); |
271 | 0 | break; |
272 | 0 | case DIFF_OP: |
273 | 0 | LM_GEN1(L_DBG, "!="); |
274 | 0 | break; |
275 | 0 | case PLUS_OP: |
276 | 0 | LM_GEN1(L_DBG, "+"); |
277 | 0 | break; |
278 | 0 | case MINUS_OP: |
279 | 0 | LM_GEN1(L_DBG, "-"); |
280 | 0 | break; |
281 | 0 | case DIV_OP: |
282 | 0 | LM_GEN1(L_DBG, "/"); |
283 | 0 | break; |
284 | 0 | case MULT_OP: |
285 | 0 | LM_GEN1(L_DBG, "*"); |
286 | 0 | break; |
287 | 0 | case MODULO_OP: |
288 | 0 | LM_GEN1(L_DBG, " mod "); |
289 | 0 | break; |
290 | 0 | case BAND_OP: |
291 | 0 | LM_GEN1(L_DBG, "&"); |
292 | 0 | break; |
293 | 0 | case BOR_OP: |
294 | 0 | LM_GEN1(L_DBG, "|"); |
295 | 0 | break; |
296 | 0 | case BXOR_OP: |
297 | 0 | LM_GEN1(L_DBG, "^"); |
298 | 0 | break; |
299 | 0 | case BLSHIFT_OP: |
300 | 0 | LM_GEN1(L_DBG, "<<"); |
301 | 0 | break; |
302 | 0 | case BRSHIFT_OP: |
303 | 0 | LM_GEN1(L_DBG, ">>"); |
304 | 0 | break; |
305 | 0 | case BNOT_OP: |
306 | 0 | LM_GEN1(L_DBG, "~"); |
307 | 0 | break; |
308 | 0 | case VALUE_OP: |
309 | 0 | case NO_OP: |
310 | 0 | break; |
311 | 0 | default: |
312 | 0 | LM_GEN1(L_DBG, "<UNKNOWN[%d]>", exp->op); |
313 | 0 | } |
314 | 0 | switch(exp->right.type){ |
315 | 0 | case NOSUBTYPE: |
316 | | /* LM_GEN1(L_DBG, "N/A"); */ |
317 | 0 | break; |
318 | 0 | case STRING_ST: |
319 | 0 | LM_GEN1(L_DBG, "\"%s\"", ZSW((char*)exp->right.v.data)); |
320 | 0 | break; |
321 | 0 | case NET_ST: |
322 | 0 | print_net((struct net*)exp->right.v.data); |
323 | 0 | break; |
324 | 0 | case IP_ST: |
325 | 0 | print_ip("", (struct ip_addr*)exp->right.v.data, ""); |
326 | 0 | break; |
327 | 0 | case ACTIONS_ST: |
328 | 0 | print_actions((struct action*)exp->right.v.data); |
329 | 0 | break; |
330 | 0 | case NUMBER_ST: |
331 | 0 | LM_GEN1(L_DBG, "%d",exp->right.v.n); |
332 | 0 | break; |
333 | 0 | case SCRIPTVAR_ST: |
334 | 0 | LM_GEN1(L_DBG, "scriptvar[%d]", exp->right.v.spec->type); |
335 | 0 | break; |
336 | 0 | case NULLV_ST: |
337 | 0 | LM_GEN1(L_DBG, "null"); |
338 | 0 | break; |
339 | 0 | case EXPR_ST: |
340 | 0 | print_expr((struct expr*)exp->right.v.data); |
341 | 0 | break; |
342 | 0 | default: |
343 | 0 | LM_GEN1(L_DBG, "type<%d>", exp->right.type); |
344 | 0 | } |
345 | 0 | }else if (exp->type==EXP_T){ |
346 | 0 | switch(exp->op){ |
347 | 0 | case AND_OP: |
348 | 0 | LM_GEN1(L_DBG, "AND( "); |
349 | 0 | print_expr(exp->left.v.expr); |
350 | 0 | LM_GEN1(L_DBG, ", "); |
351 | 0 | print_expr(exp->right.v.expr); |
352 | 0 | LM_GEN1(L_DBG, " )"); |
353 | 0 | break; |
354 | 0 | case OR_OP: |
355 | 0 | LM_GEN1(L_DBG, "OR( "); |
356 | 0 | print_expr(exp->left.v.expr); |
357 | 0 | LM_GEN1(L_DBG, ", "); |
358 | 0 | print_expr(exp->right.v.expr); |
359 | 0 | LM_GEN1(L_DBG, " )"); |
360 | 0 | break; |
361 | 0 | case NOT_OP: |
362 | 0 | LM_GEN1(L_DBG, "NOT( "); |
363 | 0 | print_expr(exp->left.v.expr); |
364 | 0 | LM_GEN1(L_DBG, " )"); |
365 | 0 | break; |
366 | 0 | case EVAL_OP: |
367 | 0 | LM_GEN1(L_DBG, "EVAL( "); |
368 | 0 | print_expr(exp->left.v.expr); |
369 | 0 | LM_GEN1(L_DBG, " )"); |
370 | 0 | break; |
371 | 0 | case PLUS_OP: |
372 | 0 | LM_GEN1(L_DBG, "PLUS( "); |
373 | 0 | print_expr(exp->left.v.expr); |
374 | 0 | LM_GEN1(L_DBG, ", "); |
375 | 0 | print_expr(exp->right.v.expr); |
376 | 0 | LM_GEN1(L_DBG, " )"); |
377 | 0 | break; |
378 | 0 | case MINUS_OP: |
379 | 0 | LM_GEN1(L_DBG, "MINUS( "); |
380 | 0 | print_expr(exp->left.v.expr); |
381 | 0 | LM_GEN1(L_DBG, ", "); |
382 | 0 | print_expr(exp->right.v.expr); |
383 | 0 | LM_GEN1(L_DBG, " )"); |
384 | 0 | break; |
385 | 0 | case DIV_OP: |
386 | 0 | LM_GEN1(L_DBG, "DIV( "); |
387 | 0 | print_expr(exp->left.v.expr); |
388 | 0 | LM_GEN1(L_DBG, ", "); |
389 | 0 | print_expr(exp->right.v.expr); |
390 | 0 | LM_GEN1(L_DBG, " )"); |
391 | 0 | break; |
392 | 0 | case MULT_OP: |
393 | 0 | LM_GEN1(L_DBG, "MULT( "); |
394 | 0 | print_expr(exp->left.v.expr); |
395 | 0 | LM_GEN1(L_DBG, ", "); |
396 | 0 | print_expr(exp->right.v.expr); |
397 | 0 | LM_GEN1(L_DBG, " )"); |
398 | 0 | break; |
399 | 0 | case MODULO_OP: |
400 | 0 | LM_GEN1(L_DBG, "MODULO( "); |
401 | 0 | print_expr(exp->left.v.expr); |
402 | 0 | LM_GEN1(L_DBG, ", "); |
403 | 0 | print_expr(exp->right.v.expr); |
404 | 0 | LM_GEN1(L_DBG, " )"); |
405 | 0 | break; |
406 | 0 | case BAND_OP: |
407 | 0 | LM_GEN1(L_DBG, "BAND( "); |
408 | 0 | print_expr(exp->left.v.expr); |
409 | 0 | LM_GEN1(L_DBG, ", "); |
410 | 0 | print_expr(exp->right.v.expr); |
411 | 0 | LM_GEN1(L_DBG, " )"); |
412 | 0 | break; |
413 | 0 | case BOR_OP: |
414 | 0 | LM_GEN1(L_DBG, "BOR( "); |
415 | 0 | print_expr(exp->left.v.expr); |
416 | 0 | LM_GEN1(L_DBG, ", "); |
417 | 0 | print_expr(exp->right.v.expr); |
418 | 0 | LM_GEN1(L_DBG, " )"); |
419 | 0 | break; |
420 | 0 | case BXOR_OP: |
421 | 0 | LM_GEN1(L_DBG, "BXOR( "); |
422 | 0 | print_expr(exp->left.v.expr); |
423 | 0 | LM_GEN1(L_DBG, ", "); |
424 | 0 | print_expr(exp->right.v.expr); |
425 | 0 | LM_GEN1(L_DBG, " )"); |
426 | 0 | break; |
427 | 0 | case BLSHIFT_OP: |
428 | 0 | LM_GEN1(L_DBG, "BLSHIFT( "); |
429 | 0 | print_expr(exp->left.v.expr); |
430 | 0 | LM_GEN1(L_DBG, ", "); |
431 | 0 | print_expr(exp->right.v.expr); |
432 | 0 | LM_GEN1(L_DBG, " )"); |
433 | 0 | break; |
434 | 0 | case BRSHIFT_OP: |
435 | 0 | LM_GEN1(L_DBG, "BRSHIFT( "); |
436 | 0 | print_expr(exp->left.v.expr); |
437 | 0 | LM_GEN1(L_DBG, ", "); |
438 | 0 | print_expr(exp->right.v.expr); |
439 | 0 | LM_GEN1(L_DBG, " )"); |
440 | 0 | break; |
441 | 0 | case BNOT_OP: |
442 | 0 | LM_GEN1(L_DBG, "BNOT( "); |
443 | 0 | print_expr(exp->left.v.expr); |
444 | 0 | LM_GEN1(L_DBG, " )"); |
445 | 0 | break; |
446 | 0 | default: |
447 | 0 | LM_GEN1(L_DBG, "UNKNOWN_EXP[%d] ", exp->op); |
448 | 0 | } |
449 | |
|
450 | 0 | }else{ |
451 | 0 | LM_ERR("unknown type\n"); |
452 | 0 | } |
453 | 0 | } |
454 | | |
455 | | |
456 | | void print_action(struct action* t) |
457 | 0 | { |
458 | 0 | switch(t->type){ |
459 | 0 | case ASSERT_T: |
460 | 0 | LM_GEN1(L_DBG, "assert("); |
461 | 0 | break; |
462 | 0 | case DROP_T: |
463 | 0 | LM_GEN1(L_DBG, "drop("); |
464 | 0 | break; |
465 | 0 | case LOG_T: |
466 | 0 | LM_GEN1(L_DBG, "log("); |
467 | 0 | break; |
468 | 0 | case ERROR_T: |
469 | 0 | LM_GEN1(L_DBG, "error("); |
470 | 0 | break; |
471 | 0 | case ROUTE_T: |
472 | 0 | LM_GEN1(L_DBG, "route("); |
473 | 0 | break; |
474 | 0 | case EXEC_T: |
475 | 0 | LM_GEN1(L_DBG, "exec("); |
476 | 0 | break; |
477 | 0 | case LEN_GT_T: |
478 | 0 | LM_GEN1(L_DBG, "len_gt("); |
479 | 0 | break; |
480 | 0 | case IF_T: |
481 | 0 | LM_GEN1(L_DBG, "if ("); |
482 | 0 | break; |
483 | 0 | case WHILE_T: |
484 | 0 | LM_GEN1(L_DBG, "while ("); |
485 | 0 | break; |
486 | 0 | case CMD_T: |
487 | 0 | LM_GEN1(L_DBG, " function_call("); |
488 | 0 | break; |
489 | 0 | case RETURN_T: |
490 | 0 | LM_GEN1(L_DBG, "return("); |
491 | 0 | break; |
492 | 0 | case EXIT_T: |
493 | 0 | LM_GEN1(L_DBG, "exit("); |
494 | 0 | break; |
495 | 0 | case SWITCH_T: |
496 | 0 | LM_GEN1(L_DBG, "switch("); |
497 | 0 | break; |
498 | 0 | case CASE_T: |
499 | 0 | LM_GEN1(L_DBG, "case("); |
500 | 0 | break; |
501 | 0 | case DEFAULT_T: |
502 | 0 | LM_GEN1(L_DBG, "default("); |
503 | 0 | break; |
504 | 0 | case BREAK_T: |
505 | 0 | LM_GEN1(L_DBG, "break("); |
506 | 0 | break; |
507 | 0 | case EQ_T: |
508 | 0 | LM_GEN1(L_DBG, "assign("); |
509 | 0 | break; |
510 | 0 | default: |
511 | 0 | LM_GEN1(L_DBG, "UNKNOWN("); |
512 | 0 | } |
513 | 0 | switch(t->elem[0].type){ |
514 | 0 | case STRING_ST: |
515 | 0 | LM_GEN1(L_DBG, "\"%s\"", ZSW(t->elem[0].u.string)); |
516 | 0 | break; |
517 | 0 | case NUMBER_ST: |
518 | 0 | LM_GEN1(L_DBG, "%lu",t->elem[0].u.number); |
519 | 0 | break; |
520 | 0 | case SCRIPTVAR_ST: |
521 | 0 | LM_GEN1(L_DBG, "scriptvar[%d]",t->elem[0].u.item->type); |
522 | 0 | break; |
523 | 0 | case IP_ST: |
524 | 0 | print_ip("", (struct ip_addr*)t->elem[0].u.data, ""); |
525 | 0 | break; |
526 | 0 | case EXPR_ST: |
527 | 0 | print_expr((struct expr*)t->elem[0].u.data); |
528 | 0 | break; |
529 | 0 | case ACTIONS_ST: |
530 | 0 | print_actions((struct action*)t->elem[0].u.data); |
531 | 0 | break; |
532 | 0 | case CMD_ST: |
533 | 0 | LM_GEN1(L_DBG, "f<%s>",((const cmd_export_t*)t->elem[0].u.data_const)->name); |
534 | 0 | break; |
535 | 0 | case SOCKID_ST: |
536 | 0 | LM_GEN1(L_DBG, "%d:%s:%d", |
537 | 0 | ((struct socket_id*)t->elem[0].u.data)->proto, |
538 | 0 | ZSW(((struct socket_id*)t->elem[0].u.data)->name), |
539 | 0 | ((struct socket_id*)t->elem[0].u.data)->port |
540 | 0 | ); |
541 | 0 | break; |
542 | 0 | default: |
543 | 0 | LM_GEN1(L_DBG, "type<%d>", t->elem[0].type); |
544 | 0 | } |
545 | 0 | if (t->type==IF_T) LM_GEN1(L_DBG, ") {"); |
546 | 0 | switch(t->elem[1].type){ |
547 | 0 | case NOSUBTYPE: |
548 | 0 | break; |
549 | 0 | case STRING_ST: |
550 | 0 | LM_GEN1(L_DBG, ", \"%s\"", ZSW(t->elem[1].u.string)); |
551 | 0 | break; |
552 | 0 | case NUMBER_ST: |
553 | 0 | LM_GEN1(L_DBG, ", %lu",t->elem[1].u.number); |
554 | 0 | break; |
555 | 0 | case EXPR_ST: |
556 | 0 | print_expr((struct expr*)t->elem[1].u.data); |
557 | 0 | break; |
558 | 0 | case ACTIONS_ST: |
559 | 0 | print_actions((struct action*)t->elem[1].u.data); |
560 | 0 | break; |
561 | 0 | case SOCKID_ST: |
562 | 0 | LM_GEN1(L_DBG, "%d:%s:%d", |
563 | 0 | ((struct socket_id*)t->elem[1].u.data)->proto, |
564 | 0 | ZSW(((struct socket_id*)t->elem[1].u.data)->name), |
565 | 0 | ((struct socket_id*)t->elem[1].u.data)->port |
566 | 0 | ); |
567 | 0 | break; |
568 | 0 | default: |
569 | 0 | LM_GEN1(L_DBG, ", type<%d>", t->elem[1].type); |
570 | 0 | } |
571 | 0 | if (t->type==IF_T && t->elem[2].type!=NOSUBTYPE) LM_GEN1(L_DBG, " } else { "); |
572 | 0 | switch(t->elem[2].type){ |
573 | 0 | case NOSUBTYPE: |
574 | 0 | break; |
575 | 0 | case STRING_ST: |
576 | 0 | LM_GEN1(L_DBG, ", \"%s\"", ZSW(t->elem[2].u.string)); |
577 | 0 | break; |
578 | 0 | case NUMBER_ST: |
579 | 0 | LM_GEN1(L_DBG, ", %lu",t->elem[2].u.number); |
580 | 0 | break; |
581 | 0 | case EXPR_ST: |
582 | 0 | print_expr((struct expr*)t->elem[2].u.data); |
583 | 0 | break; |
584 | 0 | case ACTIONS_ST: |
585 | 0 | print_actions((struct action*)t->elem[2].u.data); |
586 | 0 | break; |
587 | 0 | case SOCKID_ST: |
588 | 0 | LM_GEN1(L_DBG, "%d:%s:%d", |
589 | 0 | ((struct socket_id*)t->elem[2].u.data)->proto, |
590 | 0 | ZSW(((struct socket_id*)t->elem[2].u.data)->name), |
591 | 0 | ((struct socket_id*)t->elem[2].u.data)->port |
592 | 0 | ); |
593 | 0 | break; |
594 | 0 | default: |
595 | 0 | LM_GEN1(L_DBG, ", type<%d>", t->elem[2].type); |
596 | 0 | } |
597 | 0 | if (t->type==IF_T) LM_GEN1(L_DBG, "}; "); |
598 | 0 | else LM_GEN1(L_DBG, "); "); |
599 | |
|
600 | 0 | } |
601 | | |
602 | | void print_actions(struct action* a) |
603 | 0 | { |
604 | 0 | while(a) { |
605 | 0 | print_action(a); |
606 | 0 | a = a->next; |
607 | 0 | } |
608 | 0 | } |
609 | | |
610 | | |
611 | | static int is_mod_func_in_expr(struct expr *e, const char *name, int param_no) |
612 | 0 | { |
613 | 0 | if (e->type==ELEM_T) { |
614 | 0 | if (e->left.type==ACTION_O) |
615 | 0 | if (is_mod_func_used((struct action*)e->right.v.data,name,param_no)==1) |
616 | 0 | return 1; |
617 | 0 | } else if (e->type==EXP_T) { |
618 | 0 | if (e->left.v.expr && is_mod_func_in_expr(e->left.v.expr,name,param_no)==1) |
619 | 0 | return 1; |
620 | 0 | if (e->right.v.expr && is_mod_func_in_expr(e->right.v.expr,name,param_no)==1) |
621 | 0 | return 1; |
622 | 0 | } |
623 | 0 | return 0; |
624 | 0 | } |
625 | | |
626 | | |
627 | | int is_mod_func_used(struct action *a, const char *name, int param_no) |
628 | 0 | { |
629 | 0 | const cmd_export_t *cmd; |
630 | 0 | while(a) { |
631 | 0 | if (a->type==CMD_T) { |
632 | | /* first param is the name of the function */ |
633 | 0 | cmd = (const cmd_export_t*)a->elem[0].u.data_const; |
634 | 0 | if (strcasecmp(cmd->name, name)==0) { |
635 | 0 | if (param_no==-1 || |
636 | 0 | (a->elem[param_no].type != NOSUBTYPE && |
637 | 0 | a->elem[param_no].type != NULLV_ST)) { |
638 | 0 | LM_DBG("function %s found to be used in script\n",name); |
639 | 0 | return 1; |
640 | 0 | } |
641 | |
|
642 | 0 | } |
643 | 0 | } |
644 | | |
645 | | /* follow all leads from actions/expressions than may have |
646 | | * sub-blocks of instructions */ |
647 | 0 | if (a->elem[0].type==ACTIONS_ST) |
648 | 0 | if (is_mod_func_used((struct action*)a->elem[0].u.data, |
649 | 0 | name,param_no)==1) |
650 | 0 | return 1; |
651 | 0 | if (a->elem[0].type==EXPR_ST) |
652 | 0 | if (is_mod_func_in_expr((struct expr*)a->elem[0].u.data, |
653 | 0 | name,param_no)==1) |
654 | 0 | return 1; |
655 | | |
656 | 0 | if (a->elem[1].type==ACTIONS_ST) |
657 | 0 | if (is_mod_func_used((struct action*)a->elem[1].u.data, |
658 | 0 | name,param_no)==1) |
659 | 0 | return 1; |
660 | 0 | if (a->elem[1].type==EXPR_ST) |
661 | 0 | if (is_mod_func_in_expr((struct expr*)a->elem[1].u.data, |
662 | 0 | name,param_no)==1) |
663 | 0 | return 1; |
664 | | |
665 | 0 | if (a->elem[2].type==ACTIONS_ST) |
666 | 0 | if (is_mod_func_used((struct action*)a->elem[2].u.data, |
667 | 0 | name,param_no)==1) |
668 | 0 | return 1; |
669 | 0 | if (a->elem[2].type==EXPR_ST) |
670 | 0 | if (is_mod_func_in_expr((struct expr*)a->elem[2].u.data, |
671 | 0 | name,param_no)==1) |
672 | 0 | return 1; |
673 | | |
674 | 0 | a = a->next; |
675 | 0 | } |
676 | | |
677 | 0 | return 0; |
678 | 0 | } |
679 | | |
680 | | int is_mod_async_func_used(struct action *a, const char *name, int param_no) |
681 | 0 | { |
682 | 0 | const acmd_export_t *acmd; |
683 | |
|
684 | 0 | for (; a; a=a->next) { |
685 | 0 | if (a->type==ASYNC_T || a->type==LAUNCH_T) { |
686 | 0 | acmd = ((struct action *)(a->elem[0].u.data))->elem[0].u.data_const; |
687 | |
|
688 | 0 | if (strcasecmp(acmd->name, name)==0) { |
689 | 0 | if (param_no==-1 || |
690 | 0 | (((struct action *)(a->elem[0].u.data))->elem[param_no].type != NOSUBTYPE && |
691 | 0 | ((struct action *)(a->elem[0].u.data))->elem[param_no].type != NULLV_ST)) { |
692 | 0 | LM_DBG("function %s found to be used in script\n",name); |
693 | 0 | return 1; |
694 | 0 | } |
695 | |
|
696 | 0 | } |
697 | 0 | } |
698 | | |
699 | | /* follow all leads from actions than may have |
700 | | * sub-blocks of instructions */ |
701 | 0 | if (a->elem[0].type==ACTIONS_ST) |
702 | 0 | if (is_mod_async_func_used((struct action*)a->elem[0].u.data, |
703 | 0 | name,param_no)==1) |
704 | 0 | return 1; |
705 | | |
706 | 0 | if (a->elem[1].type==ACTIONS_ST) |
707 | 0 | if (is_mod_async_func_used((struct action*)a->elem[1].u.data, |
708 | 0 | name,param_no)==1) |
709 | 0 | return 1; |
710 | | |
711 | 0 | if (a->elem[2].type==ACTIONS_ST) |
712 | 0 | if (is_mod_async_func_used((struct action*)a->elem[2].u.data, |
713 | 0 | name,param_no)==1) |
714 | 0 | return 1; |
715 | 0 | } |
716 | | |
717 | 0 | return 0; |
718 | 0 | } |