Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
Archivo: avp.c Proyecto: 2pac/kamailio
/*
 *  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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
/*
	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;
}
Ejemplo n.º 5
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;
        }
}
Ejemplo n.º 6
0
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;
	}
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
/* 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);
}