t_fifo.c

来自「性能优秀的SIP Proxy」· C语言 代码 · 共 821 行 · 第 1/2 页

C
821
字号
/* * $Id: t_fifo.c,v 1.12 2006/06/13 10:50:12 bogdan_iancu Exp $ * * transaction maintenance functions * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of openser, a free SIP server. * * openser 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 * * openser 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: * ------- *  2004-02-23  created by splitting it from t_funcs (bogdan) *  2004-11-15  t_write_xxx can print whatever avp/hdr *  2005-07-14  t_write_xxx specification aligned to use pseudo-variables  *              (bogdan) */#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <sys/uio.h>#include <unistd.h>#include <fcntl.h>#include <sys/un.h>#include <ctype.h>#include <string.h>#include "../../str.h"#include "../../ut.h"#include "../../dprint.h"#include "../../items.h"#include "../../mem/mem.h"#include "../../parser/parser_f.h"#include "../../parser/parse_from.h"#include "../../parser/parse_rr.h"#include "../../parser/contact/parse_contact.h"#include "../../tsend.h"#include "t_lookup.h"#include "t_fwd.h"#include "t_fifo.h"/* AF_LOCAL is not defined on solaris */#if !defined(AF_LOCAL)#define AF_LOCAL AF_UNIX#endif#if !defined(PF_LOCAL)#define PF_LOCAL PF_UNIX#endif/* solaris doesn't have SUN_LEN */#ifndef SUN_LEN#define SUN_LEN(sa)	 ( strlen((sa)->sun_path) + \					 (size_t)(((struct sockaddr_un*)0)->sun_path) )#endifint tm_unix_tx_timeout = 2; /* Default is 2 seconds */#define TWRITE_PARAMS          20#define TWRITE_VERSION_S       "0.3"#define TWRITE_VERSION_LEN     (sizeof(TWRITE_VERSION_S)-1)#define eol_line(_i_)          ( lines_eol[2*(_i_)] )#define IDBUF_LEN              128#define ROUTE_BUFFER_MAX       512#define APPEND_BUFFER_MAX      4096#define CMD_BUFFER_MAX         128#define append_str(_dest,_src,_len) \	do{ \		memcpy( (_dest) , (_src) , (_len) );\		(_dest) += (_len) ;\	}while(0);#define append_chr(_dest,_c) \	*((_dest)++) = _c;#define copy_route(s,len,rs,rlen) \	do {\		if(rlen+len+3 >= ROUTE_BUFFER_MAX){\			LOG(L_ERR,"vm: buffer overflow while copying new route\n");\			goto error;\		}\		if(len){\			append_chr(s,','); len++;\		}\		append_chr(s,'<');len++;\		append_str(s,rs,rlen);\		len += rlen; \		append_chr(s,'>');len++;\	} while(0)static str   lines_eol[2*TWRITE_PARAMS];static str   eol={"\n",1};static int sock;struct append_elem {	str        name;       /* name / title */	xl_spec_t  spec;       /* value's spec */	struct append_elem *next;};struct tw_append {	str name;	int add_body;	struct append_elem *elems;	struct tw_append   *next;};struct tw_info {	str action;	struct tw_append *append;};static struct tw_append *tw_appends;/* tw_append syntax: * tw_append = name:element[;element] * element   = (title=pseudo_variable) | msg(body) */int parse_tw_append( modparam_t type, void* val){	struct append_elem *last;	struct append_elem *elem;	struct tw_append *app;	xl_spec_t lspec;	char *s;	str  foo;	int  xl_flags;		if (val==0 || ((char*)val)[0]==0)		return 0;	s = (char*)val;	xl_flags = XL_THROW_ERROR | XL_DISABLE_COLORS;	/* start parsing - first the name */	while( *s && isspace((int)*s) )  s++;	if ( !*s || *s==':')		goto parse_error;	foo.s = s;	while ( *s && *s!=':' && !isspace((int)*s) ) s++;	if ( !*s || foo.s==s )		goto parse_error;	foo.len = s - foo.s;	/* parse separator */	while( *s && isspace((int)*s) )  s++;	if ( !*s || *s!=':')		goto parse_error;	s++;	/* check for name duplication */	for(app=tw_appends;app;app=app->next)		if (app->name.len==foo.len && !strncasecmp(app->name.s,foo.s,foo.len)){			LOG(L_ERR,"ERROR:tm:parse_tw_append: duplicated tw_append name "				"<%.*s>\n",foo.len,foo.s);			goto error;		}	/* new tw_append structure */	app = (struct tw_append*)pkg_malloc( sizeof(struct tw_append) );	if (app==0) {		LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg memory\n");		goto error;	}	/* init the new append */	app->name = foo;	last = app->elems = 0;	/* link the new append */	app->next = tw_appends;	tw_appends = app;	/* parse the elements */	while (*s) {		/* skip white spaces */		while( *s && isspace((int)*s) )  s++;		if ( !*s )			goto parse_error;		/* parse element name */		foo.s = s;		while( *s && *s!='=' && *s!=';' && !isspace((int)*s) ) s++;		if (foo.s==s)			goto parse_error;		foo.len = s - foo.s;		/* skip spaces */		while( *s && isspace((int)*s) )  s++;		if ( *s && *s!='=' && *s!=';' )			goto parse_error;		/* short element (without name) ? */		if (*s=='=' ) {			/* skip '=' */			s++;			/* new append_elem structure */			elem = (struct append_elem*)pkg_malloc(sizeof(struct append_elem));			if (elem==0) {				LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg memory\n");				goto error;			}			memset( elem, 0, sizeof(struct append_elem));			/* set and link the element */			elem->name = foo;			if (last==0) {				app->elems = elem;			} else {				last->next = elem;			}			last = elem;			/* skip spaces */			while (*s && isspace((int)*s))				s++;		} else {			/* go back to reparse as value */			s = foo.s;			elem = 0;		}		/* get value type */		if ( (foo.s=xl_parse_spec( s, &lspec, xl_flags))==0 )			goto parse_error;		/* if short element....which one? */		if (elem==0) {			if (lspec.type!=XL_MSG_BODY) {			LOG(L_ERR,"ERROR:tm:parse_tw_append: short spec '%.*s' unknown"					"(aceepted only body)\n",(int)(long)(foo.s-s), s);				goto error;			}			app->add_body = 1;		} else {			elem->spec = lspec;		}		/* continue parsing*/		s = foo.s;		/* skip spaces */		while (*s && isspace((int)*s))  s++;		if (*s && *(s++)!=';')			goto parse_error;	}	/* go throught all elements and make the names null terminated */	for( elem=app->elems ; elem ; elem=elem->next)		elem->name.s[elem->name.len] = 0;	/* make the append name null terminated also */	app->name.s[app->name.len] = 0;	return 0;parse_error:	LOG(L_ERR,"ERROR:tm:parse_tw_append: parse error in <%s> around "		"position %ld(%c)\n", (char*)val, (long)(s-(char*)val),*s);error:	return -1;}static struct tw_append *search_tw_append(char *name, int len){	struct tw_append * app;	for( app=tw_appends ; app ; app=app->next )		if (app->name.len==len && !strncasecmp(app->name.s,name,len) )			return app;	return 0;}int fixup_t_write( void** param, int param_no){	struct tw_info *twi;	char *s;	if (param_no==2) {		twi = (struct tw_info*)pkg_malloc( sizeof(struct tw_info) );		if (twi==0) {			LOG(L_ERR,"ERROR:tm:fixup_t_write: no more pkg memory\n");			return E_OUT_OF_MEM;		}		memset( twi, 0 , sizeof(struct tw_info));		s = (char*)*param;		twi->action.s = s;		if ( (s=strchr(s,'/'))!=0) {			twi->action.len = s - twi->action.s;			if (twi->action.len==0) {				LOG(L_ERR,"ERROR:tm:fixup_t_write: empty action name\n");				return E_CFG;			}			s++;			if (*s==0) {				LOG(L_ERR,"ERROR:tm:fixup_t_write: empty append name\n");				return E_CFG;			}			twi->append = search_tw_append( s, strlen(s));			if (twi->append==0) {				LOG(L_ERR,"ERROR:tm:fixup_t_write: unknown append name "					"<%s>\n",s);				return E_CFG;			}		} else {			twi->action.len = strlen(twi->action.s);		}		*param=(void*)twi;	}	return 0;}int init_twrite_sock(void){	int flags;	sock = socket(PF_LOCAL, SOCK_DGRAM, 0);	if (sock == -1) {		LOG(L_ERR, "init_twrite_sock: Unable to create socket: %s\n", strerror(errno));		return -1;	}	     /* Turn non-blocking mode on */	flags = fcntl(sock, F_GETFL);	if (flags == -1){		LOG(L_ERR, "init_twrite_sock: fcntl failed: %s\n",		    strerror(errno));		close(sock);		return -1;	}			if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {		LOG(L_ERR, "init_twrite_sock: fcntl: set non-blocking failed:"		    " %s\n", strerror(errno));		close(sock);		return -1;	}	return 0;}int init_twrite_lines(){	int i;	/* init the line table */	for(i=0;i<TWRITE_PARAMS;i++) {		lines_eol[2*i].s = 0;		lines_eol[2*i].len = 0;		lines_eol[2*i+1] = eol;	}	/* first line is the version - fill it now */	eol_line(0).s   = TWRITE_VERSION_S;	eol_line(0).len = TWRITE_VERSION_LEN;	return 0;}static int inline write_to_fifo(char *fifo, int cnt ){	int   fd_fifo;	/* open FIFO file stream */	if((fd_fifo = open(fifo,O_WRONLY | O_NONBLOCK)) == -1){		switch(errno){			case ENXIO:				LOG(L_ERR,"ERROR:tm:write_to_fifo: nobody listening on "					" [%s] fifo for reading!\n",fifo);			default:				LOG(L_ERR,"ERROR:tm:write_to_fifo: failed to open [%s] "					"fifo : %s\n", fifo, strerror(errno));		}		goto error;	}	/* write now (unbuffered straight-down write) */repeat:	if (writev(fd_fifo, (struct iovec*)lines_eol, 2*cnt)<0) {		if (errno!=EINTR) {			LOG(L_ERR, "ERROR:tm:write_to_fifo: writev failed: %s\n",				strerror(errno));			close(fd_fifo);

⌨️ 快捷键说明

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