1 /*
2  * Copyright (C) 2008 iptelorg GmbH
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /*!
18  * \file
19  * \brief Kamailio core :: kamailio compatible fixups
20  * \ingroup core
21  * Module: \ref core
22  */
23 
24 #include "mod_fix.h"
25 #include "mem/mem.h"
26 #include "trim.h"
27 
28 
29 
30 #if 0
31 /* TODO: */
32 int fixup_regexpNL_null(void** param, int param_no); /* not used */
33 int fixup_regexpNL_none(void** param, int param_no); /* textops */
34 #endif
35 
36 
37 
38 #define FREE_FIXUP_FP(suffix, minp, maxp) \
39 	int fixup_free_##suffix(void** param, int param_no) \
40 	{ \
41 		if ((param_no > (maxp)) || (param_no < (minp))) \
42 			return E_UNSPEC; \
43 		if (*param) \
44 			fparam_free_restore(param); \
45 		return 0; \
46 	}
47 
48 
49 /** macro for declaring a fixup and the corresponding free_fixup
50   * for a function which fixes to fparam_t and expects 2 different types.
51   *
52   * The result (in *param) will be a fparam_t.
53   *
54   * @param suffix - function suffix (fixup_ will be pre-pended to it
55   * @param minp - minimum parameter number acceptable
56   * @param maxp - maximum parameter number
57   * @param no1 -  number of parameters of type1
58   * @param type1 - fix_param type for the 1st param
59   * @param type2 - fix_param type for all the other params
60   */
61 #define FIXUP_F2FP(suffix, minp, maxp, no1, type1, type2) \
62 	int fixup_##suffix (void** param, int param_no) \
63 	{ \
64 		if ((param_no > (maxp)) || (param_no <(minp))) \
65 			return E_UNSPEC; \
66 		if (param_no <= (no1)){ \
67 			if (fix_param_types((type1), param)!=0) {\
68 				ERR("Cannot convert function parameter %d to" #type1 "\n", \
69 						param_no);\
70 				return E_UNSPEC; \
71 			} \
72 		}else{ \
73 			if (fix_param_types((type2), param)!=0) {\
74 				ERR("Cannot convert function parameter %d to" #type2 "\n", \
75 						param_no); \
76 				return E_UNSPEC; \
77 			} \
78 		}\
79 		return 0; \
80 	} \
81 	FREE_FIXUP_FP(suffix, minp, maxp)
82 
83 
84 /** macro for declaring a fixup and the corresponding free_fixup
85   * for a function which fixes directly to the requested type.
86   *
87   * @see FIXUP_F2FP for the parameters
88   * Side effect: declares also some _fp_helper functions
89   */
90 #define FIXUP_F2T(suffix, minp, maxp, no1, type1, type2) \
91 	FIXUP_F2FP(fp_##suffix, minp, maxp, no1, type1, type2) \
92 	int fixup_##suffix (void** param, int param_no) \
93 	{ \
94 		int ret; \
95 		if ((ret=fixup_fp_##suffix (param, param_no))!=0) \
96 			return ret; \
97 		*param=((fparam_t*)*param)->fixed; \
98 		return 0; \
99 	} \
100 	int fixup_free_##suffix (void** param, int param_no) \
101 	{ \
102 		void* p; \
103 		int ret; \
104 		if (param && *param){ \
105 			p=*param - (long)&((fparam_t*)0)->v; \
106 			if ((ret=fixup_free_fp_##suffix(&p, param_no))==0) *param=p; \
107 			return ret; \
108 		} \
109 		return 0; \
110 	}
111 
112 
113 /** macro for declaring a fixup and the corresponding free_fixup
114   * for a function expecting first no1 params as fparamt_t and the
115   * rest as direct type.
116   *
117   * @see FIXUP_F2FP for the parameters with the exception
118   * that only the first no1 parameters are converted to
119   * fparamt_t and the rest directly to the correponding type
120   *
121   * Side effect: declares also some _fpt_helper functions
122   */
123 #define FIXUP_F2FP_T(suffix, minp, maxp, no1, type1, type2) \
124 	FIXUP_F2FP(fpt_##suffix, minp, maxp, no1, type1, type2) \
125 	int fixup_##suffix (void** param, int param_no) \
126 	{ \
127 		int ret; \
128 		if ((ret=fixup_fpt_##suffix(param, param_no))!=0) \
129 			return ret; \
130 		if (param_no>(no1)) *param=&((fparam_t*)*param)->v; \
131 		return 0; \
132 	} \
133 	int fixup_free_##suffix (void** param, int param_no) \
134 	{ \
135 		void* p; \
136 		int ret; \
137 		if (param && *param){ \
138 			p=(param_no>(no1))? *param - (long)&((fparam_t*)0)->v : *param;\
139 			if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=p; \
140 			return ret; \
141 		} \
142 		return 0; \
143 	}
144 
145 
146 /** macro for declaring a fixup which fixes all the paremeters to the same
147   * type.
148   *
149   * @see FIXUP_F2T.
150   */
151 #define FIXUP_F1T(suffix, minp, maxp, type) \
152 	FIXUP_F2T(suffix, minp, maxp, maxp, type, 0)
153 
154 
155 
156 FIXUP_F1T(str_null, 1, 1, FPARAM_STR)
157 FIXUP_F1T(str_str, 1, 2,  FPARAM_STR)
158 FIXUP_F1T(str_all, 1, 100,  FPARAM_STR)
159 
160 /*
161   no free fixups possible for unit_*
162   (they overwrite the pointer with the converted number => the original
163    value cannot be recovered)
164 FIXUP_F1T(uint_null, 1, 1, FPARAM_INT)
165 FIXUP_F1T(uint_uint, 1, 2, FPARAM_INT)
166 */
167 
168 
169 
fixup_uint_uint(void ** param,int param_no)170 int fixup_uint_uint(void** param, int param_no)
171 {
172 	str s;
173 	unsigned int num;
174 
175 	s.s = *param;
176 	s.len = strlen(s.s);
177 	if (likely(str2int(&s, &num) == 0)) {
178 		*param = (void*)(long)num;
179 	} else
180 		/* not a number */
181 		return E_UNSPEC;
182 	return 0;
183 }
184 
185 
186 
fixup_uint_null(void ** param,int param_no)187 int fixup_uint_null(void** param, int param_no)
188 {
189 	if (param_no == 1)
190 		return fixup_uint_uint(param, param_no);
191 	return E_UNSPEC;
192 }
193 
194 
195 /* fixup_regexp_null() has to be written "by hand", since
196    it needs to save the original pointer (the fixup users expects
197    a pointer to the regex in *param and hence the original value
198    needed on free cannot be recovered directly).
199 FIXUP_F1T(regexp_null, 1, 1, FPARAM_REGEX)
200 */
201 
202 struct regex_fixup {
203 	regex_t regex; /* compiled regex */
204 	void* orig;    /* original pointer */
205 };
206 
fixup_regexp_null(void ** param,int param_no)207 int fixup_regexp_null(void** param, int param_no)
208 {
209 	struct regex_fixup* re;
210 
211 	if (param_no != 1)
212 		return E_UNSPEC;
213 	if ((re=pkg_malloc(sizeof(*re))) ==0) {
214 		PKG_MEM_ERROR;
215 		goto error;
216 	}
217 	if (regcomp(&re->regex, *param,
218 				REG_EXTENDED|REG_ICASE|REG_NEWLINE))
219 		goto error;
220 	re->orig = *param;
221 	*param = re;
222 	return 0;
223 error:
224 	if (re)
225 		pkg_free(re);
226 	return E_UNSPEC;
227 }
228 
fixup_regexp_regexp(void ** param,int param_no)229 int fixup_regexp_regexp(void** param, int param_no)
230 {
231 	return fixup_regexp_null(param, 1);
232 }
233 
fixup_free_regexp_null(void ** param,int param_no)234 int fixup_free_regexp_null(void** param, int param_no)
235 {
236 	struct regex_fixup* re;
237 
238 	if (param_no != 1)
239 		return E_UNSPEC;
240 	if (*param) {
241 		re = *param;
242 		*param = re->orig;
243 		regfree(&re->regex);
244 		pkg_free(re);
245 	}
246 	return 0;
247 }
248 
fixup_free_regexp_regexp(void ** param,int param_no)249 int fixup_free_regexp_regexp(void** param, int param_no)
250 {
251 	return fixup_free_regexp_null(param, 1);
252 }
253 
254 /* fixup_pvar_*() has to be written "by hand", since
255    it needs to save the original pointer (the fixup users expects
256    a pointer to the pv_spec_t in *param and hence the original value
257    needed on free cannot be recovered directly).
258 FIXUP_F1T(pvar_null, 1, 1, FPARAM_PVS)
259 FIXUP_F1T(pvar_pvar, 1, 2, FPARAM_PVS)
260 */
261 
262 typedef struct pvs_fixup {
263 	pv_spec_t pvs; /* parsed pv spec */
264 	void* orig;    /* original pointer */
265 } pvs_fixup_t;
266 
fixup_pvar_all(void ** param,int param_no)267 int fixup_pvar_all(void** param, int param_no)
268 {
269 	pvs_fixup_t* pvs_f;
270 	str name;
271 
272 	pvs_f = 0;
273 	name.s = *param;
274 	name.len = strlen(name.s);
275 	trim(&name);
276 	if (name.len == 0 || name.s[0] != '$')
277 		/* not a pvs id */
278 		goto error;
279 	if ((pvs_f=pkg_malloc(sizeof(*pvs_f))) == 0) {
280 		PKG_MEM_ERROR;
281 		goto error;
282 	}
283 	if (pv_parse_spec2(&name, &pvs_f->pvs, 1) == 0)
284 		/* not a valid pvs identifier */
285 		goto error;
286 	pvs_f->orig = *param;
287 	*param = pvs_f;
288 	return 0;
289 error:
290 	if (pvs_f)
291 		pkg_free(pvs_f);
292 	return E_UNSPEC;
293 }
294 
295 
296 
fixup_free_pvar_all(void ** param,int param_no)297 int fixup_free_pvar_all(void** param, int param_no)
298 {
299 	pvs_fixup_t* pvs_f;
300 
301 	if (*param) {
302 		pvs_f = *param;
303 		*param = pvs_f->orig;
304 		/* free only the contents (don't attempt to free &pvs_f->pvs)*/
305 		pv_spec_destroy(&pvs_f->pvs);
306 		/* free the whole pvs_fixup_t */
307 		pkg_free(pvs_f);
308 	}
309 	return 0;
310 }
311 
312 
313 
fixup_pvar_pvar(void ** param,int param_no)314 int fixup_pvar_pvar(void** param, int param_no)
315 {
316 	if (param_no > 2)
317 		return E_UNSPEC;
318 	return fixup_pvar_all(param, param_no);
319 }
320 
321 
322 
fixup_free_pvar_pvar(void ** param,int param_no)323 int fixup_free_pvar_pvar(void** param, int param_no)
324 {
325 	if (param_no > 2)
326 		return E_UNSPEC;
327 	return fixup_free_pvar_all(param, param_no);
328 }
329 
330 
fixup_pvar_pvar_pvar(void ** param,int param_no)331 int fixup_pvar_pvar_pvar(void** param, int param_no)
332 {
333 	if (param_no > 3)
334 		return E_UNSPEC;
335 	return fixup_pvar_all(param, param_no);
336 }
337 
fixup_free_pvar_pvar_pvar(void ** param,int param_no)338 int fixup_free_pvar_pvar_pvar(void** param, int param_no)
339 {
340 	if (param_no > 3)
341 		return E_UNSPEC;
342 	return fixup_free_pvar_all(param, param_no);
343 }
344 
345 
fixup_pvar_null(void ** param,int param_no)346 int fixup_pvar_null(void** param, int param_no)
347 {
348 	if (param_no != 1)
349 		return E_UNSPEC;
350 	return fixup_pvar_all(param, param_no);
351 }
352 
353 
354 
fixup_free_pvar_null(void ** param,int param_no)355 int fixup_free_pvar_null(void** param, int param_no)
356 {
357 	if (param_no != 1)
358 		return E_UNSPEC;
359 	return fixup_free_pvar_all(param, param_no);
360 }
361 
fixup_pvar_none(void ** param,int param_no)362 int fixup_pvar_none(void** param, int param_no)
363 {
364 	if (param_no == 1)
365 		return fixup_pvar_all(param, param_no);
366 	return 0;
367 }
368 
369 
370 
fixup_free_pvar_none(void ** param,int param_no)371 int fixup_free_pvar_none(void** param, int param_no)
372 {
373 	if (param_no == 1)
374 		return fixup_free_pvar_all(param, param_no);
375 	return 0;
376 }
377 
378 
379 /* must be written "by hand", see above (fixup_pvar_pvar).
380 FIXUP_F2T(pvar_str, 1, 2, 1, FPARAM_PVS, FPARAM_STR)
381 FIXUP_F2T(pvar_str_str, 1, 3, 1, FPARAM_PVS, FPARAM_STR)
382 */
383 
fixup_pvar_str(void ** param,int param_no)384 int fixup_pvar_str(void** param, int param_no)
385 {
386 	if (param_no == 1)
387 		return fixup_pvar_all(param, param_no);
388 	else if (param_no == 2)
389 		return fixup_str_str(param, param_no);
390 	return E_UNSPEC;
391 }
392 
393 
394 
fixup_free_pvar_str(void ** param,int param_no)395 int fixup_free_pvar_str(void** param, int param_no)
396 {
397 	if (param_no == 1)
398 		return fixup_free_pvar_all(param, param_no);
399 	else if (param_no == 2)
400 		return fixup_free_str_str(param, param_no);
401 	return E_UNSPEC;
402 }
403 
404 
405 
fixup_pvar_str_str(void ** param,int param_no)406 int fixup_pvar_str_str(void** param, int param_no)
407 {
408 	if (param_no == 1)
409 		return fixup_pvar_all(param, param_no);
410 	else if (param_no == 2 || param_no == 3)
411 		return fixup_str_all(param, param_no);
412 	return E_UNSPEC;
413 }
414 
415 
416 
fixup_free_pvar_str_str(void ** param,int param_no)417 int fixup_free_pvar_str_str(void** param, int param_no)
418 {
419 	if (param_no == 1)
420 		return fixup_free_pvar_all(param, param_no);
421 	else if (param_no == 2 || param_no == 3)
422 		return fixup_free_str_all(param, param_no);
423 	return E_UNSPEC;
424 }
425 
426 
fixup_pvar_uint(void ** param,int param_no)427 int fixup_pvar_uint(void** param, int param_no)
428 {
429 	if (param_no == 1)
430 		return fixup_pvar_all(param, param_no);
431 	else if (param_no == 2)
432 		return fixup_uint_uint(param, param_no);
433 	return E_UNSPEC;
434 }
435 
436 
fixup_free_pvar_uint(void ** param,int param_no)437 int fixup_free_pvar_uint(void** param, int param_no)
438 {
439 	if (param_no == 1)
440 		return fixup_free_pvar_all(param, param_no);
441 	return E_UNSPEC;
442 }
443 
444 
445 FIXUP_F2FP(igp_null, 1, 1, 1, FPARAM_INT|FPARAM_PVS, 0)
446 FIXUP_F2FP(igp_igp, 1, 2, 2,  FPARAM_INT|FPARAM_PVS, 0)
447 
448 /* must be declared by hand, because of the pvar special handling
449    (see above)
450 FIXUP_F2FP(igp_pvar, 1, 2, 1,  FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
451 FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
452 */
453 
fixup_igp_pvar(void ** param,int param_no)454 int fixup_igp_pvar(void** param, int param_no)
455 {
456 	if (param_no == 1)
457 		return fixup_igp_null(param, param_no);
458 	else if (param_no == 2)
459 		return fixup_pvar_all(param, param_no);
460 	return E_UNSPEC;
461 }
462 
463 
fixup_free_igp_pvar(void ** param,int param_no)464 int fixup_free_igp_pvar(void** param, int param_no)
465 {
466 	if (param_no == 1)
467 		return fixup_free_igp_null(param, param_no);
468 	else if (param_no == 2)
469 		return fixup_free_pvar_all(param, param_no);
470 	return E_UNSPEC;
471 }
472 
473 
fixup_igp_pvar_pvar(void ** param,int param_no)474 int fixup_igp_pvar_pvar(void** param, int param_no)
475 {
476 	if (param_no == 1)
477 		return fixup_igp_null(param, param_no);
478 	else if (param_no == 2 || param_no == 3)
479 		return fixup_pvar_all(param, param_no);
480 	return E_UNSPEC;
481 }
482 
483 
fixup_free_igp_pvar_pvar(void ** param,int param_no)484 int fixup_free_igp_pvar_pvar(void** param, int param_no)
485 {
486 	if (param_no == 1)
487 		return fixup_free_igp_null(param, param_no);
488 	else if (param_no == 2 || param_no == 3)
489 		return fixup_free_pvar_all(param, param_no);
490 	return E_UNSPEC;
491 }
492 
493 
fixup_igp_spve(void ** param,int param_no)494 int fixup_igp_spve(void** param, int param_no)
495 {
496 	if (param_no == 1)
497 		return fixup_igp_null(param, param_no);
498 	else if (param_no == 2)
499 		return fixup_spve_all(param, param_no);
500 	return E_UNSPEC;
501 }
502 
503 
fixup_free_igp_spve(void ** param,int param_no)504 int fixup_free_igp_spve(void** param, int param_no)
505 {
506 	if (param_no == 1)
507 		return fixup_free_igp_null(param, param_no);
508 	else if (param_no == 2)
509 		return fixup_free_spve_all(param, param_no);
510 	return E_UNSPEC;
511 }
512 
513 
514 /** macro for declaring a spve fixup and the corresponding free_fixup
515   * for a function expecting first no1 params as fparam converted spve
516   * and the * rest as direct type.
517   *
518   * @see FIXUP_F2FP for the parameters with the exception
519   * that the first no1 parameters are converted to fparam_t from spve
520   * and the rest directly to the corresponding type
521   *
522   * Side effect: declares also some _spvet_helper functions
523   */
524 #define FIXUP_F_SPVE_T(suffix, minp, maxp, no1, type2) \
525 	FIXUP_F1T(spvet_##suffix, minp, maxp, type2) \
526 	int fixup_##suffix (void** param, int param_no) \
527 	{ \
528 		int ret; \
529 		fparam_t* fp; \
530 		if (param_no<=(no1)){ \
531 			if ((ret=fix_param_types(FPARAM_PVE, param))<0){ \
532 				ERR("Cannot convert function parameter %d to spve \n", \
533 						param_no);\
534 				return E_UNSPEC; \
535 			} else{ \
536 				fp=(fparam_t*)*param; \
537 				if ((ret==0) && (fp->v.pve->spec==0 \
538 							|| fp->v.pve->spec->getf==0)){ \
539 					fparam_free_restore(param); \
540 					return fix_param_types(FPARAM_STR, param); \
541 				} else if (ret==1) \
542 					return fix_param_types(FPARAM_STR, param); \
543 				return ret; \
544 			} \
545 		} else return fixup_spvet_##suffix(param, param_no); \
546 		return 0; \
547 	} \
548 	int fixup_free_##suffix (void** param, int param_no) \
549 	{ \
550 		if (param && *param){ \
551 			if (param_no<=(no1)) \
552 				fparam_free_restore(param); \
553 			else \
554 				return fixup_free_spvet_##suffix(param, param_no); \
555 		} \
556 		return 0; \
557 	}
558 
559 
560 /* format: name, minp, maxp, no_of_spve_params, type_for_rest_params */
561 FIXUP_F_SPVE_T(spve_spve, 1, 2, 2, 0)
562 FIXUP_F_SPVE_T(spve_uint, 1, 2, 1, FPARAM_INT)
563 FIXUP_F_SPVE_T(spve_str, 1, 2, 1, FPARAM_STR)
564 FIXUP_F_SPVE_T(spve_null, 1, 1, 1, 0)
565 
566 /** get the corresp. fixup_free* function.
567  * @param f -fixup function pointer.
568  * @return  - pointer to free_fixup function if known, 0 otherwise.
569  */
mod_fix_get_fixup_free(fixup_function f)570 free_fixup_function mod_fix_get_fixup_free(fixup_function f)
571 {
572 	if (f == fixup_str_null) return fixup_free_str_null;
573 	if (f == fixup_str_str) return fixup_free_str_str;
574 	/* no free fixup for fixup_uint_* (they overwrite the pointer
575 	   value with a number and the original value cannot be recovered) */
576 	if (f == fixup_uint_null) return 0;
577 	if (f == fixup_uint_uint) return 0;
578 	if (f == fixup_regexp_null) return fixup_free_regexp_null;
579 	if (f == fixup_pvar_null) return fixup_free_pvar_null;
580 	if (f == fixup_pvar_pvar) return fixup_free_pvar_pvar;
581 	if (f == fixup_pvar_str) return fixup_free_pvar_str;
582 	if (f == fixup_pvar_str_str) return fixup_free_pvar_str_str;
583 	if (f == fixup_igp_igp) return fixup_free_igp_igp;
584 	if (f == fixup_igp_null) return fixup_free_igp_null;
585 	if (f == fixup_igp_pvar) return fixup_free_igp_pvar;
586 	if (f == fixup_igp_pvar_pvar) return fixup_free_igp_pvar_pvar;
587 	if (f == fixup_spve_spve) return fixup_free_spve_spve;
588 	if (f == fixup_spve_null) return fixup_free_spve_null;
589 	/* no free fixup, because of the uint part (the uint cannot be freed,
590 	   see above fixup_uint_null) */
591 	if (f == fixup_spve_uint) return 0;
592 	if (f == fixup_spve_str) return fixup_free_spve_str;
593 	return 0;
594 }
595 
596 /**
597  *
598  */
fixup_spve_all(void ** param,int param_no)599 int fixup_spve_all(void** param, int param_no)
600 {
601 	return fixup_spve_null(param, 1);
602 }
603 
604 /**
605  *
606  */
fixup_free_spve_all(void ** param,int param_no)607 int fixup_free_spve_all(void** param, int param_no)
608 {
609 	return fixup_free_spve_null(param, 1);
610 }
611 
612 /**
613  *
614  */
fixup_igp_all(void ** param,int param_no)615 int fixup_igp_all(void** param, int param_no)
616 {
617 	return fixup_igp_null(param, 1);
618 }
619 
620 /**
621  *
622  */
fixup_free_igp_all(void ** param,int param_no)623 int fixup_free_igp_all(void** param, int param_no)
624 {
625 	return fixup_free_igp_null(param, 1);
626 }
627 
628 /**
629  *
630  */
fixup_spve_igp(void ** param,int param_no)631 int fixup_spve_igp(void** param, int param_no)
632 {
633 	if(param_no==1)
634 		return fixup_spve_null(param, 1);
635 	if(param_no==2)
636 		return fixup_igp_null(param, 1);
637 	return E_UNSPEC;
638 }
639 
640 /**
641  *
642  */
fixup_free_spve_igp(void ** param,int param_no)643 int fixup_free_spve_igp(void** param, int param_no)
644 {
645 	if(param_no==1)
646 		return fixup_free_spve_null(param, 1);
647 	if(param_no==2)
648 		return fixup_free_igp_null(param, 1);
649 	return E_UNSPEC;
650 }
651 
652 /**
653  *
654  */
fixup_spve_spve_igp(void ** param,int param_no)655 int fixup_spve_spve_igp(void** param, int param_no)
656 {
657 	if(param_no==1 || param_no==2)
658 		return fixup_spve_null(param, 1);
659 	if(param_no==3)
660 		return fixup_igp_null(param, 1);
661 	return E_UNSPEC;
662 }
663 
664 /**
665  *
666  */
fixup_free_spve_spve_igp(void ** param,int param_no)667 int fixup_free_spve_spve_igp(void** param, int param_no)
668 {
669 	if(param_no==1 || param_no==2)
670 		return fixup_free_spve_null(param, 1);
671 	if(param_no==3)
672 		return fixup_free_igp_null(param, 1);
673 	return E_UNSPEC;
674 }
675 
676 /**
677  *
678  */
fixup_spve_pvar(void ** param,int param_no)679 int fixup_spve_pvar(void** param, int param_no)
680 {
681 	if(param_no==1)
682 		return fixup_spve_null(param, 1);
683 	if(param_no==2)
684 		return fixup_pvar_null(param, 1);
685 	return E_UNSPEC;
686 }
687 
688 /**
689  *
690  */
fixup_free_spve_pvar(void ** param,int param_no)691 int fixup_free_spve_pvar(void** param, int param_no)
692 {
693 	if(param_no==1)
694 		return fixup_free_spve_null(param, 1);
695 	if(param_no==2)
696 		return fixup_free_pvar_null(param, 1);
697 	return E_UNSPEC;
698 }
699 
700 /**
701  *
702  */
fixup_none_spve(void ** param,int param_no)703 int fixup_none_spve(void** param, int param_no)
704 {
705 	if(param_no==2)
706 		return fixup_spve_null(param, 1);
707 	return 0;
708 }
709 
710 /**
711  *
712  */
fixup_free_none_spve(void ** param,int param_no)713 int fixup_free_none_spve(void** param, int param_no)
714 {
715 	if(param_no==2)
716 		return fixup_free_spve_null(param, 1);
717 	return 0;
718 }
719 
720 
721 /**
722  *
723  */
fixup_vstr_all(void ** param,int param_no)724 int fixup_vstr_all(void** param, int param_no)
725 {
726 	str s;
727 	pv_elem_t *xm;
728 
729 	s.s = (char*)(*param);
730 	s.len = strlen(s.s);
731 	if(pv_parse_format(&s, &xm)<0) {
732 		LM_ERR("invalid parameter format [%s]\n", (char*)(*param));
733 		return E_UNSPEC;
734 	}
735 	*param = (void*)xm;
736 	return 0;
737 }
738 
739 /**
740  *
741  */
fixup_free_vstr_all(void ** param,int param_no)742 int fixup_free_vstr_all(void** param, int param_no)
743 {
744 	pv_elem_free_all((pv_elem_t*)(*param));
745 	return 0;
746 }
747 /**
748  *
749  */
fixup_get_vstr_buf(sip_msg_t * msg,pv_elem_t * p,char * buf,int blen)750 int fixup_get_vstr_buf(sip_msg_t *msg, pv_elem_t *p, char *buf, int blen)
751 {
752 	if(pv_printf(msg, p, buf, &blen)<0) {
753 		LM_ERR("unable to get the value\n");
754 		return -1;
755 	}
756 	return -1;
757 }
758