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