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