static int l_siplua_AVP_destroy(lua_State *L) { struct usr_avp *first_avp; int name; str s; int_str val; int flags = 0; luaL_checkany(L, 1); s.s = (char *) lua_tostring(L, 1); s.len = strlen(s.s); name = get_avp_id(&s); first_avp = search_first_avp(flags, name, &val, NULL); if (first_avp != NULL) { destroy_avp(first_avp); lua_pushboolean(L, 1); } else lua_pushnil(L); return 1; }
/* * returns 1 if msg contains an AVP with the given name and value, * returns -1 otherwise */ static int attr_equals(struct sip_msg* msg, char* p1, char* p2) { avp_ident_t avpid; int_str value, avp_value; avp_t* avp; struct search_state st; if (get_avp_id(&avpid, (fparam_t*)p1, msg) < 0) { return -1; } if (p2 && get_str_fparam(&value.s, msg, (fparam_t*)p2) < 0) { ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p2)->orig); return -1; } avp = search_avp(avpid, &avp_value, &st); if (avp == 0) return -1; if (!p2) return 1; while (avp != 0) { if (avp->flags & AVP_VAL_STR) { if ((avp_value.s.len == value.s.len) && !memcmp(avp_value.s.s, value.s.s, avp_value.s.len)) { return 1; } } else { if (avp_value.n == str2s(value.s.s, value.s.len, 0)) { return 1; } } avp = search_next_avp(&st, &avp_value); } return -1; }
static int l_siplua_AVP_get(lua_State *L) { struct usr_avp *first_avp; int name; str s; int_str val; int flags = 0; luaL_checkany(L, 1); s.s = (char *) lua_tostring(L, 1); s.len = strlen(s.s); name = get_avp_id(&s); first_avp = search_first_avp(flags, name, &val, NULL); if (first_avp != NULL) { if (is_avp_str_val(first_avp)) lua_pushlstring(L, val.s.s, val.s.len); else lua_pushinteger(L, val.n); } else lua_pushnil(L); return 1; }
/* Exctracts and generates AVPs from the Radius reply */ int extract_avp(VALUE_PAIR* vp) { static str names, values; int name; unsigned int r; char *p; char *end; int_str value; unsigned short flags = 0; /* empty? */ if (vp->lvalue == 0 || vp->strvalue == 0) return -1; p = vp->strvalue; end = vp->strvalue + vp->lvalue; /* get name */ if (*p == '#') { /* name is always a string */ ++p; } names.s = p; names.len = 0; while (p < end && *p != ':' && *p != '#') p++; if (names.s == p || p == end) { LM_ERR("empty AVP name\n"); return -1; } names.len = p - names.s; /* get value */ if (*p != '#') { /* string value */ flags |= AVP_VAL_STR; } values.s = ++p; values.len = end-values.s; if (values.len == 0) { LM_ERR("empty AVP value\n"); return -1; } if (!(flags&AVP_VAL_STR)) { /* convert value to integer */ if (str2int(&values,&r) != 0) { LM_ERR("invalid AVP numrical value '%.*s'\n", values.len,values.s); return -1; } value.n = (int)r; } else value.s = values; name = get_avp_id(&names); if (name < 0) { LM_ERR("cannot get AVP id (%.*s)\n", names.len, names.s); return -1; } if (add_avp( flags, name, value) < 0) { LM_ERR("unable to create a new AVP\n"); return -1; } else { LM_DBG("AVP '%.*s'='%.*s'/%d has been added\n", names.len, names.s, (flags&AVP_VAL_STR)?value.s.len:4, (flags&AVP_VAL_STR)?value.s.s:"null", (flags&AVP_VAL_STR)?0:value.n ); } return 0; }
int h350_service_level(struct sip_msg* _msg, pv_elem_t* _avp_name_prefix) { int i, rc, avp_count = 0; str avp_name_prefix; int_str avp_name; int_str avp_val; struct berval **attr_vals; static char service_level_avp_name[AVP_NAME_STR_BUF_LEN]; /* * get service_level */ if (pv_printf_s(_msg, _avp_name_prefix, &avp_name_prefix) != 0) { LM_ERR("pv_printf_s failed\n"); return E_H350_INTERNAL; } /* * get LDAP attribute values */ if ((rc = ldap_api.ldap_result_attr_vals(&h350_service_level_name, &attr_vals)) < 0) { LM_ERR("Getting LDAP attribute values failed\n"); return E_H350_INTERNAL; } if (rc > 0) { /* no LDAP values found */ return E_H350_NO_SUCCESS; } /* copy avp name prefix into service_level_avp_name */ if (avp_name_prefix.len < AVP_NAME_STR_BUF_LEN) { memcpy(service_level_avp_name, avp_name_prefix.s, avp_name_prefix.len); } else { LM_ERR("AVP name prefix too long [%d] (max [%d])\n", avp_name_prefix.len, AVP_NAME_STR_BUF_LEN); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } /* * loop through service level values and add AVP(s) */ for (i = 0; attr_vals[i] != NULL; i++) { /* get avp name */ if (avp_name_prefix.len + attr_vals[i]->bv_len >= AVP_NAME_STR_BUF_LEN) { LM_ERR("AVP name too long for [%s]\n", attr_vals[i]->bv_val); continue; } memcpy( service_level_avp_name + avp_name_prefix.len, attr_vals[i]->bv_val, attr_vals[i]->bv_len); avp_name.s.s = service_level_avp_name; avp_name.s.len = avp_name_prefix.len + attr_vals[i]->bv_len; avp_name.n = get_avp_id(&avp_name.s); if (avp_name.n <= 0) { LM_ERR("cannot get avp id\n"); continue; } /* avp value = 1 */ avp_val.n = 1; if (add_avp(AVP_NAME_STR, avp_name.n, avp_val) < 0) { LM_ERR("failed to create new AVP\n"); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } avp_count++; } ldap_api.ldap_value_free_len(attr_vals); if (avp_count > 0) { return avp_count; } else { return E_H350_NO_SUCCESS; } }
int h350_call_preferences(struct sip_msg* _msg, pv_elem_t* _avp_name_prefix) { int rc, i, avp_count = 0; struct berval **attr_vals; size_t nmatch = 5; regmatch_t pmatch[5]; int avp_name; int_str avp_val; str avp_val_str, avp_name_str, avp_name_prefix_str, call_pref_timeout_str; int call_pref_timeout; static char call_pref_avp_name[AVP_NAME_STR_BUF_LEN]; /* * get avp_name_prefix_str */ if (pv_printf_s(_msg, _avp_name_prefix, &avp_name_prefix_str) != 0) { LM_ERR("pv_printf_s failed\n"); return E_H350_INTERNAL; } /* * get LDAP attribute values */ if ((rc = ldap_api.ldap_result_attr_vals( &h350_call_pref_name, &attr_vals)) < 0) { LM_ERR("Getting LDAP attribute values failed\n"); return E_H350_INTERNAL; } if (rc > 0) { /* no LDAP values found */ return E_H350_NO_SUCCESS; } /* * loop through call pref values and add AVP(s) */ /* copy avp name prefix into call_pref_avp_name */ if (avp_name_prefix_str.len < AVP_NAME_STR_BUF_LEN) { memcpy(call_pref_avp_name, avp_name_prefix_str.s, avp_name_prefix_str.len); } else { LM_ERR("AVP name prefix too long [%d] (max [%d])", avp_name_prefix_str.len, AVP_NAME_STR_BUF_LEN); return E_H350_INTERNAL; } for (i = 0; attr_vals[i] != NULL; i++) { if ((rc = regexec(call_pref_preg, attr_vals[i]->bv_val, nmatch, pmatch, 0)) != 0) { switch (rc) { case REG_NOMATCH: LM_INFO("no h350 call preference regex match for [%s]\n", attr_vals[i]->bv_val); continue; case REG_ESPACE: LM_ERR("regexec returned REG_ESPACE - out of memory\n"); default: LM_ERR("regexec failed\n"); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } } /* calculate call preference sip uri */ if (avp_name_prefix_str.len + pmatch[2].rm_eo - pmatch[2].rm_so >= AVP_NAME_STR_BUF_LEN) { LM_ERR("AVP name too long for [%s]", attr_vals[i]->bv_val); continue; } avp_val_str.s = attr_vals[i]->bv_val + pmatch[1].rm_so; avp_val_str.len = pmatch[1].rm_eo - pmatch[1].rm_so; avp_val.s = avp_val_str; /* calculate call preference avp name */ memcpy( call_pref_avp_name + avp_name_prefix_str.len, attr_vals[i]->bv_val + pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so); avp_name_str.s = call_pref_avp_name; avp_name_str.len = avp_name_prefix_str.len + pmatch[2].rm_eo - pmatch[2].rm_so; avp_name = get_avp_id(&avp_name_str); if (avp_name <= 0) { LM_ERR("cannot get avp id\n"); continue; } /* add avp */ if (add_avp(AVP_NAME_STR | AVP_VAL_STR, avp_name, avp_val) < 0) { LM_ERR("failed to create new AVP\n"); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } avp_count++; /* check for call preference timeout */ if ((pmatch[4].rm_eo - pmatch[4].rm_so) == 0) { continue; } /* calculate call preference timeout avp name */ memcpy( avp_name_str.s + avp_name_str.len, "_t", 2); avp_name_str.len += 2; avp_name = get_avp_id(&avp_name_str); if (avp_name <= 0) { LM_ERR("cannot get avp id\n"); continue; } /* calculate timeout avp value */ call_pref_timeout_str.s = attr_vals[i]->bv_val + pmatch[4].rm_so; call_pref_timeout_str.len = pmatch[4].rm_eo - pmatch[4].rm_so; if (str2sint(&call_pref_timeout_str, &call_pref_timeout) != 0) { LM_ERR("str2sint failed\n"); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } call_pref_timeout = call_pref_timeout / 1000; /* add timeout avp */ avp_val.n = call_pref_timeout; if (add_avp(AVP_NAME_STR, avp_name, avp_val) < 0) { LM_ERR("failed to create new AVP\n"); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } } ldap_api.ldap_value_free_len(attr_vals); if (avp_count > 0) { return avp_count; } else { return E_H350_NO_SUCCESS; } }
int exec_avp(struct sip_msg *msg, char *cmd, pvname_list_p avpl) { int_str avp_val; int_str avp_name; unsigned short avp_type; FILE *pipe; int ret; char res_line[MAX_URI_SIZE+1]; str res; int exit_status; int i; pvname_list_t* crt; pid_t pid; /* pessimist: assume error by default */ ret=-1; pid = __popen3(cmd, NULL, &pipe, NULL); if (pid < 0) { LM_ERR("failed to run command: %s\n", cmd); ser_error=E_EXEC; return ret; } LM_DBG("Forked pid %d\n", pid); schedule_to_kill(pid); wait(&exit_status); /* read now line by line */ i=0; crt = avpl; while (fgets(res_line, MAX_URI_SIZE, pipe)) { res.s = res_line; res.len=strlen(res.s); trim_trailing(&res); /* skip empty line */ if (res.len==0) continue; /* ZT */ res.s[res.len]=0; avp_type = 0; if(crt==NULL) { avp_name.s.s = int2str(i + 1, &avp_name.s.len); if (!avp_name.s.s) { LM_ERR("cannot convert %d to string\n", i + 1); goto error; } avp_name.n = get_avp_id(&avp_name.s); if (avp_name.n < 0) { LM_ERR("cannot get avp id\n"); goto error; } } else { if(pv_get_avp_name(msg, &(crt->sname.pvp), &avp_name.n, &avp_type)!=0) { LM_ERR("can't get item name [%d]\n",i); goto error; } } avp_type |= AVP_VAL_STR; avp_val.s = res; if(add_avp(avp_type, avp_name.n, avp_val)!=0) { LM_ERR("unable to add avp\n"); goto error; } if(crt) crt = crt->next; i++; } if (i==0) LM_DBG("no result from %s\n", cmd); /* success */ ret=1; error: if (ferror(pipe)) { LM_ERR("pipe: %d/%s\n", errno, strerror(errno)); ser_error=E_EXEC; ret=-1; } pclose(pipe); if (WIFEXITED(exit_status)) { /* exited properly .... */ /* return false if script exited with non-zero status */ if (WEXITSTATUS(exit_status)!=0) ret=-1; } else { /* exited erroneously */ LM_ERR("cmd %s failed. exit_status=%d, errno=%d: %s\n", cmd, exit_status, errno, strerror(errno) ); ret=-1; } return ret; }
int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp, struct db_param *dbp, struct db_url *url, int use_domain) { struct sip_uri uri; struct usr_avp **avp_list; struct usr_avp *avp; unsigned short name_type; int avp_name; int_str i_s; str uuid; int keys_nr; int n; pv_value_t xvalue; str *s0, *s1, *s2; str *sn; s0 = s1 = s2 = NULL; name_type = 0; if (!((sp->opd&AVPOPS_VAL_PVAR)||(sp->opd&AVPOPS_VAL_STR))) { LM_CRIT("invalid flag combination (%d/%d)\n", sp->opd, sp->ops); goto error; } keys_nr = 6; /* uuid, avp name, avp val, avp type, user, domain */ /* get uuid from avp */ if (sp->opd&AVPOPS_VAL_PVAR) { if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0) { LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops); goto error; } if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY)) { LM_ERR("no value for first param\n"); goto error; } uuid = xvalue.rs; } else { uuid.s = sp->u.s.s; uuid.len = sp->u.s.len; } if(sp->opd&AVPOPS_FLAG_UUID0) { s0 = &uuid; } else { /* parse uri */ if (parse_uri(uuid.s, uuid.len, &uri)<0) { LM_ERR("failed to parse uri\n"); goto error; } /* check uri */ if(!uri.user.s|| !uri.user.len|| !uri.host.len|| !uri.host.s) { LM_ERR("incomplet uri <%.*s>\n", uuid.len, uuid.s); goto error; } if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_USER0)) s1 = &uri.user; if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_DOMAIN0)) s2 = &uri.host; } /* set values for keys */ store_vals[0].val.str_val = (s0)?*s0:empty; store_vals[4].val.str_val = (s1)?*s1:empty; if (use_domain || sp->opd&AVPOPS_FLAG_DOMAIN0) store_vals[5].val.str_val = (s2)?*s2:empty; avp_name = -1; /* is dynamic avp name ? */ if(dbp->a.type==AVPOPS_VAL_PVAR) { if(pv_has_dname(&dbp->a.u.sval)) { /* TODO change here to be aware of the int name */ if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0) { LM_CRIT("failed to get value for P2\n"); goto error; } if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY)) { LM_INFO("no value for P2\n"); goto error; } if(xvalue.flags&PV_TYPE_INT) { name_type = 0; avp_name = xvalue.ri; } else { name_type = AVP_NAME_STR; avp_name = -1; } if(xvalue.flags&PV_VAL_STR) { if(xvalue.rs.len>=AVPOPS_ATTR_LEN) { LM_ERR("name too long [%d/%.*s...]\n", xvalue.rs.len, 16, xvalue.rs.s); goto error; } dbp->sa.s = avpops_attr_buf; memcpy(dbp->sa.s, xvalue.rs.s, xvalue.rs.len); dbp->sa.len = xvalue.rs.len; dbp->sa.s[dbp->sa.len] = '\0'; avp_name = get_avp_id(&dbp->sa); /* search for the id only once */ if (avp_name < 0) { LM_ERR("cannot find avp\n"); goto error; } } else { LM_INFO("no string value for p2\n"); goto error; } } else { name_type = dbp->a.u.sval.pvp.pvn.u.isname.type; avp_name = dbp->a.u.sval.pvp.pvn.u.isname.name.n; } } else { LM_WARN("TODO: avp is not a dynamic name <%.*s> name is %d\n", dbp->sa.len, dbp->sa.s, avp_name); avp_name = -1; } /* set the script flags */ if(dbp->a.type==AVPOPS_VAL_PVAR) name_type |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00; /* set uuid/(username and domain) fields */ n =0 ; if ((dbp->a.opd&AVPOPS_VAL_NONE)==0) { /* if avp wasn't found yet */ if (avp_name < 0) { avp_name = get_avp_id(&dbp->sa); /* search for the id only once */ if (avp_name < 0) { LM_ERR("cannot find avp\n"); goto error; } } /* avp name is known ->set it and its type */ store_vals[1].val.str_val = dbp->sa; /*attr name*/ avp = search_first_avp( 0, avp_name, &i_s, 0); for( ; avp; avp=search_first_avp( 0, avp_name, &i_s, avp)) { /* don't insert avps which were loaded */ if (avp->flags&AVP_IS_IN_DB) continue; /* set type */ store_vals[3].val.int_val = (avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)| (avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT); /* set value */ int_str2db_val( i_s, &store_vals[2].val.str_val, avp->flags&AVP_VAL_STR); /* save avp */ if (db_store_avp( url, store_keys, store_vals, keys_nr, &dbp->table)==0 ) { avp->flags |= AVP_IS_IN_DB; n++; } } } else { /* avp name is unknown -> go through all list */ avp_list = get_avp_list(); avp = *avp_list; for ( ; avp ; avp=avp->next ) { /* don't insert avps which were loaded */ if (avp->flags&AVP_IS_IN_DB) continue; /* set attribute name and type */ if ( (sn=get_avp_name(avp))==0 ) i_s.n = avp->id; else i_s.s = *sn; int_str2db_val( i_s, &store_vals[1].val.str_val, AVP_NAME_STR); store_vals[3].val.int_val = (avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)| (avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT); /* set avp value */ get_avp_val( avp, &i_s); int_str2db_val( i_s, &store_vals[2].val.str_val, avp->flags&AVP_VAL_STR); /* save avp */ if (db_store_avp( url, store_keys, store_vals, keys_nr, &dbp->table)==0) { avp->flags |= AVP_IS_IN_DB; n++; } } } LM_DBG(" %d avps were stored\n",n); return n==0?-1:1; error: return -1; }
int ops_dbload_avps (struct sip_msg* msg, struct fis_param *sp, struct db_param *dbp, struct db_url *url, int use_domain, str *prefix) { struct sip_uri uri; db_res_t *res = NULL; str uuid; int i, n, sh_flg; str *s0, *s1, *s2; int avp_name; int avp_type = 0; pv_value_t xvalue; s0 = s1 = s2 = NULL; if (!((sp->opd&AVPOPS_VAL_PVAR)||(sp->opd&AVPOPS_VAL_STR))) { LM_CRIT("invalid flag combination (%d/%d)\n", sp->opd, sp->ops); goto error; } /* get uuid from avp */ if (sp->opd&AVPOPS_VAL_PVAR) { if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0) { LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops); goto error; } if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY)) { LM_ERR("no value for first param\n"); goto error; } uuid = xvalue.rs; } else { uuid.s = sp->u.s.s; uuid.len = sp->u.s.len; } if(sp->opd&AVPOPS_FLAG_UUID0) { s0 = &uuid; } else { /* parse uri */ if (parse_uri(uuid.s, uuid.len, &uri)<0) { LM_ERR("failed to parse uri\n"); goto error; } /* check uri */ if(!uri.user.s|| !uri.user.len|| !uri.host.len|| !uri.host.s) { LM_ERR("incomplet uri <%.*s>\n", uuid.len, uuid.s); goto error; } if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_USER0)) s1 = &uri.user; if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_DOMAIN0)) s2 = &uri.host; } /* is dynamic avp name ? */ if(dbp->a.type==AVPOPS_VAL_PVAR) { if(pv_has_dname(&(dbp->a.u.sval))) { if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0) { LM_CRIT("failed to get value for P2\n"); goto error; } if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY)) { LM_ERR("no value for p2\n"); goto error; } if(xvalue.flags&PV_VAL_STR) { if(xvalue.rs.len>=AVPOPS_ATTR_LEN) { LM_ERR("name too long [%d/%.*s...]\n", xvalue.rs.len, 16, xvalue.rs.s); goto error; } dbp->sa.s = avpops_attr_buf; memcpy(dbp->sa.s, xvalue.rs.s, xvalue.rs.len); dbp->sa.len = xvalue.rs.len; dbp->sa.s[dbp->sa.len] = '\0'; } else { LM_INFO("no string value for p2\n"); goto error; } } } /* do DB query */ res = db_load_avp( url, s0, s1, ((use_domain)||(sp->opd&AVPOPS_FLAG_DOMAIN0))?s2:0, dbp->sa.s, &dbp->table, dbp->scheme); /* res query ? */ if (res==0) { LM_ERR("db_load failed\n"); goto error; } sh_flg = (dbp->scheme)?dbp->scheme->db_flags:-1; /* validate row */ avp_name = -1; if(dbp->a.type==AVPOPS_VAL_PVAR) { if(pv_has_dname(&dbp->a.u.sval)) { if(xvalue.flags&PV_TYPE_INT) { avp_name = xvalue.ri; } else { if (prefix) { if (xvalue.rs.len + prefix->len > AVPOPS_ATTR_LEN) { LM_ERR("name too long [%d/%.*s...]\n", prefix->len + xvalue.rs.len, 16, prefix->s); goto error; } memcpy(avpops_attr_buf, prefix->s, prefix->len); memcpy(avpops_attr_buf + prefix->len, xvalue.rs.s, xvalue.rs.len); xvalue.rs.s = avpops_attr_buf; xvalue.rs.len = prefix->len + xvalue.rs.len; } avp_name = get_avp_id(&xvalue.rs); if (avp_name < 0) { LM_ERR("cannot get avp id\n"); return -1; } } } else { avp_name = dbp->a.u.sval.pvp.pvn.u.isname.name.n; avp_type = dbp->a.u.sval.pvp.pvn.u.isname.type; } } /* process the results */ for( n=0,i=0 ; i<res->n ; i++) { if (dbrow2avp(&res->rows[i], dbp, avp_name, avp_type, sh_flg, prefix) < 0) continue; n++; } db_close_query( url, res ); LM_DBG("loaded avps = %d\n",n); return n?1:-1; error: return -1; }
/* value 0 - attr value * value 1 - attr name * value 2 - attr type */ static int dbrow2avp(struct db_row *row, struct db_param *dbp, int attr, int attr_type, int just_val_flags, str *prefix) { unsigned int uint; int db_flags; str atmp; str vtmp; int avp_attr; int_str avp_val; int flags; flags = dbp->a.opd; if (just_val_flags==-1) { /* check for null fields into the row */ if (row->values[0].nul || row->values[1].nul || row->values[2].nul ) { LM_ERR("dbrow contains NULL fields\n"); return -1; } /* check the value types */ if ( (row->values[0].type!=DB_STRING && row->values[0].type!=DB_STR) || (row->values[1].type!=DB_STRING && row->values[1].type!=DB_STR) || row->values[2].type!=DB_INT ) { LM_ERR("wrong field types in dbrow\n"); return -1; } /* check the content of flag field */ uint = (unsigned int)row->values[2].val.int_val; db_flags = ((uint&AVPOPS_DB_NAME_INT)?0:AVP_NAME_STR) | ((uint&AVPOPS_DB_VAL_INT)?0:AVP_VAL_STR); } else { /* check the validity of value column */ if (row->values[0].nul || (row->values[0].type!=DB_STRING && row->values[0].type!=DB_STR && row->values[0].type!=DB_INT) ) { LM_ERR("empty or wrong type for 'value' using scheme\n"); return -1; } db_flags = just_val_flags; } /* is the avp name already known? */ if ( (flags&AVPOPS_VAL_NONE)==0 ) { /* use the name */ avp_attr = attr; db_flags |= attr_type; } else { /* take the name from db response */ if (row->values[1].type==DB_STRING) { atmp.s = (char*)row->values[1].val.string_val; atmp.len = strlen(atmp.s); } else { atmp = row->values[1].val.str_val; } if (prefix) { if (atmp.len + prefix->len > AVPOPS_ATTR_LEN) { LM_ERR("name too long [%d/%.*s...]\n", prefix->len + atmp.len, 16, prefix->s); return -1; } memcpy(avpops_attr_buf, prefix->s, prefix->len); memcpy(avpops_attr_buf + prefix->len, atmp.s, atmp.len); atmp.s = avpops_attr_buf; atmp.len += prefix->len; } /* there is always a name here - get the ID */ avp_attr = get_avp_id(&atmp); if (avp_attr < 0) return -2; } /* now get the value as correct type */ if (row->values[0].type==DB_STRING) { vtmp.s = (char*)row->values[0].val.string_val; vtmp.len = strlen(vtmp.s); } else if (row->values[0].type==DB_STR){ vtmp = row->values[0].val.str_val; } else { vtmp.s = 0; vtmp.len = 0; } if (db_flags&AVP_VAL_STR) { /* value must be saved as string */ if (row->values[0].type==DB_INT) { vtmp.s = int2str( (unsigned long)row->values[0].val.int_val, &vtmp.len); } avp_val.s = vtmp; } else { /* value must be saved as integer */ if (row->values[0].type!=DB_INT) { if (vtmp.len==0 || vtmp.s==0 || str2int(&vtmp, &uint)==-1) { LM_ERR("value is not int as flags say <%s>\n", vtmp.s); return -1; } avp_val.n = (int)uint; } else { avp_val.n = row->values[0].val.int_val; } } /* added the avp */ db_flags |= AVP_IS_IN_DB; /* set script flags */ db_flags |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00; return add_avp( (unsigned short)db_flags, avp_attr, avp_val); }