• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • Directories
  • File List
  • Globals

mod_fix.c

Go to the documentation of this file.
00001 /* 
00002  * Copyright (C) 2008 iptelorg GmbH
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* 
00018  * History:
00019  * --------
00020  *  2008-11-25  initial version (andrei)
00021  */
00022 
00030 #include "mod_fix.h"
00031 #include "mem/mem.h"
00032 #include "trim.h"
00033 
00034 
00035 
00036 #if 0
00037 /* TODO: */
00038 int fixup_regexpNL_null(void** param, int param_no); /* not used */
00039 int fixup_regexpNL_none(void** param, int param_no); /* textops */
00040 #endif
00041 
00042 
00043 
00044 #define FREE_FIXUP_FP(suffix, minp, maxp) \
00045         int fixup_free_##suffix(void** param, int param_no) \
00046         { \
00047                 if ((param_no > (maxp)) || (param_no < (minp))) \
00048                         return E_UNSPEC; \
00049                 if (*param) \
00050                         fparam_free_restore(param); \
00051                 return 0; \
00052         }
00053 
00054 
00067 #define FIXUP_F2FP(suffix, minp, maxp, no1, type1, type2) \
00068         int fixup_##suffix (void** param, int param_no) \
00069         { \
00070                 if ((param_no > (maxp)) || (param_no <(minp))) \
00071                         return E_UNSPEC; \
00072                 if (param_no <= (no1)){ \
00073                         if (fix_param_types((type1), param)!=0) {\
00074                                 ERR("Cannot convert function parameter %d to" #type1 "\n", \
00075                                                 param_no);\
00076                                 return E_UNSPEC; \
00077                         } \
00078                 }else{ \
00079                         if (fix_param_types((type2), param)!=0) {\
00080                                 ERR("Cannot convert function parameter %d to" #type2 "\n", \
00081                                                 param_no); \
00082                                 return E_UNSPEC; \
00083                         } \
00084                 }\
00085                 return 0; \
00086         } \
00087         FREE_FIXUP_FP(suffix, minp, maxp)
00088 
00089 
00096 #define FIXUP_F2T(suffix, minp, maxp, no1, type1, type2) \
00097         FIXUP_F2FP(fp_##suffix, minp, maxp, no1, type1, type2) \
00098         int fixup_##suffix (void** param, int param_no) \
00099         { \
00100                 int ret; \
00101                 if ((ret=fixup_fp_##suffix (param, param_no))!=0) \
00102                         return ret; \
00103                 *param=((fparam_t*)*param)->fixed; \
00104                 return 0; \
00105         } \
00106         int fixup_free_##suffix (void** param, int param_no) \
00107         { \
00108                 void* p; \
00109                 int ret; \
00110                 if (param && *param){ \
00111                         p=*param - (long)&((fparam_t*)0)->v; \
00112                         if ((ret=fixup_free_fp_##suffix(&p, param_no))==0) *param=p; \
00113                         return ret; \
00114                 } \
00115                 return 0; \
00116         }
00117 
00118 
00129 #define FIXUP_F2FP_T(suffix, minp, maxp, no1, type1, type2) \
00130         FIXUP_F2FP(fpt_##suffix, minp, maxp, no1, type1, type2) \
00131         int fixup_##suffix (void** param, int param_no) \
00132         { \
00133                 int ret; \
00134                 if ((ret=fixup_fpt_##suffix(param, param_no))!=0) \
00135                         return ret; \
00136                 if (param_no>(no1)) *param=&((fparam_t*)*param)->v; \
00137                 return 0; \
00138         } \
00139         int fixup_free_##suffix (void** param, int param_no) \
00140         { \
00141                 void* p; \
00142                 int ret; \
00143                 if (param && *param){ \
00144                         p=(param_no>(no1))? *param - (long)&((fparam_t*)0)->v : *param;\
00145                         if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=p; \
00146                         return ret; \
00147                 } \
00148                 return 0; \
00149         }
00150 
00151 
00157 #define FIXUP_F1T(suffix, minp, maxp, type) \
00158         FIXUP_F2T(suffix, minp, maxp, maxp, type, 0)
00159 
00160 
00161 
00162 FIXUP_F1T(str_null, 1, 1, FPARAM_STR)
00163 FIXUP_F1T(str_str, 1, 2,  FPARAM_STR)
00164 FIXUP_F1T(str_all, 1, 100,  FPARAM_STR)
00165 
00166 /*
00167   no free fixups possible for unit_*
00168   (they overwrite the pointer with the converted number => the original
00169    value cannot be recovered)
00170 FIXUP_F1T(uint_null, 1, 1, FPARAM_INT)
00171 FIXUP_F1T(uint_uint, 1, 2, FPARAM_INT)
00172 */
00173 
00174 
00175 
00176 int fixup_uint_uint(void** param, int param_no)
00177 {
00178         str s;
00179         unsigned int num;
00180         
00181         s.s = *param;
00182         s.len = strlen(s.s);
00183         if (likely(str2int(&s, &num) == 0)) {
00184                 *param = (void*)(long)num;
00185         } else
00186                 /* not a number */
00187                 return E_UNSPEC;
00188         return 0;
00189 }
00190 
00191 
00192 
00193 int fixup_uint_null(void** param, int param_no)
00194 {
00195         if (param_no == 1)
00196                 return fixup_uint_uint(param, param_no);
00197         return E_UNSPEC;
00198 }
00199 
00200 
00201 /* fixup_regexp_null() has to be written "by hand", since
00202    it needs to save the original pointer (the fixup users expects
00203    a pointer to the regex in *param and hence the original value
00204    needed on free cannot be recovered directly).
00205 FIXUP_F1T(regexp_null, 1, 1, FPARAM_REGEX)
00206 */
00207 
00208 struct regex_fixup {
00209         regex_t regex; /* compiled regex */
00210         void* orig;    /* original pointer */
00211 };
00212 
00213 int fixup_regexp_null(void** param, int param_no)
00214 {
00215         struct regex_fixup* re;
00216         
00217         if (param_no != 1)
00218                 return E_UNSPEC;
00219         if ((re=pkg_malloc(sizeof(*re))) ==0) {
00220                 ERR("No memory left\n");
00221                 goto error;
00222         }
00223         if (regcomp(&re->regex, *param,
00224                                 REG_EXTENDED|REG_ICASE|REG_NEWLINE))
00225                 goto error;
00226         re->orig = *param;
00227         *param = re;
00228         return 0;
00229 error:
00230         if (re)
00231                 pkg_free(re);
00232         return E_UNSPEC;
00233 }
00234 
00235 
00236 int fixup_free_regexp_null(void** param, int param_no)
00237 {
00238         struct regex_fixup* re;
00239         
00240         if (param_no != 1)
00241                 return E_UNSPEC;
00242         if (*param) {
00243                 re = *param;
00244                 *param = re->orig;
00245                 regfree(&re->regex);
00246                 pkg_free(re);
00247         }
00248         return 0;
00249 }
00250 
00251 /* fixup_pvar_*() has to be written "by hand", since
00252    it needs to save the original pointer (the fixup users expects
00253    a pointer to the pv_spec_t in *param and hence the original value
00254    needed on free cannot be recovered directly).
00255 FIXUP_F1T(pvar_null, 1, 1, FPARAM_PVS)
00256 FIXUP_F1T(pvar_pvar, 1, 2, FPARAM_PVS)
00257 */
00258 
00259 struct pvs_fixup {
00260         pv_spec_t pvs; /* parsed pv spec */
00261         void* orig;    /* original pointer */
00262 };
00263 
00264 int fixup_pvar_all(void** param, int param_no)
00265 {
00266         struct pvs_fixup* pvs_f;
00267         str name;
00268         
00269         pvs_f = 0;
00270         name.s = *param;
00271         name.len = strlen(name.s);
00272         trim(&name);
00273         if (name.len == 0 || name.s[0] != '$')
00274                 /* not a pvs id */
00275                 goto error;
00276         if ((pvs_f=pkg_malloc(sizeof(*pvs_f))) == 0) {
00277                 ERR("No memory left\n");
00278                 goto error;
00279         }
00280         if (pv_parse_spec2(&name, &pvs_f->pvs, 1) == 0)
00281                 /* not a valid pvs identifier */
00282                 goto error;
00283         pvs_f->orig = *param;
00284         *param = pvs_f;
00285         return 0;
00286 error:
00287         if (pvs_f)
00288                 pkg_free(pvs_f);
00289         return E_UNSPEC;
00290 }
00291 
00292 
00293 
00294 int fixup_free_pvar_all(void** param, int param_no)
00295 {
00296         struct pvs_fixup* pvs_f;
00297         
00298         if (*param) {
00299                 pvs_f = *param;
00300                 *param = pvs_f->orig;
00301                 /* free only the contents (don't attempt to free &pvs_f->pvs)*/
00302                 pv_spec_destroy(&pvs_f->pvs);
00303                 /* free the whole pvs_fixup */
00304                 pkg_free(pvs_f);
00305         }
00306         return 0;
00307 }
00308 
00309 
00310 
00311 int fixup_pvar_pvar(void** param, int param_no)
00312 {
00313         if (param_no > 2)
00314                 return E_UNSPEC;
00315         return fixup_pvar_all(param, param_no);
00316 }
00317 
00318 
00319 
00320 int fixup_free_pvar_pvar(void** param, int param_no)
00321 {
00322         if (param_no > 2)
00323                 return E_UNSPEC;
00324         return fixup_free_pvar_all(param, param_no);
00325 }
00326 
00327 
00328 
00329 int fixup_pvar_null(void** param, int param_no)
00330 {
00331         if (param_no != 1)
00332                 return E_UNSPEC;
00333         return fixup_pvar_all(param, param_no);
00334 }
00335 
00336 
00337 
00338 int fixup_free_pvar_null(void** param, int param_no)
00339 {
00340         if (param_no != 1)
00341                 return E_UNSPEC;
00342         return fixup_free_pvar_all(param, param_no);
00343 }
00344 
00345 /* must be written "by hand", see above (fixup_pvar_pvar).
00346 FIXUP_F2T(pvar_str, 1, 2, 1, FPARAM_PVS, FPARAM_STR)
00347 FIXUP_F2T(pvar_str_str, 1, 3, 1, FPARAM_PVS, FPARAM_STR)
00348 */
00349 
00350 int fixup_pvar_str(void** param, int param_no)
00351 {
00352         if (param_no == 1)
00353                 return fixup_pvar_all(param, param_no);
00354         else if (param_no == 2)
00355                 return fixup_str_str(param, param_no);
00356         return E_UNSPEC;
00357 }
00358 
00359 
00360 
00361 int fixup_free_pvar_str(void** param, int param_no)
00362 {
00363         if (param_no == 1)
00364                 return fixup_free_pvar_all(param, param_no);
00365         else if (param_no == 2)
00366                 return fixup_free_str_str(param, param_no);
00367         return E_UNSPEC;
00368 }
00369 
00370 
00371 
00372 int fixup_pvar_str_str(void** param, int param_no)
00373 {
00374         if (param_no == 1)
00375                 return fixup_pvar_all(param, param_no);
00376         else if (param_no == 2 || param_no == 3)
00377                 return fixup_str_all(param, param_no);
00378         return E_UNSPEC;
00379 }
00380 
00381 
00382 
00383 int fixup_free_pvar_str_str(void** param, int param_no)
00384 {
00385         if (param_no == 1)
00386                 return fixup_free_pvar_all(param, param_no);
00387         else if (param_no == 2 || param_no == 3)
00388                 return fixup_free_str_all(param, param_no);
00389         return E_UNSPEC;
00390 }
00391 
00392 
00393 int fixup_pvar_uint(void** param, int param_no)
00394 {
00395         if (param_no == 1)
00396                 return fixup_pvar_all(param, param_no);
00397         else if (param_no == 2)
00398                 return fixup_uint_uint(param, param_no);
00399         return E_UNSPEC;
00400 }
00401 
00402 
00403 int fixup_free_pvar_uint(void** param, int param_no)
00404 {
00405         if (param_no == 1)
00406                 return fixup_free_pvar_all(param, param_no);
00407         return E_UNSPEC;
00408 }
00409 
00410 
00411 FIXUP_F2FP(igp_null, 1, 1, 1, FPARAM_INT|FPARAM_PVS, 0)
00412 FIXUP_F2FP(igp_igp, 1, 2, 2,  FPARAM_INT|FPARAM_PVS, 0)
00413 
00414 /* must be declared by hand, because of the pvar special handling
00415    (see above)
00416 FIXUP_F2FP(igp_pvar, 1, 2, 1,  FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
00417 FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
00418 */
00419 
00420 int fixup_igp_pvar(void** param, int param_no)
00421 {
00422         if (param_no == 1)
00423                 return fixup_igp_null(param, param_no);
00424         else if (param_no == 2)
00425                 return fixup_pvar_all(param, param_no);
00426         return E_UNSPEC;
00427 }
00428 
00429 
00430 
00431 int fixup_free_igp_pvar(void** param, int param_no)
00432 {
00433         if (param_no == 1)
00434                 return fixup_free_igp_null(param, param_no);
00435         else if (param_no == 2)
00436                 return fixup_free_pvar_all(param, param_no);
00437         return E_UNSPEC;
00438 }
00439 
00440 
00441 
00442 int fixup_igp_pvar_pvar(void** param, int param_no)
00443 {
00444         if (param_no == 1)
00445                 return fixup_igp_null(param, param_no);
00446         else if (param_no == 2 || param_no == 3)
00447                 return fixup_pvar_all(param, param_no);
00448         return E_UNSPEC;
00449 }
00450 
00451 
00452 
00453 int fixup_free_igp_pvar_pvar(void** param, int param_no)
00454 {
00455         if (param_no == 1)
00456                 return fixup_free_igp_null(param, param_no);
00457         else if (param_no == 2 || param_no == 3)
00458                 return fixup_free_pvar_all(param, param_no);
00459         return E_UNSPEC;
00460 }
00461 
00462 
00463 
00474 #define FIXUP_F_SPVE_T(suffix, minp, maxp, no1, type2) \
00475         FIXUP_F1T(spvet_##suffix, minp, maxp, type2) \
00476         int fixup_##suffix (void** param, int param_no) \
00477         { \
00478                 int ret; \
00479                 fparam_t* fp; \
00480                 if (param_no<=(no1)){ \
00481                         if ((ret=fix_param_types(FPARAM_PVE, param))<0){ \
00482                                 ERR("Cannot convert function parameter %d to spve \n", \
00483                                                 param_no);\
00484                                 return E_UNSPEC; \
00485                         } else{ \
00486                                 fp=(fparam_t*)*param; \
00487                                 if ((ret==0) && (fp->v.pve->spec.getf==0)){ \
00488                                         fparam_free_restore(param); \
00489                                         return fix_param_types(FPARAM_STR, param); \
00490                                 } else if (ret==1) \
00491                                         return fix_param_types(FPARAM_STR, param); \
00492                                 return ret; \
00493                         } \
00494                 } else return fixup_spvet_##suffix(param, param_no); \
00495                 return 0; \
00496         } \
00497         int fixup_free_##suffix (void** param, int param_no) \
00498         { \
00499                 if (param && *param){ \
00500                         if (param_no<=(no1)) \
00501                                 fparam_free_restore(param); \
00502                         else \
00503                                 return fixup_free_spvet_##suffix(param, param_no); \
00504                 } \
00505                 return 0; \
00506         }
00507 
00508 
00509 /* format: name, minp, maxp, no_of_spve_params, type_for_rest_params */
00510 FIXUP_F_SPVE_T(spve_spve, 1, 2, 2, 0)
00511 FIXUP_F_SPVE_T(spve_uint, 1, 2, 1, FPARAM_INT)
00512 FIXUP_F_SPVE_T(spve_str, 1, 2, 1, FPARAM_STR)
00513 FIXUP_F_SPVE_T(spve_null, 1, 1, 1, 0)
00514 
00519 free_fixup_function mod_fix_get_fixup_free(fixup_function f)
00520 {
00521         if (f == fixup_str_null) return fixup_free_str_null;
00522         if (f == fixup_str_str) return fixup_free_str_str;
00523         /* no free fixup for fixup_uint_* (they overwrite the pointer
00524            value with a number and the original value cannot be recovered) */
00525         if (f == fixup_uint_null) return 0;
00526         if (f == fixup_uint_uint) return 0;
00527         if (f == fixup_regexp_null) return fixup_free_regexp_null;
00528         if (f == fixup_pvar_null) return fixup_free_pvar_null;
00529         if (f == fixup_pvar_pvar) return fixup_free_pvar_pvar;
00530         if (f == fixup_pvar_str) return fixup_free_pvar_str;
00531         if (f == fixup_pvar_str_str) return fixup_free_pvar_str_str;
00532         if (f == fixup_igp_igp) return fixup_free_igp_igp;
00533         if (f == fixup_igp_null) return fixup_free_igp_null;
00534         if (f == fixup_igp_pvar) return fixup_free_igp_pvar;
00535         if (f == fixup_igp_pvar_pvar) return fixup_free_igp_pvar_pvar;
00536         if (f == fixup_spve_spve) return fixup_free_spve_spve;
00537         if (f == fixup_spve_null) return fixup_free_spve_null;
00538         /* no free fixup, because of the uint part (the uint cannot be freed,
00539            see above fixup_uint_null) */
00540         if (f == fixup_spve_uint) return 0;
00541         if (f == fixup_spve_str) return fixup_free_spve_str;
00542         return 0;
00543 }
00544 
00548 int fixup_spve_all(void** param, int param_no)
00549 {
00550         return fixup_spve_null(param, 1);
00551 }
00552 
00556 int fixup_igp_all(void** param, int param_no)
00557 {
00558         return fixup_igp_null(param, 1);
00559 }

Generated on Tue May 22 2012 13:10:11 for SIP Router by  doxygen 1.7.1