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