1 /* $NetBSD: ntpd.c,v 1.1.1.1 2009/12/13 16:56:15 kardel Exp $ */
4 * ntpd.c - main program for the fixed point NTP daemon
11 #include "ntp_machine.h"
14 #include "ntp_stdlib.h"
15 #include <ntp_random.h>
17 #include "ntp_syslog.h"
18 #include "isc/assertions.h"
19 #include "isc/error.h"
20 #include "isc/strerror.h"
21 #include "isc/formatcheck.h"
27 #include "ntpd-opts.h"
32 #ifdef HAVE_SYS_STAT_H
33 # include <sys/stat.h>
36 #if !defined(VMS) /*wjm*/
37 # ifdef HAVE_SYS_PARAM_H
38 # include <sys/param.h>
41 #ifdef HAVE_SYS_SIGNAL_H
42 # include <sys/signal.h>
46 #ifdef HAVE_SYS_IOCTL_H
47 # include <sys/ioctl.h>
48 #endif /* HAVE_SYS_IOCTL_H */
49 #ifdef HAVE_SYS_RESOURCE_H
50 # include <sys/resource.h>
51 #endif /* HAVE_SYS_RESOURCE_H */
52 #if defined(HAVE_RTPRIO)
53 # ifdef HAVE_SYS_RESOURCE_H
54 # include <sys/resource.h>
56 # ifdef HAVE_SYS_LOCK_H
57 # include <sys/lock.h>
59 # include <sys/rtprio.h>
62 # ifdef HAVE_SYS_LOCK_H
63 # include <sys/lock.h>
67 #if defined(HAVE_SCHED_SETSCHEDULER)
71 # ifdef HAVE_SYS_SCHED_H
72 # include <sys/sched.h>
76 #if defined(HAVE_SYS_MMAN_H)
77 # include <sys/mman.h>
85 # include <apollo/base.h>
86 #endif /* SYS_DOMAINOS */
89 #include "ntp_cmdargs.h"
91 #if 0 /* HMS: I don't think we need this. 961223 */
94 # include <sys/mman.h>
96 # include <sys/lock.h>
106 # include <sys/ci/ciioctl.h>
113 #ifdef HAVE_LINUX_CAPABILITIES
114 # include <sys/capability.h>
115 # include <sys/prctl.h>
120 * Signals we catch for debugging. If not debugging we ignore them.
122 #define MOREDEBUGSIG SIGUSR1
123 #define LESSDEBUGSIG SIGUSR2
126 * Signals which terminate us gracefully.
129 # define SIGDIE1 SIGHUP
130 # define SIGDIE3 SIGQUIT
131 # define SIGDIE2 SIGINT
132 # define SIGDIE4 SIGTERM
133 #endif /* SYS_WINNT */
135 #ifdef HAVE_DNSREGISTRATION
141 * Scheduling priority we run at
143 #define NTPD_PRIO (-12)
145 int priority_done
= 2; /* 0 - Set priority */
146 /* 1 - priority is OK where it is */
147 /* 2 - Don't set priority */
148 /* 1 and 2 are pretty much the same */
154 volatile int debug
= 0; /* No debugging by default */
157 int listen_to_virtual_ips
= 1;
158 const char *specific_interface
= NULL
; /* interface name or IP address to bind to */
161 * No-fork flag. If set, we do not become a background daemon.
163 int nofork
= 0; /* Fork by default */
165 #ifdef HAVE_DNSREGISTRATION
167 * mDNS registration flag. If set, we attempt to register with the mDNS system, but only
168 * after we have synched the first time. If the attempt fails, then try again once per
169 * minute for up to 5 times. After all, we may be starting before mDNS.
173 #endif /* HAVE_DNSREGISTRATION */
177 char *user
= NULL
; /* User to switch to */
178 char *group
= NULL
; /* group to switch to */
179 const char *chrootdir
= NULL
; /* directory to chroot to */
185 #endif /* HAVE_DROPROOT */
188 * Initializing flag. All async routines watch this and only do their
189 * thing when it is clear.
194 * Version declaration
196 extern const char *Version
;
198 char const *progname
;
204 * We put this here, since the argument profile is syscall-specific
206 extern int syscall (int, ...);
207 #endif /* DECL_SYSCALL */
211 static RETSIGTYPE
finish (int);
216 static RETSIGTYPE
moredebug (int);
217 static RETSIGTYPE
lessdebug (int);
219 #else /* not DEBUG */
220 static RETSIGTYPE
no_debug (int);
221 #endif /* not DEBUG */
223 int ntpdmain (int, char **);
224 static void set_process_priority (void);
225 void init_logging (char const *, int);
226 void setup_logfile (void);
227 static void process_commandline_opts(int *, char ***);
229 static void assertion_failed (const char *file
, int line
,
230 isc_assertiontype_t type
, const char *cond
);
231 static void library_fatal_error (const char *file
, int line
,
232 const char *format
, va_list args
) ISC_FORMAT_PRINTF(3, 0);
233 static void library_unexpected_error(const char *file
, int line
,
234 const char *format
, va_list args
) ISC_FORMAT_PRINTF(3, 0);
238 * Initialize the logging
249 * Logging. This may actually work on the gizmo board. Find a name
250 * to log with by using the basename
252 cp
= strrchr(name
, '/');
261 openlog(cp
, LOG_PID
);
262 # else /* LOG_DAEMON */
265 # define LOG_NTP LOG_DAEMON
267 openlog(cp
, LOG_PID
| LOG_NDELAY
, LOG_NTP
);
270 setlogmask(LOG_UPTO(LOG_DEBUG
));
273 setlogmask(LOG_UPTO(LOG_DEBUG
)); /* @@@ was INFO */
274 # endif /* LOG_DAEMON */
278 NLOG(NLOG_SYSINFO
) /* 'if' clause for syslog */
279 msyslog(LOG_NOTICE
, "%s", Version
);
284 * Redirect logging to a file if requested with -l.
285 * The ntp.conf logfile directive does not use this code, see
286 * config_vars() in ntp_config.c.
293 if (HAVE_OPT( LOGFILE
)) {
294 const char *my_optarg
= OPT_ARG( LOGFILE
);
297 if(strcmp(my_optarg
, "stderr") == 0)
299 else if(strcmp(my_optarg
, "stdout") == 0)
302 new_file
= fopen(my_optarg
, "a");
303 if (new_file
!= NULL
) {
305 msyslog(LOG_NOTICE
, "logging to file %s", my_optarg
);
306 if (syslog_file
!= NULL
&&
307 fileno(syslog_file
) != fileno(new_file
))
308 (void)fclose(syslog_file
);
310 syslog_file
= new_file
;
315 "Cannot open log file %s",
322 process_commandline_opts(
329 optct
= optionProcess(&ntpdOptions
, *pargc
, *pargv
);
342 process_commandline_opts(&argc
, &argv
);
344 return ntpsim(argc
, argv
);
347 #ifdef NO_MAIN_ALLOWED
348 CALL(ntpd
,"ntpd",ntpdmain
);
357 return ntpdmain(argc
, argv
);
359 #endif /* SYS_WINNT */
360 #endif /* NO_MAIN_ALLOWED */
365 * OK. AIX is different than solaris in how it implements plock().
366 * If you do NOT adjust the stack limit, you will get the MAXIMUM
367 * stack size allocated and PINNED with you program. To check the
368 * value, use ulimit -a.
370 * To fix this, we create an automatic variable and set our stack limit
371 * to that PLUS 32KB of extra space (we need some headroom).
373 * This subroutine gets the stack address.
375 * Grover Davidson and Matt Ladendorf
386 * Signal handler for SIGDANGER.
389 catch_danger(int signo
)
391 msyslog(LOG_INFO
, "ntpd: setpgid(): %m");
392 /* Make the system believe we'll free something, but don't do it! */
398 * Set the process priority
401 set_process_priority(void)
406 msyslog(LOG_DEBUG
, "set_process_priority: %s: priority_done is <%d>",
408 ? "Leave priority alone"
409 : "Attempt to set priority"
414 #if defined(HAVE_SCHED_SETSCHEDULER)
415 if (!priority_done
) {
416 extern int config_priority_override
, config_priority
;
418 struct sched_param sched
;
420 pmax
= sched_get_priority_max(SCHED_FIFO
);
421 sched
.sched_priority
= pmax
;
422 if ( config_priority_override
) {
423 pmin
= sched_get_priority_min(SCHED_FIFO
);
424 if ( config_priority
> pmax
)
425 sched
.sched_priority
= pmax
;
426 else if ( config_priority
< pmin
)
427 sched
.sched_priority
= pmin
;
429 sched
.sched_priority
= config_priority
;
431 if ( sched_setscheduler(0, SCHED_FIFO
, &sched
) == -1 )
432 msyslog(LOG_ERR
, "sched_setscheduler(): %m");
436 #endif /* HAVE_SCHED_SETSCHEDULER */
437 #if defined(HAVE_RTPRIO)
439 if (!priority_done
) {
442 srtp
.type
= RTP_PRIO_REALTIME
; /* was: RTP_PRIO_NORMAL */
443 srtp
.prio
= 0; /* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
445 if (rtprio(RTP_SET
, getpid(), &srtp
) < 0)
446 msyslog(LOG_ERR
, "rtprio() error: %m");
450 # else /* not RTP_SET */
451 if (!priority_done
) {
452 if (rtprio(0, 120) < 0)
453 msyslog(LOG_ERR
, "rtprio() error: %m");
457 # endif /* not RTP_SET */
458 #endif /* HAVE_RTPRIO */
459 #if defined(NTPD_PRIO) && NTPD_PRIO != 0
460 # ifdef HAVE_ATT_NICE
461 if (!priority_done
) {
463 if (-1 == nice (NTPD_PRIO
) && errno
!= 0)
464 msyslog(LOG_ERR
, "nice() error: %m");
468 # endif /* HAVE_ATT_NICE */
469 # ifdef HAVE_BSD_NICE
470 if (!priority_done
) {
471 if (-1 == setpriority(PRIO_PROCESS
, 0, NTPD_PRIO
))
472 msyslog(LOG_ERR
, "setpriority() error: %m");
476 # endif /* HAVE_BSD_NICE */
477 #endif /* NTPD_PRIO && NTPD_PRIO != 0 */
479 msyslog(LOG_ERR
, "set_process_priority: No way found to improve our priority");
484 * Main program. Initialize us, disconnect us from the tty if necessary,
485 * and loop waiting for I/O and/or timer expiries.
494 struct recvbuf
*rbuf
;
495 #ifdef _AIX /* HMS: ifdef SIGDANGER? */
500 initializing
= 1; /* mark that we are initializing */
501 process_commandline_opts(&argc
, &argv
);
502 init_logging(progname
, 1); /* Open the log file */
516 #if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
521 if (uid
&& !HAVE_OPT( SAVECONFIGQUIT
)) {
522 msyslog(LOG_ERR
, "ntpd: must be run as root, not uid %ld", (long)uid
);
523 printf("must be run as root, not uid %ld\n", (long)uid
);
529 /* getstartup(argc, argv); / * startup configuration, may set debug */
532 debug
= DESC(DEBUG_LEVEL
).optOccCt
;
533 DPRINTF(1, ("%s\n", Version
));
536 /* honor -l/--logfile option to log to a file */
540 * Enable the Multi-Media Timer for Windows?
543 if (HAVE_OPT( MODIFYMMTIMER
))
544 set_mm_timer(MM_TIMER_HIRES
);
547 if (HAVE_OPT( NOFORK
) || HAVE_OPT( QUIT
)
551 || HAVE_OPT( SAVECONFIGQUIT
))
554 if (HAVE_OPT( NOVIRTUALIPS
))
555 listen_to_virtual_ips
= 0;
558 * --interface, listen on specified interfaces
560 if (HAVE_OPT( INTERFACE
)) {
561 int ifacect
= STACKCT_OPT( INTERFACE
);
562 const char** ifaces
= STACKLST_OPT( INTERFACE
);
563 isc_netaddr_t netaddr
;
565 while (ifacect
-- > 0) {
567 is_ip_address(*ifaces
, &netaddr
)
570 *ifaces
, -1, ACTION_LISTEN
);
575 if (HAVE_OPT( NICE
))
578 #if defined(HAVE_SCHED_SETSCHEDULER)
579 if (HAVE_OPT( PRIORITY
)) {
580 config_priority
= OPT_VALUE_PRIORITY
;
581 config_priority_override
= 1;
588 * Start interpolation thread, must occur before first
594 * Initialize random generator and public key pair
598 ntp_srandom((int)(now
.l_i
* now
.l_uf
));
603 * Detach us from the terminal. May need an #ifndef GIZMO.
608 * Install trap handlers to log errors and assertion
609 * failures. Default handlers print to stderr which
610 * doesn't work if detached.
612 isc_assertion_setcallback(assertion_failed
);
613 isc_error_setfatal(library_fatal_error
);
614 isc_error_setunexpected(library_unexpected_error
);
619 # else /* not HAVE_DAEMON */
620 if (fork()) /* HMS: What about a -1? */
624 #if !defined(F_CLOSEM)
627 #endif /* !FCLOSEM */
628 if (syslog_file
!= NULL
) {
632 #if defined(F_CLOSEM)
634 * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
635 * by Eric Agar (saves us from doing 32767 system
638 if (fcntl(0, F_CLOSEM
, 0) == -1)
639 msyslog(LOG_ERR
, "ntpd: failed to close open files(): %m");
640 #else /* not F_CLOSEM */
642 # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
643 max_fd
= sysconf(_SC_OPEN_MAX
);
644 # else /* HAVE_SYSCONF && _SC_OPEN_MAX */
645 max_fd
= getdtablesize();
646 # endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
647 for (s
= 0; s
< max_fd
; s
++)
648 (void) close((int)s
);
649 #endif /* not F_CLOSEM */
654 init_logging(progname
, 0);
655 /* we lost our logfile (if any) daemonizing */
663 proc2_$
who_am_i(&puid
);
664 proc2_$
make_server(&puid
, &st
);
666 #endif /* SYS_DOMAINOS */
667 #if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
669 if (setsid() == (pid_t
)-1)
670 msyslog(LOG_ERR
, "ntpd: setsid(): %m");
672 if (setpgid(0, 0) == -1)
673 msyslog(LOG_ERR
, "ntpd: setpgid(): %m");
675 #else /* HAVE_SETPGID || HAVE_SETSID */
677 # if defined(TIOCNOTTY)
680 fid
= open("/dev/tty", 2);
683 (void) ioctl(fid
, (u_long
) TIOCNOTTY
, (char *) 0);
686 # endif /* defined(TIOCNOTTY) */
687 # ifdef HAVE_SETPGRP_0
689 # else /* HAVE_SETPGRP_0 */
690 (void) setpgrp(0, getpid());
691 # endif /* HAVE_SETPGRP_0 */
693 #endif /* HAVE_SETPGID || HAVE_SETSID */
695 /* Don't get killed by low-on-memory signal. */
696 sa
.sa_handler
= catch_danger
;
697 sigemptyset(&sa
.sa_mask
);
698 sa
.sa_flags
= SA_RESTART
;
700 (void) sigaction(SIGDANGER
, &sa
, NULL
);
703 # endif /* not HAVE_DAEMON */
704 # endif /* SYS_WINNT */
706 # endif /* NODETACH */
711 * SCO OpenServer's system clock offers much more precise timekeeping
712 * on the base CPU than the other CPUs (for multiprocessor systems),
713 * so we must lock to the base CPU.
716 int fd
= open("/dev/at1", O_RDONLY
);
719 if (ioctl(fd
, ACPU_LOCK
, &zero
) < 0)
720 msyslog(LOG_ERR
, "cannot lock to base CPU: %m");
723 * If we can't open the device, this probably just isn't
724 * a multiprocessor system, so we're A-OK.
729 #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)
730 # ifdef HAVE_SETRLIMIT
732 * Set the stack limit to something smaller, so that we don't lock a lot
733 * of unused stack memory.
738 /* HMS: must make the rlim_cur amount configurable */
739 if (getrlimit(RLIMIT_STACK
, &rl
) != -1
740 && (rl
.rlim_cur
= 50 * 4096) < rl
.rlim_max
)
742 if (setrlimit(RLIMIT_STACK
, &rl
) == -1)
745 "Cannot adjust stack limit for mlockall: %m");
748 # ifdef RLIMIT_MEMLOCK
750 * The default RLIMIT_MEMLOCK is very low on Linux systems.
751 * Unless we increase this limit malloc calls are likely to
752 * fail if we drop root privlege. To be useful the value
753 * has to be larger than the largest ntpd resident set size.
755 rl
.rlim_cur
= rl
.rlim_max
= 32*1024*1024;
756 if (setrlimit(RLIMIT_MEMLOCK
, &rl
) == -1) {
757 msyslog(LOG_ERR
, "Cannot set RLIMIT_MEMLOCK: %m");
759 # endif /* RLIMIT_MEMLOCK */
761 # endif /* HAVE_SETRLIMIT */
763 * lock the process into memory
765 if (mlockall(MCL_CURRENT
|MCL_FUTURE
) < 0)
766 msyslog(LOG_ERR
, "mlockall(): %m");
767 #else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
772 * set the stack limit for AIX for plock().
773 * see get_aix_stack() for more info.
775 if (ulimit(SET_STACKLIM
, (get_aix_stack() - 8*4096)) < 0)
777 msyslog(LOG_ERR
,"Cannot adjust stack limit for plock on AIX: %m");
781 * lock the process into memory
783 if (plock(PROCLOCK
) < 0)
784 msyslog(LOG_ERR
, "plock(PROCLOCK): %m");
785 # else /* not PROCLOCK */
790 if (plock(TXTLOCK
) < 0)
791 msyslog(LOG_ERR
, "plock(TXTLOCK) error: %m");
792 # else /* not TXTLOCK */
793 msyslog(LOG_ERR
, "plock() - don't know what to lock!");
794 # endif /* not TXTLOCK */
795 # endif /* not PROCLOCK */
796 # endif /* HAVE_PLOCK */
797 #endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
800 * Set up signals we pay attention to locally.
803 (void) signal_no_reset(SIGDIE1
, finish
);
806 (void) signal_no_reset(SIGDIE2
, finish
);
809 (void) signal_no_reset(SIGDIE3
, finish
);
812 (void) signal_no_reset(SIGDIE4
, finish
);
816 (void) signal_no_reset(SIGBUS
, finish
);
819 #if !defined(SYS_WINNT) && !defined(VMS)
821 (void) signal_no_reset(MOREDEBUGSIG
, moredebug
);
822 (void) signal_no_reset(LESSDEBUGSIG
, lessdebug
);
824 (void) signal_no_reset(MOREDEBUGSIG
, no_debug
);
825 (void) signal_no_reset(LESSDEBUGSIG
, no_debug
);
827 #endif /* !SYS_WINNT && !VMS */
830 * Set up signals we should never pay attention to.
833 (void) signal_no_reset(SIGPIPE
, SIG_IGN
);
837 * Call the init_ routines to initialize the data structures.
839 * Exactly what command-line options are we expecting here?
853 set_process_priority();
854 init_proto(); /* Call at high priority */
857 mon_start(MON_ON
); /* monitor on by default now */
858 /* turn off in config if unwanted */
861 * Get the configuration. This is done in a separate module
862 * since this will definitely be different for the gizmo board.
864 getconfig(argc
, argv
);
865 report_event(EVNT_SYSRESTART
, NULL
, NULL
);
866 loop_config(LOOP_DRIFTCOMP
, old_drift
);
871 /* Drop super-user privileges and chroot now if the OS supports this */
873 #ifdef HAVE_LINUX_CAPABILITIES
874 /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
875 if (prctl( PR_SET_KEEPCAPS
, 1L, 0L, 0L, 0L ) == -1) {
876 msyslog( LOG_ERR
, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
880 /* we need a user to switch to */
882 msyslog(LOG_ERR
, "Need user name to drop root privileges (see -u flag!)" );
885 #endif /* HAVE_LINUX_CAPABILITIES */
888 if (isdigit((unsigned char)*user
)) {
889 sw_uid
= (uid_t
)strtoul(user
, &endp
, 0);
893 if ((pw
= getpwuid(sw_uid
)) != NULL
) {
894 user
= strdup(pw
->pw_name
);
896 msyslog(LOG_ERR
, "strdup() failed: %m");
902 msyslog(LOG_ERR
, "Cannot find user ID %s", user
);
909 if ((pw
= getpwnam(user
)) != NULL
) {
914 msyslog(LOG_ERR
, "getpwnam(%s) failed: %m", user
);
916 msyslog(LOG_ERR
, "Cannot find user `%s'", user
);
922 if (isdigit((unsigned char)*group
)) {
923 sw_gid
= (gid_t
)strtoul(group
, &endp
, 0);
928 if ((gr
= getgrnam(group
)) != NULL
) {
932 msyslog(LOG_ERR
, "Cannot find group `%s'", group
);
939 /* make sure cwd is inside the jail: */
940 if (chdir(chrootdir
)) {
941 msyslog(LOG_ERR
, "Cannot chdir() to `%s': %m", chrootdir
);
944 if (chroot(chrootdir
)) {
945 msyslog(LOG_ERR
, "Cannot chroot() to `%s': %m", chrootdir
);
949 msyslog(LOG_ERR
, "Cannot chdir() to`root after chroot(): %m");
953 if (user
&& initgroups(user
, sw_gid
)) {
954 msyslog(LOG_ERR
, "Cannot initgroups() to user `%s': %m", user
);
957 if (group
&& setgid(sw_gid
)) {
958 msyslog(LOG_ERR
, "Cannot setgid() to group `%s': %m", group
);
961 if (group
&& setegid(sw_gid
)) {
962 msyslog(LOG_ERR
, "Cannot setegid() to group `%s': %m", group
);
966 setgroups(1, &sw_gid
);
968 initgroups(pw
->pw_name
, pw
->pw_gid
);
969 if (user
&& setuid(sw_uid
)) {
970 msyslog(LOG_ERR
, "Cannot setuid() to user `%s': %m", user
);
973 if (user
&& seteuid(sw_uid
)) {
974 msyslog(LOG_ERR
, "Cannot seteuid() to user `%s': %m", user
);
978 #ifndef HAVE_LINUX_CAPABILITIES
980 * for now assume that the privilege to bind to privileged ports
981 * is associated with running with uid 0 - should be refined on
982 * ports that allow binding to NTP_PORT with uid != 0
984 disable_dynamic_updates
|= (sw_uid
!= 0); /* also notifies routing message listener */
987 if (disable_dynamic_updates
&& interface_interval
) {
988 interface_interval
= 0;
989 msyslog(LOG_INFO
, "running in unprivileged mode disables dynamic interface tracking");
992 #ifdef HAVE_LINUX_CAPABILITIES
995 * We may be running under non-root uid now, but we still hold full root privileges!
996 * We drop all of them, except for the crucial one or two: cap_sys_time and
997 * cap_net_bind_service if doing dynamic interface tracking.
1000 char *captext
= (interface_interval
)
1001 ? "cap_sys_time,cap_net_bind_service=ipe"
1002 : "cap_sys_time=ipe";
1003 if( ! ( caps
= cap_from_text( captext
) ) ) {
1004 msyslog( LOG_ERR
, "cap_from_text() failed: %m" );
1007 if( cap_set_proc( caps
) == -1 ) {
1008 msyslog( LOG_ERR
, "cap_set_proc() failed to drop root privileges: %m" );
1013 #endif /* HAVE_LINUX_CAPABILITIES */
1015 } /* if( droproot ) */
1016 #endif /* HAVE_DROPROOT */
1019 * Use select() on all on all input fd's for unlimited
1020 * time. select() will terminate on SIGALARM or on the
1021 * reception of input. Using select() means we can't do
1022 * robust signal handling and we get a potential race
1023 * between checking for alarms and doing the select().
1024 * Mostly harmless, I think.
1026 /* On VMS, I suspect that select() can't be interrupted
1027 * by a "signal" either, so I take the easy way out and
1028 * have select() time out after one second.
1029 * System clock updates really aren't time-critical,
1030 * and - lacking a hardware reference clock - I have
1031 * yet to learn about anything else that is.
1033 #if defined(HAVE_IO_COMPLETION_PORT)
1036 GetReceivedBuffers();
1037 #else /* normal I/O */
1039 BLOCK_IO_AND_ALARM();
1043 # if !defined(HAVE_SIGNALED_IO)
1044 extern fd_set activefds
;
1045 extern int maxactivefd
;
1051 if (alarm_flag
) /* alarmed? */
1057 if (!was_alarmed
&& has_full_recv_buffer() == ISC_FALSE
)
1060 * Nothing to do. Wait for something.
1062 # ifndef HAVE_SIGNALED_IO
1064 # if defined(VMS) || defined(SYS_VXWORKS)
1065 /* make select() wake up after one second */
1069 t1
.tv_sec
= 1; t1
.tv_usec
= 0;
1070 nfound
= select(maxactivefd
+1, &rdfdes
, (fd_set
*)0,
1074 nfound
= select(maxactivefd
+1, &rdfdes
, (fd_set
*)0,
1075 (fd_set
*)0, (struct timeval
*)0);
1083 (void)input_handler(&ts
);
1085 else if (nfound
== -1 && errno
!= EINTR
)
1086 msyslog(LOG_ERR
, "select() error: %m");
1089 msyslog(LOG_DEBUG
, "select(): nfound=%d, error: %m", nfound
);
1091 # else /* HAVE_SIGNALED_IO */
1094 # endif /* HAVE_SIGNALED_IO */
1095 if (alarm_flag
) /* alarmed? */
1104 UNBLOCK_IO_AND_ALARM();
1106 * Out here, signals are unblocked. Call timer routine
1107 * to process expiry.
1111 BLOCK_IO_AND_ALARM();
1114 #endif /* ! HAVE_IO_COMPLETION_PORT */
1125 rbuf
= get_full_recv_buffer();
1126 while (rbuf
!= NULL
)
1133 UNBLOCK_IO_AND_ALARM();
1136 { /* avoid timer starvation during lengthy I/O handling */
1142 * Call the data procedure to handle each received
1145 if (rbuf
->receiver
!= NULL
) /* This should always be true */
1150 L_SUB(&dts
, &rbuf
->recv_time
);
1151 DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts
, 9)));
1152 collect_timing(rbuf
, "buffer processing delay", 1, &dts
);
1155 (rbuf
->receiver
)(rbuf
);
1157 msyslog(LOG_ERR
, "receive buffer corruption - receiver found to be NULL - ABORTING");
1161 BLOCK_IO_AND_ALARM();
1163 rbuf
= get_full_recv_buffer();
1169 collect_timing(NULL
, "processing", bufcount
, &tsb
);
1170 DPRINTF(2, ("processing time for %d buffers %s\n", bufcount
, lfptoa(&tsb
, 9)));
1179 #ifdef HAVE_DNSREGISTRATION
1180 if (mdnsreg
&& (current_time
- mdnsreg
) > 60 && mdnstries
&& sys_leap
!= LEAP_NOTINSYNC
) {
1181 mdnsreg
= current_time
;
1182 msyslog(LOG_INFO
, "Attemping to register mDNS");
1183 if ( DNSServiceRegister (&mdns
, 0, 0, NULL
, "_ntp._udp", NULL
, NULL
,
1184 htons(NTP_PORT
), 0, NULL
, NULL
, NULL
) != kDNSServiceErr_NoError
) {
1186 msyslog(LOG_ERR
, "Unable to register mDNS, giving up.");
1188 msyslog(LOG_INFO
, "Unable to register mDNS, will try later.");
1191 msyslog(LOG_INFO
, "mDNS service registered.");
1195 #endif /* HAVE_DNSREGISTRATION */
1198 UNBLOCK_IO_AND_ALARM();
1205 * finish - exit gracefully
1212 msyslog(LOG_NOTICE
, "ntpd exiting on signal %d", sig
);
1213 #ifdef HAVE_DNSREGISTRATION
1215 DNSServiceRefDeallocate(mdns
);
1220 printf("\nfinish(SIGBUS)\n");
1223 case 0: /* Should never happen... */
1230 #endif /* SIGDIE2 */
1234 * Redirect trap messages from ISC libraries to syslog.
1235 * This code was cloned and simplified from BIND.
1239 * assertion_failed - Handle assertion failures.
1243 assertion_failed(const char *file
, int line
, isc_assertiontype_t type
,
1246 isc_assertion_setcallback(NULL
); /* Avoid recursion */
1248 msyslog(LOG_ERR
, "%s:%d: %s(%s) failed",
1249 file
, line
, isc_assertion_typetotext(type
), cond
);
1250 msyslog(LOG_ERR
, "exiting (due to assertion failure)");
1256 * library_fatal_error - Handle fatal errors from our libraries.
1260 library_fatal_error(const char *file
, int line
, const char *format
,
1265 isc_error_setfatal(NULL
); /* Avoid recursion */
1267 msyslog(LOG_ERR
, "%s:%d: fatal error:", file
, line
);
1268 vsnprintf(errbuf
, sizeof(errbuf
), format
, args
);
1269 msyslog(LOG_ERR
, errbuf
);
1270 msyslog(LOG_ERR
, "exiting (due to fatal error in library)");
1276 * library_unexpected_error - Handle non fatal errors from our libraries.
1278 #define MAX_UNEXPECTED_ERRORS 100
1279 int unexpected_error_cnt
= 0;
1281 library_unexpected_error(const char *file
, int line
, const char *format
,
1286 if (unexpected_error_cnt
>= MAX_UNEXPECTED_ERRORS
)
1287 return; /* avoid clutter in log */
1289 msyslog(LOG_ERR
, "%s:%d: unexpected error:", file
, line
);
1290 vsnprintf(errbuf
, sizeof(errbuf
), format
, args
);
1291 msyslog(LOG_ERR
, errbuf
);
1293 if (++unexpected_error_cnt
== MAX_UNEXPECTED_ERRORS
)
1295 msyslog(LOG_ERR
, "Too many errors. Shutting up.");
1304 * moredebug - increase debugging verbosity
1311 int saved_errno
= errno
;
1316 msyslog(LOG_DEBUG
, "debug raised to %d", debug
);
1318 errno
= saved_errno
;
1322 * lessdebug - decrease debugging verbosity
1329 int saved_errno
= errno
;
1334 msyslog(LOG_DEBUG
, "debug lowered to %d", debug
);
1336 errno
= saved_errno
;
1339 #else /* not DEBUG */
1342 * no_debug - We don't do the debug here.
1349 int saved_errno
= errno
;
1351 msyslog(LOG_DEBUG
, "ntpd not compiled for debugging (signal %d)", sig
);
1352 errno
= saved_errno
;
1354 #endif /* not SYS_WINNT */
1355 #endif /* not DEBUG */