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

📄 cpl_nonsig.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/* * $Id: cpl_nonsig.c,v 1.8 2004/08/24 08:58:26 janakj 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 <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <time.h>#include <sys/uio.h>#include <signal.h>#include "../../mem/shm_mem.h"#include "../../mem/mem.h"#include "../../dprint.h"#include "cpl_nonsig.h"#include "CPL_tree.h"#define MAX_LOG_FILE_NAME      32#define MAX_FD                 32#define FILE_NAME_SUFIX        ".log"#define FILE_NAME_SUFIX_LEN    (sizeof(FILE_NAME_SUFIX)-1)#define LOG_SEPARATOR          ": "#define LOG_SEPARATOR_LEN      (sizeof(LOG_SEPARATOR)-1)#define DEFAULT_LOG_NAME       "default_log"#define DEFAULT_LOG_NAME_LEN   (sizeof(DEFAULT_LOG_NAME)-1)#define LOG_TERMINATOR          "\n"#define LOG_TERMINATOR_LEN      (sizeof(LOG_TERMINATOR)-1)static char file[MAX_LOG_DIR_SIZE+1+MAX_LOG_FILE_NAME+FILE_NAME_SUFIX_LEN+1];static char *file_ptr;static inline void write_log( struct cpl_cmd *cmd){	struct iovec  wr_vec[5];	time_t now;	char *time_ptr;	int fd;	int ret;	/* build file name (cmd->s1 is the user name)*/	if (cmd->s1.len>MAX_LOG_FILE_NAME)		cmd->s1.len = MAX_LOG_FILE_NAME;	memcpy(file_ptr, cmd->s1.s, cmd->s1.len );	memcpy(file_ptr+cmd->s1.len,FILE_NAME_SUFIX,FILE_NAME_SUFIX_LEN);	file_ptr[cmd->s1.len+FILE_NAME_SUFIX_LEN] = 0;	/* get current date+time -> wr_vec[0] */	time( &now );	time_ptr = ctime( &now );	wr_vec[0].iov_base = time_ptr;	wr_vec[0].iov_len = strlen( time_ptr );	/* ctime_r adds a \n at the end -> overwrite it with space */	time_ptr[ wr_vec[0].iov_len-1 ] = ' ';	/* log name (cmd->s2) ->  wr_vec[1] */	if (cmd->s2.s==0 || cmd->s2.len==0) {		wr_vec[1].iov_base = DEFAULT_LOG_NAME;		wr_vec[1].iov_len = DEFAULT_LOG_NAME_LEN;	} else {		wr_vec[1].iov_base = cmd->s2.s;		wr_vec[1].iov_len = cmd->s2.len;	}	/* log separator ->  wr_vec[2] */	wr_vec[2].iov_base = LOG_SEPARATOR;	wr_vec[2].iov_len = LOG_SEPARATOR_LEN;	/* log comment (cmd->s3) ->  wr_vec[3] */	wr_vec[3].iov_base = cmd->s3.s;	wr_vec[3].iov_len = cmd->s3.len;	/* log terminator ->  wr_vec[2] */	wr_vec[4].iov_base = LOG_TERMINATOR;	wr_vec[4].iov_len = LOG_TERMINATOR_LEN;	/* [create+]open the file */	fd = open( file, O_CREAT|O_APPEND|O_WRONLY, 0664);	if (fd==-1) {		LOG(L_ERR,"ERROR:cpl_c:write_log: cannot open file [%s] : %s\n",			file, strerror(errno) );		return;	}	/* get the log */	DBG("DEBUG:cpl_c:write_log: logging into [%s]... \n",file);	/* I'm really not interested in the return code for write ;-) */	while ( (ret=writev( fd, wr_vec, 5))==-1 ) {		if (errno==EINTR)			continue;		LOG(L_ERR,"ERROR:cpl_c:write_log: writing to log file [%s] : %s\n",			file, strerror(errno) );	}	close (fd);	shm_free( cmd->s1.s );}static inline void send_mail( struct cpl_cmd *cmd){	char *argv[5];	int pfd[2];	pid_t  pid;	int i;	if (pipe(pfd) < 0) {		LOG(L_ERR,"ERROR:cpl_c:send_mail: pipe failed: %s\n",strerror(errno));		return;	}	/* even if I haven't fork yet, I push the date on the pipe just to get	 * rid of one more malloc + copy */	if (cmd->s3.len && cmd->s3.s) {		if ( (i=write( pfd[1], cmd->s3.s, cmd->s3.len ))!=cmd->s3.len ) {			LOG(L_ERR,"ERROR:cpl_c:send_mail: write returned error %s\n",				strerror(errno));			goto error;		}	}	if ( (pid = fork()) < 0) {		LOG(L_ERR,"ERROR:cpl_c:send_mail: fork failed: %s\n",strerror(errno));		goto error;	} else if (pid==0) {		/* child -> close all descriptors excepting pfd[0] */		for (i=3; i < MAX_FD; i++)			if (i!=pfd[0])				close(i);		if (pfd[0] != STDIN_FILENO) {			dup2(pfd[0], STDIN_FILENO);			close(pfd[0]);		}		/* set the argument vector*/		argv[0] = "mail";		argv[1] = "-s";		if (cmd->s2.s && cmd->s2.len) {			/* put the subject in this format : <"$subject"\0> */			if ( (argv[2]=(char*)pkg_malloc(1+cmd->s2.len+1+1))==0) {				LOG(L_ERR,"ERROR:cpl_c:send_mail: cannot get pkg memory\n");				goto child_exit;			}			argv[2][0] = '\"';			memcpy(argv[2]+1,cmd->s2.s,cmd->s2.len);			argv[2][cmd->s2.len+1] = '\"';			argv[2][cmd->s2.len+2] = 0;		} else {			argv[2] = "\"[CPL notification]\"";		}		/* put the TO in <$to\0> format*/		if ( (argv[3]=(char*)pkg_malloc(cmd->s1.len+1))==0) {			LOG(L_ERR,"ERROR:cpl_c:send_mail: cannot get pkg memory\n");			goto child_exit;		}		memcpy(argv[3],cmd->s1.s,cmd->s1.len);		argv[3][cmd->s1.len] = 0;		/* last element in vector mist be a null pointer */		argv[4] = (char*)0;		/* just debug */		for(i=0;i<sizeof(argv)/sizeof(char*);i++)			DBG(" argv[%d] = %s\n",i,argv[i]);		/* once I copy localy all the data from shm mem -> free the shm */		shm_free( cmd->s1.s );		/* set an alarm -> sending the email shouldn't take more than 10 sec */		alarm(10);		/* run the external mailer */		DBG("DEBUG:cpl_c:send_mail: new forked process created -> "			"doing execv..\n");		execv("/usr/bin/mail",argv);		/* if we got here means execv exit with error :-( */		LOG(L_ERR,"ERROR:cpl_c:send_mail: execv failed! (%s)\n",			strerror(errno));child_exit:		_exit(127);	}	/* parent -> close both ends of pipe */	close(pfd[0]);	close(pfd[1]);	return;error:	shm_free( cmd->s1.s );	close(pfd[0]);	close(pfd[1]);	return;}void cpl_aux_process( int cmd_out, char *log_dir){	struct cpl_cmd cmd;	int len;	/* this process will ignore SIGCHLD signal */	if (signal( SIGCHLD, SIG_IGN)==SIG_ERR) {		LOG(L_ERR,"ERROR:cpl_c:cpl_aux_process: cannot set to IGNORE "			"SIGCHLD signal\n");	}	/* set the path for logging */	if (log_dir) {		strcpy( file, log_dir);		file_ptr = file + strlen(log_dir);		*(file_ptr++) = '/';	}	while(1) {		/* let's read a command from pipe */		len = read( cmd_out, &cmd, sizeof(struct cpl_cmd));		if (len!=sizeof(struct cpl_cmd)) {			if (len>=0) {				LOG(L_ERR,"ERROR:cpl_aux_processes: truncated message"					" read from pipe! -> discarded\n");			} else if (errno!=EAGAIN) {				LOG(L_ERR,"ERROR:cpl_aux_process: pipe reading failed: "					" : %s\n",strerror(errno));			}			sleep(1);			continue;		}		/* process the command*/		switch (cmd.code) {			case CPL_LOG_CMD:				write_log( &cmd );				break;			case CPL_MAIL_CMD:				send_mail( &cmd );				break;			default:				LOG(L_ERR,"ERROR:cpl_aux_process: unknown command (%d) "					"received! -> ignoring\n",cmd.code);		} /* end switch*/	}}

⌨️ 快捷键说明

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