Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.sbin / i4b / isdnd / main.c
1 /*
2  * Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      i4b daemon - main program entry
28  *      -------------------------------
29  *
30  * $FreeBSD: src/usr.sbin/i4b/isdnd/main.c,v 1.8.2.5 2001/12/16 15:13:38 hm Exp $
31  * $DragonFly: src/usr.sbin/i4b/isdnd/main.c,v 1.2 2003/06/17 04:29:54 dillon Exp $
32  *
33  *      last edit-date: [Tue Jun  5 17:06:20 2001]
34  *
35  *---------------------------------------------------------------------------*/
36
37 #include <locale.h>
38 #include <paths.h>
39
40 #ifdef I4B_EXTERNAL_MONITOR
41 #include "monitor.h"
42 #endif
43
44 #define MAIN
45 #include "isdnd.h"
46 #undef MAIN
47
48 #ifdef I4B_EXTERNAL_MONITOR
49
50 #ifdef I4B_NOTCPIP_MONITOR
51 /* monitor via local socket */
52 static void mloop(int sockfd);
53 #else /* I4B_NOTCPIP_MONITOR */
54 /* monitor via local and tcp/ip socket */
55 static void mloop(int localsock, int remotesock);
56 #endif /* I4B_NOTCPIP_MONITOR */
57
58 #else /* I4B_EXTERNAL_MONITOR */
59 /* no monitoring at all */
60 static void mloop();
61 #endif /* I4B_EXTERNAL_MONITOR */
62
63 #ifdef USE_CURSES
64 static void kbdrdhdl(void);
65 #endif
66
67 static void isdnrdhdl(void);
68 static void usage(void);
69
70 #define MSG_BUF_SIZ     1024    /* message buffer size */
71
72 /*---------------------------------------------------------------------------*
73  *      usage display and exit
74  *---------------------------------------------------------------------------*/
75 static void
76 usage(void)
77 {
78         fprintf(stderr, "\n");
79         fprintf(stderr, "isdnd - i4b ISDN manager daemon, version %02d.%02d.%d, %s %s\n", VERSION, REL, STEP, __DATE__, __TIME__);
80 #ifdef DEBUG
81         fprintf(stderr, "  usage: isdnd [-c file] [-d level] [-F] [-f [-r dev] [-t termtype]]\n");
82 #else
83         fprintf(stderr, "  usage: isdnd [-c file] [-F] [-f [-r dev] [-t termtype]]\n");
84 #endif  
85         fprintf(stderr, "               [-l] [-L file] [-m] [-s facility] [-u time]\n");
86         fprintf(stderr, "    -c <filename> configuration file name (def: %s)\n", CONFIG_FILE_DEF);
87 #ifdef DEBUG
88         fprintf(stderr, "    -d <level>    set debug flag bits:\n");
89         fprintf(stderr, "                  general = 0x%04x, rates  = 0x%04x, timing   = 0x%04x\n", DL_MSG,   DL_RATES, DL_TIME);
90         fprintf(stderr, "                  state   = 0x%04x, retry  = 0x%04x, dial     = 0x%04x\n", DL_STATE, DL_RCVRY, DL_DIAL);
91         fprintf(stderr, "                  process = 0x%04x, kernio = 0x%04x, ctrlstat = 0x%04x\n", DL_PROC,  DL_DRVR,  DL_CNST);
92         fprintf(stderr, "                  rc-file = 0x%04x, budget = 0x%04x, valid    = 0x%04x\n", DL_RCCF,  DL_BDGT, DL_VALID);
93         fprintf(stderr, "    -dn           no debug output on fullscreen display\n");
94 #endif
95         fprintf(stderr, "    -f            fullscreen status display\n");
96         fprintf(stderr, "    -F            do not become a daemon process\n");
97         fprintf(stderr, "    -l            use a logfile instead of syslog\n");
98         fprintf(stderr, "    -L <file>     use file instead of %s for logging\n", LOG_FILE_DEF);
99         fprintf(stderr, "    -P            pretty print real config to stdout and exit\n");
100         fprintf(stderr, "    -r <device>   redirect output to other device    (for -f)\n");
101         fprintf(stderr, "    -s <facility> use facility instead of %d for syslog logging\n", LOG_LOCAL0 >> 3);
102         fprintf(stderr, "    -t <termtype> terminal type of redirected screen (for -f)\n");
103         fprintf(stderr, "    -u <time>     length of a charging unit in seconds\n");
104 #ifdef I4B_EXTERNAL_MONITOR
105         fprintf(stderr, "    -m            inhibit network/local monitoring (protocol %02d.%02d)\n", MPROT_VERSION, MPROT_REL);
106 #endif  
107         fprintf(stderr, "\n");
108         exit(1);
109 }
110
111 /*---------------------------------------------------------------------------*
112  *      program entry
113  *---------------------------------------------------------------------------*/
114 int
115 main(int argc, char **argv)
116 {
117         int i;
118         msg_vr_req_t mvr;
119         
120 #ifdef I4B_EXTERNAL_MONITOR
121         int sockfd = -1;                /* local monitor socket */
122 #ifndef I4B_NOTCPIP_MONITOR
123         int remotesockfd = -1;          /* tcp/ip monitor socket */
124 #endif
125 #endif
126
127         setlocale (LC_ALL, "");
128         
129         while ((i = getopt(argc, argv, "mc:d:fFlL:Pr:s:t:u:")) != -1)
130         {
131                 switch (i)
132                 {
133 #ifdef I4B_EXTERNAL_MONITOR
134                         case 'm':
135                                 inhibit_monitor = 1;
136                                 break;
137 #endif
138                                 
139                         case 'c':
140                                 configfile = optarg;
141                                 break;
142
143 #ifdef DEBUG                            
144                         case 'd':
145                                 if(*optarg == 'n')
146                                         debug_noscreen = 1;
147                                 else if((sscanf(optarg, "%i", &debug_flags)) == 1)
148                                         do_debug = 1;
149                                 else
150                                         usage();                                
151                                 break;
152 #endif
153
154                         case 'f':
155                                 do_fullscreen = 1;
156                                 do_fork = 0;                    
157 #ifndef USE_CURSES
158                                 fprintf(stderr, "Sorry, no fullscreen mode available - daemon compiled without USE_CURSES\n");
159                                 exit(1);
160 #endif
161                                 break;
162
163                         case 'F':
164                                 do_fork = 0;
165                                 break;
166
167                         case 'l':
168                                 uselogfile = 1;
169                                 break;
170
171                         case 'L':
172                                 strlcpy(logfile, optarg, sizeof(logfile));
173                                 break;
174
175                         case 'P':
176                                 do_print = 1;
177                                 break;
178
179                         case 'r':
180                                 rdev = optarg;
181                                 do_rdev = 1;
182                                 break;
183
184                         case 's':
185                                 if(isdigit(*optarg))
186                                 {
187                                         int facility;
188                                         logfacility = strtoul(optarg, NULL, 10);
189                                         facility = logfacility << 3;
190
191                                         if((facility < LOG_KERN) ||
192                                            (facility > LOG_FTP && facility < LOG_LOCAL0) ||
193                                            (facility > LOG_LOCAL7))
194                                         {
195                                                 fprintf(stderr, "Error, option -s has invalid logging facility %d", logfacility);
196                                                 usage();
197                                         }
198                                         logfacility = facility;
199                                 }
200                                 else
201                                 {
202                                         fprintf(stderr, "Error: option -s requires a numeric argument!\n");
203                                         usage();
204                                 }
205                                 break;
206
207                         case 't':
208                                 ttype = optarg;
209                                 do_ttytype = 1;
210                                 break;
211
212                         case 'u':
213                                 if(isdigit(*optarg))
214                                 {
215                                         unit_length = strtoul(optarg, NULL, 10);
216                                         if(unit_length < ULSRC_CMDLMIN)
217                                                 unit_length = ULSRC_CMDLMIN;
218                                         else if(unit_length > ULSRC_CMDLMAX)
219                                                 unit_length = ULSRC_CMDLMAX;
220                                         got_unitlen = 1;
221                                 }
222                                 else
223                                 {
224                                         fprintf(stderr, "Error: option -T requires a numeric argument!\n");
225                                         usage();
226                                 }
227                                 break;
228
229                         case '?':
230                         default:
231                                 usage();
232                                 break;
233                 }
234         }
235 #ifdef DEBUG
236         if(!do_debug)
237                 debug_noscreen = 0;
238 #endif
239
240         if(!do_print)
241         {
242                 umask(UMASK);   /* set our umask ... */ 
243         
244                 init_log();     /* initialize the logging subsystem */
245         }
246         
247         check_pid();    /* check if we are already running */
248
249         if(!do_print)
250         {
251                 if(do_fork || (do_fullscreen && do_rdev)) /* daemon mode ? */
252                         daemonize();
253         
254                 write_pid();    /* write our pid to file */
255                         
256                 /* set signal handler(s) */
257         
258                 signal(SIGCHLD, sigchild_handler); /* process handling  */
259                 signal(SIGHUP,  rereadconfig);  /* reread configuration */
260                 signal(SIGUSR1, reopenfiles);   /* reopen acct/log files*/
261                 signal(SIGPIPE, SIG_IGN);       /* handled manually     */
262                 signal(SIGINT,  do_exit);       /* clean up on SIGINT   */
263                 signal(SIGTERM, do_exit);       /* clean up on SIGTERM  */
264                 signal(SIGQUIT, do_exit);       /* clean up on SIGQUIT  */      
265         }
266
267         /* open isdn device */
268         
269         if((isdnfd = open(I4BDEVICE, O_RDWR)) < 0)
270         {
271                 log(LL_ERR, "main: cannot open %s: %s", I4BDEVICE, strerror(errno));
272                 exit(1);
273         }
274
275         /* check kernel and userland have same version/release numbers */
276         
277         if((ioctl(isdnfd, I4B_VR_REQ, &mvr)) < 0)
278         {
279                 log(LL_ERR, "main: ioctl I4B_VR_REQ failed: %s", strerror(errno));
280                 do_exit(1);
281         }
282
283         if(mvr.version != VERSION)
284         {
285                 log(LL_ERR, "main: version mismatch, kernel %d, daemon %d", mvr.version, VERSION);
286                 do_exit(1);
287         }
288
289         if(mvr.release != REL)
290         {
291                 log(LL_ERR, "main: release mismatch, kernel %d, daemon %d", mvr.release, REL);
292                 do_exit(1);
293         }
294
295         if(mvr.step != STEP)
296         {
297                 log(LL_ERR, "main: step mismatch, kernel %d, daemon %d", mvr.step, STEP);
298                 do_exit(1);
299         }
300
301         /* init controller state array */
302
303         init_controller();
304
305         /* read runtime configuration file and configure ourselves */
306         
307         configure(configfile, 0);
308
309         if(config_error_flag)
310         {
311                 log(LL_ERR, "there were %d error(s) in the configuration file, terminating!", config_error_flag);
312                 exit(1);
313         }
314
315         /* set controller ISDN protocol */
316         
317         init_controller_protocol();
318         
319         /* init active controllers, if any */
320         
321         signal(SIGCHLD, SIG_IGN);               /*XXX*/
322
323         init_active_controller();
324
325         signal(SIGCHLD, sigchild_handler);      /*XXX*/
326         
327         /* handle the rates stuff */
328         
329         if((i = readrates(ratesfile)) == ERROR)
330         {
331                 if(rate_error != NULL)
332                         log(LL_ERR, "%s", rate_error);
333                 exit(1);
334         }
335
336         if(i == GOOD)
337         {
338                 got_rate = 1;   /* flag, ratesfile read and ok */
339                 DBGL(DL_RCCF, (log(LL_DBG, "ratesfile %s read successfully", ratesfile)));
340         }
341         else
342         {
343                 if(rate_error != NULL)
344                         log(LL_WRN, "%s", rate_error);
345         }
346
347         /* if writing accounting info, open file, set unbuffered */
348         
349         if(useacctfile)
350         {
351                 if((acctfp = fopen(acctfile, "a")) == NULL)
352                 {
353                         log(LL_ERR, "ERROR, can't open acctfile %s for writing, terminating!", acctfile);
354                         exit(1);
355                 }
356                 setvbuf(acctfp, (char *)NULL, _IONBF, 0);               
357         }
358
359         /* initialize alias processing */
360
361         if(aliasing)
362                 init_alias(aliasfile);
363
364         /* init holidays */
365         
366         init_holidays(holidayfile);             
367
368         /* init remote monitoring */
369         
370 #ifdef I4B_EXTERNAL_MONITOR
371         if(do_monitor)
372         {
373                 monitor_init();
374                 sockfd = monitor_create_local_socket();
375 #ifndef I4B_NOTCPIP_MONITOR
376                 remotesockfd = monitor_create_remote_socket(monitorport);
377 #endif
378         }
379 #endif
380         
381         /* in case fullscreendisplay, initialize */
382
383 #ifdef USE_CURSES
384         if(do_fullscreen)
385         {
386                 init_screen();
387         }
388 #endif
389
390         /* init realtime priority */
391                 
392 #ifdef USE_RTPRIO
393         if(rt_prio != RTPRIO_NOTUSED)
394         {
395                 struct rtprio rtp;
396
397                 rtp.type = RTP_PRIO_REALTIME;
398                 rtp.prio = rt_prio;
399
400                 if((rtprio(RTP_SET, getpid(), &rtp)) == -1)
401                 {
402                         log(LL_ERR, "rtprio failed: %s", strerror(errno));
403                         do_exit(1);
404                 }
405         }
406 #endif
407
408         starttime = time(NULL); /* get starttime */
409         
410         srandom(580403);        /* init random number gen */
411         
412         mloop(          /* enter loop of no return .. */
413 #ifdef I4B_EXTERNAL_MONITOR
414                 sockfd
415 #ifndef I4B_NOTCPIP_MONITOR
416                 , remotesockfd
417 #endif
418 #endif
419                 );
420         do_exit(0);
421         return(0);
422 }
423
424 /*---------------------------------------------------------------------------*
425  *      program exit
426  *---------------------------------------------------------------------------*/
427 void
428 do_exit(int exitval)
429 {
430         close_allactive();
431
432         unlink(PIDFILE);
433
434         log(LL_DMN, "daemon terminating, exitval = %d", exitval);
435         
436 #ifdef USE_CURSES
437         if(do_fullscreen)
438                 endwin();
439 #endif
440
441 #ifdef I4B_EXTERNAL_MONITOR
442         monitor_exit();
443 #endif
444
445         exit(exitval);
446 }
447
448 /*---------------------------------------------------------------------------*
449  *      program exit
450  *---------------------------------------------------------------------------*/
451 void
452 error_exit(int exitval, const char *fmt, ...)
453 {
454         close_allactive();
455
456         unlink(PIDFILE);
457
458         log(LL_DMN, "fatal error, daemon terminating, exitval = %d", exitval);
459         
460 #ifdef USE_CURSES
461         if(do_fullscreen)
462                 endwin();
463 #endif
464
465 #ifdef I4B_EXTERNAL_MONITOR
466         monitor_exit();
467 #endif
468
469         if(mailto[0] && mailer[0])
470         {
471
472 #define EXITBL 2048
473
474                 char ebuffer[EXITBL];
475                 char sbuffer[EXITBL];
476                 va_list ap;
477
478                 va_start(ap, fmt);
479                 vsnprintf(ebuffer, EXITBL-1, fmt, ap);
480                 va_end(ap);
481
482                 signal(SIGCHLD, SIG_IGN);       /* remove handler */
483                 
484                 snprintf(sbuffer, sizeof(sbuffer), "%s%s%s%s%s%s%s%s",
485                         "cat << ENDOFDATA | ",
486                         mailer,
487                         " -s \"i4b isdnd: fatal error, terminating\" ",
488                         mailto,
489                         "\nThe isdnd terminated because of a fatal error:\n\n",
490                         ebuffer,
491                         "\n\nYours sincerely,\n   the isdnd\n",
492                         "\nENDOFDATA\n");
493                 system(sbuffer);
494         }
495
496         exit(exitval);
497 }
498
499 /*---------------------------------------------------------------------------*
500  *      main loop
501  *---------------------------------------------------------------------------*/
502 static void
503 mloop(
504 #ifdef I4B_EXTERNAL_MONITOR
505         int localmonitor
506 #ifndef I4B_NOTCPIP_MONITOR
507         , int remotemonitor
508 #endif
509 #endif
510 )
511 {
512         fd_set set;
513         struct timeval timeout;
514         int ret;
515         int high_selfd;
516
517         /* go into loop */
518         
519         log(LL_DMN, "i4b isdn daemon started (pid = %d)", getpid());
520  
521         for(;;)
522         {
523                 FD_ZERO(&set);
524
525 #ifdef USE_CURSES
526                 if(do_fullscreen)
527                         FD_SET(fileno(stdin), &set);
528 #endif
529
530                 FD_SET(isdnfd, &set);
531
532                 high_selfd = isdnfd;
533                 
534 #ifdef I4B_EXTERNAL_MONITOR
535                 if(do_monitor)
536                 {
537                         if (localmonitor != -1) {
538                                 /* always watch for new connections */
539                                 FD_SET(localmonitor, &set);
540                                 if(localmonitor > high_selfd)
541                                         high_selfd = localmonitor;
542                         }
543 #ifndef I4B_NOTCPIP_MONITOR
544                         if (remotemonitor != -1) {
545                                 FD_SET(remotemonitor, &set);
546                                 if(remotemonitor > high_selfd)
547                                         high_selfd = remotemonitor;
548                         }
549 #endif
550
551                         /* if there are client connections, let monitor module
552                          * enter them into the fdset */
553                         if(accepted)
554                         {
555                                 monitor_prepselect(&set, &high_selfd);
556                         }
557                 }
558 #endif
559                 
560                 timeout.tv_sec = 1;
561                 timeout.tv_usec = 0;
562
563                 ret = select(high_selfd + 1, &set, NULL, NULL, &timeout);
564
565                 if(ret > 0)
566                 {       
567                         if(FD_ISSET(isdnfd, &set))
568                                 isdnrdhdl();
569
570 #ifdef USE_CURSES
571                         if(FD_ISSET(fileno(stdin), &set))
572                                 kbdrdhdl();
573 #endif
574
575 #ifdef I4B_EXTERNAL_MONITOR
576                         if(do_monitor)
577                         {
578                                 if(localmonitor != -1 && FD_ISSET(localmonitor, &set))
579                                         monitor_handle_connect(localmonitor, 1);
580
581 #ifndef I4B_NOTCPIP_MONITOR
582                                 if(remotemonitor != -1 && FD_ISSET(remotemonitor, &set))
583                                         monitor_handle_connect(remotemonitor, 0);
584 #endif
585                                 if(accepted)
586                                         monitor_handle_input(&set);
587                         }
588 #endif
589                 }
590                 else if(ret == -1)
591                 {
592                         if(errno != EINTR)
593                         {
594                                 log(LL_ERR, "mloop: ERROR, select error on isdn device, errno = %d!", errno);
595                                 error_exit(1, "mloop: ERROR, select error on isdn device, errno = %d!", errno);
596                         }
597                 }                       
598
599                 /* handle timeout and recovery */               
600
601                 handle_recovery();
602         }
603 }
604
605 #ifdef USE_CURSES
606 /*---------------------------------------------------------------------------*
607  *      data from keyboard available, read and process it 
608  *---------------------------------------------------------------------------*/
609 static void
610 kbdrdhdl(void)
611 {
612         int ch = getch();
613
614         if(ch == ERR)
615         {
616                 log(LL_ERR, "kbdrdhdl: ERROR, read error on controlling tty, errno = %d!", errno);
617                 error_exit(1, "kbdrdhdl: ERROR, read error on controlling tty, errno = %d!", errno);
618         }
619
620         switch(ch)
621         {
622                 case 0x0c:      /* control L */
623                         wrefresh(curscr);
624                         break;
625                 
626                 case '\n':
627                 case '\r':
628                         do_menu();
629                         break;
630         }
631 }
632 #endif
633
634 /*---------------------------------------------------------------------------*
635  *      data from /dev/isdn available, read and process them
636  *---------------------------------------------------------------------------*/
637 static void
638 isdnrdhdl(void)
639 {
640         static unsigned char msg_rd_buf[MSG_BUF_SIZ];
641         msg_hdr_t *hp = (msg_hdr_t *)&msg_rd_buf[0];
642         
643         register int len;
644
645         if((len = read(isdnfd, msg_rd_buf, MSG_BUF_SIZ)) > 0)
646         {
647                 switch(hp->type)
648                 {
649                         case MSG_CONNECT_IND:                           
650                                 msg_connect_ind((msg_connect_ind_t *)msg_rd_buf);
651                                 break;
652                                 
653                         case MSG_CONNECT_ACTIVE_IND:
654                                 msg_connect_active_ind((msg_connect_active_ind_t *)msg_rd_buf);
655                                 break;
656
657                         case MSG_DISCONNECT_IND:
658                                 msg_disconnect_ind((msg_disconnect_ind_t *)msg_rd_buf);
659                                 break;
660                                 
661                         case MSG_DIALOUT_IND:
662                                 msg_dialout((msg_dialout_ind_t *)msg_rd_buf);
663                                 break;
664
665                         case MSG_ACCT_IND:
666                                 msg_accounting((msg_accounting_ind_t *)msg_rd_buf);
667                                 break;
668
669                         case MSG_IDLE_TIMEOUT_IND:
670                                 msg_idle_timeout_ind((msg_idle_timeout_ind_t *)msg_rd_buf);
671                                 break;
672
673                         case MSG_CHARGING_IND:
674                                 msg_charging_ind((msg_charging_ind_t *)msg_rd_buf);
675                                 break;
676
677                         case MSG_PROCEEDING_IND:
678                                 msg_proceeding_ind((msg_proceeding_ind_t *)msg_rd_buf);
679                                 break;
680
681                         case MSG_ALERT_IND:
682                                 msg_alert_ind((msg_alert_ind_t *)msg_rd_buf);
683                                 break;
684
685                         case MSG_DRVRDISC_REQ:
686                                 msg_drvrdisc_req((msg_drvrdisc_req_t *)msg_rd_buf);
687                                 break;
688
689                         case MSG_L12STAT_IND:
690                                 msg_l12stat_ind((msg_l12stat_ind_t *)msg_rd_buf);
691                                 break;
692
693                         case MSG_TEIASG_IND:
694                                 msg_teiasg_ind((msg_teiasg_ind_t *)msg_rd_buf);
695                                 break;
696
697                         case MSG_PDEACT_IND:
698                                 msg_pdeact_ind((msg_pdeact_ind_t *)msg_rd_buf);
699                                 break;
700
701                         case MSG_NEGCOMP_IND:
702                                 msg_negcomplete_ind((msg_negcomplete_ind_t *)msg_rd_buf);
703                                 break;
704
705                         case MSG_IFSTATE_CHANGED_IND:
706                                 msg_ifstatechg_ind((msg_ifstatechg_ind_t *)msg_rd_buf);
707                                 break;
708
709                         case MSG_DIALOUTNUMBER_IND:
710                                 msg_dialoutnumber((msg_dialoutnumber_ind_t *)msg_rd_buf);
711                                 break;
712
713                         case MSG_PACKET_IND:
714                                 msg_packet_ind((msg_packet_ind_t *)msg_rd_buf);
715                                 break;
716
717                         case MSG_KEYPAD_IND:
718                                 msg_keypad((msg_keypad_ind_t *)msg_rd_buf);
719                                 break;
720
721                         default:
722                                 log(LL_WRN, "ERROR, unknown message received from %sisdn (0x%x)", _PATH_DEV, msg_rd_buf[0]);
723                                 break;
724                 }
725         }
726         else
727         {
728                 log(LL_WRN, "ERROR, read error on isdn device, errno = %d, length = %d", errno, len);
729         }
730 }
731
732 /*---------------------------------------------------------------------------*
733  *      re-read the config file on SIGHUP or menu command
734  *---------------------------------------------------------------------------*/
735 void
736 rereadconfig(int dummy)
737 {
738         extern int entrycount;
739
740         log(LL_DMN, "re-reading configuration file");
741         
742         close_allactive();
743
744 #if I4B_EXTERNAL_MONITOR
745         monitor_clear_rights();
746 #endif
747
748         entrycount = -1;
749         nentries = 0;
750         
751         /* read runtime configuration file and configure ourselves */
752         
753         configure(configfile, 1);
754
755         if(config_error_flag)
756         {
757                 log(LL_ERR, "rereadconfig: there were %d error(s) in the configuration file, terminating!", config_error_flag);
758                 error_exit(1, "rereadconfig: there were %d error(s) in the configuration file, terminating!", config_error_flag);
759         }
760
761         if(aliasing)
762         {
763                 /* reread alias database */
764                 free_aliases();
765                 init_alias(aliasfile);
766         }
767 }
768
769 /*---------------------------------------------------------------------------*
770  *      re-open the log/acct files on SIGUSR1
771  *---------------------------------------------------------------------------*/
772 void
773 reopenfiles(int dummy)
774 {
775         if(useacctfile)
776         {
777                 /* close file */
778                 
779                 fflush(acctfp);
780                 fclose(acctfp);
781
782                 /* if user specified a suffix, rename the old file */
783                 
784                 if(rotatesuffix[0] != '\0')
785                 {
786                         char filename[MAXPATHLEN];
787
788                         snprintf(filename, sizeof(filename), "%s%s", acctfile, rotatesuffix);
789
790                         if((rename(acctfile, filename)) != 0)
791                         {
792                                 log(LL_ERR, "reopenfiles: acct rename failed, cause = %s", strerror(errno));
793                                 error_exit(1, "reopenfiles: acct rename failed, cause = %s", strerror(errno));
794                         }
795                 }
796
797                 if((acctfp = fopen(acctfile, "a")) == NULL)
798                 {
799                         log(LL_ERR, "ERROR, can't open acctfile %s for writing, terminating!", acctfile);
800                         error_exit(1, "ERROR, can't open acctfile %s for writing, terminating!", acctfile);
801                 }
802                 setvbuf(acctfp, (char *)NULL, _IONBF, 0);
803         }
804
805         if(uselogfile)
806         {
807                 finish_log();
808
809                 /* if user specified a suffix, rename the old file */
810                 
811                 if(rotatesuffix[0] != '\0')
812                 {
813                         char filename[MAXPATHLEN];
814
815                         snprintf(filename, sizeof(filename), "%s%s", logfile, rotatesuffix);
816
817                         if((rename(logfile, filename)) != 0)
818                         {
819                                 log(LL_ERR, "reopenfiles: log rename failed, cause = %s", strerror(errno));
820                                 error_exit(1, "reopenfiles: log rename failed, cause = %s", strerror(errno));
821                         }
822                 }
823
824                 if((logfp = fopen(logfile, "a")) == NULL)
825                 {
826                         fprintf(stderr, "ERROR, cannot open logfile %s: %s\n",
827                                 logfile, strerror(errno));
828                         error_exit(1, "reopenfiles: ERROR, cannot open logfile %s: %s\n",
829                                 logfile, strerror(errno));
830                 }
831
832                 /* set unbuffered operation */
833
834                 setvbuf(logfp, (char *)NULL, _IONBF, 0);
835         }
836 }
837
838 /* EOF */