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