mi_fifo.c

Go to the documentation of this file.
00001 /*
00002  * $Id: mi_fifo.c 5514 2009-01-26 12:33:24Z henningw $
00003  *
00004  * Copyright (C) 2006 Voice Sistem SRL
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00021  *
00022  *
00023  * History:
00024  * ---------
00025  *  2006-09-25  first version (bogdan)
00026  */
00027 
00028 /*!
00029  * \file
00030  * \brief MI_FIFO :: Fifo API for the Kamailio manager interface
00031  * \ingroup mi
00032  */
00033 
00034 
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <sys/stat.h>
00038 #include <sys/types.h>
00039 #include <unistd.h>
00040 #include <errno.h>
00041 #include <signal.h>
00042 
00043 #include "../../sr_module.h"
00044 #include "../../dprint.h"
00045 #include "../../ut.h"
00046 #include "../../mem/mem.h"
00047 #include "../../mem/shm_mem.h"
00048 #include "../../mi/mi.h"
00049 #include "mi_fifo.h"
00050 #include "mi_parser.h"
00051 #include "mi_writer.h"
00052 #include "fifo_fnc.h"
00053 
00054 static int mi_mod_init(void);
00055 static int mi_child_init(int rank);
00056 static void fifo_process(int rank);
00057 static int mi_destroy(void);
00058 
00059 /* FIFO server vars */
00060 static char *mi_fifo = 0;           /*!< FIFO name */
00061 static char *mi_fifo_reply_dir = DEFAULT_MI_REPLY_DIR;   /*!< dir where reply fifos are allowed */
00062 static char *mi_reply_indent = DEFAULT_MI_REPLY_IDENT;
00063 static int  mi_fifo_uid = -1;          /*!< Fifo default UID */
00064 static char *mi_fifo_uid_s = 0;           /*!< Fifo default User ID name */
00065 static int  mi_fifo_gid = -1;          /*!< Fifo default Group ID */
00066 static char *mi_fifo_gid_s = 0;           /*!< Fifo default Group ID name */
00067 static int  mi_fifo_mode = S_IRUSR| S_IWUSR| S_IRGRP| S_IWGRP; /* Default file mode rw-rw---- */
00068 static int  read_buf_size = MAX_MI_FIFO_READ;
00069 
00070 MODULE_VERSION
00071 
00072 /*! \brief Configuration parameters in .cfg file */
00073 static param_export_t mi_params[] = {        
00074    {"fifo_name",        STR_PARAM, &mi_fifo},
00075    {"fifo_mode",        INT_PARAM, &mi_fifo_mode},
00076    {"fifo_group",       STR_PARAM, &mi_fifo_gid_s},
00077    {"fifo_group",       INT_PARAM, &mi_fifo_gid},
00078    {"fifo_user",        STR_PARAM, &mi_fifo_uid_s},
00079    {"fifo_user",        INT_PARAM, &mi_fifo_uid},
00080    {"reply_dir",        STR_PARAM, &mi_fifo_reply_dir},
00081    {"reply_indent",     STR_PARAM, &mi_reply_indent},
00082    {0,0,0}
00083 };
00084 
00085 
00086 static proc_export_t mi_procs[] = {
00087    {"MI FIFO",  0,  0,  fifo_process,  1 },
00088    {0,0,0,0,0}
00089 };
00090 
00091 
00092 struct module_exports exports = {
00093    "mi_fifo",                     /*!< module name */
00094    DEFAULT_DLFLAGS,               /*!< dlopen flags */
00095    0,                             /*!< exported functions */
00096    mi_params,                     /*!< exported parameters */
00097    0,                             /*!< exported statistics */
00098    0,                             /*!< exported MI functions */
00099    0,                             /*!< exported pseudo-variables */
00100    mi_procs,                      /*!< extra processes */
00101    mi_mod_init,                   /*!< module initialization function */
00102    0,                             /*!< response handling function */
00103    (destroy_function) mi_destroy, /*!< destroy function */
00104    mi_child_init                  /*!< per-child init function */
00105 };
00106 
00107 
00108 
00109 /*! \brief Initialize mi_fifo module */
00110 static int mi_mod_init(void)
00111 {
00112    int n;
00113    struct stat filestat;
00114 
00115    /* checking the mi_fifo module param */
00116    if (mi_fifo==NULL || *mi_fifo == 0) {
00117       LM_ERR("No MI fifo configured\n");
00118       return -1;
00119    }
00120 
00121    LM_DBG("testing mi_fifo existance ...\n");
00122    n=stat(mi_fifo, &filestat);
00123    if (n==0) {
00124       /* FIFO exist, delete it (safer) */
00125       if (unlink(mi_fifo)<0){
00126          LM_ERR("Cannot delete old MI fifo (%s): %s\n",
00127             mi_fifo, strerror(errno));
00128          return -1;
00129       }
00130    } else if (n<0 && errno!=ENOENT){
00131       LM_ERR("MI FIFO stat failed: %s\n", strerror(errno));
00132       return -1;
00133    }
00134 
00135    /* checking the mi_fifo_reply_dir param */
00136    if(!mi_fifo_reply_dir || *mi_fifo_reply_dir == 0) {
00137       LM_ERR("mi_fifo_reply_dir parameter is empty\n");
00138       return -1;
00139    }
00140 
00141    /* Check if the directory for the reply fifo exists */
00142    n = stat(mi_fifo_reply_dir, &filestat);
00143    if(n < 0){
00144       LM_ERR("Directory stat for MI Fifo reply failed: %s\n", strerror(errno));
00145       return -1;
00146    }
00147 
00148    if(S_ISDIR(filestat.st_mode) == 0){
00149       LM_ERR("mi_fifo_reply_dir parameter is not a directory\n");
00150       return -1;
00151    }
00152 
00153    /* check mi_fifo_mode */
00154    if(!mi_fifo_mode){
00155       LM_WARN("cannot specify mi_fifo_mode = 0, forcing it to rw-------\n");
00156       mi_fifo_mode = S_IRUSR| S_IWUSR;
00157    }
00158 
00159    if (mi_fifo_uid_s){
00160       if (user2uid(&mi_fifo_uid, &mi_fifo_gid, mi_fifo_uid_s)<0){
00161          LM_ERR("Bad user name %s\n", mi_fifo_uid_s);
00162          return -1;
00163       }
00164    }
00165 
00166    if (mi_fifo_gid_s){
00167       if (group2gid(&mi_fifo_gid, mi_fifo_gid_s)<0){
00168          LM_ERR("Bad group name %s\n", mi_fifo_gid_s);
00169          return -1;
00170       }
00171    }
00172 
00173    return 0;
00174 }
00175 
00176 
00177 /*! \brief Initialize module for child processes */
00178 static int mi_child_init(int rank)
00179 {
00180    if (rank==PROC_TIMER || rank>0 ) {
00181       if ( mi_writer_init(read_buf_size, mi_reply_indent)!=0 ) {
00182          LM_CRIT("failed to init the reply writer\n");
00183          return -1;
00184       }
00185    }
00186 
00187    return 0;
00188 }
00189 
00190 
00191 static void fifo_process(int rank)
00192 {
00193    FILE *fifo_stream;
00194 
00195    LM_DBG("new process with pid = %d created\n",getpid());
00196 
00197    fifo_stream = mi_init_fifo_server( mi_fifo, mi_fifo_mode,
00198       mi_fifo_uid, mi_fifo_gid, mi_fifo_reply_dir);
00199    if ( fifo_stream==NULL ) {
00200       LM_CRIT("The function mi_init_fifo_server returned with error!!!\n");
00201       exit(-1);
00202    }
00203 
00204    if( init_mi_child()!=0) {
00205       LM_CRIT("Failed to init the mi process\n");
00206       exit(-1);
00207    }
00208 
00209    if ( mi_parser_init(read_buf_size)!=0 ) {
00210       LM_CRIT("Failed to init the command parser\n");
00211       exit(-1);
00212    }
00213 
00214    if ( mi_writer_init(read_buf_size, mi_reply_indent)!=0 ) {
00215       LM_CRIT("Failed to init the reply writer\n");
00216       exit(-1);
00217    }
00218 
00219    mi_fifo_server( fifo_stream );
00220 
00221    LM_CRIT("the function mi_fifo_server returned with error!!!\n");
00222    exit(-1);
00223 }
00224 
00225 
00226 static int mi_destroy(void)
00227 {
00228    int n;
00229    struct stat filestat;
00230 
00231    /* destroying the fifo file */
00232    n=stat(mi_fifo, &filestat);
00233    if (n==0){
00234       /* FIFO exist, delete it (safer) */
00235       if (unlink(mi_fifo)<0){
00236          LM_ERR("cannot delete the fifo (%s): %s\n",
00237             mi_fifo, strerror(errno));
00238          goto error;
00239       }
00240    } else if (n<0 && errno!=ENOENT) {
00241       LM_ERR("FIFO stat failed: %s\n", strerror(errno));
00242       goto error;
00243    }
00244 
00245    return 0;
00246 error:
00247    return -1;
00248 }
00249 

Generated on Wed May 23 20:00:27 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6