Esempio n. 1
0
static void NETWORK_on_received(DictionaryIterator *iter, void *context)
{
    int rval = 0;
    struct NetworkState *state = context;
    abort_if(!state, "state is null");

    Tuple *tuple = dict_find(iter, 0);
    abort_if(!tuple, "tuple is null");

    char *action = tuple->value->cstring;
    log_debug("<-- %s", action);

    if(strcmp(action, "COUNT") == 0)
    {
        rval = process_count(iter, state);
        abort_if(rval, "process_count failed");
    }
    else if(strcmp(action, "HABIT") == 0)
    {
        rval = process_habit(iter, state);
        abort_if(rval, "process_habit failed");
    }
    else if(strcmp(action, "OK") == 0)
    {
        rval = process_ok(state);
        abort_if(rval, "process_ok failed");
    }

CLEANUP:
    return;
}
Esempio n. 2
0
int init_tm_stats(void)
{
	int size;

	tm_stats=shm_malloc(sizeof(struct t_stats));
	if (tm_stats==0) {
		LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
		goto error0;
	}
	memset(tm_stats, 0, sizeof(struct t_stats) );

	size=sizeof(stat_counter)*process_count();
	tm_stats->s_waiting=shm_malloc(size);
	if (tm_stats->s_waiting==0) {
		LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
		goto error1;
	}
	memset(tm_stats->s_waiting, 0, size );

	tm_stats->s_transactions=shm_malloc(size);
	if (tm_stats->s_transactions==0) {
		LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
		goto error2;
	}
	memset(tm_stats->s_transactions, 0, size );

	tm_stats->s_client_transactions=shm_malloc(size);
	if (tm_stats->s_client_transactions==0) {
		LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
		goto error3;
	}
	memset(tm_stats->s_client_transactions, 0, size );

	if (register_fifo_cmd(fifo_stats, "t_stats", 0)<0) {
		LOG(L_CRIT, "cannot register fifo stats\n");
		goto error4;
	}

	if (unixsock_register_cmd("t_stats", unixsock_stats) < 0) {
		LOG(L_CRIT, "cannot register fifo stats\n");
		goto error4;
	}

	return 1;

error4:
	shm_free(tm_stats->s_client_transactions);
	tm_stats->s_client_transactions=0;
error3:
	shm_free(tm_stats->s_transactions);
	tm_stats->s_transactions=0;
error2:
	shm_free(tm_stats->s_waiting);
	tm_stats->s_waiting=0;
error1:
	shm_free(tm_stats);
error0:
	return -1;
}
Esempio n. 3
0
File: main.c Progetto: OPSF/uClinux
/* tries to send a signal to all our processes
 * if daemonized  is ok to send the signal to all the process group,
 * however if not daemonized we might end up sending the signal also
 * to the shell which launched us => most signals will kill it if 
 * it's not in interactive mode and we don't want this. The non-daemonized 
 * case can occur when an error is encountered before daemonize is called 
 * (e.g. when parsing the config file) or when ser is started in "dont-fork"
 *  mode. Sending the signal to all the processes in pt[] will not work
 *  for processes forked from modules (which have no correspondent entry in 
 *  pt), but this can happen only in dont_fork mode (which is only for
 *  debugging). So in the worst case + "dont-fork" we might leave some
 *  zombies. -- andrei */
static void kill_all_children(int signum)
{
	int r;

	if (own_pgid) kill(0, signum);
	else if (pt)
		for (r=1; r<process_count(); r++)
			if (pt[r].pid) kill(pt[r].pid, signum);
}
// Handle input from Erlang VM
static void outputv(ErlDrvData handle, ErlIOVec *ev) {
    bdb_drv_t* pdrv = (bdb_drv_t*) handle;

    ErlDrvBinary* data = ev->binv[1];

    int command = data->orig_bytes[0]; // First byte is the command
  
    switch(command) {
    case 'O':
        process_open(pdrv, ev);
        break;

    case 'S':
        process_set(pdrv, ev);
        break;

    case 'G':
        process_get(pdrv, ev);
        break;

    case 'D':
        process_del(pdrv, ev);
        break;

    case 'C':
        process_count(pdrv, ev);
        break;

    case 'F':
        process_flush(pdrv, ev);
        break;

    case 'B':
        process_bulk_get(pdrv, ev);
        break;

    case 'Z':
        process_compact(pdrv, ev);
        break;

    case 'T':
        process_truncate(pdrv, ev);
        break;

    default:
        process_unkown(pdrv, ev);
    }

}
Esempio n. 5
0
int static unixsock_stats(str* cmd)
{
	unsigned long total, current, waiting, total_local;
	int i;
	int pno;

	unixsock_reply_asciiz( "200 OK\n");

	pno = process_count();
	for(i = 0, total = 0, waiting = 0, total_local = 0; i < pno; i++) {
		total += tm_stats->s_transactions[i];
		waiting += tm_stats->s_waiting[i];
		total_local += tm_stats->s_client_transactions[i];
	}
	current = total - tm_stats->deleted;
	waiting -= tm_stats->deleted;

	if (unixsock_reply_printf("Current: %lu (%lu waiting) "
				  "Total: %lu (%lu local) " CLEANUP_EOL,
				  current, waiting, total, total_local) < 0) goto err;

	if (unixsock_reply_printf("Replied localy: %lu" CLEANUP_EOL ,
				  tm_stats->replied_localy ) < 0) goto err;
	if (unixsock_reply_printf("Completion status 6xx: %lu,",
				  tm_stats->completed_6xx ) < 0) goto err;
	if (unixsock_reply_printf(" 5xx: %lu,",
				  tm_stats->completed_5xx ) < 0) goto err;
	if (unixsock_reply_printf(" 4xx: %lu,",
				  tm_stats->completed_4xx ) < 0) goto err;
	if (unixsock_reply_printf(" 3xx: %lu,",
				  tm_stats->completed_3xx ) < 0) goto err;
	if (unixsock_reply_printf("2xx: %lu" CLEANUP_EOL ,
				  tm_stats->completed_2xx ) < 0) goto err;
	
	unixsock_reply_send();
	return 0;

 err:
	unixsock_reply_reset();
	unixsock_reply_asciiz("500 Buffer too small\n");
	unixsock_reply_send();
	return -1;
}
Esempio n. 6
0
static int ps_cmd(str* msg)
{
	int p, ret;

	ret = 0;
	unixsock_reply_asciiz("200 OK\n");
	for (p = 0; p < process_count(); p++) {
		if (unixsock_reply_printf("%d\t%d\t%s\n", p, pt[p].pid, pt[p].desc) < 0) {
			unixsock_reply_reset();
			unixsock_reply_asciiz("500 Error while printing reply\n");
			ret = -1;
			break;
		}
	}
	
	if (unixsock_reply_send() < 0) {
		ret = -1;
	}
	return ret;
}
Esempio n. 7
0
static int ps_fifo_cmd(FILE *stream, char *response_file )
{
	FILE *reply_pipe;
	int p;

	if (response_file==0 || *response_file==0 ) {
		 LOG(L_ERR, "ERROR: ps_fifo_cmd: null file\n");
		return -1;
	}
	reply_pipe=open_reply_pipe(response_file);
	if (reply_pipe==NULL) {
		LOG(L_ERR, "ERROR: ps_fifo_cmd: opening reply pipe (%s) failed\n",
			response_file );
		return -1;
	}

	fputs( "200 ok\n", reply_pipe);
	for (p=0; p<process_count();p++) 
		fprintf( reply_pipe, "%d\t%d\t%s\n",
			p, pt[p].pid, pt[p].desc );

	fclose(reply_pipe);
	return 1;
}
Esempio n. 8
0
int print_stats(  FILE *f )
{
	unsigned long total, current, waiting, total_local;
	int i;
	int pno;

	pno=process_count();
	for(i=0, total=0, waiting=0, total_local=0; i<pno;i++) {
		total+=tm_stats->s_transactions[i];
		waiting+=tm_stats->s_waiting[i];
		total_local+=tm_stats->s_client_transactions[i];
	}
	current=total-tm_stats->deleted;
	waiting-=tm_stats->deleted;

	

	fprintf(f, "Current: %lu (%lu waiting) "
		"Total: %lu (%lu local) " CLEANUP_EOL,
		current, waiting, total, total_local);

	fprintf(f, "Replied localy: %lu" CLEANUP_EOL ,
		tm_stats->replied_localy );
	fprintf(f, "Completion status 6xx: %lu,",
		tm_stats->completed_6xx );
	fprintf(f, " 5xx: %lu,",
		tm_stats->completed_5xx );
	fprintf(f, " 4xx: %lu,",
		tm_stats->completed_4xx );
	fprintf(f, " 3xx: %lu,",
		tm_stats->completed_3xx );
	fprintf(f, "2xx: %lu" CLEANUP_EOL ,
		tm_stats->completed_2xx );
	
	return 1;
}
Esempio n. 9
0
File: main.c Progetto: OPSF/uClinux
/* main loop */
int main_loop()
{
	int  i;
	pid_t pid;
	struct socket_info* si;
#ifdef USE_TCP
	int sockfd[2];
#endif

	/* one "main" process and n children handling i/o */

	is_main=0;
	if (dont_fork){
#ifdef STATS
		setstats( 0 );
#endif
		if (udp_listen==0){
			LOG(L_ERR, "ERROR: 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){
			LOG(L_WARN, "WARNING: using only the first listen address"
						" (no fork)\n");
		}
		/* initialize fifo server -- we need to open the fifo before
		 * do_suid() and start the fifo server after all the socket 
		 * are initialized, to inherit them*/
		if (init_fifo_server()<0) {
			LOG(L_ERR, "initializing fifo server failed\n");
			goto error;
		}
		 /* Initialize Unix domain socket server */
		if (init_unixsock_socket()<0) {
			LOG(L_ERR, "Error while creating unix domain sockets\n");
			goto error;
		}
		if (do_suid()==-1) goto error; /* try to drop privileges */
		/* process_no now initialized to zero -- increase from now on
		   as new processes are forked (while skipping 0 reserved for main 
		*/

		/* we need another process to act as the timer*/
#ifdef USE_TCP
		/* if we are using tcp we always need a timer process,
		 * we cannot count on select timeout to measure time
		 * (it works only on linux)
		 */
		if ((!tcp_disable)||(timer_list))
#else
		if (timer_list)
#endif
		{
				process_no++;
				if ((pid=fork())<0){
					LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
					goto error;
				}
				
				if (pid==0){
					/* child */
					/* timer!*/
					/* process_bit = 0; */
					if (init_child(PROC_TIMER) < 0) {
						LOG(L_ERR, "timer: init_child failed\n");
						goto error;
					}
					for(;;){
						sleep(TIMER_TICK);
						timer_ticker();
					}
				}else{
						pt[process_no].pid=pid; /*should be shared mem anyway*/
						strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
				}
		}

		/* if configured, start a server for accepting FIFO commands,
		 * we need to do it after all the sockets are initialized, to 
		 * inherit them*/
		if (start_fifo_server()<0) {
			LOG(L_ERR, "starting fifo server failed\n");
			goto error;
		}

		if (init_unixsock_children()<0) {
			LOG(L_ERR, "Error while initializing Unix domain socket server\n");
			goto error;
		}

		/* main process, receive loop */
		process_no=0; /*main process number*/
		pt[process_no].pid=getpid();
		snprintf(pt[process_no].desc, MAX_PT_DESC, 
			"stand-alone receiver @ %s:%s", 
			 bind_address->name.s, bind_address->port_no_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) {
			LOG(L_ERR, "main_dontfork: init_child failed\n");
			goto error;
		}

		is_main=1; /* hack 42: call init_child with is_main=0 in case
					 some modules wants to fork a child */
		
		return udp_rcv_loop();
	}else{
		/* process_no now initialized to zero -- increase from now on
		   as new processes are forked (while skipping 0 reserved for main )
		*/

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

		/* initialize fifo server -- we need to open the fifo before
		 * do_suid() and start the fifo server after all the socket 
		 * are initialized, to inherit them*/
		if (init_fifo_server()<0) {
			LOG(L_ERR, "initializing fifo server failed\n");
			goto error;
		}
		 /* Initialize Unix domain socket server */
		     /* Create the unix domain sockets */
		if (init_unixsock_socket()<0) {
			LOG(L_ERR, "ERROR: Could not create unix domain sockets\n");
			goto error;
		}

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

		/* if configured, start a server for accepting FIFO commands,
		 * we need to do it after all the sockets are initialized, to 
		 * inherit them*/
		if (start_fifo_server()<0) {
			LOG(L_ERR, "starting fifo server failed\n");
			goto error;
		}
		     /* Spawn children listening on unix domain socket if and only if
		      * the unix domain socket server has not been disabled (i == 0)
		      */
		if (init_unixsock_children()<0) {
			LOG(L_ERR, "ERROR: Could not initialize unix domain socket server\n");
			goto error;
		}

		/* udp processes */
		for(si=udp_listen; si; si=si->next){
			for(i=0;i<children_no;i++){
				process_no++;
#ifdef USE_TCP
				if(!tcp_disable){
		 			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
						LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
							strerror(errno));
						goto error;
					}
				}
#endif
				if ((pid=fork())<0){
					LOG(L_CRIT,  "main_loop: Cannot fork\n");
					goto error;
				}else if (pid==0){
					     /* child */
#ifdef USE_TCP
					if (!tcp_disable){
						close(sockfd[0]);
						unix_tcp_sock=sockfd[1];
					}
#endif
					bind_address=si; /* shortcut */
					if (init_child(i + 1) < 0) {
						LOG(L_ERR, "init_child failed\n");
						goto error;
					}
#ifdef STATS
					setstats( i+r*children_no );
#endif
					return udp_rcv_loop();
				}else{
						pt[process_no].pid=pid; /*should be in shared mem.*/
						snprintf(pt[process_no].desc, MAX_PT_DESC,
							"receiver child=%d sock= %s:%s", i, 	
							si->name.s, si->port_no_str.s );
#ifdef USE_TCP
						if (!tcp_disable){
							close(sockfd[1]);
							pt[process_no].unix_sock=sockfd[0];
							pt[process_no].idx=-1; /* this is not a "tcp"
													  process*/
						}
#endif
				}
			}
			/*parent*/
			/*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
		}
	}

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

#ifdef USE_TCP
	/* if we are using tcp we always need the timer */
	if ((!tcp_disable)||(timer_list))
#else
	if (timer_list)
#endif
	{
#ifdef USE_TCP
		if (!tcp_disable){
 			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
				LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
					strerror(errno));
				goto error;
			}
		}
#endif
		/* fork again for the attendant process*/
		process_no++;
		if ((pid=fork())<0){
			LOG(L_CRIT, "main_loop: cannot fork timer process\n");
			goto error;
		}else if (pid==0){
			/* child */
			/* is_main=0; */
#ifdef USE_TCP
			if (!tcp_disable){
				close(sockfd[0]);
				unix_tcp_sock=sockfd[1];
			}
#endif
			if (init_child(PROC_TIMER) < 0) {
				LOG(L_ERR, "timer: init_child failed\n");
				goto error;
			}
			
			for(;;){
				/* debug:  instead of doing something useful */
				/* (placeholder for timers, etc.) */
				sleep(TIMER_TICK);
				/* if we received a signal => TIMER_TICK may have not elapsed*/
				timer_ticker();
			}
		}else{
			pt[process_no].pid=pid;
			strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
#ifdef USE_TCP
			if(!tcp_disable){
						close(sockfd[1]);
						pt[process_no].unix_sock=sockfd[0];
						pt[process_no].idx=-1; /* this is not a "tcp" process*/
			}
#endif
		}
	}
#ifdef USE_TCP
		if (!tcp_disable){
				/* start tcp  & tls receivers */
			if (tcp_init_children()<0) goto error;
				/* start tcp+tls master proc */
			process_no++;
			if ((pid=fork())<0){
				LOG(L_CRIT, "main_loop: cannot fork tcp main process\n");
				goto error;
			}else if (pid==0){
				/* child */
				/* is_main=0; */
				if (init_child(PROC_TCP_MAIN) < 0) {
					LOG(L_ERR, "tcp_main: error in init_child\n");
					goto error;
				}
				tcp_main_loop();
			}else{
				pt[process_no].pid=pid;
				strncpy(pt[process_no].desc, "tcp main process", MAX_PT_DESC );
				pt[process_no].unix_sock=-1;
				pt[process_no].idx=-1; /* this is not a "tcp" process*/
				unix_tcp_sock=-1;
			}
		}
#endif
	/* main */
	pt[0].pid=getpid();
	strncpy(pt[0].desc, "attendant", MAX_PT_DESC );
#ifdef USE_TCP
	if(!tcp_disable){
		pt[process_no].unix_sock=-1;
		pt[process_no].idx=-1; /* this is not a "tcp" process*/
		unix_tcp_sock=-1;
	}
#endif
	/*DEBUG- remove it*/
#ifdef DEBUG
	fprintf(stderr, "\n% 3d processes (%3d), % 3d children * "
			"listening addresses + tcp listeners + tls listeners"
			"+ main + fifo %s\n", process_no+1, process_count(), children_no,
			(timer_list)?"+ timer":"");
	for (r=0; r<=process_no; r++){
		fprintf(stderr, "% 3d   % 5d - %s\n", r, pt[r].pid, pt[r].desc);
	}
#endif
	process_no=0; 
	/* process_bit = 0; */
	is_main=1;
	
	if (init_child(PROC_MAIN) < 0) {
		LOG(L_ERR, "main: error in init_child\n");
		goto error;
	}
	for(;;){
			pause();
			handle_sigs();
	}
	
	
	/*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 */
	return -1;

}
Esempio n. 10
0
File: main.c Progetto: OPSF/uClinux
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;

}