コード例 #1
0
ファイル: avpops_parse.c プロジェクト: Drooids/openser-xmlrpc
int parse_avp_db(char *s, struct db_param *dbp, int allow_scheme)
{
	unsigned long ul;
	str   tmp;
	str   s0;
	char  have_scheme;
	char *p;
	char *p0;
	unsigned int flags;

	tmp.s = s;
	/* parse the attribute name - check first if it's not an alias */
	p0=strchr(tmp.s, '/');
	if(p0!=NULL)
		*p0=0;
	if ( *s!='$')
	{
		if(strlen(s)<1)
		{
			LM_ERR("bad param - expected : $avp(name), *, s or i value\n");
			return E_UNSPEC;
		}
		switch(*s) {
			case 's': case 'S':
				dbp->a.opd = AVPOPS_VAL_NONE|AVPOPS_VAL_STR;
			break;
			case 'i': case 'I':
				dbp->a.opd = AVPOPS_VAL_NONE|AVPOPS_VAL_INT;
			break;
			case '*': case 'a': case 'A':
				dbp->a.opd = AVPOPS_VAL_NONE;
			break;
			default:
				LM_ERR("bad param - expected : *, s or i AVP flag\n");
			return E_UNSPEC;
		}
		/* flags */
		flags = 0;
		if(*(s+1)!='\0')
		{
			s0.s = s+1;
			s0.len = strlen(s0.s);
			if(str2int(&s0, &flags)!=0)
			{
				LM_ERR("error - bad avp flags\n");
				goto error;
			}
		}
		dbp->a.u.sval.pvp.pvn.u.isname.type |= (flags<<8)&0xff00;
		dbp->a.type = AVPOPS_VAL_NONE;
	} else {
		s0.s = s; s0.len = strlen(s0.s);
		p = pv_parse_spec(&s0, &dbp->a.u.sval);
		if (p==0 || *p!='\0' || dbp->a.u.sval.type!=PVT_AVP)
		{
			LM_ERR("bad param - expected : $avp(name) or int/str value\n");
			return E_UNSPEC;
		}
		dbp->a.type = AVPOPS_VAL_PVAR;
	}

	/* optimize and keep the attribute name as str also to
	 * speed up db querie builds */
	if (dbp->a.type == AVPOPS_VAL_PVAR)
	{
		dbp->a.opd = AVPOPS_VAL_PVAR;
		if(pv_has_sname(&dbp->a.u.sval))
		{
			dbp->sa.s=(char*)pkg_malloc(
					dbp->a.u.sval.pvp.pvn.u.isname.name.s.len+1);
			if (dbp->sa.s==0)
			{
				LM_ERR("no more pkg mem\n");
				goto error;
			}
			memcpy(dbp->sa.s, dbp->a.u.sval.pvp.pvn.u.isname.name.s.s,
					dbp->a.u.sval.pvp.pvn.u.isname.name.s.len);
			dbp->sa.len = dbp->a.u.sval.pvp.pvn.u.isname.name.s.len;
			dbp->sa.s[dbp->sa.len] = 0;
			dbp->a.opd = AVPOPS_VAL_PVAR|AVPOPS_VAL_STR;
		} else if(pv_has_iname(&dbp->a.u.sval)) {
			ul = (unsigned long)dbp->a.u.sval.pvp.pvn.u.isname.name.n;
			tmp.s = int2str( ul, &(tmp.len) );
			dbp->sa.s = (char*)pkg_malloc( tmp.len + 1 );
			if (dbp->sa.s==0)
			{
				LM_ERR("no more pkg mem\n");
				goto error;
			}
			memcpy( dbp->sa.s, tmp.s, tmp.len);
			dbp->sa.len = tmp.len;
			dbp->sa.s[dbp->sa.len] = 0;
			dbp->a.opd = AVPOPS_VAL_PVAR|AVPOPS_VAL_INT;
		}
	}

	/* restore '/' */
	if(p0)
		*p0 = '/';
	/* is there a table name ? */
	s = p0;
	if (s && *s)
	{
		s++;
		if (*s=='$')
		{
			if (allow_scheme==0)
			{
				LM_ERR("function doesn't support DB schemes\n");
				goto error;
			}
			if (dbp->a.opd&AVPOPS_VAL_NONE)
			{
				LM_ERR("inconsistent usage of "
					"DB scheme without complet specification of AVP name\n");
				goto error;
			}
			have_scheme = 1;
			s++;
		} else {
			have_scheme = 0;
		}
		tmp.s = s;
		tmp.len = 0;
		while ( *s ) s++;
		tmp.len = s - tmp.s;
		if (tmp.len==0)
		{
			LM_ERR("empty scheme/table name\n");
			goto error;
		}
		if (have_scheme)
		{
			dbp->scheme = avp_get_db_scheme( tmp.s );
			if (dbp->scheme==0) 
			{
				LM_ERR("scheme <%s> not found\n", tmp.s);
				goto error;
			}
			/* update scheme flags with AVP name type*/
			dbp->scheme->db_flags|=dbp->a.opd&AVPOPS_VAL_STR?AVP_NAME_STR:0;
		} else {
			/* duplicate table as str NULL terminated */
			dbp->table = (char*)pkg_malloc( tmp.len + 1 );
			if (dbp->table==0)
			{
				LM_ERR("no more pkg mem\n");
				goto error;;
			}
			memcpy( dbp->table, tmp.s, tmp.len);
			dbp->table[tmp.len] = 0;
		}
	}

	return 0;
error:
	return -1;
}
コード例 #2
0
int parse_avp_db(char *s, struct db_param *dbp, int allow_scheme)
{
	unsigned long ul;
	str   tmp;
	char  c;
	char  have_scheme;
	int   type;

	/* parse the attribute name - check first if it's not an alias */
	if ( *s=='$')
	{
		tmp.s = ++s;
		/* is an avp alias -> see where it ends */
		if ( (s=strchr(tmp.s, '/'))!=0 )
		{
			c = *s;
			tmp.len = s - tmp.s;
		} else {
			c = 0;
			tmp.len = strlen(tmp.s);
		}
		if (tmp.len==0)
		{
			LOG(L_ERR,"ERROR:avpops:parse_avp_db: empty alias in <%s>\n", s);
			goto error;
		}
		/* search the alias */
		if ( lookup_avp_galias( &tmp, &type, &dbp->a.val)!=0 )
		{
			LOG(L_ERR,"ERROR:avpops:parse_avp_db: unknow alias"
				"\"%s\"\n", tmp.s);
			goto error;
		}
		dbp->a.flags = (type&AVP_NAME_STR)?AVPOPS_VAL_STR:AVPOPS_VAL_INT;
	} else {
		if ( (s=parse_avp_attr( s, &(dbp->a), '/'))==0 )
			goto error;
		if (*s!=0 && *s!='/')
		{
			LOG(L_ERR,"ERROR:avpops:parse_avp_db: parse error arround "
				"<%s>\n",s);
			goto error;
		}
	}
	dbp->a.flags |= AVPOPS_VAL_AVP;

	/* optimize asn keep the attribute name as str also to
	 * speed up db querie builds */
	if (!(dbp->a.flags&AVPOPS_VAL_NONE))
	{
		if (dbp->a.flags&AVPOPS_VAL_STR)
		{
			dbp->sa = dbp->a.val.s;
		} else {
			ul = (unsigned long)dbp->a.val.n;
			tmp.s = int2str( ul, &(tmp.len) );
			dbp->sa.s = (char*)pkg_malloc( tmp.len + 1 );
			if (dbp->sa.s==0)
			{
				LOG(L_ERR,"ERROR:avpops:parse_avp_db: no more pkg mem\n");
				goto error;
			}
			memcpy( dbp->sa.s, tmp.s, tmp.len);
			dbp->sa.len = tmp.len;
			dbp->sa.s[dbp->sa.len] = 0;
		}
	}

	/* is there a table name ? */
	if (s && *s)
	{
		s++;
		if (*s=='$')
		{
			if (allow_scheme==0)
			{
				LOG(L_ERR,"ERROR:avpops:parse_avp_db: function doesn't "
					"support DB schemes\n");
				goto error;
			}
			if (dbp->a.flags&AVPOPS_VAL_NONE)
			{
				LOG(L_ERR,"ERROR:avpops:parse_avp_db: inconsistent usage of "
					"DB scheme without complet specification of AVP name\n");
				goto error;
			}
			have_scheme = 1;
			s++;
		} else {
			have_scheme = 0;
		}
		tmp.s = s;
		tmp.len = 0;
		while ( *s ) s++;
		tmp.len = s - tmp.s;
		if (tmp.len==0)
		{
			LOG(L_ERR,"ERROR:avpops:parse_av_dbp: empty scheme/table name\n");
			goto error;
		}
		if (have_scheme)
		{
			dbp->scheme = avp_get_db_scheme( tmp.s );
			if (dbp->scheme==0) 
			{
				LOG(L_ERR,"ERROR:avpops:parse_avp_db: scheme <%s> not found\n",
					tmp.s);
				goto error;
			}
			/* update scheme flags with AVP name type*/
			dbp->scheme->db_flags|=dbp->a.flags&AVPOPS_VAL_STR?AVP_NAME_STR:0;
		} else {
			/* duplicate table as str NULL terminated */
			dbp->table = (char*)pkg_malloc( tmp.len + 1 );
			if (dbp->table==0)
			{
				LOG(L_ERR,"ERROR:avpops:parse_avp_db: no more pkg mem\n");
				goto error;;
			}
			memcpy( dbp->table, tmp.s, tmp.len);
			dbp->table[tmp.len] = 0;
		}
	}

	return 0;
error:
	return -1;
}