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
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
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_INIT || 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 str s;
00217 char *p;
00218
00219 flags=0;
00220 if (db_url.s==0)
00221 {
00222 LM_ERR("you have to configure a db_url for using avp_db_xxx functions\n");
00223 return E_UNSPEC;
00224 }
00225
00226 s.s = (char*)*param;
00227 if (param_no==1)
00228 {
00229
00230 sp = (struct fis_param*)pkg_malloc(sizeof(struct fis_param));
00231 if (sp==0) {
00232 LM_ERR("no more pkg mem!\n");
00233 return E_OUT_OF_MEM;
00234 }
00235 memset( sp, 0, sizeof(struct fis_param));
00236
00237 if ( (p=strchr(s.s,'/'))!=0)
00238 {
00239 *(p++) = 0;
00240
00241 if (!strcasecmp("domain",p)) {
00242 flags|=AVPOPS_FLAG_DOMAIN0;
00243 } else if (!strcasecmp("username",p)) {
00244 flags|=AVPOPS_FLAG_USER0;
00245 } else if (!strcasecmp("uri",p)) {
00246 flags|=AVPOPS_FLAG_URI0;
00247 } else if (!strcasecmp("uuid",p)) {
00248 flags|=AVPOPS_FLAG_UUID0;
00249 } else {
00250 LM_ERR("unknow flag "
00251 "<%s>\n",p);
00252 return E_UNSPEC;
00253 }
00254 }
00255 if (*s.s!='$')
00256 {
00257
00258 sp->opd = ((flags==0)?AVPOPS_FLAG_UUID0:flags)|AVPOPS_VAL_STR;
00259 sp->u.s.s = (char*)pkg_malloc(strlen(s.s)+1);
00260 if (sp->u.s.s==0) {
00261 LM_ERR("no more pkg mem!!\n");
00262 return E_OUT_OF_MEM;
00263 }
00264 sp->u.s.len = strlen(s.s);
00265 strcpy(sp->u.s.s, s.s);
00266 } else {
00267
00268 s.len = strlen(s.s);
00269 p = pv_parse_spec(&s, &sp->u.sval);
00270 if (p==0 || sp->u.sval.type==PVT_NULL || sp->u.sval.type==PVT_EMPTY)
00271 {
00272 LM_ERR("bad param 1; "
00273 "expected : $pseudo-variable or int/str value\n");
00274 return E_UNSPEC;
00275 }
00276
00277 if(sp->u.sval.type==PVT_RURI || sp->u.sval.type==PVT_FROM
00278 || sp->u.sval.type==PVT_TO || sp->u.sval.type==PVT_OURI)
00279 {
00280 sp->opd = ((flags==0)?AVPOPS_FLAG_URI0:flags)|AVPOPS_VAL_PVAR;
00281 } else {
00282 sp->opd = ((flags==0)?AVPOPS_FLAG_UUID0:flags)|AVPOPS_VAL_PVAR;
00283 }
00284 }
00285 *param=(void*)sp;
00286 } else if (param_no==2) {
00287
00288 dbp = (struct db_param*)pkg_malloc(sizeof(struct db_param));
00289 if (dbp==0)
00290 {
00291 LM_ERR("no more pkg mem!!!\n");
00292 return E_OUT_OF_MEM;
00293 }
00294 memset( dbp, 0, sizeof(struct db_param));
00295 if ( parse_avp_db( s.s, dbp, allow_scheme)!=0 )
00296 {
00297 LM_ERR("parse failed\n");
00298 return E_UNSPEC;
00299 }
00300 *param=(void*)dbp;
00301 }
00302
00303 return 0;
00304 }
00305
00306
00307 static int fixup_db_load_avp(void** param, int param_no)
00308 {
00309 return fixup_db_avp( param, param_no, 1);
00310 }
00311
00312 static int fixup_db_delete_avp(void** param, int param_no)
00313 {
00314 return fixup_db_avp( param, param_no, 0);
00315 }
00316
00317
00318 static int fixup_db_store_avp(void** param, int param_no)
00319 {
00320 return fixup_db_avp( param, param_no, 0);
00321 }
00322
00323 static int fixup_db_query_avp(void** param, int param_no)
00324 {
00325 pv_elem_t *model = NULL;
00326 pvname_list_t *anlist = NULL;
00327 str s;
00328
00329 if (db_url.s==0)
00330 {
00331 LM_ERR("you have to configure db_url for using avp_db_query function\n");
00332 return E_UNSPEC;
00333 }
00334
00335 s.s = (char*)(*param);
00336 if (param_no==1)
00337 {
00338 if(s.s==NULL)
00339 {
00340 LM_ERR("null format in P%d\n",
00341 param_no);
00342 return E_UNSPEC;
00343 }
00344 s.len = strlen(s.s);
00345 if(pv_parse_format(&s, &model)<0)
00346 {
00347 LM_ERR("wrong format[%s]\n", s.s);
00348 return E_UNSPEC;
00349 }
00350
00351 *param = (void*)model;
00352 return 0;
00353 } else if(param_no==2) {
00354 if(s.s==NULL)
00355 {
00356 LM_ERR("null format in P%d\n", param_no);
00357 return E_UNSPEC;
00358 }
00359 s.len = strlen(s.s);
00360
00361 anlist = parse_pvname_list(&s, PVT_AVP);
00362 if(anlist==NULL)
00363 {
00364 LM_ERR("bad format in P%d [%s]\n", param_no, s.s);
00365 return E_UNSPEC;
00366 }
00367 *param = (void*)anlist;
00368 return 0;
00369 }
00370
00371 return 0;
00372 }
00373
00374
00375 static int fixup_delete_avp(void** param, int param_no)
00376 {
00377 struct fis_param *ap=NULL;
00378 char *p;
00379 char *s;
00380 unsigned int flags;
00381 str s0;
00382
00383 s = (char*)(*param);
00384 if (param_no==1) {
00385
00386 if ( (p=strchr(s,'/'))!=0 )
00387 *(p++)=0;
00388
00389 if(*s=='$')
00390 {
00391
00392 ap = avpops_parse_pvar(s);
00393 if (ap==0)
00394 {
00395 LM_ERR("unable to get"
00396 " pseudo-variable in param \n");
00397 return E_UNSPEC;
00398 }
00399 if (ap->u.sval.type!=PVT_AVP)
00400 {
00401 LM_ERR("bad param; expected : $avp(name)\n");
00402 return E_UNSPEC;
00403 }
00404 ap->opd|=AVPOPS_VAL_PVAR;
00405 ap->type = AVPOPS_VAL_PVAR;
00406 } else {
00407 if(strlen(s)<1)
00408 {
00409 LM_ERR("bad param - expected : $avp(name), *, s or i value\n");
00410 return E_UNSPEC;
00411 }
00412 ap = (struct fis_param*)pkg_malloc(sizeof(struct fis_param));
00413 if (ap==0)
00414 {
00415 LM_ERR(" no more pkg mem\n");
00416 return E_OUT_OF_MEM;
00417 }
00418 memset(ap, 0, sizeof(struct fis_param));
00419 ap->opd|=AVPOPS_VAL_NONE;
00420 switch(*s) {
00421 case 's': case 'S':
00422 ap->opd = AVPOPS_VAL_NONE|AVPOPS_VAL_STR;
00423 break;
00424 case 'i': case 'I':
00425 ap->opd = AVPOPS_VAL_NONE|AVPOPS_VAL_INT;
00426 break;
00427 case '*': case 'a': case 'A':
00428 ap->opd = AVPOPS_VAL_NONE;
00429 break;
00430 default:
00431 LM_ERR(" bad param - expected : *, s or i AVP flag\n");
00432 pkg_free(ap);
00433 return E_UNSPEC;
00434 }
00435
00436 flags = 0;
00437 if(*(s+1)!='\0')
00438 {
00439 s0.s = s+1;
00440 s0.len = strlen(s0.s);
00441 if(str2int(&s0, &flags)!=0)
00442 {
00443 LM_ERR("bad avp flags\n");
00444 pkg_free(ap);
00445 return E_UNSPEC;
00446 }
00447 }
00448 ap->type = AVPOPS_VAL_INT;
00449 ap->u.n = flags<<8;
00450 }
00451
00452
00453 for( ; p&&*p ; p++ )
00454 {
00455 switch (*p)
00456 {
00457 case 'g':
00458 case 'G':
00459 ap->ops|=AVPOPS_FLAG_ALL;
00460 break;
00461 default:
00462 LM_ERR(" bad flag <%c>\n",*p);
00463 if(ap!=NULL)
00464 pkg_free(ap);
00465 return E_UNSPEC;
00466 }
00467 }
00468
00469 if (ap->opd&AVPOPS_VAL_NONE)
00470 ap->ops |= AVPOPS_FLAG_ALL;
00471
00472 *param=(void*)ap;
00473 }
00474
00475 return 0;
00476 }
00477
00478 static int fixup_copy_avp(void** param, int param_no)
00479 {
00480 struct fis_param *ap;
00481 char *s;
00482 char *p;
00483
00484 s = (char*)*param;
00485 ap = 0;
00486 p = 0;
00487
00488 if (param_no==2)
00489 {
00490
00491 if ( (p=strchr(s,'/'))!=0 )
00492 *(p++)=0;
00493 }
00494
00495 ap = avpops_parse_pvar(s);
00496 if (ap==0)
00497 {
00498 LM_ERR("unable to get pseudo-variable in P%d\n", param_no);
00499 return E_OUT_OF_MEM;
00500 }
00501
00502
00503 if (ap->u.sval.type!=PVT_AVP)
00504 {
00505 LM_ERR("you must specify only AVP as parameter\n");
00506 return E_UNSPEC;
00507 }
00508
00509 if (param_no==2)
00510 {
00511
00512 for( ; p&&*p ; p++ )
00513 {
00514 switch (*p) {
00515 case 'g':
00516 case 'G':
00517 ap->ops|=AVPOPS_FLAG_ALL;
00518 break;
00519 case 'd':
00520 case 'D':
00521 ap->ops|=AVPOPS_FLAG_DELETE;
00522 break;
00523 case 'n':
00524 case 'N':
00525 ap->ops|=AVPOPS_FLAG_CASTN;
00526 break;
00527 case 's':
00528 case 'S':
00529 ap->ops|=AVPOPS_FLAG_CASTS;
00530 break;
00531 default:
00532 LM_ERR("bad flag <%c>\n",*p);
00533 return E_UNSPEC;
00534 }
00535 }
00536 }
00537
00538 *param=(void*)ap;
00539 return 0;
00540 }
00541
00542 static int fixup_pushto_avp(void** param, int param_no)
00543 {
00544 struct fis_param *ap;
00545 char *s;
00546 char *p;
00547
00548 s = (char*)*param;
00549 ap = 0;
00550
00551 if (param_no==1)
00552 {
00553 if ( *s!='$')
00554 {
00555 LM_ERR("bad param 1; expected : $ru $du ...\n");
00556 return E_UNSPEC;
00557 }
00558
00559
00560 if ( (p=strchr(s,'/'))!=0 )
00561 *(p++)=0;
00562 ap = avpops_parse_pvar(s);
00563 if (ap==0)
00564 {
00565 LM_ERR("unable to get pseudo-variable in param 1\n");
00566 return E_OUT_OF_MEM;
00567 }
00568
00569 switch(ap->u.sval.type) {
00570 case PVT_RURI:
00571 ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_RURI;
00572 if ( p && !(
00573 (!strcasecmp("username",p)
00574 && (ap->opd|=AVPOPS_FLAG_USER0)) ||
00575 (!strcasecmp("domain",p)
00576 && (ap->opd|=AVPOPS_FLAG_DOMAIN0)) ))
00577 {
00578 LM_ERR("unknown ruri flag \"%s\"!\n",p);
00579 return E_UNSPEC;
00580 }
00581 break;
00582 case PVT_DSTURI:
00583 if ( p!=0 )
00584 {
00585 LM_ERR("unknown duri flag \"%s\"!\n",p);
00586 return E_UNSPEC;
00587 }
00588 ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_DURI;
00589 break;
00590 case PVT_HDR:
00591
00592 LM_ERR("push to header is obsoleted - use append_hf() "
00593 "or append_to_reply() from textops module!\n");
00594 return E_UNSPEC;
00595 break;
00596 case PVT_BRANCH:
00597 if ( p!=0 )
00598 {
00599 LM_ERR("unknown branch flag \"%s\"!\n",p);
00600 return E_UNSPEC;
00601 }
00602 ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_BRANCH;
00603 break;
00604 default:
00605 LM_ERR("unsupported destination \"%s\"; "
00606 "expected $ru,$du,$br\n",s);
00607 return E_UNSPEC;
00608 }
00609 } else if (param_no==2) {
00610
00611 if ( *s!='$')
00612 {
00613 LM_ERR("bad param 2; expected: $pseudo-variable ...\n");
00614 return E_UNSPEC;
00615 }
00616
00617
00618 if ( (p=strchr(s,'/'))!=0 )
00619 *(p++)=0;
00620 ap = avpops_parse_pvar(s);
00621 if (ap==0)
00622 {
00623 LM_ERR("unable to get pseudo-variable in param 2\n");
00624 return E_OUT_OF_MEM;
00625 }
00626 if (ap->u.sval.type==PVT_NULL)
00627 {
00628 LM_ERR("bad param 2; expected : $pseudo-variable ...\n");
00629 pkg_free(ap);
00630 return E_UNSPEC;
00631 }
00632 ap->opd |= AVPOPS_VAL_PVAR;
00633
00634
00635 for( ; p&&*p ; p++ )
00636 {
00637 switch (*p) {
00638 case 'g':
00639 case 'G':
00640 ap->ops|=AVPOPS_FLAG_ALL;
00641 break;
00642 default:
00643 LM_ERR("bad flag <%c>\n",*p);
00644 pkg_free(ap);
00645 return E_UNSPEC;
00646 }
00647 }
00648 }
00649
00650 *param=(void*)ap;
00651 return 0;
00652 }
00653
00654 static int fixup_check_avp(void** param, int param_no)
00655 {
00656 struct fis_param *ap;
00657 regex_t* re;
00658 char *s;
00659
00660 s = (char*)*param;
00661 ap = 0;
00662
00663 if (param_no==1)
00664 {
00665 ap = avpops_parse_pvar(s);
00666 if (ap==0)
00667 {
00668 LM_ERR("unable to get pseudo-variable in param 1\n");
00669 return E_OUT_OF_MEM;
00670 }
00671
00672 if (ap->u.sval.type==PVT_NULL)
00673 {
00674 LM_ERR("null pseudo-variable in param 1\n");
00675 return E_UNSPEC;
00676 }
00677 } else if (param_no==2) {
00678 if ( (ap=parse_check_value(s))==0 )
00679 {
00680 LM_ERR("failed to parse checked value \n");
00681 return E_UNSPEC;
00682 }
00683
00684 if (ap->ops&AVPOPS_OP_RE)
00685 {
00686 if ( (ap->opd&AVPOPS_VAL_STR)==0 )
00687 {
00688 LM_ERR("regexp operation requires string value\n");
00689 return E_UNSPEC;
00690 }
00691 re = pkg_malloc(sizeof(regex_t));
00692 if (re==0)
00693 {
00694 LM_ERR("no more pkg mem\n");
00695 return E_OUT_OF_MEM;
00696 }
00697 LM_DBG("compiling regexp <%.*s>\n", ap->u.s.len, ap->u.s.s);
00698 if (regcomp(re, ap->u.s.s,
00699 REG_EXTENDED|REG_ICASE|REG_NEWLINE))
00700 {
00701 pkg_free(re);
00702 LM_ERR("bad re <%.*s>\n", ap->u.s.len, ap->u.s.s);
00703 return E_BAD_RE;
00704 }
00705
00706
00707 ap->u.s.s = (char*)re;
00708 } else if (ap->ops&AVPOPS_OP_FM) {
00709 if ( !( ap->opd&AVPOPS_VAL_PVAR ||
00710 (!(ap->opd&AVPOPS_VAL_PVAR) && ap->opd&AVPOPS_VAL_STR) ) )
00711 {
00712 LM_ERR("fast_match operation requires string value or "
00713 "avp name/alias (%d/%d)\n", ap->opd, ap->ops);
00714 return E_UNSPEC;
00715 }
00716 }
00717 }
00718
00719 *param=(void*)ap;
00720 return 0;
00721 }
00722
00723 static int fixup_subst(void** param, int param_no)
00724 {
00725 struct subst_expr* se;
00726 str subst;
00727 struct fis_param *ap;
00728 struct fis_param **av;
00729 char *s;
00730 char *p;
00731
00732 if (param_no==1) {
00733 s = (char*)*param;
00734 ap = 0;
00735 p = 0;
00736 av = (struct fis_param**)pkg_malloc(2*sizeof(struct fis_param*));
00737 if(av==NULL)
00738 {
00739 LM_ERR("no more pkg memory\n");
00740 return E_UNSPEC;
00741 }
00742 memset(av, 0, 2*sizeof(struct fis_param*));
00743
00744
00745 if ( (p=strchr(s,'/'))!=0 )
00746 *(p++)=0;
00747 ap = avpops_parse_pvar(s);
00748 if (ap==0)
00749 {
00750 LM_ERR("unable to get pseudo-variable in param 2 [%s]\n", s);
00751 return E_OUT_OF_MEM;
00752 }
00753 if (ap->u.sval.type!=PVT_AVP)
00754 {
00755 LM_ERR("bad attribute name <%s>\n", (char*)*param);
00756 pkg_free(av);
00757 return E_UNSPEC;
00758 }
00759
00760 if (ap->opd&AVPOPS_VAL_NONE)
00761 {
00762 LM_ERR("you must specify a name for the AVP\n");
00763 return E_UNSPEC;
00764 }
00765 av[0] = ap;
00766 if(p==0 || *p=='\0')
00767 {
00768 *param=(void*)av;
00769 return 0;
00770 }
00771
00772
00773 s = p;
00774 if(*s==PV_MARKER)
00775 {
00776 if ( (p=strchr(s,'/'))!=0 )
00777 *(p++)=0;
00778 if(p==0 || (p!=0 && p-s>1))
00779 {
00780 ap = avpops_parse_pvar(s);
00781 if (ap==0)
00782 {
00783 LM_ERR("unable to get pseudo-variable in param 2 [%s]\n",s);
00784 return E_OUT_OF_MEM;
00785 }
00786
00787 if (ap->u.sval.type!=PVT_AVP)
00788 {
00789 LM_ERR("bad attribute name <%s>!\n", s);
00790 pkg_free(av);
00791 return E_UNSPEC;
00792 }
00793
00794 if (ap->opd&AVPOPS_VAL_NONE)
00795 {
00796 LM_ERR("you must specify a name for the AVP!\n");
00797 return E_UNSPEC;
00798 }
00799 av[1] = ap;
00800 }
00801 if(p==0 || *p=='\0')
00802 {
00803 *param=(void*)av;
00804 return 0;
00805 }
00806 }
00807
00808
00809 for( ; p&&*p ; p++ )
00810 {
00811 switch (*p) {
00812 case 'g':
00813 case 'G':
00814 av[0]->ops|=AVPOPS_FLAG_ALL;
00815 break;
00816 case 'd':
00817 case 'D':
00818 av[0]->ops|=AVPOPS_FLAG_DELETE;
00819 break;
00820 default:
00821 LM_ERR("bad flag <%c>\n",*p);
00822 return E_UNSPEC;
00823 }
00824 }
00825 *param=(void*)av;
00826 } else if (param_no==2) {
00827 LM_DBG("%s fixing %s\n", exports.name, (char*)(*param));
00828 subst.s=*param;
00829 subst.len=strlen(*param);
00830 se=subst_parser(&subst);
00831 if (se==0){
00832 LM_ERR("%s: bad subst re %s\n",exports.name, (char*)*param);
00833 return E_BAD_RE;
00834 }
00835
00836
00837
00838 *param=se;
00839 }
00840
00841 return 0;
00842 }
00843
00844 static int fixup_op_avp(void** param, int param_no)
00845 {
00846 struct fis_param *ap;
00847 struct fis_param **av;
00848 char *s;
00849 char *p;
00850
00851 s = (char*)*param;
00852 ap = 0;
00853
00854 if (param_no==1)
00855 {
00856 av = (struct fis_param**)pkg_malloc(2*sizeof(struct fis_param*));
00857 if(av==NULL)
00858 {
00859 LM_ERR("no more pkg memory\n");
00860 return E_UNSPEC;
00861 }
00862 memset(av, 0, 2*sizeof(struct fis_param*));
00863
00864 if ( (p=strchr(s,'/'))!=0 )
00865 *(p++)=0;
00866
00867 av[0] = avpops_parse_pvar(s);
00868 if (av[0]==0)
00869 {
00870 LM_ERR("unable to get pseudo-variable in param 1\n");
00871 return E_OUT_OF_MEM;
00872 }
00873 if (av[0]->u.sval.type!=PVT_AVP)
00874 {
00875 LM_ERR("bad attribute name <%s>\n", (char*)*param);
00876 pkg_free(av);
00877 return E_UNSPEC;
00878 }
00879 if(p==0 || *p=='\0')
00880 {
00881 *param=(void*)av;
00882 return 0;
00883 }
00884
00885 s = p;
00886 ap = avpops_parse_pvar(s);
00887 if (ap==0)
00888 {
00889 LM_ERR("unable to get pseudo-variable in param 1 (2)\n");
00890 return E_OUT_OF_MEM;
00891 }
00892 if (ap->u.sval.type!=PVT_AVP)
00893 {
00894 LM_ERR("bad attribute name/alias <%s>!\n", s);
00895 pkg_free(av);
00896 return E_UNSPEC;
00897 }
00898 av[1] = ap;
00899 *param=(void*)av;
00900 return 0;
00901 } else if (param_no==2) {
00902 if ( (ap=parse_op_value(s))==0 )
00903 {
00904 LM_ERR("failed to parse the value \n");
00905 return E_UNSPEC;
00906 }
00907
00908 if ( (ap->opd&AVPOPS_VAL_STR)!=0 && (ap->opd&AVPOPS_VAL_PVAR)==0)
00909 {
00910 LM_ERR("operations requires integer values\n");
00911 return E_UNSPEC;
00912 }
00913 *param=(void*)ap;
00914 return 0;
00915 }
00916 return -1;
00917 }
00918
00919 static int fixup_is_avp_set(void** param, int param_no)
00920 {
00921 struct fis_param *ap;
00922 char *p;
00923 char *s;
00924
00925 s = (char*)(*param);
00926 if (param_no==1) {
00927
00928 if ( (p=strchr(s,'/'))!=0 )
00929 *(p++)=0;
00930
00931 ap = avpops_parse_pvar(s);
00932 if (ap==0)
00933 {
00934 LM_ERR("unable to get pseudo-variable in param\n");
00935 return E_OUT_OF_MEM;
00936 }
00937
00938 if (ap->u.sval.type!=PVT_AVP)
00939 {
00940 LM_ERR("bad attribute name <%s>\n", (char*)*param);
00941 return E_UNSPEC;
00942 }
00943 if(p==0 || *p=='\0')
00944 ap->ops|=AVPOPS_FLAG_ALL;
00945
00946
00947 for( ; p&&*p ; p++ )
00948 {
00949 switch (*p) {
00950 case 'e':
00951 case 'E':
00952 ap->ops|=AVPOPS_FLAG_EMPTY;
00953 break;
00954 case 'n':
00955 case 'N':
00956 if(ap->ops&AVPOPS_FLAG_CASTS)
00957 {
00958 LM_ERR("invalid flag combination <%c> and 's|S'\n",*p);
00959 return E_UNSPEC;
00960 }
00961 ap->ops|=AVPOPS_FLAG_CASTN;
00962 break;
00963 case 's':
00964 case 'S':
00965 if(ap->ops&AVPOPS_FLAG_CASTN)
00966 {
00967 LM_ERR("invalid flag combination <%c> and 'n|N'\n",*p);
00968 return E_UNSPEC;
00969 }
00970 ap->ops|=AVPOPS_FLAG_CASTS;
00971 break;
00972 default:
00973 LM_ERR("bad flag <%c>\n",*p);
00974 return E_UNSPEC;
00975 }
00976 }
00977
00978 *param=(void*)ap;
00979 }
00980
00981 return 0;
00982 }
00983
00984 static int w_dbload_avps(struct sip_msg* msg, char* source, char* param)
00985 {
00986 return ops_dbload_avps ( msg, (struct fis_param*)source,
00987 (struct db_param*)param, use_domain);
00988 }
00989
00990 static int w_dbdelete_avps(struct sip_msg* msg, char* source, char* param)
00991 {
00992 return ops_dbdelete_avps ( msg, (struct fis_param*)source,
00993 (struct db_param*)param, use_domain);
00994 }
00995
00996 static int w_dbstore_avps(struct sip_msg* msg, char* source, char* param)
00997 {
00998 return ops_dbstore_avps ( msg, (struct fis_param*)source,
00999 (struct db_param*)param, use_domain);
01000 }
01001
01002 static int w_dbquery1_avps(struct sip_msg* msg, char* query, char* param)
01003 {
01004 return ops_dbquery_avps ( msg, (pv_elem_t*)query, 0);
01005 }
01006
01007 static int w_dbquery2_avps(struct sip_msg* msg, char* query, char* dest)
01008 {
01009 return ops_dbquery_avps ( msg, (pv_elem_t*)query, (pvname_list_t*)dest);
01010 }
01011
01012 static int w_delete_avps(struct sip_msg* msg, char* param, char* foo)
01013 {
01014 return ops_delete_avp ( msg, (struct fis_param*)param);
01015 }
01016
01017 static int w_copy_avps(struct sip_msg* msg, char* name1, char *name2)
01018 {
01019 return ops_copy_avp ( msg, (struct fis_param*)name1,
01020 (struct fis_param*)name2);
01021 }
01022
01023 static int w_pushto_avps(struct sip_msg* msg, char* destination, char *param)
01024 {
01025 return ops_pushto_avp ( msg, (struct fis_param*)destination,
01026 (struct fis_param*)param);
01027 }
01028
01029 static int w_check_avps(struct sip_msg* msg, char* param, char *check)
01030 {
01031 return ops_check_avp ( msg, (struct fis_param*)param,
01032 (struct fis_param*)check);
01033 }
01034
01035 static int w_op_avps(struct sip_msg* msg, char* param, char *op)
01036 {
01037 return ops_op_avp ( msg, (struct fis_param**)param,
01038 (struct fis_param*)op);
01039 }
01040
01041 static int w_subst(struct sip_msg* msg, char* src, char *subst)
01042 {
01043 return ops_subst(msg, (struct fis_param**)src, (struct subst_expr*)subst);
01044 }
01045
01046 static int w_is_avp_set(struct sip_msg* msg, char* param, char *op)
01047 {
01048 return ops_is_avp_set(msg, (struct fis_param*)param);
01049 }
01050
01051 static int w_print_avps(struct sip_msg* msg, char* foo, char *bar)
01052 {
01053 return ops_print_avp();
01054 }
01055