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 + -
显示快捷键?