コード例 #1
0
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
    static int chd_rank;
    int  i,rc;
    pid_t pid;
    struct socket_info* si;
    int* startup_done = NULL;
    stat_var *load_p = NULL;

    chd_rank=0;

    if (dont_fork) {

        if (create_status_pipe() < 0) {
            LM_ERR("failed to create status pipe");
            goto error;
        }

        if (udp_listen==0) {
            LM_ERR("no fork mode requires at least one"
                   " udp listen address, exiting...\n");
            goto error;
        }
        /* only one address, we ignore all the others */
        if (udp_init(udp_listen)==-1) goto error;
        bind_address=udp_listen;
        sendipv4=bind_address;
        sendipv6=bind_address; /*FIXME*/
        if (udp_listen->next) {
            LM_WARN("using only the first listen address (no fork)\n");
        }

        /* try to drop privileges */
        if (do_suid(uid, gid)==-1)
            goto error;

        if (start_module_procs()!=0) {
            LM_ERR("failed to fork module processes\n");
            goto error;
        }

        /* we need another process to act as the timer*/
        if (start_timer_processes()!=0) {
            LM_CRIT("cannot start timer process(es)\n");
            goto error;
        }

        /* main process, receive loop */
        set_proc_attrs("stand-alone SIP receiver %.*s",
                       bind_address->sock_str.len, bind_address->sock_str.s );

        /* We will call child_init even if we
         * do not fork - and it will be called with rank 1 because
         * in fact we behave like a child, not like main process */
        if (init_child(1) < 0) {
            LM_ERR("init_child failed in don't fork\n");
            goto error;
        }

        if (startup_rlist.a)
            run_startup_route();

        is_main=1;

        if (register_udp_load_stat(&udp_listen->sock_str,
                                   &pt[process_no].load)!=0) {
            LM_ERR("failed to init udp load statistics\n");
            goto error;
        }

        clean_write_pipeend();
        LM_DBG("waiting for status code from children\n");
        rc = wait_for_all_children();
        if (rc < 0) {
            LM_ERR("failed to succesfully init children\n");
            return rc;
        }

        return udp_rcv_loop();
    } else {  /* don't fork */

        for(si=udp_listen; si; si=si->next) {
            /* create the listening socket (for each address)*/
            /* udp */
            if (udp_init(si)==-1) goto error;
            /* get first ipv4/ipv6 socket*/
            if ((si->address.af==AF_INET)&&
                    ((sendipv4==0)||(sendipv4->flags&SI_IS_LO)))
                sendipv4=si;
#ifdef USE_IPV6
            if((sendipv6==0)&&(si->address.af==AF_INET6))
                sendipv6=si;
#endif
        }
#ifdef USE_TCP
        if (!tcp_disable) {
            for(si=tcp_listen; si; si=si->next) {
                /* same thing for tcp */
                if (tcp_init(si)==-1)  goto error;
                /* get first ipv4/ipv6 socket*/
                if ((si->address.af==AF_INET)&
                        ((sendipv4_tcp==0)||(sendipv4_tcp->flags&SI_IS_LO)))
                    sendipv4_tcp=si;
#ifdef USE_IPV6
                if((sendipv6_tcp==0)&&(si->address.af==AF_INET6))
                    sendipv6_tcp=si;
#endif
            }
        }
#ifdef USE_TLS
        if (!tls_disable) {
            for(si=tls_listen; si; si=si->next) {
                /* same as for tcp*/
                if (tls_init(si)==-1)  goto error;
                /* get first ipv4/ipv6 socket*/
                if ((si->address.af==AF_INET)&&
                        ((sendipv4_tls==0)||(sendipv4_tls->flags&SI_IS_LO)))
                    sendipv4_tls=si;
#ifdef USE_IPV6
                if((sendipv6_tls==0)&&(si->address.af==AF_INET6))
                    sendipv6_tls=si;
#endif
            }
        }
#endif /* USE_TLS */
#endif /* USE_TCP */
#ifdef USE_SCTP
        if (!sctp_disable) {
            for(si=sctp_listen; si; si=si->next) {
                /* same thing for sctp */
                if (sctp_server_init(si)==-1)  goto error;
                /* get first ipv4/ipv6 socket*/
                if ((si->address.af==AF_INET)&&
                        ((sendipv4_sctp==0)||(sendipv4_sctp->flags&SI_IS_LO)))
                    sendipv4_sctp=si;
#ifdef USE_IPV6
                if((sendipv6_sctp==0)&&(si->address.af==AF_INET6))
                    sendipv6_sctp=si;
#endif
            }
        }
#endif /* USE_SCTP */

        /* all processes should have access to all the sockets (for sending)
         * so we open all first*/
        if (do_suid(uid, gid)==-1) goto error; /* try to drop privileges */

        if (start_module_procs()!=0) {
            LM_ERR("failed to fork module processes\n");
            goto error;
        }

        if(startup_rlist.a) {/* if a startup route was defined */
            startup_done = (int*)shm_malloc(sizeof(int));
            if(startup_done == NULL)
            {
                LM_ERR("No more shared memory\n");
                goto error;
            }
            *startup_done = 0;
        }

        /* udp processes */
        for(si=udp_listen; si; si=si->next) {

            if (register_udp_load_stat(&si->sock_str, &load_p)!=0) {
                LM_ERR("failed to init load statistics\n");
                goto error;
            }

            for(i=0; i<children_no; i++) {
                chd_rank++;
                if ( (pid=internal_fork( "UDP receiver"))<0 ) {
                    LM_CRIT("cannot fork UDP process\n");
                    goto error;
                } else {
                    if (pid==0) {
                        /* new UDP process */
                        /* set a more detailed description */
                        set_proc_attrs("SIP receiver %.*s ",
                                       si->sock_str.len, si->sock_str.s);
                        bind_address=si; /* shortcut */
                        if (init_child(chd_rank) < 0) {
                            LM_ERR("init_child failed for UDP listener\n");
                            if (send_status_code(-1) < 0)
                                LM_ERR("failed to send status code\n");
                            clean_write_pipeend();
                            exit(-1);
                        }

                        if (send_status_code(0) < 0)
                            LM_ERR("failed to send status code\n");
                        clean_write_pipeend();

                        if(chd_rank == 1 && startup_rlist.a) {
                            if(run_startup_route()< 0) {
                                LM_ERR("Startup route processing failed\n");
                                exit(-1);
                            }
                            *startup_done = 1;
                        }

                        /* all UDP listeners on same interface
                         * have same SHM load pointer */
                        pt[process_no].load = load_p;
                        udp_rcv_loop();
                        exit(-1);
                    }
                    else {
                        /* if the first process that runs startup_route*/
                        if(chd_rank == 1 && startup_rlist.a) {
                            while(!startup_done) {
                                usleep(5);
                            }
                            shm_free(startup_done);
                        }
                    }
                }
            }
            /*parent*/
            /*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
        }
    }

#ifdef USE_SCTP
    if(!sctp_disable) {
        for(si=sctp_listen; si; si=si->next) {
            for(i=0; i<children_no; i++) {
                chd_rank++;
                if ( (pid=internal_fork( "SCTP receiver"))<0 ) {
                    LM_CRIT("cannot fork SCTP process\n");
                    goto error;
                } else if (pid==0) {
                    /* new SCTP process */
                    /* set a more detailed description */
                    set_proc_attrs("SIP receiver %.*s ",
                                   si->sock_str.len, si->sock_str.s);
                    bind_address=si; /* shortcut */
                    if (init_child(chd_rank) < 0) {
                        LM_ERR("init_child failed\n");
                        if (send_status_code(-1) < 0)
                            LM_ERR("failed to send status code\n");
                        clean_write_pipeend();
                        exit(-1);
                    }

                    if (send_status_code(0) < 0)
                        LM_ERR("failed to send status code\n");
                    clean_write_pipeend();

                    sctp_server_rcv_loop();
                    exit(-1);
                }
            }
        }
    }
#endif /* USE_SCTP */

    /* this is the main process -> it shouldn't send anything */
    bind_address=0;

    /* fork for the timer process*/
    if (start_timer_processes()!=0) {
        LM_CRIT("cannot start timer process(es)\n");
        goto error;
    }

#ifdef USE_TCP
    if (!tcp_disable) {
        /* start tcp  & tls receivers */
        if (tcp_init_children(&chd_rank)<0) goto error;
        /* start tcp+tls master proc */
        if ( (pid=internal_fork( "TCP main"))<0 ) {
            LM_CRIT("cannot fork tcp main process\n");
            goto error;
        } else if (pid==0) {
            /* child */
            /* close the TCP inter-process sockets */
            close(unix_tcp_sock);
            unix_tcp_sock = -1;
            close(pt[process_no].unix_sock);
            pt[process_no].unix_sock = -1;
            /* init modules */
            if (init_child(PROC_TCP_MAIN) < 0) {
                LM_ERR("error in init_child for tcp main\n");
                if (send_status_code(-1) < 0)
                    LM_ERR("failed to send status code\n");
                clean_write_pipeend();

                exit(-1);
            }

            if (send_status_code(0) < 0)
                LM_ERR("failed to send status code\n");
            clean_write_pipeend();

            tcp_main_loop();
            exit(-1);
        }
    }
#endif

    /* main process left */
    is_main=1;
    set_proc_attrs("attendant");

    if (init_child(PROC_MAIN) < 0) {
        LM_ERR("error in init_child for PROC_MAIN\n");
        goto error;
    }

    if (send_status_code(0) < 0)
        LM_ERR("failed to send status code\n");
    clean_write_pipeend();

    for(;;) {
        handle_sigs();
        pause();
    }

    /*return 0; */
error:
    is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
    if (!dont_fork && send_status_code(-1) < 0)
        LM_ERR("failed to send status code\n");
    clean_write_pipeend();

    return -1;

}
コード例 #2
0
ファイル: daemonize.c プロジェクト: Ellenwief/opensips
/*!
 * \brief daemon init
 * \param name daemon name
 * \param own_pgid daemon process group
 * \return return 0 on success, -1 on error
 */
int daemonize(char* name, int * own_pgid)
{
	FILE *pid_stream;
	pid_t pid;
	int r, p,rc;
	int pid_items;

	p=-1;

	/* flush std file descriptors to avoid flushes after fork
	 *  (same message appearing multiple times)
	 *  and switch to unbuffered
	 */
	setbuf(stdout, 0);
	setbuf(stderr, 0);
	if (chroot_dir&&(chroot(chroot_dir)<0)){
		LM_CRIT("Cannot chroot to %s: %s\n", chroot_dir, strerror(errno));
		goto error;
	}
	
	if (chdir(working_dir)<0){
		LM_CRIT("Cannot chdir to %s: %s\n", working_dir, strerror(errno));
		goto error;
	}

	if (create_status_pipe() < 0) {
		LM_ERR("failed to create status pipe");
		goto error;
	}

	if (!no_daemon_mode) {
		/* fork to become!= group leader*/
		if ((pid=fork())<0){
			LM_CRIT("Cannot fork:%s\n", strerror(errno));
			goto error;
		}else if (pid!=0){
			/* parent process => wait for status codes from children*/
			clean_write_pipeend();
			LM_DBG("waiting for status code from children\n");
			rc = wait_for_all_children();
			LM_INFO("pre-daemon process exiting with %d\n",rc);
			exit(rc);
		}

		/* cleanup read end - nobody should
		 * need to read from status pipe from this point on */
		clean_read_pipeend();

		/* become session leader to drop the ctrl. terminal */
		if (setsid()<0){
			LM_WARN("setsid failed: %s\n",strerror(errno));
		}else{
			*own_pgid=1;/* we have our own process group */
		}
		/* fork again to drop group  leadership */
		if ((pid=fork())<0){
			LM_CRIT("Cannot  fork:%s\n", strerror(errno));
			goto error;
		}else if (pid!=0){
			/*parent process => exit */
			exit(0);
		}
	}

#ifdef __OS_linux
	/* setsid may disables core dumping on linux, reenable it */
	if ( !disable_core_dump && prctl(PR_SET_DUMPABLE, 1)) {
		LM_ERR("Cannot enable core dumping after setuid\n");
	}
#endif

	/* added by noh: create a pid file for the main process */
	if (pid_file!=0){
		
		if ((pid_stream=fopen(pid_file, "r"))!=NULL){
			pid_items=fscanf(pid_stream, "%d", &p);
			fclose(pid_stream);
			if (p==-1 || pid_items <= 0){
				LM_WARN("pid file %s exists, but doesn't contain a valid"
					" pid number, replacing...\n", pid_file);
			} else 
			if (kill((pid_t)p, 0)==0 || errno==EPERM){
				LM_CRIT("running process found in the pid file %s\n",
					pid_file);
				goto error;
			}else{
				LM_WARN("pid file contains old pid, replacing pid\n");
			}
		}
		pid=getpid();
		if ((pid_stream=fopen(pid_file, "w"))==NULL){
			LM_ERR("unable to create pid file %s: %s\n", 
				pid_file, strerror(errno));
			goto error;
		}else{
			r = fprintf(pid_stream, "%i\n", (int)pid);
			if (r<=0)  {
				LM_ERR("unable to write pid to file %s: %s\n", 
					pid_file, strerror(errno));
				goto error;
			}
			fclose(pid_stream);
		}
	}

	if (pgid_file!=0){
		if ((pid_stream=fopen(pgid_file, "r"))!=NULL){
			pid_items=fscanf(pid_stream, "%d", &p);
			fclose(pid_stream);
			if (p==-1 || pid_items <= 0){
				LM_WARN("pgid file %s exists, but doesn't contain a valid"
					" pgid number, replacing...\n", pgid_file);
			}
		}
		if (own_pgid){
			pid=getpgid(0);
			if ((pid_stream=fopen(pgid_file, "w"))==NULL){
				LM_ERR("unable to create pgid file %s: %s\n",
					pgid_file, strerror(errno));
				goto error;
			}else{
				r = fprintf(pid_stream, "%i\n", (int)pid);
				if (r<=0)  {
					LM_ERR("unable to write pgid to file %s: %s\n", 
						pid_file, strerror(errno));
					goto error;
				}
				fclose(pid_stream);
			}
		}else{
			LM_WARN("we don't have our own process so we won't save"
					" our pgid\n");
			unlink(pgid_file); /* just to be sure nobody will miss-use the old
								  value*/
		}
	}

	/* try to replace stdin, stdout & stderr with /dev/null */
	if (freopen("/dev/null", "r", stdin)==0){
		LM_WARN("unable to replace stdin with /dev/null: %s\n",
			strerror(errno));
		/* continue, leave it open */
	};
	if (freopen("/dev/null", "w", stdout)==0){
		LM_WARN("unable to replace stdout with /dev/null: %s\n",
			strerror(errno));
		/* continue, leave it open */
	};
	/* close stderr only if not to be used */
	if ( (!log_stderr) && (freopen("/dev/null", "w", stderr)==0)){
		LM_WARN("unable to replace stderr with /dev/null: %s\n",
			strerror(errno));
		/* continue, leave it open */
	};

	/* close any open file descriptors */
	closelog();

	/* 32 is the maximum number of inherited open file descriptors */
	for (r=3; r < 32; r++){
		/* future children must still inherit
		 * and write to this pipe end */
		if (r != status_pipe[1])
			close(r);
	}

	if (!log_stderr)
		openlog(name, LOG_PID|LOG_CONS, log_facility);
		/* LOG_CONS, LOG_PERRROR ? */

	return  0;

error:
	return -1;
}
コード例 #3
0
ファイル: main.c プロジェクト: yuantangliang/opensips
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
    static int chd_rank;
    int* startup_done = NULL;

    chd_rank=0;

    if (init_debug() != 0) {
        LM_ERR("failed to init logging levels\n");
        goto error;
    }

    if (dont_fork) {

        if (create_status_pipe() < 0) {
            LM_ERR("failed to create status pipe\n");
            goto error;
        }

        if (udp_init_nofork() < 0) {
            LM_ERR("failed to init UDP for no fork mode\n");
            goto error;
        }

        /* try to drop privileges */
        if (do_suid(uid, gid)==-1)
            goto error;

        if (start_module_procs()!=0) {
            LM_ERR("failed to fork module processes\n");
            goto error;
        }

        /* we need another process to act as the timer*/
        if (start_timer_processes()!=0) {
            LM_CRIT("cannot start timer process(es)\n");
            goto error;
        }

        is_main=1;

        udp_start_nofork();
        /* udp_start_nofork() returns only if error */

        /* in case of failed startup, behave as "attendant" to trigger
         * proper cleanup sequance (and proper signal handler !!!).
         * So, reset the dont_fork (as it will force inline signal handling)*/
        dont_fork = 0;
        return -1;

    } else {  /* don't fork */

        if (trans_init_all_listeners()<0) {
            LM_ERR("failed to init all SIP listeners, aborting\n");
            goto error;
        }

        /* all processes should have access to all the sockets (for sending)
         * so we open all first*/
        if (do_suid(uid, gid)==-1) goto error; /* try to drop privileges */

        if (start_module_procs()!=0) {
            LM_ERR("failed to fork module processes\n");
            goto error;
        }

        if(startup_rlist.a) {/* if a startup route was defined */
            startup_done = (int*)shm_malloc(sizeof(int));
            if(startup_done == NULL) {
                LM_ERR("No more shared memory\n");
                goto error;
            }
            *startup_done = 0;
        }

        if (fix_socket_list(&bin) != 0) {
            LM_ERR("failed to initialize binary interface socket list!\n");
            goto error;
        }

        /* OpenSIPS <--> OpenSIPS communication interface */
        if (bin && start_bin_receivers() != 0) {
            LM_CRIT("cannot start binary interface receiver processes!\n");
            goto error;
        }

        /* fork for the timer process*/
        if (start_timer_processes()!=0) {
            LM_CRIT("cannot start timer process(es)\n");
            goto error;
        }

        /* fork all processes required by UDP network layer */
        if (udp_start_processes( &chd_rank, startup_done)<0) {
            LM_CRIT("cannot start TCP processes\n");
            goto error;
        }

        /* fork all processes required by TCP network layer */
        if (tcp_start_processes( &chd_rank, startup_done)<0) {
            LM_CRIT("cannot start TCP processes\n");
            goto error;
        }
    }

    /* this is the main process -> it shouldn't send anything */
    bind_address=0;

    if (startup_done) {
        if (*startup_done==0)
            LM_CRIT("BUG: startup route defined, but not run :( \n");
        shm_free(startup_done);
    }

    /* main process left */
    is_main=1;
    set_proc_attrs("attendant");

    if (init_child(PROC_MAIN) < 0) {
        LM_ERR("error in init_child for PROC_MAIN\n");
        report_failure_status();
        goto error;
    }

    report_conditional_status( (!no_daemon_mode), 0);

    for(;;) {
        handle_sigs();
        pause();
    }

    /*return 0; */
error:
    is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
    report_conditional_status( (!dont_fork), -1);
    return -1;

}
コード例 #4
0
ファイル: main.c プロジェクト: Parantido/opensips
/**
 * 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 = 1;
	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':
					*log_level = debug_mode ? L_DBG : (*log_level)+1;
					break;
			case 'D':
					debug_mode=1;
					*log_level = L_DBG;
					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;
	}

	/* 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 (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\n");
		goto error;
	}
	/*init TCP networking layer*/
	if (tcp_init()<0){
		LM_CRIT("could not initialize tcp\n");
		goto error;
	}

	if (create_status_pipe() < 0) {
		LM_ERR("failed to create status pipe\n");
		goto error;
	}

	if (debug_mode) {

		LM_NOTICE("DEBUG MODE activated\n");
		if (no_daemon_mode==0) {
			LM_NOTICE("disabling daemon mode (found enabled)\n");
			no_daemon_mode = 1;
		}
		if (log_stderr==0) {
			LM_NOTICE("enabling logging to standard error (found disabled)\n");
			log_stderr = 1;
		}
		if (*log_level<L_DBG) {
			LM_NOTICE("setting logging to debug level (found on %d)\n",
				*log_level);
			*log_level = L_DBG;
		}
		if (disable_core_dump) {
			LM_NOTICE("enabling core dumping (found off)\n");
			disable_core_dump = 0;
		}
		if (udp_count_processes()!=0) {
			if (children_no!=2) {
				LM_NOTICE("setting UDP children to 2 (found %d)\n",
					children_no);
				children_no = 2;
			}
		}
		if (tcp_count_processes()!=0) {
			if (tcp_children_no!=2) {
				LM_NOTICE("setting TCP children to 2 (found %d)\n",
					tcp_children_no);
				tcp_children_no = 2;
			}
		}

	} else { /* debug_mode */

		/* init_daemon */
		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(set_open_fds_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 async reactor */
	if (init_reactor_size()<0) {
		LM_CRIT("failed to init internal reactor, exiting...\n");
		goto error;
	}

	/* 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;
	}

	if (init_log_level() != 0) {
		LM_ERR("failed to init logging levels\n");
		goto error;
	}

	if (trans_init_all_listeners()<0) {
		LM_ERR("failed to init all SIP listeners, aborting\n");
		goto error;
	}

	/* all processes should have access to all the sockets (for sending)
	 * so we open all first*/
	if (do_suid(uid, gid)==-1)
		goto error;

	ret = main_loop();

error:
	/*kill everything*/
	kill_all_children(SIGTERM);
	/*clean-up*/
	cleanup(0);
error00:
	LM_NOTICE("Exiting....\n");
	return ret;
}