📄 cpl_switches.h
字号:
/* * $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 + -