core: fix another bunch of 'no real prototype' warnings, add doxygen docs
[sip-router] / mod_fix.c
1 /* 
2  * $Id$
3  * 
4  * Copyright (C) 2008 iptelorg GmbH
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /**
19  * @file mod_fix.c
20  * @brief kamailio compatible fixups
21  */
22 /* 
23  * History:
24  * --------
25  *  2008-11-25  initial version (andrei)
26  */
27
28 /*!
29  * \file
30  * \brief SIP-router core :: 
31  * \ingroup core
32  * Module: \ref core
33  */
34
35 #include "mod_fix.h"
36 #include "mem/mem.h"
37 #include "trim.h"
38
39
40
41 #if 0
42 /* TODO: */
43 int fixup_regexpNL_null(void** param, int param_no); /* not used */
44 int fixup_regexpNL_none(void** param, int param_no); /* textops */
45 #endif
46
47
48
49 #define FREE_FIXUP_FP(suffix, minp, maxp) \
50         int fixup_free_##suffix(void** param, int param_no) \
51         { \
52                 if ((param_no > (maxp)) || (param_no < (minp))) \
53                         return E_UNSPEC; \
54                 if (*param) \
55                         fparam_free_restore(param); \
56                 return 0; \
57         }
58
59
60 /** macro for declaring a fixup and the corresponding free_fixup
61   * for a function which fixes to fparam_t and expects 2 different types.
62   *
63   * The result (in *param) will be a fparam_t.
64   *
65   * @param suffix - function suffix (fixup_ will be pre-pended to it 
66   * @param minp - minimum parameter number acceptable
67   * @param maxp - maximum parameter number
68   * @param no1 -  number of parameters of type1
69   * @param type1 - fix_param type for the 1st param
70   * @paran type2 - fix_param type for all the other params
71   */
72 #define FIXUP_F2FP(suffix, minp, maxp, no1, type1, type2) \
73         int fixup_##suffix (void** param, int param_no) \
74         { \
75                 if ((param_no > (maxp)) || (param_no <(minp))) \
76                         return E_UNSPEC; \
77                 if (param_no <= (no1)){ \
78                         if (fix_param_types((type1), param)!=0) {\
79                                 ERR("Cannot convert function parameter %d to" #type1 "\n", \
80                                                 param_no);\
81                                 return E_UNSPEC; \
82                         } \
83                 }else{ \
84                         if (fix_param_types((type2), param)!=0) {\
85                                 ERR("Cannot convert function parameter %d to" #type2 "\n", \
86                                                 param_no); \
87                                 return E_UNSPEC; \
88                         } \
89                 }\
90                 return 0; \
91         } \
92         FREE_FIXUP_FP(suffix, minp, maxp)
93
94
95 /** macro for declaring a fixup and the corresponding free_fixup
96   * for a function which fixes directly to the requested type.
97   *
98   * @see FIXUP_F2FP for the parameters
99   * Side effect: declares also some _fp_helper functions
100   */
101 #define FIXUP_F2T(suffix, minp, maxp, no1, type1, type2) \
102         FIXUP_F2FP(fp_##suffix, minp, maxp, no1, type1, type2) \
103         int fixup_##suffix (void** param, int param_no) \
104         { \
105                 int ret; \
106                 if ((ret=fixup_fp_##suffix (param, param_no))!=0) \
107                         return ret; \
108                 *param=((fparam_t*)*param)->fixed; \
109                 return 0; \
110         } \
111         int fixup_free_##suffix (void** param, int param_no) \
112         { \
113                 void* p; \
114                 int ret; \
115                 if (param && *param){ \
116                         p=*param - (long)&((fparam_t*)0)->v; \
117                         if ((ret=fixup_free_fp_##suffix(&p, param_no))==0) *param=p; \
118                         return ret; \
119                 } \
120                 return 0; \
121         }
122
123
124 /** macro for declaring a fixup and the corresponding free_fixup
125   * for a function expecting first no1 params as fparamt_t and the
126   * rest as direct type.
127   *
128   * @see FIXUP_F2FP for the parameters with the exception
129   * that only the first no1 parameters are converted to 
130   * fparamt_t and the rest directly to the correponding type
131   *
132   * Side effect: declares also some _fpt_helper functions
133   */
134 #define FIXUP_F2FP_T(suffix, minp, maxp, no1, type1, type2) \
135         FIXUP_F2FP(fpt_##suffix, minp, maxp, no1, type1, type2) \
136         int fixup_##suffix (void** param, int param_no) \
137         { \
138                 int ret; \
139                 if ((ret=fixup_fpt_##suffix(param, param_no))!=0) \
140                         return ret; \
141                 if (param_no>(no1)) *param=&((fparam_t*)*param)->v; \
142                 return 0; \
143         } \
144         int fixup_free_##suffix (void** param, int param_no) \
145         { \
146                 void* p; \
147                 int ret; \
148                 if (param && *param){ \
149                         p=(param_no>(no1))? *param - (long)&((fparam_t*)0)->v : *param;\
150                         if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=p; \
151                         return ret; \
152                 } \
153                 return 0; \
154         }
155
156
157 /** macro for declaring a fixup which fixes all the paremeters to the same
158   * type.
159   *
160   * @see FIXUP_F2T.
161   */
162 #define FIXUP_F1T(suffix, minp, maxp, type) \
163         FIXUP_F2T(suffix, minp, maxp, maxp, type, 0)
164
165
166
167 FIXUP_F1T(str_null, 1, 1, FPARAM_STR)
168 FIXUP_F1T(str_str, 1, 2,  FPARAM_STR)
169 FIXUP_F1T(str_all, 1, 100,  FPARAM_STR)
170
171 /*
172   no free fixups possible for unit_*
173   (they overwrite the pointer with the converted number => the original
174    value cannot be recovered)
175 FIXUP_F1T(uint_null, 1, 1, FPARAM_INT)
176 FIXUP_F1T(uint_uint, 1, 2, FPARAM_INT)
177 */
178
179
180
181 int fixup_uint_uint(void** param, int param_no)
182 {
183         str s;
184         unsigned int num;
185         
186         s.s = *param;
187         s.len = strlen(s.s);
188         if (likely(str2int(&s, &num) == 0)) {
189                 *param = (void*)(long)num;
190         } else
191                 /* not a number */
192                 return E_UNSPEC;
193         return 0;
194 }
195
196
197
198 int fixup_uint_null(void** param, int param_no)
199 {
200         if (param_no == 1)
201                 return fixup_uint_uint(param, param_no);
202         return E_UNSPEC;
203 }
204
205
206 /* fixup_regexp_null() has to be written "by hand", since
207    it needs to save the original pointer (the fixup users expects
208    a pointer to the regex in *param and hence the original value
209    needed on free cannot be recovered directly).
210 FIXUP_F1T(regexp_null, 1, 1, FPARAM_REGEX)
211 */
212
213 struct regex_fixup {
214         regex_t regex; /* compiled regex */
215         void* orig;    /* original pointer */
216 };
217
218 int fixup_regexp_null(void** param, int param_no)
219 {
220         struct regex_fixup* re;
221         
222         if (param_no != 1)
223                 return E_UNSPEC;
224         if ((re=pkg_malloc(sizeof(*re))) ==0) {
225                 ERR("No memory left\n");
226                 goto error;
227         }
228         if (regcomp(&re->regex, *param,
229                                 REG_EXTENDED|REG_ICASE|REG_NEWLINE))
230                 goto error;
231         re->orig = *param;
232         *param = re;
233         return 0;
234 error:
235         if (re)
236                 pkg_free(re);
237         return E_UNSPEC;
238 }
239
240
241 int fixup_free_regexp_null(void** param, int param_no)
242 {
243         struct regex_fixup* re;
244         
245         if (param_no != 1)
246                 return E_UNSPEC;
247         if (*param) {
248                 re = *param;
249                 *param = re->orig;
250                 regfree(&re->regex);
251                 pkg_free(re);
252         }
253         return 0;
254 }
255
256 /* fixup_pvar_*() has to be written "by hand", since
257    it needs to save the original pointer (the fixup users expects
258    a pointer to the pv_spec_t in *param and hence the original value
259    needed on free cannot be recovered directly).
260 FIXUP_F1T(pvar_null, 1, 1, FPARAM_PVS)
261 FIXUP_F1T(pvar_pvar, 1, 2, FPARAM_PVS)
262 */
263
264 struct pvs_fixup {
265         pv_spec_t pvs; /* parsed pv spec */
266         void* orig;    /* original pointer */
267 };
268
269 int fixup_pvar_all(void** param, int param_no)
270 {
271         struct pvs_fixup* pvs_f;
272         str name;
273         
274         pvs_f = 0;
275         name.s = *param;
276         name.len = strlen(name.s);
277         trim(&name);
278         if (name.len == 0 || name.s[0] != '$')
279                 /* not a pvs id */
280                 goto error;
281         if ((pvs_f=pkg_malloc(sizeof(*pvs_f))) == 0) {
282                 ERR("No memory left\n");
283                 goto error;
284         }
285         if (pv_parse_spec2(&name, &pvs_f->pvs, 1) == 0)
286                 /* not a valid pvs identifier */
287                 goto error;
288         pvs_f->orig = *param;
289         *param = pvs_f;
290         return 0;
291 error:
292         if (pvs_f)
293                 pkg_free(pvs_f);
294         return E_UNSPEC;
295 }
296
297
298
299 int fixup_free_pvar_all(void** param, int param_no)
300 {
301         struct pvs_fixup* pvs_f;
302         
303         if (*param) {
304                 pvs_f = *param;
305                 *param = pvs_f->orig;
306                 /* free only the contents (don't attempt to free &pvs_f->pvs)*/
307                 pv_spec_destroy(&pvs_f->pvs);
308                 /* free the whole pvs_fixup */
309                 pkg_free(pvs_f);
310         }
311         return 0;
312 }
313
314
315
316 int fixup_pvar_pvar(void** param, int param_no)
317 {
318         if (param_no > 2)
319                 return E_UNSPEC;
320         return fixup_pvar_all(param, param_no);
321 }
322
323
324
325 int fixup_free_pvar_pvar(void** param, int param_no)
326 {
327         if (param_no > 2)
328                 return E_UNSPEC;
329         return fixup_free_pvar_all(param, param_no);
330 }
331
332
333
334 int fixup_pvar_null(void** param, int param_no)
335 {
336         if (param_no != 1)
337                 return E_UNSPEC;
338         return fixup_pvar_all(param, param_no);
339 }
340
341
342
343 int fixup_free_pvar_null(void** param, int param_no)
344 {
345         if (param_no != 1)
346                 return E_UNSPEC;
347         return fixup_free_pvar_all(param, param_no);
348 }
349
350 /* must be written "by hand", see above (fixup_pvar_pvar).
351 FIXUP_F2T(pvar_str, 1, 2, 1, FPARAM_PVS, FPARAM_STR)
352 FIXUP_F2T(pvar_str_str, 1, 3, 1, FPARAM_PVS, FPARAM_STR)
353 */
354
355 int fixup_pvar_str(void** param, int param_no)
356 {
357         if (param_no == 1)
358                 return fixup_pvar_all(param, param_no);
359         else if (param_no == 2)
360                 return fixup_str_str(param, param_no);
361         return E_UNSPEC;
362 }
363
364
365
366 int fixup_free_pvar_str(void** param, int param_no)
367 {
368         if (param_no == 1)
369                 return fixup_free_pvar_all(param, param_no);
370         else if (param_no == 2)
371                 return fixup_free_str_str(param, param_no);
372         return E_UNSPEC;
373 }
374
375
376
377 int fixup_pvar_str_str(void** param, int param_no)
378 {
379         if (param_no == 1)
380                 return fixup_pvar_all(param, param_no);
381         else if (param_no == 2 || param_no == 3)
382                 return fixup_str_all(param, param_no);
383         return E_UNSPEC;
384 }
385
386
387
388 int fixup_free_pvar_str_str(void** param, int param_no)
389 {
390         if (param_no == 1)
391                 return fixup_free_pvar_all(param, param_no);
392         else if (param_no == 2 || param_no == 3)
393                 return fixup_free_str_all(param, param_no);
394         return E_UNSPEC;
395 }
396
397
398
399 FIXUP_F2FP(igp_null, 1, 1, 1, FPARAM_INT|FPARAM_PVS, 0)
400 FIXUP_F2FP(igp_igp, 1, 2, 2,  FPARAM_INT|FPARAM_PVS, 0)
401
402 /* must be declared by hand, because of the pvar special handling
403    (see above)
404 FIXUP_F2FP(igp_pvar, 1, 2, 1,  FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
405 FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
406 */
407
408 int fixup_igp_pvar(void** param, int param_no)
409 {
410         if (param_no == 1)
411                 return fixup_igp_null(param, param_no);
412         else if (param_no == 2)
413                 return fixup_pvar_all(param, param_no);
414         return E_UNSPEC;
415 }
416
417
418
419 int fixup_free_igp_pvar(void** param, int param_no)
420 {
421         if (param_no == 1)
422                 return fixup_free_igp_null(param, param_no);
423         else if (param_no == 2)
424                 return fixup_free_pvar_all(param, param_no);
425         return E_UNSPEC;
426 }
427
428
429
430 int fixup_igp_pvar_pvar(void** param, int param_no)
431 {
432         if (param_no == 1)
433                 return fixup_igp_null(param, param_no);
434         else if (param_no == 2 || param_no == 3)
435                 return fixup_pvar_all(param, param_no);
436         return E_UNSPEC;
437 }
438
439
440
441 int fixup_free_igp_pvar_pvar(void** param, int param_no)
442 {
443         if (param_no == 1)
444                 return fixup_free_igp_null(param, param_no);
445         else if (param_no == 2 || param_no == 3)
446                 return fixup_free_pvar_all(param, param_no);
447         return E_UNSPEC;
448 }
449
450
451
452 /** macro for declaring a spve fixup and the corresponding free_fixup
453   * for a function expecting first no1 params as fparam converted spve 
454   * and the * rest as direct type.
455   *
456   * @see FIXUP_F2FP for the parameters with the exception
457   * that the first no1 parameters are converted to fparam_t from spve
458   * and the rest directly to the corresponding type
459   *
460   * Side effect: declares also some _spvet_helper functions
461   */
462 #define FIXUP_F_SPVE_T(suffix, minp, maxp, no1, type2) \
463         FIXUP_F1T(spvet_##suffix, minp, maxp, type2) \
464         int fixup_##suffix (void** param, int param_no) \
465         { \
466                 int ret; \
467                 fparam_t* fp; \
468                 if (param_no<=(no1)){ \
469                         if ((ret=fix_param_types(FPARAM_PVE, param))<0){ \
470                                 ERR("Cannot convert function parameter %d to spve \n", \
471                                                 param_no);\
472                                 return E_UNSPEC; \
473                         } else{ \
474                                 fp=(fparam_t*)*param; \
475                                 if ((ret==0) && (fp->v.pve->spec.getf==0)){ \
476                                         fparam_free_restore(param); \
477                                         return fix_param_types(FPARAM_STR, param); \
478                                 } else if (ret==1) \
479                                         return fix_param_types(FPARAM_STR, param); \
480                                 return ret; \
481                         } \
482                 } else return fixup_spvet_##suffix(param, param_no); \
483                 return 0; \
484         } \
485         int fixup_free_##suffix (void** param, int param_no) \
486         { \
487                 if (param && *param){ \
488                         if (param_no<=(no1)) \
489                                 fparam_free_restore(param); \
490                         else \
491                                 return fixup_free_spvet_##suffix(param, param_no); \
492                 } \
493                 return 0; \
494         }
495
496
497 /* format: name, minp, maxp, no_of_spve_params, type_for_rest_params */
498 FIXUP_F_SPVE_T(spve_spve, 1, 2, 2, 0)
499 FIXUP_F_SPVE_T(spve_uint, 1, 2, 1, FPARAM_INT)
500 FIXUP_F_SPVE_T(spve_str, 1, 2, 1, FPARAM_STR)
501 FIXUP_F_SPVE_T(spve_null, 1, 1, 1, 0)
502
503 /** get the corresp. fixup_free* function.
504  * @param f -fixup function pointer.
505  * @return  - pointer to free_fixup function if known, 0 otherwise.
506  */
507 free_fixup_function mod_fix_get_fixup_free(fixup_function f)
508 {
509         if (f == fixup_str_null) return fixup_free_str_null;
510         if (f == fixup_str_str) return fixup_free_str_str;
511         /* no free fixup for fixup_uint_* (they overwrite the pointer
512            value with a number and the original value cannot be recovered) */
513         if (f == fixup_uint_null) return 0;
514         if (f == fixup_uint_uint) return 0;
515         if (f == fixup_regexp_null) return fixup_free_regexp_null;
516         if (f == fixup_pvar_null) return fixup_free_pvar_null;
517         if (f == fixup_pvar_pvar) return fixup_free_pvar_pvar;
518         if (f == fixup_pvar_str) return fixup_free_pvar_str;
519         if (f == fixup_pvar_str_str) return fixup_free_pvar_str_str;
520         if (f == fixup_igp_igp) return fixup_free_igp_igp;
521         if (f == fixup_igp_null) return fixup_free_igp_null;
522         if (f == fixup_igp_pvar) return fixup_free_igp_pvar;
523         if (f == fixup_igp_pvar_pvar) return fixup_free_igp_pvar_pvar;
524         if (f == fixup_spve_spve) return fixup_free_spve_spve;
525         if (f == fixup_spve_null) return fixup_free_spve_null;
526         /* no free fixup, because of the uint part (the uint cannot be freed,
527            see above fixup_uint_null) */
528         if (f == fixup_spve_uint) return 0;
529         if (f == fixup_spve_str) return fixup_free_spve_str;
530         return 0;
531 }