Coverage Report

Created: 2025-07-18 06:32

/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
}