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

📄 cpl_run.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) {		get_basic_attr( p, attr_name, n, intr, script_error);		switch (attr_name) {			case STATUS_ATTR:				status = n;				break;			case REASON_ATTR:				get_str_attr( p, reason_s, n, intr, script_error,1);				break;			default:				LOG(L_ERR,"ERROR:cpl_c:run_reject: unknown attribute "					"(%d) in REJECT node\n",attr_name);				goto script_error;		}	}	if (status==UNDEF_CHAR) {		LOG(L_ERR,"ERROR:cpl_c:run_reject: mandatory attribute STATUS "			"not found\n");		goto script_error;	}	if (status<400 || status>=700) {		LOG(L_ERR,"ERROR:cpl_c:run_reject: bad attribute STATUS "			"(%d)\n",status);		goto script_error;	}	if (reason_s==(char*)UNDEF_CHAR ) {		switch (status) {			case 486:				reason_s = "Busy Here";				break;			case 404:				reason_s = "Not Found";				break;			case 603:				reason_s = "Decline";				break;			case 500:				reason_s = "Internal Server Error";				break;			default:				reason_s = "Generic Error";		}	}	/* if still stateless and FORCE_STATEFUL set -> build the transaction */	if ( !(intr->flags&CPL_IS_STATEFUL) && intr->flags&CPL_FORCE_STATEFUL) {		i = cpl_fct.tmb.t_newtran( intr->msg );		if (i<0) {			LOG(L_ERR,"ERROR:cpl-c:run_reject: failed to build new "				"transaction!\n");			goto runtime_error;		} else if (i==0) {			LOG(L_ERR,"ERROR:cpl-c:run_reject: processed INVITE is a "				"retransmission!\n");			/* instead of generating an error is better just to break the			 * script by returning EO_SCRIPT */			return EO_SCRIPT;		}		intr->flags |= CPL_IS_STATEFUL;	}	/* send the reply */	if ( intr->flags&CPL_IS_STATEFUL ) {		/* reply statefully */		i = cpl_fct.tmb.t_reply(intr->msg, (int)status, reason_s );	} else {		/* reply statelessly */		i = cpl_fct.sl_reply(intr->msg, (char*)(long)status, reason_s );	}	if ( i!=1 ) {		LOG(L_ERR,"ERROR:run_reject: unable to send reject reply!\n");		goto runtime_error;	}	return EO_SCRIPT;runtime_error:	return CPL_RUNTIME_ERROR;script_error:	return CPL_SCRIPT_ERROR;}/* UPDATED + CHECKED */static inline char *run_redirect( struct cpl_interpreter *intr ){	struct location *loc;	struct lump_rpl *lump;	unsigned short attr_name;	unsigned short permanent;	unsigned short n;	char *p;	str lump_str;	char *cp;	int i;	permanent = NO_VAL;	/* sanity check */	if (NR_OF_KIDS(intr->ip)!=0) {		LOG(L_ERR,"ERROR:cpl-c:run_redirect: REDIRECT node doesn't suppose "			"to have any sub-nodes. Found %d!\n",NR_OF_KIDS(intr->ip));		goto script_error;	}	/* read the attributes of the REDIRECT node*/	for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) {		get_basic_attr( p, attr_name, n, intr, script_error);		switch (attr_name) {			case PERMANENT_ATTR:				if (n!=YES_VAL && n!=NO_VAL) {					LOG(L_ERR,"ERROR:cpl-c:run_redirect: unsupported value (%d)"						" in attribute PERMANENT for REDIRECT node",n);					goto script_error;				}				permanent = n;				break;			default:				LOG(L_ERR,"ERROR:run_redirect: unknown attribute "					"(%d) in REDIRECT node\n",attr_name);				goto script_error;		}	}	/* build the lump for Contact header */	lump_str.len = 9 /*"Contact: "*/;	for(loc=intr->loc_set;loc;loc=loc->next)		lump_str.len += 1/*"<"*/ + loc->addr.uri.len + 7/*">;q=x.x"*/ +			2*(loc->next!=0)/*" ,"*/;	lump_str.len += CRLF_LEN;	lump_str.s = pkg_malloc( lump_str.len );	if(!lump_str.s) {		LOG(L_ERR,"ERROR:cpl-c:run_redirect: out of pkg memory!\n");		goto runtime_error;	}	cp = lump_str.s;	memcpy( cp , "Contact: " , 9);	cp += 9;	for(loc=intr->loc_set;loc;loc=loc->next) {		*(cp++) = '<';		memcpy(cp,loc->addr.uri.s,loc->addr.uri.len);		cp += loc->addr.uri.len;		memcpy(cp,">;q=",4);		cp += 4;		*(cp++) = (loc->addr.priority!=10)?'0':'1';		*(cp++) = '.';		*(cp++) = '0'+(loc->addr.priority%10);		if (loc->next) {			*(cp++) = ' ';			*(cp++) = ',';		}	}	memcpy(cp,CRLF,CRLF_LEN);	/* if still stateless and FORCE_STATEFUL set -> build the transaction */	if ( !(intr->flags&CPL_IS_STATEFUL) && intr->flags&CPL_FORCE_STATEFUL) {		i = cpl_fct.tmb.t_newtran( intr->msg );		if (i<0) {			LOG(L_ERR,"ERROR:cpl-c:run_redirect: failed to build new "				"transaction!\n");			pkg_free( lump_str.s );			goto runtime_error;		} else if (i==0) {			LOG(L_ERR,"ERROR:cpl-c:run_redirect: processed INVITE is a "				"retransmission!\n");			/* instead of generating an error is better just to break the			 * script by returning EO_SCRIPT */			pkg_free( lump_str.s );			return EO_SCRIPT;		}		intr->flags |= CPL_IS_STATEFUL;	}	/* add the lump to the reply */	lump = add_lump_rpl( intr->msg, lump_str.s , lump_str.len , LUMP_RPL_HDR);	if(!lump) {		LOG(L_ERR,"ERROR:cpl-c:run_redirect: unable to add lump_rpl! \n");		pkg_free( lump_str.s );		goto runtime_error;	}	/* send the reply */	if ( intr->flags&CPL_IS_STATEFUL ) {		/* reply statefully */		if (permanent)			i = cpl_fct.tmb.t_reply( intr->msg, (int)301, "Moved permanently");		else			i = cpl_fct.tmb.t_reply( intr->msg, (int)302, "Moved temporarily");	} else {		/* reply statelessly */		if (permanent)			i = cpl_fct.sl_reply( intr->msg, (char*)301, "Moved permanently");		else			i = cpl_fct.sl_reply( intr->msg, (char*)302, "Moved temporarily");	}	/* msg which I'm working on can be in private memory or is a clone into	 * shared memory (if I'm after a failed proxy); So, it's better to removed	 * by myself the lump that I added previously */	unlink_lump_rpl( intr->msg, lump);	free_lump_rpl( lump );	if (i!=1) {		LOG(L_ERR,"ERROR:cpl-c:run_redirect: unable to send "			"redirect reply!\n");		goto runtime_error;	}	return EO_SCRIPT;runtime_error:	return CPL_RUNTIME_ERROR;script_error:	return CPL_SCRIPT_ERROR;}/* UPDATED + CHECKED */static inline char *run_log( struct cpl_interpreter *intr ){	char  *p;	unsigned short attr_name;	unsigned short n;	str name    = {0,0};	str comment = {0,0};	str user;	int i;	/* sanity check */	if (NR_OF_KIDS(intr->ip)>1) {		LOG(L_ERR,"ERROR:cpl_c:run_log: LOG node suppose to have max one child"			", not %d!\n",NR_OF_KIDS(intr->ip));		goto script_error;	}	/* is logging enabled? */	if ( cpl_env.log_dir==0 )		goto done;	/* read the attributes of the LOG node*/	p = ATTR_PTR(intr->ip);	for( i=NR_OF_ATTR(intr->ip); i>0 ; i-- ) {		get_basic_attr( p, attr_name, n, intr, script_error);		switch (attr_name) {			case NAME_ATTR:				get_str_attr( p, name.s, n, intr, script_error,1);				name.len = n;				break;			case COMMENT_ATTR:				get_str_attr( p, comment.s, n, intr, script_error,1);				comment.len = n;				break;			default:				LOG(L_ERR,"ERROR:cpl_c:run_log: unknown attribute "					"(%d) in LOG node\n",attr_name);				goto script_error;		}	}	if (comment.len==0) {		LOG(L_NOTICE,"NOTICE:cpl_c:run_log: LOG node has no comment attr -> "			"skipping\n");		goto done;	}	user.len = intr->user.len + name.len + comment.len;	/* duplicate the attrs in shm memory */	user.s = p = (char*)shm_malloc( user.len );	if (!user.s) {		LOG(L_ERR,"ERROR:cpl_c:run_log: no more shm memory!\n");		goto runtime_error;	}	/* copy the user name */	memcpy( p, intr->user.s, intr->user.len);	user.len = intr->user.len;	p += intr->user.len;	/* copy the log name */	if (name.len) {		memcpy( p, name.s, name.len );		name.s = p;		p += name.len;	}	/* copy the comment */	memcpy( p, comment.s, comment.len);	comment.s = p;	/* send the command */	write_cpl_cmd( CPL_LOG_CMD, &user, &name, &comment );done:	return get_first_child(intr->ip);runtime_error:	return CPL_RUNTIME_ERROR;script_error:	return CPL_SCRIPT_ERROR;}/* UPDATED + CHECKED */static inline char *run_mail( struct cpl_interpreter *intr ){	unsigned short attr_name;	unsigned short n;	char  *p;	str subject = {0,0};	str body    = {0,0};	str to      = {0,0};	int i;	/* sanity check */	if (NR_OF_KIDS(intr->ip)>1) {		LOG(L_ERR,"ERROR:cpl_c:run_mail: MAIL node suppose to have max one"			" child, not %d!\n",NR_OF_KIDS(intr->ip));		goto script_error;	}	/* read the attributes of the MAIL node*/	for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) {		get_basic_attr(p, attr_name, n, intr, script_error);		switch (attr_name) {			case TO_ATTR:				get_str_attr(p, to.s, n, intr, script_error,0);				to.len = n;				break;			case SUBJECT_ATTR:				get_str_attr(p, subject.s, n, intr, script_error,0);				subject.len = n;				break;			case BODY_ATTR:				get_str_attr(p, body.s, n, intr, script_error,0);				body.len = n;				break;			default:				LOG(L_ERR,"ERROR:run_mail: unknown attribute "					"(%d) in MAIL node\n",attr_name);				goto script_error;		}	}	if (to.len==0) {		LOG(L_ERR,"ERROR:cpl_c:run_mail: email has an empty TO hdr!\n");		goto script_error;	}	if (body.len==0 && subject.len==0) {		LOG(L_WARN,"WARNING:cpl_c:run_mail: I refuse to send email with no "			"body and no subject -> skipping...\n");		goto done;	}	/* duplicate the attrs in shm memory */	p = (char*)shm_malloc( to.len + subject.len + body.len );	if (!p) {		LOG(L_ERR,"ERROR:cpl_c:run_mail: no more shm memory!\n");		goto runtime_error;	}	/* copy the TO */	memcpy( p, to.s, to.len );	to.s = p;	p += to.len;	/* copy the subject */	if (subject.len) {		memcpy( p, subject.s, subject.len );		subject.s = p;		p += subject.len;	}	/* copy the body */	if (body.len) {		memcpy( p, body.s, body.len );		body.s = p;		p += body.len;	}	/* send the command */	write_cpl_cmd( CPL_MAIL_CMD, &to, &subject, &body);done:	return get_first_child(intr->ip);runtime_error:	return CPL_RUNTIME_ERROR;script_error:	return CPL_SCRIPT_ERROR;}static inline int run_default( struct cpl_interpreter *intr ){	if (!(intr->flags&CPL_PROXY_DONE)) {		/* no signaling operations */		if ( !(intr->flags&CPL_LOC_SET_MODIFIED) ) {			/*  no location modifications */			if (intr->loc_set==0 ) {				/* case 1 : no location modifications or signaling operations				 * performed, location set empty ->				 * Look up the user's location through whatever mechanism the				 * server would use if no CPL script were in effect */				return SCRIPT_DEFAULT;			} else {				/* case 2 : no location modifications or signaling operations				 * performed, location set non-empty: (This can only happen 				 * for outgoing calls.) ->				 * Proxy the call to the address in the location set.				 * With other words, let ser to continue processing the				 * request as nothing happened */				return SCRIPT_DEFAULT;			}		} else {			/* case 3 : location modifications performed, no signaling 			 * operations ->			 * Proxy the call to the addresses in the location set */			if (!cpl_proxy_to_loc_set(intr->msg,&(intr->loc_set),intr->flags))				return SCRIPT_END;			return SCRIPT_RUN_ERROR;		}	} else {		/* case 4 : proxy operation previously taken -> return whatever the 		 * "best" response is of all accumulated responses to the call to this		 * point, according to the rules of the underlying signaling		 * protocol. */		/* we will let ser to choose and forward one of the replies -> for this		 * nothing must be done */		return SCRIPT_END;	}	/*return SCRIPT_RUN_ERROR;*/}/* include all inline functions for processing the switches */#include "cpl_switches.h"/* include inline function for running proxy node */#include "cpl_proxy.h"int cpl_run_script( struct cpl_interpreter *intr ){	char *new_ip;	do {		check_overflow_by_offset( SIMPLE_NODE_SIZE(intr->ip), intr, error);		switch ( NODE_TYPE(intr->ip) ) {			case CPL_NODE:				DBG("DEBUG:cpl_run_script: processing CPL node \n");				new_ip = run_cpl_node( intr ); /*UPDATED&TESTED*/				break;			case ADDRESS_SWITCH_NODE:				DBG("DEBUG:cpl_run_script: processing address-switch node\n");				new_ip = run_address_switch( intr ); /*UPDATED&TESTED*/				break;			case STRING_SWITCH_NODE:				DBG("DEBUG:cpl_run_script: processing string-switch node\n");				new_ip = run_string_switch( intr ); /*UPDATED&TESTED*/				break;			case PRIORITY_SWITCH_NODE:				DBG("DEBUG:cpl_run_script: processing priority-switch node\n");				new_ip = run_priority_switch( intr ); /*UPDATED&TESTED*/				break;			case TIME_SWITCH_NODE:				DBG("DEBUG:cpl_run_script: processing time-switch node\n");				new_ip = run_time_switch( intr ); /*UPDATED&TESTED*/				break;			case LANGUAGE_SWITCH_NODE:				DBG("DEBUG:cpl_run_script: processing language-switch node\n");				new_ip = run_language_switch( intr ); /*UPDATED&TESTED*/				break;			case LOOKUP_NODE:				DBG("DEBUG:cpl_run_script: processing lookup node\n");				new_ip = run_lookup( intr ); /*UPDATED&TESTED*/				break;			case LOCATION_NODE:				DBG("DEBUG:cpl_run_script: processing location node\n");				new_ip = run_location( intr ); /*UPDATED&TESTED*/				break;			case REMOVE_LOCATION_NODE:				DBG("DEBUG:cpl_run_script: processing remove_location node\n");				new_ip = run_remove_location( intr ); /*UPDATED&TESTED*/				break;			case PROXY_NODE:				DBG("DEBUG:cpl_run_script: processing proxy node\n");				new_ip = run_proxy( intr );/*UPDATED&TESTED*/				break;			case REJECT_NODE:				DBG("DEBUG:cpl_run_script: processing reject node\n");				new_ip = run_reject( intr ); /*UPDATED&TESTED*/				break;			case REDIRECT_NODE:				DBG("DEBUG:cpl_run_script: processing redirect node\n");				new_ip = run_redirect( intr ); /*UPDATED&TESTED*/				break;			case LOG_NODE:				DBG("DEBUG:cpl_run_script: processing log node\n");				new_ip = run_log( intr ); /*UPDATED&TESTED*/				break;			case MAIL_NODE:				DBG("DEBUG:cpl_run_script: processing mail node\n");				new_ip = run_mail( intr ); /*UPDATED&TESTED*/				break;			case SUB_NODE:				DBG("DEBUG:cpl_run_script: processing sub node\n");				new_ip = run_sub( intr ); /*UPDATED&TESTED*/				break;			default:				LOG(L_ERR,"ERROR:cpl_run_script: unknown type node (%d)\n",					NODE_TYPE(intr->ip));				goto error;		}		if (new_ip==CPL_RUNTIME_ERROR) {			LOG(L_ERR,"ERROR:cpl_c:cpl_run_script: runtime error\n");			return SCRIPT_RUN_ERROR;		} else if (new_ip==CPL_SCRIPT_ERROR) {			LOG(L_ERR,"ERROR:cpl_c:cpl_run_script: script error\n");			return SCRIPT_FORMAT_ERROR;		} else if (new_ip==DEFAULT_ACTION) {			DBG("DEBUG:cpl_c:cpl_run_script: running default action\n");			return run_default(intr);		} else if (new_ip==EO_SCRIPT) {			DBG("DEBUG:cpl_c:cpl_run_script: script interpretation done!\n");			return SCRIPT_END;		} else if (new_ip==CPL_TO_CONTINUE) {			DBG("DEBUG:cpl_c:cpl_run_script: done for the moment; waiting "				"after signaling!\n");			return SCRIPT_TO_BE_CONTINUED;		}		/* move to the new instruction */		intr->ip = new_ip;	}while(1);error:	return SCRIPT_FORMAT_ERROR;}

⌨️ 快捷键说明

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