core: added generic fparam fixup_free functions
[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_contents((fparam_t*)*param); \
56                         pkg_free(*param); \
57                         *param=0; \
58                 } \
59                 return 0; \
60         }
61
62
63 /** macro for declaring a fixup and the corresponding free_fixup
64   * for a function which fixes to fparam_t and expects 2 different types.
65   *
66   * The result (in *param) will be a fparam_t.
67   *
68   * @param suffix - function suffix (fixup_ will be pre-pended to it 
69   * @param minp - minimum parameter number acceptable
70   * @param maxp - maximum parameter number
71   * @param no1 -  number of parameters of type1
72   * @param type1 - fix_param type for the 1st param
73   * @paran type2 - fix_param type for all the other params
74   */
75 #define FIXUP_F2FP(suffix, minp, maxp, no1, type1, type2) \
76         int fixup_##suffix (void** param, int param_no) \
77         { \
78                 if ((param_no > (maxp)) || (param_no <(minp))) \
79                         return E_UNSPEC; \
80                 if (param_no <= (no1)){ \
81                         if (fix_param_types((type1), param)!=0) {\
82                                 ERR("Cannot convert function parameter %d to" #type1 "\n", \
83                                                 param_no);\
84                                 return E_UNSPEC; \
85                         } \
86                 }else{ \
87                         if (fix_param_types((type2), param)!=0) {\
88                                 ERR("Cannot convert function parameter %d to" #type2 "\n", \
89                                                 param_no); \
90                                 return E_UNSPEC; \
91                         } \
92                 }\
93                 return 0; \
94         } \
95         FREE_FIXUP_FP(suffix, minp, maxp)
96
97
98 /** macro for declaring a fixup and the corresponding free_fixup
99   * for a function which fixes directly to the requested type.
100   *
101   * @see FIXUP_F2FP for the parameters
102   * Side effect: declares also some _fp_helper functions
103   */
104 #define FIXUP_F2T(suffix, minp, maxp, no1, type1, type2) \
105         FIXUP_F2FP(fp_##suffix, minp, maxp, no1, type1, type2) \
106         int fixup_##suffix (void** param, int param_no) \
107         { \
108                 int ret; \
109                 if ((ret=fixup_fp_##suffix (param, param_no))!=0) \
110                         return ret; \
111                 *param=((fparam_t*)*param)->fixed; \
112                 return 0; \
113         } \
114         int fixup_free_##suffix (void** param, int param_no) \
115         { \
116                 void* p; \
117                 int ret; \
118                 if (param && *param){ \
119                         p=*param - (long)&((fparam_t*)0)->v; \
120                         if ((ret=fixup_free_fp_##suffix(&p, param_no))==0) *param=p; \
121                         return ret; \
122                 } \
123                 return 0; \
124         }
125
126
127 /** macro for declaring a fixup and the corresponding free_fixup
128   * for a function expecting first no1 params as fparamt_t and the
129   * rest as direct type.
130   *
131   * @see FIXUP_F2FP for the parameters with the exception
132   * that only the first no1 parameters are converted to 
133   * fparamt_t and the rest directly to the correponding type
134   *
135   * Side effect: declares also some _fpt_helper functions
136   */
137 #define FIXUP_F2FP_T(suffix, minp, maxp, no1, type1, type2) \
138         FIXUP_F2FP(fpt_##suffix, minp, maxp, no1, type1, type2) \
139         int fixup_##suffix (void** param, int param_no) \
140         { \
141                 int ret; \
142                 if ((ret=fixup_fpt_##suffix(param, param_no))!=0) \
143                         return ret; \
144                 if (param_no>(no1)) *param=&((fparam_t*)*param)->v; \
145                 return 0; \
146         } \
147         int fixup_free_##suffix (void** param, int param_no) \
148         { \
149                 void* p; \
150                 int ret; \
151                 if (param && *param){ \
152                         p=(param_no>(no1))? *param - (long)&((fparam_t*)0)->v : *param;\
153                         if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=0; \
154                         return ret; \
155                 } \
156                 return 0; \
157         }
158
159
160 /** macro for declaring a fixup which fixes all the paremeters to the same
161   * type.
162   *
163   * @see FIXUP_F2T.
164   */
165 #define FIXUP_F1T(suffix, minp, maxp, type) \
166         FIXUP_F2T(suffix, minp, maxp, maxp, type, 0)
167
168
169
170 FIXUP_F1T(str_null, 1, 1, FPARAM_STR)
171 FIXUP_F1T(str_str, 1, 2,  FPARAM_STR)
172
173 /* TODO: int can be converted in place, no need for pkg_malloc'ed fparam_t*/
174 FIXUP_F1T(uint_null, 1, 1, FPARAM_INT)
175 FIXUP_F1T(uint_uint, 1, 2, FPARAM_INT)
176
177 FIXUP_F1T(regexp_null, 1, 1, FPARAM_REGEX)
178
179 FIXUP_F1T(pvar_null, 1, 1, FPARAM_PVS)
180 FIXUP_F1T(pvar_pvar, 1, 2, FPARAM_PVS)
181
182 FIXUP_F2T(pvar_str, 1, 2, 1, FPARAM_PVS, FPARAM_STR)
183 FIXUP_F2T(pvar_str_str, 1, 3, 1, FPARAM_PVS, FPARAM_STR)
184
185 FIXUP_F2FP(igp_null, 1, 1, 1, FPARAM_INT|FPARAM_PVS, 0)
186 FIXUP_F2FP(igp_igp, 1, 2, 2,  FPARAM_INT|FPARAM_PVS, 0)
187 FIXUP_F2FP(igp_pvar, 1, 2, 1,  FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
188
189 FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
190
191 /** macro for declaring a spve fixup and the corresponding free_fixup
192   * for a function expecting first no1 params as fparam converted spve 
193   * and the * rest as direct type.
194   *
195   * @see FIXUP_F2FP for the parameters with the exception
196   * that the first no1 parameters are converted to fparam_t from spve
197   * and the rest directly to the corresponding type
198   *
199   * Side effect: declares also some _spvet_helper functions
200   */
201 #define FIXUP_F_SPVE_T(suffix, minp, maxp, no1, type2) \
202         FIXUP_F1T(spvet_##suffix, minp, maxp, type2) \
203         int fixup_##suffix (void** param, int param_no) \
204         { \
205                 int ret; \
206                 char * bkp; \
207                 fparam_t* fp; \
208                 if (param_no<=(no1)){ \
209                         if ((ret=fix_param_types(FPARAM_PVE, param))<0){ \
210                                 ERR("Cannot convert function parameter %d to" #type2 "\n", \
211                                                 param_no);\
212                                 return E_UNSPEC; \
213                         } else{ \
214                                 fp=(fparam_t*)*param; \
215                                 if ((ret==0) && (fp->v.pve->spec.getf==0)){ \
216                                         bkp=fp->orig; \
217                                         fp->orig=0; /* make sure orig string is not freed */ \
218                                         fparam_free_contents(fp); \
219                                         pkg_free(fp); \
220                                         *param=bkp; \
221                                         return fix_param_types(FPARAM_STR, param); \
222                                 } else if (ret==1) \
223                                         return fix_param_types(FPARAM_STR, param); \
224                                 return ret; \
225                         } \
226                 } else return fixup_spvet_##suffix(param, param_no); \
227                 return 0; \
228         } \
229         int fixup_free_##suffix (void** param, int param_no) \
230         { \
231                 if (param && *param){ \
232                         if (param_no<=(no1)){ \
233                                 fparam_free_contents((fparam_t*)*param); \
234                                 pkg_free(*param); \
235                                 *param=0; \
236                         } else \
237                                 return fixup_free_spvet_##suffix(param, param_no); \
238                 } \
239                 return 0; \
240         }
241
242
243 /* format: name, minp, maxp, no_of_spve_params, type_for_rest_params */
244 FIXUP_F_SPVE_T(spve_spve, 1, 2, 2, 0)
245 FIXUP_F_SPVE_T(spve_uint, 1, 2, 1, FPARAM_INT)
246 FIXUP_F_SPVE_T(spve_str, 1, 2, 1, FPARAM_STR)
247 FIXUP_F_SPVE_T(spve_null, 1, 1, 1, 0)