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