avpops_impl.c

Go to the documentation of this file.
00001 /*
00002  * $Id: avpops_impl.c 5585 2009-02-10 21:39:56Z miconda $
00003  *
00004  * Copyright (C) 2004-2006 Voice Sistem SRL
00005  *
00006  * This file is part of Kamailio.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License
00010  * as published by the Free Software Foundation; either version 2
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00021  *
00022  * History:
00023  * ---------
00024  *  2004-10-04  first version (ramona)
00025  *  2005-01-30  "fm" (fast match) operator added (ramona)
00026  *  2005-01-30  avp_copy (copy/move operation) added (ramona)
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    /* unique user id */
00072    store_keys[0] = db_columns[0]; /*uuid*/
00073    store_vals[0].type = DB_STR;
00074    store_vals[0].nul  = 0;
00075    /* attribute */
00076    store_keys[1] = db_columns[1]; /*attribute*/
00077    store_vals[1].type = DB_STR;
00078    store_vals[1].nul  = 0;
00079    /* value */
00080    store_keys[2] = db_columns[2]; /*value*/
00081    store_vals[2].type = DB_STR;
00082    store_vals[2].nul  = 0;
00083    /* type */
00084    store_keys[3] = db_columns[3]; /*type*/
00085    store_vals[3].type = DB_INT;
00086    store_vals[3].nul  = 0;
00087    /* user name */
00088    store_keys[4] = db_columns[4]; /*username*/
00089    store_vals[4].type = DB_STR;
00090    store_vals[4].nul  = 0;
00091    /* domain */
00092    store_keys[5] = db_columns[5]; /*domain*/
00093    store_vals[5].type = DB_STR;
00094    store_vals[5].nul  = 0;
00095 }
00096 
00097 
00098 /* value 0 - attr value
00099  * value 1 - attr name
00100  * value 2 - attr type
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       /* check for null fields into the row */
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       /* check the value types */
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       /* check the content of flag field */
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       /* does the avp type match ? */
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       /* check the validity of value column */
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    /* is the avp name already known? */
00156    if ( (flags&AVPOPS_VAL_NONE)==0 )
00157    {
00158       /* use the name  */
00159       avp_attr = attr;
00160       db_flags |= attr_type;
00161    } else {
00162       /* take the name from db response */
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          /* name is string */
00173          avp_attr.s = atmp;
00174       } else {
00175          /* name is ID */
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    /* now get the value as correct type */
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       /* value must be saved as string */
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       /* value must be saved as integer */
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    /* added the avp */
00217    db_flags |= AVP_IS_IN_DB;
00218    /* set script flags */
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    /* which uri will be used? */
00227    if (source&AVPOPS_USE_FROM)
00228    { /* from */
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    {  /* to */
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) {  /* 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       /* val is string */
00260       *val = is_val.s;
00261    } else {
00262       /* val is integer */
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    /* get uuid from avp */
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       /* parse uri */
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       /* check uri */
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    /* is dynamic avp name ? */
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    /* do DB query */
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    /* res query ?  */
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    /* process the results */
00391    for( n=0,i=0 ; i<res->n ; i++)
00392    {
00393       /* validate row */
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       //if ( dbrow2avp( &res->rows[i], dbp->a.opd, avp_name, sh_flg) < 0 )
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    /* get uuid from avp */
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       /* parse uri */
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       /* check uri */
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    /* is dynamic avp name ? */
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    /* do DB delete */
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    /* res ?  */
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; /* uuid, avp name, avp val, avp type, user, domain */
00560    
00561    /* get uuid from avp */
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       /* parse uri */
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       /* check uri */
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    /* set values for keys  */
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    /* is dynamic avp name ? */
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    /* set the script flags */
00655    if(dbp->a.type==AVPOPS_VAL_PVAR)
00656       name_type |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00;
00657    
00658    /* set uuid/(username and domain) fields */
00659 
00660    n =0 ;
00661 
00662    if ((dbp->a.opd&AVPOPS_VAL_NONE)==0)
00663    {
00664       /* avp name is known ->set it and its type */
00665       store_vals[1].val.str_val = dbp->sa; /*attr name*/
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          /* don't insert avps which were loaded */
00670          if (avp->flags&AVP_IS_IN_DB)
00671             continue;
00672          /* set type */
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          /* set value */
00677          int_str2db_val( i_s, &store_vals[2].val.str_val,
00678             avp->flags&AVP_VAL_STR);
00679          /* save avp */
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       /* avp name is unknown -> go through all list */
00689       avp_list = get_avp_list();
00690       avp = *avp_list;
00691 
00692       for ( ; avp ; avp=avp->next )
00693       {
00694          /* don't insert avps which were loaded */
00695          if (avp->flags&AVP_IS_IN_DB)
00696             continue;
00697          /* check if type match */
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          /* set attribute name and type */
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          /* set avp value */
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          /* save avp */
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       /* avp name is known ->search by name */
00776       /* get avp name */
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       /* avp name is not given - we have just flags */
00785       /* -> go through all list */
00786       avp_list = get_avp_list();
00787       avp = *avp_list;
00788 
00789       for ( ; avp ; avp=avp_next )
00790       {
00791          avp_next = avp->next;
00792          /* check if type match */
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          /* remove avp */
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    /* get avp src name */
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    /* get avp dst name */
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       /* build a new avp with new name, but old value */
00847       /* do we need cast conversion ?!?! */
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       /* copy all avps? */
00873       if ( !(dst->ops&AVPOPS_FLAG_ALL) ) {
00874          /* delete the old one? */
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          /* delete the old one? */
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       /* search for the avp */
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       /* the avp val will be used all the time as str */
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       /* push the value into right position */
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          /* rewrite part of ruri */
00993          if (n)
00994          {
00995             /* if is not the first modification, push the current uri as
00996              * branch */
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);/* end while */
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    /* look if the required avp(s) is/are present */
01064    if(src->u.sval.type==PVT_AVP)
01065    {
01066       /* search for the avp */
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    /* copy string since pseudo-variables uses static buffer */
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       /* the 2nd operator is variable -> get avp value */
01113       check_flags = 0;
01114       if(val->u.sval.type==PVT_AVP)
01115       {
01116          /* search for the avp */
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    /* are both values of the same type? */
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       /* string values to check */
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       /* do check */
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       /* int values to check -> do check */
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    /* cycle for the second value (only if avp can have multiple vals) */
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    /* cycle for the first value -> next avp */
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; /* check failed */
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    /* go through all list */
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    /* avp name is known ->search by name */
01359    /* get src avp name */
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       /* get dst avp name */
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          /* build a new avp with new name */
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          /* copy all avps? */
01422          if (!(src[0]->ops&AVPOPS_FLAG_ALL) ) {
01423             /* delete the old one? */
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             /* delete the old one? */
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    /* look if the required avp(s) is/are present */
01467          /* search for the avp */
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       /* the 2nd operator is variable -> get value */
01518       op_flags = 0;
01519       if(val->u.sval.type==PVT_AVP)
01520       {
01521          /* search for the avp */
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    /* do operation */
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    /* add the new avp */
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    /* cycle for the second value (only if avp can have multiple vals) */
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    /* cycle for the first value -> next avp */
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    /* get avp name */
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    /* get avp index */
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       /* last index [-1] or all [*] go here as well */
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 

Generated on Thu May 17 12:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6