⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avpops_impl.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: avpops_impl.c,v 1.5 2004/11/15 10:19:39 ramona Exp $ * * Copyright (C) 2004 Voice Sistem SRL * * This file is part of SIP Express Router. * * AVPOPS SER-module is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * AVPOPS SER-module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. * * For any questions about this software and its license, please contact * Voice Sistem at following e-mail address: *         office@voice-sistem.ro * * * History: * --------- *  2004-10-04  first version (ramona) */#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <regex.h>#include "../../ut.h"#include "../../dprint.h"#include "../../usr_avp.h"#include "../../action.h"#include "../../ip_addr.h"#include "../../config.h"#include "../../dset.h"#include "../../data_lump.h"#include "../../data_lump_rpl.h"#include "../../parser/parse_from.h"#include "../../parser/parse_uri.h"#include "../../mem/mem.h"#include "avpops_impl.h"#include "avpops_db.h"static db_key_t  store_keys[6];static db_val_t  store_vals[6];static str      empty={"",0};void init_store_avps( char **db_columns){	/* unique user id */	store_keys[0] = db_columns[0]; /*uuid*/	store_vals[0].type = DB_STR;	store_vals[0].nul  = 0;	/* attribute */	store_keys[1] = db_columns[1]; /*attribute*/	store_vals[1].type = DB_STR;	store_vals[1].nul  = 0;	/* value */	store_keys[2] = db_columns[2]; /*value*/	store_vals[2].type = DB_STR;	store_vals[2].nul  = 0;	/* type */	store_keys[3] = db_columns[3]; /*type*/	store_vals[3].type = DB_INT;	store_vals[3].nul  = 0;	/* user name */	store_keys[4] = db_columns[4]; /*username*/	store_vals[4].type = DB_STR;	store_vals[4].nul  = 0;	/* domain */	store_keys[5] = db_columns[5]; /*domain*/	store_vals[5].type = DB_STR;	store_vals[5].nul  = 0;}/* value 0 - attr value * value 1 - attr name * value 2 - attr type */static int dbrow2avp(struct db_row *row, int flags, int_str attr,														int just_val_flags){	unsigned int uint;	int  db_flags;	str  atmp;	str  vtmp;	int_str avp_attr;	int_str avp_val;	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 )		{			LOG( L_ERR, "ERROR:avpops:dbrow2avp: 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 )		{			LOG(L_ERR,"ERROR:avpops:dbrow2avp: 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);			DBG("db_flags=%d, flags=%d\n",db_flags,flags);		/* does the avp type match ? */		if(!((flags&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 ||				((flags&AVPOPS_VAL_INT)&&((db_flags&AVP_NAME_STR)==0)) ||				((flags&AVPOPS_VAL_STR)&&(db_flags&AVP_NAME_STR))))			return -2;	} else {		/* check the validity of value column */		if (row->values[0].nul || 		(row->values[0].type!=DB_STRING && row->values[0].type!=DB_STR) )		{			LOG(L_ERR,"ERROR:avpops:dbrow2avp: 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;	} 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 (db_flags&AVP_NAME_STR)		{			/* name is string */			avp_attr.s = &atmp;		} else {			/* name is ID */			if (str2int( &atmp, &uint)==-1)			{				LOG(L_ERR,"ERROR:avpops:dbrow2avp: name is not ID as flags say"					" <%s>\n", atmp.s);				return -1;			}			avp_attr.n = (int)uint;		}	}	/* 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 {		vtmp = row->values[0].val.str_val;	}	if (db_flags&AVP_VAL_STR)	{		/* value is string */		avp_val.s = &vtmp;	} else {		/* name is ID */		if (str2int(&vtmp, &uint)==-1)		{			LOG(L_ERR,"ERROR:avpops:dbrow2avp: value is not int as flags say"				" <%s>\n", vtmp.s);			return -1;		}		avp_val.n = (int)uint;	}	/* added the avp */	db_flags |= AVP_IS_IN_DB;	return add_avp( (unsigned short)db_flags, avp_attr, avp_val);}inline static str* get_source_uri(struct sip_msg* msg,int source){	/* which uri will be used? */	if (source&AVPOPS_USE_FROM)	{ /* from */		if (parse_from_header( msg )<0 )		{			LOG(L_ERR,"ERROR:avpops:get_source_uri: failed "				"to parse from\n");			goto error;		}		return &(get_from(msg)->uri);	} else if (source&AVPOPS_USE_TO)	{  /* to */		if (parse_headers( msg, HDR_TO, 0)<0)		{			LOG(L_ERR,"ERROR:avpops:get_source_uri: failed "				"to parse to\n");			goto error;		}		return &(get_to(msg)->uri);	} else if (source&AVPOPS_USE_RURI) {  /* RURI */		if(msg->new_uri.s!=NULL && msg->new_uri.len>0)			return &(msg->new_uri);		return &(msg->first_line.u.request.uri);	} else {		LOG(L_CRIT,"BUG:avpops:get_source_uri: unknow source <%d>\n",			source);		goto error;	}error:	return 0;}static int parse_source_uri(struct sip_msg* msg,int source,struct sip_uri *uri){	str *uri_s;	/* get uri */	if ( (uri_s=get_source_uri(msg,source))==0 )	{		LOG(L_ERR,"ERROR:avpops:parse_source_uri: cannot get uri\n");		goto error;	}	/* parse uri */	if (parse_uri(uri_s->s, uri_s->len , uri)<0)	{		LOG(L_ERR,"ERROR:avpops:parse_source_uri: failed to parse uri\n");		goto error;	}	/* check uri */	if (!uri->user.s || !uri->user.len || !uri->host.len || !uri->host.s )	{		LOG(L_ERR,"ERROR:avpops:parse_source_uri: incomplet uri <%.*s>\n",			uri_s->len,uri_s->s);		goto error;	}	return 0;error:	return -1;}static inline void int_str2db_val( int_str is_val, str *val, int is_s){	if (is_s)	{		/* val is string */		*val = *is_val.s;	} else {		/* val is integer */		val->s =			int2str((unsigned long)is_val.n, &val->len);	}}static int get_avp_as_str(struct fis_param *ap ,str *val){	struct usr_avp  *avp;	unsigned short  name_type;	int_str         avp_val;	name_type = ((ap->flags&AVPOPS_VAL_INT)?0:AVP_NAME_STR);	avp = search_first_avp( name_type, ap->val, &avp_val);	if (avp==0)	{		DBG("DEBUG:avpops:get_val_as_str: no avp found\n");		return -1;	}	int_str2db_val( avp_val, val, avp->flags&AVP_VAL_STR);	return 0;}int ops_dbload_avps (struct sip_msg* msg, struct fis_param *sp,									struct db_param *dbp, int use_domain){	struct sip_uri   uri;	db_res_t         *res;	str              uuid;	int  i, n, sh_flg;	if (sp->flags&AVPOPS_VAL_NONE)	{		/* get and parse uri */		if (parse_source_uri( msg, sp->flags, &uri)<0 )		{			LOG(L_ERR,"ERROR:avpops:load_avps: failed to get uri\n");			goto error;		}		/* do DB query */		res = db_load_avp( 0, (sp->flags&AVPOPS_FLAG_DOMAIN)?&empty:&uri.user,				(use_domain||(sp->flags&AVPOPS_FLAG_DOMAIN))?&uri.host:0,				dbp->sa.s, dbp->table , dbp->scheme);	} else if (sp->flags&AVPOPS_VAL_AVP) {		/* get uuid from avp */		if (get_avp_as_str( sp, &uuid)<0)		{			LOG(L_ERR,"ERROR:avpops:load_avps: failed to get uuid\n");			goto error;		}		/* do DB query */		res = db_load_avp( &uuid, 0, 0, dbp->sa.s, dbp->table, dbp->scheme);	} else  if (sp->flags&AVPOPS_VAL_STR) {		/* use the STR val as uuid */		/* do DB query */		res = db_load_avp( sp->val.s, 0, 0, dbp->sa.s, dbp->table, dbp->scheme);	} else {		LOG(L_CRIT,"BUG:avpops:load_avps: invalid flag combination (%d)\n",			sp->flags);		goto error;	}	/* res query ?  */	if (res==0)	{		LOG(L_ERR,"ERROR:avpops:load_avps: db_load failed\n");		goto error;	}	sh_flg = (dbp->scheme)?dbp->scheme->db_flags:-1;	/* process the results */	for( n=0,i=0 ; i<res->n ; i++)	{		/* validate row */		if ( dbrow2avp( &res->rows[i], dbp->a.flags, dbp->a.val, sh_flg) < 0 )			continue;		n++;	}	db_close_query( res );	DBG("DEBUG:avpops:load_avps: loaded avps = %d\n",n);	return n?1:-1;error:	return -1;}int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp,									struct db_param *dbp, int use_domain){	struct sip_uri   uri;	struct usr_avp   **avp_list;	struct usr_avp   *avp;	unsigned short   name_type;	int_str          i_s;	str              uuid;	int              keys_off;	int              keys_nr;	int              n;		if (sp->flags&AVPOPS_VAL_NONE)	{		/* get and parse uri */		if (parse_source_uri( msg, sp->flags, &uri)<0 )		{			LOG(L_ERR,"ERROR:avpops:store_avps: failed to get uri\n");			goto error;		}		/* set values for keys  */		keys_off = 1;		store_vals[4].val.str_val =			(sp->flags&AVPOPS_FLAG_DOMAIN)?empty:uri.user;		if (use_domain || sp->flags&AVPOPS_FLAG_DOMAIN)		{			store_vals[5].val.str_val = uri.host;			keys_nr = 5;		} else {			keys_nr = 4;		}	} else if (sp->flags&AVPOPS_VAL_AVP) {		/* get uuid from avp */		if (get_avp_as_str(sp, &uuid)<0)		{			LOG(L_ERR,"ERROR:avpops:store_avps: failed to get uuid\n");			goto error;		}		/* set values for keys  */		keys_off = 0;		keys_nr = 4;		store_vals[0].val.str_val = uuid;	} else if (sp->flags&AVPOPS_VAL_STR) {		/* use the STR value as uuid */		/* set values for keys  */		keys_off = 0;		keys_nr = 4;		store_vals[0].val.str_val = *sp->val.s;	} else {		LOG(L_CRIT,"BUG:avpops:store_avps: invalid flag combination (%d)\n",			sp->flags);		goto error;	}	/* set uuid/(username and domain) fields */	n =0 ;	if ((dbp->a.flags&AVPOPS_VAL_NONE)==0)	{		/* avp name is known ->set it and its type */		name_type = (((dbp->a.flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR);		store_vals[1].val.str_val = dbp->sa; /*attr name*/		avp = search_first_avp( name_type, dbp->a.val, &i_s);		for( ; avp; avp=search_next_avp(avp,&i_s))		{			/* 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( store_keys+keys_off, store_vals+keys_off,					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;			/* check if type match */			if ( !( (dbp->a.flags&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 ||				((dbp->a.flags&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0)				||((dbp->a.flags&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR))))				continue;			/* set attribute name and type */			if ( (i_s.s=get_avp_name(avp))==0 )				i_s.n = avp->id;			int_str2db_val( i_s, &store_vals[1].val.str_val,				avp->flags&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( store_keys+keys_off, store_vals+keys_off,			keys_nr, dbp->table)==0)			{				avp->flags |= AVP_IS_IN_DB;				n++;			}		}	}	DBG("DEBUG:avpops:store_avps: %d avps were stored\n",n);	return n==0?-1:1;error:	return -1;}int ops_dbdelete_avps (struct sip_msg* msg, struct fis_param *sp,									struct db_param *dbp, int use_domain){	struct sip_uri  uri;	int             res;	str             uuid;	if (sp->flags&AVPOPS_VAL_NONE)	{		/* get and parse uri */		if (parse_source_uri( msg, sp->flags, &uri)<0 )		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -