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