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