static int name2id(int type, char *name) { if (type & USER) return user2uid(name); if (type & GROUP) return group2gid(name); return -1; }
static int fix_group(modparam_t type, void * val) { char* s; if ((type & PARAM_STRING)==0){ LOG(L_CRIT, "BUG: ctl: fix_group: bad parameter type %d\n", type); goto error; } s=(char*)val; if (group2gid(&usock_gid, s)<0){ LOG(L_ERR, "ERROR: ctl: bad group name/gid number %s\n", s); goto error; } return 0; error: return -1; }
/** * Main routine, start of the program execution. * \param argc the number of arguments * \param argv pointer to the arguments array * \return don't return on sucess, -1 on error * \see main_loop */ int main(int argc, char** argv) { /* configure by default logging to syslog */ int cfg_log_stderr = 0; FILE* cfg_stream; int c,r; char *tmp; int tmp_len; int port; int proto; char *options; int ret; unsigned int seed; int rfd; /*init*/ ret=-1; my_argc=argc; my_argv=argv; /*init pkg mallocs (before parsing cfg or cmd line !)*/ if (init_pkg_mallocs()==-1) goto error00; init_route_lists(); /* process command line (get port no, cfg. file path etc) */ opterr=0; options="f:cCm:b:l:n:N:rRvdDETSVhw:t:u:g:P:G:W:o:"; while((c=getopt(argc,argv,options))!=-1){ switch(c){ case 'f': cfg_file=optarg; break; case 'C': config_check |= 2; case 'c': if (config_check==3) break; config_check |= 1; cfg_log_stderr=1; /* force stderr logging */ break; case 'm': shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024; if (tmp &&(*tmp)){ LM_ERR("bad shmem size number: -m %s\n", optarg); goto error00; }; break; case 'b': maxbuffer=strtol(optarg, &tmp, 10); if (tmp &&(*tmp)){ LM_ERR("bad max buffer size number: -b %s\n", optarg); goto error00; } break; case 'l': if (parse_phostport(optarg, strlen(optarg), &tmp, &tmp_len, &port, &proto)<0){ LM_ERR("bad -l address specifier: %s\n", optarg); goto error00; } tmp[tmp_len]=0; /* null terminate the host */ /* add a new addr. to our address list */ if (add_listen_iface(tmp, port, proto, 0, 0, 0)!=0){ LM_ERR("failed to add new listen address\n"); goto error00; } break; case 'n': children_no=strtol(optarg, &tmp, 10); if ((tmp==0) ||(*tmp)){ LM_ERR("bad process number: -n %s\n", optarg); goto error00; } break; case 'v': check_via=1; break; case 'r': received_dns|=DO_DNS; break; case 'R': received_dns|=DO_REV_DNS; case 'd': #ifdef CHANGEABLE_DEBUG_LEVEL (*debug)++; #else debug++; #endif break; case 'D': dont_fork=1; break; case 'E': cfg_log_stderr=1; break; case 'T': #ifdef USE_TCP tcp_disable=1; #else LM_WARN("tcp support not compiled in\n"); #endif break; case 'S': #ifdef USE_SCTP sctp_disable=1; #else LM_WARN("sctp support not compiled in\n"); #endif break; case 'N': #ifdef USE_TCP tcp_children_no=strtol(optarg, &tmp, 10); if ((tmp==0) ||(*tmp)){ LM_ERR("bad process number: -N %s\n", optarg); goto error00; } #else LM_WARN("tcp support not compiled in\n"); #endif break; case 'W': #ifdef USE_TCP tcp_poll_method=get_poll_type(optarg); if (tcp_poll_method==POLL_NONE){ LM_ERR("bad poll method name: -W %s\ntry " "one of %s.\n", optarg, poll_support); goto error00; } #else LM_WARN("tcp support not compiled in\n"); #endif break; case 'V': printf("version: %s\n", version); printf("flags: %s\n", flags ); print_ct_constants(); printf("%s\n",id); printf("%s compiled on %s with %s\n", __FILE__, compiled, COMPILER ); exit(0); break; case 'h': printf("version: %s\n", version); printf("%s",help_msg); exit(0); break; case 'w': working_dir=optarg; break; case 't': chroot_dir=optarg; break; case 'u': user=optarg; break; case 'g': group=optarg; break; case 'P': pid_file=optarg; break; case 'G': pgid_file=optarg; break; case 'o': if (add_arg_var(optarg) < 0) LM_ERR("cannot add option %s\n", optarg); break; case '?': if (isprint(optopt)) LM_ERR("Unknown option `-%c`.\n", optopt); else LM_ERR("Unknown option character `\\x%x`.\n", optopt); goto error00; case ':': LM_ERR("Option `-%c` requires an argument.\n", optopt); goto error00; default: abort(); } } log_stderr = cfg_log_stderr; /* fill missing arguments with the default values*/ if (cfg_file==0) cfg_file=CFG_FILE; /* load config file or die */ cfg_stream=fopen (cfg_file, "r"); if (cfg_stream==0){ LM_ERR("loading config file(%s): %s\n", cfg_file, strerror(errno)); goto error00; } /* seed the prng, try to use /dev/urandom if possible */ /* no debugging information is logged, because the standard log level prior the config file parsing is L_NOTICE */ seed=0; if ((rfd=open("/dev/urandom", O_RDONLY))!=-1){ try_again: if (read(rfd, (void*)&seed, sizeof(seed))==-1){ if (errno==EINTR) goto try_again; /* interrupted by signal */ LM_WARN("could not read from /dev/urandom (%d)\n", errno); } LM_DBG("initialize the pseudo random generator from " "/dev/urandom\n"); LM_DBG("read %u from /dev/urandom\n", seed); close(rfd); }else{ LM_WARN("could not open /dev/urandom (%d)\n", errno); LM_WARN("using a unsafe seed for the pseudo random number generator"); } seed+=getpid()+time(0); LM_DBG("seeding PRNG with %u\n", seed); srand(seed); LM_DBG("test random number %u\n", rand()); /*register builtin modules*/ register_builtin_modules(); #ifdef USE_TLS /* initialize default TLS domains, must be done before reading the config */ if (pre_init_tls()<0){ LM_CRIT("could not pre_init_tls, exiting...\n"); goto error00; } #endif /* USE_TLS */ if (preinit_black_lists()!=0) { LM_CRIT("failed to alloc black list's anchor\n"); goto error00; } /* parse the config file, prior to this only default values e.g. for debugging settings will be used */ yyin=cfg_stream; if ((yyparse()!=0)||(cfg_errors)){ LM_ERR("bad config file (%d errors)\n", cfg_errors); goto error00; } if (config_check>1 && check_rls()!=0) { LM_ERR("bad function call in config file\n"); return ret; } #ifdef EXTRA_DEBUG print_rl(); #endif /* init the resolver, before fixing the config */ resolv_init(); /* fix parameters */ if (port_no<=0) port_no=SIP_PORT; #ifdef USE_TLS if (tls_port_no<=0) tls_port_no=SIPS_PORT; #endif if (children_no<=0) children_no=CHILD_NO; #ifdef USE_TCP if (!tcp_disable){ if (tcp_children_no<=0) tcp_children_no=children_no; } #endif if (working_dir==0) working_dir="/"; /* get uid/gid */ if (user){ if (user2uid(&uid, &gid, user)<0){ LM_ERR("bad user name/uid number: -u %s\n", user); goto error00; } } if (group){ if (group2gid(&gid, group)<0){ LM_ERR("bad group name/gid number: -u %s\n", group); goto error00; } } if (fix_all_socket_lists()!=0){ LM_ERR("failed to initialize list addresses\n"); goto error00; } /* print all the listen addresses */ printf("Listening on \n"); print_all_socket_lists(); printf("Aliases: \n"); /*print_aliases();*/ print_aliases(); printf("\n"); if (dont_fork){ LM_WARN("no fork mode %s\n", (udp_listen)?( (udp_listen->next)?" and more than one listen address found" "(will use only the first one)":"" ):"and no udp listen address found" ); } if (config_check){ LM_NOTICE("config file ok, exiting...\n"); return 0; } time(&startup_time); /*init shm mallocs * this must be here * -to allow setting shm mem size from the command line * => if shm_mem should be settable from the cfg file move * everything after * -it must be also before init_timer and init_tcp * -it must be after we know uid (so that in the SYSV sems case, * the sems will have the correct euid) * --andrei */ if (init_shm_mallocs()==-1) goto error; /*init timer, before parsing the cfg!*/ if (init_timer()<0){ LM_CRIT("could not initialize timer, exiting...\n"); goto error; } #ifdef USE_TCP if (!tcp_disable){ /*init tcp*/ if (init_tcp()<0){ LM_CRIT("could not initialize tcp, exiting...\n"); goto error; } } #ifdef USE_TLS if (!tls_disable){ /* init tls*/ if (init_tls()<0){ LM_CRIT("could not initialize tls, exiting...\n"); goto error; } } #endif /* USE_TLS */ #endif /* USE_TCP */ /* init_daemon? */ if (!dont_fork){ if ( daemonize((log_name==0)?argv[0]:log_name, &own_pgid) <0 ) goto error; } /* install signal handlers */ if (install_sigs() != 0){ LM_ERR("could not install the signal handlers\n"); goto error; } #ifdef CHANGEABLE_DEBUG_LEVEL #ifdef SHM_MEM debug=shm_malloc(sizeof(int)); if (debug==0) { LM_ERR("ERROR: out of memory\n"); goto error; } *debug = debug_init; #else LM_WARN("no shm mem support compiled -> changeable debug " "level turned off\n"); #endif #endif if (disable_core_dump) set_core_dump(0, 0); else set_core_dump(1, shm_mem_size+PKG_MEM_POOL_SIZE+4*1024*1024); if (open_files_limit>0){ if(increase_open_fds(open_files_limit)<0){ LM_ERR("ERROR: error could not increase file limits\n"); goto error; } } /* print OpenSIPS version to log for history tracking */ LM_NOTICE("version: %s\n", version); /* print some data about the configuration */ #ifdef SHM_MEM LM_INFO("using %ld Mb shared memory\n", ((shm_mem_size/1024)/1024)); #endif LM_INFO("using %i Mb private memory per process\n", ((PKG_MEM_POOL_SIZE/1024)/1024)); /* init serial forking engine */ if (init_serialization()!=0) { LM_ERR("failed to initialize serialization\n"); goto error; } /* Init statistics */ if (init_stats_collector()<0) { LM_ERR("failed to initialize statistics\n"); goto error; } /* Init MI */ if (init_mi_core()<0) { LM_ERR("failed to initialize MI core\n"); goto error; } /* init black list engine */ if (init_black_lists()!=0) { LM_CRIT("failed to init black lists\n"); goto error; } /* init resolver's blacklist */ if (resolv_blacklist_init()!=0) { LM_CRIT("failed to create DNS blacklist\n"); goto error; } /* init modules */ if (init_modules() != 0) { LM_ERR("error while initializing modules\n"); goto error; } /* register route timers */ if(register_route_timers() < 0) { LM_ERR("Failed to register timer\n"); goto error; } /* check pv context list */ if(pv_contextlist_check() != 0) { LM_ERR("used pv context that was not defined\n"); goto error; } /* init multi processes support */ if (init_multi_proc_support()!=0) { LM_ERR("failed to init multi-proc support\n"); goto error; } #ifdef PKG_MALLOC /* init stats support for pkg mem */ if (init_pkg_stats(counted_processes)!=0) { LM_ERR("failed to init stats for pkg\n"); goto error; } #endif /* fix routing lists */ if ( (r=fix_rls())!=0){ LM_ERR("failed to fix configuration with err code %d\n", r); goto error; }; ret=main_loop(); error: /*kill everything*/ kill_all_children(SIGTERM); /*clean-up*/ cleanup(0); error00: return ret; }
/*! \brief Initialize fifo transport */ int jsonrpc_init_fifo_file(void) { int n; struct stat filestat; /* checking the jsonrpc_fifo module param */ if (jsonrpc_fifo==NULL || *jsonrpc_fifo == 0) { jsonrpc_fifo=NULL; LM_DBG("No fifo configured\n"); return 0; } LM_DBG("testing if fifo file exists ...\n"); n=stat(jsonrpc_fifo, &filestat); if (n==0) { /* FIFO exist, delete it (safer) if no config check */ if(config_check==0) { if (unlink(jsonrpc_fifo)<0){ LM_ERR("Cannot delete old fifo (%s): %s\n", jsonrpc_fifo, strerror(errno)); return -1; } } } else if (n<0 && errno!=ENOENT){ LM_ERR("MI FIFO stat failed: %s\n", strerror(errno)); return -1; } /* checking the fifo_reply_dir param */ if(!jsonrpc_fifo_reply_dir || *jsonrpc_fifo_reply_dir == 0) { LM_ERR("fifo_reply_dir parameter is empty\n"); return -1; } /* Check if the directory for the reply fifo exists */ n = stat(jsonrpc_fifo_reply_dir, &filestat); if(n < 0){ LM_ERR("Directory stat for MI Fifo reply failed: %s\n", strerror(errno)); return -1; } if(S_ISDIR(filestat.st_mode) == 0){ LM_ERR("fifo_reply_dir parameter is not a directory\n"); return -1; } /* check fifo_mode */ if(!jsonrpc_fifo_mode){ LM_WARN("cannot specify fifo_mode = 0, forcing it to rw-------\n"); jsonrpc_fifo_mode = S_IRUSR | S_IWUSR; } if (jsonrpc_fifo_uid_s){ if (user2uid(&jsonrpc_fifo_uid, &jsonrpc_fifo_gid, jsonrpc_fifo_uid_s)<0){ LM_ERR("Bad user name %s\n", jsonrpc_fifo_uid_s); return -1; } } if (jsonrpc_fifo_gid_s){ if (group2gid(&jsonrpc_fifo_gid, jsonrpc_fifo_gid_s)<0){ LM_ERR("Bad group name %s\n", jsonrpc_fifo_gid_s); return -1; } } /* add space for one extra process */ register_procs(1); /* add child to update local config framework structures */ cfg_register_child(1); return 0; }
int main(int argc, char** argv) { FILE* cfg_stream; int c,r; char *tmp; int tmp_len; int port; int proto; char *options; int ret; unsigned int seed; int rfd; /*init*/ ret=-1; my_argc=argc; my_argv=argv; /*init pkg mallocs (before parsing cfg or cmd line !)*/ if (init_pkg_mallocs()==-1) goto error; #ifdef DBG_MSG_QA fprintf(stderr, "WARNING: ser startup: " "DBG_MSG_QA enabled, ser may exit abruptly\n"); #endif /* process command line (get port no, cfg. file path etc) */ opterr=0; options= #ifdef STATS "s:" #endif "f:cm:b:l:n:N:rRvdDETVhw:t:u:g:P:G:i:x:"; while((c=getopt(argc,argv,options))!=-1){ switch(c){ case 'f': cfg_file=optarg; break; case 'c': config_check=1; log_stderr=1; /* force stderr logging */ break; case 's': #ifdef STATS stat_file=optarg; #endif break; case 'm': shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024; if (tmp &&(*tmp)){ fprintf(stderr, "bad shmem size number: -m %s\n", optarg); goto error; }; LOG(L_INFO, "ser: shared memory: %ld bytes\n", shm_mem_size ); break; case 'b': maxbuffer=strtol(optarg, &tmp, 10); if (tmp &&(*tmp)){ fprintf(stderr, "bad max buffer size number: -p %s\n", optarg); goto error; } break; case 'l': if (parse_phostport(optarg, &tmp, &tmp_len, &port, &proto)<0){ fprintf(stderr, "bad -l address specifier: %s\n", optarg); goto error; } tmp[tmp_len]=0; /* null terminate the host */ /* add a new addr. to our address list */ if (add_listen_iface(tmp, port, proto, 0)!=0){ fprintf(stderr, "failed to add new listen address\n"); goto error; } break; case 'n': children_no=strtol(optarg, &tmp, 10); if ((tmp==0) ||(*tmp)){ fprintf(stderr, "bad process number: -n %s\n", optarg); goto error; } break; case 'v': check_via=1; break; case 'r': received_dns|=DO_DNS; break; case 'R': received_dns|=DO_REV_DNS; case 'd': debug++; break; case 'D': dont_fork=1; break; case 'E': log_stderr=1; break; case 'T': #ifdef USE_TCP tcp_disable=1; #else fprintf(stderr,"WARNING: tcp support not compiled in\n"); #endif break; case 'N': #ifdef USE_TCP tcp_children_no=strtol(optarg, &tmp, 10); if ((tmp==0) ||(*tmp)){ fprintf(stderr, "bad process number: -N %s\n", optarg); goto error; } #else fprintf(stderr,"WARNING: tcp support not compiled in\n"); #endif break; case 'V': printf("version: %s\n", version); printf("flags: %s\n", flags ); print_ct_constants(); printf("%s\n",id); printf("%s compiled on %s with %s\n", __FILE__, compiled, COMPILER ); exit(0); break; case 'h': printf("version: %s\n", version); printf("%s",help_msg); exit(0); break; case 'w': working_dir=optarg; break; case 't': chroot_dir=optarg; break; case 'u': user=optarg; break; case 'g': group=optarg; break; case 'P': pid_file=optarg; break; case 'G': pgid_file=optarg; break; case 'i': fifo=optarg; break; case 'x': unixsock_name=optarg; break; case '?': if (isprint(optopt)) fprintf(stderr, "Unknown option `-%c´.\n", optopt); else fprintf(stderr, "Unknown option character `\\x%x´.\n", optopt); goto error; case ':': fprintf(stderr, "Option `-%c´ requires an argument.\n", optopt); goto error; default: abort(); } } /* fill missing arguments with the default values*/ if (cfg_file==0) cfg_file=CFG_FILE; /* load config file or die */ cfg_stream=fopen (cfg_file, "r"); if (cfg_stream==0){ fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file, strerror(errno)); goto error; } /* seed the prng */ /* try to use /dev/urandom if possible */ seed=0; if ((rfd=open("/dev/urandom", O_RDONLY))!=-1){ try_again: if (read(rfd, (void*)&seed, sizeof(seed))==-1){ if (errno==EINTR) goto try_again; /* interrupted by signal */ LOG(L_WARN, "WARNING: could not read from /dev/urandom (%d)\n", errno); } DBG("read %u from /dev/urandom\n", seed); close(rfd); }else{ LOG(L_WARN, "WARNING: could not open /dev/urandom (%d)\n", errno); } seed+=getpid()+time(0); DBG("seeding PRNG with %u\n", seed); srand(seed); DBG("test random number %u\n", rand()); /* register a diagnostic FIFO command - moved to fifo server - bogdan if (register_core_fifo()<0) { LOG(L_CRIT, "unable to register core FIFO commands\n"); goto error; }*/ /*register builtin modules*/ register_builtin_modules(); yyin=cfg_stream; if ((yyparse()!=0)||(cfg_errors)){ fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors); goto error; } print_rl(); /* fix parameters */ if (port_no<=0) port_no=SIP_PORT; #ifdef USE_TLS if (tls_port_no<=0) tls_port_no=SIPS_PORT; #endif if (children_no<=0) children_no=CHILD_NO; #ifdef USE_TCP if (!tcp_disable){ if (tcp_children_no<=0) tcp_children_no=children_no; } #endif if (working_dir==0) working_dir="/"; /* get uid/gid */ if (user){ if (user2uid(&uid, &gid, user)<0){ fprintf(stderr, "bad user name/uid number: -u %s\n", user); goto error; } } if (group){ if (group2gid(&gid, group)<0){ fprintf(stderr, "bad group name/gid number: -u %s\n", group); goto error; } } /* fix sock/fifo uid/gid */ if (sock_user){ if (user2uid(&sock_uid, 0, sock_user)<0){ fprintf(stderr, "bad socket user name/uid number %s\n", user); goto error; } } if (sock_group){ if (group2gid(&sock_gid, sock_group)<0){ fprintf(stderr, "bad group name/gid number: -u %s\n", group); goto error; } } if (fix_all_socket_lists()!=0){ fprintf(stderr, "failed to initialize list addresses\n"); goto error; } /* print all the listen addresses */ printf("Listening on \n"); print_all_socket_lists(); printf("Aliases: \n"); /*print_aliases();*/ print_aliases(); printf("\n"); if (dont_fork){ fprintf(stderr, "WARNING: no fork mode %s\n", (udp_listen)?( (udp_listen->next)?" and more than one listen address found" "(will use only the the first one)":"" ):"and no udp listen address found" ); } if (config_check){ fprintf(stderr, "config file ok, exiting...\n"); goto error; } /*init shm mallocs * this must be here * -to allow setting shm mem size from the command line * => if shm_mem should be settable from the cfg file move * everything after * -it must be also before init_timer and init_tcp * -it must be after we know uid (so that in the SYSV sems case, * the sems will have the correct euid) * --andrei */ if (init_shm_mallocs()==-1) goto error; /*init timer, before parsing the cfg!*/ if (init_timer()<0){ LOG(L_CRIT, "could not initialize timer, exiting...\n"); goto error; } #ifdef USE_TCP if (!tcp_disable){ /*init tcp*/ if (init_tcp()<0){ LOG(L_CRIT, "could not initialize tcp, exiting...\n"); goto error; } } #ifdef USE_TLS if (!tls_disable){ /* init tls*/ if (init_tls()<0){ LOG(L_CRIT, "could not initialize tls, exiting...\n"); goto error; } } #endif /* USE_TLS */ #endif /* USE_TCP */ /* init_daemon? */ if (!dont_fork){ if ( daemonize(argv[0]) <0 ) goto error; } if (install_sigs() != 0){ fprintf(stderr, "ERROR: could not install the signal handlers\n"); goto error; } /*alloc pids*/ #ifdef SHM_MEM pt=shm_malloc(sizeof(struct process_table)*process_count()); #else pt=pkg_malloc(sizeof(struct process_table)*process_count()); #endif if (pt==0){ fprintf(stderr, "ERROR: out of memory\n"); goto error; } memset(pt, 0, sizeof(struct process_table)*process_count()); if (disable_core_dump) set_core_dump(0, 0); else set_core_dump(1, shm_mem_size+PKG_MEM_POOL_SIZE+4*1024*1024); if (open_files_limit>0){ if(increase_open_fds(open_files_limit)<0){ fprintf(stderr, "ERROR: error could not increase file limits\n"); goto error; } } if (init_modules() != 0) { fprintf(stderr, "ERROR: error while initializing modules\n"); goto error; } /* fix routing lists */ if ( (r=fix_rls())!=0){ fprintf(stderr, "ERROR: error %d while trying to fix configuration\n", r); goto error; }; #ifdef STATS if (init_stats( dont_fork ? 1 : children_no )==-1) goto error; #endif ret=main_loop(); /*kill everything*/ kill_all_children(SIGTERM); /*clean-up*/ cleanup(0); return ret; error: /*kill everything*/ kill_all_children(SIGTERM); /*clean-up*/ cleanup(0); return -1; }
static int mi_mod_init(void) { int n; struct stat filestat; /* checking the mi_fifo module param */ if (mi_fifo==NULL || *mi_fifo == 0) { LM_ERR("no fifo configured\n"); return -1; } LM_DBG("testing fifo existance ...\n"); n=stat(mi_fifo, &filestat); if (n==0){ /* FIFO exist, delete it (safer) */ if (unlink(mi_fifo)<0){ LM_ERR("cannot delete old fifo (%s): %s\n", mi_fifo, strerror(errno)); return -1; } }else if (n<0 && errno!=ENOENT){ LM_ERR("FIFO stat failed: %s\n", strerror(errno)); return -1; } /* checking the mi_fifo_reply_dir param */ if(!mi_fifo_reply_dir || *mi_fifo_reply_dir == 0){ LM_ERR("mi_fifo_reply_dir parameter is empty\n"); return -1; } n = stat(mi_fifo_reply_dir, &filestat); if(n < 0){ LM_ERR("directory stat failed: %s\n", strerror(errno)); return -1; } if(S_ISDIR(filestat.st_mode) == 0){ LM_ERR("mi_fifo_reply_dir parameter is not a directory\n"); return -1; } /* check mi_fifo_mode */ if(!mi_fifo_mode){ LM_WARN("cannot specify mi_fifo_mode = 0, forcing it to rw-------\n"); mi_fifo_mode = S_IRUSR| S_IWUSR; } if (mi_fifo_uid_s){ if (user2uid(&mi_fifo_uid, &mi_fifo_gid, mi_fifo_uid_s)<0){ LM_ERR("bad user name %s\n", mi_fifo_uid_s); return -1; } } if (mi_fifo_gid_s){ if (group2gid(&mi_fifo_gid, mi_fifo_gid_s)<0){ LM_ERR("bad group name %s\n", mi_fifo_gid_s); return -1; } } return 0; }
/** * Main routine, start of the program execution. * \param argc the number of arguments * \param argv pointer to the arguments array * \return don't return on sucess, -1 on error * \see main_loop */ int main(int argc, char** argv) { /* configure by default logging to syslog */ int cfg_log_stderr = 0; FILE* cfg_stream; int c,r; char *tmp; int tmp_len; int port; int proto; char *options; int ret; unsigned int seed; int rfd; /*init*/ ret=-1; my_argc=argc; my_argv=argv; /* process pkg mem size from command line */ opterr=0; options="f:cCm:M:b:l:n:N:rRvdDFETSVhw:t:u:g:P:G:W:o:"; while((c=getopt(argc,argv,options))!=-1){ switch(c){ case 'M': pkg_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024; if (tmp &&(*tmp)){ LM_ERR("bad pkgmem size number: -m %s\n", optarg); goto error00; }; break; } } /*init pkg mallocs (before parsing cfg but after parsing cmd line !)*/ if (init_pkg_mallocs()==-1) goto error00; init_route_lists(); /* process command line (get port no, cfg. file path etc) */ /* first reset getopt */ optind = 1; while((c=getopt(argc,argv,options))!=-1){ switch(c){ case 'f': cfg_file=optarg; break; case 'C': config_check |= 2; case 'c': if (config_check==3) break; config_check |= 1; cfg_log_stderr=1; /* force stderr logging */ break; case 'm': shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024; if (tmp &&(*tmp)){ LM_ERR("bad shmem size number: -m %s\n", optarg); goto error00; }; break; case 'M': /* ignoring it, parsed previously */ break; case 'b': maxbuffer=strtol(optarg, &tmp, 10); if (tmp &&(*tmp)){ LM_ERR("bad max buffer size number: -b %s\n", optarg); goto error00; } break; case 'l': if (parse_phostport(optarg, strlen(optarg), &tmp, &tmp_len, &port, &proto)<0){ LM_ERR("bad -l address specifier: %s\n", optarg); goto error00; } tmp[tmp_len]=0; /* null terminate the host */ /* add a new addr. to our address list */ if (add_cmd_listener(tmp, port, proto)!=0){ LM_ERR("failed to add new listen address\n"); goto error00; } break; case 'n': children_no=strtol(optarg, &tmp, 10); if ((tmp==0) ||(*tmp)){ LM_ERR("bad process number: -n %s\n", optarg); goto error00; } break; case 'v': check_via=1; break; case 'r': received_dns|=DO_DNS; break; case 'R': received_dns|=DO_REV_DNS; break; case 'd': (*debug)++; break; case 'D': dont_fork=1; break; case 'F': no_daemon_mode=1; break; case 'E': cfg_log_stderr=1; break; case 'N': tcp_children_no=strtol(optarg, &tmp, 10); if ((tmp==0) ||(*tmp)){ LM_ERR("bad process number: -N %s\n", optarg); goto error00; } break; case 'W': io_poll_method=get_poll_type(optarg); if (io_poll_method==POLL_NONE){ LM_ERR("bad poll method name: -W %s\ntry " "one of %s.\n", optarg, poll_support); goto error00; } break; case 'V': printf("version: %s\n", version); printf("flags: %s\n", flags ); print_ct_constants(); printf("%s compiled on %s with %s\n", __FILE__, compiled, COMPILER ); exit(0); break; case 'h': printf("version: %s\n", version); printf("%s",help_msg); exit(0); break; case 'w': working_dir=optarg; break; case 't': chroot_dir=optarg; break; case 'u': user=optarg; break; case 'g': group=optarg; break; case 'P': pid_file=optarg; break; case 'G': pgid_file=optarg; break; case 'o': if (add_arg_var(optarg) < 0) LM_ERR("cannot add option %s\n", optarg); break; case '?': if (isprint(optopt)) LM_ERR("Unknown option `-%c`.\n", optopt); else LM_ERR("Unknown option character `\\x%x`.\n", optopt); goto error00; case ':': LM_ERR("Option `-%c` requires an argument.\n", optopt); goto error00; default: abort(); } } log_stderr = cfg_log_stderr; /* fill missing arguments with the default values*/ if (cfg_file==0) cfg_file=CFG_FILE; /* load config file or die */ cfg_stream=fopen (cfg_file, "r"); if (cfg_stream==0){ LM_ERR("loading config file(%s): %s\n", cfg_file, strerror(errno)); goto error00; } /* seed the prng, try to use /dev/urandom if possible */ /* no debugging information is logged, because the standard log level prior the config file parsing is L_NOTICE */ seed=0; if ((rfd=open("/dev/urandom", O_RDONLY))!=-1){ try_again: if (read(rfd, (void*)&seed, sizeof(seed))==-1){ if (errno==EINTR) goto try_again; /* interrupted by signal */ LM_WARN("could not read from /dev/urandom (%d)\n", errno); } LM_DBG("initialize the pseudo random generator from " "/dev/urandom\n"); LM_DBG("read %u from /dev/urandom\n", seed); close(rfd); }else{ LM_WARN("could not open /dev/urandom (%d)\n", errno); LM_WARN("using a unsafe seed for the pseudo random number generator"); } seed+=getpid()+time(0); LM_DBG("seeding PRNG with %u\n", seed); srand(seed); LM_DBG("test random number %u\n", rand()); /*register builtin modules*/ register_builtin_modules(); /* init avps */ if (init_global_avps() != 0) { LM_ERR("error while initializing avps\n"); goto error; } /* used for parser debugging */ #ifdef DEBUG_PARSER yydebug = 1; #endif /* * initializes transport interfaces - we initialize them here because we * can have listening interfaces declared in the command line */ if (trans_init() < 0) { LM_ERR("cannot initialize transport interface\n"); goto error; } /* get uid/gid */ if (user){ if (user2uid(&uid, &gid, user)<0){ LM_ERR("bad user name/uid number: -u %s\n", user); goto error00; } } if (group){ if (group2gid(&gid, group)<0){ LM_ERR("bad group name/gid number: -u %s\n", group); goto error00; } } /*init shm mallocs * this must be here * -to allow setting shm mem size from the command line * -it must be also before init_timer and init_tcp * -it must be after we know uid (so that in the SYSV sems case, * the sems will have the correct euid) * --andrei */ if (init_shm_mallocs()==-1) goto error; if (init_stats_collector() < 0) { LM_ERR("failed to initialize statistics\n"); goto error; } /* parse the config file, prior to this only default values e.g. for debugging settings will be used */ yyin=cfg_stream; if ((yyparse()!=0)||(cfg_errors)){ LM_ERR("bad config file (%d errors)\n", cfg_errors); goto error00; } if (config_check>1 && check_rls()!=0) { LM_ERR("bad function call in config file\n"); return ret; } if (solve_module_dependencies(modules) != 0) { LM_ERR("failed to solve module dependencies\n"); return -1; } #ifdef EXTRA_DEBUG print_rl(); #endif if (no_daemon_mode+dont_fork > 1) { LM_ERR("cannot use -D (fork=no) and -F together\n"); return ret; } /* init the resolver, before fixing the config */ resolv_init(); fix_poll_method( &io_poll_method ); /* fix temporary listeners added in the cmd line */ if (fix_cmd_listeners() < 0) { LM_ERR("cannot add temproray listeners\n"); return ret; } /* load transport protocols */ if (trans_load() < 0) { LM_ERR("cannot load transport protocols\n"); goto error; } /* fix parameters */ if (working_dir==0) working_dir="/"; if (fix_all_socket_lists()!=0){ LM_ERR("failed to initialize list addresses\n"); goto error00; } /* print all the listen addresses */ printf("Listening on \n"); print_all_socket_lists(); printf("Aliases: \n"); /*print_aliases();*/ print_aliases(); printf("\n"); if (dont_fork){ LM_WARN("no fork mode %s\n", (protos[PROTO_UDP].listeners)?( (protos[PROTO_UDP].listeners->next)?" and more than one listen" " address found(will use only the first one)":"" ):"and no udp listen address found" ); } if (config_check){ LM_NOTICE("config file ok, exiting...\n"); return 0; } time(&startup_time); /* Init statistics */ init_shm_statistics(); /*init UDP networking layer*/ if (udp_init()<0){ LM_CRIT("could not initialize tcp, exiting...\n"); goto error; } /*init TCP networking layer*/ if (tcp_init()<0){ LM_CRIT("could not initialize tcp, exiting...\n"); goto error; } /* init_daemon? */ if (!dont_fork){ if ( daemonize((log_name==0)?argv[0]:log_name, &own_pgid) <0 ) goto error; } /* install signal handlers */ if (install_sigs() != 0){ LM_ERR("could not install the signal handlers\n"); goto error; } if (disable_core_dump) set_core_dump(0, 0); else set_core_dump(1, shm_mem_size+pkg_mem_size+4*1024*1024); if (open_files_limit>0){ if(increase_open_fds(open_files_limit)<0){ LM_ERR("ERROR: error could not increase file limits\n"); goto error; } } /* print OpenSIPS version to log for history tracking */ LM_NOTICE("version: %s\n", version); /* print some data about the configuration */ LM_INFO("using %ld Mb shared memory\n", ((shm_mem_size/1024)/1024)); LM_INFO("using %ld Mb private memory per process\n", ((pkg_mem_size/1024)/1024)); /* init timer */ if (init_timer()<0){ LM_CRIT("could not initialize timer, exiting...\n"); goto error; } /* init serial forking engine */ if (init_serialization()!=0) { LM_ERR("failed to initialize serialization\n"); goto error; } /* Init MI */ if (init_mi_core()<0) { LM_ERR("failed to initialize MI core\n"); goto error; } /* Register core events */ if (evi_register_core() != 0) { LM_ERR("failed register core events\n"); goto error; } /* init black list engine */ if (init_black_lists()!=0) { LM_CRIT("failed to init blacklists\n"); goto error; } /* init resolver's blacklist */ if (resolv_blacklist_init()!=0) { LM_CRIT("failed to create DNS blacklist\n"); goto error; } /* init modules */ if (init_modules() != 0) { LM_ERR("error while initializing modules\n"); goto error; } /* register route timers */ if(register_route_timers() < 0) { LM_ERR("Failed to register timer\n"); goto error; } /* check pv context list */ if(pv_contextlist_check() != 0) { LM_ERR("used pv context that was not defined\n"); goto error; } /* init query list now in shm * so all processes that will be forked from now on * will have access to it * * if it fails, give it a try and carry on */ if (init_ql_support() != 0) { LM_ERR("failed to initialise buffering query list\n"); query_buffer_size = 0; *query_list = NULL; } /* init multi processes support */ if (init_multi_proc_support()!=0) { LM_ERR("failed to init multi-proc support\n"); goto error; } #ifdef PKG_MALLOC /* init stats support for pkg mem */ if (init_pkg_stats(counted_processes)!=0) { LM_ERR("failed to init stats for pkg\n"); goto error; } #endif /* init avps */ if (init_extra_avps() != 0) { LM_ERR("error while initializing avps\n"); goto error; } /* fix routing lists */ if ( (r=fix_rls())!=0){ LM_ERR("failed to fix configuration with err code %d\n", r); goto error; }; ret=main_loop(); error: /*kill everything*/ kill_all_children(SIGTERM); /*clean-up*/ cleanup(0); error00: return ret; }
int jsonrpc_dgram_mod_init(void) { unsigned int port_no; int n; struct stat filestat; struct hostent *host; char *p, *host_s; str port_str; int len; int sep; /* checking the mi_socket module param */ LM_DBG("testing socket existance...\n"); if( jsonrpc_dgram_socket==NULL || *jsonrpc_dgram_socket == 0) { LM_ERR("no DATAGRAM_ socket configured\n"); return -1; } LM_DBG("the socket's name/address is %s\n", jsonrpc_dgram_socket); memset( &jsonrpc_dgram_addr, 0, sizeof(jsonrpc_dgram_sockaddr_t) ); if(strlen(jsonrpc_dgram_socket)<6) { LM_ERR("lenght of socket address is too short: %s\n", jsonrpc_dgram_socket); return -1; } if(strncmp(jsonrpc_dgram_socket, "udp:", 4) == 0) { /*for an UDP socket*/ LM_DBG("udp socket provided\n"); /*separate proto and host */ p = jsonrpc_dgram_socket+4; if( (*(p)) == '\0') { LM_ERR("malformed ip address\n"); return -1; } host_s=p; LM_DBG("remaining address after separating the protocol is %s\n", p); if( (p = strrchr(p+1, ':')) == 0 ) { LM_ERR("no port specified\n"); return -1; } /*the address contains a port number*/ *p = '\0'; p++; port_str.s = p; port_str.len = strlen(p); LM_DBG("the port string is %s\n", p); if(str2int(&port_str, &port_no) != 0 ) { LM_ERR("there is not a valid number port\n"); return -1; } *p = '\0'; if (port_no<1024 || port_no>65535) { LM_ERR("invalid port number; must be in [1024,65535]\n"); return -1; } if(! (host = resolvehost(host_s)) ) { LM_ERR("failed to resolve %s\n", host_s); return -1; } LM_DBG("the ip is %s\n",host_s); if(hostent2su( &(jsonrpc_dgram_addr.udp_addr), host, 0, port_no ) !=0) { LM_ERR("failed to resolve %s\n", jsonrpc_dgram_socket); return -1; } jsonrpc_dgram_socket_domain = host->h_addrtype; goto done; } /* in case of a Unix socket*/ LM_DBG("UNIX socket provided\n"); if(*jsonrpc_dgram_socket != '/') { if(runtime_dir!=NULL && *runtime_dir!=0) { len = strlen(runtime_dir); sep = 0; if(runtime_dir[len-1]!='/') { sep = 1; } len += sep + strlen(jsonrpc_dgram_socket); p = pkg_malloc(len + 1); if(p==NULL) { LM_ERR("no more pkg\n"); return -1; } strcpy(p, runtime_dir); if(sep) strcat(p, "/"); strcat(p, jsonrpc_dgram_socket); jsonrpc_dgram_socket = p; LM_DBG("unix socket path is [%s]\n", jsonrpc_dgram_socket); } } n=stat(jsonrpc_dgram_socket, &filestat); if( n==0) { LM_INFO("the socket %s already exists, trying to delete it...\n", jsonrpc_dgram_socket); if(config_check==0) { if (unlink(jsonrpc_dgram_socket)<0) { LM_ERR("cannot delete old socket: %s\n", strerror(errno)); return -1; } } } else if (n<0 && errno!=ENOENT) { LM_ERR("socket stat failed:%s\n", strerror(errno)); return -1; } /* check mi_unix_socket_mode */ if(!jsonrpc_dgram_unix_socket_mode) { LM_WARN("cannot specify jsonrpc_dgram_unix_socket_mode = 0," " forcing it to rw-------\n"); jsonrpc_dgram_unix_socket_mode = S_IRUSR| S_IWUSR; } if (jsonrpc_dgram_unix_socket_uid_s) { if (user2uid(&jsonrpc_dgram_unix_socket_uid, &jsonrpc_dgram_unix_socket_gid, jsonrpc_dgram_unix_socket_uid_s)<0) { LM_ERR("bad user name %s\n", jsonrpc_dgram_unix_socket_uid_s); return -1; } } if (jsonrpc_dgram_unix_socket_gid_s) { if (group2gid(&jsonrpc_dgram_unix_socket_gid, jsonrpc_dgram_unix_socket_gid_s)<0) { LM_ERR("bad group name %s\n", jsonrpc_dgram_unix_socket_gid_s); return -1; } } /*create the unix socket address*/ jsonrpc_dgram_addr.unix_addr.sun_family = AF_LOCAL; if(strlen(jsonrpc_dgram_socket) >= sizeof(jsonrpc_dgram_addr.unix_addr.sun_path)-1) { LM_ERR("socket path is too long\n"); return -1; } memcpy(jsonrpc_dgram_addr.unix_addr.sun_path, jsonrpc_dgram_socket, strlen(jsonrpc_dgram_socket)); done: /* add space for extra processes */ register_procs(jsonrpc_dgram_workers); /* add child to update local config framework structures */ cfg_register_child(jsonrpc_dgram_workers); return 0; }
static int mi_mod_init(void) { unsigned int port_no; int n; struct stat filestat; struct hostent * host; char *p, *host_s; str port_str; /* checking the mi_socket module param */ LM_DBG("testing socket existance...\n"); if( mi_socket==NULL || *mi_socket == 0) { LM_ERR("no DATAGRAM_ socket configured\n"); return -1; } LM_DBG("the socket's name/address is %s\n", mi_socket); memset( &mi_dtgram_addr, 0, sizeof(mi_dtgram_addr) ); if(strncmp(mi_socket, "udp:",4) == 0) { /*for an UDP socket*/ LM_DBG("we have an udp socket\n"); /*separate proto and host */ p = mi_socket+4; if( (*(p)) == '\0') { LM_ERR("malformed ip address\n"); return -1; } host_s=p; LM_DBG("the remaining address after separating the protocol is %s\n",p); if( (p = strrchr(p+1, ':')) == 0 ) { LM_ERR("no port specified\n"); return -1; } /*the address contains a port number*/ *p = '\0'; p++; port_str.s = p; port_str.len = strlen(p); LM_DBG("the port string is %s\n", p); if(str2int(&port_str, &port_no) != 0 ) { LM_ERR("there is not a valid number port\n"); return -1; } *p = '\0'; if (port_no<1024 || port_no>MAX_NB_PORT) { LM_ERR("invalid port number; must be in [1024,%d]\n",MAX_NB_PORT); return -1; } if(! (host = resolvehost(host_s)) ) { LM_ERR("failed to resolve %s\n", host_s); return -1; } LM_DBG("the ip is %s\n",host_s); if(hostent2su( &(mi_dtgram_addr.udp_addr), host, 0, port_no ) !=0){ LM_ERR("failed to resolve %s\n", mi_socket); return -1; } mi_socket_domain = host->h_addrtype; goto done; } /* in case of a Unix socket*/ LM_DBG("we have an UNIX socket\n"); n=stat(mi_socket, &filestat); if( n==0) { LM_INFO("the socket %s already exists, trying to delete it...\n", mi_socket); if(config_check==0) { if (unlink(mi_socket)<0) { LM_ERR("cannot delete old socket: %s\n", strerror(errno)); return -1; } } } else if (n<0 && errno!=ENOENT) { LM_ERR("socket stat failed:%s\n", strerror(errno)); return -1; } /* check mi_unix_socket_mode */ if(!mi_unix_socket_mode) { LM_WARN("cannot specify mi_unix_socket_mode = 0, forcing it to rw-------\n"); mi_unix_socket_mode = S_IRUSR| S_IWUSR; } if (mi_unix_socket_uid_s) { if (user2uid(&mi_unix_socket_uid, &mi_unix_socket_gid, mi_unix_socket_uid_s)<0) { LM_ERR("bad user name %s\n", mi_unix_socket_uid_s); return -1; } } if (mi_unix_socket_gid_s) { if (group2gid(&mi_unix_socket_gid, mi_unix_socket_gid_s)<0) { LM_ERR("bad group name %s\n", mi_unix_socket_gid_s); return -1; } } /*create the unix socket address*/ mi_dtgram_addr.unix_addr.sun_family = AF_LOCAL; memcpy( mi_dtgram_addr.unix_addr.sun_path, mi_socket, strlen(mi_socket)); done: /* add space for extra processes */ register_procs(mi_procs[0].no); /* add child to update local config framework structures */ cfg_register_child(mi_procs[0].no); return 0; }