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

📄 cpl_switches.h

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 H
📖 第 1 页 / 共 3 页
字号:
/* * $Id: cpl_switches.h,v 1.13.2.1 2005/06/03 00:56:22 andrei Exp $ * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser 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 * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser 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 * * History: * ------- * 2003-06-27: file created (bogdan) */#include "cpl_time.h"#include "../../parser/parse_from.h"#include "../../parser/parse_uri.h"/* UPDATED + CHECKED */static inline char *run_address_switch( struct cpl_interpreter *intr ){	static str def_port_str = {"5060",4};	unsigned short field, subfield;	char  *p;	char  *kid;	unsigned short  attr_name;	unsigned short n;	int i;	int k;	str cpl_val;	str *msg_val;	str *uri;	struct sip_uri parsed_uri;	field = subfield = UNDEF_CHAR;	msg_val = 0;	p=ATTR_PTR(intr->ip);	/* parse the attributes */	for( i=NR_OF_ATTR(intr->ip) ; i>0 ; i-- ) {		get_basic_attr( p, attr_name, n, intr, script_error);		switch (attr_name) {			case FIELD_ATTR:				if (field!=UNDEF_CHAR) {					LOG(L_ERR,"ERROR:cpl-c:run_address_switch: multiple FIELD "						"attrs found\n");					goto script_error;				}				field = n;				break;			case SUBFIELD_ATTR:				if (subfield!=UNDEF_CHAR) {					LOG(L_ERR,"ERROR:cpl-c:run_address_switch: multiple SUBFIELD"						" attrs found\n");					goto script_error;				}				subfield = n; break;			default:				LOG(L_ERR,"ERROR:cpl_c:run_address_switch: unknown attribute "					"(%d) in ADDRESS_SWITCH node\n",*p);				goto script_error;		}	}	if (field==UNDEF_CHAR) {		LOG(L_ERR,"ERROR:cpl_c:run_address_switch: mandatory param FIELD "			"no found\n");		goto script_error;	}	/* test the condition from all the sub-nodes */	for( i=0 ; i<NR_OF_KIDS(intr->ip) ; i++ ) {		kid = intr->ip + KID_OFFSET(intr->ip,i);		check_overflow_by_ptr( kid+SIMPLE_NODE_SIZE(kid), intr, script_error);		switch ( NODE_TYPE(kid) ) {			case NOT_PRESENT_NODE:				DBG("DEBUG:run_address_switch: NOT_PRESENT node found ->"					"skipping (useless in this case)\n");				break;			case OTHERWISE_NODE :				if (i!=NR_OF_KIDS(intr->ip)-1) {					LOG(L_ERR,"ERROR:run_address_switch: OTHERWISE node "						"not found as the last sub-node!\n");					goto script_error;				}				DBG("DEBUG:run_address_switch: matching on OTHERWISE node\n");				return get_first_child(kid);			case ADDRESS_NODE :				/* check the number of attributes */				if (NR_OF_ATTR(kid)!=1) {					LOG(L_ERR,"ERROR:run_address_switch: incorrect nr of attrs "						"(%d) in ADDRESS node\n",NR_OF_ATTR(kid));					goto script_error;				}				/* get the attribute name */				p = ATTR_PTR(kid);				get_basic_attr( p, attr_name, cpl_val.len, intr, script_error);				if (attr_name!=IS_ATTR && attr_name!=CONTAINS_ATTR &&				attr_name!=SUBDOMAIN_OF_ATTR) {					LOG(L_ERR,"ERROR:run_address_switch: unknown attribute "						"(%d) in ADDRESS node\n",attr_name);					goto script_error;				}				/* get attribute value */				get_str_attr( p, cpl_val.s, cpl_val.len, intr, script_error,1);				DBG("DEBUG:run_address_switch: testing ADDRESS branch "					" attr_name=%d attr_val=[%.*s](%d)..\n",					attr_name,cpl_val.len,cpl_val.s,cpl_val.len);				/* extract the needed value from the message */				if (!msg_val) {					switch (field) {						case ORIGIN_VAL: /* FROM */							if (!intr->from) {								/* get the header */								if (parse_from_header( intr->msg )==-1)									goto runtime_error;								intr->from = &(get_from(intr->msg)->uri);							}							uri = intr->from;						break;						case DESTINATION_VAL: /* RURI */							if (!intr->ruri)								intr->ruri = GET_RURI( intr->msg );							uri = intr->ruri;							break;						case ORIGINAL_DESTINATION_VAL: /* TO */							if (!intr->to) {								/* get and parse the header */								if (!intr->msg->to &&								(parse_headers(intr->msg,HDR_TO,0)==-1 ||								!intr->msg->to)) {									LOG(L_ERR,"ERROR:run_address_switch: bad "										"msg or missing TO header\n");									goto runtime_error;								}								intr->to = &(get_to(intr->msg)->uri);							}							uri = intr->to;							break;						default:							LOG(L_ERR,"ERROR:run_address_switch: unknown "								"attribute (%d) in ADDRESS node\n",field);							goto script_error;					}					DBG("DEBUG:run_address_switch: extracted uri is <%.*s>\n",						uri->len, uri->s);					switch (subfield) {						case UNDEF_CHAR:							msg_val = uri;							break;						case USER_VAL:							if (parse_uri( uri->s, uri->len, &parsed_uri)<0)								goto runtime_error;							msg_val = &(parsed_uri.user);							break;						case HOST_VAL:							if (parse_uri( uri->s, uri->len, &parsed_uri)<0)								goto runtime_error;							msg_val = &(parsed_uri.host);							break;						case PORT_VAL:							if (parse_uri( uri->s, uri->len, &parsed_uri)<0)								goto runtime_error;							if (parsed_uri.port.len!=0)								msg_val = &(parsed_uri.port);							else								msg_val = &def_port_str;							break;						case TEL_VAL:							if (parse_uri( uri->s, uri->len, &parsed_uri)<0)								goto runtime_error;							if (parsed_uri.user_param_val.len==5 &&							memcmp(parsed_uri.user_param_val.s,"phone",5)==0)								msg_val = &(parsed_uri.user);							break;						case ADDRESS_TYPE_VAL:						case DISPLAY_VAL:						default:							LOG(L_ERR,"ERROR:run_address_switch: unsupported "								"value attribute (%d) in ADDRESS node\n",								subfield);							goto script_error;					}					DBG("DEBUG:run_address_switch: extracted val. is <%.*s>\n",						(msg_val==0)?0:msg_val->len, (msg_val==0)?0:msg_val->s);				}				/* does the value from script match the one from message? */				switch (attr_name) {					case IS_ATTR:						if ( (!msg_val && !cpl_val.s) ||						(msg_val && msg_val->len==cpl_val.len &&						strncasecmp(msg_val->s,cpl_val.s,cpl_val.len)==0)) {							DBG("DEBUG:run_address_switch: matching on "								"ADDRESS node (IS)\n");							return get_first_child(kid);						}						break;					case CONTAINS_ATTR:						if (subfield!=DISPLAY_VAL) {							LOG(L_WARN,"WARNING:run_address_switch: operator "							"CONTAINS applies only to DISPLAY -> ignored\n");						} else {							if ( msg_val && cpl_val.len<=msg_val->len &&							strcasestr_str(msg_val, &cpl_val)!=0 ) {								DBG("DEBUG:run_address_switch: matching on "									"ADDRESS node (CONTAINS)\n");								return get_first_child(kid);							}						}						break;					case SUBDOMAIN_OF_ATTR:						switch (subfield) {							case HOST_VAL:								k = msg_val->len - cpl_val.len;								if (k>=0 && (k==0 || msg_val->s[k-1]=='.') &&								!strncasecmp(cpl_val.s,msg_val->s+k,cpl_val.len)								) {									DBG("DEBUG:run_address_switch: matching on "										"ADDRESS node (SUBDOMAIN_OF)\n");									return get_first_child(kid);								}								break;							case TEL_VAL:								if (msg_val==0) break;								if (msg_val->len>=cpl_val.len && !strncasecmp(								cpl_val.s,msg_val->s,cpl_val.len)) {									DBG("DEBUG:run_address_switch: matching on "										"ADDRESS node (SUBDOMAIN_OF)\n");									return get_first_child(kid);								}								break;							default:								LOG(L_WARN,"WARNING:run_address_switch: operator"									" SUBDOMAIN_OF applies only to HOST or TEL "									"-> ignored\n");						}						break;				}				break;			default:				LOG(L_ERR,"ERROR:run_address_switch: unknown output node type "					"(%d) for ADDRESS_SWITCH node\n",NODE_TYPE(kid));				goto script_error;		}	}	/* none of the branches of ADDRESS_SWITCH matched -> go for default */	return DEFAULT_ACTION;runtime_error:	return CPL_RUNTIME_ERROR;script_error:	return CPL_SCRIPT_ERROR;}/* UPDATED + CHECKED */static inline char *run_string_switch( struct cpl_interpreter *intr ){	unsigned short field;	char *p;	char *kid;	char *not_present_node;	unsigned short attr_name;	int i;	str cpl_val;	str msg_val;	not_present_node = 0;	msg_val.s = 0;	msg_val.len = 0;	/* parse the attribute */	if (NR_OF_ATTR(intr->ip)!=1) {		LOG(L_ERR,"ERROR:cpl_c:run_string_switch: node should have 1 attr, not"			" (%d)\n",NR_OF_ATTR(intr->ip));		goto script_error;	}	p=ATTR_PTR(intr->ip);	get_basic_attr( p, attr_name, field, intr, script_error);	if (attr_name!=FIELD_ATTR) {		LOG(L_ERR,"ERROR:cpl_c:run_string_switch: unknown param type (%d)"			" for STRING_SWITCH node\n",*p);		goto script_error;	}	for( i=0 ; i<NR_OF_KIDS(intr->ip) ; i++ ) {		kid = intr->ip + KID_OFFSET(intr->ip,i);		check_overflow_by_ptr( kid+SIMPLE_NODE_SIZE(kid), intr, script_error);		switch ( NODE_TYPE(kid) ) {			case NOT_PRESENT_NODE:				if (not_present_node) {					LOG(L_ERR,"ERROR:run_string_switch: NOT_PRESENT node "						"found twice!\n");					goto script_error;				}				not_present_node = kid;				break;			case OTHERWISE_NODE :				if (i!=NR_OF_KIDS(intr->ip)-1) {					LOG(L_ERR,"ERROR:run_string_switch: OTHERWISE node "						"not found as the last sub-node!\n");					goto script_error;				}				DBG("DEBUG:run_string_switch: matching on OTHERWISE node\n");				return get_first_child(kid);			case STRING_NODE :				/* check the number of attributes */				if (NR_OF_ATTR(kid)!=1) {					LOG(L_ERR,"ERROR:run_string_switch: incorrect nr of attrs "						"(%d) in STRING node (expected 1)\n",NR_OF_ATTR(kid));					goto script_error;				}				/* get the attribute name */				p = ATTR_PTR(kid);				get_basic_attr( p, attr_name, cpl_val.len, intr, script_error);				if (attr_name!=IS_ATTR && attr_name!=CONTAINS_ATTR ) {					LOG(L_ERR,"ERROR:run_string_switch: unknown attribute "						"(%d) in STRING node\n",attr_name);					goto script_error;				}				/* get attribute value */				get_str_attr( p, cpl_val.s, cpl_val.len, intr, script_error,1);				DBG("DEBUG:run_string_switch: testing STRING branch "					"attr_name=%d attr_val=[%.*s](%d)..\n",					attr_name,cpl_val.len,cpl_val.s,cpl_val.len);				if (!msg_val.s) {					switch (field) {						case SUBJECT_VAL: /* SUBJECT */							if (intr->subject==STR_NOT_FOUND)								goto not_present;							if (!intr->subject) {								/* get the subject header */								if (!intr->msg->subject) {									if (parse_headers(intr->msg,									HDR_SUBJECT,0)==-1) {										LOG(L_ERR,"ERROR:run_string_switch: "										"bad SUBJECT header\n");										goto runtime_error;									} else if (!intr->msg->subject) {										/* hdr not present */										intr->subject = STR_NOT_FOUND;										goto not_present;									}								}								intr->subject =									&(intr->msg->subject->body);							}							trim_len( msg_val.len,msg_val.s,								*(intr->subject));

⌨️ 快捷键说明

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