00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <sys/types.h>
00036 #include <regex.h>
00037
00038 #include "../../mem/shm_mem.h"
00039 #include "../../mem/mem.h"
00040 #include "../../parser/parse_hname2.h"
00041 #include "../../sr_module.h"
00042 #include "../../str.h"
00043 #include "../../dprint.h"
00044 #include "../../error.h"
00045 #include "../../ut.h"
00046 #include "avpops_parse.h"
00047 #include "avpops_impl.h"
00048 #include "avpops_db.h"
00049
00050
00051 MODULE_VERSION
00052
00053
00054 static str db_url = {NULL, 0};
00055 static str db_table = {NULL, 0};
00056 static int use_domain = 0;
00057 static str uuid_col = str_init("uuid");
00058 static str attribute_col = str_init("attribute");
00059 static str value_col = str_init("value");
00060 static str type_col = str_init("type");
00061 static str username_col = str_init("username");
00062 static str domain_col = str_init("domain");
00063 static str* db_columns[6] = {&uuid_col, &attribute_col, &value_col, &type_col, &username_col, &domain_col};
00064
00065
00066 static int avpops_init(void);
00067 static int avpops_child_init(int rank);
00068
00069 static int fixup_db_load_avp(void** param, int param_no);
00070 static int fixup_db_delete_avp(void** param, int param_no);
00071 static int fixup_db_store_avp(void** param, int param_no);
00072 static int fixup_db_query_avp(void** param, int param_no);
00073 static int fixup_delete_avp(void** param, int param_no);
00074 static int fixup_copy_avp(void** param, int param_no);
00075 static int fixup_pushto_avp(void** param, int param_no);
00076 static int fixup_check_avp(void** param, int param_no);
00077 static int fixup_op_avp(void** param, int param_no);
00078 static int fixup_subst(void** param, int param_no);
00079 static int fixup_is_avp_set(void** param, int param_no);
00080
00081 static int w_print_avps(struct sip_msg* msg, char* foo, char *bar);
00082 static int w_dbload_avps(struct sip_msg* msg, char* source, char* param);
00083 static int w_dbdelete_avps(struct sip_msg* msg, char* source, char* param);
00084 static int w_dbstore_avps(struct sip_msg* msg, char* source, char* param);
00085 static int w_dbquery1_avps(struct sip_msg* msg, char* query, char* param);
00086 static int w_dbquery2_avps(struct sip_msg* msg, char* query, char* dest);
00087 static int w_delete_avps(struct sip_msg* msg, char* param, char *foo);
00088 static int w_copy_avps(struct sip_msg* msg, char* param, char *check);
00089 static int w_pushto_avps(struct sip_msg* msg, char* destination, char *param);
00090 static int w_check_avps(struct sip_msg* msg, char* param, char *check);
00091 static int w_op_avps(struct sip_msg* msg, char* param, char *op);
00092 static int w_subst(struct sip_msg* msg, char* src, char *subst);
00093 static int w_is_avp_set(struct sip_msg* msg, char* param, char *foo);
00094
00095
00096
00097
00098 static cmd_export_t cmds[] = {
00099 {"avp_print", (cmd_function)w_print_avps, 0, 0, 0,
00100 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00101 {"avp_db_load", (cmd_function)w_dbload_avps, 2, fixup_db_load_avp, 0,
00102 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00103 {"avp_db_delete", (cmd_function)w_dbdelete_avps, 2, fixup_db_delete_avp, 0,
00104 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00105 {"avp_db_store", (cmd_function)w_dbstore_avps, 2, fixup_db_store_avp, 0,
00106 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00107 {"avp_db_query", (cmd_function)w_dbquery1_avps, 1, fixup_db_query_avp, 0,
00108 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00109 {"avp_db_query", (cmd_function)w_dbquery2_avps, 2, fixup_db_query_avp, 0,
00110 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00111 {"avp_delete", (cmd_function)w_delete_avps, 1, fixup_delete_avp, 0,
00112 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00113 {"avp_copy", (cmd_function)w_copy_avps, 2, fixup_copy_avp, 0,
00114 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00115 {"avp_pushto", (cmd_function)w_pushto_avps, 2, fixup_pushto_avp, 0,
00116 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00117 {"avp_check", (cmd_function)w_check_avps, 2, fixup_check_avp, 0,
00118 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00119 {"avp_op", (cmd_function)w_op_avps, 2, fixup_op_avp, 0,
00120 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00121 {"avp_subst", (cmd_function)w_subst, 2, fixup_subst, 0,
00122 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00123 {"is_avp_set", (cmd_function)w_is_avp_set, 1, fixup_is_avp_set, 0,
00124 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00125 {0, 0, 0, 0, 0, 0}
00126 };
00127
00128
00129
00130
00131
00132 static param_export_t params[] = {
00133 {"db_url", STR_PARAM, &db_url.s },
00134 {"avp_table", STR_PARAM, &db_table.s },
00135 {"use_domain", INT_PARAM, &use_domain },
00136 {"uuid_column", STR_PARAM, &uuid_col.s },
00137 {"attribute_column", STR_PARAM, &attribute_col.s },
00138 {"value_column", STR_PARAM, &value_col.s },
00139 {"type_column", STR_PARAM, &type_col.s },
00140 {"username_column", STR_PARAM, &username_col.s },
00141 {"domain_column", STR_PARAM, &domain_col.s },
00142 {"db_scheme", STR_PARAM|USE_FUNC_PARAM, (void*)avp_add_db_scheme },
00143 {0, 0, 0}
00144 };
00145
00146
00147 struct module_exports exports = {
00148 "avpops",
00149 DEFAULT_DLFLAGS,
00150 cmds,
00151 params,
00152 0,
00153 0,
00154 0,
00155 0,
00156 avpops_init,
00157 0,
00158 0,
00159 (child_init_function) avpops_child_init
00160 };
00161
00162
00163 static int avpops_init(void)
00164 {
00165 if (db_url.s)
00166 db_url.len = strlen(db_url.s);
00167 if (db_table.s)
00168 db_table.len = strlen(db_table.s);
00169 uuid_col.len = strlen(uuid_col.s);
00170 attribute_col.len = strlen(attribute_col.s);
00171 value_col.len = strlen(value_col.s);
00172 type_col.len = strlen(type_col.s);
00173 username_col.len = strlen(username_col.s);
00174 domain_col.len = strlen(domain_col.s);
00175
00176
00177 if (db_url.s!=0)
00178 {
00179
00180 if (db_table.s==0)
00181 {
00182 LM_CRIT("\"AVP_DB\" present but \"AVP_TABLE\" found empty\n");
00183 goto error;
00184 }
00185
00186 if (avpops_db_bind(&db_url)<0)
00187 goto error;
00188 }
00189
00190 init_store_avps(db_columns);
00191
00192 return 0;
00193 error:
00194 return -1;
00195 }
00196
00197
00198 static int avpops_child_init(int rank)
00199 {
00200
00201 if (db_url.s==0)
00202 return 0;
00203
00204 if (rank==PROC_MAIN || rank==PROC_TCP_MAIN)
00205 return 0;
00206
00207 return avpops_db_init(&db_url, &db_table, db_columns);
00208 }
00209
00210
00211 static int fixup_db_avp(void** param, int param_no, int allow_scheme)
00212 {
00213 struct fis_param *sp;
00214 struct db_param *dbp;
00215 int flags;
00216 int flags0;
00217 str s;
00218 char *p;
00219
00220 flags=0;
00221 flags0=0;
00222 if (db_url.s==0)
00223 {
00224 LM_ERR("you have to configure a db_url for using avp_db_xxx functions\n");
00225 return E_UNSPEC;
00226 }
00227
00228 s.s = (char*)*param;
00229 if (param_no==1)
00230 {
00231
00232 sp = (struct fis_param*)pkg_malloc(sizeof(struct fis_param));
00233 if (sp==0) {
00234 LM_ERR("no more pkg mem!\n");
00235 return E_OUT_OF_MEM;
00236 }
00237 memset( sp, 0, sizeof(struct fis_param));
00238
00239 if ( (p=strchr(s.s,'/'))!=0)
00240 {
00241 *(p++) = 0;
00242
00243 if (!strcasecmp("domain",p)) {
00244 flags|=AVPOPS_FLAG_DOMAIN0;
00245 } else if (!strcasecmp("username",p)) {
00246 flags|=AVPOPS_FLAG_USER0;
00247 } else if (!strcasecmp("uri",p)) {
00248 flags|=AVPOPS_FLAG_URI0;
00249 } else if (!strcasecmp("uuid",p)) {
00250 flags|=AVPOPS_FLAG_UUID0;
00251 } else {
00252 LM_ERR("unknow flag "
00253 "<%s>\n",p);
00254 return E_UNSPEC;
00255 }
00256 }
00257 if (*s.s!='$')
00258 {
00259
00260 sp->opd = ((flags==0)?AVPOPS_FLAG_UUID0:flags)|AVPOPS_VAL_STR;
00261 sp->u.s.s = (char*)pkg_malloc(strlen(s.s)+1);
00262 if (sp->u.s.s==0) {
00263 LM_ERR("no more pkg mem!!\n");
00264 return E_OUT_OF_MEM;
00265 }
00266 sp->u.s.len = strlen(s.s);
00267 strcpy(sp->u.s.s, s.s);
00268 } else {
00269
00270 s.len = strlen(s.s);
00271 p = pv_parse_spec(&s, &sp->u.sval);
00272 if (p==0 || sp->u.sval.type==PVT_NULL || sp->u.sval.type==PVT_EMPTY)
00273 {
00274 LM_ERR("bad param 1; "
00275 "expected : $pseudo-variable or int/str value\n");
00276 return E_UNSPEC;
00277 }
00278
00279 if(sp->u.sval.type==PVT_RURI || sp->u.sval.type==PVT_FROM
00280 || sp->u.sval.type==PVT_TO || sp->u.sval.type==PVT_OURI)
00281 {
00282 sp->opd = ((flags==0)?AVPOPS_FLAG_URI0:flags)|AVPOPS_VAL_PVAR;
00283 } else {
00284 sp->opd = ((flags==0)?AVPOPS_FLAG_UUID0:flags)|AVPOPS_VAL_PVAR;
00285 }
00286 }
00287 *param=(void*)sp;
00288 } else if (param_no==2) {
00289
00290 dbp = (struct db_param*)pkg_malloc(sizeof(struct db_param));
00291 if (dbp==0)
00292 {
00293 LM_ERR("no more pkg mem!!!\n");
00294 return E_OUT_OF_MEM;
00295 }
00296 memset( dbp, 0, sizeof(struct db_param));
00297 if ( parse_avp_db( s.s, dbp, allow_scheme)!=0 )
00298 {
00299 LM_ERR("parse failed\n");
00300 return E_UNSPEC;
00301 }
00302 *param=(void*)dbp;
00303 }
00304
00305 return 0;
00306 }
00307
00308
00309 static int fixup_db_load_avp(void** param, int param_no)
00310 {
00311 return fixup_db_avp( param, param_no, 1);
00312 }
00313
00314 static int fixup_db_delete_avp(void** param, int param_no)
00315 {
00316 return fixup_db_avp( param, param_no, 0);
00317 }
00318
00319
00320 static int fixup_db_store_avp(void** param, int param_no)
00321 {
00322 return fixup_db_avp( param, param_no, 0);
00323 }
00324
00325 static int fixup_db_query_avp(void** param, int param_no)
00326 {
00327 pv_elem_t *model = NULL;
00328 pvname_list_t *anlist = NULL;
00329 str s;
00330
00331 if (db_url.s==0)
00332 {
00333 LM_ERR("you have to configure db_url for using avp_db_query function\n");
00334 return E_UNSPEC;
00335 }
00336
00337 s.s = (char*)(*param);
00338 if (param_no==1)
00339 {
00340 if(s.s==NULL)
00341 {
00342 LM_ERR("null format in P%d\n",
00343 param_no);
00344 return E_UNSPEC;
00345 }
00346 s.len = strlen(s.s);
00347 if(pv_parse_format(&s, &model)<0)
00348 {
00349 LM_ERR("wrong format[%s]\n", s.s);
00350 return E_UNSPEC;
00351 }
00352
00353 *param = (void*)model;
00354 return 0;
00355 } else if(param_no==2) {
00356 if(s.s==NULL)
00357 {
00358 LM_ERR("null format in P%d\n", param_no);
00359 return E_UNSPEC;
00360 }
00361 s.len = strlen(s.s);
00362
00363 anlist = parse_pvname_list(&s, PVT_AVP);
00364 if(anlist==NULL)
00365 {
00366 LM_ERR("bad format in P%d [%s]\n", param_no, s.s);
00367 return E_UNSPEC;
00368 }
00369 *param = (void*)anlist;
00370 return 0;
00371 }
00372
00373 return 0;
00374 }
00375
00376
00377 static int fixup_delete_avp(void** param, int param_no)
00378 {
00379 struct fis_param *ap=NULL;
00380 char *p;
00381 char *s;
00382 unsigned int flags;
00383 str s0;
00384
00385 s = (char*)(*param);
00386 if (param_no==1) {
00387
00388 if ( (p=strchr(s,'/'))!=0 )
00389 *(p++)=0;
00390
00391 if(*s=='$')
00392 {
00393
00394 ap = avpops_parse_pvar(s);
00395 if (ap==0)
00396 {
00397 LM_ERR("unable to get"
00398 " pseudo-variable in param \n");
00399 return E_UNSPEC;
00400 }
00401 if (ap->u.sval.type!=PVT_AVP)
00402 {
00403 LM_ERR("bad param; expected : $avp(name)\n");
00404 return E_UNSPEC;
00405 }
00406 ap->opd|=AVPOPS_VAL_PVAR;
00407 ap->type = AVPOPS_VAL_PVAR;
00408 } else {
00409 if(strlen(s)<1)
00410 {
00411 LM_ERR("bad param - expected : $avp(name), *, s or i value\n");
00412 return E_UNSPEC;
00413 }
00414 ap = (struct fis_param*)pkg_malloc(sizeof(struct fis_param));
00415 if (ap==0)
00416 {
00417 LM_ERR(" no more pkg mem\n");
00418 return E_OUT_OF_MEM;
00419 }
00420 memset(ap, 0, sizeof(struct fis_param));
00421 ap->opd|=AVPOPS_VAL_NONE;
00422 switch(*s) {
00423 case 's': case 'S':
00424 ap->opd = AVPOPS_VAL_NONE|AVPOPS_VAL_STR;
00425 break;
00426 case 'i': case 'I':
00427 ap->opd = AVPOPS_VAL_NONE|AVPOPS_VAL_INT;
00428 break;
00429 case '*': case 'a': case 'A':
00430 ap->opd = AVPOPS_VAL_NONE;
00431 break;
00432 default:
00433 LM_ERR(" bad param - expected : *, s or i AVP flag\n");
00434 pkg_free(ap);
00435 return E_UNSPEC;
00436 }
00437
00438 flags = 0;
00439 if(*(s+1)!='\0')
00440 {
00441 s0.s = s+1;
00442 s0.len = strlen(s0.s);
00443 if(str2int(&s0, &flags)!=0)
00444 {
00445 LM_ERR("bad avp flags\n");
00446 pkg_free(ap);
00447 return E_UNSPEC;
00448 }
00449 }
00450 ap->type = AVPOPS_VAL_INT;
00451 ap->u.n = flags<<8;
00452 }
00453
00454
00455 for( ; p&&*p ; p++ )
00456 {
00457 switch (*p)
00458 {
00459 case 'g':
00460 case 'G':
00461 ap->ops|=AVPOPS_FLAG_ALL;
00462 break;
00463 default:
00464 LM_ERR(" bad flag <%c>\n",*p);
00465 if(ap!=NULL)
00466 pkg_free(ap);
00467 return E_UNSPEC;
00468 }
00469 }
00470
00471 if (ap->opd&AVPOPS_VAL_NONE)
00472 ap->ops |= AVPOPS_FLAG_ALL;
00473
00474 *param=(void*)ap;
00475 }
00476
00477 return 0;
00478 }
00479
00480 static int fixup_copy_avp(void** param, int param_no)
00481 {
00482 struct fis_param *ap;
00483 char *s;
00484 char *p;
00485
00486 s = (char*)*param;
00487 ap = 0;
00488 p = 0;
00489
00490 if (param_no==2)
00491 {
00492
00493 if ( (p=strchr(s,'/'))!=0 )
00494 *(p++)=0;
00495 }
00496
00497 ap = avpops_parse_pvar(s);
00498 if (ap==0)
00499 {
00500 LM_ERR("unable to get pseudo-variable in P%d\n", param_no);
00501 return E_OUT_OF_MEM;
00502 }
00503
00504
00505 if (ap->u.sval.type!=PVT_AVP)
00506 {
00507 LM_ERR("you must specify only AVP as parameter\n");
00508 return E_UNSPEC;
00509 }
00510
00511 if (param_no==2)
00512 {
00513
00514 for( ; p&&*p ; p++ )
00515 {
00516 switch (*p) {
00517 case 'g':
00518 case 'G':
00519 ap->ops|=AVPOPS_FLAG_ALL;
00520 break;
00521 case 'd':
00522 case 'D':
00523 ap->ops|=AVPOPS_FLAG_DELETE;
00524 break;
00525 case 'n':
00526 case 'N':
00527 ap->ops|=AVPOPS_FLAG_CASTN;
00528 break;
00529 case 's':
00530 case 'S':
00531 ap->ops|=AVPOPS_FLAG_CASTS;
00532 break;
00533 default:
00534 LM_ERR("bad flag <%c>\n",*p);
00535 return E_UNSPEC;
00536 }
00537 }
00538 }
00539
00540 *param=(void*)ap;
00541 return 0;
00542 }
00543
00544 static int fixup_pushto_avp(void** param, int param_no)
00545 {
00546 struct fis_param *ap;
00547 char *s;
00548 char *p;
00549
00550 s = (char*)*param;
00551 ap = 0;
00552
00553 if (param_no==1)
00554 {
00555 if ( *s!='$')
00556 {
00557 LM_ERR("bad param 1; expected : $ru $du ...\n");
00558 return E_UNSPEC;
00559 }
00560
00561
00562 if ( (p=strchr(s,'/'))!=0 )
00563 *(p++)=0;
00564 ap = avpops_parse_pvar(s);
00565 if (ap==0)
00566 {
00567 LM_ERR("unable to get pseudo-variable in param 1\n");
00568 return E_OUT_OF_MEM;
00569 }
00570
00571 switch(ap->u.sval.type) {
00572 case PVT_RURI:
00573 ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_RURI;
00574 if ( p && !(
00575 (!strcasecmp("username",p)
00576 && (ap->opd|=AVPOPS_FLAG_USER0)) ||
00577 (!strcasecmp("domain",p)
00578 && (ap->opd|=AVPOPS_FLAG_DOMAIN0)) ))
00579 {
00580 LM_ERR("unknown ruri flag \"%s\"!\n",p);
00581 return E_UNSPEC;
00582 }
00583 break;
00584 case PVT_DSTURI:
00585 if ( p!=0 )
00586 {
00587 LM_ERR("unknown duri flag \"%s\"!\n",p);
00588 return E_UNSPEC;
00589 }
00590 ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_DURI;
00591 break;
00592 case PVT_HDR:
00593
00594 LM_ERR("push to header is obsoleted - use append_hf() "
00595 "or append_to_reply() from textops module!\n");
00596 return E_UNSPEC;
00597 break;
00598 case PVT_BRANCH:
00599 if ( p!=0 )
00600 {
00601 LM_ERR("unknown branch flag \"%s\"!\n",p);
00602 return E_UNSPEC;
00603 }
00604 ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_BRANCH;
00605 break;
00606 default:
00607 LM_ERR("unsupported destination \"%s\"; "
00608 "expected $ru,$du,$br\n",s);
00609 return E_UNSPEC;
00610 }
00611 } else if (param_no==2) {
00612
00613 if ( *s!='$')
00614 {
00615 LM_ERR("bad param 2; expected: $pseudo-variable ...\n");
00616 return E_UNSPEC;
00617 }
00618
00619
00620 if ( (p=strchr(s,'/'))!=0 )
00621 *(p++)=0;
00622 ap = avpops_parse_pvar(s);
00623 if (ap==0)
00624 {
00625 LM_ERR("unable to get pseudo-variable in param 2\n");
00626 return E_OUT_OF_MEM;
00627 }
00628 if (ap->u.sval.type==PVT_NULL)
00629 {
00630 LM_ERR("bad param 2; expected : $pseudo-variable ...\n");
00631 pkg_free(ap);
00632 return E_UNSPEC;
00633 }
00634 ap->opd |= AVPOPS_VAL_PVAR;
00635
00636
00637 for( ; p&&*p ; p++ )
00638 {
00639 switch (*p) {
00640 case 'g':
00641 case 'G':
00642 ap->ops|=AVPOPS_FLAG_ALL;
00643 break;
00644 default:
00645 LM_ERR("bad flag <%c>\n",*p);
00646 pkg_free(ap);
00647 return E_UNSPEC;
00648 }
00649 }
00650 }
00651
00652 *param=(void*)ap;
00653 return 0;
00654 }
00655
00656 static int fixup_check_avp(void** param, int param_no)
00657 {
00658 struct fis_param *ap;
00659 regex_t* re;
00660 char *s;
00661
00662 s = (char*)*param;
00663 ap = 0;
00664
00665 if (param_no==1)
00666 {
00667 ap = avpops_parse_pvar(s);
00668 if (ap==0)
00669 {
00670 LM_ERR("unable to get pseudo-variable in param 1\n");
00671 return E_OUT_OF_MEM;
00672 }
00673
00674 if (ap->u.sval.type==PVT_NULL)
00675 {
00676 LM_ERR("null pseudo-variable in param 1\n");
00677 return E_UNSPEC;
00678 }
00679 } else if (param_no==2) {
00680 if ( (ap=parse_check_value(s))==0 )
00681 {
00682 LM_ERR("failed to parse checked value \n");
00683 return E_UNSPEC;
00684 }
00685
00686 if (ap->ops&AVPOPS_OP_RE)
00687 {
00688 if ( (ap->opd&AVPOPS_VAL_STR)==0 )
00689 {
00690 LM_ERR("regexp operation requires string value\n");
00691 return E_UNSPEC;
00692 }
00693 re = pkg_malloc(sizeof(regex_t));
00694 if (re==0)
00695 {
00696 LM_ERR("no more pkg mem\n");
00697 return E_OUT_OF_MEM;
00698 }
00699 LM_DBG("compiling regexp <%.*s>\n", ap->u.s.len, ap->u.s.s);
00700 if (regcomp(re, ap->u.s.s,
00701 REG_EXTENDED|REG_ICASE|REG_NEWLINE))
00702 {
00703 pkg_free(re);
00704 LM_ERR("bad re <%.*s>\n", ap->u.s.len, ap->u.s.s);
00705 return E_BAD_RE;
00706 }
00707
00708
00709 ap->u.s.s = (char*)re;
00710 } else if (ap->ops&AVPOPS_OP_FM) {
00711 if ( !( ap->opd&AVPOPS_VAL_PVAR ||
00712 (!(ap->opd&AVPOPS_VAL_PVAR) && ap->opd&AVPOPS_VAL_STR) ) )
00713 {
00714 LM_ERR("fast_match operation requires string value or "
00715 "avp name/alias (%d/%d)\n", ap->opd, ap->ops);
00716 return E_UNSPEC;
00717 }
00718 }
00719 }
00720
00721 *param=(void*)ap;
00722 return 0;
00723 }
00724
00725 static int fixup_subst(void** param, int param_no)
00726 {
00727 struct subst_expr* se;
00728 str subst;
00729 struct fis_param *ap;
00730 struct fis_param **av;
00731 char *s;
00732 char *p;
00733
00734 if (param_no==1) {
00735 s = (char*)*param;
00736 ap = 0;
00737 p = 0;
00738 av = (struct fis_param**)pkg_malloc(2*sizeof(struct fis_param*));
00739 if(av==NULL)
00740 {
00741 LM_ERR("no more pkg memory\n");
00742 return E_UNSPEC;
00743 }
00744 memset(av, 0, 2*sizeof(struct fis_param*));
00745
00746
00747 if ( (p=strchr(s,'/'))!=0 )
00748 *(p++)=0;
00749 ap = avpops_parse_pvar(s);
00750 if (ap==0)
00751 {
00752 LM_ERR("unable to get pseudo-variable in param 2 [%s]\n", s);
00753 return E_OUT_OF_MEM;
00754 }
00755 if (ap->u.sval.type!=PVT_AVP)
00756 {
00757 LM_ERR("bad attribute name <%s>\n", (char*)*param);
00758 pkg_free(av);
00759 return E_UNSPEC;
00760 }
00761
00762 if (ap->opd&AVPOPS_VAL_NONE)
00763 {
00764 LM_ERR("you must specify a name for the AVP\n");
00765 return E_UNSPEC;
00766 }
00767 av[0] = ap;
00768 if(p==0 || *p=='\0')
00769 {
00770 *param=(void*)av;
00771 return 0;
00772 }
00773
00774
00775 s = p;
00776 if(*s==PV_MARKER)
00777 {
00778 if ( (p=strchr(s,'/'))!=0 )
00779 *(p++)=0;
00780 if(p==0 || (p!=0 && p-s>1))
00781 {
00782 ap = avpops_parse_pvar(s);
00783 if (ap==0)
00784 {
00785 LM_ERR("unable to get pseudo-variable in param 2 [%s]\n",s);
00786 return E_OUT_OF_MEM;
00787 }
00788
00789 if (ap->u.sval.type!=PVT_AVP)
00790 {
00791 LM_ERR("bad attribute name <%s>!\n", s);
00792 pkg_free(av);
00793 return E_UNSPEC;
00794 }
00795
00796 if (ap->opd&AVPOPS_VAL_NONE)
00797 {
00798 LM_ERR("you must specify a name for the AVP!\n");
00799 return E_UNSPEC;
00800 }
00801 av[1] = ap;
00802 }
00803 if(p==0 || *p=='\0')
00804 {
00805 *param=(void*)av;
00806 return 0;
00807 }
00808 }
00809
00810
00811 for( ; p&&*p ; p++ )
00812 {
00813 switch (*p) {
00814 case 'g':
00815 case 'G':
00816 av[0]->ops|=AVPOPS_FLAG_ALL;
00817 break;
00818 case 'd':
00819 case 'D':
00820 av[0]->ops|=AVPOPS_FLAG_DELETE;
00821 break;
00822 default:
00823 LM_ERR("bad flag <%c>\n",*p);
00824 return E_UNSPEC;
00825 }
00826 }
00827 *param=(void*)av;
00828 } else if (param_no==2) {
00829 LM_DBG("%s fixing %s\n", exports.name, (char*)(*param));
00830 subst.s=*param;
00831 subst.len=strlen(*param);
00832 se=subst_parser(&subst);
00833 if (se==0){
00834 LM_ERR("%s: bad subst re %s\n",exports.name, (char*)*param);
00835 return E_BAD_RE;
00836 }
00837
00838
00839
00840 *param=se;
00841 }
00842
00843 return 0;
00844 }
00845
00846 static int fixup_op_avp(void** param, int param_no)
00847 {
00848 struct fis_param *ap;
00849 struct fis_param **av;
00850 char *s;
00851 char *p;
00852
00853 s = (char*)*param;
00854 ap = 0;
00855
00856 if (param_no==1)
00857 {
00858 av = (struct fis_param**)pkg_malloc(2*sizeof(struct fis_param*));
00859 if(av==NULL)
00860 {
00861 LM_ERR("no more pkg memory\n");
00862 return E_UNSPEC;
00863 }
00864 memset(av, 0, 2*sizeof(struct fis_param*));
00865
00866 if ( (p=strchr(s,'/'))!=0 )
00867 *(p++)=0;
00868
00869 av[0] = avpops_parse_pvar(s);
00870 if (av[0]==0)
00871 {
00872 LM_ERR("unable to get pseudo-variable in param 1\n");
00873 return E_OUT_OF_MEM;
00874 }
00875 if (av[0]->u.sval.type!=PVT_AVP)
00876 {
00877 LM_ERR("bad attribute name <%s>\n", (char*)*param);
00878 pkg_free(av);
00879 return E_UNSPEC;
00880 }
00881 if(p==0 || *p=='\0')
00882 {
00883 *param=(void*)av;
00884 return 0;
00885 }
00886
00887 s = p;
00888 ap = avpops_parse_pvar(s);
00889 if (ap==0)
00890 {
00891 LM_ERR("unable to get pseudo-variable in param 1 (2)\n");
00892 return E_OUT_OF_MEM;
00893 }
00894 if (ap->u.sval.type!=PVT_AVP)
00895 {
00896 LM_ERR("bad attribute name/alias <%s>!\n", s);
00897 pkg_free(av);
00898 return E_UNSPEC;
00899 }
00900 av[1] = ap;
00901 *param=(void*)av;
00902 return 0;
00903 } else if (param_no==2) {
00904 if ( (ap=parse_op_value(s))==0 )
00905 {
00906 LM_ERR("failed to parse the value \n");
00907 return E_UNSPEC;
00908 }
00909
00910 if ( (ap->opd&AVPOPS_VAL_STR)!=0 && (ap->opd&AVPOPS_VAL_PVAR)==0)
00911 {
00912 LM_ERR("operations requires integer values\n");
00913 return E_UNSPEC;
00914 }
00915 *param=(void*)ap;
00916 return 0;
00917 }
00918 return -1;
00919 }
00920
00921 static int fixup_is_avp_set(void** param, int param_no)
00922 {
00923 struct fis_param *ap;
00924 char *p;
00925 char *s;
00926
00927 s = (char*)(*param);
00928 if (param_no==1) {
00929
00930 if ( (p=strchr(s,'/'))!=0 )
00931 *(p++)=0;
00932
00933 ap = avpops_parse_pvar(s);
00934 if (ap==0)
00935 {
00936 LM_ERR("unable to get pseudo-variable in param\n");
00937 return E_OUT_OF_MEM;
00938 }
00939
00940 if (ap->u.sval.type!=PVT_AVP)
00941 {
00942 LM_ERR("bad attribute name <%s>\n", (char*)*param);
00943 return E_UNSPEC;
00944 }
00945 if(p==0 || *p=='\0')
00946 ap->ops|=AVPOPS_FLAG_ALL;
00947
00948
00949 for( ; p&&*p ; p++ )
00950 {
00951 switch (*p) {
00952 case 'e':
00953 case 'E':
00954 ap->ops|=AVPOPS_FLAG_EMPTY;
00955 break;
00956 case 'n':
00957 case 'N':
00958 if(ap->ops&AVPOPS_FLAG_CASTS)
00959 {
00960 LM_ERR("invalid flag combination <%c> and 's|S'\n",*p);
00961 return E_UNSPEC;
00962 }
00963 ap->ops|=AVPOPS_FLAG_CASTN;
00964 break;
00965 case 's':
00966 case 'S':
00967 if(ap->ops&AVPOPS_FLAG_CASTN)
00968 {
00969 LM_ERR("invalid flag combination <%c> and 'n|N'\n",*p);
00970 return E_UNSPEC;
00971 }
00972 ap->ops|=AVPOPS_FLAG_CASTS;
00973 break;
00974 default:
00975 LM_ERR("bad flag <%c>\n",*p);
00976 return E_UNSPEC;
00977 }
00978 }
00979
00980 *param=(void*)ap;
00981 }
00982
00983 return 0;
00984 }
00985
00986 static int w_dbload_avps(struct sip_msg* msg, char* source, char* param)
00987 {
00988 return ops_dbload_avps ( msg, (struct fis_param*)source,
00989 (struct db_param*)param, use_domain);
00990 }
00991
00992 static int w_dbdelete_avps(struct sip_msg* msg, char* source, char* param)
00993 {
00994 return ops_dbdelete_avps ( msg, (struct fis_param*)source,
00995 (struct db_param*)param, use_domain);
00996 }
00997
00998 static int w_dbstore_avps(struct sip_msg* msg, char* source, char* param)
00999 {
01000 return ops_dbstore_avps ( msg, (struct fis_param*)source,
01001 (struct db_param*)param, use_domain);
01002 }
01003
01004 static int w_dbquery1_avps(struct sip_msg* msg, char* query, char* param)
01005 {
01006 return ops_dbquery_avps ( msg, (pv_elem_t*)query, 0);
01007 }
01008
01009 static int w_dbquery2_avps(struct sip_msg* msg, char* query, char* dest)
01010 {
01011 return ops_dbquery_avps ( msg, (pv_elem_t*)query, (pvname_list_t*)dest);
01012 }
01013
01014 static int w_delete_avps(struct sip_msg* msg, char* param, char* foo)
01015 {
01016 return ops_delete_avp ( msg, (struct fis_param*)param);
01017 }
01018
01019 static int w_copy_avps(struct sip_msg* msg, char* name1, char *name2)
01020 {
01021 return ops_copy_avp ( msg, (struct fis_param*)name1,
01022 (struct fis_param*)name2);
01023 }
01024
01025 static int w_pushto_avps(struct sip_msg* msg, char* destination, char *param)
01026 {
01027 return ops_pushto_avp ( msg, (struct fis_param*)destination,
01028 (struct fis_param*)param);
01029 }
01030
01031 static int w_check_avps(struct sip_msg* msg, char* param, char *check)
01032 {
01033 return ops_check_avp ( msg, (struct fis_param*)param,
01034 (struct fis_param*)check);
01035 }
01036
01037 static int w_op_avps(struct sip_msg* msg, char* param, char *op)
01038 {
01039 return ops_op_avp ( msg, (struct fis_param**)param,
01040 (struct fis_param*)op);
01041 }
01042
01043 static int w_subst(struct sip_msg* msg, char* src, char *subst)
01044 {
01045 return ops_subst(msg, (struct fis_param**)src, (struct subst_expr*)subst);
01046 }
01047
01048 static int w_is_avp_set(struct sip_msg* msg, char* param, char *op)
01049 {
01050 return ops_is_avp_set(msg, (struct fis_param*)param);
01051 }
01052
01053 static int w_print_avps(struct sip_msg* msg, char* foo, char *bar)
01054 {
01055 return ops_print_avp();
01056 }
01057