xref: /freebsd/contrib/ntp/ntpd/ntpd.c (revision f4b37ed0f8b307b1f3f0f630ca725d68f1dff30d)
1 /*
2  * ntpd.c - main program for the fixed point NTP daemon
3  */
4 
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8 
9 #include "ntp_machine.h"
10 #include "ntpd.h"
11 #include "ntp_io.h"
12 #include "ntp_stdlib.h"
13 #include <ntp_random.h>
14 
15 #include "ntp_config.h"
16 #include "ntp_syslog.h"
17 #include "ntp_assert.h"
18 #include "isc/error.h"
19 #include "isc/strerror.h"
20 #include "isc/formatcheck.h"
21 #include "iosignal.h"
22 
23 #ifdef SIM
24 # include "ntpsim.h"
25 #endif
26 
27 #include "ntp_libopts.h"
28 #include "ntpd-opts.h"
29 
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33 #ifdef HAVE_SYS_STAT_H
34 # include <sys/stat.h>
35 #endif
36 #include <stdio.h>
37 #ifdef HAVE_SYS_PARAM_H
38 # include <sys/param.h>
39 #endif
40 #ifdef HAVE_SYS_SIGNAL_H
41 # include <sys/signal.h>
42 #else
43 # include <signal.h>
44 #endif
45 #ifdef HAVE_SYS_IOCTL_H
46 # include <sys/ioctl.h>
47 #endif /* HAVE_SYS_IOCTL_H */
48 #if defined(HAVE_RTPRIO)
49 # ifdef HAVE_SYS_LOCK_H
50 #  include <sys/lock.h>
51 # endif
52 # include <sys/rtprio.h>
53 #else
54 # ifdef HAVE_PLOCK
55 #  ifdef HAVE_SYS_LOCK_H
56 #	include <sys/lock.h>
57 #  endif
58 # endif
59 #endif
60 #if defined(HAVE_SCHED_SETSCHEDULER)
61 # ifdef HAVE_SCHED_H
62 #  include <sched.h>
63 # else
64 #  ifdef HAVE_SYS_SCHED_H
65 #   include <sys/sched.h>
66 #  endif
67 # endif
68 #endif
69 #if defined(HAVE_SYS_MMAN_H)
70 # include <sys/mman.h>
71 #endif
72 
73 #ifdef HAVE_TERMIOS_H
74 # include <termios.h>
75 #endif
76 
77 #ifdef SYS_DOMAINOS
78 # include <apollo/base.h>
79 #endif /* SYS_DOMAINOS */
80 
81 
82 #include "recvbuff.h"
83 #include "ntp_cmdargs.h"
84 
85 #if 0				/* HMS: I don't think we need this. 961223 */
86 #ifdef LOCK_PROCESS
87 # ifdef SYS_SOLARIS
88 #  include <sys/mman.h>
89 # else
90 #  include <sys/lock.h>
91 # endif
92 #endif
93 #endif
94 
95 #ifdef _AIX
96 # include <ulimit.h>
97 #endif /* _AIX */
98 
99 #ifdef SCO5_CLOCK
100 # include <sys/ci/ciioctl.h>
101 #endif
102 
103 #ifdef HAVE_DROPROOT
104 # include <ctype.h>
105 # include <grp.h>
106 # include <pwd.h>
107 #ifdef HAVE_LINUX_CAPABILITIES
108 # include <sys/capability.h>
109 # include <sys/prctl.h>
110 #endif /* HAVE_LINUX_CAPABILITIES */
111 #if defined(HAVE_PRIV_H) && defined(HAVE_SOLARIS_PRIVS)
112 # include <priv.h>
113 #endif /* HAVE_PRIV_H */
114 #endif /* HAVE_DROPROOT */
115 
116 #if defined (LIBSECCOMP) && (KERN_SECCOMP)
117 /* # include <sys/types.h> */
118 # include <sys/resource.h>
119 # include <seccomp.h>
120 #endif /* LIBSECCOMP and KERN_SECCOMP */
121 
122 #ifdef HAVE_DNSREGISTRATION
123 # include <dns_sd.h>
124 DNSServiceRef mdns;
125 #endif
126 
127 #ifdef HAVE_SETPGRP_0
128 # define ntp_setpgrp(x, y)	setpgrp()
129 #else
130 # define ntp_setpgrp(x, y)	setpgrp(x, y)
131 #endif
132 
133 #ifdef HAVE_SOLARIS_PRIVS
134 # define LOWPRIVS "basic,sys_time,net_privaddr,proc_setid,!proc_info,!proc_session,!proc_exec"
135 static priv_set_t *lowprivs = NULL;
136 static priv_set_t *highprivs = NULL;
137 #endif /* HAVE_SOLARIS_PRIVS */
138 /*
139  * Scheduling priority we run at
140  */
141 #define NTPD_PRIO	(-12)
142 
143 int priority_done = 2;		/* 0 - Set priority */
144 				/* 1 - priority is OK where it is */
145 				/* 2 - Don't set priority */
146 				/* 1 and 2 are pretty much the same */
147 
148 int listen_to_virtual_ips = TRUE;
149 
150 /*
151  * No-fork flag.  If set, we do not become a background daemon.
152  */
153 int nofork;			/* Fork by default */
154 
155 #ifdef HAVE_DNSREGISTRATION
156 /*
157  * mDNS registration flag. If set, we attempt to register with the mDNS system, but only
158  * after we have synched the first time. If the attempt fails, then try again once per
159  * minute for up to 5 times. After all, we may be starting before mDNS.
160  */
161 int mdnsreg = FALSE;
162 int mdnstries = 5;
163 #endif  /* HAVE_DNSREGISTRATION */
164 
165 #ifdef HAVE_DROPROOT
166 int droproot;
167 int root_dropped;
168 char *user;		/* User to switch to */
169 char *group;		/* group to switch to */
170 const char *chrootdir;	/* directory to chroot to */
171 uid_t sw_uid;
172 gid_t sw_gid;
173 char *endp;
174 struct group *gr;
175 struct passwd *pw;
176 #endif /* HAVE_DROPROOT */
177 
178 #ifdef HAVE_WORKING_FORK
179 int	waitsync_fd_to_close = -1;	/* -w/--wait-sync */
180 #endif
181 
182 /*
183  * Initializing flag.  All async routines watch this and only do their
184  * thing when it is clear.
185  */
186 int initializing;
187 
188 /*
189  * Version declaration
190  */
191 extern const char *Version;
192 
193 char const *progname;
194 
195 int was_alarmed;
196 
197 #ifdef DECL_SYSCALL
198 /*
199  * We put this here, since the argument profile is syscall-specific
200  */
201 extern int syscall	(int, ...);
202 #endif /* DECL_SYSCALL */
203 
204 
205 #if !defined(SIM) && defined(SIGDIE1)
206 static	RETSIGTYPE	finish		(int);
207 #endif
208 
209 #if !defined(SIM) && defined(HAVE_WORKING_FORK)
210 static int	wait_child_sync_if	(int, long);
211 #endif
212 
213 #if !defined(SIM) && !defined(SYS_WINNT)
214 # ifdef	DEBUG
215 static	RETSIGTYPE	moredebug	(int);
216 static	RETSIGTYPE	lessdebug	(int);
217 # else	/* !DEBUG follows */
218 static	RETSIGTYPE	no_debug	(int);
219 # endif	/* !DEBUG */
220 #endif	/* !SIM && !SYS_WINNT */
221 
222 int	saved_argc;
223 char **	saved_argv;
224 
225 #ifndef SIM
226 int		ntpdmain		(int, char **);
227 static void	set_process_priority	(void);
228 static void	assertion_failed	(const char *, int,
229 					 isc_assertiontype_t,
230 					 const char *)
231 			__attribute__	((__noreturn__));
232 static void	library_fatal_error	(const char *, int,
233 					 const char *, va_list)
234 					ISC_FORMAT_PRINTF(3, 0);
235 static void	library_unexpected_error(const char *, int,
236 					 const char *, va_list)
237 					ISC_FORMAT_PRINTF(3, 0);
238 #endif	/* !SIM */
239 
240 
241 
242 
243 void
244 parse_cmdline_opts(
245 	int *	pargc,
246 	char ***pargv
247 	)
248 {
249 	static int	parsed;
250 	static int	optct;
251 
252 	if (!parsed)
253 		optct = ntpOptionProcess(&ntpdOptions, *pargc, *pargv);
254 
255 	parsed = 1;
256 
257 	*pargc -= optct;
258 	*pargv += optct;
259 }
260 
261 
262 #ifdef SIM
263 int
264 main(
265 	int argc,
266 	char *argv[]
267 	)
268 {
269 	progname = argv[0];
270 	parse_cmdline_opts(&argc, &argv);
271 #ifdef DEBUG
272 	debug = OPT_VALUE_SET_DEBUG_LEVEL;
273 	DPRINTF(1, ("%s\n", Version));
274 #endif
275 
276 	return ntpsim(argc, argv);
277 }
278 #else	/* !SIM follows */
279 #ifdef NO_MAIN_ALLOWED
280 CALL(ntpd,"ntpd",ntpdmain);
281 #else	/* !NO_MAIN_ALLOWED follows */
282 #ifndef SYS_WINNT
283 int
284 main(
285 	int argc,
286 	char *argv[]
287 	)
288 {
289 	return ntpdmain(argc, argv);
290 }
291 #endif /* !SYS_WINNT */
292 #endif /* !NO_MAIN_ALLOWED */
293 #endif /* !SIM */
294 
295 #ifdef _AIX
296 /*
297  * OK. AIX is different than solaris in how it implements plock().
298  * If you do NOT adjust the stack limit, you will get the MAXIMUM
299  * stack size allocated and PINNED with you program. To check the
300  * value, use ulimit -a.
301  *
302  * To fix this, we create an automatic variable and set our stack limit
303  * to that PLUS 32KB of extra space (we need some headroom).
304  *
305  * This subroutine gets the stack address.
306  *
307  * Grover Davidson and Matt Ladendorf
308  *
309  */
310 static char *
311 get_aix_stack(void)
312 {
313 	char ch;
314 	return (&ch);
315 }
316 
317 /*
318  * Signal handler for SIGDANGER.
319  */
320 static void
321 catch_danger(int signo)
322 {
323 	msyslog(LOG_INFO, "ntpd: setpgid(): %m");
324 	/* Make the system believe we'll free something, but don't do it! */
325 	return;
326 }
327 #endif /* _AIX */
328 
329 /*
330  * Set the process priority
331  */
332 #ifndef SIM
333 static void
334 set_process_priority(void)
335 {
336 
337 # ifdef DEBUG
338 	if (debug > 1)
339 		msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
340 			((priority_done)
341 			 ? "Leave priority alone"
342 			 : "Attempt to set priority"
343 				),
344 			priority_done);
345 # endif /* DEBUG */
346 
347 # if defined(HAVE_SCHED_SETSCHEDULER)
348 	if (!priority_done) {
349 		extern int config_priority_override, config_priority;
350 		int pmax, pmin;
351 		struct sched_param sched;
352 
353 		pmax = sched_get_priority_max(SCHED_FIFO);
354 		sched.sched_priority = pmax;
355 		if ( config_priority_override ) {
356 			pmin = sched_get_priority_min(SCHED_FIFO);
357 			if ( config_priority > pmax )
358 				sched.sched_priority = pmax;
359 			else if ( config_priority < pmin )
360 				sched.sched_priority = pmin;
361 			else
362 				sched.sched_priority = config_priority;
363 		}
364 		if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
365 			msyslog(LOG_ERR, "sched_setscheduler(): %m");
366 		else
367 			++priority_done;
368 	}
369 # endif /* HAVE_SCHED_SETSCHEDULER */
370 # ifdef HAVE_RTPRIO
371 #  ifdef RTP_SET
372 	if (!priority_done) {
373 		struct rtprio srtp;
374 
375 		srtp.type = RTP_PRIO_REALTIME;	/* was: RTP_PRIO_NORMAL */
376 		srtp.prio = 0;		/* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
377 
378 		if (rtprio(RTP_SET, getpid(), &srtp) < 0)
379 			msyslog(LOG_ERR, "rtprio() error: %m");
380 		else
381 			++priority_done;
382 	}
383 #  else	/* !RTP_SET follows */
384 	if (!priority_done) {
385 		if (rtprio(0, 120) < 0)
386 			msyslog(LOG_ERR, "rtprio() error: %m");
387 		else
388 			++priority_done;
389 	}
390 #  endif	/* !RTP_SET */
391 # endif	/* HAVE_RTPRIO */
392 # if defined(NTPD_PRIO) && NTPD_PRIO != 0
393 #  ifdef HAVE_ATT_NICE
394 	if (!priority_done) {
395 		errno = 0;
396 		if (-1 == nice (NTPD_PRIO) && errno != 0)
397 			msyslog(LOG_ERR, "nice() error: %m");
398 		else
399 			++priority_done;
400 	}
401 #  endif	/* HAVE_ATT_NICE */
402 #  ifdef HAVE_BSD_NICE
403 	if (!priority_done) {
404 		if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
405 			msyslog(LOG_ERR, "setpriority() error: %m");
406 		else
407 			++priority_done;
408 	}
409 #  endif	/* HAVE_BSD_NICE */
410 # endif	/* NTPD_PRIO && NTPD_PRIO != 0 */
411 	if (!priority_done)
412 		msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
413 }
414 #endif	/* !SIM */
415 
416 
417 /*
418  * Main program.  Initialize us, disconnect us from the tty if necessary,
419  * and loop waiting for I/O and/or timer expiries.
420  */
421 #ifndef SIM
422 int
423 ntpdmain(
424 	int argc,
425 	char *argv[]
426 	)
427 {
428 	l_fp		now;
429 	struct recvbuf *rbuf;
430 	const char *	logfilename;
431 # ifdef HAVE_UMASK
432 	mode_t		uv;
433 # endif
434 # if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
435 	uid_t		uid;
436 # endif
437 # if defined(HAVE_WORKING_FORK)
438 	long		wait_sync = 0;
439 	int		pipe_fds[2];
440 	int		rc;
441 	int		exit_code;
442 #  ifdef _AIX
443 	struct sigaction sa;
444 #  endif
445 #  if !defined(HAVE_SETSID) && !defined (HAVE_SETPGID) && defined(TIOCNOTTY)
446 	int		fid;
447 #  endif
448 # endif	/* HAVE_WORKING_FORK*/
449 # ifdef SCO5_CLOCK
450 	int		fd;
451 	int		zero;
452 # endif
453 
454 # ifdef HAVE_UMASK
455 	uv = umask(0);
456 	if (uv)
457 		umask(uv);
458 	else
459 		umask(022);
460 # endif
461 	saved_argc = argc;
462 	saved_argv = argv;
463 	progname = argv[0];
464 	initializing = TRUE;		/* mark that we are initializing */
465 	parse_cmdline_opts(&argc, &argv);
466 # ifdef DEBUG
467 	debug = OPT_VALUE_SET_DEBUG_LEVEL;
468 #  ifdef HAVE_SETLINEBUF
469 	setlinebuf(stdout);
470 #  endif
471 # endif
472 
473 	if (HAVE_OPT(NOFORK) || HAVE_OPT(QUIT)
474 # ifdef DEBUG
475 	    || debug
476 # endif
477 	    || HAVE_OPT(SAVECONFIGQUIT))
478 		nofork = TRUE;
479 
480 	init_logging(progname, NLOG_SYNCMASK, TRUE);
481 	/* honor -l/--logfile option to log to a file */
482 	if (HAVE_OPT(LOGFILE)) {
483 		logfilename = OPT_ARG(LOGFILE);
484 		syslogit = FALSE;
485 		change_logfile(logfilename, FALSE);
486 	} else {
487 		logfilename = NULL;
488 		if (nofork)
489 			msyslog_term = TRUE;
490 		if (HAVE_OPT(SAVECONFIGQUIT))
491 			syslogit = FALSE;
492 	}
493 	msyslog(LOG_NOTICE, "%s: Starting", Version);
494 
495 	{
496 		int i;
497 		char buf[1024];	/* Secret knowledge of msyslog buf length */
498 		char *cp = buf;
499 
500 		/* Note that every arg has an initial space character */
501 		snprintf(cp, sizeof(buf), "Command line:");
502 		cp += strlen(cp);
503 
504 		for (i = 0; i < saved_argc ; ++i) {
505 			snprintf(cp, sizeof(buf) - (cp - buf),
506 				" %s", saved_argv[i]);
507 			cp += strlen(cp);
508 		}
509 		msyslog(LOG_INFO, "%s", buf);
510 	}
511 
512 	/*
513 	 * Install trap handlers to log errors and assertion failures.
514 	 * Default handlers print to stderr which doesn't work if detached.
515 	 */
516 	isc_assertion_setcallback(assertion_failed);
517 	isc_error_setfatal(library_fatal_error);
518 	isc_error_setunexpected(library_unexpected_error);
519 
520 	/* MPE lacks the concept of root */
521 # if defined(HAVE_GETUID) && !defined(MPE)
522 	uid = getuid();
523 	if (uid && !HAVE_OPT( SAVECONFIGQUIT )) {
524 		msyslog_term = TRUE;
525 		msyslog(LOG_ERR,
526 			"must be run as root, not uid %ld", (long)uid);
527 		exit(1);
528 	}
529 # endif
530 
531 /*
532  * Enable the Multi-Media Timer for Windows?
533  */
534 # ifdef SYS_WINNT
535 	if (HAVE_OPT( MODIFYMMTIMER ))
536 		set_mm_timer(MM_TIMER_HIRES);
537 # endif
538 
539 #ifdef HAVE_DNSREGISTRATION
540 /*
541  * Enable mDNS registrations?
542  */
543 	if (HAVE_OPT( MDNS )) {
544 		mdnsreg = TRUE;
545 	}
546 #endif  /* HAVE_DNSREGISTRATION */
547 
548 	if (HAVE_OPT( NOVIRTUALIPS ))
549 		listen_to_virtual_ips = 0;
550 
551 	/*
552 	 * --interface, listen on specified interfaces
553 	 */
554 	if (HAVE_OPT( INTERFACE )) {
555 		int		ifacect = STACKCT_OPT( INTERFACE );
556 		const char**	ifaces  = STACKLST_OPT( INTERFACE );
557 		sockaddr_u	addr;
558 
559 		while (ifacect-- > 0) {
560 			add_nic_rule(
561 				is_ip_address(*ifaces, AF_UNSPEC, &addr)
562 					? MATCH_IFADDR
563 					: MATCH_IFNAME,
564 				*ifaces, -1, ACTION_LISTEN);
565 			ifaces++;
566 		}
567 	}
568 
569 	if (HAVE_OPT( NICE ))
570 		priority_done = 0;
571 
572 # ifdef HAVE_SCHED_SETSCHEDULER
573 	if (HAVE_OPT( PRIORITY )) {
574 		config_priority = OPT_VALUE_PRIORITY;
575 		config_priority_override = 1;
576 		priority_done = 0;
577 	}
578 # endif
579 
580 # ifdef HAVE_WORKING_FORK
581 	do {					/* 'loop' once */
582 		if (!HAVE_OPT( WAIT_SYNC ))
583 			break;
584 		wait_sync = OPT_VALUE_WAIT_SYNC;
585 		if (wait_sync <= 0) {
586 			wait_sync = 0;
587 			break;
588 		}
589 		/* -w requires a fork() even with debug > 0 */
590 		nofork = FALSE;
591 		if (pipe(pipe_fds)) {
592 			exit_code = (errno) ? errno : -1;
593 			msyslog(LOG_ERR,
594 				"Pipe creation failed for --wait-sync: %m");
595 			exit(exit_code);
596 		}
597 		waitsync_fd_to_close = pipe_fds[1];
598 	} while (0);				/* 'loop' once */
599 # endif	/* HAVE_WORKING_FORK */
600 
601 	init_lib();
602 # ifdef SYS_WINNT
603 	/*
604 	 * Start interpolation thread, must occur before first
605 	 * get_systime()
606 	 */
607 	init_winnt_time();
608 # endif
609 	/*
610 	 * Initialize random generator and public key pair
611 	 */
612 	get_systime(&now);
613 
614 	ntp_srandom((int)(now.l_i * now.l_uf));
615 
616 	/*
617 	 * Detach us from the terminal.  May need an #ifndef GIZMO.
618 	 */
619 	if (!nofork) {
620 
621 # ifdef HAVE_WORKING_FORK
622 		rc = fork();
623 		if (-1 == rc) {
624 			exit_code = (errno) ? errno : -1;
625 			msyslog(LOG_ERR, "fork: %m");
626 			exit(exit_code);
627 		}
628 		if (rc > 0) {
629 			/* parent */
630 			exit_code = wait_child_sync_if(pipe_fds[0],
631 						       wait_sync);
632 			exit(exit_code);
633 		}
634 
635 		/*
636 		 * child/daemon
637 		 * close all open files excepting waitsync_fd_to_close.
638 		 * msyslog() unreliable until after init_logging().
639 		 */
640 		closelog();
641 		if (syslog_file != NULL) {
642 			fclose(syslog_file);
643 			syslog_file = NULL;
644 			syslogit = TRUE;
645 		}
646 		close_all_except(waitsync_fd_to_close);
647 		INSIST(0 == open("/dev/null", 0) && 1 == dup2(0, 1) \
648 			&& 2 == dup2(0, 2));
649 
650 		init_logging(progname, 0, TRUE);
651 		/* we lost our logfile (if any) daemonizing */
652 		setup_logfile(logfilename);
653 
654 #  ifdef SYS_DOMAINOS
655 		{
656 			uid_$t puid;
657 			status_$t st;
658 
659 			proc2_$who_am_i(&puid);
660 			proc2_$make_server(&puid, &st);
661 		}
662 #  endif	/* SYS_DOMAINOS */
663 #  ifdef HAVE_SETSID
664 		if (setsid() == (pid_t)-1)
665 			msyslog(LOG_ERR, "setsid(): %m");
666 #  elif defined(HAVE_SETPGID)
667 		if (setpgid(0, 0) == -1)
668 			msyslog(LOG_ERR, "setpgid(): %m");
669 #  else		/* !HAVE_SETSID && !HAVE_SETPGID follows */
670 #   ifdef TIOCNOTTY
671 		fid = open("/dev/tty", 2);
672 		if (fid >= 0) {
673 			ioctl(fid, (u_long)TIOCNOTTY, NULL);
674 			close(fid);
675 		}
676 #   endif	/* TIOCNOTTY */
677 		ntp_setpgrp(0, getpid());
678 #  endif	/* !HAVE_SETSID && !HAVE_SETPGID */
679 #  ifdef _AIX
680 		/* Don't get killed by low-on-memory signal. */
681 		sa.sa_handler = catch_danger;
682 		sigemptyset(&sa.sa_mask);
683 		sa.sa_flags = SA_RESTART;
684 		sigaction(SIGDANGER, &sa, NULL);
685 #  endif	/* _AIX */
686 # endif		/* HAVE_WORKING_FORK */
687 	}
688 
689 # ifdef SCO5_CLOCK
690 	/*
691 	 * SCO OpenServer's system clock offers much more precise timekeeping
692 	 * on the base CPU than the other CPUs (for multiprocessor systems),
693 	 * so we must lock to the base CPU.
694 	 */
695 	fd = open("/dev/at1", O_RDONLY);
696 	if (fd >= 0) {
697 		zero = 0;
698 		if (ioctl(fd, ACPU_LOCK, &zero) < 0)
699 			msyslog(LOG_ERR, "cannot lock to base CPU: %m");
700 		close(fd);
701 	}
702 # endif
703 
704 	/* Setup stack size in preparation for locking pages in memory. */
705 # if defined(HAVE_MLOCKALL)
706 #  ifdef HAVE_SETRLIMIT
707 	ntp_rlimit(RLIMIT_STACK, DFLT_RLIMIT_STACK * 4096, 4096, "4k");
708 #   ifdef RLIMIT_MEMLOCK
709 	/*
710 	 * The default RLIMIT_MEMLOCK is very low on Linux systems.
711 	 * Unless we increase this limit malloc calls are likely to
712 	 * fail if we drop root privilege.  To be useful the value
713 	 * has to be larger than the largest ntpd resident set size.
714 	 */
715 	ntp_rlimit(RLIMIT_MEMLOCK, DFLT_RLIMIT_MEMLOCK * 1024 * 1024, 1024 * 1024, "MB");
716 #   endif	/* RLIMIT_MEMLOCK */
717 #  endif	/* HAVE_SETRLIMIT */
718 # else	/* !HAVE_MLOCKALL follows */
719 #  ifdef HAVE_PLOCK
720 #   ifdef PROCLOCK
721 #    ifdef _AIX
722 	/*
723 	 * set the stack limit for AIX for plock().
724 	 * see get_aix_stack() for more info.
725 	 */
726 	if (ulimit(SET_STACKLIM, (get_aix_stack() - 8 * 4096)) < 0)
727 		msyslog(LOG_ERR,
728 			"Cannot adjust stack limit for plock: %m");
729 #    endif	/* _AIX */
730 #   endif	/* PROCLOCK */
731 #  endif	/* HAVE_PLOCK */
732 # endif	/* !HAVE_MLOCKALL */
733 
734 	/*
735 	 * Set up signals we pay attention to locally.
736 	 */
737 # ifdef SIGDIE1
738 	signal_no_reset(SIGDIE1, finish);
739 	signal_no_reset(SIGDIE2, finish);
740 	signal_no_reset(SIGDIE3, finish);
741 	signal_no_reset(SIGDIE4, finish);
742 # endif
743 # ifdef SIGBUS
744 	signal_no_reset(SIGBUS, finish);
745 # endif
746 
747 # if !defined(SYS_WINNT) && !defined(VMS)
748 #  ifdef DEBUG
749 	(void) signal_no_reset(MOREDEBUGSIG, moredebug);
750 	(void) signal_no_reset(LESSDEBUGSIG, lessdebug);
751 #  else
752 	(void) signal_no_reset(MOREDEBUGSIG, no_debug);
753 	(void) signal_no_reset(LESSDEBUGSIG, no_debug);
754 #  endif	/* DEBUG */
755 # endif	/* !SYS_WINNT && !VMS */
756 
757 	/*
758 	 * Set up signals we should never pay attention to.
759 	 */
760 # ifdef SIGPIPE
761 	signal_no_reset(SIGPIPE, SIG_IGN);
762 # endif
763 
764 	/*
765 	 * Call the init_ routines to initialize the data structures.
766 	 *
767 	 * Exactly what command-line options are we expecting here?
768 	 */
769 	INIT_SSL();
770 	init_auth();
771 	init_util();
772 	init_restrict();
773 	init_mon();
774 	init_timer();
775 	init_request();
776 	init_control();
777 	init_peer();
778 # ifdef REFCLOCK
779 	init_refclock();
780 # endif
781 	set_process_priority();
782 	init_proto();		/* Call at high priority */
783 	init_io();
784 	init_loopfilter();
785 	mon_start(MON_ON);	/* monitor on by default now	  */
786 				/* turn off in config if unwanted */
787 
788 	/*
789 	 * Get the configuration.  This is done in a separate module
790 	 * since this will definitely be different for the gizmo board.
791 	 */
792 	getconfig(argc, argv);
793 
794 	if (do_memlock) {
795 # if defined(HAVE_MLOCKALL)
796 		/*
797 		 * lock the process into memory
798 		 */
799 		if (!HAVE_OPT(SAVECONFIGQUIT) &&
800 		    0 != mlockall(MCL_CURRENT|MCL_FUTURE))
801 			msyslog(LOG_ERR, "mlockall(): %m");
802 # else	/* !HAVE_MLOCKALL follows */
803 #  ifdef HAVE_PLOCK
804 #   ifdef PROCLOCK
805 		/*
806 		 * lock the process into memory
807 		 */
808 		if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(PROCLOCK))
809 			msyslog(LOG_ERR, "plock(PROCLOCK): %m");
810 #   else	/* !PROCLOCK follows  */
811 #    ifdef TXTLOCK
812 		/*
813 		 * Lock text into ram
814 		 */
815 		if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(TXTLOCK))
816 			msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
817 #    else	/* !TXTLOCK follows */
818 		msyslog(LOG_ERR, "plock() - don't know what to lock!");
819 #    endif	/* !TXTLOCK */
820 #   endif	/* !PROCLOCK */
821 #  endif	/* HAVE_PLOCK */
822 # endif	/* !HAVE_MLOCKALL */
823 	}
824 
825 	loop_config(LOOP_DRIFTINIT, 0);
826 	report_event(EVNT_SYSRESTART, NULL, NULL);
827 	initializing = FALSE;
828 
829 # ifdef HAVE_DROPROOT
830 	if (droproot) {
831 		/* Drop super-user privileges and chroot now if the OS supports this */
832 
833 #  ifdef HAVE_LINUX_CAPABILITIES
834 		/* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
835 		if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
836 			msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
837 			exit(-1);
838 		}
839 #  elif HAVE_SOLARIS_PRIVS
840 		/* Nothing to do here */
841 #  else
842 		/* we need a user to switch to */
843 		if (user == NULL) {
844 			msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
845 			exit(-1);
846 		}
847 #  endif	/* HAVE_LINUX_CAPABILITIES || HAVE_SOLARIS_PRIVS */
848 
849 		if (user != NULL) {
850 			if (isdigit((unsigned char)*user)) {
851 				sw_uid = (uid_t)strtoul(user, &endp, 0);
852 				if (*endp != '\0')
853 					goto getuser;
854 
855 				if ((pw = getpwuid(sw_uid)) != NULL) {
856 					free(user);
857 					user = estrdup(pw->pw_name);
858 					sw_gid = pw->pw_gid;
859 				} else {
860 					errno = 0;
861 					msyslog(LOG_ERR, "Cannot find user ID %s", user);
862 					exit (-1);
863 				}
864 
865 			} else {
866 getuser:
867 				errno = 0;
868 				if ((pw = getpwnam(user)) != NULL) {
869 					sw_uid = pw->pw_uid;
870 					sw_gid = pw->pw_gid;
871 				} else {
872 					if (errno)
873 						msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
874 					else
875 						msyslog(LOG_ERR, "Cannot find user `%s'", user);
876 					exit (-1);
877 				}
878 			}
879 		}
880 		if (group != NULL) {
881 			if (isdigit((unsigned char)*group)) {
882 				sw_gid = (gid_t)strtoul(group, &endp, 0);
883 				if (*endp != '\0')
884 					goto getgroup;
885 			} else {
886 getgroup:
887 				if ((gr = getgrnam(group)) != NULL) {
888 					sw_gid = gr->gr_gid;
889 				} else {
890 					errno = 0;
891 					msyslog(LOG_ERR, "Cannot find group `%s'", group);
892 					exit (-1);
893 				}
894 			}
895 		}
896 
897 		if (chrootdir ) {
898 			/* make sure cwd is inside the jail: */
899 			if (chdir(chrootdir)) {
900 				msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
901 				exit (-1);
902 			}
903 			if (chroot(chrootdir)) {
904 				msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
905 				exit (-1);
906 			}
907 			if (chdir("/")) {
908 				msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
909 				exit (-1);
910 			}
911 		}
912 #  ifdef HAVE_SOLARIS_PRIVS
913 		if ((lowprivs = priv_str_to_set(LOWPRIVS, ",", NULL)) == NULL) {
914 			msyslog(LOG_ERR, "priv_str_to_set() failed:%m");
915 			exit(-1);
916 		}
917 		if ((highprivs = priv_allocset()) == NULL) {
918 			msyslog(LOG_ERR, "priv_allocset() failed:%m");
919 			exit(-1);
920 		}
921 		(void) getppriv(PRIV_PERMITTED, highprivs);
922 		(void) priv_intersect(highprivs, lowprivs);
923 		if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) {
924 			msyslog(LOG_ERR, "setppriv() failed:%m");
925 			exit(-1);
926 		}
927 #  endif /* HAVE_SOLARIS_PRIVS */
928 		if (user && initgroups(user, sw_gid)) {
929 			msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
930 			exit (-1);
931 		}
932 		if (group && setgid(sw_gid)) {
933 			msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
934 			exit (-1);
935 		}
936 		if (group && setegid(sw_gid)) {
937 			msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
938 			exit (-1);
939 		}
940 		if (group)
941 			setgroups(1, &sw_gid);
942 		else
943 			initgroups(pw->pw_name, pw->pw_gid);
944 		if (user && setuid(sw_uid)) {
945 			msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
946 			exit (-1);
947 		}
948 		if (user && seteuid(sw_uid)) {
949 			msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
950 			exit (-1);
951 		}
952 
953 #  if !defined(HAVE_LINUX_CAPABILITIES) && !defined(HAVE_SOLARIS_PRIVS)
954 		/*
955 		 * for now assume that the privilege to bind to privileged ports
956 		 * is associated with running with uid 0 - should be refined on
957 		 * ports that allow binding to NTP_PORT with uid != 0
958 		 */
959 		disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
960 #  endif /* !HAVE_LINUX_CAPABILITIES && !HAVE_SOLARIS_PRIVS */
961 
962 		if (disable_dynamic_updates && interface_interval) {
963 			interface_interval = 0;
964 			msyslog(LOG_INFO, "running as non-root disables dynamic interface tracking");
965 		}
966 
967 #  ifdef HAVE_LINUX_CAPABILITIES
968 		{
969 			/*
970 			 *  We may be running under non-root uid now, but we still hold full root privileges!
971 			 *  We drop all of them, except for the crucial one or two: cap_sys_time and
972 			 *  cap_net_bind_service if doing dynamic interface tracking.
973 			 */
974 			cap_t caps;
975 			char *captext;
976 
977 			captext = (0 != interface_interval)
978 				      ? "cap_sys_time,cap_net_bind_service=pe"
979 				      : "cap_sys_time=pe";
980 			caps = cap_from_text(captext);
981 			if (!caps) {
982 				msyslog(LOG_ERR,
983 					"cap_from_text(%s) failed: %m",
984 					captext);
985 				exit(-1);
986 			}
987 			if (-1 == cap_set_proc(caps)) {
988 				msyslog(LOG_ERR,
989 					"cap_set_proc() failed to drop root privs: %m");
990 				exit(-1);
991 			}
992 			cap_free(caps);
993 		}
994 #  endif	/* HAVE_LINUX_CAPABILITIES */
995 #  ifdef HAVE_SOLARIS_PRIVS
996 		if (priv_delset(lowprivs, "proc_setid") == -1) {
997 			msyslog(LOG_ERR, "priv_delset() failed:%m");
998 			exit(-1);
999 		}
1000 		if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) {
1001 			msyslog(LOG_ERR, "setppriv() failed:%m");
1002 			exit(-1);
1003 		}
1004 		priv_freeset(lowprivs);
1005 		priv_freeset(highprivs);
1006 #  endif /* HAVE_SOLARIS_PRIVS */
1007 		root_dropped = TRUE;
1008 		fork_deferred_worker();
1009 	}	/* if (droproot) */
1010 # endif	/* HAVE_DROPROOT */
1011 
1012 /* libssecomp sandboxing */
1013 #if defined (LIBSECCOMP) && (KERN_SECCOMP)
1014 	scmp_filter_ctx ctx;
1015 
1016 	if ((ctx = seccomp_init(SCMP_ACT_KILL)) < 0)
1017 		msyslog(LOG_ERR, "%s: seccomp_init(SCMP_ACT_KILL) failed: %m", __func__);
1018 	else {
1019 		msyslog(LOG_DEBUG, "%s: seccomp_init(SCMP_ACT_KILL) succeeded", __func__);
1020 	}
1021 
1022 #ifdef __x86_64__
1023 int scmp_sc[] = {
1024 	SCMP_SYS(adjtimex),
1025 	SCMP_SYS(bind),
1026 	SCMP_SYS(brk),
1027 	SCMP_SYS(chdir),
1028 	SCMP_SYS(clock_gettime),
1029 	SCMP_SYS(clock_settime),
1030 	SCMP_SYS(close),
1031 	SCMP_SYS(connect),
1032 	SCMP_SYS(exit_group),
1033 	SCMP_SYS(fstat),
1034 	SCMP_SYS(fsync),
1035 	SCMP_SYS(futex),
1036 	SCMP_SYS(getitimer),
1037 	SCMP_SYS(getsockname),
1038 	SCMP_SYS(ioctl),
1039 	SCMP_SYS(lseek),
1040 	SCMP_SYS(madvise),
1041 	SCMP_SYS(mmap),
1042 	SCMP_SYS(munmap),
1043 	SCMP_SYS(open),
1044 	SCMP_SYS(poll),
1045 	SCMP_SYS(read),
1046 	SCMP_SYS(recvmsg),
1047 	SCMP_SYS(rename),
1048 	SCMP_SYS(rt_sigaction),
1049 	SCMP_SYS(rt_sigprocmask),
1050 	SCMP_SYS(rt_sigreturn),
1051 	SCMP_SYS(select),
1052 	SCMP_SYS(sendto),
1053 	SCMP_SYS(setitimer),
1054 	SCMP_SYS(setsid),
1055 	SCMP_SYS(socket),
1056 	SCMP_SYS(stat),
1057 	SCMP_SYS(time),
1058 	SCMP_SYS(write),
1059 };
1060 #endif
1061 #ifdef __i386__
1062 int scmp_sc[] = {
1063 	SCMP_SYS(_newselect),
1064 	SCMP_SYS(adjtimex),
1065 	SCMP_SYS(brk),
1066 	SCMP_SYS(chdir),
1067 	SCMP_SYS(clock_gettime),
1068 	SCMP_SYS(clock_settime),
1069 	SCMP_SYS(close),
1070 	SCMP_SYS(exit_group),
1071 	SCMP_SYS(fsync),
1072 	SCMP_SYS(futex),
1073 	SCMP_SYS(getitimer),
1074 	SCMP_SYS(madvise),
1075 	SCMP_SYS(mmap),
1076 	SCMP_SYS(mmap2),
1077 	SCMP_SYS(munmap),
1078 	SCMP_SYS(open),
1079 	SCMP_SYS(poll),
1080 	SCMP_SYS(read),
1081 	SCMP_SYS(rename),
1082 	SCMP_SYS(rt_sigaction),
1083 	SCMP_SYS(rt_sigprocmask),
1084 	SCMP_SYS(select),
1085 	SCMP_SYS(setitimer),
1086 	SCMP_SYS(setsid),
1087 	SCMP_SYS(sigprocmask),
1088 	SCMP_SYS(sigreturn),
1089 	SCMP_SYS(socketcall),
1090 	SCMP_SYS(stat64),
1091 	SCMP_SYS(time),
1092 	SCMP_SYS(write),
1093 };
1094 #endif
1095 	{
1096 		int i;
1097 
1098 		for (i = 0; i < COUNTOF(scmp_sc); i++) {
1099 			if (seccomp_rule_add(ctx,
1100 			    SCMP_ACT_ALLOW, scmp_sc[i], 0) < 0) {
1101 				msyslog(LOG_ERR,
1102 				    "%s: seccomp_rule_add() failed: %m",
1103 				    __func__);
1104 			}
1105 		}
1106 	}
1107 
1108 	if (seccomp_load(ctx) < 0)
1109 		msyslog(LOG_ERR, "%s: seccomp_load() failed: %m",
1110 		    __func__);
1111 	else {
1112 		msyslog(LOG_DEBUG, "%s: seccomp_load() succeeded", __func__);
1113 	}
1114 #endif /* LIBSECCOMP and KERN_SECCOMP */
1115 
1116 # ifdef HAVE_IO_COMPLETION_PORT
1117 
1118 	for (;;) {
1119 		GetReceivedBuffers();
1120 # else /* normal I/O */
1121 
1122 	BLOCK_IO_AND_ALARM();
1123 	was_alarmed = FALSE;
1124 
1125 	for (;;) {
1126 		if (alarm_flag) {	/* alarmed? */
1127 			was_alarmed = TRUE;
1128 			alarm_flag = FALSE;
1129 		}
1130 
1131 		if (!was_alarmed && !has_full_recv_buffer()) {
1132 			/*
1133 			 * Nothing to do.  Wait for something.
1134 			 */
1135 			io_handler();
1136 		}
1137 
1138 		if (alarm_flag) {	/* alarmed? */
1139 			was_alarmed = TRUE;
1140 			alarm_flag = FALSE;
1141 		}
1142 
1143 		if (was_alarmed) {
1144 			UNBLOCK_IO_AND_ALARM();
1145 			/*
1146 			 * Out here, signals are unblocked.  Call timer routine
1147 			 * to process expiry.
1148 			 */
1149 			timer();
1150 			was_alarmed = FALSE;
1151 			BLOCK_IO_AND_ALARM();
1152 		}
1153 
1154 # endif		/* !HAVE_IO_COMPLETION_PORT */
1155 
1156 # ifdef DEBUG_TIMING
1157 		{
1158 			l_fp pts;
1159 			l_fp tsa, tsb;
1160 			int bufcount = 0;
1161 
1162 			get_systime(&pts);
1163 			tsa = pts;
1164 # endif
1165 			rbuf = get_full_recv_buffer();
1166 			while (rbuf != NULL) {
1167 				if (alarm_flag) {
1168 					was_alarmed = TRUE;
1169 					alarm_flag = FALSE;
1170 				}
1171 				UNBLOCK_IO_AND_ALARM();
1172 
1173 				if (was_alarmed) {
1174 					/* avoid timer starvation during lengthy I/O handling */
1175 					timer();
1176 					was_alarmed = FALSE;
1177 				}
1178 
1179 				/*
1180 				 * Call the data procedure to handle each received
1181 				 * packet.
1182 				 */
1183 				if (rbuf->receiver != NULL) {
1184 # ifdef DEBUG_TIMING
1185 					l_fp dts = pts;
1186 
1187 					L_SUB(&dts, &rbuf->recv_time);
1188 					DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
1189 					collect_timing(rbuf, "buffer processing delay", 1, &dts);
1190 					bufcount++;
1191 # endif
1192 					(*rbuf->receiver)(rbuf);
1193 				} else {
1194 					msyslog(LOG_ERR, "fatal: receive buffer callback NULL");
1195 					abort();
1196 				}
1197 
1198 				BLOCK_IO_AND_ALARM();
1199 				freerecvbuf(rbuf);
1200 				rbuf = get_full_recv_buffer();
1201 			}
1202 # ifdef DEBUG_TIMING
1203 			get_systime(&tsb);
1204 			L_SUB(&tsb, &tsa);
1205 			if (bufcount) {
1206 				collect_timing(NULL, "processing", bufcount, &tsb);
1207 				DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
1208 			}
1209 		}
1210 # endif
1211 
1212 		/*
1213 		 * Go around again
1214 		 */
1215 
1216 # ifdef HAVE_DNSREGISTRATION
1217 		if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) {
1218 			mdnsreg = current_time;
1219 			msyslog(LOG_INFO, "Attempting to register mDNS");
1220 			if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL,
1221 			    htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
1222 				if (!--mdnstries) {
1223 					msyslog(LOG_ERR, "Unable to register mDNS, giving up.");
1224 				} else {
1225 					msyslog(LOG_INFO, "Unable to register mDNS, will try later.");
1226 				}
1227 			} else {
1228 				msyslog(LOG_INFO, "mDNS service registered.");
1229 				mdnsreg = FALSE;
1230 			}
1231 		}
1232 # endif /* HAVE_DNSREGISTRATION */
1233 
1234 	}
1235 	UNBLOCK_IO_AND_ALARM();
1236 	return 1;
1237 }
1238 #endif	/* !SIM */
1239 
1240 
1241 #if !defined(SIM) && defined(SIGDIE1)
1242 /*
1243  * finish - exit gracefully
1244  */
1245 static RETSIGTYPE
1246 finish(
1247 	int sig
1248 	)
1249 {
1250 	const char *sig_desc;
1251 
1252 	sig_desc = NULL;
1253 #ifdef HAVE_STRSIGNAL
1254 	sig_desc = strsignal(sig);
1255 #endif
1256 	if (sig_desc == NULL)
1257 		sig_desc = "";
1258 	msyslog(LOG_NOTICE, "%s exiting on signal %d (%s)", progname,
1259 		sig, sig_desc);
1260 	/* See Bug 2513 and Bug 2522 re the unlink of PIDFILE */
1261 # ifdef HAVE_DNSREGISTRATION
1262 	if (mdns != NULL)
1263 		DNSServiceRefDeallocate(mdns);
1264 # endif
1265 	peer_cleanup();
1266 	exit(0);
1267 }
1268 #endif	/* !SIM && SIGDIE1 */
1269 
1270 
1271 #ifndef SIM
1272 /*
1273  * wait_child_sync_if - implements parent side of -w/--wait-sync
1274  */
1275 # ifdef HAVE_WORKING_FORK
1276 static int
1277 wait_child_sync_if(
1278 	int	pipe_read_fd,
1279 	long	wait_sync
1280 	)
1281 {
1282 	int	rc;
1283 	int	exit_code;
1284 	time_t	wait_end_time;
1285 	time_t	cur_time;
1286 	time_t	wait_rem;
1287 	fd_set	readset;
1288 	struct timeval wtimeout;
1289 
1290 	if (0 == wait_sync)
1291 		return 0;
1292 
1293 	/* waitsync_fd_to_close used solely by child */
1294 	close(waitsync_fd_to_close);
1295 	wait_end_time = time(NULL) + wait_sync;
1296 	do {
1297 		cur_time = time(NULL);
1298 		wait_rem = (wait_end_time > cur_time)
1299 				? (wait_end_time - cur_time)
1300 				: 0;
1301 		wtimeout.tv_sec = wait_rem;
1302 		wtimeout.tv_usec = 0;
1303 		FD_ZERO(&readset);
1304 		FD_SET(pipe_read_fd, &readset);
1305 		rc = select(pipe_read_fd + 1, &readset, NULL, NULL,
1306 			    &wtimeout);
1307 		if (-1 == rc) {
1308 			if (EINTR == errno)
1309 				continue;
1310 			exit_code = (errno) ? errno : -1;
1311 			msyslog(LOG_ERR,
1312 				"--wait-sync select failed: %m");
1313 			return exit_code;
1314 		}
1315 		if (0 == rc) {
1316 			/*
1317 			 * select() indicated a timeout, but in case
1318 			 * its timeouts are affected by a step of the
1319 			 * system clock, select() again with a zero
1320 			 * timeout to confirm.
1321 			 */
1322 			FD_ZERO(&readset);
1323 			FD_SET(pipe_read_fd, &readset);
1324 			wtimeout.tv_sec = 0;
1325 			wtimeout.tv_usec = 0;
1326 			rc = select(pipe_read_fd + 1, &readset, NULL,
1327 				    NULL, &wtimeout);
1328 			if (0 == rc)	/* select() timeout */
1329 				break;
1330 			else		/* readable */
1331 				return 0;
1332 		} else			/* readable */
1333 			return 0;
1334 	} while (wait_rem > 0);
1335 
1336 	fprintf(stderr, "%s: -w/--wait-sync %ld timed out.\n",
1337 		progname, wait_sync);
1338 	return ETIMEDOUT;
1339 }
1340 # endif	/* HAVE_WORKING_FORK */
1341 
1342 
1343 /*
1344  * assertion_failed - Redirect assertion failures to msyslog().
1345  */
1346 static void
1347 assertion_failed(
1348 	const char *file,
1349 	int line,
1350 	isc_assertiontype_t type,
1351 	const char *cond
1352 	)
1353 {
1354 	isc_assertion_setcallback(NULL);    /* Avoid recursion */
1355 
1356 	msyslog(LOG_ERR, "%s:%d: %s(%s) failed",
1357 		file, line, isc_assertion_typetotext(type), cond);
1358 	msyslog(LOG_ERR, "exiting (due to assertion failure)");
1359 
1360 #if defined(DEBUG) && defined(SYS_WINNT)
1361 	if (debug)
1362 		DebugBreak();
1363 #endif
1364 
1365 	abort();
1366 }
1367 
1368 
1369 /*
1370  * library_fatal_error - Handle fatal errors from our libraries.
1371  */
1372 static void
1373 library_fatal_error(
1374 	const char *file,
1375 	int line,
1376 	const char *format,
1377 	va_list args
1378 	)
1379 {
1380 	char errbuf[256];
1381 
1382 	isc_error_setfatal(NULL);  /* Avoid recursion */
1383 
1384 	msyslog(LOG_ERR, "%s:%d: fatal error:", file, line);
1385 	vsnprintf(errbuf, sizeof(errbuf), format, args);
1386 	msyslog(LOG_ERR, "%s", errbuf);
1387 	msyslog(LOG_ERR, "exiting (due to fatal error in library)");
1388 
1389 #if defined(DEBUG) && defined(SYS_WINNT)
1390 	if (debug)
1391 		DebugBreak();
1392 #endif
1393 
1394 	abort();
1395 }
1396 
1397 
1398 /*
1399  * library_unexpected_error - Handle non fatal errors from our libraries.
1400  */
1401 # define MAX_UNEXPECTED_ERRORS 100
1402 int unexpected_error_cnt = 0;
1403 static void
1404 library_unexpected_error(
1405 	const char *file,
1406 	int line,
1407 	const char *format,
1408 	va_list args
1409 	)
1410 {
1411 	char errbuf[256];
1412 
1413 	if (unexpected_error_cnt >= MAX_UNEXPECTED_ERRORS)
1414 		return;	/* avoid clutter in log */
1415 
1416 	msyslog(LOG_ERR, "%s:%d: unexpected error:", file, line);
1417 	vsnprintf(errbuf, sizeof(errbuf), format, args);
1418 	msyslog(LOG_ERR, "%s", errbuf);
1419 
1420 	if (++unexpected_error_cnt == MAX_UNEXPECTED_ERRORS)
1421 		msyslog(LOG_ERR, "Too many errors.  Shutting up.");
1422 
1423 }
1424 #endif	/* !SIM */
1425 
1426 #if !defined(SIM) && !defined(SYS_WINNT)
1427 # ifdef DEBUG
1428 
1429 /*
1430  * moredebug - increase debugging verbosity
1431  */
1432 static RETSIGTYPE
1433 moredebug(
1434 	int sig
1435 	)
1436 {
1437 	int saved_errno = errno;
1438 
1439 	if (debug < 255)
1440 	{
1441 		debug++;
1442 		msyslog(LOG_DEBUG, "debug raised to %d", debug);
1443 	}
1444 	errno = saved_errno;
1445 }
1446 
1447 
1448 /*
1449  * lessdebug - decrease debugging verbosity
1450  */
1451 static RETSIGTYPE
1452 lessdebug(
1453 	int sig
1454 	)
1455 {
1456 	int saved_errno = errno;
1457 
1458 	if (debug > 0)
1459 	{
1460 		debug--;
1461 		msyslog(LOG_DEBUG, "debug lowered to %d", debug);
1462 	}
1463 	errno = saved_errno;
1464 }
1465 
1466 # else	/* !DEBUG follows */
1467 
1468 
1469 /*
1470  * no_debug - We don't do the debug here.
1471  */
1472 static RETSIGTYPE
1473 no_debug(
1474 	int sig
1475 	)
1476 {
1477 	int saved_errno = errno;
1478 
1479 	msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
1480 	errno = saved_errno;
1481 }
1482 # endif	/* !DEBUG */
1483 #endif	/* !SIM && !SYS_WINNT */
1484