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 #include <stdlib.h>
00030 #include <string.h>
00031 #include <sys/types.h>
00032 #include <regex.h>
00033 #include <fnmatch.h>
00034
00035 #include "../../ut.h"
00036 #include "../../dprint.h"
00037 #include "../../usr_avp.h"
00038 #include "../../action.h"
00039 #include "../../ip_addr.h"
00040 #include "../../config.h"
00041 #include "../../dset.h"
00042 #include "../../data_lump.h"
00043 #include "../../data_lump_rpl.h"
00044 #include "../../pvar.h"
00045 #include "../../parser/parse_from.h"
00046 #include "../../parser/parse_uri.h"
00047 #include "../../mem/mem.h"
00048 #include "avpops_impl.h"
00049 #include "avpops_db.h"
00050
00051
00052 #define avpops_str2int_str(a, b) \
00053 do { \
00054 if(a.s==0) \
00055 b.n = a.len; \
00056 else \
00057 b.s = a; \
00058 } while(0)
00059
00060
00061 static db_key_t store_keys[6];
00062 static db_val_t store_vals[6];
00063 static str empty={"",0};
00064
00065
00066 #define AVP_PRINTBUF_SIZE 1024
00067 static char printbuf[AVP_PRINTBUF_SIZE];
00068
00069 void init_store_avps(str **db_columns)
00070 {
00071
00072 store_keys[0] = db_columns[0];
00073 store_vals[0].type = DB_STR;
00074 store_vals[0].nul = 0;
00075
00076 store_keys[1] = db_columns[1];
00077 store_vals[1].type = DB_STR;
00078 store_vals[1].nul = 0;
00079
00080 store_keys[2] = db_columns[2];
00081 store_vals[2].type = DB_STR;
00082 store_vals[2].nul = 0;
00083
00084 store_keys[3] = db_columns[3];
00085 store_vals[3].type = DB_INT;
00086 store_vals[3].nul = 0;
00087
00088 store_keys[4] = db_columns[4];
00089 store_vals[4].type = DB_STR;
00090 store_vals[4].nul = 0;
00091
00092 store_keys[5] = db_columns[5];
00093 store_vals[5].type = DB_STR;
00094 store_vals[5].nul = 0;
00095 }
00096
00097
00098
00099
00100
00101
00102 static int dbrow2avp(struct db_row *row, struct db_param *dbp, int_str attr,
00103 int attr_type, int just_val_flags)
00104 {
00105 unsigned int uint;
00106 int db_flags;
00107 str atmp;
00108 str vtmp;
00109 int_str avp_attr;
00110 int_str avp_val;
00111 int flags;
00112
00113 flags = dbp->a.opd;
00114
00115 if (just_val_flags==-1)
00116 {
00117
00118 if (row->values[0].nul || row->values[1].nul || row->values[2].nul )
00119 {
00120 LM_ERR("dbrow contains NULL fields\n");
00121 return -1;
00122 }
00123
00124
00125 if ( (row->values[0].type!=DB_STRING && row->values[0].type!=DB_STR)
00126 || (row->values[1].type!=DB_STRING && row->values[1].type!=DB_STR)
00127 || row->values[2].type!=DB_INT )
00128 {
00129 LM_ERR("wrong field types in dbrow\n");
00130 return -1;
00131 }
00132
00133
00134 uint = (unsigned int)row->values[2].val.int_val;
00135 db_flags = ((uint&AVPOPS_DB_NAME_INT)?0:AVP_NAME_STR) |
00136 ((uint&AVPOPS_DB_VAL_INT)?0:AVP_VAL_STR);
00137
00138 LM_DBG("db_flags=%d, flags=%d\n",db_flags,flags);
00139
00140 if(!((flags&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 ||
00141 ((flags&AVPOPS_VAL_INT)&&((db_flags&AVP_NAME_STR)==0)) ||
00142 ((flags&AVPOPS_VAL_STR)&&(db_flags&AVP_NAME_STR))))
00143 return -2;
00144 } else {
00145
00146 if (row->values[0].nul || (row->values[0].type!=DB_STRING &&
00147 row->values[0].type!=DB_STR && row->values[0].type!=DB_INT) )
00148 {
00149 LM_ERR("empty or wrong type for 'value' using scheme\n");
00150 return -1;
00151 }
00152 db_flags = just_val_flags;
00153 }
00154
00155
00156 if ( (flags&AVPOPS_VAL_NONE)==0 )
00157 {
00158
00159 avp_attr = attr;
00160 db_flags |= attr_type;
00161 } else {
00162
00163 if (row->values[1].type==DB_STRING)
00164 {
00165 atmp.s = (char*)row->values[1].val.string_val;
00166 atmp.len = strlen(atmp.s);
00167 } else {
00168 atmp = row->values[1].val.str_val;
00169 }
00170 if (db_flags&AVP_NAME_STR)
00171 {
00172
00173 avp_attr.s = atmp;
00174 } else {
00175
00176 if (str2int( &atmp, &uint)==-1)
00177 {
00178 LM_ERR("name is not ID as flags say <%s>\n", atmp.s);
00179 return -1;
00180 }
00181 avp_attr.n = (int)uint;
00182 }
00183 }
00184
00185
00186 if (row->values[0].type==DB_STRING)
00187 {
00188 vtmp.s = (char*)row->values[0].val.string_val;
00189 vtmp.len = strlen(vtmp.s);
00190 } else if (row->values[0].type==DB_STR){
00191 vtmp = row->values[0].val.str_val;
00192 } else {
00193 vtmp.s = 0;
00194 vtmp.len = 0;
00195 }
00196 if (db_flags&AVP_VAL_STR) {
00197
00198 if (row->values[0].type==DB_INT) {
00199 vtmp.s = int2str( (unsigned long)row->values[0].val.int_val,
00200 &vtmp.len);
00201 }
00202 avp_val.s = vtmp;
00203 } else {
00204
00205 if (row->values[0].type!=DB_INT) {
00206 if (vtmp.len==0 || vtmp.s==0 || str2int(&vtmp, &uint)==-1) {
00207 LM_ERR("value is not int as flags say <%s>\n", vtmp.s);
00208 return -1;
00209 }
00210 avp_val.n = (int)uint;
00211 } else {
00212 avp_val.n = row->values[0].val.int_val;
00213 }
00214 }
00215
00216
00217 db_flags |= AVP_IS_IN_DB;
00218
00219 db_flags |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00;
00220 return add_avp( (unsigned short)db_flags, avp_attr, avp_val);
00221 }
00222
00223
00224 inline static str* get_source_uri(struct sip_msg* msg,int source)
00225 {
00226
00227 if (source&AVPOPS_USE_FROM)
00228 {
00229 if (parse_from_header( msg )<0 )
00230 {
00231 LM_ERR("failed to parse from\n");
00232 goto error;
00233 }
00234 return &(get_from(msg)->uri);
00235 } else if (source&AVPOPS_USE_TO)
00236 {
00237 if (parse_headers( msg, HDR_TO_F, 0)<0)
00238 {
00239 LM_ERR("failed to parse to\n");
00240 goto error;
00241 }
00242 return &(get_to(msg)->uri);
00243 } else if (source&AVPOPS_USE_RURI) {
00244 if(msg->new_uri.s!=NULL && msg->new_uri.len>0)
00245 return &(msg->new_uri);
00246 return &(msg->first_line.u.request.uri);
00247 } else {
00248 LM_ERR("unknow source <%d>\n", source);
00249 goto error;
00250 }
00251 error:
00252 return 0;
00253 }
00254
00255 static inline void int_str2db_val( int_str is_val, str *val, int is_s)
00256 {
00257 if (is_s)
00258 {
00259
00260 *val = is_val.s;
00261 } else {
00262
00263 val->s =
00264 int2str((unsigned long)is_val.n, &val->len);
00265 }
00266 }
00267
00268 static int avpops_get_aname(struct sip_msg* msg, struct fis_param *ap,
00269 int_str *avp_name, unsigned short *name_type)
00270 {
00271 if(ap==NULL || avp_name==NULL || name_type==NULL)
00272 {
00273 LM_ERR("bad parameters\n");
00274 return -1;
00275 }
00276
00277 return pv_get_avp_name(msg, &ap->u.sval.pvp, avp_name, name_type);
00278 }
00279
00280 #define AVPOPS_ATTR_LEN 64
00281 static char avpops_attr_buf[AVPOPS_ATTR_LEN];
00282
00283 int ops_dbload_avps (struct sip_msg* msg, struct fis_param *sp,
00284 struct db_param *dbp, int use_domain)
00285 {
00286 struct sip_uri uri;
00287 db_res_t *res = NULL;
00288 str uuid;
00289 int i, n, sh_flg;
00290 str *s0, *s1, *s2;
00291 int_str avp_name;
00292 int avp_type = 0;
00293 pv_value_t xvalue;
00294
00295 s0 = s1 = s2 = NULL;
00296 if (!((sp->opd&AVPOPS_VAL_PVAR)||(sp->opd&AVPOPS_VAL_STR))) {
00297 LM_CRIT("invalid flag combination (%d/%d)\n", sp->opd, sp->ops);
00298 goto error;
00299 }
00300
00301
00302 if (sp->opd&AVPOPS_VAL_PVAR)
00303 {
00304 if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0)
00305 {
00306 LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops);
00307 goto error;
00308 }
00309 if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY))
00310 {
00311 LM_ERR("no value for first param\n");
00312 goto error;
00313 }
00314 uuid = xvalue.rs;
00315 } else {
00316 uuid.s = sp->u.s.s;
00317 uuid.len = sp->u.s.len;
00318 }
00319
00320 if(sp->opd&AVPOPS_FLAG_UUID0)
00321 {
00322 s0 = &uuid;
00323 } else {
00324
00325 if (parse_uri(uuid.s, uuid.len, &uri)<0)
00326 {
00327 LM_ERR("failed to parse uri\n");
00328 goto error;
00329 }
00330
00331
00332 if(!uri.user.s|| !uri.user.len|| !uri.host.len|| !uri.host.s)
00333 {
00334 LM_ERR("incomplet uri <%.*s>\n", uuid.len, uuid.s);
00335 goto error;
00336 }
00337 if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_USER0))
00338 s1 = &uri.user;
00339 if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_DOMAIN0))
00340 s2 = &uri.host;
00341 }
00342
00343
00344 if(dbp->a.type==AVPOPS_VAL_PVAR)
00345 {
00346 if(pv_has_dname(&(dbp->a.u.sval)))
00347 {
00348 if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0)
00349 {
00350 LM_CRIT("failed to get value for P2\n");
00351 goto error;
00352 }
00353 if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY))
00354 {
00355 LM_ERR("no value for p2\n");
00356 goto error;
00357 }
00358 if(xvalue.flags&PV_VAL_STR)
00359 {
00360 if(xvalue.rs.len>=AVPOPS_ATTR_LEN)
00361 {
00362 LM_ERR("name too long [%d/%.*s...]\n",
00363 xvalue.rs.len, 16, xvalue.rs.s);
00364 goto error;
00365 }
00366 dbp->sa.s = avpops_attr_buf;
00367 memcpy(dbp->sa.s, xvalue.rs.s, xvalue.rs.len);
00368 dbp->sa.len = xvalue.rs.len;
00369 dbp->sa.s[dbp->sa.len] = '\0';
00370 } else {
00371 LM_INFO("no string value for p2\n");
00372 goto error;
00373 }
00374 }
00375 }
00376
00377
00378 res = db_load_avp( s0, s1,
00379 ((use_domain)||(sp->opd&AVPOPS_FLAG_DOMAIN0))?s2:0,
00380 dbp->sa.s, &dbp->table, dbp->scheme);
00381
00382
00383 if (res==0)
00384 {
00385 LM_ERR("db_load failed\n");
00386 goto error;
00387 }
00388
00389 sh_flg = (dbp->scheme)?dbp->scheme->db_flags:-1;
00390
00391 for( n=0,i=0 ; i<res->n ; i++)
00392 {
00393
00394 memset(&avp_name, 0, sizeof(int_str));
00395 if(dbp->a.type==AVPOPS_VAL_PVAR)
00396 {
00397 if(pv_has_dname(&dbp->a.u.sval))
00398 {
00399 if(xvalue.flags&PV_TYPE_INT)
00400 {
00401 avp_name.n = xvalue.ri;
00402 } else {
00403 avpops_str2int_str(xvalue.rs, avp_name);
00404 avp_type = AVP_NAME_STR;
00405 }
00406 } else {
00407 avp_name = dbp->a.u.sval.pvp.pvn.u.isname.name;
00408 avp_type = dbp->a.u.sval.pvp.pvn.u.isname.type;
00409 }
00410 }
00411
00412 if ( dbrow2avp( &res->rows[i], dbp, avp_name, avp_type, sh_flg) < 0 )
00413 continue;
00414 n++;
00415 }
00416
00417 db_close_query( res );
00418
00419 LM_DBG("loaded avps = %d\n",n);
00420
00421 return n?1:-1;
00422 error:
00423 return -1;
00424 }
00425
00426
00427 int ops_dbdelete_avps (struct sip_msg* msg, struct fis_param *sp,
00428 struct db_param *dbp, int use_domain)
00429 {
00430 struct sip_uri uri;
00431 int res;
00432 str uuid;
00433 pv_value_t xvalue;
00434 str *s0, *s1, *s2;
00435
00436 s0 = s1 = s2 = NULL;
00437 if (!((sp->opd&AVPOPS_VAL_PVAR)||(sp->opd&AVPOPS_VAL_STR))) {
00438 LM_CRIT("invalid flag combination (%d/%d)\n", sp->opd, sp->ops);
00439 goto error;
00440 }
00441
00442
00443 if (sp->opd&AVPOPS_VAL_PVAR)
00444 {
00445 if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0)
00446 {
00447 LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops);
00448 goto error;
00449 }
00450 if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY))
00451 {
00452 LM_ERR("no value for first param\n");
00453 goto error;
00454 }
00455 uuid = xvalue.rs;
00456 } else {
00457 uuid.s = sp->u.s.s;
00458 uuid.len = sp->u.s.len;
00459 }
00460
00461 if(sp->opd&AVPOPS_FLAG_UUID0)
00462 {
00463 s0 = &uuid;
00464 } else {
00465
00466 if (parse_uri(uuid.s, uuid.len, &uri)<0)
00467 {
00468 LM_ERR("failed to parse uri\n");
00469 goto error;
00470 }
00471
00472
00473 if(!uri.user.s|| !uri.user.len|| !uri.host.len|| !uri.host.s)
00474 {
00475 LM_ERR("incomplet uri <%.*s>\n", uuid.len, uuid.s);
00476 goto error;
00477 }
00478 if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_USER0))
00479 s1 = &uri.user;
00480 if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_DOMAIN0))
00481 s2 = &uri.host;
00482 }
00483
00484
00485 if(dbp->a.type==AVPOPS_VAL_PVAR)
00486 {
00487 if(pv_has_dname(&dbp->a.u.sval))
00488 {
00489 if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0)
00490 {
00491 LM_CRIT("failed to get value for P2\n");
00492 goto error;
00493 }
00494 if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY))
00495 {
00496 LM_INFO("no value for p2\n");
00497 goto error;
00498 }
00499 if(xvalue.flags&PV_VAL_STR)
00500 {
00501 if(xvalue.rs.len>=AVPOPS_ATTR_LEN)
00502 {
00503 LM_ERR("name too long [%d/%.*s...]\n",
00504 xvalue.rs.len, 16, xvalue.rs.s);
00505 goto error;
00506 }
00507 dbp->sa.s = avpops_attr_buf;
00508 memcpy(dbp->sa.s, xvalue.rs.s, xvalue.rs.len);
00509 dbp->sa.len = xvalue.rs.len;
00510 dbp->sa.s[dbp->sa.len] = '\0';
00511 } else {
00512 LM_INFO("no string value for p2\n");
00513 goto error;
00514 }
00515 }
00516 }
00517
00518
00519 res = db_delete_avp(s0, s1,
00520 (use_domain||(sp->opd&AVPOPS_FLAG_DOMAIN0))?s2:0,
00521 dbp->sa.s, &dbp->table);
00522
00523
00524 if (res<0)
00525 {
00526 LM_ERR("db_delete failed\n");
00527 goto error;
00528 }
00529
00530 return 1;
00531 error:
00532 return -1;
00533 }
00534
00535
00536 int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp,
00537 struct db_param *dbp, int use_domain)
00538 {
00539 struct sip_uri uri;
00540 struct usr_avp **avp_list;
00541 struct usr_avp *avp;
00542 unsigned short name_type;
00543 int_str avp_name;
00544 int_str i_s;
00545 str uuid;
00546 int keys_nr;
00547 int n;
00548 pv_value_t xvalue;
00549 str *s0, *s1, *s2;
00550 str *sn;
00551
00552 s0 = s1 = s2 = NULL;
00553 name_type = 0;
00554 if (!((sp->opd&AVPOPS_VAL_PVAR)||(sp->opd&AVPOPS_VAL_STR))) {
00555 LM_CRIT("invalid flag combination (%d/%d)\n", sp->opd, sp->ops);
00556 goto error;
00557 }
00558
00559 keys_nr = 6;
00560
00561
00562 if (sp->opd&AVPOPS_VAL_PVAR)
00563 {
00564 if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0)
00565 {
00566 LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops);
00567 goto error;
00568 }
00569 if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY))
00570 {
00571 LM_ERR("no value for first param\n");
00572 goto error;
00573 }
00574 uuid = xvalue.rs;
00575 } else {
00576 uuid.s = sp->u.s.s;
00577 uuid.len = sp->u.s.len;
00578 }
00579
00580 if(sp->opd&AVPOPS_FLAG_UUID0)
00581 {
00582 s0 = &uuid;
00583 } else {
00584
00585 if (parse_uri(uuid.s, uuid.len, &uri)<0)
00586 {
00587 LM_ERR("failed to parse uri\n");
00588 goto error;
00589 }
00590
00591
00592 if(!uri.user.s|| !uri.user.len|| !uri.host.len|| !uri.host.s)
00593 {
00594 LM_ERR("incomplet uri <%.*s>\n", uuid.len, uuid.s);
00595 goto error;
00596 }
00597 if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_USER0))
00598 s1 = &uri.user;
00599 if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_DOMAIN0))
00600 s2 = &uri.host;
00601 }
00602
00603
00604 store_vals[0].val.str_val = (s0)?*s0:empty;
00605 store_vals[4].val.str_val = (s1)?*s1:empty;
00606 if (use_domain || sp->opd&AVPOPS_FLAG_DOMAIN0)
00607 store_vals[5].val.str_val = (s2)?*s2:empty;
00608
00609
00610 if(dbp->a.type==AVPOPS_VAL_PVAR)
00611 {
00612 if(pv_has_dname(&dbp->a.u.sval))
00613 {
00614 if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0)
00615 {
00616 LM_CRIT("failed to get value for P2\n");
00617 goto error;
00618 }
00619 if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY))
00620 {
00621 LM_INFO("no value for P2\n");
00622 goto error;
00623 }
00624 if(xvalue.flags&PV_TYPE_INT)
00625 {
00626 name_type = 0;
00627 avp_name.n = xvalue.ri;
00628 } else {
00629 name_type = AVP_NAME_STR;
00630 }
00631 if(xvalue.flags&PV_VAL_STR)
00632 {
00633 if(xvalue.rs.len>=AVPOPS_ATTR_LEN)
00634 {
00635 LM_ERR("name too long [%d/%.*s...]\n",
00636 xvalue.rs.len, 16, xvalue.rs.s);
00637 goto error;
00638 }
00639 dbp->sa.s = avpops_attr_buf;
00640 memcpy(dbp->sa.s, xvalue.rs.s, xvalue.rs.len);
00641 dbp->sa.len = xvalue.rs.len;
00642 dbp->sa.s[dbp->sa.len] = '\0';
00643 avp_name.s = dbp->sa;
00644 } else {
00645 LM_INFO("no string value for p2\n");
00646 goto error;
00647 }
00648 } else {
00649 name_type = dbp->a.u.sval.pvp.pvn.u.isname.type;
00650 avp_name = dbp->a.u.sval.pvp.pvn.u.isname.name;
00651 }
00652 }
00653
00654
00655 if(dbp->a.type==AVPOPS_VAL_PVAR)
00656 name_type |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00;
00657
00658
00659
00660 n =0 ;
00661
00662 if ((dbp->a.opd&AVPOPS_VAL_NONE)==0)
00663 {
00664
00665 store_vals[1].val.str_val = dbp->sa;
00666 avp = search_first_avp( name_type, avp_name, &i_s, 0);
00667 for( ; avp; avp=search_first_avp( name_type, avp_name, &i_s, avp))
00668 {
00669
00670 if (avp->flags&AVP_IS_IN_DB)
00671 continue;
00672
00673 store_vals[3].val.int_val =
00674 (avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)|
00675 (avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT);
00676
00677 int_str2db_val( i_s, &store_vals[2].val.str_val,
00678 avp->flags&AVP_VAL_STR);
00679
00680 if (db_store_avp( store_keys, store_vals,
00681 keys_nr, &dbp->table)==0 )
00682 {
00683 avp->flags |= AVP_IS_IN_DB;
00684 n++;
00685 }
00686 }
00687 } else {
00688
00689 avp_list = get_avp_list();
00690 avp = *avp_list;
00691
00692 for ( ; avp ; avp=avp->next )
00693 {
00694
00695 if (avp->flags&AVP_IS_IN_DB)
00696 continue;
00697
00698 if ( !( (dbp->a.opd&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 ||
00699 ((dbp->a.opd&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0)
00700 ||((dbp->a.opd&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR))))
00701 continue;
00702
00703
00704 if ( (sn=get_avp_name(avp))==0 )
00705 i_s.n = avp->id;
00706 else
00707 i_s.s = *sn;
00708 int_str2db_val( i_s, &store_vals[1].val.str_val,
00709 avp->flags&AVP_NAME_STR);
00710 store_vals[3].val.int_val =
00711 (avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)|
00712 (avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT);
00713
00714 get_avp_val( avp, &i_s);
00715 int_str2db_val( i_s, &store_vals[2].val.str_val,
00716 avp->flags&AVP_VAL_STR);
00717
00718 if (db_store_avp( store_keys, store_vals,
00719 keys_nr, &dbp->table)==0)
00720 {
00721 avp->flags |= AVP_IS_IN_DB;
00722 n++;
00723 }
00724 }
00725 }
00726
00727 LM_DBG(" %d avps were stored\n",n);
00728
00729 return n==0?-1:1;
00730 error:
00731 return -1;
00732 }
00733
00734 int ops_dbquery_avps(struct sip_msg* msg, pv_elem_t* query,
00735 pvname_list_t* dest)
00736 {
00737 int printbuf_len;
00738 int r;
00739
00740 if(msg==NULL || query==NULL)
00741 {
00742 LM_ERR("bad parameters\n");
00743 return -1;
00744 }
00745
00746 printbuf_len = AVP_PRINTBUF_SIZE-1;
00747 if(pv_printf(msg, query, printbuf, &printbuf_len)<0 || printbuf_len<=0)
00748 {
00749 LM_ERR("cannot print the query\n");
00750 return -1;
00751 }
00752
00753 LM_DBG("query [%s]\n", printbuf);
00754
00755 r = db_query_avp(msg, printbuf, dest);
00756 if(r>=0)
00757 return 1;
00758 return r;
00759 }
00760
00761
00762 int ops_delete_avp(struct sip_msg* msg, struct fis_param *ap)
00763 {
00764 struct usr_avp **avp_list;
00765 struct usr_avp *avp;
00766 struct usr_avp *avp_next;
00767 unsigned short name_type;
00768 int_str avp_name;
00769 int n;
00770
00771 n = 0;
00772
00773 if ((ap->opd&AVPOPS_VAL_NONE)==0)
00774 {
00775
00776
00777 if(avpops_get_aname(msg, ap, &avp_name, &name_type)!=0)
00778 {
00779 LM_ERR("failed to get dst AVP name\n");
00780 return -1;
00781 }
00782 n = destroy_avps( name_type, avp_name, ap->ops&AVPOPS_FLAG_ALL );
00783 } else {
00784
00785
00786 avp_list = get_avp_list();
00787 avp = *avp_list;
00788
00789 for ( ; avp ; avp=avp_next )
00790 {
00791 avp_next = avp->next;
00792
00793 if ( !( (ap->opd&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 ||
00794 ((ap->opd&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0) ||
00795 ((ap->opd&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR)) ) )
00796 continue;
00797 if((ap->u.sval.pvp.pvn.u.isname.type&AVP_SCRIPT_MASK)!=0
00798 && ((ap->u.sval.pvp.pvn.u.isname.type&AVP_SCRIPT_MASK)
00799 &avp->flags)==0)
00800 continue;
00801
00802 destroy_avp( avp );
00803 n++;
00804 if ( !(ap->ops&AVPOPS_FLAG_ALL) )
00805 break;
00806 }
00807 }
00808
00809 LM_DBG("%d avps were removed\n",n);
00810
00811 return n?1:-1;
00812 }
00813
00814 int ops_copy_avp( struct sip_msg* msg, struct fis_param* src,
00815 struct fis_param* dst)
00816 {
00817 struct usr_avp *avp;
00818 struct usr_avp *prev_avp;
00819 int_str avp_val;
00820 int_str avp_val2;
00821 unsigned short name_type1;
00822 unsigned short name_type2;
00823 int_str avp_name1;
00824 int_str avp_name2;
00825 int n;
00826
00827 n = 0;
00828 prev_avp = 0;
00829
00830
00831 if(avpops_get_aname(msg, src, &avp_name1, &name_type1)!=0)
00832 {
00833 LM_ERR("failed to get src AVP name\n");
00834 goto error;
00835 }
00836
00837 if(avpops_get_aname(msg, dst, &avp_name2, &name_type2)!=0)
00838 {
00839 LM_ERR("failed to get dst AVP name\n");
00840 goto error;
00841 }
00842
00843 avp = search_first_avp( name_type1, avp_name1, &avp_val, 0);
00844 while ( avp )
00845 {
00846
00847
00848 if((avp->flags&AVP_VAL_STR) && (dst->ops&AVPOPS_FLAG_CASTN)) {
00849 if(str2int(&avp_val.s, (unsigned int*)&avp_val2.n)!=0)
00850 {
00851 LM_ERR("cannot convert str to int\n");
00852 goto error;
00853 }
00854 if ( add_avp( name_type2, avp_name2, avp_val2)==-1 ) {
00855 LM_ERR("failed to create new avp!\n");
00856 goto error;
00857 }
00858 } else if(!(avp->flags&AVP_VAL_STR)&&(dst->ops&AVPOPS_FLAG_CASTS)) {
00859 avp_val2.s.s = int2str(avp_val.n, &avp_val2.s.len);
00860 if ( add_avp( name_type2|AVP_VAL_STR, avp_name2, avp_val2)==-1 ) {
00861 LM_ERR("failed to create new avp.\n");
00862 goto error;
00863 }
00864 } else {
00865 if ( add_avp( name_type2|(avp->flags&AVP_VAL_STR), avp_name2,
00866 avp_val)==-1 ) {
00867 LM_ERR("failed to create new avp\n");
00868 goto error;
00869 }
00870 }
00871 n++;
00872
00873 if ( !(dst->ops&AVPOPS_FLAG_ALL) ) {
00874
00875 if (dst->ops&AVPOPS_FLAG_DELETE)
00876 destroy_avp( avp );
00877 break;
00878 } else {
00879 prev_avp = avp;
00880 avp = search_first_avp( name_type1, avp_name1, &avp_val, prev_avp);
00881
00882 if (dst->ops&AVPOPS_FLAG_DELETE)
00883 destroy_avp( prev_avp );
00884 }
00885 }
00886
00887 return n?1:-1;
00888 error:
00889 return -1;
00890 }
00891
00892
00893 #define STR_BUF_SIZE 1024
00894 static char str_buf[STR_BUF_SIZE];
00895
00896 inline static int append_0(str *in, str *out)
00897 {
00898 if (in->len+1>STR_BUF_SIZE)
00899 return -1;
00900 memcpy( str_buf, in->s, in->len);
00901 str_buf[in->len] = 0;
00902 out->len = in->len;
00903 out->s = str_buf;
00904 return 0;
00905 }
00906
00907
00908 int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst,
00909 struct fis_param* src)
00910 {
00911 struct action act;
00912 struct usr_avp *avp;
00913 unsigned short name_type;
00914 int_str avp_val;
00915 int_str avp_name;
00916 str val;
00917 int act_type;
00918 int n;
00919 int flags;
00920 pv_value_t xvalue;
00921
00922 avp = NULL;
00923 flags = 0;
00924 if(src->u.sval.type==PVT_AVP)
00925 {
00926
00927 if(avpops_get_aname(msg, src, &avp_name, &name_type)!=0)
00928 {
00929 LM_ERR("failed to get src AVP name\n");
00930 goto error;
00931 }
00932 avp = search_first_avp( name_type, avp_name, &avp_val, 0);
00933 if (avp==0)
00934 {
00935 LM_DBG(" no src avp found\n");
00936 goto error;
00937 }
00938 flags = avp->flags;
00939 } else {
00940 if(pv_get_spec_value(msg, &(src->u.sval), &xvalue)!=0)
00941 {
00942 LM_ERR("cannot get src value\n");
00943 goto error;
00944 }
00945 if(xvalue.flags&PV_TYPE_INT)
00946 {
00947 avp_val.n = xvalue.ri;
00948 } else {
00949 flags = AVP_VAL_STR;
00950 avp_val.s = xvalue.rs;
00951 }
00952 }
00953
00954 n = 0;
00955 do {
00956
00957 if (flags&AVP_VAL_STR) {
00958 val = avp_val.s;
00959 } else {
00960 val.s = int2str((unsigned long)avp_val.n, &val.len);
00961 }
00962
00963 act_type = 0;
00964
00965 if (dst->opd&AVPOPS_USE_RURI)
00966 {
00967 if (dst->opd&AVPOPS_FLAG_USER0)
00968 act_type = SET_USER_T;
00969 else if (dst->opd&AVPOPS_FLAG_DOMAIN0)
00970 act_type = SET_HOST_T;
00971 else
00972 act_type = SET_URI_T;
00973 if ( flags&AVP_VAL_STR && append_0( &val, &val)!=0 ) {
00974 LM_ERR("failed to make 0 term.\n");
00975 goto error;
00976 }
00977 } else if (dst->opd&AVPOPS_USE_DURI) {
00978 if (!(flags&AVP_VAL_STR)) {
00979 goto error;
00980 }
00981 } else if (dst->opd&AVPOPS_USE_BRANCH) {
00982 if (!(flags&AVP_VAL_STR)) {
00983 goto error;
00984 }
00985 } else {
00986 LM_CRIT("destination unknown (%d/%d)\n", dst->opd, dst->ops);
00987 goto error;
00988 }
00989
00990 if ( act_type )
00991 {
00992
00993 if (n)
00994 {
00995
00996
00997 if (append_branch( msg, 0, 0, 0, Q_UNSPECIFIED, 0, 0)!=1 )
00998 {
00999 LM_ERR("append_branch action failed\n");
01000 goto error;
01001 }
01002 }
01003 memset(&act, 0, sizeof(act));
01004 act.elem[0].type = STRING_ST;
01005 act.elem[0].u.string = val.s;
01006 act.type = act_type;
01007 if (do_action(&act, msg)<0)
01008 {
01009 LM_ERR("SET_XXXX_T action failed\n");
01010 goto error;
01011 }
01012 } else if (dst->opd&AVPOPS_USE_DURI) {
01013 if(set_dst_uri(msg, &val)!=0)
01014 {
01015 LM_ERR("changing dst uri failed\n");
01016 goto error;
01017 }
01018 } else if (dst->opd&AVPOPS_USE_BRANCH) {
01019 if (append_branch( msg, &val, 0, 0, Q_UNSPECIFIED, 0,
01020 msg->force_send_socket)!=1 )
01021 {
01022 LM_ERR("append_branch action failed\n");
01023 goto error;
01024 }
01025 } else {
01026 LM_ERR("unknown destination\n");
01027 goto error;
01028 }
01029
01030 n++;
01031 if ( !(src->ops&AVPOPS_FLAG_ALL) )
01032 break;
01033 if(avp==NULL)
01034 break;
01035 if((avp = search_first_avp( name_type, avp_name, &avp_val, avp))!=NULL)
01036 flags = avp->flags;
01037 } while (avp);
01038
01039 LM_DBG("%d avps were processed\n",n);
01040 return 1;
01041 error:
01042 return -1;
01043 }
01044
01045 int ops_check_avp( struct sip_msg* msg, struct fis_param* src,
01046 struct fis_param* val)
01047 {
01048 unsigned short name_type1;
01049 unsigned short name_type2;
01050 struct usr_avp *avp1;
01051 struct usr_avp *avp2;
01052 regmatch_t pmatch;
01053 int_str avp_name1;
01054 int_str avp_name2;
01055 int_str avp_val;
01056 int_str check_val;
01057 int check_flags;
01058 int n, rt;
01059 int flags;
01060 pv_value_t xvalue;
01061 char backup;
01062
01063
01064 if(src->u.sval.type==PVT_AVP)
01065 {
01066
01067 if(avpops_get_aname(msg, src, &avp_name1, &name_type1)!=0)
01068 {
01069 LM_ERR("failed to get src AVP name\n");
01070 goto error;
01071 }
01072 avp1 = search_first_avp( name_type1, avp_name1, &avp_val, 0);
01073 if (avp1==0)
01074 {
01075 LM_DBG("no src avp found\n");
01076 goto error;
01077 }
01078 flags = avp1->flags;
01079 } else {
01080 avp1 = 0;
01081 flags = 0;
01082 if(pv_get_spec_value(msg, &(src->u.sval), &xvalue)!=0)
01083 {
01084 LM_ERR("cannot get src value\n");
01085 goto error;
01086 }
01087 if(xvalue.flags&PV_TYPE_INT)
01088 {
01089 avp_val.n = xvalue.ri;
01090 } else {
01091 flags = AVP_VAL_STR;
01092 avp_val.s = xvalue.rs;
01093 }
01094 }
01095
01096 cycle1:
01097
01098 if(flags&AVP_VAL_STR)
01099 {
01100 if(avp_val.s.len>=STR_BUF_SIZE)
01101 {
01102 LM_ERR("src value too long\n");
01103 goto error;
01104 }
01105 strncpy(str_buf, avp_val.s.s, avp_val.s.len);
01106 str_buf[avp_val.s.len] = '\0';
01107 avp_val.s.s = str_buf;
01108 }
01109
01110 if (val->opd&AVPOPS_VAL_PVAR)
01111 {
01112
01113 check_flags = 0;
01114 if(val->u.sval.type==PVT_AVP)
01115 {
01116
01117 if(avpops_get_aname(msg, val, &avp_name2, &name_type2)!=0)
01118 {
01119 LM_ERR("failed to get dst AVP name\n");
01120 goto error;
01121 }
01122 avp2 = search_first_avp( name_type2, avp_name2, &check_val, 0);
01123 if (avp2==0)
01124 {
01125 LM_DBG("no dst avp found\n");
01126 goto error;
01127 }
01128 check_flags = avp2->flags;
01129 } else {
01130 avp2 = 0;
01131 if(pv_get_spec_value(msg, &(val->u.sval), &xvalue)!=0)
01132 {
01133 LM_ERR("cannot get dst value\n");
01134 goto error;
01135 }
01136 if(xvalue.flags&PV_TYPE_INT)
01137 {
01138 check_val.n = xvalue.ri;
01139 } else {
01140 check_flags = AVP_VAL_STR;
01141 check_val.s = xvalue.rs;
01142 }
01143 }
01144 } else {
01145 check_flags = 0;
01146 if(val->type == AVPOPS_VAL_INT)
01147 {
01148 check_val.n = val->u.n;
01149 } else {
01150 check_val.s = val->u.s;
01151 check_flags = AVP_VAL_STR;
01152 }
01153 avp2 = 0;
01154 }
01155
01156 cycle2:
01157
01158 if ((flags&AVP_VAL_STR)^(check_flags&AVP_VAL_STR))
01159 {
01160 LM_ERR("value types don't match\n");
01161 goto next;
01162 }
01163
01164 if (flags&AVP_VAL_STR)
01165 {
01166
01167 LM_DBG("check <%.*s> against <%.*s> as str /%d\n",
01168 avp_val.s.len,avp_val.s.s,
01169 (val->ops&AVPOPS_OP_RE)?6:check_val.s.len,
01170 (val->ops&AVPOPS_OP_RE)?"REGEXP":check_val.s.s,
01171 val->ops);
01172
01173 if (val->ops&AVPOPS_OP_EQ)
01174 {
01175 if (avp_val.s.len==check_val.s.len)
01176 {
01177 if (val->ops&AVPOPS_FLAG_CI)
01178 {
01179 if (strncasecmp(avp_val.s.s,check_val.s.s,
01180 check_val.s.len)==0)
01181 return 1;
01182 } else {
01183 if (strncmp(avp_val.s.s,check_val.s.s,check_val.s.len)==0 )
01184 return 1;
01185 }
01186 }
01187 } else if (val->ops&AVPOPS_OP_NE) {
01188 if (avp_val.s.len!=check_val.s.len)
01189 return 1;
01190 if (val->ops&AVPOPS_FLAG_CI)
01191 {
01192 if (strncasecmp(avp_val.s.s,check_val.s.s,check_val.s.len)!=0)
01193 return 1;
01194 } else {
01195 if (strncmp(avp_val.s.s,check_val.s.s,check_val.s.len)!=0 )
01196 return 1;
01197 }
01198 } else if (val->ops&AVPOPS_OP_LT) {
01199 n = (avp_val.s.len>=check_val.s.len)?avp_val.s.len:check_val.s.len;
01200 rt = strncasecmp(avp_val.s.s,check_val.s.s,n);
01201 if (rt<0)
01202 return 1;
01203 if(rt==0 && avp_val.s.len<check_val.s.len)
01204 return 1;
01205 } else if (val->ops&AVPOPS_OP_LE) {
01206 n = (avp_val.s.len>=check_val.s.len)?avp_val.s.len:check_val.s.len;
01207 if (strncasecmp(avp_val.s.s,check_val.s.s,n)<=0)
01208 return 1;
01209 } else if (val->ops&AVPOPS_OP_GT) {
01210 n = (avp_val.s.len>=check_val.s.len)?avp_val.s.len:check_val.s.len;
01211 rt = strncasecmp(avp_val.s.s,check_val.s.s,n);
01212 if (rt>0)
01213 return 1;
01214 if(rt==0 && avp_val.s.len>check_val.s.len)
01215 return 1;
01216 } else if (val->ops&AVPOPS_OP_GE) {
01217 n = (avp_val.s.len>=check_val.s.len)?avp_val.s.len:check_val.s.len;
01218 if (strncasecmp(avp_val.s.s,check_val.s.s,n)>=0)
01219 return 1;
01220 } else if (val->ops&AVPOPS_OP_RE) {
01221 backup = avp_val.s.s[avp_val.s.len];
01222 avp_val.s.s[avp_val.s.len] = '\0';
01223 if (regexec((regex_t*)check_val.s.s, avp_val.s.s, 1, &pmatch,0)==0)
01224 {
01225 avp_val.s.s[avp_val.s.len] = backup;
01226 return 1;
01227 }
01228 avp_val.s.s[avp_val.s.len] = backup;
01229 } else if (val->ops&AVPOPS_OP_FM){
01230 backup = avp_val.s.s[avp_val.s.len];
01231 avp_val.s.s[avp_val.s.len] = '\0';
01232 if (fnmatch( check_val.s.s, avp_val.s.s,
01233 #ifdef FNM_CASEFOLD
01234 (val->ops&AVPOPS_FLAG_CI)?FNM_CASEFOLD:
01235 #endif
01236 0 )==0)
01237 {
01238 avp_val.s.s[avp_val.s.len] = backup;
01239 return 1;
01240 }
01241 avp_val.s.s[avp_val.s.len] = backup;
01242 } else {
01243 LM_CRIT("unknown operation (flg=%d/%d)\n",val->opd, val->ops);
01244 }
01245 } else {
01246
01247 LM_DBG("check <%d> against <%d> as int /%d\n",
01248 avp_val.n, check_val.n, val->ops);
01249 if (val->ops&AVPOPS_OP_EQ)
01250 {
01251 if ( avp_val.n==check_val.n)
01252 return 1;
01253 } else if (val->ops&AVPOPS_OP_NE) {
01254 if ( avp_val.n!=check_val.n)
01255 return 1;
01256 } else if (val->ops&AVPOPS_OP_LT) {
01257 if ( avp_val.n<check_val.n)
01258 return 1;
01259 } else if (val->ops&AVPOPS_OP_LE) {
01260 if ( avp_val.n<=check_val.n)
01261 return 1;
01262 } else if (val->ops&AVPOPS_OP_GT) {
01263 if ( avp_val.n>check_val.n)
01264 return 1;
01265 } else if (val->ops&AVPOPS_OP_GE) {
01266 if ( avp_val.n>=check_val.n)
01267 return 1;
01268 } else if (val->ops&AVPOPS_OP_BAND) {
01269 if ( avp_val.n&check_val.n)
01270 return 1;
01271 } else if (val->ops&AVPOPS_OP_BOR) {
01272 if ( avp_val.n|check_val.n)
01273 return 1;
01274 } else if (val->ops&AVPOPS_OP_BXOR) {
01275 if ( avp_val.n^check_val.n)
01276 return 1;
01277 } else {
01278 LM_CRIT("unknown operation (flg=%d)\n",val->ops);
01279 }
01280 }
01281
01282 next:
01283
01284 if ((avp2!=NULL)
01285 && (avp2=search_first_avp( name_type2, avp_name2, &check_val, avp2))!=NULL)
01286 {
01287 check_flags = avp2->flags;
01288 goto cycle2;
01289
01290 } else {
01291 if(avp1 && val->ops&AVPOPS_FLAG_ALL)
01292 {
01293 avp1=search_first_avp(name_type1, avp_name1, &avp_val, avp1);
01294 if (avp1)
01295 goto cycle1;
01296 }
01297 }
01298
01299 LM_DBG("no match\n");
01300 return -1;
01301 error:
01302 return -1;
01303 }
01304
01305
01306 int ops_print_avp(void)
01307 {
01308 struct usr_avp **avp_list;
01309 struct usr_avp *avp;
01310 int_str val;
01311 str *name;
01312
01313
01314 avp_list = get_avp_list();
01315 avp = *avp_list;
01316
01317 for ( ; avp ; avp=avp->next)
01318 {
01319 LM_INFO("p=%p, flags=0x%04X\n",avp, avp->flags);
01320 if (avp->flags&AVP_NAME_STR)
01321 {
01322 name = get_avp_name(avp);
01323 LM_INFO("\t\t\tname=<%.*s>\n",name->len,name->s);
01324 } else {
01325 LM_INFO("\t\t\tid=<%d>\n",avp->id);
01326 }
01327 get_avp_val( avp, &val);
01328 if (avp->flags&AVP_VAL_STR)
01329 {
01330 LM_INFO("\t\t\tval_str=<%.*s / %d>\n",val.s.len,val.s.s,
01331 val.s.len);
01332 } else {
01333 LM_INFO("\t\t\tval_int=<%d>\n",val.n);
01334 }
01335 }
01336
01337
01338 return 1;
01339 }
01340
01341 int ops_subst(struct sip_msg* msg, struct fis_param** src,
01342 struct subst_expr* se)
01343 {
01344 struct usr_avp *avp;
01345 struct usr_avp *prev_avp;
01346 int_str avp_val;
01347 unsigned short name_type1;
01348 unsigned short name_type2;
01349 int_str avp_name1;
01350 int_str avp_name2;
01351 int n;
01352 int nmatches;
01353 str* result;
01354
01355 n = 0;
01356 prev_avp = 0;
01357
01358
01359
01360 if(avpops_get_aname(msg, src[0], &avp_name1, &name_type1)!=0)
01361 {
01362 LM_ERR("failed to get src AVP name\n");
01363 return -1;
01364 }
01365
01366 avp = search_first_avp(name_type1, avp_name1, &avp_val, 0);
01367
01368 if(avp==NULL)
01369 return -1;
01370
01371 if(src[1]!=0)
01372 {
01373
01374 if(avpops_get_aname(msg, src[1], &avp_name2, &name_type2)!=0)
01375 {
01376 LM_ERR("failed to get dst AVP name\n");
01377 return -1;
01378 }
01379 } else {
01380 name_type2 = name_type1;
01381 avp_name2 = avp_name1;
01382 }
01383
01384 if(name_type2&AVP_NAME_STR)
01385 {
01386 if(avp_name2.s.len>=STR_BUF_SIZE)
01387 {
01388 LM_ERR("dst name too long\n");
01389 goto error;
01390 }
01391 strncpy(str_buf, avp_name2.s.s, avp_name2.s.len);
01392 str_buf[avp_name2.s.len] = '\0';
01393 avp_name2.s.s = str_buf;
01394 }
01395
01396 while(avp)
01397 {
01398 if(!is_avp_str_val(avp))
01399 {
01400 prev_avp = avp;
01401 avp = search_first_avp(name_type1, avp_name1, &avp_val, prev_avp);
01402 continue;
01403 }
01404
01405 result=subst_str(avp_val.s.s, msg, se, &nmatches);
01406 if(result!=NULL)
01407 {
01408
01409 avp_val.s = *result;
01410 if(add_avp(name_type2|AVP_VAL_STR, avp_name2, avp_val)==-1 ) {
01411 LM_ERR("failed to create new avp\n");
01412 if(result->s!=0)
01413 pkg_free(result->s);
01414 pkg_free(result);
01415 goto error;
01416 }
01417 if(result->s!=0)
01418 pkg_free(result->s);
01419 pkg_free(result);
01420 n++;
01421
01422 if (!(src[0]->ops&AVPOPS_FLAG_ALL) ) {
01423
01424 if (src[0]->ops&AVPOPS_FLAG_DELETE || src[1]==0)
01425 destroy_avp(avp);
01426 break;
01427 } else {
01428 prev_avp = avp;
01429 avp = search_first_avp(name_type1,avp_name1,&avp_val,prev_avp);
01430
01431 if (src[0]->ops&AVPOPS_FLAG_DELETE || src[1]==0)
01432 destroy_avp( prev_avp );
01433 }
01434 } else {
01435 prev_avp = avp;
01436 avp = search_first_avp(name_type1, avp_name1, &avp_val, prev_avp);
01437 }
01438
01439 }
01440 LM_DBG("subst to %d avps\n", n);
01441 return n?1:-1;
01442 error:
01443 return -1;
01444 }
01445
01446 int ops_op_avp( struct sip_msg* msg, struct fis_param** av,
01447 struct fis_param* val)
01448 {
01449 unsigned short name_type1;
01450 unsigned short name_type2;
01451 unsigned short name_type3;
01452 struct fis_param* src;
01453 struct usr_avp *avp1;
01454 struct usr_avp *avp2;
01455 struct usr_avp *prev_avp;
01456 int_str avp_name1;
01457 int_str avp_name2;
01458 int_str avp_name3;
01459 int_str avp_val;
01460 int_str op_val;
01461 int op_flags;
01462 int result;
01463 pv_value_t xvalue;
01464
01465 src = av[0];
01466
01467
01468 if(avpops_get_aname(msg, src, &avp_name1, &name_type1)!=0)
01469 {
01470 LM_ERR("failed to get src AVP name\n");
01471 goto error;
01472 }
01473 avp1 = search_first_avp(name_type1, avp_name1, &avp_val, 0);
01474 if (avp1==0)
01475 {
01476 LM_DBG(" no src avp found\n");
01477 goto error;
01478 }
01479
01480 while(avp1!=0)
01481 {
01482 if(!(avp1->flags&AVP_VAL_STR))
01483 break;
01484 avp1 = search_first_avp(name_type1, avp_name1, &avp_val, avp1);
01485 }
01486 if (avp1==0 && !(val->ops&AVPOPS_OP_BNOT)) {
01487 LM_DBG("no proper avp found\n");
01488 goto error;
01489 }
01490 name_type3 = name_type1;
01491 avp_name3 = avp_name1;
01492 if(av[1]!=0)
01493 {
01494 if(avpops_get_aname(msg, av[1], &avp_name3, &name_type3)!=0)
01495 {
01496 LM_ERR("failed to get dst AVP name\n");
01497 goto error;
01498 }
01499 }
01500 if(name_type3&AVP_NAME_STR)
01501 {
01502 if(avp_name3.s.len>=STR_BUF_SIZE)
01503 {
01504 LM_ERR("failed to get dst name too long\n");
01505 goto error;
01506 }
01507 strncpy(str_buf, avp_name3.s.s, avp_name3.s.len);
01508 str_buf[avp_name3.s.len] = '\0';
01509 avp_name3.s.s = str_buf;
01510 }
01511 prev_avp = 0;
01512 result = 0;
01513
01514 cycle1:
01515 if (val->opd&AVPOPS_VAL_PVAR)
01516 {
01517
01518 op_flags = 0;
01519 if(val->u.sval.type==PVT_AVP)
01520 {
01521
01522 if(avpops_get_aname(msg, val, &avp_name2, &name_type2)!=0)
01523 {
01524 LM_ERR("failed to get dst AVP name\n");
01525 goto error;
01526 }
01527 avp2 = search_first_avp( name_type2, avp_name2, &op_val, 0);
01528 while(avp2!=0)
01529 {
01530 if(!(avp2->flags&AVP_VAL_STR))
01531 break;
01532 avp2 = search_first_avp( name_type2, avp_name2, &op_val, avp2);
01533 }
01534 if (avp2==0)
01535 {
01536 LM_DBG("no dst avp found\n");
01537 goto error;
01538 }
01539 } else {
01540 avp2 = 0;
01541 if(pv_get_spec_value(msg, &(val->u.sval), &xvalue)!=0)
01542 {
01543 LM_ERR("cannot get dst value\n");
01544 goto error;
01545 }
01546 if(xvalue.flags&PV_TYPE_INT)
01547 {
01548 op_val.n = xvalue.ri;
01549 } else {
01550 LM_ERR("dst value is str\n");
01551 goto error;
01552 }
01553 }
01554 } else {
01555 if(val->type == AVPOPS_VAL_INT)
01556 op_val.n = val->u.n;
01557 else
01558 op_val.s = val->u.s;
01559 avp2 = 0;
01560 }
01561
01562 cycle2:
01563
01564 LM_DBG(" use <%d> and <%d>\n",
01565 avp_val.n, op_val.n);
01566 if (val->ops&AVPOPS_OP_ADD)
01567 {
01568 result = avp_val.n+op_val.n;
01569 } else if (val->ops&AVPOPS_OP_SUB) {
01570 result = avp_val.n-op_val.n;
01571 } else if (val->ops&AVPOPS_OP_MUL) {
01572 result = avp_val.n*op_val.n;
01573 } else if (val->ops&AVPOPS_OP_DIV) {
01574 if(op_val.n!=0)
01575 result = (int)(avp_val.n/op_val.n);
01576 else
01577 {
01578 LM_ERR("division by 0\n");
01579 result = 0;
01580 }
01581 } else if (val->ops&AVPOPS_OP_MOD) {
01582 if(op_val.n!=0)
01583 result = avp_val.n%op_val.n;
01584 else
01585 {
01586 LM_ERR("modulo by 0\n");
01587 result = 0;
01588 }
01589 } else if (val->ops&AVPOPS_OP_BAND) {
01590 result = avp_val.n&op_val.n;
01591 } else if (val->ops&AVPOPS_OP_BOR) {
01592 result = avp_val.n|op_val.n;
01593 } else if (val->ops&AVPOPS_OP_BXOR) {
01594 result = avp_val.n^op_val.n;
01595 } else if (val->ops&AVPOPS_OP_BNOT) {
01596 result = ~op_val.n;
01597 } else {
01598 LM_CRIT("unknown operation (flg=%d)\n",val->ops);
01599 goto error;
01600 }
01601
01602
01603 avp_val.n = result;
01604 if(add_avp(name_type3, avp_name3, avp_val)==-1 ) {
01605 LM_ERR("failed to create new avp\n");
01606 goto error;
01607 }
01608
01609
01610 while((avp2!=NULL)
01611 &&(avp2=search_first_avp( name_type2, avp_name2, &op_val, avp2))!=0)
01612 {
01613 if(!(avp2->flags&AVP_VAL_STR))
01614 goto cycle2;
01615 }
01616 prev_avp = avp1;
01617
01618 while((avp1!=NULL)
01619 &&(avp1=search_first_avp(name_type1, avp_name1, &avp_val, avp1))!=0)
01620 {
01621 if (!(avp1->flags&AVP_VAL_STR))
01622 {
01623 if(val->ops&AVPOPS_FLAG_DELETE && prev_avp!=0)
01624 {
01625 destroy_avp(prev_avp);
01626 prev_avp = 0;
01627 }
01628 goto cycle1;
01629 }
01630 }
01631 LM_DBG("done\n");
01632 if(val->ops&AVPOPS_FLAG_DELETE && prev_avp!=0)
01633 {
01634 destroy_avp(prev_avp);
01635 prev_avp = 0;
01636 }
01637 return 1;
01638
01639 error:
01640 return -1;
01641 }
01642
01643 int ops_is_avp_set(struct sip_msg* msg, struct fis_param *ap)
01644 {
01645 struct usr_avp *avp;
01646 unsigned short name_type;
01647 int_str avp_name;
01648 int_str avp_value;
01649 int index;
01650 int findex;
01651
01652
01653 if(avpops_get_aname(msg, ap, &avp_name, &name_type)!=0)
01654 {
01655 LM_ERR("failed to get AVP name\n");
01656 return -1;
01657 }
01658
01659
01660 if(pv_get_spec_index(msg, &ap->u.sval.pvp, &index, &findex)!=0)
01661 {
01662 LM_ERR("failed to get AVP index\n");
01663 return -1;
01664 }
01665
01666 avp=search_first_avp(name_type, avp_name, &avp_value, 0);
01667 if(avp==0)
01668 return -1;
01669
01670 do {
01671
01672 if(index<=0)
01673 {
01674 if(ap->ops&AVPOPS_FLAG_ALL)
01675 return 1;
01676 if((ap->ops&AVPOPS_FLAG_CASTS && !(avp->flags&AVP_VAL_STR))
01677 ||(ap->ops&AVPOPS_FLAG_CASTN && avp->flags&AVP_VAL_STR))
01678 return -1;
01679 if(ap->ops&AVPOPS_FLAG_EMPTY)
01680 {
01681 if(avp->flags&AVP_VAL_STR)
01682 {
01683 if(avp_value.s.s==0 || avp_value.s.len==0)
01684 return 1;
01685 else
01686 return -1;
01687 } else {
01688 if(avp_value.n==0)
01689 return 1;
01690 else
01691 return -1;
01692 }
01693 }
01694 return 1;
01695 }
01696 index--;
01697 } while ((avp=search_first_avp(name_type, avp_name, &avp_value, avp))!=0);
01698
01699 return -1;
01700 }
01701