cpl_nonsig.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <unistd.h>
00028 #include <errno.h>
00029 #include <string.h>
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #include <fcntl.h>
00033 #include <time.h>
00034 #include <sys/uio.h>
00035 #include <signal.h>
00036
00037 #include "../../mem/shm_mem.h"
00038 #include "../../mem/mem.h"
00039 #include "../../dprint.h"
00040 #include "cpl_nonsig.h"
00041 #include "CPL_tree.h"
00042
00043
00044 #define MAX_LOG_FILE_NAME 32
00045
00046 #define FILE_NAME_SUFIX ".log"
00047 #define FILE_NAME_SUFIX_LEN (sizeof(FILE_NAME_SUFIX)-1)
00048
00049 #define LOG_SEPARATOR ": "
00050 #define LOG_SEPARATOR_LEN (sizeof(LOG_SEPARATOR)-1)
00051
00052 #define DEFAULT_LOG_NAME "default_log"
00053 #define DEFAULT_LOG_NAME_LEN (sizeof(DEFAULT_LOG_NAME)-1)
00054
00055 #define LOG_TERMINATOR "\n"
00056 #define LOG_TERMINATOR_LEN (sizeof(LOG_TERMINATOR)-1)
00057
00058
00059 static char file[MAX_LOG_DIR_SIZE+1+MAX_LOG_FILE_NAME+FILE_NAME_SUFIX_LEN+1];
00060 static char *file_ptr;
00061
00062
00063 static inline void write_log( struct cpl_cmd *cmd)
00064 {
00065 struct iovec wr_vec[5];
00066 time_t now;
00067 char *time_ptr;
00068 int fd;
00069 int ret;
00070
00071
00072 if (cmd->s1.len>MAX_LOG_FILE_NAME)
00073 cmd->s1.len = MAX_LOG_FILE_NAME;
00074 memcpy(file_ptr, cmd->s1.s, cmd->s1.len );
00075 memcpy(file_ptr+cmd->s1.len,FILE_NAME_SUFIX,FILE_NAME_SUFIX_LEN);
00076 file_ptr[cmd->s1.len+FILE_NAME_SUFIX_LEN] = 0;
00077
00078
00079 time( &now );
00080 time_ptr = ctime( &now );
00081 wr_vec[0].iov_base = time_ptr;
00082 wr_vec[0].iov_len = strlen( time_ptr );
00083
00084 time_ptr[ wr_vec[0].iov_len-1 ] = ' ';
00085
00086
00087 if (cmd->s2.s==0 || cmd->s2.len==0) {
00088 wr_vec[1].iov_base = DEFAULT_LOG_NAME;
00089 wr_vec[1].iov_len = DEFAULT_LOG_NAME_LEN;
00090 } else {
00091 wr_vec[1].iov_base = cmd->s2.s;
00092 wr_vec[1].iov_len = cmd->s2.len;
00093 }
00094
00095
00096 wr_vec[2].iov_base = LOG_SEPARATOR;
00097 wr_vec[2].iov_len = LOG_SEPARATOR_LEN;
00098
00099
00100 wr_vec[3].iov_base = cmd->s3.s;
00101 wr_vec[3].iov_len = cmd->s3.len;
00102
00103
00104 wr_vec[4].iov_base = LOG_TERMINATOR;
00105 wr_vec[4].iov_len = LOG_TERMINATOR_LEN;
00106
00107
00108 fd = open( file, O_CREAT|O_APPEND|O_WRONLY, 0664);
00109 if (fd==-1) {
00110 LM_ERR("cannot open file [%s] : %s\n",
00111 file, strerror(errno) );
00112 return;
00113 }
00114
00115 LM_DBG("logging into [%s]... \n",file);
00116
00117 while ( (ret=writev( fd, wr_vec, 5))==-1 ) {
00118 if (errno==EINTR)
00119 continue;
00120 LM_ERR("writing to log file [%s] : %s\n",
00121 file, strerror(errno) );
00122 }
00123 close (fd);
00124
00125 shm_free( cmd->s1.s );
00126 }
00127
00128
00129
00130 static inline void send_mail( struct cpl_cmd *cmd)
00131 {
00132 char *argv[5];
00133 int pfd[2];
00134 pid_t pid;
00135 int i;
00136
00137 if (pipe(pfd) < 0) {
00138 LM_ERR("pipe failed: %s\n",strerror(errno));
00139 return;
00140 }
00141
00142
00143
00144 if (cmd->s3.len && cmd->s3.s) {
00145 if ( (i=write( pfd[1], cmd->s3.s, cmd->s3.len ))!=cmd->s3.len ) {
00146 LM_ERR("write returned error %s\n",
00147 strerror(errno));
00148 goto error;
00149 }
00150 }
00151
00152 if ( (pid = fork()) < 0) {
00153 LM_ERR("fork failed: %s\n",strerror(errno));
00154 goto error;
00155 } else if (pid==0) {
00156
00157
00158 for (i=3; i < 32; i++)
00159 if (i!=pfd[0])
00160 close(i);
00161 if (pfd[0] != STDIN_FILENO) {
00162 dup2(pfd[0], STDIN_FILENO);
00163 close(pfd[0]);
00164 }
00165
00166
00167 argv[0] = "mail";
00168 argv[1] = "-s";
00169 if (cmd->s2.s && cmd->s2.len) {
00170
00171 if ( (argv[2]=(char*)pkg_malloc(1+cmd->s2.len+1+1))==0) {
00172 LM_ERR("cannot get pkg memory\n");
00173 goto child_exit;
00174 }
00175 argv[2][0] = '\"';
00176 memcpy(argv[2]+1,cmd->s2.s,cmd->s2.len);
00177 argv[2][cmd->s2.len+1] = '\"';
00178 argv[2][cmd->s2.len+2] = 0;
00179 } else {
00180 argv[2] = "\"[CPL notification]\"";
00181 }
00182
00183 if ( (argv[3]=(char*)pkg_malloc(cmd->s1.len+1))==0) {
00184 LM_ERR("cannot get pkg memory\n");
00185 goto child_exit;
00186 }
00187 memcpy(argv[3],cmd->s1.s,cmd->s1.len);
00188 argv[3][cmd->s1.len] = 0;
00189
00190 argv[4] = (char*)0;
00191
00192 for(i=0;i<sizeof(argv)/sizeof(char*);i++)
00193 LM_DBG("argv[%d] = %s\n",i,argv[i]);
00194
00195 shm_free( cmd->s1.s );
00196
00197
00198 alarm(10);
00199
00200 LM_DBG("new forked process created -> "
00201 "doing execv..\n");
00202 execv("/usr/bin/mail",argv);
00203
00204 LM_ERR("execv failed! (%s)\n",strerror(errno));
00205 child_exit:
00206 _exit(127);
00207 }
00208
00209
00210 close(pfd[0]);
00211 close(pfd[1]);
00212 return;
00213 error:
00214 shm_free( cmd->s1.s );
00215 close(pfd[0]);
00216 close(pfd[1]);
00217 return;
00218 }
00219
00220
00221
00222
00223 void cpl_aux_process( int cmd_out, char *log_dir)
00224 {
00225 struct cpl_cmd cmd;
00226 int len;
00227
00228
00229 if (signal( SIGCHLD, SIG_IGN)==SIG_ERR) {
00230 LM_ERR("cannot set to IGNORE SIGCHLD signal\n");
00231 }
00232
00233
00234 if (log_dir) {
00235 strcpy( file, log_dir);
00236 file_ptr = file + strlen(log_dir);
00237 *(file_ptr++) = '/';
00238 }
00239
00240 while(1) {
00241
00242 len = read( cmd_out, &cmd, sizeof(struct cpl_cmd));
00243 if (len!=sizeof(struct cpl_cmd)) {
00244 if (len>=0) {
00245 LM_ERR("truncated message"
00246 " read from pipe! -> discarded\n");
00247 } else if (errno!=EAGAIN) {
00248 LM_ERR("pipe reading failed: "
00249 " : %s\n",strerror(errno));
00250 }
00251 sleep(1);
00252 continue;
00253 }
00254
00255
00256 switch (cmd.code) {
00257 case CPL_LOG_CMD:
00258 write_log( &cmd );
00259 break;
00260 case CPL_MAIL_CMD:
00261 send_mail( &cmd );
00262 break;
00263 default:
00264 LM_ERR("unknown command (%d) "
00265 "received! -> ignoring\n",cmd.code);
00266 }
00267
00268 }
00269 }
00270