21e9c0fe5759de746c109892c3fc1ccf750a3c30
[sip-router] / main.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  * History:
28  * -------
29  *  2002-01-29  argc/argv globalized via my_{argc|argv} (jiri)
30  *  2003-01-23  mhomed added (jiri)
31  *  2003-03-19  replaced all malloc/frees w/ pkg_malloc/pkg_free (andrei)
32  *  2003-03-29  pkg cleaners for fifo and script callbacks introduced (jiri)
33  *  2003-03-31  removed snmp part (obsolete & no place in core) (andrei)
34  *  2003-04-06  child_init called in all processes (janakj)
35  *  2003-04-08  init_mallocs split into init_{pkg,shm}_mallocs and 
36  *               init_shm_mallocs called after cmd. line parsing (andrei)
37  *  2003-04-15  added tcp_disable support (andrei)
38  *  2003-05-09  closelog() before openlog to force opening a new fd 
39  *               (needed on solaris) (andrei)
40  *  2003-06-11  moved all signal handlers init. in install_sigs and moved it
41  *               after daemonize (so that we won't catch anymore our own
42  *               SIGCHLD generated when becoming session leader) (andrei)
43  *              changed is_main default value to 1 (andrei)
44  *  2003-06-28  kill_all_children is now used instead of kill(0, sig)
45  *                see comment above it for explanations. (andrei)
46  *  2003-06-29  replaced port_no_str snprintf w/ int2str (andrei)
47  *  2003-10-10  added switch for config check (-c) (andrei)
48  *  2003-10-24  converted to the new socket_info lists (andrei)
49  *  2004-03-30  core dump is enabled by default
50  *              added support for increasing the open files limit    (andrei)
51  *  2004-04-28  sock_{user,group,uid,gid,mode} added
52  *              user2uid() & user2gid() added  (andrei)
53  *  2004-09-11  added timeout on children shutdown and final cleanup
54  *               (if it takes more than 60s => something is definitely wrong
55  *                => kill all or abort)  (andrei)
56  *              force a shm_unlock before cleaning-up, in case we have a
57  *               crashed childvwhich still holds the lock  (andrei)
58  *  2004-12-02  removed -p, extended -l to support [proto:]address[:port],
59  *               added parse_phostport, parse_proto (andrei)
60  *  2005-06-16  always record the pid in pt[process_no].pid twice: once in the
61  *               parent & once in the child to avoid a short window when one
62  *               of them might use it "unset" (andrei)
63  *  2005-07-25  use sigaction for setting the signal handlers (andrei)
64  */
65
66
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <errno.h>
70 #include <ctype.h>
71 #include <string.h>
72 #include <netdb.h>
73 #include <unistd.h>
74 #include <sys/types.h>
75 #include <sys/socket.h>
76 #if defined(HAVE_NETINET_IN_SYSTM)
77 #include <netinet/in_systm.h>
78 #endif
79 #include <netinet/in.h>
80 #include <netinet/ip.h>
81 #include <arpa/inet.h>
82 #include <sys/utsname.h>
83 #include <sys/stat.h>
84 #include <sys/mman.h>
85 #include <fcntl.h>
86 #include <sys/time.h>
87 #include <sys/wait.h>
88 #include <pwd.h>
89 #include <grp.h>
90 #include <signal.h>
91
92 #include <sys/ioctl.h>
93 #include <net/if.h>
94 #ifdef HAVE_SYS_SOCKIO_H
95 #include <sys/sockio.h>
96 #endif
97
98 #include "config.h"
99 #include "dprint.h"
100 #include "daemonize.h"
101 #include "route.h"
102 #include "udp_server.h"
103 #include "globals.h"
104 #include "mem/mem.h"
105 #ifdef SHM_MEM
106 #include "mem/shm_mem.h"
107 #endif
108 #include "sr_module.h"
109 #include "timer.h"
110 #include "parser/msg_parser.h"
111 #include "ip_addr.h"
112 #include "resolve.h"
113 #include "parser/parse_hname2.h"
114 #include "parser/digest/digest_parser.h"
115 #include "fifo_server.h"
116 #include "unixsock_server.h"
117 #include "name_alias.h"
118 #include "hash_func.h"
119 #include "pt.h"
120 #include "script_cb.h"
121 #include "ut.h"
122 #ifdef USE_TCP
123 #include "poll_types.h"
124 #include "tcp_init.h"
125 #ifdef USE_TLS
126 #include "tls/tls_init.h"
127 #endif
128 #endif
129 #include "usr_avp.h"
130
131
132 #include "stats.h"
133
134 #ifdef DEBUG_DMALLOC
135 #include <dmalloc.h>
136 #endif
137 #include "version.h"
138
139 static char id[]="@(#) $Id$";
140 static char* version=SER_FULL_VERSION;
141 static char* flags=SER_COMPILE_FLAGS;
142 char compiled[]= __TIME__ " " __DATE__ ;
143
144
145 static char help_msg[]= "\
146 Usage: " NAME " -l address [-p port] [-l address [-p port]...] [options]\n\
147 Options:\n\
148     -f file      Configuration file (default " CFG_FILE ")\n\
149     -c           Check configuration file for errors\n\
150     -l address   Listen on the specified address/interface (multiple -l\n\
151                   mean listening on more addresses).  The address format is\n\
152                   [proto:]addr[:port], where proto=udp|tcp and \n\
153                   addr= host|ip_address|interface_name. E.g: -l locahost, \n\
154                   -l udp:127.0.0.1:5080, -l eth0:5062 The default behavior\n\
155                   is to listen on all the interfaces.\n\
156     -n processes Number of child processes to fork per interface\n\
157                   (default: 8)\n\
158     -r           Use dns to check if is necessary to add a \"received=\"\n\
159                   field to a via\n\
160     -R           Same as `-r` but use reverse dns;\n\
161                   (to use both use `-rR`)\n\
162     -v           Turn on \"via:\" host checking when forwarding replies\n\
163     -d           Debugging mode (multiple -d increase the level)\n\
164     -D           Do not fork into daemon mode\n\
165     -E           Log to stderr\n"
166 #ifdef USE_TCP
167 "    -T           Disable tcp\n\
168     -N           Number of tcp child processes (default: equal to `-n`)\n\
169     -W           poll method\n"
170 #endif
171 "    -V           Version number\n\
172     -h           This help message\n\
173     -b nr        Maximum receive buffer size which will not be exceeded by\n\
174                   auto-probing procedure even if  OS allows\n\
175     -m nr        Size of shared memory allocated in Megabytes\n\
176     -w dir       Change the working directory to \"dir\" (default \"/\")\n\
177     -t dir       Chroot to \"dir\"\n\
178     -u uid       Change uid \n\
179     -g gid       Change gid \n\
180     -P file      Create a pid file\n\
181     -G file      Create a pgid file\n\
182     -i fifo_path Create a fifo (useful for monitoring " NAME ") \n\
183     -x socket    Create a unix domain socket \n"
184 #ifdef STATS
185 "    -s file     File to which statistics is dumped (disabled otherwise)\n"
186 #endif
187 ;
188
189 /* print compile-time constants */
190 void print_ct_constants()
191 {
192 #ifdef ADAPTIVE_WAIT
193         printf("ADAPTIVE_WAIT_LOOPS=%d, ", ADAPTIVE_WAIT_LOOPS);
194 #endif
195 /*
196 #ifdef SHM_MEM
197         printf("SHM_MEM_SIZE=%d, ", SHM_MEM_SIZE);
198 #endif
199 */
200         printf("MAX_RECV_BUFFER_SIZE %d, MAX_LISTEN %d,"
201                         " MAX_URI_SIZE %d, BUF_SIZE %d\n",
202                 MAX_RECV_BUFFER_SIZE, MAX_LISTEN, MAX_URI_SIZE, 
203                 BUF_SIZE );
204 #ifdef USE_TCP
205         printf("poll method support: %s.\n", poll_support);
206 #endif
207 }
208
209 /* debugging function */
210 /*
211 void receive_stdin_loop()
212 {
213         #define BSIZE 1024
214         char buf[BSIZE+1];
215         int len;
216
217         while(1){
218                 len=fread(buf,1,BSIZE,stdin);
219                 buf[len+1]=0;
220                 receive_msg(buf, len);
221                 printf("-------------------------\n");
222         }
223 }
224 */
225
226 /* global vars */
227
228 int own_pgid = 0; /* whether or not we have our own pgid (and it's ok
229                                          to use kill(0, sig) */
230 char* cfg_file = 0;
231 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
232                                                                                                   not want to exceed during the
233                                                                                                   auto-probing procedure; may 
234                                                                                                   be re-configured */
235 int children_no = 0;                    /* number of children processing requests */
236 #ifdef USE_TCP
237 int tcp_children_no = 0;
238 int tcp_disable = 0; /* 1 if tcp is disabled */
239 #endif
240 #ifdef USE_TLS
241 int tls_disable = 0; /* 1 if tls is disabled */
242 #endif
243 struct process_table *pt=0;             /*array with children pids, 0= main proc,
244                                                                         alloc'ed in shared mem if possible*/
245 int sig_flag = 0;              /* last signal received */
246 int debug = L_NOTICE;
247 int dont_fork = 0;
248 int log_stderr = 0;
249 /* log facility (see syslog(3)) */
250 int log_facility = LOG_DAEMON;
251 int config_check = 0;
252 /* check if reply first via host==us */
253 int check_via =  0;        
254 /* shall use stateful synonym branches? faster but not reboot-safe */
255 int syn_branch = 1;
256 /* debugging level for memory stats */
257 int memlog = L_DBG;
258 /* should replies include extensive warnings? by default yes,
259    good for trouble-shooting
260 */
261 int sip_warning = 1;
262 /* should localy-generated messages include server's signature?
263    be default yes, good for trouble-shooting
264 */
265 int server_signature=1;
266 /* should ser try to locate outbound interface on multihomed
267  * host? by default not -- too expensive
268  */
269 int mhomed=0;
270 /* use dns and/or rdns or to see if we need to add 
271    a ;received=x.x.x.x to via: */
272 int received_dns = 0;      
273 char* working_dir = 0;
274 char* chroot_dir = 0;
275 char* user=0;
276 char* group=0;
277 int uid = 0;
278 int gid = 0;
279 char* sock_user=0;
280 char* sock_group=0;
281 int sock_uid= -1;
282 int sock_gid= -1;
283 int sock_mode= S_IRUSR| S_IWUSR| S_IRGRP| S_IWGRP; /* rw-rw---- */
284
285 /* more config stuff */
286 int disable_core_dump=0; /* by default enabled */
287 int open_files_limit=-1; /* don't touch it by default */
288 /* a hint to reply modules whether they should send reply
289    to IP advertised in Via or IP from which a request came
290 */
291 int reply_to_via=0;
292
293 #ifdef USE_MCAST
294 int mcast_loopback = 0;
295 int mcast_ttl = -1; /* if -1, don't touch it, use the default (usually 1) */
296 #endif /* USE_MCAST */
297
298 int tos = IPTOS_LOWDELAY;
299
300 #if 0
301 char* names[MAX_LISTEN];              /* our names */
302 int names_len[MAX_LISTEN];            /* lengths of the names*/
303 struct ip_addr addresses[MAX_LISTEN]; /* our ips */
304 int addresses_no=0;                   /* number of names/ips */
305 #endif
306 struct socket_info* udp_listen=0;
307 #ifdef USE_TCP
308 struct socket_info* tcp_listen=0;
309 #endif
310 #ifdef USE_TLS
311 struct socket_info* tls_listen=0;
312 #endif
313 struct socket_info* bind_address=0; /* pointer to the crt. proc.
314                                                                          listening address*/
315 struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
316 struct socket_info* sendipv6; /* same as above for ipv6 */
317 #ifdef USE_TCP
318 struct socket_info* sendipv4_tcp; 
319 struct socket_info* sendipv6_tcp; 
320 #endif
321 #ifdef USE_TLS
322 struct socket_info* sendipv4_tls;
323 struct socket_info* sendipv6_tls;
324 #endif
325
326 unsigned short port_no=0; /* default port*/
327 #ifdef USE_TLS
328 unsigned short tls_port_no=0; /* default port */
329 #endif
330
331 struct host_alias* aliases=0; /* name aliases list */
332
333 /* ipc related globals */
334 int process_no = 0;
335 /* process_bm_t process_bit = 0; */
336 #ifdef ROUTE_SRV
337 #endif
338
339 /* cfg parsing */
340 int cfg_errors=0;
341
342 /* shared memory (in MB) */
343 unsigned long shm_mem_size=SHM_MEM_SIZE * 1024 * 1024;
344
345 /* export command-line to anywhere else */
346 int my_argc;
347 char **my_argv;
348
349 #define MAX_FD 32 /* maximum number of inherited open file descriptors,
350                     (normally it shouldn't  be bigger  than 3) */
351
352
353 extern FILE* yyin;
354 extern int yyparse();
355
356
357 int is_main=1; /* flag = is this the  "main" process? */
358
359 char* pid_file = 0; /* filename as asked by use */
360 char* pgid_file = 0;
361
362
363 /* call it before exiting; if show_status==1, mem status is displayed */
364 void cleanup(show_status)
365 {
366         /*clean-up*/
367         if (mem_lock) 
368                 shm_unlock(); /* hack: force-unlock the shared memory lock in case
369                                          some process crashed and let it locked; this will 
370                                          allow an almost gracious shutdown */
371         destroy_modules();
372 #ifdef USE_TCP
373         destroy_tcp();
374 #endif
375 #ifdef USE_TLS
376         destroy_tls();
377 #endif
378         destroy_timer();
379         close_unixsock_server();
380         destroy_fifo();
381         destroy_script_cb();
382 #ifdef PKG_MALLOC
383         if (show_status){
384                 LOG(memlog, "Memory status (pkg):\n");
385                 pkg_status();
386         }
387 #endif
388 #ifdef SHM_MEM
389         if (pt) shm_free(pt);
390         pt=0;
391         if (show_status){
392                         LOG(memlog, "Memory status (shm):\n");
393                         shm_status();
394         }
395         /* zero all shmem alloc vars that we still use */
396         shm_mem_destroy();
397 #endif
398         if (pid_file) unlink(pid_file);
399         if (pgid_file) unlink(pgid_file);
400 }
401
402
403 /* tries to send a signal to all our processes
404  * if daemonized  is ok to send the signal to all the process group,
405  * however if not daemonized we might end up sending the signal also
406  * to the shell which launched us => most signals will kill it if 
407  * it's not in interactive mode and we don't want this. The non-daemonized 
408  * case can occur when an error is encountered before daemonize is called 
409  * (e.g. when parsing the config file) or when ser is started in "dont-fork"
410  *  mode. Sending the signal to all the processes in pt[] will not work
411  *  for processes forked from modules (which have no correspondent entry in 
412  *  pt), but this can happen only in dont_fork mode (which is only for
413  *  debugging). So in the worst case + "dont-fork" we might leave some
414  *  zombies. -- andrei */
415 static void kill_all_children(int signum)
416 {
417         int r;
418
419         if (own_pgid) kill(0, signum);
420         else if (pt)
421                 for (r=1; r<process_count(); r++)
422                         if (pt[r].pid) kill(pt[r].pid, signum);
423 }
424
425
426
427 #ifdef USE_SIGACTION
428 static void (*set_sig_h(int sig, void (*handler) (int) ))(int)
429 {
430         struct sigaction act;
431         struct sigaction old;
432         
433         memset(&act, 0, sizeof(act));
434         act.sa_handler=handler;
435         /*
436         sigemptyset(&act.sa_mask);
437         act.sa_flags=0;
438         */
439         LOG(L_CRIT, "setting signal %d to %p\n", sig, handler);
440         /* sa_sigaction not set, we use sa_hanlder instead */ 
441         return (sigaction (sig, &act, &old)==-1)?SIG_ERR:old.sa_handler;
442 }
443 #else
444 #define set_sig_h signal
445 #endif
446
447
448
449 /* if this handler is called, a critical timeout has occured while
450  * waiting for the children to finish => we should kill everything and exit */
451 static void sig_alarm_kill(int signo)
452 {
453         kill_all_children(SIGKILL); /* this will kill the whole group
454                                                                   including "this" process;
455                                                                   for debugging replace with SIGABRT
456                                                                   (but warning: it might generate lots
457                                                                    of cores) */
458 }
459
460
461 /* like sig_alarm_kill, but the timeout has occured when cleaning up
462  * => try to leave a core for future diagnostics */
463 static void sig_alarm_abort(int signo)
464 {
465         /* LOG is not signal safe, but who cares, we are abort-ing anyway :-) */
466         LOG(L_CRIT, "BUG: shutdown timeout triggered, dying...");
467         abort();
468 }
469
470
471
472 void handle_sigs()
473 {
474         pid_t   chld;
475         int     chld_status;
476
477         switch(sig_flag){
478                 case 0: break; /* do nothing*/
479                 case SIGPIPE:
480                                 /* SIGPIPE might be rarely received on use of
481                                    exec module; simply ignore it
482                                  */
483                                 LOG(L_WARN, "WARNING: SIGPIPE received and ignored\n");
484                                 break;
485                 case SIGINT:
486                 case SIGTERM:
487                         /* we end the program in all these cases */
488                         if (sig_flag==SIGINT)
489                                 DBG("INT received, program terminates\n");
490                         else
491                                 DBG("SIGTERM received, program terminates\n");
492                                 
493                         /* first of all, kill the children also */
494                         kill_all_children(SIGTERM);
495
496                              /* Wait for all the children to die */
497                         while(wait(0) > 0);
498                         
499                         cleanup(1); /* cleanup & show status*/
500                         dprint("Thank you for flying " NAME "\n");
501                         exit(0);
502                         break;
503                         
504                 case SIGUSR1:
505 #ifdef STATS
506                         dump_all_statistic();
507 #endif
508 #ifdef PKG_MALLOC
509                         LOG(memlog, "Memory status (pkg):\n");
510                         pkg_status();
511 #endif
512 #ifdef SHM_MEM
513                         LOG(memlog, "Memory status (shm):\n");
514                         shm_status();
515 #endif
516                         break;
517                         
518                 case SIGCHLD:
519                         while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
520                                 if (WIFEXITED(chld_status)) 
521                                         LOG(L_INFO, "child process %d exited normally,"
522                                                         " status=%d\n", chld, 
523                                                         WEXITSTATUS(chld_status));
524                                 else if (WIFSIGNALED(chld_status)) {
525                                         LOG(L_INFO, "child process %d exited by a signal"
526                                                         " %d\n", chld, WTERMSIG(chld_status));
527 #ifdef WCOREDUMP
528                                         LOG(L_INFO, "core was %sgenerated\n",
529                                                          WCOREDUMP(chld_status) ?  "" : "not " );
530 #endif
531                                 }else if (WIFSTOPPED(chld_status)) 
532                                         LOG(L_INFO, "child process %d stopped by a"
533                                                                 " signal %d\n", chld,
534                                                                  WSTOPSIG(chld_status));
535                         }
536 #ifndef STOP_JIRIS_CHANGES
537                         if (dont_fork) {
538                                 LOG(L_INFO, "INFO: dont_fork turned on, living on\n");
539                                 break;
540                         } 
541                         LOG(L_INFO, "INFO: terminating due to SIGCHLD\n");
542 #endif
543                         /* exit */
544                         kill_all_children(SIGTERM);
545                         if (set_sig_h(SIGALRM, sig_alarm_kill) == SIG_ERR ) {
546                                 LOG(L_ERR, "ERROR: could not install SIGALARM handler\n");
547                                 /* continue, the process will die anyway if no
548                                  * alarm is installed which is exactly what we want */
549                         }
550                         alarm(60); /* 1 minute close timeout */
551                         while(wait(0) > 0); /* wait for all the children to terminate*/
552                         set_sig_h(SIGALRM, sig_alarm_abort);
553                         cleanup(1); /* cleanup & show status*/
554                         alarm(0);
555                         set_sig_h(SIGALRM, SIG_IGN);
556                         DBG("terminating due to SIGCHLD\n");
557                         exit(0);
558                         break;
559                 
560                 case SIGHUP: /* ignoring it*/
561                                         DBG("SIGHUP received, ignoring it\n");
562                                         break;
563                 default:
564                         LOG(L_CRIT, "WARNING: unhandled signal %d\n", sig_flag);
565         }
566         sig_flag=0;
567 }
568
569
570
571 /* added by jku; allows for regular exit on a specific signal;
572    good for profiling which only works if exited regularly and
573    not by default signal handlers
574     - modified by andrei: moved most of the stuff to handle_sigs, 
575        made it safer for the "fork" case
576 */
577 static void sig_usr(int signo)
578 {
579
580
581         if (is_main){
582                 if (sig_flag==0) sig_flag=signo;
583                 else /*  previous sig. not processed yet, ignoring? */
584                         return; ;
585                 if (dont_fork) 
586                                 /* only one proc, doing everything from the sig handler,
587                                 unsafe, but this is only for debugging mode*/
588                         handle_sigs();
589         }else{
590                 /* process the important signals */
591                 switch(signo){
592                         case SIGPIPE:
593                                         LOG(L_INFO, "INFO: signal %d received\n", signo);
594                                 break;
595                         case SIGINT:
596                         case SIGTERM:
597                                         LOG(L_INFO, "INFO: signal %d received\n", signo);
598                                         /* print memory stats for non-main too */
599                                         #ifdef PKG_MALLOC
600                                         LOG(memlog, "Memory status (pkg):\n");
601                                         pkg_status();
602                                         #endif
603                                         exit(0);
604                                         break;
605                         case SIGUSR1:
606                                 /* statistics, do nothing, printed only from the main proc */
607                                         break;
608                                 /* ignored*/
609                         case SIGUSR2:
610                         case SIGHUP:
611                                         break;
612                         case SIGCHLD:
613 #ifndef                         STOP_JIRIS_CHANGES
614                                         DBG("SIGCHLD received: "
615                                                 "we do not worry about grand-children\n");
616 #else
617                                         exit(0); /* terminate if one child died */
618 #endif
619                 }
620         }
621 }
622
623
624
625 /* install the signal handlers, returns 0 on success, -1 on error */
626 int install_sigs()
627 {
628         /* added by jku: add exit handler */
629         if (set_sig_h(SIGINT, sig_usr) == SIG_ERR ) {
630                 DPrint("ERROR: no SIGINT signal handler can be installed\n");
631                 goto error;
632         }
633         /* if we debug and write to a pipe, we want to exit nicely too */
634         if (set_sig_h(SIGPIPE, sig_usr) == SIG_ERR ) {
635                 DPrint("ERROR: no SIGINT signal handler can be installed\n");
636                 goto error;
637         }
638         if (set_sig_h(SIGUSR1, sig_usr)  == SIG_ERR ) {
639                 DPrint("ERROR: no SIGUSR1 signal handler can be installed\n");
640                 goto error;
641         }
642         if (set_sig_h(SIGCHLD , sig_usr)  == SIG_ERR ) {
643                 DPrint("ERROR: no SIGCHLD signal handler can be installed\n");
644                 goto error;
645         }
646         if (set_sig_h(SIGTERM , sig_usr)  == SIG_ERR ) {
647                 DPrint("ERROR: no SIGTERM signal handler can be installed\n");
648                 goto error;
649         }
650         if (set_sig_h(SIGHUP , sig_usr)  == SIG_ERR ) {
651                 DPrint("ERROR: no SIGHUP signal handler can be installed\n");
652                 goto error;
653         }
654         if (set_sig_h(SIGUSR2 , sig_usr)  == SIG_ERR ) {
655                 DPrint("ERROR: no SIGUSR2 signal handler can be installed\n");
656                 goto error;
657         }
658         return 0;
659 error:
660         return -1;
661 }
662
663
664
665 /* converts a username into uid:gid,
666  * returns -1 on error & 0 on success */
667 static int user2uid(int* uid, int* gid, char* user)
668 {
669         char* tmp;
670         struct passwd *pw_entry;
671         
672         if (user){
673                 *uid=strtol(user, &tmp, 10);
674                 if ((tmp==0) ||(*tmp)){
675                         /* maybe it's a string */
676                         pw_entry=getpwnam(user);
677                         if (pw_entry==0){
678                                 goto error;
679                         }
680                         *uid=pw_entry->pw_uid;
681                         if (gid) *gid=pw_entry->pw_gid;
682                 }
683                 return 0;
684         }
685 error:
686         return -1;
687 }
688
689
690
691 /* converts a group name into a gid
692  * returns -1 on error, 0 on success */
693 static int group2gid(int* gid, char* group)
694 {
695         char* tmp;
696         struct group  *gr_entry;
697         
698         if (group){
699                 *gid=strtol(group, &tmp, 10);
700                 if ((tmp==0) ||(*tmp)){
701                         /* maybe it's a string */
702                         gr_entry=getgrnam(group);
703                         if (gr_entry==0){
704                                 goto error;
705                         }
706                         *gid=gr_entry->gr_gid;
707                 }
708                 return 0;
709         }
710 error:
711         return -1;
712 }
713
714
715
716 /* returns -1 on error, 0 on success
717  * sets proto */
718 static int parse_proto(unsigned char* s, long len, int* proto)
719 {
720 #define PROTO2UINT(a, b, c) ((  (((unsigned int)(a))<<16)+ \
721                                                                 (((unsigned int)(b))<<8)+  \
722                                                                 ((unsigned int)(c)) ) | 0x20202020)
723         unsigned int i;
724         if (len!=3) return -1;
725         i=PROTO2UINT(s[0], s[1], s[2]);
726         switch(i){
727                 case PROTO2UINT('u', 'd', 'p'):
728                         *proto=PROTO_UDP;
729                         break;
730 #ifdef USE_TCP
731                 case PROTO2UINT('t', 'c', 'p'):
732                         *proto=PROTO_TCP;
733                         break;
734 #ifdef USE_TLS
735                 case PROTO2UINT('t', 'l', 's'):
736                         *proto=PROTO_TLS;
737                         break;
738 #endif
739 #endif
740                 default:
741                         return -1;
742         }
743         return 0;
744 }
745
746
747
748 /*
749  * parses [proto:]host[:port]
750  * where proto= udp|tcp|tls
751  * returns 0 on success and -1 on failure
752  */
753 static int parse_phostport(char* s, char** host, int* hlen, int* port,
754                                                         int* proto)
755 {
756         char* first; /* first ':' occurrence */
757         char* second; /* second ':' occurrence */
758         char* p;
759         int bracket;
760         char* tmp;
761         
762         first=second=0;
763         bracket=0;
764         
765         /* find the first 2 ':', ignoring possible ipv6 addresses
766          * (substrings between [])
767          */
768         for(p=s; *p; p++){
769                 switch(*p){
770                         case '[':
771                                 bracket++;
772                                 if (bracket>1) goto error_brackets;
773                                 break;
774                         case ']':
775                                 bracket--;
776                                 if (bracket<0) goto error_brackets;
777                                 break;
778                         case ':':
779                                 if (bracket==0){
780                                         if (first==0) first=p;
781                                         else if( second==0) second=p;
782                                         else goto error_colons;
783                                 }
784                                 break;
785                 }
786         }
787         if (p==s) return -1;
788         if (*(p-1)==':') goto error_colons;
789         
790         if (first==0){ /* no ':' => only host */
791                 *host=s;
792                 *hlen=(int)(p-s);
793                 *port=0;
794                 *proto=0;
795                 return 0;
796         }
797         if (second){ /* 2 ':' found => check if valid */
798                 if (parse_proto((unsigned char*)s, first-s, proto)<0) goto error_proto;
799                 *port=strtol(second+1, &tmp, 10);
800                 if ((tmp==0)||(*tmp)||(tmp==second+1)) goto error_port;
801                 *host=first+1;
802                 *hlen=(int)(second-*host);
803                 return 0;
804         }
805         /* only 1 ':' found => it's either proto:host or host:port */
806         *port=strtol(first+1, &tmp, 10);
807         if ((tmp==0)||(*tmp)||(tmp==first+1)){
808                 /* invalid port => it's proto:host */
809                 if (parse_proto((unsigned char*)s, first-s, proto)<0) goto error_proto;
810                 *port=0;
811                 *host=first+1;
812                 *hlen=(int)(p-*host);
813         }else{
814                 /* valid port => its host:port */
815                 *proto=0;
816                 *host=s;
817                 *hlen=(int)(first-*host);
818         }
819         return 0;
820 error_brackets:
821         LOG(L_ERR, "ERROR: parse_phostport: too many brackets in %s\n", s);
822         return -1;
823 error_colons:
824         LOG(L_ERR, "ERROR: parse_phostport: too many colons in %s\n", s);
825         return -1;
826 error_proto:
827         LOG(L_ERR, "ERROR: parse_phostport: bad protocol in %s\n", s);
828         return -1;
829 error_port:
830         LOG(L_ERR, "ERROR: parse_phostport: bad port number in %s\n", s);
831         return -1;
832 }
833
834
835
836 /* main loop */
837 int main_loop()
838 {
839         int  i;
840         pid_t pid;
841         struct socket_info* si;
842 #ifdef USE_TCP
843         int sockfd[2];
844 #endif
845 #ifdef DEBUG
846         int r;
847 #endif
848
849         /* one "main" process and n children handling i/o */
850
851         is_main=0;
852         if (dont_fork){
853 #ifdef STATS
854                 setstats( 0 );
855 #endif
856                 if (udp_listen==0){
857                         LOG(L_ERR, "ERROR: no fork mode requires at least one"
858                                         " udp listen address, exiting...\n");
859                         goto error;
860                 }
861                 /* only one address, we ignore all the others */
862                 if (udp_init(udp_listen)==-1) goto error;
863                 bind_address=udp_listen;
864                 sendipv4=bind_address;
865                 sendipv6=bind_address; /*FIXME*/
866                 if (udp_listen->next){
867                         LOG(L_WARN, "WARNING: using only the first listen address"
868                                                 " (no fork)\n");
869                 }
870                 /* initialize fifo server -- we need to open the fifo before
871                  * do_suid() and start the fifo server after all the socket 
872                  * are initialized, to inherit them*/
873                 if (init_fifo_server()<0) {
874                         LOG(L_ERR, "initializing fifo server failed\n");
875                         goto error;
876                 }
877                  /* Initialize Unix domain socket server */
878                 if (init_unixsock_socket()<0) {
879                         LOG(L_ERR, "Error while creating unix domain sockets\n");
880                         goto error;
881                 }
882                 if (do_suid()==-1) goto error; /* try to drop privileges */
883                 /* process_no now initialized to zero -- increase from now on
884                    as new processes are forked (while skipping 0 reserved for main 
885                 */
886
887                 /* we need another process to act as the timer*/
888 #ifdef USE_TCP
889                 /* if we are using tcp we always need a timer process,
890                  * we cannot count on select timeout to measure time
891                  * (it works only on linux)
892                  */
893                 if ((!tcp_disable)||(timer_list))
894 #else
895                 if (timer_list)
896 #endif
897                 {
898                                 process_no++;
899                                 if ((pid=fork())<0){
900                                         LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
901                                         goto error;
902                                 }
903                                 
904                                 if (pid==0){
905                                         /* child */
906                                         /* record pid twice to avoid the child using it, before
907                                          * parent gets a chance to set it*/
908                                         pt[process_no].pid=getpid();
909                                         /* timer!*/
910                                         /* process_bit = 0; */
911                                         if (init_child(PROC_TIMER) < 0) {
912                                                 LOG(L_ERR, "timer: init_child failed\n");
913                                                 goto error;
914                                         }
915                                         for(;;){
916                                                 sleep(TIMER_TICK);
917                                                 timer_ticker();
918                                         }
919                                 }else{
920                                                 pt[process_no].pid=pid; /*should be shared mem anyway*/
921                                                 strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
922                                 }
923                 }
924
925                 /* if configured, start a server for accepting FIFO commands,
926                  * we need to do it after all the sockets are initialized, to 
927                  * inherit them*/
928                 if (start_fifo_server()<0) {
929                         LOG(L_ERR, "starting fifo server failed\n");
930                         goto error;
931                 }
932
933                 if (init_unixsock_children()<0) {
934                         LOG(L_ERR, "Error while initializing Unix domain socket server\n");
935                         goto error;
936                 }
937
938                 /* main process, receive loop */
939                 process_no=0; /*main process number*/
940                 pt[process_no].pid=getpid();
941                 snprintf(pt[process_no].desc, MAX_PT_DESC, 
942                         "stand-alone receiver @ %s:%s", 
943                          bind_address->name.s, bind_address->port_no_str.s );
944                 
945                 
946                      /* We will call child_init even if we
947                       * do not fork - and it will be called with rank 1 because
948                       * in fact we behave like a child, not like main process
949                       */
950
951                 if (init_child(1) < 0) {
952                         LOG(L_ERR, "main_dontfork: init_child failed\n");
953                         goto error;
954                 }
955
956                 is_main=1; /* hack 42: call init_child with is_main=0 in case
957                                          some modules wants to fork a child */
958                 
959                 return udp_rcv_loop();
960         }else{
961                 /* process_no now initialized to zero -- increase from now on
962                    as new processes are forked (while skipping 0 reserved for main )
963                 */
964
965                 for(si=udp_listen;si;si=si->next){
966                         /* create the listening socket (for each address)*/
967                         /* udp */
968                         if (udp_init(si)==-1) goto error;
969                         /* get first ipv4/ipv6 socket*/
970                         if ((si->address.af==AF_INET)&&
971                                         ((sendipv4==0)||(sendipv4->flags&SI_IS_LO)))
972                                 sendipv4=si;
973         #ifdef USE_IPV6
974                         if((sendipv6==0)&&(si->address.af==AF_INET6))
975                                 sendipv6=si;
976         #endif
977                 }
978 #ifdef USE_TCP
979                 if (!tcp_disable){
980                         for(si=tcp_listen; si; si=si->next){
981                                 /* same thing for tcp */
982                                 if (tcp_init(si)==-1)  goto error;
983                                 /* get first ipv4/ipv6 socket*/
984                                 if ((si->address.af==AF_INET)&&
985                                                 ((sendipv4_tcp==0)||(sendipv4_tcp->flags&SI_IS_LO)))
986                                         sendipv4_tcp=si;
987                 #ifdef USE_IPV6
988                                 if((sendipv6_tcp==0)&&(si->address.af==AF_INET6))
989                                         sendipv6_tcp=si;
990                 #endif
991                         }
992                 }
993 #ifdef USE_TLS
994                 if (!tls_disable){
995                         for(si=tls_listen; si; si=si->next){
996                                 /* same as for tcp*/
997                                 if (tls_init(si)==-1)  goto error;
998                                 /* get first ipv4/ipv6 socket*/
999                                 if ((si->address.af==AF_INET)&&
1000                                                 ((sendipv4_tls==0)||(sendipv4_tls->flags&SI_IS_LO)))
1001                                         sendipv4_tls=si;
1002                 #ifdef USE_IPV6
1003                                 if((sendipv6_tls==0)&&(si->address.af==AF_INET6))
1004                                         sendipv6_tls=si;
1005                 #endif
1006                         }
1007                 }
1008 #endif /* USE_TLS */
1009 #endif /* USE_TCP */
1010
1011                 /* initialize fifo server -- we need to open the fifo before
1012                  * do_suid() and start the fifo server after all the socket 
1013                  * are initialized, to inherit them*/
1014                 if (init_fifo_server()<0) {
1015                         LOG(L_ERR, "initializing fifo server failed\n");
1016                         goto error;
1017                 }
1018                  /* Initialize Unix domain socket server */
1019                      /* Create the unix domain sockets */
1020                 if (init_unixsock_socket()<0) {
1021                         LOG(L_ERR, "ERROR: Could not create unix domain sockets\n");
1022                         goto error;
1023                 }
1024
1025                         /* all processes should have access to all the sockets (for sending)
1026                          * so we open all first*/
1027                 if (do_suid()==-1) goto error; /* try to drop privileges */
1028
1029                 /* if configured, start a server for accepting FIFO commands,
1030                  * we need to do it after all the sockets are initialized, to 
1031                  * inherit them*/
1032                 if (start_fifo_server()<0) {
1033                         LOG(L_ERR, "starting fifo server failed\n");
1034                         goto error;
1035                 }
1036                      /* Spawn children listening on unix domain socket if and only if
1037                       * the unix domain socket server has not been disabled (i == 0)
1038                       */
1039                 if (init_unixsock_children()<0) {
1040                         LOG(L_ERR, "ERROR: Could not initialize unix domain socket server\n");
1041                         goto error;
1042                 }
1043
1044                 /* udp processes */
1045                 for(si=udp_listen; si; si=si->next){
1046                         for(i=0;i<children_no;i++){
1047                                 process_no++;
1048 #ifdef USE_TCP
1049                                 if(!tcp_disable){
1050                                         if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
1051                                                 LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
1052                                                         strerror(errno));
1053                                                 goto error;
1054                                         }
1055                                 }
1056 #endif
1057                                 if ((pid=fork())<0){
1058                                         LOG(L_CRIT,  "main_loop: Cannot fork\n");
1059                                         goto error;
1060                                 }else if (pid==0){
1061                                              /* child */
1062 #ifdef USE_TCP
1063                                         if (!tcp_disable){
1064                                                 close(sockfd[0]);
1065                                                 unix_tcp_sock=sockfd[1];
1066                                         }
1067 #endif
1068                                         /* record pid twice to avoid the child using it, before
1069                                          * parent gets a chance to set it*/
1070                                         pt[process_no].pid=getpid();
1071                                         bind_address=si; /* shortcut */
1072                                         if (init_child(i + 1) < 0) {
1073                                                 LOG(L_ERR, "init_child failed\n");
1074                                                 goto error;
1075                                         }
1076 #ifdef STATS
1077                                         setstats( i+r*children_no );
1078 #endif
1079                                         return udp_rcv_loop();
1080                                 }else{
1081                                                 pt[process_no].pid=pid; /*should be in shared mem.*/
1082                                                 snprintf(pt[process_no].desc, MAX_PT_DESC,
1083                                                         "receiver child=%d sock= %s:%s", i,     
1084                                                         si->name.s, si->port_no_str.s );
1085 #ifdef USE_TCP
1086                                                 if (!tcp_disable){
1087                                                         close(sockfd[1]);
1088                                                         pt[process_no].unix_sock=sockfd[0];
1089                                                         pt[process_no].idx=-1; /* this is not a "tcp"
1090                                                                                                           process*/
1091                                                 }
1092 #endif
1093                                 }
1094                         }
1095                         /*parent*/
1096                         /*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
1097                 }
1098         }
1099
1100         /*this is the main process*/
1101         bind_address=0;                         /* main proc -> it shouldn't send anything, */
1102         
1103
1104 #ifdef USE_TCP
1105         /* if we are using tcp we always need the timer */
1106         if ((!tcp_disable)||(timer_list))
1107 #else
1108         if (timer_list)
1109 #endif
1110         {
1111 #ifdef USE_TCP
1112                 if (!tcp_disable){
1113                         if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
1114                                 LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
1115                                         strerror(errno));
1116                                 goto error;
1117                         }
1118                 }
1119 #endif
1120                 /* fork again for the attendant process*/
1121                 process_no++;
1122                 if ((pid=fork())<0){
1123                         LOG(L_CRIT, "main_loop: cannot fork timer process\n");
1124                         goto error;
1125                 }else if (pid==0){
1126                         /* child */
1127                         /* is_main=0; */
1128 #ifdef USE_TCP
1129                         if (!tcp_disable){
1130                                 close(sockfd[0]);
1131                                 unix_tcp_sock=sockfd[1];
1132                         }
1133 #endif
1134                         /* record pid twice to avoid the child using it, before
1135                          * parent gets a chance to set it*/
1136                         pt[process_no].pid=getpid();
1137                         if (init_child(PROC_TIMER) < 0) {
1138                                 LOG(L_ERR, "timer: init_child failed\n");
1139                                 goto error;
1140                         }
1141                         
1142                         for(;;){
1143                                 /* debug:  instead of doing something useful */
1144                                 /* (placeholder for timers, etc.) */
1145                                 sleep(TIMER_TICK);
1146                                 /* if we received a signal => TIMER_TICK may have not elapsed*/
1147                                 timer_ticker();
1148                         }
1149                 }else{
1150                         pt[process_no].pid=pid;
1151                         strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
1152 #ifdef USE_TCP
1153                         if(!tcp_disable){
1154                                                 close(sockfd[1]);
1155                                                 pt[process_no].unix_sock=sockfd[0];
1156                                                 pt[process_no].idx=-1; /* this is not a "tcp" process*/
1157                         }
1158 #endif
1159                 }
1160         }
1161 #ifdef USE_TCP
1162                 if (!tcp_disable){
1163                                 /* start tcp  & tls receivers */
1164                         if (tcp_init_children()<0) goto error;
1165                                 /* start tcp+tls master proc */
1166                         process_no++;
1167                         if ((pid=fork())<0){
1168                                 LOG(L_CRIT, "main_loop: cannot fork tcp main process\n");
1169                                 goto error;
1170                         }else if (pid==0){
1171                                 /* child */
1172                                 /* is_main=0; */
1173                                 /* record pid twice to avoid the child using it, before
1174                                  * parent gets a chance to set it*/
1175                                 pt[process_no].pid=getpid();
1176                                 if (init_child(PROC_TCP_MAIN) < 0) {
1177                                         LOG(L_ERR, "tcp_main: error in init_child\n");
1178                                         goto error;
1179                                 }
1180                                 tcp_main_loop();
1181                         }else{
1182                                 pt[process_no].pid=pid;
1183                                 strncpy(pt[process_no].desc, "tcp main process", MAX_PT_DESC );
1184                                 pt[process_no].unix_sock=-1;
1185                                 pt[process_no].idx=-1; /* this is not a "tcp" process*/
1186                                 unix_tcp_sock=-1;
1187                         }
1188                 }
1189 #endif
1190         /* main */
1191         pt[0].pid=getpid();
1192         strncpy(pt[0].desc, "attendant", MAX_PT_DESC );
1193 #ifdef USE_TCP
1194         if(!tcp_disable){
1195                 pt[process_no].unix_sock=-1;
1196                 pt[process_no].idx=-1; /* this is not a "tcp" process*/
1197                 unix_tcp_sock=-1;
1198         }
1199 #endif
1200         /*DEBUG- remove it*/
1201 #ifdef DEBUG
1202         fprintf(stderr, "\n% 3d processes (%3d), % 3d children * "
1203                         "listening addresses + tcp listeners + tls listeners"
1204                         "+ main + fifo %s\n", process_no+1, process_count(), children_no,
1205                         (timer_list)?"+ timer":"");
1206         for (r=0; r<=process_no; r++){
1207                 fprintf(stderr, "% 3d   % 5d - %s\n", r, pt[r].pid, pt[r].desc);
1208         }
1209 #endif
1210         process_no=0; 
1211         /* process_bit = 0; */
1212         is_main=1;
1213         
1214         if (init_child(PROC_MAIN) < 0) {
1215                 LOG(L_ERR, "main: error in init_child\n");
1216                 goto error;
1217         }
1218         for(;;){
1219                         pause();
1220                         handle_sigs();
1221         }
1222         
1223         
1224         /*return 0; */
1225  error:
1226         is_main=1;  /* if we are here, we are the "main process",
1227                                   any forked children should exit with exit(-1) and not
1228                                   ever use return */
1229         return -1;
1230
1231 }
1232
1233
1234
1235
1236 int main(int argc, char** argv)
1237 {
1238
1239         FILE* cfg_stream;
1240         int c,r;
1241         char *tmp;
1242         int tmp_len;
1243         int port;
1244         int proto;
1245         char *options;
1246         int ret;
1247         unsigned int seed;
1248         int rfd;
1249
1250         /*init*/
1251         ret=-1;
1252         my_argc=argc; my_argv=argv;
1253         
1254         /*init pkg mallocs (before parsing cfg or cmd line !)*/
1255         if (init_pkg_mallocs()==-1)
1256                 goto error;
1257
1258 #ifdef DBG_MSG_QA
1259         fprintf(stderr, "WARNING: ser startup: "
1260                 "DBG_MSG_QA enabled, ser may exit abruptly\n");
1261 #endif
1262
1263
1264
1265         /* process command line (get port no, cfg. file path etc) */
1266         opterr=0;
1267         options=
1268 #ifdef STATS
1269         "s:"
1270 #endif
1271         "f:cm:b:l:n:N:rRvdDETVhw:t:u:g:P:G:i:x:W:";
1272         
1273         while((c=getopt(argc,argv,options))!=-1){
1274                 switch(c){
1275                         case 'f':
1276                                         cfg_file=optarg;
1277                                         break;
1278                         case 'c':
1279                                         config_check=1;
1280                                         log_stderr=1; /* force stderr logging */
1281                                         break;
1282                         case 's':
1283                                 #ifdef STATS
1284                                         stat_file=optarg;
1285                                 #endif
1286                                         break;
1287                         case 'm':
1288                                         shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
1289                                         if (tmp &&(*tmp)){
1290                                                 fprintf(stderr, "bad shmem size number: -m %s\n",
1291                                                                                 optarg);
1292                                                 goto error;
1293                                         };
1294                                         LOG(L_INFO, "ser: shared memory: %ld bytes\n",
1295                                                                         shm_mem_size );
1296                                         break;
1297
1298                         case 'b':
1299                                         maxbuffer=strtol(optarg, &tmp, 10);
1300                                         if (tmp &&(*tmp)){
1301                                                 fprintf(stderr, "bad max buffer size number: -p %s\n",
1302                                                                                         optarg);
1303                                                 goto error;
1304                                         }
1305                                         break;
1306                         case 'l':
1307                                         if (parse_phostport(optarg, &tmp, &tmp_len,
1308                                                                                         &port, &proto)<0){
1309                                                 fprintf(stderr, "bad -l address specifier: %s\n",
1310                                                                                 optarg);
1311                                                 goto error;
1312                                         }
1313                                         tmp[tmp_len]=0; /* null terminate the host */
1314                                         /* add a new addr. to our address list */
1315                                         if (add_listen_iface(tmp, port, proto, 0)!=0){
1316                                                 fprintf(stderr, "failed to add new listen address\n");
1317                                                 goto error;
1318                                         }
1319                                         break;
1320                         case 'n':
1321                                         children_no=strtol(optarg, &tmp, 10);
1322                                         if ((tmp==0) ||(*tmp)){
1323                                                 fprintf(stderr, "bad process number: -n %s\n",
1324                                                                         optarg);
1325                                                 goto error;
1326                                         }
1327                                         break;
1328                         case 'v':
1329                                         check_via=1;
1330                                         break;
1331                         case 'r':
1332                                         received_dns|=DO_DNS;
1333                                         break;
1334                         case 'R':
1335                                         received_dns|=DO_REV_DNS;
1336                         case 'd':
1337                                         debug++;
1338                                         break;
1339                         case 'D':
1340                                         dont_fork=1;
1341                                         break;
1342                         case 'E':
1343                                         log_stderr=1;
1344                                         break;
1345                         case 'T':
1346 #ifdef USE_TCP
1347                                         tcp_disable=1;
1348 #else
1349                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
1350 #endif
1351                                         break;
1352                         case 'N':
1353 #ifdef USE_TCP
1354                                         tcp_children_no=strtol(optarg, &tmp, 10);
1355                                         if ((tmp==0) ||(*tmp)){
1356                                                 fprintf(stderr, "bad process number: -N %s\n",
1357                                                                         optarg);
1358                                                 goto error;
1359                                         }
1360 #else
1361                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
1362 #endif
1363                                         break;
1364                         case 'W':
1365 #ifdef USE_TCP
1366                                         tcp_poll_method=get_poll_type(optarg);
1367                                         if (tcp_poll_method==POLL_NONE){
1368                                                 fprintf(stderr, "bad poll method name: -W %s\ntry "
1369                                                                                 "one of %s.\n", optarg, poll_support);
1370                                                 goto error;
1371                                         }
1372 #else
1373                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
1374 #endif
1375                                         break;
1376                         case 'V':
1377                                         printf("version: %s\n", version);
1378                                         printf("flags: %s\n", flags );
1379                                         print_ct_constants();
1380                                         printf("%s\n",id);
1381                                         printf("%s compiled on %s with %s\n", __FILE__,
1382                                                         compiled, COMPILER );
1383                                         
1384                                         exit(0);
1385                                         break;
1386                         case 'h':
1387                                         printf("version: %s\n", version);
1388                                         printf("%s",help_msg);
1389                                         exit(0);
1390                                         break;
1391                         case 'w':
1392                                         working_dir=optarg;
1393                                         break;
1394                         case 't':
1395                                         chroot_dir=optarg;
1396                                         break;
1397                         case 'u':
1398                                         user=optarg;
1399                                         break;
1400                         case 'g':
1401                                         group=optarg;
1402                                         break;
1403                         case 'P':
1404                                         pid_file=optarg;
1405                                         break;
1406                         case 'G':
1407                                         pgid_file=optarg;
1408                                         break;
1409                         case 'i':
1410                                         fifo=optarg;
1411                                         break;
1412                         case 'x':
1413                                         unixsock_name=optarg;
1414                                         break;
1415                         case '?':
1416                                         if (isprint(optopt))
1417                                                 fprintf(stderr, "Unknown option `-%c´.\n", optopt);
1418                                         else
1419                                                 fprintf(stderr, 
1420                                                                 "Unknown option character `\\x%x´.\n",
1421                                                                 optopt);
1422                                         goto error;
1423                         case ':':
1424                                         fprintf(stderr, 
1425                                                                 "Option `-%c´ requires an argument.\n",
1426                                                                 optopt);
1427                                         goto error;
1428                         default:
1429                                         abort();
1430                 }
1431         }
1432         
1433         /* fill missing arguments with the default values*/
1434         if (cfg_file==0) cfg_file=CFG_FILE;
1435
1436         /* load config file or die */
1437         cfg_stream=fopen (cfg_file, "r");
1438         if (cfg_stream==0){
1439                 fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file,
1440                                 strerror(errno));
1441                 goto error;
1442         }
1443
1444         /* seed the prng */
1445         /* try to use /dev/urandom if possible */
1446         seed=0;
1447         if ((rfd=open("/dev/urandom", O_RDONLY))!=-1){
1448 try_again:
1449                 if (read(rfd, (void*)&seed, sizeof(seed))==-1){
1450                         if (errno==EINTR) goto try_again; /* interrupted by signal */
1451                         LOG(L_WARN, "WARNING: could not read from /dev/urandom (%d)\n",
1452                                                 errno);
1453                 }
1454                 DBG("read %u from /dev/urandom\n", seed);
1455                         close(rfd);
1456         }else{
1457                 LOG(L_WARN, "WARNING: could not open /dev/urandom (%d)\n", errno);
1458         }
1459         seed+=getpid()+time(0);
1460         DBG("seeding PRNG with %u\n", seed);
1461         srand(seed);
1462         DBG("test random number %u\n", rand());
1463         
1464         
1465         
1466         /* register a diagnostic FIFO command  - moved to fifo server - bogdan
1467         if (register_core_fifo()<0) {
1468                 LOG(L_CRIT, "unable to register core FIFO commands\n");
1469                 goto error;
1470         }*/
1471
1472         /*register builtin  modules*/
1473         register_builtin_modules();
1474
1475         yyin=cfg_stream;
1476         if ((yyparse()!=0)||(cfg_errors)){
1477                 fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors);
1478                 goto error;
1479         }
1480         
1481         
1482         
1483         print_rl();
1484         
1485         /* init the resolver, before fixing the config */
1486         resolv_init();
1487         /* fix parameters */
1488         if (port_no<=0) port_no=SIP_PORT;
1489 #ifdef USE_TLS
1490         if (tls_port_no<=0) tls_port_no=SIPS_PORT;
1491 #endif
1492         
1493         
1494         if (children_no<=0) children_no=CHILD_NO;
1495 #ifdef USE_TCP
1496         if (!tcp_disable){
1497                 if (tcp_children_no<=0) tcp_children_no=children_no;
1498         }
1499 #endif
1500         
1501         if (working_dir==0) working_dir="/";
1502         
1503         /* get uid/gid */
1504         if (user){
1505                 if (user2uid(&uid, &gid, user)<0){
1506                         fprintf(stderr, "bad user name/uid number: -u %s\n", user);
1507                         goto error;
1508                 }
1509         }
1510         if (group){
1511                 if (group2gid(&gid, group)<0){
1512                                 fprintf(stderr, "bad group name/gid number: -u %s\n", group);
1513                         goto error;
1514                 }
1515         }
1516         /* fix sock/fifo uid/gid */
1517         if (sock_user){
1518                 if (user2uid(&sock_uid, 0, sock_user)<0){
1519                         fprintf(stderr, "bad socket user name/uid number %s\n", user);
1520                         goto error;
1521                 }
1522         }
1523         if (sock_group){
1524                 if (group2gid(&sock_gid, sock_group)<0){
1525                         fprintf(stderr, "bad group name/gid number: -u %s\n", group);
1526                         goto error;
1527                 }
1528         }
1529         if (fix_all_socket_lists()!=0){
1530                 fprintf(stderr,  "failed to initialize list addresses\n");
1531                 goto error;
1532         }
1533         /* print all the listen addresses */
1534         printf("Listening on \n");
1535         print_all_socket_lists();
1536         printf("Aliases: \n");
1537         /*print_aliases();*/
1538         print_aliases();
1539         printf("\n");
1540         
1541         if (dont_fork){
1542                 fprintf(stderr, "WARNING: no fork mode %s\n", 
1543                                 (udp_listen)?(
1544                                 (udp_listen->next)?" and more than one listen address found"
1545                                 "(will use only the the first one)":""
1546                                 ):"and no udp listen address found" );
1547         }
1548         if (config_check){
1549                 fprintf(stderr, "config file ok, exiting...\n");
1550                 goto error;
1551         }
1552
1553
1554         /*init shm mallocs
1555          *  this must be here 
1556          *     -to allow setting shm mem size from the command line
1557          *       => if shm_mem should be settable from the cfg file move
1558          *       everything after
1559          *     -it must be also before init_timer and init_tcp
1560          *     -it must be after we know uid (so that in the SYSV sems case,
1561          *        the sems will have the correct euid)
1562          * --andrei */
1563         if (init_shm_mallocs()==-1)
1564                 goto error;
1565         /*init timer, before parsing the cfg!*/
1566         if (init_timer()<0){
1567                 LOG(L_CRIT, "could not initialize timer, exiting...\n");
1568                 goto error;
1569         }
1570         
1571         if (init_avps()<0) goto error;
1572
1573 #ifdef USE_TCP
1574         if (!tcp_disable){
1575                 /*init tcp*/
1576                 if (init_tcp()<0){
1577                         LOG(L_CRIT, "could not initialize tcp, exiting...\n");
1578                         goto error;
1579                 }
1580         }
1581 #ifdef USE_TLS
1582         if (!tls_disable){
1583                 /* init tls*/
1584                 if (init_tls()<0){
1585                         LOG(L_CRIT, "could not initialize tls, exiting...\n");
1586                         goto error;
1587                 }
1588         }
1589 #endif /* USE_TLS */
1590 #endif /* USE_TCP */
1591         /* init_daemon? */
1592         if (!dont_fork){
1593                 if ( daemonize(argv[0]) <0 ) goto error;
1594         }
1595         if (install_sigs() != 0){
1596                 fprintf(stderr, "ERROR: could not install the signal handlers\n");
1597                 goto error;
1598         }
1599         
1600         
1601         /*alloc pids*/
1602 #ifdef SHM_MEM
1603         pt=shm_malloc(sizeof(struct process_table)*process_count());
1604 #else
1605         pt=pkg_malloc(sizeof(struct process_table)*process_count());
1606 #endif
1607         if (pt==0){
1608                 fprintf(stderr, "ERROR: out  of memory\n");
1609                 goto error;
1610         }
1611         memset(pt, 0, sizeof(struct process_table)*process_count());
1612
1613         if (disable_core_dump) set_core_dump(0, 0);
1614         else set_core_dump(1, shm_mem_size+PKG_MEM_POOL_SIZE+4*1024*1024);
1615         if (open_files_limit>0){
1616                 if(increase_open_fds(open_files_limit)<0){ 
1617                         fprintf(stderr, "ERROR: error could not increase file limits\n");
1618                         goto error;
1619                 }
1620         }
1621         
1622         if (init_modules() != 0) {
1623                 fprintf(stderr, "ERROR: error while initializing modules\n");
1624                 goto error;
1625         }
1626         /* fix routing lists */
1627         if ( (r=fix_rls())!=0){
1628                 fprintf(stderr, "ERROR: error %d while trying to fix configuration\n",
1629                                                 r);
1630                 goto error;
1631         };
1632
1633 #ifdef STATS
1634         if (init_stats(  dont_fork ? 1 : children_no  )==-1) goto error;
1635 #endif
1636         
1637         ret=main_loop();
1638         /*kill everything*/
1639         kill_all_children(SIGTERM);
1640         /*clean-up*/
1641         cleanup(0);
1642         return ret;
1643
1644 error:
1645         /*kill everything*/
1646         kill_all_children(SIGTERM);
1647         /*clean-up*/
1648         cleanup(0);
1649         return -1;
1650
1651 }
1652