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
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 "../../pt.h"
00047 #include "../../globals.h"
00048 #include "../../mem/mem.h"
00049 #include "../../mem/shm_mem.h"
00050 #include "../../cfg/cfg_struct.h"
00051 #include "../../lib/kmi/mi.h"
00052 #include "mi_fifo.h"
00053 #include "mi_parser.h"
00054 #include "mi_writer.h"
00055 #include "fifo_fnc.h"
00056
00057 static int mi_mod_init(void);
00058 static int mi_child_init(int rank);
00059 static void fifo_process(int rank);
00060 static int mi_destroy(void);
00061
00062
00063 static char *mi_fifo = 0;
00064 static char *mi_fifo_reply_dir = DEFAULT_MI_REPLY_DIR;
00065 static char *mi_reply_indent = DEFAULT_MI_REPLY_IDENT;
00066 static int mi_fifo_uid = -1;
00067 static char *mi_fifo_uid_s = 0;
00068 static int mi_fifo_gid = -1;
00069 static char *mi_fifo_gid_s = 0;
00070 static int mi_fifo_mode = S_IRUSR| S_IWUSR| S_IRGRP| S_IWGRP;
00071 static int read_buf_size = MAX_MI_FIFO_READ;
00072
00073 MODULE_VERSION
00074
00076 static param_export_t mi_params[] = {
00077 {"fifo_name", STR_PARAM, &mi_fifo},
00078 {"fifo_mode", INT_PARAM, &mi_fifo_mode},
00079 {"fifo_group", STR_PARAM, &mi_fifo_gid_s},
00080 {"fifo_group", INT_PARAM, &mi_fifo_gid},
00081 {"fifo_user", STR_PARAM, &mi_fifo_uid_s},
00082 {"fifo_user", INT_PARAM, &mi_fifo_uid},
00083 {"reply_dir", STR_PARAM, &mi_fifo_reply_dir},
00084 {"reply_indent", STR_PARAM, &mi_reply_indent},
00085 {0,0,0}
00086 };
00087
00088
00089 static proc_export_t mi_procs[] = {
00090 {"MI FIFO", 0, 0, fifo_process, 1 },
00091 {0,0,0,0,0}
00092 };
00093
00094
00095 struct module_exports exports = {
00096 "mi_fifo",
00097 DEFAULT_DLFLAGS,
00098 0,
00099 mi_params,
00100 0,
00101 0,
00102 0,
00103 mi_procs,
00104 mi_mod_init,
00105 0,
00106 (destroy_function) mi_destroy,
00107 mi_child_init
00108 };
00109
00110
00111
00113 static int mi_mod_init(void)
00114 {
00115 int n;
00116 struct stat filestat;
00117
00118
00119 if (mi_fifo==NULL || *mi_fifo == 0) {
00120 LM_ERR("No MI fifo configured\n");
00121 return -1;
00122 }
00123
00124 LM_DBG("testing mi_fifo existance ...\n");
00125 n=stat(mi_fifo, &filestat);
00126 if (n==0) {
00127
00128 if(config_check==0) {
00129 if (unlink(mi_fifo)<0){
00130 LM_ERR("Cannot delete old MI fifo (%s): %s\n",
00131 mi_fifo, strerror(errno));
00132 return -1;
00133 }
00134 }
00135 } else if (n<0 && errno!=ENOENT){
00136 LM_ERR("MI FIFO stat failed: %s\n", strerror(errno));
00137 return -1;
00138 }
00139
00140
00141 if(!mi_fifo_reply_dir || *mi_fifo_reply_dir == 0) {
00142 LM_ERR("mi_fifo_reply_dir parameter is empty\n");
00143 return -1;
00144 }
00145
00146
00147 n = stat(mi_fifo_reply_dir, &filestat);
00148 if(n < 0){
00149 LM_ERR("Directory stat for MI Fifo reply failed: %s\n", strerror(errno));
00150 return -1;
00151 }
00152
00153 if(S_ISDIR(filestat.st_mode) == 0){
00154 LM_ERR("mi_fifo_reply_dir parameter is not a directory\n");
00155 return -1;
00156 }
00157
00158
00159 if(!mi_fifo_mode){
00160 LM_WARN("cannot specify mi_fifo_mode = 0, forcing it to rw-------\n");
00161 mi_fifo_mode = S_IRUSR| S_IWUSR;
00162 }
00163
00164 if (mi_fifo_uid_s){
00165 if (user2uid(&mi_fifo_uid, &mi_fifo_gid, mi_fifo_uid_s)<0){
00166 LM_ERR("Bad user name %s\n", mi_fifo_uid_s);
00167 return -1;
00168 }
00169 }
00170
00171 if (mi_fifo_gid_s){
00172 if (group2gid(&mi_fifo_gid, mi_fifo_gid_s)<0){
00173 LM_ERR("Bad group name %s\n", mi_fifo_gid_s);
00174 return -1;
00175 }
00176 }
00177
00178
00179 register_procs(1);
00180
00181
00182 cfg_register_child(1);
00183
00184 return 0;
00185 }
00186
00187
00189 static int mi_child_init(int rank)
00190 {
00191 int pid;
00192
00193 if (rank==PROC_TIMER || rank>0 ) {
00194 if ( mi_writer_init(read_buf_size, mi_reply_indent)!=0 ) {
00195 LM_CRIT("failed to init the reply writer\n");
00196 return -1;
00197 }
00198 }
00199
00200 if (rank==PROC_MAIN) {
00201 pid=fork_process(PROC_NOCHLDINIT, "MI FIFO", 1);
00202 if (pid<0)
00203 return -1;
00204 if(pid==0){
00205
00206
00207
00208 if (cfg_child_init())
00209 return -1;
00210
00211 fifo_process(1);
00212 }
00213 }
00214
00215 return 0;
00216 }
00217
00218
00219 static void fifo_process(int rank)
00220 {
00221 FILE *fifo_stream;
00222
00223 LM_DBG("new process with pid = %d created\n",getpid());
00224
00225 fifo_stream = mi_init_fifo_server( mi_fifo, mi_fifo_mode,
00226 mi_fifo_uid, mi_fifo_gid, mi_fifo_reply_dir);
00227 if ( fifo_stream==NULL ) {
00228 LM_CRIT("The function mi_init_fifo_server returned with error!!!\n");
00229 exit(-1);
00230 }
00231
00232 if( init_mi_child(PROC_NOCHLDINIT, 1)!=0) {
00233 LM_CRIT("Failed to init the mi process\n");
00234 exit(-1);
00235 }
00236
00237 if ( mi_parser_init(read_buf_size)!=0 ) {
00238 LM_CRIT("Failed to init the command parser\n");
00239 exit(-1);
00240 }
00241
00242 if ( mi_writer_init(read_buf_size, mi_reply_indent)!=0 ) {
00243 LM_CRIT("Failed to init the reply writer\n");
00244 exit(-1);
00245 }
00246
00247 mi_fifo_server( fifo_stream );
00248
00249 LM_CRIT("the function mi_fifo_server returned with error!!!\n");
00250 exit(-1);
00251 }
00252
00253
00254 static int mi_destroy(void)
00255 {
00256 int n;
00257 struct stat filestat;
00258
00259
00260 n=stat(mi_fifo, &filestat);
00261 if (n==0){
00262
00263 if(config_check==0) {
00264 if (unlink(mi_fifo)<0){
00265 LM_ERR("cannot delete the fifo (%s): %s\n",
00266 mi_fifo, strerror(errno));
00267 goto error;
00268 }
00269 }
00270 } else if (n<0 && errno!=ENOENT) {
00271 LM_ERR("FIFO stat failed: %s\n", strerror(errno));
00272 goto error;
00273 }
00274
00275 return 0;
00276 error:
00277 return -1;
00278 }
00279