Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,1205 +0,0 @@
1
-/*
2
- * Copyright (C) 2001-2003 FhG Fokus
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- *
20
- */
21
-
22
-
23
-/*!
24
- * \file
25
- * \brief Kamailio core :: Attribute value pair handling (AVP)
26
- * \ingroup core
27
- * Module: \ref core
28
- */
29
-
30
-#include <assert.h>
31
-#include <ctype.h>
32
-#include <string.h>
33
-#include <stdlib.h>
34
-
35
-#include <stdio.h>
36
-
37
-#include "sr_module.h"
38
-#include "dprint.h"
39
-#include "str.h"
40
-#include "ut.h"
41
-#include "mem/shm_mem.h"
42
-#include "mem/mem.h"
43
-#include "usr_avp.h"
44
-
45
-enum idx {
46
-	IDX_FROM_URI = 0,
47
-	IDX_TO_URI,
48
-	IDX_FROM_USER,
49
-	IDX_TO_USER,
50
-	IDX_FROM_DOMAIN,
51
-	IDX_TO_DOMAIN,
52
-	IDX_MAX
53
-};
54
-
55
-
56
-struct avp_galias {
57
-	str alias;
58
-	struct avp_spec  avp;
59
-	struct avp_galias *next;
60
-};
61
-
62
-static struct avp_galias *galiases = 0;
63
-
64
-static avp_list_t def_list[IDX_MAX];    /* Default AVP lists */
65
-static avp_list_t* crt_list[IDX_MAX];  /* Pointer to current AVP lists */
66
-
67
-/* Global AVP related variables go to shm mem */
68
-static avp_list_t* def_glist;
69
-static avp_list_t** crt_glist;
70
-
71
-/* AVP flags */
72
-int registered_avpflags_no = 0;
73
-static char *registered_avpflags[MAX_AVPFLAG];
74
-
75
-/* Initialize AVP lists in private memory and allocate memory
76
- * for shared lists
77
- */
78
-int init_avps(void)
79
-{
80
-	int i;
81
-	     /* Empty default lists */
82
-	memset(def_list, 0, sizeof(avp_list_t) * IDX_MAX);
83
-
84
-	     /* Point current pointers to default lists */
85
-	for(i = 0; i < IDX_MAX; i++) {
86
-		crt_list[i] = &def_list[i];
87
-	}
88
-
89
-	def_glist = (avp_list_t*)shm_malloc(sizeof(avp_list_t));
90
-	crt_glist = (avp_list_t**)shm_malloc(sizeof(avp_list_t*));
91
-	if (!def_glist || !crt_glist) {
92
-		LM_ERR("No memory to allocate default global AVP list\n");
93
-		return -1;
94
-	}
95
-	*def_glist = 0;
96
-	*crt_glist = def_glist;
97
-	return 0;
98
-}
99
-
100
-
101
-/*
102
- * Select active AVP list based on the value of flags
103
- */
104
-static avp_list_t* select_list(avp_flags_t flags)
105
-{
106
-	if (flags & AVP_CLASS_URI) {
107
-		if (flags & AVP_TRACK_TO) {
108
-			return crt_list[IDX_TO_URI];
109
-		} else {
110
-			return crt_list[IDX_FROM_URI];
111
-		}
112
-	} else if (flags & AVP_CLASS_USER) {
113
-		if (flags & AVP_TRACK_TO) {
114
-			return crt_list[IDX_TO_USER];
115
-		} else {
116
-			return crt_list[IDX_FROM_USER];
117
-		}
118
-	} else if (flags & AVP_CLASS_DOMAIN) {
119
-		if (flags & AVP_TRACK_TO) {
120
-			return crt_list[IDX_TO_DOMAIN];
121
-		} else {
122
-			return crt_list[IDX_FROM_DOMAIN];
123
-		}
124
-	} else if (flags & AVP_CLASS_GLOBAL) {
125
-		return *crt_glist;
126
-	}
127
-
128
-	return NULL;
129
-}
130
-
131
-inline static avp_id_t compute_ID( str *name )
132
-{
133
-	char *p;
134
-	avp_id_t id;
135
-
136
-	id=0;
137
-	for( p=name->s+name->len-1 ; p>=name->s ; p-- )
138
-		id ^= *p;
139
-	return id;
140
-}
141
-
142
-
143
-avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val)
144
-{
145
-	avp_t *avp;
146
-	str *s;
147
-	struct str_int_data *sid;
148
-	struct str_str_data *ssd;
149
-	int len;
150
-
151
-	if (name.s.s == 0 && name.s.len == 0) {
152
-		LM_ERR("0 ID or NULL NAME AVP!");
153
-		goto error;
154
-	}
155
-
156
-	/* compute the required mem size */
157
-	len = sizeof(struct usr_avp);
158
-	if (flags&AVP_NAME_STR) {
159
-		if ( name.s.s==0 || name.s.len==0) {
160
-			LM_ERR("EMPTY NAME AVP!");
161
-			goto error;
162
-		}
163
-		if (flags&AVP_VAL_STR) {
164
-			len += sizeof(struct str_str_data)-sizeof(union usr_avp_data)
165
-				+ name.s.len + 1 /* Terminating zero for regex search */
166
-				+ val.s.len + 1; /* Value is zero terminated */
167
-		} else {
168
-			len += sizeof(struct str_int_data)-sizeof(union usr_avp_data)
169
-				+ name.s.len + 1; /* Terminating zero for regex search */
170
-		}
171
-	} else if (flags&AVP_VAL_STR) {
172
-		len += sizeof(str)-sizeof(union usr_avp_data) + val.s.len + 1;
173
-	}
174
-
175
-	avp = (struct usr_avp*)shm_malloc( len );
176
-	if (avp==0) {
177
-		LM_ERR("no more shm mem\n");
178
-		return 0;
179
-	}
180
-
181
-	avp->flags = flags;
182
-	avp->id = (flags&AVP_NAME_STR)? compute_ID(&name.s) : name.n ;
183
-	avp->next = NULL;
184
-
185
-	switch ( flags&(AVP_NAME_STR|AVP_VAL_STR) )
186
-	{
187
-		case 0:
188
-			/* avp type ID, int value */
189
-			avp->d.l = val.n;
190
-			break;
191
-		case AVP_NAME_STR:
192
-			/* avp type str, int value */
193
-			sid = (struct str_int_data*)&avp->d.data[0];
194
-			sid->val = val.n;
195
-			sid->name.len =name.s.len;
196
-			sid->name.s = (char*)sid + sizeof(struct str_int_data);
197
-			memcpy( sid->name.s , name.s.s, name.s.len);
198
-			sid->name.s[name.s.len] = '\0'; /* Zero terminator */
199
-			break;
200
-		case AVP_VAL_STR:
201
-			/* avp type ID, str value */
202
-			s = (str*)&avp->d.data[0];
203
-			s->len = val.s.len;
204
-			s->s = (char*)s + sizeof(str);
205
-			memcpy( s->s, val.s.s , s->len);
206
-			s->s[s->len] = 0;
207
-			break;
208
-		case AVP_NAME_STR|AVP_VAL_STR:
209
-			/* avp type str, str value */
210
-			ssd = (struct str_str_data*)&avp->d.data[0];
211
-			ssd->name.len = name.s.len;
212
-			ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
213
-			memcpy( ssd->name.s , name.s.s, name.s.len);
214
-			ssd->name.s[name.s.len]='\0'; /* Zero terminator */
215
-			ssd->val.len = val.s.len;
216
-			ssd->val.s = ssd->name.s + ssd->name.len + 1;
217
-			memcpy( ssd->val.s , val.s.s, val.s.len);
218
-			ssd->val.s[ssd->val.len] = 0;
219
-			break;
220
-	}
221
-	return avp;
222
-error:
223
-	return 0;
224
-}
225
-
226
-int add_avp_list(avp_list_t* list, avp_flags_t flags, avp_name_t name, avp_value_t val)
227
-{
228
-	avp_t *avp;
229
-
230
-	assert(list != 0);
231
-
232
-	if ((avp = create_avp(flags, name, val))) {
233
-		avp->next = *list;
234
-		*list = avp;
235
-		return 0;
236
-	}
237
-
238
-	return -1;
239
-}
240
-
241
-
242
-int add_avp(avp_flags_t flags, avp_name_t name, avp_value_t val)
243
-{
244
-	avp_flags_t avp_class;
245
-	avp_list_t* list;
246
-
247
-	     /* Add avp to uri class if no class has been
248
-	      * specified by the caller
249
-	      */
250
-	if ((flags & AVP_CLASS_ALL) == 0) flags |= AVP_CLASS_URI;
251
-	if ((flags & AVP_TRACK_ALL) == 0) flags |= AVP_TRACK_FROM;
252
-	if (!(list = select_list(flags)))
253
-		return -1;
254
-
255
-	if (flags & AVP_CLASS_URI) avp_class = AVP_CLASS_URI;
256
-	else if (flags & AVP_CLASS_USER) avp_class = AVP_CLASS_USER;
257
-	else if (flags & AVP_CLASS_DOMAIN) avp_class = AVP_CLASS_DOMAIN;
258
-	else avp_class = AVP_CLASS_GLOBAL;
259
-
260
-	     /* Make that only the selected class is set
261
-	      * if the caller set more classes in flags
262
-	      */
263
-	return add_avp_list(list, flags & (~(AVP_CLASS_ALL) | avp_class), name, val);
264
-}
265
-
266
-int add_avp_before(avp_t *avp, avp_flags_t flags, avp_name_t name, avp_value_t val)
267
-{
268
-	avp_t *new_avp;
269
-
270
-	if (!avp) {
271
-		return add_avp(flags, name, val);
272
-	}
273
-
274
-	if ((flags & AVP_CLASS_ALL) == 0) flags |= (avp->flags & AVP_CLASS_ALL);
275
-	if ((flags & AVP_TRACK_ALL) == 0) flags |= (avp->flags & AVP_TRACK_ALL);
276
-
277
-	if ((avp->flags & (AVP_CLASS_ALL|AVP_TRACK_ALL)) != (flags & (AVP_CLASS_ALL|AVP_TRACK_ALL))) {
278
-		LM_ERR("Source and target AVPs have different CLASS/TRACK\n");
279
-		return -1;
280
-	}
281
-	if ((new_avp=create_avp(flags, name, val))) {
282
-		new_avp->next=avp->next;
283
-		avp->next=new_avp;
284
-		return 0;
285
-	}
286
-	return -1;
287
-}
288
-
289
-/* get value functions */
290
-inline str* get_avp_name(avp_t *avp)
291
-{
292
-	struct str_int_data *sid;
293
-	struct str_str_data *ssd;
294
-	
295
-	switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) )
296
-	{
297
-		case 0:
298
-			/* avp type ID, int value */
299
-		case AVP_VAL_STR:
300
-			/* avp type ID, str value */
301
-			return 0;
302
-		case AVP_NAME_STR:
303
-			/* avp type str, int value */
304
-			sid = (struct str_int_data*)&avp->d.data[0];
305
-			return &sid->name;
306
-		case AVP_NAME_STR|AVP_VAL_STR:
307
-			/* avp type str, str value */
308
-			ssd = (struct str_str_data*)&avp->d.data[0];
309
-			return &ssd->name;
310
-	}
311
-
312
-	LM_ERR("unknown avp type (name&val) %d\n", avp->flags&(AVP_NAME_STR|AVP_VAL_STR));
313
-	return 0;
314
-}
315
-
316
-
317
-inline void get_avp_val(avp_t *avp, avp_value_t *val)
318
-{
319
-	str *s;
320
-	struct str_int_data *sid;
321
-	struct str_str_data *ssd;
322
-	
323
-	if (avp==0 || val==0)
324
-		return;
325
-
326
-	switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) ) {
327
-		case 0:
328
-			/* avp type ID, int value */
329
-			val->n = avp->d.l;
330
-			break;
331
-		case AVP_NAME_STR:
332
-			/* avp type str, int value */
333
-			sid = (struct str_int_data*)&avp->d.data[0];
334
-			val->n = sid->val;
335
-			break;
336
-		case AVP_VAL_STR:
337
-			/* avp type ID, str value */
338
-			s = (str*)&avp->d.data[0];
339
-			val->s = *s;
340
-			break;
341
-		case AVP_NAME_STR|AVP_VAL_STR:
342
-			/* avp type str, str value */
343
-			ssd = (struct str_str_data*)&avp->d.data[0];
344
-			val->s = ssd->val;
345
-			break;
346
-	}
347
-}
348
-
349
-
350
-/* Return the current list of user attributes */
351
-avp_list_t get_avp_list(avp_flags_t flags)
352
-{
353
-	avp_list_t *list;
354
-
355
-	list = select_list(flags);
356
-	return (list ? *list : NULL);
357
-}
358
-
359
-
360
-/*
361
- * Compare given id with id in avp, return true if they match
362
- */
363
-static inline int match_by_id(avp_t* avp, avp_id_t id)
364
-{
365
-	if (avp->id == id && (avp->flags&AVP_NAME_STR)==0) {
366
-		return 1;
367
-	}
368
-	return 0;
369
-}
370
-
371
-
372
-/*
373
- * Compare given name with name in avp, return true if they are same
374
- */
375
-static inline int match_by_name(avp_t* avp, avp_id_t id, str* name)
376
-{
377
-	str* avp_name;
378
-	if (id==avp->id && avp->flags&AVP_NAME_STR &&
379
-	    (avp_name=get_avp_name(avp))!=0 && avp_name->len==name->len
380
-	    && !strncasecmp( avp_name->s, name->s, name->len) ) {
381
-		return 1;
382
-	}
383
-	return 0;
384
-}
385
-
386
-
387
-/*
388
- * Compare name with name in AVP using regular expressions, return
389
- * true if they match
390
- */
391
-static inline int match_by_re(avp_t* avp, regex_t* re)
392
-{
393
-	regmatch_t pmatch;
394
-	str * avp_name;
395
-	     /* AVP identifiable by name ? */
396
-	if (!(avp->flags&AVP_NAME_STR)) return 0;
397
-	if ((avp_name=get_avp_name(avp))==0) /* valid AVP name ? */
398
-		return 0;
399
-	if (!avp_name->s) /* AVP name validation */
400
-		return 0;
401
-	if (regexec(re, avp_name->s, 1, &pmatch,0)==0) { /* re match ? */
402
-		return 1;
403
-	}
404
-	return 0;
405
-}
406
-
407
-
408
-avp_t *search_first_avp(avp_flags_t flags, avp_name_t name, avp_value_t *val, struct search_state* s)
409
-{
410
-	avp_ident_t id;
411
-	id.flags = flags;
412
-	id.name = name;
413
-	id.index = 0;
414
-	return search_avp (id, val, s);
415
-}
416
-
417
-avp_t *search_avp (avp_ident_t ident, avp_value_t* val, struct search_state* state)
418
-{
419
-	avp_t* ret;
420
-	static struct search_state st;
421
-	avp_list_t* list;
422
-
423
-	if (ident.name.s.s==0 && ident.name.s.len == 0) {
424
-		LM_ERR("0 ID or NULL NAME AVP!");
425
-		return 0;
426
-	}
427
-
428
-	switch (ident.flags & AVP_INDEX_ALL) {
429
-		case AVP_INDEX_BACKWARD:
430
-		case AVP_INDEX_FORWARD:
431
-			WARN("AVP specified with index, but not used for search\n");
432
-			break;
433
-	}
434
-
435
-	if (!state) state = &st;
436
-
437
-	if ((ident.flags & AVP_CLASS_ALL) == 0) {
438
-		     /* The caller did not specify any class to search in, so enable
439
-		      * all of them by default
440
-		      */
441
-		ident.flags |= AVP_CLASS_ALL;
442
-
443
-		if ((ident.flags & AVP_TRACK_ALL) == 0) {
444
-		    /* The caller did not specify even the track to search in, so search
445
-		     * in the track_from
446
-		     */
447
-			ident.flags |= AVP_TRACK_FROM;
448
-		}
449
-	}
450
-
451
-	if (!(list = select_list(ident.flags)))
452
-		return NULL;
453
-
454
-	state->flags = ident.flags;
455
-	state->avp = *list;
456
-	state->name = ident.name;
457
-
458
-	if (ident.flags & AVP_NAME_STR) {
459
-		state->id = compute_ID(&ident.name.s);
460
-	}
461
-
462
-        ret = search_next_avp(state, val);
463
-
464
-	     /* Make sure that search next avp stays in the same class as the first
465
-	      * avp found
466
-	      */
467
-	if (state && ret) state->flags = (ident.flags & ~AVP_CLASS_ALL) | (ret->flags & AVP_CLASS_ALL);
468
-	return ret;
469
-}
470
-
471
-avp_t *search_next_avp(struct search_state* s, avp_value_t *val )
472
-{
473
-	int matched;
474
-	avp_t* avp;
475
-	avp_list_t *list;
476
-
477
-	if (s == 0) {
478
-		LM_ERR("Invalid parameter value\n");
479
-		return 0;
480
-	}
481
-
482
-	switch (s->flags & AVP_INDEX_ALL) {
483
-		case AVP_INDEX_BACKWARD:
484
-		case AVP_INDEX_FORWARD:
485
-			WARN("AVP specified with index, but not used for search\n");
486
-			break;
487
-	}
488
-
489
-	while(1) {
490
-		for( ; s->avp; s->avp = s->avp->next) {
491
-			if (s->flags & AVP_NAME_RE) {
492
-				matched = match_by_re(s->avp, s->name.re);
493
-			} else if (s->flags & AVP_NAME_STR) {
494
-				matched = match_by_name(s->avp, s->id, &s->name.s);
495
-			} else {
496
-				matched = match_by_id(s->avp, s->name.n);
497
-			}
498
-			if (matched) {
499
-				avp = s->avp;
500
-				s->avp = s->avp->next;
501
-				if (val) get_avp_val(avp, val);
502
-				return avp;
503
-			}
504
-		}
505
-
506
-		if (s->flags & AVP_CLASS_URI) {
507
-			s->flags &= ~AVP_CLASS_URI;
508
-			list = select_list(s->flags);
509
-		} else if (s->flags & AVP_CLASS_USER) {
510
-			s->flags &= ~AVP_CLASS_USER;
511
-			list = select_list(s->flags);
512
-		} else if (s->flags & AVP_CLASS_DOMAIN) {
513
-			s->flags &= ~AVP_CLASS_DOMAIN;
514
-			list = select_list(s->flags);
515
-		} else {
516
-			s->flags &= ~AVP_CLASS_GLOBAL;
517
-			return 0;
518
-		}
519
-		if (!list) return 0;
520
-		s->avp = *list;
521
-	}
522
-
523
-	return 0;
524
-}
525
-
526
-int search_reverse( avp_t *cur, struct search_state* st,
527
-                     avp_index_t index, avp_list_t *ret)
528
-{
529
-	avp_index_t lvl;
530
-
531
-	if (!cur)
532
-		return 0;
533
-	lvl = search_reverse(search_next_avp(st, NULL), st, index, ret)+1;
534
-	if (index==lvl)
535
-		*ret=cur;
536
-	return lvl;
537
-}
538
-
539
-avp_t *search_avp_by_index( avp_flags_t flags, avp_name_t name,
540
-                            avp_value_t *val, avp_index_t index)
541
-{
542
-	avp_t *ret, *cur;
543
-	struct search_state st;
544
-
545
-	if (flags & AVP_NAME_RE) {
546
-		BUG("search_by_index not supported for AVP_NAME_RE\n");
547
-		return 0;
548
-	}
549
-	switch (flags & AVP_INDEX_ALL) {
550
-		case 0:
551
-			ret = search_first_avp(flags, name, val, &st);
552
-			if (!ret || search_next_avp(&st, NULL))
553
-				return 0;
554
-			else
555
-				return ret;
556
-		case AVP_INDEX_ALL:
557
-			BUG("search_by_index not supported for anonymous index []\n");
558
-			return 0;
559
-		case AVP_INDEX_FORWARD:
560
-			ret = NULL;
561
-			cur = search_first_avp(flags & ~AVP_INDEX_ALL, name, NULL, &st);
562
-			search_reverse(cur, &st, index, &ret);
563
-			if (ret && val)
564
-				get_avp_val(ret, val);
565
-			return ret;
566
-		case AVP_INDEX_BACKWARD:
567
-			ret = search_first_avp(flags & ~AVP_INDEX_ALL, name, val, &st);
568
-			for (index--; (ret && index); ret=search_next_avp(&st, val), index--);
569
-			return ret;
570
-	}
571
-
572
-	return 0;
573
-}
574
-
575
-/* FIXME */
576
-/********* free functions ********/
577
-
578
-void destroy_avp(avp_t *avp_del)
579
-{
580
-	int i;
581
-	avp_t *avp, *avp_prev;
582
-
583
-	for (i = 0; i < IDX_MAX; i++) {
584
-		for( avp_prev=0,avp=*crt_list[i] ; avp ;
585
-		     avp_prev=avp,avp=avp->next ) {
586
-			if (avp==avp_del) {
587
-				if (avp_prev) {
588
-					avp_prev->next=avp->next;
589
-				} else {
590
-					*crt_list[i] = avp->next;
591
-				}
592
-				shm_free(avp);
593
-				return;
594
-			}
595
-		}
596
-	}
597
-
598
-	for( avp_prev=0,avp=**crt_glist ; avp ;
599
-	     avp_prev=avp,avp=avp->next ) {
600
-		if (avp==avp_del) {
601
-			if (avp_prev) {
602
-				avp_prev->next=avp->next;
603
-			} else {
604
-				**crt_glist = avp->next;
605
-			}
606
-			shm_free(avp);
607
-			return;
608
-		}
609
-	}
610
-}
611
-
612
-
613
-void destroy_avp_list_unsafe(avp_list_t* list)
614
-{
615
-	avp_t *avp, *foo;
616
-
617
-	avp = *list;
618
-	while( avp ) {
619
-		foo = avp;
620
-		avp = avp->next;
621
-		shm_free_unsafe( foo );
622
-	}
623
-	*list = 0;
624
-}
625
-
626
-
627
-inline void destroy_avp_list(avp_list_t* list)
628
-{
629
-	avp_t *avp, *foo;
630
-
631
-	LM_DBG("destroying list %p\n", *list);
632
-	avp = *list;
633
-	while( avp ) {
634
-		foo = avp;
635
-		avp = avp->next;
636
-		shm_free( foo );
637
-	}
638
-	*list = 0;
639
-}
640
-
641
-int reset_avp_list(int flags)
642
-{
643
-    int i;
644
-    if (flags & AVP_CLASS_URI) {
645
-	if (flags & AVP_TRACK_FROM) i = IDX_FROM_URI;
646
-	else i = IDX_TO_URI;
647
-    } else if (flags & AVP_CLASS_USER) {
648
-	if (flags & AVP_TRACK_FROM) i = IDX_FROM_USER;
649
-	else i = IDX_TO_USER;
650
-    } else if (flags & AVP_CLASS_DOMAIN) {
651
-	if (flags & AVP_TRACK_FROM) i = IDX_FROM_DOMAIN;
652
-	else i = IDX_TO_DOMAIN;
653
-    } else return -1;
654
-
655
-    crt_list[i] = &def_list[i];
656
-    destroy_avp_list(crt_list[i]);
657
-    return 0;
658
-}
659
-
660
-void reset_avps(void)
661
-{
662
-	int i;
663
-	for(i = 0; i < IDX_MAX; i++) {
664
-		crt_list[i] = &def_list[i];
665
-		destroy_avp_list(crt_list[i]);
666
-	}
667
-}
668
-
669
-
670
-avp_list_t* set_avp_list( avp_flags_t flags, avp_list_t* list )
671
-{
672
-	avp_list_t* prev;
673
-
674
-	if (flags & AVP_CLASS_URI) {
675
-		if (flags & AVP_TRACK_FROM) {
676
-			prev = crt_list[IDX_FROM_URI];
677
-			crt_list[IDX_FROM_URI] = list;
678
-		} else {
679
-			prev = crt_list[IDX_TO_URI];
680
-			crt_list[IDX_TO_URI] = list;
681
-		}
682
-	} else if (flags & AVP_CLASS_USER) {
683
-		if (flags & AVP_TRACK_FROM) {
684
-			prev = crt_list[IDX_FROM_USER];
685
-			crt_list[IDX_FROM_USER] = list;
686
-		} else {
687
-			prev = crt_list[IDX_TO_USER];
688
-			crt_list[IDX_TO_USER] = list;
689
-		}
690
-	} else if (flags & AVP_CLASS_DOMAIN) {
691
-		if (flags & AVP_TRACK_FROM) {
692
-			prev = crt_list[IDX_FROM_DOMAIN];
693
-			crt_list[IDX_FROM_DOMAIN] = list;
694
-		} else {
695
-			prev = crt_list[IDX_TO_DOMAIN];
696
-			crt_list[IDX_TO_DOMAIN] = list;
697
-		}
698
-	} else {
699
-		prev = *crt_glist;
700
-	        *crt_glist = list;
701
-	}
702
-
703
-	return prev;
704
-}
705
-
706
-
707
-/********* global aliases functions ********/
708
-
709
-static inline int check_avp_galias(str *alias, int type, int_str avp_name)
710
-{
711
-	struct avp_galias *ga;
712
-
713
-	type &= AVP_NAME_STR;
714
-
715
-	for( ga=galiases ; ga ; ga=ga->next ) {
716
-		/* check for duplicated alias names */
717
-		if ( alias->len==ga->alias.len &&
718
-		(strncasecmp( alias->s, ga->alias.s, alias->len)==0) )
719
-			return -1;
720
-		/*check for duplicated avp names */
721
-		if (type==ga->avp.type) {
722
-			if (type&AVP_NAME_STR){
723
-				if (avp_name.s.len==ga->avp.name.s.len &&
724
-				    (strncasecmp(avp_name.s.s, ga->avp.name.s.s,
725
-						 avp_name.s.len)==0) )
726
-					return -1;
727
-			} else {
728
-				if (avp_name.n==ga->avp.name.n)
729
-					return -1;
730
-			}
731
-		}
732
-	}
733
-	return 0;
734
-}
735
-
736
-
737
-int add_avp_galias(str *alias, int type, int_str avp_name)
738
-{
739
-	struct avp_galias *ga;
740
-
741
-	if ((type&AVP_NAME_STR && (!avp_name.s.s ||
742
-				   !avp_name.s.len)) ||!alias || !alias->s ||
743
-		!alias->len ){
744
-		LM_ERR("null params received\n");
745
-		goto error;
746
-	}
747
-
748
-	if (check_avp_galias(alias,type,avp_name)!=0) {
749
-		LM_ERR("duplicate alias/avp entry\n");
750
-		goto error;
751
-	}
752
-
753
-	ga = (struct avp_galias*)pkg_malloc( sizeof(struct avp_galias) );
754
-	if (ga==0) {
755
-		LM_ERR("no more pkg memory\n");
756
-		goto error;
757
-	}
758
-
759
-	ga->alias.s = (char*)pkg_malloc( alias->len+1 );
760
-	if (ga->alias.s==0) {
761
-		LM_ERR("no more pkg memory\n");
762
-		goto error1;
763
-	}
764
-	memcpy( ga->alias.s, alias->s, alias->len);
765
-	ga->alias.len = alias->len;
766
-
767
-	ga->avp.type = type&AVP_NAME_STR;
768
-
769
-	if (type&AVP_NAME_STR) {
770
-		ga->avp.name.s.s = (char*)pkg_malloc( avp_name.s.len+1 );
771
-		if (ga->avp.name.s.s==0) {
772
-			LM_ERR("no more pkg memory\n");
773
-			goto error2;
774
-		}
775
-		ga->avp.name.s.len = avp_name.s.len;
776
-		memcpy( ga->avp.name.s.s, avp_name.s.s, avp_name.s.len);
777
-		ga->avp.name.s.s[avp_name.s.len] = 0;
778
-		LM_DBG("registering <%s> for avp name <%s>\n",
779
-			ga->alias.s, ga->avp.name.s.s);
780
-	} else {
781
-		ga->avp.name.n = avp_name.n;
782
-		LM_DBG("registering <%s> for avp id <%d>\n",
783
-			ga->alias.s, ga->avp.name.n);
784
-	}
785
-
786
-	ga->next = galiases;
787
-	galiases = ga;
788
-
789
-	return 0;
790
-error2:
791
-	pkg_free(ga->alias.s);
792
-error1:
793
-	pkg_free(ga);
794
-error:
795
-	return -1;
796
-}
797
-
798
-
799
-int lookup_avp_galias(str *alias, int *type, int_str *avp_name)
800
-{
801
-	struct avp_galias *ga;
802
-
803
-	for( ga=galiases ; ga ; ga=ga->next )
804
-		if (alias->len==ga->alias.len &&
805
-		(strncasecmp( alias->s, ga->alias.s, alias->len)==0) ) {
806
-			*type = ga->avp.type;
807
-			*avp_name = ga->avp.name;
808
-			return 0;
809
-		}
810
-
811
-	return -1;
812
-}
813
-
814
-
815
-/* parsing functions */
816
-#define ERR_IF_CONTAINS(name,chr) \
817
-	if (memchr(name->s,chr,name->len)) { \
818
-		LM_ERR("Unexpected control character '%c' in AVP name\n", chr); \
819
-		goto error; \
820
-	}
821
-
822
-int parse_avp_name( str *name, int *type, int_str *avp_name, int *index)
823
-{
824
-	int ret;
825
-	avp_ident_t attr;
826
-
827
-	ret=parse_avp_ident(name, &attr);
828
-	if (!ret) {
829
-		if (type) *type = attr.flags;
830
-		if (avp_name) *avp_name = attr.name;
831
-		if (index) *index = attr.index;
832
-	}
833
-	return ret;
834
-}
835
-
836
-
837
-/** parse an avp indentifier.
838
- *
839
- * Parses the following avp indentifier forms:
840
- *       - "i:<number>"  - old form, deprecated  (e.g. i:42)
841
- *       - "s:<string>"  - old form, deprecated  (e.g. s:foo)
842
- *       - "<track>.<name>"                      (e.g.: f.bar)
843
- *       - "<track>.<name>[<index>]"             (e.g.: f.bar[1])
844
- *       - "<track><class>.<name>"               (e.g:  tu.bar)
845
- *       - "<track><class>.<name>[<index>]"      (e.g:  fd.bar[2])
846
- *       - "<string>"                            (e.g.: foo)
847
- * Where:
848
- *          \<string\> = ascii string
849
- *          \<id\>   = ascii string w/o '[', ']', '.' and '/'
850
- *          \<name\> = \<id\> | '/' regex '/'
851
- *                   (Note: regex use is deprecated)
852
- *          \<track\> = 'f' | 't'
853
- *                   (from or to)
854
- *          \<class\> = 'r' | 'u' | 'd' | 'g'
855
- *                    (uri, user, domain or global)
856
- *          \<index\> = \<number\> | '-' \<number\> | ''
857
- *                    (the avp index, if missing it means AVP_INDEX_ALL, but
858
- *                     it's use is deprecated)
859
- * More examples:
860
- *       "fr.bar[1]"  - from track, uri class, avp "bar", the value 1.
861
- *       "tu./^foo/"  - to track,  user class, all avps for which the name
862
- *                      starts with foo (note RE in avp names are deprecated).
863
- *        "t.did"     - to track, "did" avp
864
- *
865
- * @param name  - avp identifier
866
- * @param *attr - the result will be stored here
867
- * @return 0 on success, -1 on error
868
- */
869
-int parse_avp_ident( str *name, avp_ident_t* attr)
870
-{
871
-	unsigned int id;
872
-	char c;
873
-	char *p;
874
-	str s;
875
-
876
-	if (name==0 || name->s==0 || name->len==0) {
877
-		LM_ERR("NULL name or name->s or name->len\n");
878
-		goto error;
879
-	}
880
-
881
-	attr->index = 0;
882
-	LM_DBG("Parsing '%.*s'\n", name->len, name->s);
883
-	if (name->len>=2 && name->s[1]==':') { /* old fashion i: or s: */
884
-	        /* WARN("i: and s: avp name syntax is deprecated!\n"); */
885
-		c = name->s[0];
886
-		name->s += 2;
887
-		name->len -= 2;
888
-		if (name->len==0)
889
-			goto error;
890
-		switch (c) {
891
-			case 's': case 'S':
892
-				attr->flags = AVP_NAME_STR;
893
-				attr->name.s = *name;
894
-				break;
895
-			case 'i': case 'I':
896
-				attr->flags = 0;
897
-				if (str2int( name, &id)!=0) {
898
-					LM_ERR("invalid ID <%.*s> - not a number\n",
899
-						name->len, name->s);
900
-					goto error;
901
-				}
902
-				attr->name.n = (int)id;
903
-				break;
904
-			default:
905
-				LM_ERR("unsupported type [%c]\n", c);
906
-				goto error;